mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Merge branch 'fluke/multizone-defaults' into 'main'
Create defaults on missing zones See merge request asus-linux/asusctl!120
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use crate::laptops::LaptopLedData;
|
use crate::laptops::LaptopLedData;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use rog_aura::usb::AuraControl;
|
use rog_aura::usb::AuraControl;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
@@ -92,6 +92,27 @@ impl AuraConfig {
|
|||||||
config
|
config
|
||||||
.builtins
|
.builtins
|
||||||
.insert(*n, AuraEffect::default_with_mode(*n));
|
.insert(*n, AuraEffect::default_with_mode(*n));
|
||||||
|
|
||||||
|
if !support_data.multizone.is_empty() {
|
||||||
|
let mut default = vec![];
|
||||||
|
for (i, tmp) in support_data.multizone.iter().enumerate() {
|
||||||
|
default.push(AuraEffect {
|
||||||
|
mode: *n,
|
||||||
|
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 let Some(m) = config.multizone.as_mut() {
|
||||||
|
m.insert(*n, default);
|
||||||
|
} else {
|
||||||
|
let mut tmp = BTreeMap::new();
|
||||||
|
tmp.insert(*n, default);
|
||||||
|
config.multizone = Some(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be okay to unwrap this as is since it is a Default
|
// Should be okay to unwrap this as is since it is a Default
|
||||||
|
|||||||
@@ -9,17 +9,20 @@ use crate::{
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
use rog_aura::{usb::AuraControl, AuraZone};
|
use rog_aura::{usb::AuraControl, AuraZone, Direction, Speed, GRADIENT};
|
||||||
use rog_aura::{
|
use rog_aura::{
|
||||||
usb::{LED_APPLY, LED_SET},
|
usb::{LED_APPLY, LED_SET},
|
||||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||||
};
|
};
|
||||||
use rog_supported::LedSupportedFunctions;
|
use rog_supported::LedSupportedFunctions;
|
||||||
use smol::{stream::StreamExt, Executor};
|
use smol::{stream::StreamExt, Executor};
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
io::{Read, Write},
|
||||||
|
};
|
||||||
use std::{fs::OpenOptions, sync::MutexGuard};
|
use std::{fs::OpenOptions, sync::MutexGuard};
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
@@ -160,7 +163,7 @@ pub struct CtrlKbdLedReloader(pub Arc<Mutex<CtrlKbdLed>>);
|
|||||||
|
|
||||||
impl crate::Reloadable for CtrlKbdLedReloader {
|
impl crate::Reloadable for CtrlKbdLedReloader {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||||
ctrl.write_current_config_mode()?;
|
ctrl.write_current_config_mode()?;
|
||||||
ctrl.set_power_states(&ctrl.config)
|
ctrl.set_power_states(&ctrl.config)
|
||||||
.map_err(|err| warn!("{err}"))
|
.map_err(|err| warn!("{err}"))
|
||||||
@@ -179,7 +182,6 @@ impl CtrlKbdLedZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlKbdLed {
|
impl CtrlKbdLed {
|
||||||
#[inline]
|
|
||||||
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
|
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
|
||||||
// TODO: return error if *all* nodes are None
|
// TODO: return error if *all* nodes are None
|
||||||
let mut led_node = None;
|
let mut led_node = None;
|
||||||
@@ -353,7 +355,6 @@ impl CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Should only be used if the bytes you are writing are verified correct
|
/// Should only be used if the bytes you are writing are verified correct
|
||||||
#[inline]
|
|
||||||
fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
||||||
if let Some(led_node) = &self.led_node {
|
if let Some(led_node) = &self.led_node {
|
||||||
if let Ok(mut file) = OpenOptions::new().write(true).open(led_node) {
|
if let Ok(mut file) = OpenOptions::new().write(true).open(led_node) {
|
||||||
@@ -367,7 +368,6 @@ impl CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write an effect block. This is for per-key
|
/// Write an effect block. This is for per-key
|
||||||
#[inline]
|
|
||||||
fn _write_effect(&mut self, effect: &[Vec<u8>]) -> Result<(), RogError> {
|
fn _write_effect(&mut self, effect: &[Vec<u8>]) -> Result<(), RogError> {
|
||||||
if self.flip_effect_write {
|
if self.flip_effect_write {
|
||||||
for row in effect.iter().rev() {
|
for row in effect.iter().rev() {
|
||||||
@@ -382,7 +382,6 @@ impl CtrlKbdLed {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(super) fn toggle_mode(&mut self, reverse: bool) -> Result<(), RogError> {
|
pub(super) fn toggle_mode(&mut self, reverse: bool) -> Result<(), RogError> {
|
||||||
let current = self.config.current_mode;
|
let current = self.config.current_mode;
|
||||||
if let Some(idx) = self
|
if let Some(idx) = self
|
||||||
@@ -418,7 +417,6 @@ impl CtrlKbdLed {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_mode(&self, mode: &AuraEffect) -> Result<(), RogError> {
|
fn write_mode(&self, mode: &AuraEffect) -> Result<(), RogError> {
|
||||||
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||||
self.write_bytes(&bytes)?;
|
self.write_bytes(&bytes)?;
|
||||||
@@ -428,10 +426,25 @@ impl CtrlKbdLed {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn write_current_config_mode(&mut self) -> Result<(), RogError> {
|
||||||
fn write_current_config_mode(&self) -> Result<(), RogError> {
|
|
||||||
if self.config.multizone_on {
|
if self.config.multizone_on {
|
||||||
let mode = self.config.current_mode;
|
let mode = self.config.current_mode;
|
||||||
|
let mut create = false;
|
||||||
|
// There is no multizone config for this mode so create one here
|
||||||
|
// using the colours of rainbow if it exists, or first available
|
||||||
|
// mode, or random
|
||||||
|
if self.config.multizone.is_none() {
|
||||||
|
create = true;
|
||||||
|
} else if let Some(multizones) = self.config.multizone.as_ref() {
|
||||||
|
if !multizones.contains_key(&mode) {
|
||||||
|
create = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if create {
|
||||||
|
info!("No user-set config for zone founding, attempting a default");
|
||||||
|
self.create_multizone_default()?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(multizones) = self.config.multizone.as_ref() {
|
if let Some(multizones) = self.config.multizone.as_ref() {
|
||||||
if let Some(set) = multizones.get(&mode) {
|
if let Some(set) = multizones.get(&mode) {
|
||||||
for mode in set {
|
for mode in set {
|
||||||
@@ -448,6 +461,33 @@ impl CtrlKbdLed {
|
|||||||
|
|
||||||
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_modes.multizone.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)]
|
||||||
@@ -519,4 +559,40 @@ mod tests {
|
|||||||
"No Aura keyboard node found"
|
"No Aura keyboard node found"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_multizone_if_no_config() {
|
||||||
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
|
let config = AuraConfig::default();
|
||||||
|
let supported_modes = LaptopLedData {
|
||||||
|
prod_family: "".into(),
|
||||||
|
board_names: vec![],
|
||||||
|
standard: vec![AuraModeNum::Static],
|
||||||
|
multizone: vec![],
|
||||||
|
per_key: false,
|
||||||
|
};
|
||||||
|
let mut controller = CtrlKbdLed {
|
||||||
|
led_node: None,
|
||||||
|
bright_node: String::new(),
|
||||||
|
supported_modes,
|
||||||
|
flip_effect_write: false,
|
||||||
|
config,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(controller.config.multizone.is_none());
|
||||||
|
assert!(controller.create_multizone_default().is_err());
|
||||||
|
assert!(controller.config.multizone.is_none());
|
||||||
|
|
||||||
|
controller.supported_modes.multizone.push(AuraZone::Key1);
|
||||||
|
controller.supported_modes.multizone.push(AuraZone::Key2);
|
||||||
|
assert!(controller.create_multizone_default().is_ok());
|
||||||
|
assert!(controller.config.multizone.is_some());
|
||||||
|
|
||||||
|
let m = controller.config.multizone.unwrap();
|
||||||
|
assert!(m.contains_key(&AuraModeNum::Static));
|
||||||
|
let e = m.get(&AuraModeNum::Static).unwrap();
|
||||||
|
assert_eq!(e.len(), 2);
|
||||||
|
assert_eq!(e[0].zone, AuraZone::Key1);
|
||||||
|
assert_eq!(e[1].zone, AuraZone::Key2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -731,7 +731,8 @@ mod tests {
|
|||||||
vec![Pixel::default(); 1000],
|
vec![Pixel::default(); 1000],
|
||||||
100,
|
100,
|
||||||
AnimeType::GA402,
|
AnimeType::GA402,
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
matrix._edge_outline();
|
matrix._edge_outline();
|
||||||
let data = AnimeDataBuffer::from(&matrix);
|
let data = AnimeDataBuffer::from(&matrix);
|
||||||
let pkt = AnimePacketType::from(data);
|
let pkt = AnimePacketType::from(data);
|
||||||
|
|||||||
@@ -16,3 +16,12 @@ pub mod error;
|
|||||||
pub const LED_MSG_LEN: usize = 17;
|
pub const LED_MSG_LEN: usize = 17;
|
||||||
|
|
||||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
pub const RED: Colour = Colour(0xff, 0x00, 0x00);
|
||||||
|
pub const GREEN: Colour = Colour(0x00, 0xff, 0x00);
|
||||||
|
pub const BLUE: Colour = Colour(0x00, 0x00, 0xff);
|
||||||
|
pub const VIOLET: Colour = Colour(0x9B, 0x26, 0xB6);
|
||||||
|
pub const TEAL: Colour = Colour(0x00, 0x7C, 0x80);
|
||||||
|
pub const YELLOW: Colour = Colour(0xff, 0xef, 0x00);
|
||||||
|
pub const ORANGE: Colour = Colour(0xff, 0xa4, 0x00);
|
||||||
|
pub const GRADIENT: [Colour; 7] = [RED, VIOLET, BLUE, TEAL, GREEN, YELLOW, ORANGE];
|
||||||
|
|||||||
Reference in New Issue
Block a user