From b1212585e214772c0357e1c5b25c826754236f75 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sat, 18 May 2024 22:56:12 +1200 Subject: [PATCH] Add GA401I to aura_support Closes #501 --- CHANGELOG.md | 8 ++++ asusd/src/ctrl_aura/config.rs | 33 +++++++++++++++ asusd/src/ctrl_aura/controller.rs | 67 +++++++++++------------------- asusd/src/ctrl_aura/trait_impls.rs | 2 +- rog-aura/data/aura_support.ron | 11 ++++- rog-aura/src/aura_detection.rs | 28 +++++++------ 6 files changed, 92 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 866c8a70..f64b7562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Add the GA401I model to aura_support. + +### Changed + +- Aura support return a default aura definition instead of nothing +- Minor updates in aura controller to ensure configs are updated if the support file changes + ## [v6.0.9] ### Added diff --git a/asusd/src/ctrl_aura/config.rs b/asusd/src/ctrl_aura/config.rs index e09ad63e..f880fd68 100644 --- a/asusd/src/ctrl_aura/config.rs +++ b/asusd/src/ctrl_aura/config.rs @@ -9,6 +9,8 @@ use rog_aura::{ }; use serde_derive::{Deserialize, Serialize}; +use crate::error::RogError; + #[derive(Deserialize, Serialize, Default, Debug, Clone)] // #[serde(default)] pub struct AuraConfig { @@ -130,6 +132,37 @@ impl AuraConfig { } None } + + /// Create a default for the `current_mode` if multizone and no config + /// exists. + pub(super) fn create_multizone_default( + &mut self, + supported_data: &LedSupportData, + ) -> Result<(), RogError> { + let mut default = vec![]; + for (i, tmp) in supported_data.basic_zones.iter().enumerate() { + default.push(AuraEffect { + mode: self.current_mode, + zone: *tmp, + colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]), + colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]), + speed: Speed::Med, + direction: Direction::Left, + }); + } + if default.is_empty() { + return Err(RogError::AuraEffectNotSupported); + } + + if let Some(multizones) = self.multizone.as_mut() { + multizones.insert(self.current_mode, default); + } else { + let mut tmp = BTreeMap::new(); + tmp.insert(self.current_mode, default); + self.multizone = Some(tmp); + } + Ok(()) + } } #[cfg(test)] diff --git a/asusd/src/ctrl_aura/controller.rs b/asusd/src/ctrl_aura/controller.rs index 4f962e04..7c59c43a 100644 --- a/asusd/src/ctrl_aura/controller.rs +++ b/asusd/src/ctrl_aura/controller.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashSet}; +use std::collections::HashSet; use config_traits::{StdConfig, StdConfigLoad}; use dmi_id::DMIID; @@ -7,9 +7,7 @@ use log::{debug, info, warn}; use rog_aura::aura_detection::LedSupportData; use rog_aura::keyboard::{LedUsbPackets, UsbPackets}; use rog_aura::usb::{LED_APPLY, LED_SET}; -use rog_aura::{ - AuraDeviceType, AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN, -}; +use rog_aura::{AuraDeviceType, AuraEffect, LedBrightness, LED_MSG_LEN}; use rog_platform::hid_raw::HidRaw; use rog_platform::keyboard_led::KeyboardBacklight; use udev::Device; @@ -180,7 +178,7 @@ impl CtrlKbdLed { info!("AuraControl found device at: {:?}", dev_node); let dev = HidRaw::from_device(device)?; let mut controller = Self::from_hidraw(dev, dbus_path.clone())?; - controller.config = Self::init_config(&prod_id); + controller.config = Self::load_and_update_config(&prod_id); interfaces.insert(dbus_path); return Ok(Some(controller)); } @@ -225,7 +223,7 @@ impl CtrlKbdLed { led_node: LEDNode::KbdLed(kbd_backlight), supported_data: LedSupportData::get_data("tuf"), per_key_mode_active: false, - config: Self::init_config("tuf"), + config: Self::load_and_update_config("tuf"), dbus_path: dbus_path_for_tuf(), }; devices.push(ctrl); @@ -244,7 +242,7 @@ impl CtrlKbdLed { /// The generated data from this function has a default config. This config /// should be overwritten. The reason for the default config is because /// of async issues between this and udev/hidraw - pub fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result { + fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result { let rgb_led = KeyboardBacklight::new() .map_err(|e| { log::error!( @@ -274,7 +272,8 @@ impl CtrlKbdLed { Ok(ctrl) } - pub fn init_config(prod_id: &str) -> AuraConfig { + /// Reload the config from disk then verify and update it if required + fn load_and_update_config(prod_id: &str) -> AuraConfig { // New loads data from the DB also let mut config_init = AuraConfig::new(prod_id); // config_init.set_filename(prod_id); @@ -289,6 +288,11 @@ impl CtrlKbdLed { // Then replace just incase the initialised data contains new modes added config_loaded.builtins = config_init.builtins; + // Check the powerzones and replace, if the len is different then the support file was updated + if config_loaded.enabled.states.len() != config_init.enabled.states.len() { + config_loaded.enabled.states = config_init.enabled.states; + } + if let (Some(mut multizone_init), Some(multizone_loaded)) = (config_init.multizone, config_loaded.multizone.as_mut()) { @@ -374,7 +378,8 @@ impl CtrlKbdLed { Ok(()) } - pub fn write_mode(&mut self, mode: &AuraEffect) -> Result<(), RogError> { + /// Write the AuraEffect to the device + pub fn write_effect_and_apply(&mut self, mode: &AuraEffect) -> Result<(), RogError> { if let LEDNode::KbdLed(platform) = &self.led_node { let buf = [ 1, @@ -414,53 +419,25 @@ impl CtrlKbdLed { } if create { info!("No user-set config for zone founding, attempting a default"); - self.create_multizone_default()?; + self.config.create_multizone_default(&self.supported_data)?; } if let Some(multizones) = self.config.multizone.as_mut() { if let Some(set) = multizones.get(&mode) { for mode in set.clone() { - self.write_mode(&mode)?; + self.write_effect_and_apply(&mode)?; } } } } else { let mode = self.config.current_mode; if let Some(effect) = self.config.builtins.get(&mode).cloned() { - self.write_mode(&effect)?; + self.write_effect_and_apply(&effect)?; } } Ok(()) } - - /// Create a default for the `current_mode` if multizone and no config - /// exists. - fn create_multizone_default(&mut self) -> Result<(), RogError> { - let mut default = vec![]; - for (i, tmp) in self.supported_data.basic_zones.iter().enumerate() { - default.push(AuraEffect { - mode: self.config.current_mode, - zone: *tmp, - colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]), - colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]), - speed: Speed::Med, - direction: Direction::Left, - }); - } - if default.is_empty() { - return Err(RogError::AuraEffectNotSupported); - } - - if let Some(multizones) = self.config.multizone.as_mut() { - multizones.insert(self.config.current_mode, default); - } else { - let mut tmp = BTreeMap::new(); - tmp.insert(self.config.current_mode, default); - self.config.multizone = Some(tmp); - } - Ok(()) - } } #[cfg(test)] @@ -502,12 +479,18 @@ mod tests { }; assert!(controller.config.multizone.is_none()); - assert!(controller.create_multizone_default().is_err()); + assert!(controller + .config + .create_multizone_default(&controller.supported_data) + .is_err()); assert!(controller.config.multizone.is_none()); controller.supported_data.basic_zones.push(AuraZone::Key1); controller.supported_data.basic_zones.push(AuraZone::Key2); - assert!(controller.create_multizone_default().is_ok()); + assert!(controller + .config + .create_multizone_default(&controller.supported_data) + .is_ok()); assert!(controller.config.multizone.is_some()); let m = controller.config.multizone.unwrap(); diff --git a/asusd/src/ctrl_aura/trait_impls.rs b/asusd/src/ctrl_aura/trait_impls.rs index 7c455c25..b1df854c 100644 --- a/asusd/src/ctrl_aura/trait_impls.rs +++ b/asusd/src/ctrl_aura/trait_impls.rs @@ -146,7 +146,7 @@ impl CtrlAuraZbus { ))); } - ctrl.write_mode(&effect)?; + ctrl.write_effect_and_apply(&effect)?; if ctrl.config.brightness == LedBrightness::Off { ctrl.config.brightness = LedBrightness::Med; } diff --git a/rog-aura/data/aura_support.ron b/rog-aura/data/aura_support.ron index 1260ed24..40049fe5 100644 --- a/rog-aura/data/aura_support.ron +++ b/rog-aura/data/aura_support.ron @@ -449,6 +449,15 @@ advanced_type: PerKey, power_zones: [Keyboard, Lightbar, Logo, RearGlow], ), + ( + device_name: "GA401I", + product_id: "", + layout_name: "ga401q", + basic_modes: [Static, Breathe, Pulse], + basic_zones: [], + advanced_type: None, + power_zones: [Keyboard], + ), ( device_name: "GA401Q", product_id: "", @@ -845,4 +854,4 @@ advanced_type: None, power_zones: [Keyboard], ), -]) \ No newline at end of file +]) diff --git a/rog-aura/src/aura_detection.rs b/rog-aura/src/aura_detection.rs index 90a17b18..2ce3f62e 100644 --- a/rog-aura/src/aura_detection.rs +++ b/rog-aura/src/aura_detection.rs @@ -70,11 +70,9 @@ impl LedSupportData { // product_family"); if let Some(data) = LedSupportFile::load_from_supoprt_db() { - if let Some(data) = data.match_device(&dmi.board_name, product_id) { - return data; - } + return data.match_device(&dmi.board_name, product_id); } - info!("Using generic LED control for keyboard brightness only"); + info!("Using generic LED control for keyboard brightness only. No aura_support file found"); let mut data = LedSupportData::default(); data.power_zones.push(PowerZones::Keyboard); data @@ -91,7 +89,7 @@ impl LedSupportFile { /// The list is stored in ordered format, so the iterator must be reversed /// to ensure we match to *whole names* first before doing a glob match - fn match_device(&self, device_name: &str, product_id: &str) -> Option { + fn match_device(&self, device_name: &str, product_id: &str) -> LedSupportData { for config in self.0.iter().rev() { if device_name.contains(&config.device_name) { info!("Matched to {}", config.device_name); @@ -99,20 +97,24 @@ impl LedSupportFile { info!("Checking product ID"); if config.product_id == product_id { info!("Matched to {}", config.product_id); - return Some(config.clone()); + return config.clone(); } else { continue; } } - return Some(config.clone()); - } else { - warn!( - "the aura_support.ron file has no entry for this model: {device_name}, \ - {product_id}" - ) + return config.clone(); } } - None + warn!("the aura_support.ron file has no entry for this model: {device_name}, {product_id}. Using a default"); + LedSupportData { + device_name: device_name.to_owned(), + product_id: product_id.to_owned(), + layout_name: "Default".to_owned(), + basic_modes: vec![AuraModeNum::Static], + basic_zones: vec![], + advanced_type: AdvancedAuraType::None, + power_zones: vec![PowerZones::Keyboard], + } } /// Load `LedSupportFile` from the `aura_support.ron` file at