Move DBUS and keyboard reads on to tokio

This greatly improves throughput of per-key LED effects.
Also add a cool-down timer in the main loop to adjust
thread speed and prevent it running at maximum speed.
This commit is contained in:
Luke
2020-04-26 22:28:25 +12:00
parent 13e736dbed
commit 8200dc85e6
8 changed files with 182 additions and 157 deletions

12
Cargo.lock generated
View File

@@ -24,17 +24,6 @@ dependencies = [
"winapi 0.3.8", "winapi 0.3.8",
] ]
[[package]]
name = "async-trait"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@@ -631,7 +620,6 @@ name = "rog-daemon"
version = "0.6.1" version = "0.6.1"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"async-trait",
"dbus", "dbus",
"dbus-tokio", "dbus-tokio",
"env_logger", "env_logger",

View File

@@ -29,5 +29,3 @@ log = "^0.4.8"
uhid-virt = "^0.0.4" uhid-virt = "^0.0.4"
#keycode = "0.3" #keycode = "0.3"
env_logger = "^0.7.1" env_logger = "^0.7.1"
async-trait = "0.1.30"

View File

@@ -46,7 +46,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// It takes each interrupt at least 1ms. 10ms to write complete block. Plus any extra // It takes each interrupt at least 1ms. 10ms to write complete block. Plus any extra
// penalty time such as read waits // penalty time such as read waits
let time = time::Duration::from_millis(1); // aim for 60 per second let time = time::Duration::from_millis(10); // aim for 100 per second
let row = KeyColourArray::get_init_msg(); let row = KeyColourArray::get_init_msg();
let msg = let msg =

View File

