diff --git a/Cargo.lock b/Cargo.lock index fdb2f77f..7cd7329a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -626,6 +626,8 @@ dependencies = [ [[package]] name = "uhid-virt" version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c6ade685b787ea3b980b5a47bdc54ef3943adbd41a72ea5352a12a0dc9d821" dependencies = [ "enumflags2", "libc", diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index 0f0116b6..c3186ff1 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -4,19 +4,25 @@ use dbus::{ tree::{Factory, MethodErr}, }; use log::{error, info, warn}; -use rog_lib::core::RogCore; +use rog_lib::{ + core::RogCore, + laptops::{match_laptop, Laptop}, +}; use std::error::Error; use std::time::Duration; use std::{cell::RefCell, rc::Rc}; pub struct Daemon { rogcore: RogCore, + laptop: Box, } impl Daemon { pub fn new() -> Self { + let laptop = match_laptop(); + Daemon { - rogcore: RogCore::new().map_or_else( + rogcore: RogCore::new(&*laptop).map_or_else( |err| { error!("{}", err); panic!("{}", err); @@ -26,6 +32,7 @@ impl Daemon { daemon }, ), + laptop, } } @@ -60,8 +67,12 @@ impl Daemon { move |m| { // Reads the args passed to the method let bytes: Vec = m.msg.read1()?; - - match daemon.borrow_mut().rogcore.aura_set_and_save(&bytes[..]) + let supported = + Vec::from(daemon.borrow().laptop.supported_modes()); + match daemon + .borrow_mut() + .rogcore + .aura_set_and_save(&supported, &bytes[..]) { Ok(_) => { let s = format!("Wrote {:x?}", bytes); @@ -86,6 +97,7 @@ impl Daemon { tree.start_receive(&connection); let mut key_buf = [0u8; 32]; + let hotkey_group_bytes = Vec::from(daemon.borrow().laptop.hotkey_group_bytes()); loop { connection .process(Duration::from_millis(10)) @@ -96,15 +108,18 @@ impl Daemon { // READ KEYBOARD // TODO: this needs to move to a thread, but there is unsafety let mut borrowed_daemon = daemon.borrow_mut(); - match borrowed_daemon.rogcore.poll_keyboard(&mut key_buf) { + match borrowed_daemon + .rogcore + .poll_keyboard(&hotkey_group_bytes, &mut key_buf) + { Ok(read) => { // Doing this because the Laptop trait takes RogCore, but RogCore contains laptop // and this makes the borrow checker unhappy, but it's safe for this let mut rogcore = unsafe { &mut (*daemon.as_ptr()).rogcore }; - let laptop = borrowed_daemon.rogcore.laptop(); if let Some(_count) = read { - laptop + borrowed_daemon + .laptop .do_hotkey_action(&mut rogcore, key_buf[1]) .unwrap_or_else(|err| { warn!("{:?}", err); diff --git a/rog-lib/Cargo.toml b/rog-lib/Cargo.toml index efcc4b70..517068dc 100644 --- a/rog-lib/Cargo.toml +++ b/rog-lib/Cargo.toml @@ -14,4 +14,4 @@ sysfs-class = "0.1.2" aho-corasick = "0.7" thiserror = "1.0.15" log = "0.4" -uhid-virt = { path = "../../uhid-fs" } \ No newline at end of file +uhid-virt = "0.0.2" \ No newline at end of file diff --git a/rog-lib/src/core.rs b/rog-lib/src/core.rs index e64118e2..ea501c6a 100644 --- a/rog-lib/src/core.rs +++ b/rog-lib/src/core.rs @@ -5,7 +5,6 @@ use aho_corasick::AhoCorasick; use gumdrop::Options; use log::{debug, warn}; use rusb::DeviceHandle; -use std::cell::{Ref, RefCell}; use std::process::Command; use std::str::FromStr; use std::time::Duration; @@ -35,18 +34,14 @@ static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 pub struct RogCore { handle: DeviceHandle, initialised: bool, - led_interface_num: u8, - keys_interface_num: u8, + led_iface_num: u8, keys_endpoint: u8, config: Config, - laptop: RefCell>, virt_keys: VirtKeys, } impl RogCore { - pub fn new() -> Result { - let laptop = match_laptop()?; - + pub fn new(laptop: &dyn Laptop) -> Result { let mut dev_handle = RogCore::get_device(laptop.usb_vendor(), laptop.usb_product())?; dev_handle.set_active_configuration(0).unwrap_or(()); @@ -76,11 +71,9 @@ impl RogCore { Ok(RogCore { handle: dev_handle, initialised: false, - led_interface_num, - keys_interface_num, + led_iface_num: led_interface_num, keys_endpoint, config: Config::default().read(), - laptop: RefCell::new(laptop), virt_keys: VirtKeys::new(), }) } @@ -89,10 +82,6 @@ impl RogCore { &mut self.virt_keys } - pub fn laptop(&self) -> Ref> { - self.laptop.borrow() - } - pub fn config(&self) -> &Config { &self.config } @@ -123,7 +112,7 @@ impl RogCore { fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> { self.handle - .claim_interface(self.led_interface_num) + .claim_interface(self.led_iface_num) .map_err(|err| AuraError::UsbError(err))?; if !self.initialised { @@ -143,7 +132,7 @@ impl RogCore { self.aura_write(&LED_APPLY)?; self.handle - .release_interface(self.led_interface_num) + .release_interface(self.led_iface_num) .map_err(|err| AuraError::UsbError(err))?; Ok(()) } @@ -159,28 +148,35 @@ impl RogCore { Ok(bright) } - pub fn aura_set_and_save(&mut self, bytes: &[u8]) -> Result<(), AuraError> { + pub fn aura_set_and_save( + &mut self, + supported_modes: &[BuiltInModeByte], + bytes: &[u8], + ) -> Result<(), AuraError> { let mode = BuiltInModeByte::from(bytes[3]); - if self.laptop().supported_modes().contains(&mode) || bytes[1] == 0xba { + 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(); - debug!("Wrote: {:X?}", bytes); return Ok(()); } warn!("{:?} not supported", BuiltInModeByte::from(mode)); Err(AuraError::NotSupported) } - pub fn poll_keyboard(&mut self, buf: &mut [u8; 32]) -> Result, AuraError> { + pub fn poll_keyboard( + &mut self, + hotkey_group_bytes: &[u8], + buf: &mut [u8; 32], + ) -> Result, AuraError> { let res = match self .handle .read_interrupt(self.keys_endpoint, buf, Duration::from_micros(1)) { Ok(o) => { - if self.laptop.borrow().hotkey_group_bytes().contains(&buf[0]) { + if hotkey_group_bytes.contains(&buf[0]) { Ok(Some(o)) } else { Ok(None) @@ -337,15 +333,14 @@ impl VirtKeys { } } - pub fn press(&mut self, key: u8) { + pub fn press(&mut self, input: [u8; 2]) { let mut bytes = [0u8; 8]; bytes[0] = 0x02; - bytes[1] = key; - // email button - // bytes[1] = 0x8a; - // bytes[2] = 0x01; + bytes[1] = input[0]; + bytes[2] = input[1]; self.device.write(&bytes).unwrap(); bytes[1] = 0; + bytes[2] = 0; self.device.write(&bytes).unwrap(); } } @@ -369,18 +364,29 @@ pub const CONSUMER: [u8; 25] = [ // Needs another Usage (80) for system control // B5 for toggle int/ext display // b2 for external +#[derive(Copy, Clone)] pub enum ConsumerKeys { - VolUp = 0xe9, // USAGE (Volume up) - VolDown = 0xea, // USAGE (Volume down) - VolMute = 0xe2, // USAGE (Volume mute) - TrackNext = 0xb6, // USAGE (Track next) - PlayToggl = 0xcd, // USAGE (Play/Pause) - TrackPrev = 0xb5, // USAGE (Track prev) - TrackStop = 0xb7, - Power = 0x30, - Reset = 0x31, - Sleep = 0x32, // USAGE (Sleep) - BacklightInc = 0x6f, // USAGE (Backlight Inc) - BacklightDec = 0x70, // USAGE (Backlight Dec) - BacklightTog = 0x72, // USAGE (Backlight toggle? display toggle?) + VolUp = 0x0e9, // USAGE (Volume up) + VolDown = 0x0ea, // USAGE (Volume down) + VolMute = 0x0e2, // USAGE (Volume mute) + TrackNext = 0x0b6, // USAGE (Track next) + PlayToggl = 0x0cd, // USAGE (Play/Pause) + TrackPrev = 0x0b5, // USAGE (Track prev) + TrackStop = 0x0b7, + Power = 0x030, + Reset = 0x031, + Sleep = 0x032, // USAGE (Sleep) + BacklightInc = 0x06f, // USAGE (Backlight Inc) + BacklightDec = 0x070, // USAGE (Backlight Dec) + BacklightTog = 0x072, // USAGE (Backlight toggle? display toggle?) + Present = 0x188, +} + +impl From for [u8; 2] { + fn from(key: ConsumerKeys) -> Self { + let mut bytes = [0u8; 2]; + bytes[0] = key as u8; + bytes[1] = (key as u16 >> 8) as u8; + bytes + } } diff --git a/rog-lib/src/laptops.rs b/rog-lib/src/laptops.rs index 5a881e4f..dfddb481 100644 --- a/rog-lib/src/laptops.rs +++ b/rog-lib/src/laptops.rs @@ -1,14 +1,14 @@ use crate::aura::BuiltInModeByte; -use crate::core::{Backlight, RogCore}; +use crate::core::{Backlight, ConsumerKeys, RogCore}; use crate::error::AuraError; use log::info; -pub fn match_laptop() -> Result, AuraError> { +pub fn match_laptop() -> Box { let dmi = sysfs_class::DmiId::default(); - let board_name = dmi.board_name()?; + let board_name = dmi.board_name().unwrap(); match board_name.as_str() { // The hell does it have a \n for anyway? - "GX502GW\n" => Ok(Box::new(LaptopGX502GW::new())), + "GX502GW\n" => Box::new(LaptopGX502GW::new()), _ => { panic!("could not match laptop"); } @@ -77,6 +77,7 @@ impl LaptopGX502GW { } } impl Laptop for LaptopGX502GW { + // TODO: This really needs to match against u16 in future fn do_hotkey_action(&self, rogcore: &mut RogCore, key_byte: u8) -> Result<(), AuraError> { match GX502GWKeys::from(key_byte) { GX502GWKeys::LedBrightUp => { @@ -86,7 +87,7 @@ impl Laptop for LaptopGX502GW { rogcore.config_mut().brightness = bright; } let bytes = RogCore::aura_brightness_bytes(bright)?; - rogcore.aura_set_and_save(&bytes)?; + rogcore.aura_set_and_save(&self.supported_modes, &bytes)?; } GX502GWKeys::LedBrightDown => { let mut bright = rogcore.config().brightness; @@ -95,7 +96,7 @@ impl Laptop for LaptopGX502GW { rogcore.config_mut().brightness = bright; } let bytes = RogCore::aura_brightness_bytes(bright)?; - rogcore.aura_set_and_save(&bytes)?; + rogcore.aura_set_and_save(&self.supported_modes, &bytes)?; } GX502GWKeys::AuraNext => { let mut mode = rogcore.config().current_mode[3] + 1; @@ -106,7 +107,7 @@ impl Laptop for LaptopGX502GW { } rogcore.config_mut().current_mode[3] = mode; if let Some(bytes) = rogcore.config_mut().get_current() { - rogcore.aura_set_and_save(&bytes)?; + rogcore.aura_set_and_save(&self.supported_modes, &bytes)?; } } GX502GWKeys::AuraPrevious => { @@ -120,7 +121,7 @@ impl Laptop for LaptopGX502GW { } rogcore.config_mut().current_mode[3] = mode; if let Some(bytes) = rogcore.config_mut().get_current() { - rogcore.aura_set_and_save(&bytes)?; + rogcore.aura_set_and_save(&self.supported_modes, &bytes)?; rogcore.config().write(); } } @@ -139,7 +140,9 @@ impl Laptop for LaptopGX502GW { GX502GWKeys::MicToggle => {} GX502GWKeys::Fan => {} - GX502GWKeys::ScreenToggle => {} + GX502GWKeys::ScreenToggle => { + rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into()); + } GX502GWKeys::TouchPadToggle => {} GX502GWKeys::Rog => {} @@ -149,7 +152,7 @@ impl Laptop for LaptopGX502GW { "Unmapped key, attempt to pass to virtual device: {:?}, {:X?}", &key_byte, &key_byte ); - rogcore.virt_keys().press(key_byte); + rogcore.virt_keys().press([key_byte, 0]); } } }