Better handling

This commit is contained in:
Luke
2020-04-20 20:56:49 +12:00
parent a78b3ffd84
commit 21f89807d0
6 changed files with 93 additions and 118 deletions

30
Cargo.lock generated
View File

@@ -33,12 +33,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@@ -452,7 +446,6 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
name = "rog-core" name = "rog-core"
version = "0.3.2" version = "0.3.2"
dependencies = [ dependencies = [
"arrayvec",
"dbus", "dbus",
"env_logger 0.7.1", "env_logger 0.7.1",
"gumdrop", "gumdrop",
@@ -460,7 +453,6 @@ dependencies = [
"rog-lib", "rog-lib",
"serde", "serde",
"serde_derive", "serde_derive",
"uhid-fs",
] ]
[[package]] [[package]]
@@ -476,6 +468,7 @@ dependencies = [
"sysfs-class", "sysfs-class",
"thiserror", "thiserror",
"toml", "toml",
"uhid-virt",
] ]
[[package]] [[package]]
@@ -621,18 +614,6 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85f514e095d348c279b1e5cd76795082cf15bd59b93207832abe0b1d8fed236" 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]] [[package]]
name = "uhid-sys" name = "uhid-sys"
version = "1.0.0" version = "1.0.0"
@@ -642,6 +623,15 @@ dependencies = [
"bindgen", "bindgen",
] ]
[[package]]
name = "uhid-virt"
version = "0.0.2"
dependencies = [
"enumflags2",
"libc",
"uhid-sys",
]
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.7" version = "0.1.7"

View File

@@ -12,5 +12,3 @@ serde_derive = "1.0"
log = "0.4" log = "0.4"
env_logger = "0.7" env_logger = "0.7"
rog-lib = { path = "../rog-lib" } rog-lib = { path = "../rog-lib" }
uhid-fs = "0.0.1"
arrayvec = "0.5.1"

View File

@@ -1,15 +1,13 @@
use crate::{DBUS_IFACE, DBUS_PATH}; use crate::{DBUS_IFACE, DBUS_PATH};
use arrayvec::*;
use dbus::{ use dbus::{
blocking::Connection, blocking::Connection,
tree::{Factory, MethodErr}, tree::{Factory, MethodErr},
}; };
use log::{error, info, warn}; use log::{error, info, warn};
use rog_lib::core::*; use rog_lib::core::RogCore;
use std::error::Error; use std::error::Error;
use std::time::Duration; use std::time::Duration;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use uhid_fs::{Bus, CreateParams, UHIDDevice};
pub struct Daemon { pub struct Daemon {
rogcore: RogCore, rogcore: RogCore,
@@ -87,24 +85,6 @@ impl Daemon {
// We add the tree to the connection so that incoming method calls will be handled. // We add the tree to the connection so that incoming method calls will be handled.
tree.start_receive(&connection); 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]; let mut key_buf = [0u8; 32];
loop { loop {
connection connection
@@ -124,13 +104,8 @@ impl Daemon {
let laptop = borrowed_daemon.rogcore.laptop(); let laptop = borrowed_daemon.rogcore.laptop();
if let Some(_count) = read { if let Some(_count) = read {
let virt = virt.clone();
laptop laptop
.do_hotkey_action( .do_hotkey_action(&mut rogcore, key_buf[1])
&mut rogcore,
key_buf[1],
Box::new(move |input| virt.borrow_mut().press(input)),
)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
warn!("{:?}", err); warn!("{:?}", err);
}); });
@@ -141,59 +116,3 @@ impl Daemon {
} }
} }
} }
pub struct VirtKeys<T: std::io::Write + std::io::Read> {
pub device: UHIDDevice<T>,
}
impl<T: std::io::Write + std::io::Read> VirtKeys<T> {
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?)
}

View File

@@ -14,3 +14,4 @@ sysfs-class = "0.1.2"
aho-corasick = "0.7" aho-corasick = "0.7"
thiserror = "1.0.15" thiserror = "1.0.15"
log = "0.4" log = "0.4"
uhid-virt = { path = "../../uhid-fs" }

View File

@@ -10,6 +10,7 @@ use std::process::Command;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use sysfs_class::{Brightness, SysClass}; use sysfs_class::{Brightness, SysClass};
use uhid_virt::{Bus, CreateParams, UHIDDevice};
pub const LED_MSG_LEN: usize = 17; pub const LED_MSG_LEN: usize = 17;
static LED_INIT1: [u8; 2] = [0x5d, 0xb9]; static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
@@ -39,6 +40,7 @@ pub struct RogCore {
keys_endpoint: u8, keys_endpoint: u8,
config: Config, config: Config,
laptop: RefCell<Box<dyn Laptop>>, laptop: RefCell<Box<dyn Laptop>>,
virt_keys: VirtKeys,
} }
impl RogCore { impl RogCore {
@@ -79,9 +81,14 @@ impl RogCore {
keys_endpoint, keys_endpoint,
config: Config::default().read(), config: Config::default().read(),
laptop: RefCell::new(laptop), 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<Box<dyn Laptop>> { pub fn laptop(&self) -> Ref<Box<dyn Laptop>> {
self.laptop.borrow() self.laptop.borrow()
} }
@@ -307,3 +314,73 @@ impl FromStr for LedBrightness {
} }
} }
} }
pub struct VirtKeys {
pub device: UHIDDevice<std::fs::File>,
}
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?)
}

View File

@@ -23,12 +23,7 @@ pub fn match_laptop() -> Result<Box<dyn Laptop>, AuraError> {
/// has 3 explicit groups: main, vol+media, and the ones that the Linux kernel doesn't /// has 3 explicit groups: main, vol+media, and the ones that the Linux kernel doesn't
/// map. /// map.
pub trait Laptop { pub trait Laptop {
fn do_hotkey_action( fn do_hotkey_action(&self, core: &mut RogCore, key_byte: u8) -> Result<(), AuraError>;
&self,
core: &mut RogCore,
key_byte: u8,
virt: Box<dyn Fn(u8)>,
) -> Result<(), AuraError>;
fn hotkey_group_bytes(&self) -> &[u8]; fn hotkey_group_bytes(&self) -> &[u8];
fn led_iface_num(&self) -> u8; fn led_iface_num(&self) -> u8;
fn supported_modes(&self) -> &[BuiltInModeByte]; fn supported_modes(&self) -> &[BuiltInModeByte];
@@ -82,12 +77,7 @@ impl LaptopGX502GW {
} }
} }
impl Laptop for LaptopGX502GW { impl Laptop for LaptopGX502GW {
fn do_hotkey_action( fn do_hotkey_action(&self, rogcore: &mut RogCore, key_byte: u8) -> Result<(), AuraError> {
&self,
rogcore: &mut RogCore,
key_byte: u8,
virt: Box<dyn Fn(u8)>,
) -> Result<(), AuraError> {
match GX502GWKeys::from(key_byte) { match GX502GWKeys::from(key_byte) {
GX502GWKeys::LedBrightUp => { GX502GWKeys::LedBrightUp => {
let mut bright = rogcore.config().brightness; let mut bright = rogcore.config().brightness;
@@ -159,7 +149,7 @@ impl Laptop for LaptopGX502GW {
"Unmapped key, attempt to pass to virtual device: {:?}, {:X?}", "Unmapped key, attempt to pass to virtual device: {:?}, {:X?}",
&key_byte, &key_byte &key_byte, &key_byte
); );
virt(key_byte); rogcore.virt_keys().press(key_byte);
} }
} }
} }