mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Fix reloading last keyboard brightness on boot
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rog-daemon"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Return show-stopping errors, otherwise map error to a log level
|
||||
|
||||
use crate::{config::Config, virt_device::VirtKeys};
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_aura::{aura_brightness_bytes, error::AuraError, BuiltInModeByte};
|
||||
use log::{error, info, warn};
|
||||
use rusb::DeviceHandle;
|
||||
use std::error::Error;
|
||||
use std::fs::OpenOptions;
|
||||
@@ -13,16 +12,6 @@ use std::process::Command;
|
||||
use std::ptr::NonNull;
|
||||
use std::time::Duration;
|
||||
|
||||
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
||||
static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
|
||||
// Only these two packets must be 17 bytes
|
||||
static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 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];
|
||||
|
||||
static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy";
|
||||
static FAN_TYPE_2_PATH: &str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode";
|
||||
|
||||
@@ -75,22 +64,6 @@ impl RogCore {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn reload(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = if Path::new(FAN_TYPE_1_PATH).exists() {
|
||||
FAN_TYPE_1_PATH
|
||||
} else if Path::new(FAN_TYPE_2_PATH).exists() {
|
||||
FAN_TYPE_2_PATH
|
||||
} else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
file.write_all(format!("{:?}\n", config.fan_mode).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(config.fan_mode), config)?;
|
||||
info!("Reloaded last saved settings");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn virt_keys(&mut self) -> &mut VirtKeys {
|
||||
&mut self.virt_keys
|
||||
}
|
||||
@@ -108,15 +81,30 @@ impl RogCore {
|
||||
Err(rusb::Error::NoDevice)
|
||||
}
|
||||
|
||||
pub fn fan_mode_step(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = if Path::new(FAN_TYPE_1_PATH).exists() {
|
||||
FAN_TYPE_1_PATH
|
||||
fn get_fan_path() -> Result<&'static str, std::io::Error> {
|
||||
if Path::new(FAN_TYPE_1_PATH).exists() {
|
||||
Ok(FAN_TYPE_1_PATH)
|
||||
} else if Path::new(FAN_TYPE_2_PATH).exists() {
|
||||
FAN_TYPE_2_PATH
|
||||
Ok(FAN_TYPE_2_PATH)
|
||||
} else {
|
||||
return Ok(());
|
||||
};
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"Fan mode not available",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn fan_mode_reload(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = RogCore::get_fan_path()?;
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
file.write_all(format!("{:?}\n", config.fan_mode).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(config.fan_mode), config)?;
|
||||
info!("Reloaded last saved settings");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fan_mode_step(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = RogCore::get_fan_path()?;
|
||||
let mut fan_ctrl = OpenOptions::new().read(true).write(true).open(path)?;
|
||||
|
||||
let mut buf = String::new();
|
||||
@@ -300,220 +288,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub enum AuraCommand {
|
||||
BrightInc,
|
||||
BrightDec,
|
||||
BuiltinNext,
|
||||
BuiltinPrev,
|
||||
WriteBytes(Vec<u8>),
|
||||
WriteEffect(Vec<Vec<u8>>),
|
||||
ReloadLast,
|
||||
}
|
||||
|
||||
/// UNSAFE: Must live as long as RogCore
|
||||
///
|
||||
/// Because we're holding a pointer to something that *may* go out of scope while the
|
||||
/// pointer is held. We're relying on access to struct to be behind a Mutex, and for behaviour
|
||||
/// that may cause invalididated pointer to cause the program to panic rather than continue.
|
||||
pub struct LedWriter<'d, C: 'd>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
handle: NonNull<DeviceHandle<C>>,
|
||||
bright_min_max: (u8, u8),
|
||||
supported_modes: Vec<BuiltInModeByte>,
|
||||
led_endpoint: u8,
|
||||
initialised: bool,
|
||||
_phantom: PhantomData<&'d DeviceHandle<C>>,
|
||||
}
|
||||
|
||||
/// UNSAFE
|
||||
unsafe impl<'d, C> Send for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
unsafe impl<'d, C> Sync for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
|
||||
impl<'d, C> LedWriter<'d, C>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
pub fn new(
|
||||
device_handle: NonNull<DeviceHandle<C>>,
|
||||
led_endpoint: u8,
|
||||
bright_min_max: (u8, u8),
|
||||
supported_modes: Vec<BuiltInModeByte>,
|
||||
) -> Self {
|
||||
LedWriter {
|
||||
handle: device_handle,
|
||||
led_endpoint,
|
||||
bright_min_max,
|
||||
supported_modes,
|
||||
initialised: false,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn do_command(
|
||||
&mut self,
|
||||
command: AuraCommand,
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
if !self.initialised {
|
||||
self.write_bytes(&LED_INIT1).await?;
|
||||
self.write_bytes(LED_INIT2.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT3).await?;
|
||||
self.write_bytes(LED_INIT4.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT5).await?;
|
||||
self.initialised = true;
|
||||
}
|
||||
|
||||
match command {
|
||||
AuraCommand::BrightInc => {
|
||||
let mut bright = config.brightness;
|
||||
if bright < self.bright_min_max.1 {
|
||||
bright += 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.set_and_save(&bytes, config).await?;
|
||||
info!("Increased LED brightness to {:#?}", bright);
|
||||
}
|
||||
}
|
||||
AuraCommand::BrightDec => {
|
||||
let mut bright = config.brightness;
|
||||
if bright > self.bright_min_max.0 {
|
||||
bright -= 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.set_and_save(&bytes, config).await?;
|
||||
info!("Decreased LED brightness to {:#?}", bright);
|
||||
}
|
||||
}
|
||||
AuraCommand::BuiltinNext => {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = self
|
||||
.supported_modes
|
||||
.binary_search(&mode_curr.into())
|
||||
.unwrap();
|
||||
let idx_next = if idx < self.supported_modes.len() - 1 {
|
||||
idx + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.set_builtin(config, idx_next).await?;
|
||||
}
|
||||
AuraCommand::BuiltinPrev => {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = self
|
||||
.supported_modes
|
||||
.binary_search(&mode_curr.into())
|
||||
.unwrap();
|
||||
let idx_next = if idx > 0 {
|
||||
idx - 1
|
||||
} else {
|
||||
self.supported_modes.len() - 1
|
||||
};
|
||||
self.set_builtin(config, idx_next).await?;
|
||||
}
|
||||
AuraCommand::WriteBytes(bytes) => self.set_and_save(&bytes, config).await?,
|
||||
AuraCommand::WriteEffect(effect) => self.write_effect(effect).await?,
|
||||
AuraCommand::ReloadLast => self.reload_last_builtin(&config).await?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Should only be used if the bytes you are writing are verified correct
|
||||
async fn write_bytes(&mut self, message: &[u8]) -> Result<(), AuraError> {
|
||||
match unsafe { self.handle.as_ref() }.write_interrupt(
|
||||
self.led_endpoint,
|
||||
message,
|
||||
Duration::from_millis(5),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write to led interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn write_array_of_bytes(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> {
|
||||
for message in messages {
|
||||
self.write_bytes(*message).await?;
|
||||
self.write_bytes(&LED_SET).await?;
|
||||
}
|
||||
// Changes won't persist unless apply is set
|
||||
self.write_bytes(&LED_APPLY).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
async fn write_effect(&self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> {
|
||||
for row in effect.iter() {
|
||||
match unsafe { self.handle.as_ref() }.write_interrupt(
|
||||
self.led_endpoint,
|
||||
row,
|
||||
Duration::from_millis(1),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write LED interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Used to set a builtin mode and save the settings for it
|
||||
async fn set_and_save(&mut self, bytes: &[u8], config: &mut Config) -> Result<(), AuraError> {
|
||||
let mode = BuiltInModeByte::from(bytes[3]);
|
||||
// safety pass-through of possible effect write
|
||||
if bytes[1] == 0xbc {
|
||||
self.write_bytes(bytes).await?;
|
||||
return Ok(());
|
||||
} else if self.supported_modes.contains(&mode) || bytes[1] == 0xba {
|
||||
let messages = [bytes];
|
||||
self.write_array_of_bytes(&messages).await?;
|
||||
config.set_field_from(bytes);
|
||||
config.write();
|
||||
return Ok(());
|
||||
}
|
||||
warn!("{:?} not supported", mode);
|
||||
Err(AuraError::NotSupported)
|
||||
}
|
||||
|
||||
/// Used to set a builtin mode and save the settings for it
|
||||
async fn reload_last_builtin(&mut self, config: &Config) -> Result<(), AuraError> {
|
||||
let mode_curr = config.current_mode[3];
|
||||
let mode = config
|
||||
.builtin_modes
|
||||
.get_field_from(mode_curr)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.write_bytes(&mode).await?;
|
||||
info!("Reloaded last built-in mode");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select next Aura effect
|
||||
///
|
||||
/// If the current effect is the last one then the effect selected wraps around to the first.
|
||||
async fn set_builtin(&mut self, config: &mut Config, index: usize) -> Result<(), AuraError> {
|
||||
let mode_next = config
|
||||
.builtin_modes
|
||||
.get_field_from(self.supported_modes[index].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
println!("{:X?}", &mode_next);
|
||||
self.set_and_save(&mode_next, config).await?;
|
||||
info!("Switched LED mode to {:#?}", self.supported_modes[index]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum FanLevel {
|
||||
Normal,
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
use crate::{config::Config, core::*, laptops::match_laptop};
|
||||
use crate::{
|
||||
config::Config,
|
||||
core::*,
|
||||
laptops::match_laptop,
|
||||
led_control::{AuraCommand, LedWriter},
|
||||
};
|
||||
|
||||
use dbus::{
|
||||
channel::Sender,
|
||||
nonblock::Process,
|
||||
tree::{Factory, MTSync, Method, MethodErr, Signal, Tree},
|
||||
};
|
||||
|
||||
use dbus_tokio::connection;
|
||||
use log::{error, info, warn};
|
||||
use rog_aura::{DBUS_IFACE, DBUS_PATH};
|
||||
@@ -46,7 +53,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
);
|
||||
|
||||
// Reload settings
|
||||
rogcore.reload(&mut config).await?;
|
||||
rogcore.fan_mode_reload(&mut config).await?;
|
||||
let mut led_writer = LedWriter::new(
|
||||
rogcore.get_raw_device_handle(),
|
||||
laptop.led_endpoint(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::config::Config;
|
||||
use crate::core::{AuraCommand, RogCore};
|
||||
use crate::{config::Config, core::RogCore, led_control::AuraCommand};
|
||||
use rog_aura::{error::AuraError, BuiltInModeByte};
|
||||
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
|
||||
use crate::virt_device::ConsumerKeys;
|
||||
|
||||
235
rog-core/src/led_control.rs
Normal file
235
rog-core/src/led_control.rs
Normal file
@@ -0,0 +1,235 @@
|
||||
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
||||
static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
|
||||
// Only these two packets must be 17 bytes
|
||||
static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 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;
|
||||
use log::{error, info, warn};
|
||||
use rog_aura::{aura_brightness_bytes, error::AuraError, BuiltInModeByte};
|
||||
use rusb::DeviceHandle;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::NonNull;
|
||||
use std::time::Duration;
|
||||
|
||||
pub enum AuraCommand {
|
||||
BrightInc,
|
||||
BrightDec,
|
||||
BuiltinNext,
|
||||
BuiltinPrev,
|
||||
WriteBytes(Vec<u8>),
|
||||
WriteEffect(Vec<Vec<u8>>),
|
||||
ReloadLast,
|
||||
}
|
||||
|
||||
/// UNSAFE: Must live as long as RogCore
|
||||
///
|
||||
/// Because we're holding a pointer to something that *may* go out of scope while the
|
||||
/// pointer is held. We're relying on access to struct to be behind a Mutex, and for behaviour
|
||||
/// that may cause invalididated pointer to cause the program to panic rather than continue.
|
||||
pub struct LedWriter<'d, C: 'd>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
handle: NonNull<DeviceHandle<C>>,
|
||||
bright_min_max: (u8, u8),
|
||||
supported_modes: Vec<BuiltInModeByte>,
|
||||
led_endpoint: u8,
|
||||
initialised: bool,
|
||||
_phantom: PhantomData<&'d DeviceHandle<C>>,
|
||||
}
|
||||
|
||||
/// UNSAFE
|
||||
unsafe impl<'d, C> Send for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
unsafe impl<'d, C> Sync for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
|
||||
impl<'d, C> LedWriter<'d, C>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
pub fn new(
|
||||
device_handle: NonNull<DeviceHandle<C>>,
|
||||
led_endpoint: u8,
|
||||
bright_min_max: (u8, u8),
|
||||
supported_modes: Vec<BuiltInModeByte>,
|
||||
) -> Self {
|
||||
LedWriter {
|
||||
handle: device_handle,
|
||||
led_endpoint,
|
||||
bright_min_max,
|
||||
supported_modes,
|
||||
initialised: false,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn do_command(
|
||||
&mut self,
|
||||
command: AuraCommand,
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
if !self.initialised {
|
||||
self.write_bytes(&LED_INIT1).await?;
|
||||
self.write_bytes(LED_INIT2.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT3).await?;
|
||||
self.write_bytes(LED_INIT4.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT5).await?;
|
||||
self.initialised = true;
|
||||
}
|
||||
|
||||
match command {
|
||||
AuraCommand::BrightInc => {
|
||||
let mut bright = config.brightness;
|
||||
if bright < self.bright_min_max.1 {
|
||||
bright += 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.set_and_save(&bytes, config).await?;
|
||||
info!("Increased LED brightness to {:#?}", bright);
|
||||
}
|
||||
}
|
||||
AuraCommand::BrightDec => {
|
||||
let mut bright = config.brightness;
|
||||
if bright > self.bright_min_max.0 {
|
||||
bright -= 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.set_and_save(&bytes, config).await?;
|
||||
info!("Decreased LED brightness to {:#?}", bright);
|
||||
}
|
||||
}
|
||||
AuraCommand::BuiltinNext => {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = self
|
||||
.supported_modes
|
||||
.binary_search(&mode_curr.into())
|
||||
.unwrap();
|
||||
let idx_next = if idx < self.supported_modes.len() - 1 {
|
||||
idx + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.set_builtin(config, idx_next).await?;
|
||||
}
|
||||
AuraCommand::BuiltinPrev => {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = self
|
||||
.supported_modes
|
||||
.binary_search(&mode_curr.into())
|
||||
.unwrap();
|
||||
let idx_next = if idx > 0 {
|
||||
idx - 1
|
||||
} else {
|
||||
self.supported_modes.len() - 1
|
||||
};
|
||||
self.set_builtin(config, idx_next).await?;
|
||||
}
|
||||
AuraCommand::WriteBytes(bytes) => self.set_and_save(&bytes, config).await?,
|
||||
AuraCommand::WriteEffect(effect) => self.write_effect(effect).await?,
|
||||
AuraCommand::ReloadLast => self.reload_last_builtin(&config).await?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Should only be used if the bytes you are writing are verified correct
|
||||
async fn write_bytes(&mut self, message: &[u8]) -> Result<(), AuraError> {
|
||||
match unsafe { self.handle.as_ref() }.write_interrupt(
|
||||
self.led_endpoint,
|
||||
message,
|
||||
Duration::from_millis(5),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write to led interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn write_array_of_bytes(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> {
|
||||
for message in messages {
|
||||
self.write_bytes(*message).await?;
|
||||
self.write_bytes(&LED_SET).await?;
|
||||
}
|
||||
// Changes won't persist unless apply is set
|
||||
self.write_bytes(&LED_APPLY).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
async fn write_effect(&self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> {
|
||||
for row in effect.iter() {
|
||||
match unsafe { self.handle.as_ref() }.write_interrupt(
|
||||
self.led_endpoint,
|
||||
row,
|
||||
Duration::from_millis(1),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write LED interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Used to set a builtin mode and save the settings for it
|
||||
async fn set_and_save(&mut self, bytes: &[u8], config: &mut Config) -> Result<(), AuraError> {
|
||||
let mode = BuiltInModeByte::from(bytes[3]);
|
||||
// safety pass-through of possible effect write
|
||||
if bytes[1] == 0xbc {
|
||||
self.write_bytes(bytes).await?;
|
||||
return Ok(());
|
||||
} else if self.supported_modes.contains(&mode) || bytes[1] == 0xba {
|
||||
let messages = [bytes];
|
||||
self.write_array_of_bytes(&messages).await?;
|
||||
config.set_field_from(bytes);
|
||||
config.write();
|
||||
return Ok(());
|
||||
}
|
||||
warn!("{:?} not supported", mode);
|
||||
Err(AuraError::NotSupported)
|
||||
}
|
||||
|
||||
/// Used to set a builtin mode and save the settings for it
|
||||
async fn reload_last_builtin(&mut self, config: &Config) -> Result<(), AuraError> {
|
||||
let mode_curr = config.current_mode[3];
|
||||
let mode = config
|
||||
.builtin_modes
|
||||
.get_field_from(mode_curr)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.write_bytes(&mode).await?;
|
||||
// Reload brightness too
|
||||
let bright = config.brightness;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.write_bytes(&bytes).await?;
|
||||
info!("Reloaded last used mode and brightness");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select next Aura effect
|
||||
///
|
||||
/// If the current effect is the last one then the effect selected wraps around to the first.
|
||||
async fn set_builtin(&mut self, config: &mut Config, index: usize) -> Result<(), AuraError> {
|
||||
let mode_next = config
|
||||
.builtin_modes
|
||||
.get_field_from(self.supported_modes[index].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
println!("{:X?}", &mode_next);
|
||||
self.set_and_save(&mode_next, config).await?;
|
||||
info!("Switched LED mode to {:#?}", self.supported_modes[index]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -7,5 +7,7 @@ mod core;
|
||||
pub mod daemon;
|
||||
/// Laptop matching to determine capabilities
|
||||
mod laptops;
|
||||
///
|
||||
mod led_control;
|
||||
/// A virtual "consumer device" to help emit the correct key codes
|
||||
mod virt_device;
|
||||
|
||||
@@ -7,7 +7,7 @@ use rog_aura::{
|
||||
AuraDbusWriter, LED_MSG_LEN,
|
||||
};
|
||||
|
||||
static VERSION: &'static str = "0.9.3";
|
||||
static VERSION: &'static str = "0.9.4";
|
||||
|
||||
#[derive(Debug, Options)]
|
||||
struct CLIStart {
|
||||
|
||||
Reference in New Issue
Block a user