diff --git a/Cargo.toml b/Cargo.toml index 4c9abf39..cba36ae8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rog-daemon" -version = "0.5.0" +version = "0.6.0" authors = ["Luke "] edition = "2018" diff --git a/README.md b/README.md index 5c885e3e..d55c1a2e 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Currently if no options are supplied for the CLI mode selection then a default i + [X] Screen off? Now mapped to a keycode but has no effect + [X] Screen brightness up/down + [ ] ROG key custom mapping (Can be done in source) - + [ ] Fan/Performance mode + + [X] Fan/Performance mode + [ ] Screen off?? + [X] Touchpad toggle (using a virtual keyboard to emit F21...) - [X] Capture and use hotkeys **Partially completed: aura keys work** @@ -73,7 +73,7 @@ Currently if no options are supplied for the CLI mode selection then a default i + [X] Volume + media controls work - [X] Logging - required for journalctl -As the daemon currently stands it should be enough for a functional system. +Fan mode toggling requires a newer kernel. I'm unsure when the patches required for it got merged - I've tested with the 5.6.6 kernel only. ## Other Laptops diff --git a/src/config.rs b/src/config.rs index 0727f286..56ffc8a5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,6 +7,7 @@ pub static CONFIG_PATH: &'static str = "/etc/rogcore.conf"; #[derive(Default, Deserialize, Serialize)] pub struct Config { + pub fan_mode: u8, pub brightness: u8, pub current_mode: [u8; 4], pub builtin_modes: BuiltInModeBytes, diff --git a/src/core.rs b/src/core.rs index 438aa554..0183c3d5 100644 --- a/src/core.rs +++ b/src/core.rs @@ -9,8 +9,12 @@ use crate::{ }; use aho_corasick::AhoCorasick; use gumdrop::Options; -use log::{error, warn}; +use log::{error, info, warn}; use rusb::DeviceHandle; +use std::error::Error; +use std::fs::OpenOptions; +use std::io::{Read, Write}; +use std::path::Path; use std::process::Command; use std::str::FromStr; use std::time::Duration; @@ -27,6 +31,9 @@ static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08]; 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: &'static str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy"; +static FAN_TYPE_2_PATH: &'static str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode"; + /// ROG device controller /// /// For the GX502GW the LED setup sequence looks like: @@ -79,6 +86,30 @@ impl RogCore { }) } + pub(crate) fn reload(&mut self) -> Result<(), Box> { + 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 + } 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(format!("{:?}\n", self.config.fan_mode).as_bytes())?; + + Ok(()) + } + pub(crate) fn virt_keys(&mut self) -> &mut VirtKeys { &mut self.virt_keys } @@ -312,6 +343,36 @@ impl RogCore { .to_owned(); self.aura_set_and_save(supported_modes, &mode_next) } + + pub(crate) fn fan_mode_step(&mut self) -> Result<(), Box> { + 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().read(true).write(true).open(path)?; + + let mut buf = String::new(); + if let Ok(_) = file.read_to_string(&mut buf) { + let mut n = u8::from_str_radix(&buf.trim_end(), 10)?; + info!("Current fan mode: {:?}", &n); + + if n < 2 { + n += 1; + } else { + n = 0; + } + + info!("Fan mode stepped to: {:?}", &n); + file.write(format!("{:?}\n", n).as_bytes())?; + self.config.fan_mode = n; + self.config.write(); + } + Ok(()) + } } pub(crate) struct Backlight { diff --git a/src/daemon.rs b/src/daemon.rs index 384c2d2f..8baf3af7 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -14,7 +14,7 @@ use std::time::Duration; pub fn start_daemon() -> Result<(), Box> { let laptop = match_laptop(); - let rogcore = RogCore::new(&*laptop).map_or_else( + let mut rogcore = RogCore::new(&*laptop).map_or_else( |err| { error!("{}", err); panic!("{}", err); @@ -24,6 +24,8 @@ pub fn start_daemon() -> Result<(), Box> { daemon }, ); + // Reload settings + rogcore.reload()?; let mut connection = Connection::new_system().map_or_else( |err| { diff --git a/src/laptops/gx502.rs b/src/laptops/gx502.rs index 2ea736fa..c44bbd04 100644 --- a/src/laptops/gx502.rs +++ b/src/laptops/gx502.rs @@ -4,7 +4,7 @@ use crate::error::AuraError; use crate::virt_device::ConsumerKeys; //use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState}; use super::Laptop; -use log::info; +use log::{info, warn}; pub(super) struct LaptopGX502 { usb_vendor: u16, @@ -107,7 +107,11 @@ impl LaptopGX502 { GX502Keys::Sleep => rogcore.suspend_with_systemd(), GX502Keys::AirplaneMode => rogcore.toggle_airplane_mode(), GX502Keys::MicToggle => {} - GX502Keys::Fan => {} + GX502Keys::Fan => { + rogcore.fan_mode_step().unwrap_or_else(|err| { + warn!("Couldn't toggle fan mode: {:?}", err); + }); + } GX502Keys::ScreenToggle => { rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into()); } diff --git a/src/main.rs b/src/main.rs index 903dd5d1..dbba98d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use env_logger::{Builder, Target}; use gumdrop::Options; use log::LevelFilter; -static VERSION: &'static str = "0.5.0"; +static VERSION: &'static str = "0.6.0"; #[derive(Debug, Options)] struct CLIStart {