mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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]
|
## [v6.0.9]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use rog_aura::{
|
|||||||
};
|
};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::error::RogError;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
|
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
|
||||||
// #[serde(default)]
|
// #[serde(default)]
|
||||||
pub struct AuraConfig {
|
pub struct AuraConfig {
|
||||||
@@ -130,6 +132,37 @@ impl AuraConfig {
|
|||||||
}
|
}
|
||||||
None
|
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)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
@@ -7,9 +7,7 @@ use log::{debug, info, warn};
|
|||||||
use rog_aura::aura_detection::LedSupportData;
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::keyboard::{LedUsbPackets, UsbPackets};
|
use rog_aura::keyboard::{LedUsbPackets, UsbPackets};
|
||||||
use rog_aura::usb::{LED_APPLY, LED_SET};
|
use rog_aura::usb::{LED_APPLY, LED_SET};
|
||||||
use rog_aura::{
|
use rog_aura::{AuraDeviceType, AuraEffect, LedBrightness, LED_MSG_LEN};
|
||||||
AuraDeviceType, AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN,
|
|
||||||
};
|
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardBacklight;
|
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||||
use udev::Device;
|
use udev::Device;
|
||||||
@@ -180,7 +178,7 @@ impl CtrlKbdLed {
|
|||||||
info!("AuraControl found device at: {:?}", dev_node);
|
info!("AuraControl found device at: {:?}", dev_node);
|
||||||
let dev = HidRaw::from_device(device)?;
|
let dev = HidRaw::from_device(device)?;
|
||||||
let mut controller = Self::from_hidraw(dev, dbus_path.clone())?;
|
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);
|
interfaces.insert(dbus_path);
|
||||||
return Ok(Some(controller));
|
return Ok(Some(controller));
|
||||||
}
|
}
|
||||||
@@ -225,7 +223,7 @@ impl CtrlKbdLed {
|
|||||||
led_node: LEDNode::KbdLed(kbd_backlight),
|
led_node: LEDNode::KbdLed(kbd_backlight),
|
||||||
supported_data: LedSupportData::get_data("tuf"),
|
supported_data: LedSupportData::get_data("tuf"),
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config: Self::init_config("tuf"),
|
config: Self::load_and_update_config("tuf"),
|
||||||
dbus_path: dbus_path_for_tuf(),
|
dbus_path: dbus_path_for_tuf(),
|
||||||
};
|
};
|
||||||
devices.push(ctrl);
|
devices.push(ctrl);
|
||||||
@@ -244,7 +242,7 @@ impl CtrlKbdLed {
|
|||||||
/// The generated data from this function has a default config. This config
|
/// The generated data from this function has a default config. This config
|
||||||
/// should be overwritten. The reason for the default config is because
|
/// should be overwritten. The reason for the default config is because
|
||||||
/// of async issues between this and udev/hidraw
|
/// of async issues between this and udev/hidraw
|
||||||
pub fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result<Self, RogError> {
|
fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result<Self, RogError> {
|
||||||
let rgb_led = KeyboardBacklight::new()
|
let rgb_led = KeyboardBacklight::new()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
log::error!(
|
log::error!(
|
||||||
@@ -274,7 +272,8 @@ impl CtrlKbdLed {
|
|||||||
Ok(ctrl)
|
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
|
// New loads data from the DB also
|
||||||
let mut config_init = AuraConfig::new(prod_id);
|
let mut config_init = AuraConfig::new(prod_id);
|
||||||
// config_init.set_filename(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
|
// Then replace just incase the initialised data contains new modes added
|
||||||
config_loaded.builtins = config_init.builtins;
|
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)) =
|
if let (Some(mut multizone_init), Some(multizone_loaded)) =
|
||||||
(config_init.multizone, config_loaded.multizone.as_mut())
|
(config_init.multizone, config_loaded.multizone.as_mut())
|
||||||
{
|
{
|
||||||
@@ -374,7 +378,8 @@ impl CtrlKbdLed {
|
|||||||
Ok(())
|
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 {
|
if let LEDNode::KbdLed(platform) = &self.led_node {
|
||||||
let buf = [
|
let buf = [
|
||||||
1,
|
1,
|
||||||
@@ -414,53 +419,25 @@ impl CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
if create {
|
if create {
|
||||||
info!("No user-set config for zone founding, attempting a default");
|
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(multizones) = self.config.multizone.as_mut() {
|
||||||
if let Some(set) = multizones.get(&mode) {
|
if let Some(set) = multizones.get(&mode) {
|
||||||
for mode in set.clone() {
|
for mode in set.clone() {
|
||||||
self.write_mode(&mode)?;
|
self.write_effect_and_apply(&mode)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mode = self.config.current_mode;
|
let mode = self.config.current_mode;
|
||||||
if let Some(effect) = self.config.builtins.get(&mode).cloned() {
|
if let Some(effect) = self.config.builtins.get(&mode).cloned() {
|
||||||
self.write_mode(&effect)?;
|
self.write_effect_and_apply(&effect)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
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)]
|
#[cfg(test)]
|
||||||
@@ -502,12 +479,18 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert!(controller.config.multizone.is_none());
|
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());
|
assert!(controller.config.multizone.is_none());
|
||||||
|
|
||||||
controller.supported_data.basic_zones.push(AuraZone::Key1);
|
controller.supported_data.basic_zones.push(AuraZone::Key1);
|
||||||
controller.supported_data.basic_zones.push(AuraZone::Key2);
|
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());
|
assert!(controller.config.multizone.is_some());
|
||||||
|
|
||||||
let m = controller.config.multizone.unwrap();
|
let m = controller.config.multizone.unwrap();
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl CtrlAuraZbus {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl.write_mode(&effect)?;
|
ctrl.write_effect_and_apply(&effect)?;
|
||||||
if ctrl.config.brightness == LedBrightness::Off {
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
ctrl.config.brightness = LedBrightness::Med;
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,6 +449,15 @@
|
|||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
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",
|
device_name: "GA401Q",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
|
|||||||
@@ -70,11 +70,9 @@ impl LedSupportData {
|
|||||||
// product_family");
|
// product_family");
|
||||||
|
|
||||||
if let Some(data) = LedSupportFile::load_from_supoprt_db() {
|
if let Some(data) = LedSupportFile::load_from_supoprt_db() {
|
||||||
if let Some(data) = data.match_device(&dmi.board_name, product_id) {
|
return data.match_device(&dmi.board_name, product_id);
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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();
|
let mut data = LedSupportData::default();
|
||||||
data.power_zones.push(PowerZones::Keyboard);
|
data.power_zones.push(PowerZones::Keyboard);
|
||||||
data
|
data
|
||||||
@@ -91,7 +89,7 @@ impl LedSupportFile {
|
|||||||
|
|
||||||
/// The list is stored in ordered format, so the iterator must be reversed
|
/// 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
|
/// to ensure we match to *whole names* first before doing a glob match
|
||||||
fn match_device(&self, device_name: &str, product_id: &str) -> Option<LedSupportData> {
|
fn match_device(&self, device_name: &str, product_id: &str) -> LedSupportData {
|
||||||
for config in self.0.iter().rev() {
|
for config in self.0.iter().rev() {
|
||||||
if device_name.contains(&config.device_name) {
|
if device_name.contains(&config.device_name) {
|
||||||
info!("Matched to {}", config.device_name);
|
info!("Matched to {}", config.device_name);
|
||||||
@@ -99,20 +97,24 @@ impl LedSupportFile {
|
|||||||
info!("Checking product ID");
|
info!("Checking product ID");
|
||||||
if config.product_id == product_id {
|
if config.product_id == product_id {
|
||||||
info!("Matched to {}", config.product_id);
|
info!("Matched to {}", config.product_id);
|
||||||
return Some(config.clone());
|
return config.clone();
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Some(config.clone());
|
return config.clone();
|
||||||
} else {
|
|
||||||
warn!(
|
|
||||||
"the aura_support.ron file has no entry for this model: {device_name}, \
|
|
||||||
{product_id}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
/// Load `LedSupportFile` from the `aura_support.ron` file at
|
||||||
|
|||||||
Reference in New Issue
Block a user