diff --git a/Cargo.lock b/Cargo.lock index afb3b6da..fdb2f77f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,12 +33,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - [[package]] name = "atty" version = "0.2.14" @@ -452,7 +446,6 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" name = "rog-core" version = "0.3.2" dependencies = [ - "arrayvec", "dbus", "env_logger 0.7.1", "gumdrop", @@ -460,7 +453,6 @@ dependencies = [ "rog-lib", "serde", "serde_derive", - "uhid-fs", ] [[package]] @@ -476,6 +468,7 @@ dependencies = [ "sysfs-class", "thiserror", "toml", + "uhid-virt", ] [[package]] @@ -621,18 +614,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85f514e095d348c279b1e5cd76795082cf15bd59b93207832abe0b1d8fed236" -[[package]] -name = "uhid-fs" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5b307e0c404eb578300a18cd59a928445b1fa37d23b84332f9cc556f6ef3138" -dependencies = [ - "arrayvec", - "enumflags2", - "libc", - "uhid-sys", -] - [[package]] name = "uhid-sys" version = "1.0.0" @@ -642,6 +623,15 @@ dependencies = [ "bindgen", ] +[[package]] +name = "uhid-virt" +version = "0.0.2" +dependencies = [ + "enumflags2", + "libc", + "uhid-sys", +] + [[package]] name = "unicode-width" version = "0.1.7" diff --git a/rog-core/Cargo.toml b/rog-core/Cargo.toml index a1f1b6df..1289c13e 100644 --- a/rog-core/Cargo.toml +++ b/rog-core/Cargo.toml @@ -12,5 +12,3 @@ serde_derive = "1.0" log = "0.4" env_logger = "0.7" rog-lib = { path = "../rog-lib" } -uhid-fs = "0.0.1" -arrayvec = "0.5.1" \ No newline at end of file diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index e1762b07..0f0116b6 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -1,15 +1,13 @@ use crate::{DBUS_IFACE, DBUS_PATH}; -use arrayvec::*; use dbus::{ blocking::Connection, tree::{Factory, MethodErr}, }; use log::{error, info, warn}; -use rog_lib::core::*; +use rog_lib::core::RogCore; use std::error::Error; use std::time::Duration; use std::{cell::RefCell, rc::Rc}; -use uhid_fs::{Bus, CreateParams, UHIDDevice}; pub struct Daemon { rogcore: RogCore, @@ -87,24 +85,6 @@ impl Daemon { // We add the tree to the connection so that incoming method calls will be handled. tree.start_receive(&connection); - let mut rd_data = ArrayVec::new(); - CONSUMER.iter().for_each(|x| rd_data.try_push(*x).unwrap()); - - let virt = Rc::new(RefCell::new(VirtKeys { - device: UHIDDevice::try_new(CreateParams { - name: ArrayString::from("Virtual ROG buttons").unwrap(), - phys: ArrayString::from("").unwrap(), - uniq: ArrayString::from("").unwrap(), - bus: Bus::USB, - vendor: 0x0b05, - product: 0x1866, - version: 0, - country: 0, - rd_data, - }) - .unwrap(), - })); - let mut key_buf = [0u8; 32]; loop { connection @@ -124,13 +104,8 @@ impl Daemon { let laptop = borrowed_daemon.rogcore.laptop(); if let Some(_count) = read { - let virt = virt.clone(); laptop - .do_hotkey_action( - &mut rogcore, - key_buf[1], - Box::new(move |input| virt.borrow_mut().press(input)), - ) + .do_hotkey_action(&mut rogcore, key_buf[1]) .unwrap_or_else(|err| { warn!("{:?}", err); }); @@ -141,59 +116,3 @@ impl Daemon { } } } - -pub struct VirtKeys { - pub device: UHIDDevice, -} - -impl VirtKeys { - pub fn press(&mut self, key: u8) { - let mut bytes = [0u8; 8]; - bytes[0] = 0x02; - bytes[1] = key; - // email button - // bytes[1] = 0x8a; - // bytes[2] = 0x01; - let mut datavec = arrayvec::ArrayVec::new(); - bytes.iter().for_each(|x| datavec.try_push(*x).unwrap()); - - self.device.send_input(datavec.clone()).unwrap(); - datavec[1] = 0; - self.device.send_input(datavec).unwrap(); - } -} - -pub const CONSUMER: [u8; 25] = [ - 0x05, 0x0C, // Usage Page (Consumer) - 0x09, 0x01, // Usage (Consumer Control) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x02, // Report ID (2) - 0x19, 0x00, // Usage Minimum (Unassigned) - 0x2A, 0x3C, 0x02, // Usage Maximum (AC Format) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0x3C, 0x02, // Logical Maximum (572) - 0x75, 0x10, // Report Size (16) - 0x95, 0x02, // Report Count (2) - 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, -]; - -// Usage 04 for microphone -// Needs another Usage (80) for system control -// B5 for toggle int/ext display -// b2 for external -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?) -} diff --git a/rog-lib/Cargo.toml b/rog-lib/Cargo.toml index f663c2f8..efcc4b70 100644 --- a/rog-lib/Cargo.toml +++ b/rog-lib/Cargo.toml @@ -14,3 +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 diff --git a/rog-lib/src/core.rs b/rog-lib/src/core.rs index 9e5ce69f..e64118e2 100644 --- a/rog-lib/src/core.rs +++ b/rog-lib/src/core.rs @@ -10,6 +10,7 @@ use std::process::Command; use std::str::FromStr; use std::time::Duration; use sysfs_class::{Brightness, SysClass}; +use uhid_virt::{Bus, CreateParams, UHIDDevice}; pub const LED_MSG_LEN: usize = 17; static LED_INIT1: [u8; 2] = [0x5d, 0xb9]; @@ -39,6 +40,7 @@ pub struct RogCore { keys_endpoint: u8, config: Config, laptop: RefCell>, + virt_keys: VirtKeys, } impl RogCore { @@ -79,9 +81,14 @@ impl RogCore { keys_endpoint, config: Config::default().read(), laptop: RefCell::new(laptop), + virt_keys: VirtKeys::new(), }) } + pub fn virt_keys(&mut self) -> &mut VirtKeys { + &mut self.virt_keys + } + pub fn laptop(&self) -> Ref> { self.laptop.borrow() } @@ -307,3 +314,73 @@ impl FromStr for LedBrightness { } } } + +pub struct VirtKeys { + pub device: UHIDDevice, +} + +impl VirtKeys { + pub fn new() -> Self { + VirtKeys { + device: UHIDDevice::create(CreateParams { + name: String::from("Virtual ROG buttons"), + phys: String::from(""), + uniq: String::from(""), + bus: Bus::USB, + vendor: 0x0b05, + product: 0x1866, + version: 0, + country: 0, + rd_data: CONSUMER.to_vec(), + }) + .unwrap(), + } + } + + pub fn press(&mut self, key: u8) { + let mut bytes = [0u8; 8]; + bytes[0] = 0x02; + bytes[1] = key; + // email button + // bytes[1] = 0x8a; + // bytes[2] = 0x01; + self.device.write(&bytes).unwrap(); + bytes[1] = 0; + self.device.write(&bytes).unwrap(); + } +} + +pub const CONSUMER: [u8; 25] = [ + 0x05, 0x0C, // Usage Page (Consumer) + 0x09, 0x01, // Usage (Consumer Control) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x02, // Report ID (2) + 0x19, 0x00, // Usage Minimum (Unassigned) + 0x2A, 0x3C, 0x02, // Usage Maximum (AC Format) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0x3C, 0x02, // Logical Maximum (572) + 0x75, 0x10, // Report Size (16) + 0x95, 0x02, // Report Count (2) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, +]; + +// Usage 04 for microphone +// Needs another Usage (80) for system control +// B5 for toggle int/ext display +// b2 for external +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?) +} diff --git a/rog-lib/src/laptops.rs b/rog-lib/src/laptops.rs index 37341a3e..5a881e4f 100644 --- a/rog-lib/src/laptops.rs +++ b/rog-lib/src/laptops.rs @@ -23,12 +23,7 @@ pub fn match_laptop() -> Result, AuraError> { /// has 3 explicit groups: main, vol+media, and the ones that the Linux kernel doesn't /// map. pub trait Laptop { - fn do_hotkey_action( - &self, - core: &mut RogCore, - key_byte: u8, - virt: Box, - ) -> Result<(), AuraError>; + fn do_hotkey_action(&self, core: &mut RogCore, key_byte: u8) -> Result<(), AuraError>; fn hotkey_group_bytes(&self) -> &[u8]; fn led_iface_num(&self) -> u8; fn supported_modes(&self) -> &[BuiltInModeByte]; @@ -82,12 +77,7 @@ impl LaptopGX502GW { } } impl Laptop for LaptopGX502GW { - fn do_hotkey_action( - &self, - rogcore: &mut RogCore, - key_byte: u8, - virt: Box, - ) -> Result<(), AuraError> { + fn do_hotkey_action(&self, rogcore: &mut RogCore, key_byte: u8) -> Result<(), AuraError> { match GX502GWKeys::from(key_byte) { GX502GWKeys::LedBrightUp => { let mut bright = rogcore.config().brightness; @@ -159,7 +149,7 @@ impl Laptop for LaptopGX502GW { "Unmapped key, attempt to pass to virtual device: {:?}, {:X?}", &key_byte, &key_byte ); - virt(key_byte); + rogcore.virt_keys().press(key_byte); } } }