mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
unsafe pointery stuff
This commit is contained in:
444
src/core.rs
444
src/core.rs
@@ -42,9 +42,6 @@ static FAN_TYPE_2_PATH: &str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode
|
||||
/// - `LED_INIT4`
|
||||
pub(crate) struct RogCore {
|
||||
handle: DeviceHandle<rusb::GlobalContext>,
|
||||
initialised: bool,
|
||||
led_endpoint: u8,
|
||||
config: Config,
|
||||
virt_keys: VirtKeys,
|
||||
}
|
||||
|
||||
@@ -79,22 +76,19 @@ impl RogCore {
|
||||
|
||||
Ok(RogCore {
|
||||
handle: dev_handle,
|
||||
initialised: false,
|
||||
led_endpoint,
|
||||
config: Config::default().read(),
|
||||
virt_keys: VirtKeys::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn reload(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
let mode_curr = self.config.current_mode[3];
|
||||
let mode = self
|
||||
.config
|
||||
.builtin_modes
|
||||
.get_field_from(BuiltInModeByte::from(mode_curr).into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.aura_write_messages(&[&mode])?;
|
||||
pub(crate) async fn reload(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
// let mode_curr = self.config.current_mode[3];
|
||||
// let mode = self
|
||||
// .config
|
||||
// .builtin_modes
|
||||
// .get_field_from(BuiltInModeByte::from(mode_curr).into())
|
||||
// .unwrap()
|
||||
// .to_owned();
|
||||
// self.aura_write_messages(&[&mode])?;
|
||||
|
||||
let path = if Path::new(FAN_TYPE_1_PATH).exists() {
|
||||
FAN_TYPE_1_PATH
|
||||
@@ -105,8 +99,8 @@ impl RogCore {
|
||||
};
|
||||
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
file.write_all(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(self.config.fan_mode))?;
|
||||
file.write_all(format!("{:?}\n", config.fan_mode).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(config.fan_mode))?;
|
||||
info!("Reloaded last saved settings");
|
||||
Ok(())
|
||||
}
|
||||
@@ -128,174 +122,7 @@ impl RogCore {
|
||||
Err(AuraError::UsbError(rusb::Error::NoDevice))
|
||||
}
|
||||
|
||||
pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> {
|
||||
match self
|
||||
.handle
|
||||
.write_interrupt(self.led_endpoint, message, Duration::from_millis(2))
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to read keyboard interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> {
|
||||
if !self.initialised {
|
||||
self.aura_write(&LED_INIT1)?;
|
||||
self.aura_write(LED_INIT2.as_bytes())?;
|
||||
self.aura_write(&LED_INIT3)?;
|
||||
self.aura_write(LED_INIT4.as_bytes())?;
|
||||
self.aura_write(&LED_INIT5)?;
|
||||
self.initialised = true;
|
||||
}
|
||||
|
||||
for message in messages {
|
||||
self.aura_write(*message)?;
|
||||
self.aura_write(&LED_SET)?;
|
||||
}
|
||||
// Changes won't persist unless apply is set
|
||||
self.aura_write(&LED_APPLY)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
pub fn aura_write_effect(&mut self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> {
|
||||
for row in effect.iter() {
|
||||
self.aura_write(row)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
pub async fn async_write_effect(
|
||||
handle: &DeviceHandle<rusb::GlobalContext>,
|
||||
endpoint: u8,
|
||||
effect: Vec<Vec<u8>>,
|
||||
) -> Result<(), AuraError> {
|
||||
for row in effect.iter() {
|
||||
match handle.write_interrupt(endpoint, row, Duration::from_millis(2)) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write LED interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn aura_set_and_save(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
bytes: &[u8],
|
||||
) -> Result<(), AuraError> {
|
||||
let mode = BuiltInModeByte::from(bytes[3]);
|
||||
if bytes[1] == 0xbc {
|
||||
self.aura_write(bytes)?;
|
||||
return Ok(());
|
||||
} else if supported_modes.contains(&mode) || bytes[1] == 0xba {
|
||||
let messages = [bytes];
|
||||
self.aura_write_messages(&messages)?;
|
||||
self.config.set_field_from(bytes);
|
||||
self.config.write();
|
||||
return Ok(());
|
||||
}
|
||||
warn!("{:?} not supported", mode);
|
||||
Err(AuraError::NotSupported)
|
||||
}
|
||||
|
||||
pub(crate) fn aura_bright_inc(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
max_bright: u8,
|
||||
) -> Result<(), AuraError> {
|
||||
let mut bright = self.config.brightness;
|
||||
if bright < max_bright {
|
||||
bright += 1;
|
||||
self.config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.aura_set_and_save(supported_modes, &bytes)?;
|
||||
info!("Increased LED brightness to {:#?}", bright);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn aura_bright_dec(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
min_bright: u8,
|
||||
) -> Result<(), AuraError> {
|
||||
let mut bright = self.config.brightness;
|
||||
if bright > min_bright {
|
||||
bright -= 1;
|
||||
self.config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.aura_set_and_save(supported_modes, &bytes)?;
|
||||
info!("Decreased LED brightness to {:#?}", bright);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select next Aura effect
|
||||
///
|
||||
/// If the current effect is the last one then the effect selected wraps around to the first.
|
||||
pub(crate) fn aura_mode_next(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
) -> Result<(), AuraError> {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = self.config.current_mode[3];
|
||||
let idx = supported_modes.binary_search(&mode_curr.into()).unwrap();
|
||||
let idx_next = if idx < supported_modes.len() - 1 {
|
||||
idx + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let mode_next = self
|
||||
.config
|
||||
.builtin_modes
|
||||
.get_field_from(supported_modes[idx_next].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.aura_set_and_save(supported_modes, &mode_next)?;
|
||||
info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select previous Aura effect
|
||||
///
|
||||
/// If the current effect is the first one then the effect selected wraps around to the last.
|
||||
pub(crate) fn aura_mode_prev(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
) -> Result<(), AuraError> {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = self.config.current_mode[3];
|
||||
let idx = supported_modes.binary_search(&mode_curr.into()).unwrap();
|
||||
let idx_next = if idx > 0 {
|
||||
idx - 1
|
||||
} else {
|
||||
supported_modes.len() - 1
|
||||
};
|
||||
let mode_next = self
|
||||
.config
|
||||
.builtin_modes
|
||||
.get_field_from(supported_modes[idx_next].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.aura_set_and_save(supported_modes, &mode_next)?;
|
||||
info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn fan_mode_step(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
pub(crate) 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
|
||||
} else if Path::new(FAN_TYPE_2_PATH).exists() {
|
||||
@@ -319,8 +146,8 @@ impl RogCore {
|
||||
info!("Fan mode stepped to: {:#?}", FanLevel::from(n));
|
||||
fan_ctrl.write_all(format!("{:?}\n", n).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(n))?;
|
||||
self.config.fan_mode = n;
|
||||
self.config.write();
|
||||
config.fan_mode = n;
|
||||
config.write();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -435,60 +262,197 @@ impl RogCore {
|
||||
}
|
||||
}
|
||||
|
||||
// use sysfs_class::{Brightness, SysClass};
|
||||
// pub(crate) struct Backlight {
|
||||
// backlight: sysfs_class::Backlight,
|
||||
// step: u64,
|
||||
// max: u64,
|
||||
// }
|
||||
/// UNSAFE: 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(crate) struct LedWriter {
|
||||
handle: *mut DeviceHandle<rusb::GlobalContext>,
|
||||
led_endpoint: u8,
|
||||
initialised: bool,
|
||||
}
|
||||
|
||||
// impl Backlight {
|
||||
// pub(crate) fn new(id: &str) -> Result<Backlight, std::io::Error> {
|
||||
// for bl in sysfs_class::Backlight::iter() {
|
||||
// let bl = bl?;
|
||||
// if bl.id() == id {
|
||||
// let max = bl.max_brightness()?;
|
||||
// let step = max / 50;
|
||||
// return Ok(Backlight {
|
||||
// backlight: bl,
|
||||
// step,
|
||||
// max,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// panic!("Backlight not found")
|
||||
// }
|
||||
// pub(crate) fn step_up(&self) {
|
||||
// let brightness = self
|
||||
// .backlight
|
||||
// .brightness()
|
||||
// .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
// .unwrap();
|
||||
// if brightness + self.step <= self.max {
|
||||
// self.backlight
|
||||
// .set_brightness(brightness + self.step)
|
||||
// .map_or_else(
|
||||
// |err| warn!("Failed to increment backlight level: {}", err),
|
||||
// |_| {},
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// pub(crate) fn step_down(&self) {
|
||||
// let brightness = self
|
||||
// .backlight
|
||||
// .brightness()
|
||||
// .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
// .unwrap();
|
||||
// if brightness > self.step {
|
||||
// self.backlight
|
||||
// .set_brightness(brightness - self.step)
|
||||
// .map_or_else(
|
||||
// |err| warn!("Failed to increment backlight level: {}", err),
|
||||
// |_| {},
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
/// UNSAFE
|
||||
unsafe impl Send for LedWriter {}
|
||||
unsafe impl Sync for LedWriter {}
|
||||
|
||||
impl LedWriter {
|
||||
pub fn new(device_handle: *mut DeviceHandle<rusb::GlobalContext>, led_endpoint: u8) -> Self {
|
||||
LedWriter {
|
||||
handle: device_handle,
|
||||
led_endpoint,
|
||||
initialised: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> {
|
||||
let handle = unsafe { &*self.handle };
|
||||
match handle.write_interrupt(self.led_endpoint, message, Duration::from_millis(2)) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to read keyboard interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> {
|
||||
if !self.initialised {
|
||||
self.aura_write(&LED_INIT1)?;
|
||||
self.aura_write(LED_INIT2.as_bytes())?;
|
||||
self.aura_write(&LED_INIT3)?;
|
||||
self.aura_write(LED_INIT4.as_bytes())?;
|
||||
self.aura_write(&LED_INIT5)?;
|
||||
self.initialised = true;
|
||||
}
|
||||
|
||||
for message in messages {
|
||||
self.aura_write(*message)?;
|
||||
self.aura_write(&LED_SET)?;
|
||||
}
|
||||
// Changes won't persist unless apply is set
|
||||
self.aura_write(&LED_APPLY)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
pub fn aura_write_effect(&mut self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> {
|
||||
for row in effect.iter() {
|
||||
self.aura_write(row)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
pub async fn async_write_effect(
|
||||
&self,
|
||||
endpoint: u8,
|
||||
effect: Vec<Vec<u8>>,
|
||||
) -> Result<(), AuraError> {
|
||||
let handle = unsafe { &*self.handle };
|
||||
for row in effect.iter() {
|
||||
match handle.write_interrupt(endpoint, row, Duration::from_millis(2)) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write LED interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn aura_set_and_save(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
bytes: &[u8],
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
let mode = BuiltInModeByte::from(bytes[3]);
|
||||
if bytes[1] == 0xbc {
|
||||
self.aura_write(bytes)?;
|
||||
return Ok(());
|
||||
} else if supported_modes.contains(&mode) || bytes[1] == 0xba {
|
||||
let messages = [bytes];
|
||||
self.aura_write_messages(&messages)?;
|
||||
config.set_field_from(bytes);
|
||||
config.write();
|
||||
return Ok(());
|
||||
}
|
||||
warn!("{:?} not supported", mode);
|
||||
Err(AuraError::NotSupported)
|
||||
}
|
||||
|
||||
pub(crate) fn aura_bright_inc(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
max_bright: u8,
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
let mut bright = config.brightness;
|
||||
if bright < max_bright {
|
||||
bright += 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.aura_set_and_save(supported_modes, &bytes, config)?;
|
||||
info!("Increased LED brightness to {:#?}", bright);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn aura_bright_dec(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
min_bright: u8,
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
let mut bright = config.brightness;
|
||||
if bright > min_bright {
|
||||
bright -= 1;
|
||||
config.brightness = bright;
|
||||
let bytes = aura_brightness_bytes(bright);
|
||||
self.aura_set_and_save(supported_modes, &bytes, config)?;
|
||||
info!("Decreased LED brightness to {:#?}", bright);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select next Aura effect
|
||||
///
|
||||
/// If the current effect is the last one then the effect selected wraps around to the first.
|
||||
pub(crate) fn aura_mode_next(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = supported_modes.binary_search(&mode_curr.into()).unwrap();
|
||||
let idx_next = if idx < supported_modes.len() - 1 {
|
||||
idx + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let mode_next = config
|
||||
.builtin_modes
|
||||
.get_field_from(supported_modes[idx_next].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.aura_set_and_save(supported_modes, &mode_next, config)?;
|
||||
info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select previous Aura effect
|
||||
///
|
||||
/// If the current effect is the first one then the effect selected wraps around to the last.
|
||||
pub(crate) fn aura_mode_prev(
|
||||
&mut self,
|
||||
supported_modes: &[BuiltInModeByte],
|
||||
config: &mut Config,
|
||||
) -> Result<(), AuraError> {
|
||||
// TODO: different path for multi-zone (byte 2 controlled, non-zero)
|
||||
let mode_curr = config.current_mode[3];
|
||||
let idx = supported_modes.binary_search(&mode_curr.into()).unwrap();
|
||||
let idx_next = if idx > 0 {
|
||||
idx - 1
|
||||
} else {
|
||||
supported_modes.len() - 1
|
||||
};
|
||||
let mode_next = config
|
||||
.builtin_modes
|
||||
.get_field_from(supported_modes[idx_next].into())
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
self.aura_set_and_save(supported_modes, &mode_next, config)?;
|
||||
info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Options)]
|
||||
pub struct LedBrightness {
|
||||
|
||||
Reference in New Issue
Block a user