@@ -98,7 +98,7 @@ impl RogCore {
.get_field_from(BuiltInModeByte::from(mode_curr).into()) .get_field_from(BuiltInModeByte::from(mode_curr).into())
.unwrap() .unwrap()
.to_owned(); .to_owned();
self.aura_write_messages(&[&mode]).await?; self.aura_write_messages(&[&mode])?;
let path = if Path::new(FAN_TYPE_1_PATH).exists() { let path = if Path::new(FAN_TYPE_1_PATH).exists() {
FAN_TYPE_1_PATH FAN_TYPE_1_PATH
@@ -131,7 +131,7 @@ impl RogCore {
Err(AuraError::UsbError(rusb::Error::NoDevice)) Err(AuraError::UsbError(rusb::Error::NoDevice))
} }
pub async fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> { pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> {
match self match self
.handle .handle
.write_interrupt(self.led_endpoint, message, Duration::from_millis(1)) .write_interrupt(self.led_endpoint, message, Duration::from_millis(1))
@@ -145,31 +145,31 @@ impl RogCore {
Ok(()) Ok(())
} }
async fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> { fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> {
if !self.initialised { if !self.initialised {
self.aura_write(&LED_INIT1).await?; self.aura_write(&LED_INIT1)?;
self.aura_write(LED_INIT2.as_bytes()).await?; self.aura_write(LED_INIT2.as_bytes())?;
self.aura_write(&LED_INIT3).await?; self.aura_write(&LED_INIT3)?;
self.aura_write(LED_INIT4.as_bytes()).await?; self.aura_write(LED_INIT4.as_bytes())?;
self.aura_write(&LED_INIT5).await?; self.aura_write(&LED_INIT5)?;
self.initialised = true; self.initialised = true;
} }
for message in messages { for message in messages {
self.aura_write(*message).await?; self.aura_write(*message)?;
self.aura_write(&LED_SET).await?; self.aura_write(&LED_SET)?;
} }
// Changes won't persist unless apply is set // Changes won't persist unless apply is set
self.aura_write(&LED_APPLY).await?; self.aura_write(&LED_APPLY)?;
Ok(()) Ok(())
} }
/// Initialise and clear the keyboard for custom effects /// Initialise and clear the keyboard for custom effects
pub async fn aura_effect_init(&mut self) -> Result<(), AuraError> { pub fn aura_effect_init(&mut self) -> Result<(), AuraError> {
let mut init = [0u8; 64]; let mut init = [0u8; 64];
init[0] = 0x5d; // Report ID init[0] = 0x5d; // Report ID
init[1] = 0xbc; // Mode = custom??, 0xb3 is builtin init[1] = 0xbc; // Mode = custom??, 0xb3 is builtin
self.aura_write(&init).await?; self.aura_write(&init)?;
self.initialised = true; self.initialised = true;
Ok(()) Ok(())
@@ -178,25 +178,25 @@ impl RogCore {
/// Write an effect block /// Write an effect block
/// ///
/// `aura_effect_init` must be called any effect routine, and called only once. /// `aura_effect_init` must be called any effect routine, and called only once.
pub async fn aura_write_effect(&mut self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> { pub fn aura_write_effect(&mut self, effect: Vec<Vec<u8>>) -> Result<(), AuraError> {
for row in effect.iter() { for row in effect.iter() {
self.aura_write(row).await?; self.aura_write(row)?;
} }
Ok(()) Ok(())
} }
pub(crate) async fn aura_set_and_save( pub(crate) fn aura_set_and_save(
&mut self, &mut self,
supported_modes: &[BuiltInModeByte], supported_modes: &[BuiltInModeByte],
bytes: &[u8], bytes: &[u8],
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
let mode = BuiltInModeByte::from(bytes[3]); let mode = BuiltInModeByte::from(bytes[3]);
if bytes[1] == 0xbc { if bytes[1] == 0xbc {
self.aura_write(bytes).await?; self.aura_write(bytes)?;
return Ok(()); return Ok(());
} else if supported_modes.contains(&mode) || bytes[1] == 0xba { } else if supported_modes.contains(&mode) || bytes[1] == 0xba {
let messages = [bytes]; let messages = [bytes];
self.aura_write_messages(&messages).await?; self.aura_write_messages(&messages)?;
self.config.set_field_from(bytes); self.config.set_field_from(bytes);
self.config.write(); self.config.write();
return Ok(()); return Ok(());
@@ -205,7 +205,7 @@ impl RogCore {
Err(AuraError::NotSupported) Err(AuraError::NotSupported)
} }
pub(crate) async fn aura_bright_inc( pub(crate) fn aura_bright_inc(
&mut self, &mut self,
supported_modes: &[BuiltInModeByte], supported_modes: &[BuiltInModeByte],
max_bright: u8, max_bright: u8,
@@ -216,11 +216,11 @@ impl RogCore {
self.config.brightness = bright; self.config.brightness = bright;
} }
let bytes = aura_brightness_bytes(bright); let bytes = aura_brightness_bytes(bright);
self.aura_set_and_save(supported_modes, &bytes).await?; self.aura_set_and_save(supported_modes, &bytes)?;
Ok(()) Ok(())
} }
pub(crate) async fn aura_bright_dec( pub(crate) fn aura_bright_dec(
&mut self, &mut self,
supported_modes: &[BuiltInModeByte], supported_modes: &[BuiltInModeByte],
min_bright: u8, min_bright: u8,
@@ -231,14 +231,14 @@ impl RogCore {
self.config.brightness = bright; self.config.brightness = bright;
} }
let bytes = aura_brightness_bytes(bright); let bytes = aura_brightness_bytes(bright);
self.aura_set_and_save(supported_modes, &bytes).await?; self.aura_set_and_save(supported_modes, &bytes)?;
Ok(()) Ok(())
} }
/// Select next Aura effect /// Select next Aura effect
/// ///
/// If the current effect is the last one then the effect selected wraps around to the first. /// If the current effect is the last one then the effect selected wraps around to the first.
pub(crate) async fn aura_mode_next( pub(crate) fn aura_mode_next(
&mut self, &mut self,
supported_modes: &[BuiltInModeByte], supported_modes: &[BuiltInModeByte],
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
@@ -256,7 +256,7 @@ impl RogCore {
.get_field_from(supported_modes[idx_next].into()) .get_field_from(supported_modes[idx_next].into())
.unwrap() .unwrap()
.to_owned(); .to_owned();
self.aura_set_and_save(supported_modes, &mode_next).await?; self.aura_set_and_save(supported_modes, &mode_next)?;
info!("Switched LED mode to {:#?}", supported_modes[idx_next]); info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
Ok(()) Ok(())
} }
@@ -264,7 +264,7 @@ impl RogCore {
/// Select previous Aura effect /// Select previous Aura effect
/// ///
/// If the current effect is the first one then the effect selected wraps around to the last. /// If the current effect is the first one then the effect selected wraps around to the last.
pub(crate) async fn aura_mode_prev( pub(crate) fn aura_mode_prev(
&mut self, &mut self,
supported_modes: &[BuiltInModeByte], supported_modes: &[BuiltInModeByte],
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
@@ -282,7 +282,7 @@ impl RogCore {
.get_field_from(supported_modes[idx_next].into()) .get_field_from(supported_modes[idx_next].into())
.unwrap() .unwrap()
.to_owned(); .to_owned();
self.aura_set_and_save(supported_modes, &mode_next).await?; self.aura_set_and_save(supported_modes, &mode_next)?;
info!("Switched LED mode to {:#?}", supported_modes[idx_next]); info!("Switched LED mode to {:#?}", supported_modes[idx_next]);
Ok(()) Ok(())
} }
@@ -322,12 +322,13 @@ impl RogCore {
/// ///
/// `report_filter_bytes` is used to filter the data read from the interupt so /// `report_filter_bytes` is used to filter the data read from the interupt so
/// only the relevant byte array is returned. /// only the relevant byte array is returned.
pub(crate) async fn poll_keyboard(&mut self, report_filter_bytes: &[u8]) -> Option<[u8; 32]> { pub(crate) async fn poll_keyboard(
handle: &DeviceHandle<rusb::GlobalContext>,
endpoint: u8,
report_filter_bytes: Vec<u8>,
) -> Option<[u8; 32]> {
let mut buf = [0u8; 32]; let mut buf = [0u8; 32];
match self match handle.read_interrupt(endpoint, &mut buf, Duration::from_millis(200)) {
.handle
.read_interrupt(self.keys_endpoint, &mut buf, Duration::from_millis(50))
{
Ok(_) => { Ok(_) => {
if report_filter_bytes.contains(&buf[0]) { if report_filter_bytes.contains(&buf[0]) {
return Some(buf); return Some(buf);
@@ -341,6 +342,11 @@ impl RogCore {
None None
} }
pub(crate) fn get_raw_device_handle(&mut self) -> *mut DeviceHandle<rusb::GlobalContext> {
// Breaking every damn lifetime guarantee rust gives us
&mut self.handle as *mut DeviceHandle<rusb::GlobalContext>
}
/// A direct call to systemd to suspend the PC. /// A direct call to systemd to suspend the PC.
/// ///
/// This avoids desktop environments being required to handle it /// This avoids desktop environments being required to handle it

View File

@@ -12,7 +12,7 @@ use dbus_tokio::connection;
use log::{error, info}; use log::{error, info};
use std::error::Error; use std::error::Error;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::{Duration, Instant};
pub async fn start_daemon() -> Result<(), Box<dyn Error>> { pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
let laptop = match_laptop(); let laptop = match_laptop();
@@ -28,7 +28,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
); );
// Reload settings // Reload settings
rogcore.reload().await?; rogcore.reload().await?;
println!("RELOADED"); info!("Reloaded last saved settings");
let (resource, connection) = connection::new_system_sync()?; let (resource, connection) = connection::new_system_sync()?;
tokio::spawn(async { tokio::spawn(async {
@@ -36,11 +36,9 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
panic!("Lost connection to D-Bus: {}", err); panic!("Lost connection to D-Bus: {}", err);
}); });
println!("CONN REQUEST");
connection connection
.request_name(DBUS_IFACE, false, true, false) .request_name(DBUS_IFACE, false, true, false)
.await?; .await?;
println!("CONN REQUEST DONE");
let factory = Factory::new_sync::<()>(); let factory = Factory::new_sync::<()>();
@@ -127,6 +125,27 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
tree.start_receive_send(&*connection); tree.start_receive_send(&*connection);
let supported = Vec::from(laptop.supported_modes()); let supported = Vec::from(laptop.supported_modes());
let key_buf: Arc<Mutex<Option<[u8; 32]>>> = Arc::new(Mutex::new(None));
let handle = unsafe { &*(rogcore.get_raw_device_handle()) };
let endpoint = laptop.key_endpoint();
let report_filter_bytes = laptop.key_filter().to_owned();
let key_buf1 = key_buf.clone();
// This is *not* safe
tokio::spawn(async move {
loop {
let data = RogCore::poll_keyboard(handle, endpoint, report_filter_bytes.clone()).await;
if let Some(stuff) = data {
if let Ok(mut lock) = key_buf1.lock() {
lock.replace(stuff);
}
}
}
});
// When any action occurs this time is reset
let mut time_mark = Instant::now();
loop { loop {
// Timing is such that: // Timing is such that:
// - interrupt write is minimum 1ms (sometimes lower) // - interrupt write is minimum 1ms (sometimes lower)
@@ -143,26 +162,43 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
if let Ok(mut lock) = input.try_lock() { if let Ok(mut lock) = input.try_lock() {
if let Some(bytes) = &*lock { if let Some(bytes) = &*lock {
// It takes up to 20 milliseconds to write a complete colour block here // It takes up to 20 milliseconds to write a complete colour block here
rogcore.aura_set_and_save(&supported, &bytes).await?; rogcore.aura_set_and_save(&supported, &bytes)?;
*lock = None; *lock = None;
time_mark = Instant::now();
} }
} }
if let Ok(mut lock) = effect.try_lock() { if let Ok(mut lock) = effect.lock() {
if lock.is_some() { if lock.is_some() {
let effect = lock.take(); let effect = lock.take();
rogcore.aura_write_effect(effect.unwrap()).await?; rogcore.aura_write_effect(effect.unwrap())?;
time_mark = Instant::now();
} }
} }
match laptop.run(&mut rogcore).await { if let Ok(mut lock) = key_buf.try_lock() {
Ok(_) => {} if let Some(bytes) = *lock {
Err(err) => { // this takes at least 10ms per colour block
error!("{:?}", err); match laptop.run(&mut rogcore, bytes) {
panic!("Force crash for systemd to restart service") Ok(_) => {}
Err(err) => {
error!("{:?}", err);
panic!("Force crash for systemd to restart service")
}
}
*lock = None;
time_mark = Instant::now();
} }
} }
// When using an effect gen, 17-20ms is the min/max time to account for.
// If DBUS didn't take so long we could get this down to 11-12ms. let now = Instant::now();
// Cool-down steps
if now.duration_since(time_mark).as_millis() > 500 {
std::thread::sleep(Duration::from_millis(100));
} else if now.duration_since(time_mark).as_millis() > 20 {
std::thread::sleep(Duration::from_millis(20));
} else {
std::thread::sleep(Duration::from_micros(400));
}
} }
} }

View File

@@ -47,44 +47,42 @@ impl LaptopGL753 {
} }
impl LaptopGL753 { impl LaptopGL753 {
async fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { fn do_keypress_actions(
if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes).await { &self,
match GL753Keys::from(key_buf[1]) { rogcore: &mut RogCore,
GL753Keys::LedBrightUp => { key_buf: [u8; 32],
rogcore ) -> Result<(), AuraError> {
.aura_bright_inc(&self.supported_modes, self.max_led_bright) match GL753Keys::from(key_buf[1]) {
.await?; GL753Keys::LedBrightUp => {
} rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?;
GL753Keys::LedBrightDown => { }
rogcore GL753Keys::LedBrightDown => {
.aura_bright_dec(&self.supported_modes, self.min_led_bright) rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
.await?; }
} GL753Keys::ScreenBrightUp => self.backlight.step_up(),
GL753Keys::ScreenBrightUp => self.backlight.step_up(), GL753Keys::ScreenBrightDown => self.backlight.step_down(),
GL753Keys::ScreenBrightDown => self.backlight.step_down(), GL753Keys::Sleep => rogcore.suspend_with_systemd(),
GL753Keys::Sleep => rogcore.suspend_with_systemd(), GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(), GL753Keys::ScreenToggle => {
GL753Keys::ScreenToggle => { rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into()); }
} GL753Keys::TouchPadToggle => {
GL753Keys::TouchPadToggle => { let mut key = [0u8; 32];
let mut key = [0u8; 32]; key[0] = 0x01;
key[0] = 0x01; key[3] = 0x070;
key[3] = 0x070; rogcore.virt_keys().press(key);
rogcore.virt_keys().press(key); }
} GL753Keys::Rog => {
GL753Keys::Rog => { let mut key = [0u8; 32];
let mut key = [0u8; 32]; key[0] = 0x01;
key[0] = 0x01; key[3] = 0x68; // XF86Tools? F13
key[3] = 0x68; // XF86Tools? F13 rogcore.virt_keys().press(key);
rogcore.virt_keys().press(key); }
} GL753Keys::None => {
GL753Keys::None => { if key_buf[0] != 0x5A {
if key_buf[0] != 0x5A { info!("Unmapped key array: {:X?}", &key_buf);
info!("Unmapped key array: {:X?}", &key_buf); info!("Attempting passthrough: {:X?}", &key_buf[1]);
info!("Attempting passthrough: {:X?}", &key_buf[1]); rogcore.virt_keys().press(key_buf);
rogcore.virt_keys().press(key_buf);
}
} }
} }
} }
@@ -92,11 +90,9 @@ impl LaptopGL753 {
} }
} }
use async_trait::async_trait;
#[async_trait]
impl Laptop for LaptopGL753 { impl Laptop for LaptopGL753 {
async fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { fn run(&self, rogcore: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError> {
self.do_keypress_actions(rogcore).await self.do_keypress_actions(rogcore, key_buf)
} }
fn led_endpoint(&self) -> u8 { fn led_endpoint(&self) -> u8 {
self.led_endpoint self.led_endpoint
@@ -104,6 +100,9 @@ impl Laptop for LaptopGL753 {
fn key_endpoint(&self) -> u8 { fn key_endpoint(&self) -> u8 {
self.key_endpoint self.key_endpoint
} }
fn key_filter(&self) -> &[u8] {
&self.report_filter_bytes
}
fn usb_vendor(&self) -> u16 { fn usb_vendor(&self) -> u16 {
self.usb_vendor self.usb_vendor
} }

View File

@@ -89,53 +89,51 @@ impl LaptopGX502 {
} }
impl LaptopGX502 { impl LaptopGX502 {
async fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { fn do_keypress_actions(
if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes).await { &self,
match GX502Keys::from(key_buf[1]) { rogcore: &mut RogCore,
GX502Keys::LedBrightUp => { key_buf: [u8; 32],
rogcore ) -> Result<(), AuraError> {
.aura_bright_inc(&self.supported_modes, self.max_led_bright) match GX502Keys::from(key_buf[1]) {
.await?; GX502Keys::LedBrightUp => {
} rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?;
GX502Keys::LedBrightDown => { }
rogcore GX502Keys::LedBrightDown => {
.aura_bright_dec(&self.supported_modes, self.min_led_bright) rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
.await?; }
} GX502Keys::AuraNext => rogcore.aura_mode_next(&self.supported_modes)?,
GX502Keys::AuraNext => rogcore.aura_mode_next(&self.supported_modes).await?, GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&self.supported_modes)?,
GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&self.supported_modes).await?, GX502Keys::ScreenBrightUp => self.backlight.step_up(),
GX502Keys::ScreenBrightUp => self.backlight.step_up(), GX502Keys::ScreenBrightDown => self.backlight.step_down(),
GX502Keys::ScreenBrightDown => self.backlight.step_down(), GX502Keys::Sleep => rogcore.suspend_with_systemd(),
GX502Keys::Sleep => rogcore.suspend_with_systemd(), GX502Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GX502Keys::AirplaneMode => rogcore.toggle_airplane_mode(), GX502Keys::MicToggle => {}
GX502Keys::MicToggle => {} GX502Keys::Fan => {
GX502Keys::Fan => { rogcore.fan_mode_step().unwrap_or_else(|err| {
rogcore.fan_mode_step().unwrap_or_else(|err| { warn!("Couldn't toggle fan mode: {:?}", err);
warn!("Couldn't toggle fan mode: {:?}", err); });
}); }
} GX502Keys::ScreenToggle => {
GX502Keys::ScreenToggle => { rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into()); }
} GX502Keys::TouchPadToggle => {
GX502Keys::TouchPadToggle => { let mut key = [0u8; 32];
let mut key = [0u8; 32]; key[0] = 0x01;
key[0] = 0x01; key[3] = 0x070;
key[3] = 0x070; rogcore.virt_keys().press(key);
rogcore.virt_keys().press(key); }
} GX502Keys::Rog => {
GX502Keys::Rog => { //rogcore.aura_effect_init()?;
//rogcore.aura_effect_init()?; //rogcore.aura_write_effect(&self.per_key_led)?;
//rogcore.aura_write_effect(&self.per_key_led)?; // let mut key = [0u8; 32];
// let mut key = [0u8; 32]; // key[0] = 0x01;
// key[0] = 0x01; // key[3] = 0x68; // XF86Tools? F13
// key[3] = 0x68; // XF86Tools? F13 // rogcore.virt_keys().press(key);
// rogcore.virt_keys().press(key); }
} GX502Keys::None => {
GX502Keys::None => { if key_buf[0] != 0x5A {
if key_buf[0] != 0x5A { info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]); rogcore.virt_keys().press(key_buf);
rogcore.virt_keys().press(key_buf);
}
} }
} }
} }
@@ -143,11 +141,9 @@ impl LaptopGX502 {
} }
} }
use async_trait::async_trait;
#[async_trait]
impl Laptop for LaptopGX502 { impl Laptop for LaptopGX502 {
async fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { fn run(&self, rogcore: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError> {
self.do_keypress_actions(rogcore).await self.do_keypress_actions(rogcore, key_buf)
} }
fn led_endpoint(&self) -> u8 { fn led_endpoint(&self) -> u8 {
self.led_endpoint self.led_endpoint
@@ -155,6 +151,9 @@ impl Laptop for LaptopGX502 {
fn key_endpoint(&self) -> u8 { fn key_endpoint(&self) -> u8 {
self.key_endpoint self.key_endpoint
} }
fn key_filter(&self) -> &[u8] {
&self.report_filter_bytes
}
fn usb_vendor(&self) -> u16 { fn usb_vendor(&self) -> u16 {
self.usb_vendor self.usb_vendor
} }

View File

@@ -1,7 +1,6 @@
use crate::aura::BuiltInModeByte; use crate::aura::BuiltInModeByte;
use crate::core::RogCore; use crate::core::RogCore;
use crate::error::AuraError; use crate::error::AuraError;
use async_trait::async_trait;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState}; //use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
use log::info; use log::info;
@@ -63,13 +62,13 @@ pub(crate) fn match_laptop() -> Box<dyn Laptop> {
/// ///
/// If using the `keycode` crate to build keyboard input, the report must be prefixed /// If using the `keycode` crate to build keyboard input, the report must be prefixed
/// with the report ID (usually `0x01` for the virtual keyboard). /// with the report ID (usually `0x01` for the virtual keyboard).
#[async_trait]
pub(crate) trait Laptop { pub(crate) trait Laptop {
fn board_name(&self) -> &str; fn board_name(&self) -> &str;
fn prod_family(&self) -> &str; fn prod_family(&self) -> &str;
async fn run(&self, core: &mut RogCore) -> Result<(), AuraError>; fn run(&self, core: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError>;
fn led_endpoint(&self) -> u8; fn led_endpoint(&self) -> u8;
fn key_endpoint(&self) -> u8; fn key_endpoint(&self) -> u8;
fn key_filter(&self) -> &[u8];
fn usb_vendor(&self) -> u16; fn usb_vendor(&self) -> u16;
fn usb_product(&self) -> u16; fn usb_product(&self) -> u16;
fn supported_modes(&self) -> &[BuiltInModeByte]; fn supported_modes(&self) -> &[BuiltInModeByte];