diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e904046..70cd3ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 also allows for setting the brightness through `SetKeyBacklight` ### Added -- REDME_DBUS.md to document DBUS interface +- README_DBUS.md to document DBUS interface +- Dbus method `GetKeyBacklight` +- Dbus method `GetKeyBacklightModes` ## [0.13.1] - 2020-29-06 ### Fixed diff --git a/README_DBUS.md b/README_DBUS.md index 576be41f..7bce7973 100644 --- a/README_DBUS.md +++ b/README_DBUS.md @@ -9,12 +9,13 @@ pub static DBUS_IFACE: &str = "org.rogcore.Daemon"; ## Methods - `SetKeyBacklight` +- `GetKeyBacklight` - `AnimatrixWrite` - `SetFanMode` - `GetFanMode` - `SetChargeLimit` - `GetChargeLimit` -- TODO: GetLEDModes +- `GetKeyBacklightModes` ## Signals @@ -65,6 +66,18 @@ dbus. Lastly, there is `"LedBrightness": ` which accepts 0-3 for off, low, med, high. +### GetKeyBacklight + +This method will return a JSON string in the same format as accepted by `SetKeyBacklight`. + +### GetKeyBacklightModes + +Will return a JSON string array of modes that this laptop accepts. The mode data +within this will be the current settings per mode. Good for: + +- Getting supported modes +- Getting all mode settings + ### AnimatrixWrite Used to write data to the AniMe display if available. Currently is takes `[[u8; 640]; 2]` @@ -94,7 +107,15 @@ Returns the integer set from above. ### KeyBacklightChanged -When emitted, it will emit a true or false. +When emitted, it will emit the JSON data of the mode changed to, e.g: + +``` +{ + "Stable": { + "colour": [ 255, 0, 0] + } +} +``` ### FanModeChanged diff --git a/rog-client/src/aura_modes.rs b/rog-client/src/aura_modes.rs index 4ed6c19e..bb45bf2e 100644 --- a/rog-client/src/aura_modes.rs +++ b/rog-client/src/aura_modes.rs @@ -14,6 +14,7 @@ pub const RIPPLE: u8 = 0x08; pub const PULSE: u8 = 0x0a; pub const COMET: u8 = 0x0b; pub const FLASH: u8 = 0x0c; +pub const MULTISTATIC: u8 = 0x0d; #[derive(Clone, Default, Deserialize, Serialize)] pub struct Colour(pub u8, pub u8, pub u8); @@ -226,7 +227,7 @@ impl From<&AuraModes> for u8 { AuraModes::Pulse(_) => PULSE, AuraModes::Comet(_) => COMET, AuraModes::Flash(_) => FLASH, - AuraModes::MultiStatic(_) => 0x0d, + AuraModes::MultiStatic(_) => MULTISTATIC, _ => panic!("Invalid mode"), } } @@ -248,6 +249,7 @@ impl From for AuraModes { PULSE => AuraModes::Pulse(SingleColour::default()), COMET => AuraModes::Comet(SingleColour::default()), FLASH => AuraModes::Flash(SingleColour::default()), + MULTISTATIC => AuraModes::MultiStatic(MultiColour::default()), _ => panic!("Invalid mode byte"), } } diff --git a/rog-client/src/core_dbus.rs b/rog-client/src/core_dbus.rs index e6ba089a..d5b6b2a3 100644 --- a/rog-client/src/core_dbus.rs +++ b/rog-client/src/core_dbus.rs @@ -26,10 +26,8 @@ impl AuraDbusWriter { let stopper2 = stop.clone(); let match_rule = dbus::message::MatchRule::new_signal(DBUS_IFACE, "KeyBacklightChanged"); let stop_token = connection.add_match(match_rule, move |_: (), _, msg| { - if let Ok(stop) = msg.read1::() { - if stop { - stopper2.store(true, Ordering::Relaxed); - } + if msg.read1::<&str>().is_ok() { + stopper2.store(true, Ordering::Relaxed); } true })?; diff --git a/rog-client/src/lib.rs b/rog-client/src/lib.rs index c5e371cb..47c8e039 100644 --- a/rog-client/src/lib.rs +++ b/rog-client/src/lib.rs @@ -210,6 +210,13 @@ impl From for [u8; LED_MSG_LEN] { 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; diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index e563a733..ea594d49 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -198,6 +198,7 @@ pub async fn start_daemon() -> Result<(), Box> { .unwrap_or_else(|err| warn!("{}", err)); } _ => { + let json = serde_json::to_string(&command)?; led_writer .do_command(command, &mut config) .await @@ -206,14 +207,7 @@ pub async fn start_daemon() -> Result<(), Box> { .send( effect_cancel_signal .msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) - .append1(true), - ) - .unwrap_or_else(|_| 0); - connection - .send( - effect_cancel_signal - .msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) - .append1(false), + .append1(json), ) .unwrap_or_else(|_| 0); } diff --git a/rog-core/src/laptops.rs b/rog-core/src/laptops.rs index 4290558e..c7e63da0 100644 --- a/rog-core/src/laptops.rs +++ b/rog-core/src/laptops.rs @@ -1,8 +1,8 @@ use crate::{config::Config, rogcore::RogCore}; use rog_client::{ aura_modes::{ - AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, PULSE, RAIN, RAINBOW, RIPPLE, SINGLE, - STAR, STROBE, + AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, MULTISTATIC, PULSE, RAIN, RAINBOW, + RIPPLE, SINGLE, STAR, STROBE, }, error::AuraError, }; @@ -79,12 +79,12 @@ fn choose_1866_device(prod: u16) -> LaptopBase { // GM501 } else if board_name.starts_with("GM501") { laptop.supported_modes = vec![SINGLE, BREATHING, STROBE, RAINBOW]; - // G531 - } else if board_name.starts_with("GX531") - || board_name.starts_with("G531") - || board_name.starts_with("G712") - { + // GX531, G531 + } else if board_name.starts_with("GX531") || board_name.starts_with("G531") { laptop.supported_modes = vec![SINGLE, BREATHING, STROBE, RAINBOW, PULSE]; + // G712 + } else if board_name.starts_with("G712") { + laptop.supported_modes = vec![SINGLE, BREATHING, STROBE, RAINBOW, PULSE, MULTISTATIC]; } else { panic!( "Unsupported laptop, please request support at\nhttps://github.com/flukejones/rog-core" diff --git a/rog-core/src/led_control.rs b/rog-core/src/led_control.rs index 7d34be85..35c491e5 100644 --- a/rog-core/src/led_control.rs +++ b/rog-core/src/led_control.rs @@ -9,7 +9,7 @@ static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; use crate::{config::Config, error::RogError}; -use log::{error, info, warn}; +use log::{error, info}; use rog_client::{ aura_brightness_bytes, aura_modes::AuraModes, fancy::KeyColourArray, LED_MSG_LEN, }; @@ -140,24 +140,32 @@ where } _ => { let mode_num: u8 = u8::from(&mode); - if self.supported_modes.contains(&mode_num) { - let bytes: [u8; LED_MSG_LEN] = (&mode).into(); - self.write_bytes(&bytes).await?; - self.write_bytes(&LED_SET).await?; - // Changes won't persist unless apply is set - self.write_bytes(&LED_APPLY).await?; - - config.current_mode = mode_num; - config.set_mode_data(mode); - config.write(); - info!("Switched LED mode to {:#?}", config.current_mode); - return Ok(()); + match mode { + AuraModes::MultiStatic(_) => { + if self.supported_modes.contains(&mode_num) { + let bytes: [[u8; LED_MSG_LEN]; 4] = (&mode).into(); + for array in bytes.iter() { + self.write_bytes(array).await?; + } + } + } + _ => { + if self.supported_modes.contains(&mode_num) { + let bytes: [u8; LED_MSG_LEN] = (&mode).into(); + self.write_bytes(&bytes).await?; + } + } } + self.write_bytes(&LED_SET).await?; + // Changes won't persist unless apply is set + self.write_bytes(&LED_APPLY).await?; + config.current_mode = mode_num; + config.set_mode_data(mode); + config.write(); + info!("Switched LED mode to {:#?}", config.current_mode); + return Ok(()); } } - - warn!("Attempted to set unsupported mode"); - Err(RogError::NotSupported) } #[inline] diff --git a/rog-core/src/rog_dbus.rs b/rog-core/src/rog_dbus.rs index 116ac213..b0c61442 100644 --- a/rog-core/src/rog_dbus.rs +++ b/rog-core/src/rog_dbus.rs @@ -9,7 +9,7 @@ use tokio::sync::{ Mutex, }; -pub(super) fn dbus_set_ledmsg(sender: Mutex>) -> Method { +fn set_keyboard_backlight(sender: Mutex>) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -34,7 +34,48 @@ pub(super) fn dbus_set_ledmsg(sender: Mutex>) -> Method>) -> Method { + let factory = Factory::new_sync::<()>(); + factory + .method("GetKeyBacklight", (), { + move |m| { + if let Ok(lock) = config.try_lock() { + for mode in &lock.builtin_modes { + if lock.current_mode == ::from(mode) { + let mode = serde_json::to_string(&mode).unwrap(); + let mret = m.msg.method_return().append1(mode); + return Ok(vec![mret]); + } + } + Err(MethodErr::failed( + "Keyboard LED mode set to an invalid mode", + )) + } else { + Err(MethodErr::failed("Could not lock config for access")) + } + } + }) + .outarg::<&str, _>("value") +} + +fn get_keyboard_backlight_modes(config: Arc>) -> Method { + let factory = Factory::new_sync::<()>(); + factory + .method("GetKeyBacklightModes", (), { + move |m| { + if let Ok(lock) = config.try_lock() { + let mode = serde_json::to_string(&lock.builtin_modes).unwrap(); + let mret = m.msg.method_return().append1(mode); + return Ok(vec![mret]); + } else { + Err(MethodErr::failed("Could not lock config for access")) + } + } + }) + .outarg::<&str, _>("value") +} + +fn set_animatrix( sender: Mutex>>>, // need mutex only to get interior mutability in MTSync ) -> Method { let factory = Factory::new_sync::<()>(); @@ -58,7 +99,7 @@ pub(super) fn dbus_set_animatrix( .annotate("org.freedesktop.DBus.Method.NoReply", "true") } -pub(super) fn dbus_set_fan_mode(data: DbusU8Type) -> Method { +fn set_fan_mode(data: DbusU8Type) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -78,7 +119,7 @@ pub(super) fn dbus_set_fan_mode(data: DbusU8Type) -> Method { .annotate("org.freedesktop.DBus.Method.NoReply", "true") } -pub(super) fn dbus_get_fan_mode(config: Arc>) -> Method { +fn get_fan_mode(config: Arc>) -> Method { let factory = Factory::new_sync::<()>(); factory .method("GetFanMode", (), { @@ -94,7 +135,7 @@ pub(super) fn dbus_get_fan_mode(config: Arc>) -> Method("value") } -pub(super) fn dbus_get_charge_limit(config: Arc>) -> Method { +fn get_charge_limit(config: Arc>) -> Method { let factory = Factory::new_sync::<()>(); factory .method("GetChargeLimit", (), { @@ -110,7 +151,7 @@ pub(super) fn dbus_get_charge_limit(config: Arc>) -> Method("value") } -pub(super) fn dbus_set_charge_limit(data: DbusU8Type) -> Method { +fn set_charge_limit(data: DbusU8Type) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage @@ -151,17 +192,17 @@ pub(super) fn dbus_create_tree( let factory = Factory::new_sync::<()>(); - let builtin_mode_sig = Arc::new( + let key_backlight_changed = Arc::new( factory .signal("KeyBacklightChanged", ()) - .sarg::("value"), + .sarg::<&str, _>("value"), ); - let fanmode_changed_sig = Arc::new(factory.signal("FanModeChanged", ()).sarg::("value")); - let chrg_limit_changed_sig = Arc::new( + let chrg_limit_changed = Arc::new( factory .signal("ChargeLimitChanged", ()) .sarg::("value"), ); + let fanmode_changed = Arc::new(factory.signal("FanModeChanged", ()).sarg::("value")); let tree = factory .tree(()) @@ -169,15 +210,19 @@ pub(super) fn dbus_create_tree( factory.object_path(DBUS_PATH, ()).introspectable().add( factory .interface(DBUS_IFACE, ()) - .add_m(dbus_set_ledmsg(Mutex::new(aura_command_send.clone()))) - .add_m(dbus_set_animatrix(Mutex::new(animatrix_send))) - .add_m(dbus_set_fan_mode(fan_mode.clone())) - .add_m(dbus_set_charge_limit(charge_limit.clone())) - .add_m(dbus_get_fan_mode(config.clone())) - .add_m(dbus_get_charge_limit(config)) - .add_s(builtin_mode_sig.clone()) - .add_s(fanmode_changed_sig.clone()) - .add_s(chrg_limit_changed_sig.clone()), + .add_m(set_keyboard_backlight(Mutex::new( + aura_command_send.clone(), + ))) + .add_m(set_animatrix(Mutex::new(animatrix_send))) + .add_m(set_fan_mode(fan_mode.clone())) + .add_m(set_charge_limit(charge_limit.clone())) + .add_m(get_fan_mode(config.clone())) + .add_m(get_charge_limit(config.clone())) + .add_m(get_keyboard_backlight(config.clone())) + .add_m(get_keyboard_backlight_modes(config.clone())) + .add_s(key_backlight_changed.clone()) + .add_s(fanmode_changed.clone()) + .add_s(chrg_limit_changed.clone()), ), ) .add(factory.object_path("/", ()).introspectable()); @@ -188,8 +233,8 @@ pub(super) fn dbus_create_tree( animatrix_recv, fan_mode, charge_limit, - builtin_mode_sig, - fanmode_changed_sig, - chrg_limit_changed_sig, + key_backlight_changed, + fanmode_changed, + chrg_limit_changed, ) }