From 607e1fb14c26cb5f8881113b09a95063a199104d Mon Sep 17 00:00:00 2001 From: Jan Trefil <8711792+htrefil@users.noreply.github.com> Date: Sat, 2 Dec 2023 14:22:46 +0100 Subject: [PATCH] Add support for key autorepeat (EV_REP - REP_DELAY and REP_PERIOD) --- rkvm-client/src/client.rs | 4 +++ rkvm-input/src/interceptor.rs | 11 +++++-- rkvm-input/src/interceptor/caps.rs | 48 ++++++++++++++++++++++++++++++ rkvm-input/src/writer.rs | 46 ++++++++++++++++++++++++++++ rkvm-net/src/lib.rs | 2 ++ rkvm-net/src/version.rs | 2 +- rkvm-server/src/server.rs | 9 ++++++ 7 files changed, 119 insertions(+), 3 deletions(-) diff --git a/rkvm-client/src/client.rs b/rkvm-client/src/client.rs index d7771d7..9cefbf1 100644 --- a/rkvm-client/src/client.rs +++ b/rkvm-client/src/client.rs @@ -123,6 +123,8 @@ pub async fn run( rel, abs, keys, + delay, + period, } => { let entry = writers.entry(id); if let Entry::Occupied(_) = entry { @@ -141,6 +143,8 @@ pub async fn run( .rel(rel)? .abs(abs)? .key(keys)? + .delay(delay)? + .period(period)? .build() .await } diff --git a/rkvm-input/src/interceptor.rs b/rkvm-input/src/interceptor.rs index 2ae7b25..96bb16d 100644 --- a/rkvm-input/src/interceptor.rs +++ b/rkvm-input/src/interceptor.rs @@ -1,6 +1,6 @@ mod caps; -pub use caps::{AbsCaps, KeyCaps, RelCaps}; +pub use caps::{AbsCaps, KeyCaps, RelCaps, Repeat}; use crate::abs::{AbsAxis, AbsEvent, ToolType}; use crate::convert::Convert; @@ -137,6 +137,10 @@ impl Interceptor { KeyCaps::new(self) } + pub fn repeat(&self) -> Repeat { + Repeat::new(self) + } + async fn read_raw(&mut self) -> Result<(u16, u16, i32), Error> { let file = self.evdev.file().unwrap(); @@ -234,7 +238,10 @@ impl Interceptor { if ret < 0 { // We do not use ErrorKind::ResourceBusy because it is a nightly-only API. let err = if ret == -libc::EBUSY { - tracing::info!("Ignored {:?} because it is busy and can not be grabbed", path); + tracing::info!( + "Ignored {:?} because it is busy and can not be grabbed", + path + ); OpenError::NotAppliable } else { Error::from_raw_os_error(-ret).into() diff --git a/rkvm-input/src/interceptor/caps.rs b/rkvm-input/src/interceptor/caps.rs index b5e7e08..3b365ea 100644 --- a/rkvm-input/src/interceptor/caps.rs +++ b/rkvm-input/src/interceptor/caps.rs @@ -155,3 +155,51 @@ impl Iterator for KeyCaps<'_> { None } } + +pub struct Repeat { + pub delay: Option, + pub period: Option, +} + +impl Repeat { + pub(super) fn new(interceptor: &Interceptor) -> Self { + let has = unsafe { + glue::libevdev_has_event_code(interceptor.evdev.as_ptr(), glue::EV_REP, glue::REP_DELAY) + == 1 + }; + + let delay = if has { + Some(unsafe { + glue::libevdev_get_event_value( + interceptor.evdev.as_ptr(), + glue::EV_REP, + glue::REP_DELAY, + ) + }) + } else { + None + }; + + let has = unsafe { + glue::libevdev_has_event_code( + interceptor.evdev.as_ptr(), + glue::EV_REP, + glue::REP_PERIOD, + ) == 1 + }; + + let period = if has { + Some(unsafe { + glue::libevdev_get_event_value( + interceptor.evdev.as_ptr(), + glue::EV_REP, + glue::REP_PERIOD, + ) + }) + } else { + None + }; + + Self { delay, period } + } +} diff --git a/rkvm-input/src/writer.rs b/rkvm-input/src/writer.rs index ab2dbd5..7106b95 100644 --- a/rkvm-input/src/writer.rs +++ b/rkvm-input/src/writer.rs @@ -1,3 +1,5 @@ +use libc::c_int; + use crate::abs::{AbsAxis, AbsEvent, AbsInfo}; use crate::convert::Convert; use crate::evdev::Evdev; @@ -236,6 +238,50 @@ impl WriterBuilder { Ok(self) } + pub fn delay(self, value: Option) -> Result { + let value: c_int = match value { + Some(value) => value, + None => return Ok(self), + }; + + let ret = unsafe { + glue::libevdev_enable_event_code( + self.evdev.as_ptr(), + glue::EV_REP, + glue::REP_DELAY, + &value as *const _ as *const _, + ) + }; + + if ret < 0 { + return Err(Error::from_raw_os_error(-ret)); + } + + Ok(self) + } + + pub fn period(self, value: Option) -> Result { + let value: c_int = match value { + Some(value) => value, + None => return Ok(self), + }; + + let ret = unsafe { + glue::libevdev_enable_event_code( + self.evdev.as_ptr(), + glue::EV_REP, + glue::REP_PERIOD, + &value as *const _ as *const _, + ) + }; + + if ret < 0 { + return Err(Error::from_raw_os_error(-ret)); + } + + Ok(self) + } + pub async fn build(self) -> Result { Writer::from_evdev(&self.evdev).await } diff --git a/rkvm-net/src/lib.rs b/rkvm-net/src/lib.rs index 0892c06..79e0059 100644 --- a/rkvm-net/src/lib.rs +++ b/rkvm-net/src/lib.rs @@ -36,6 +36,8 @@ pub enum Update { rel: HashSet, abs: HashMap, keys: HashSet, + delay: Option, + period: Option, }, DestroyDevice { id: usize, diff --git a/rkvm-net/src/version.rs b/rkvm-net/src/version.rs index a3de6f9..a0da8a5 100644 --- a/rkvm-net/src/version.rs +++ b/rkvm-net/src/version.rs @@ -8,7 +8,7 @@ use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; pub struct Version(u16); impl Version { - pub const CURRENT: Self = Self(4); + pub const CURRENT: Self = Self(5); } impl Display for Version { diff --git a/rkvm-server/src/server.rs b/rkvm-server/src/server.rs index 2d7da44..b783181 100644 --- a/rkvm-server/src/server.rs +++ b/rkvm-server/src/server.rs @@ -79,6 +79,8 @@ pub async fn run( rel: device.rel.clone(), abs: device.abs.clone(), keys: device.keys.clone(), + delay: device.delay, + period: device.period, }) .collect(); @@ -109,6 +111,7 @@ pub async fn run( let rel = interceptor.rel().collect::>(); let abs = interceptor.abs().collect::>(); let keys = interceptor.key().collect::>(); + let repeat = interceptor.repeat(); for (_, (sender, _)) in &clients { let update = Update::CreateDevice { @@ -120,6 +123,8 @@ pub async fn run( rel: rel.clone(), abs: abs.clone(), keys: keys.clone(), + delay: repeat.delay, + period: repeat.period, }; let _ = sender.send(update).await; @@ -134,6 +139,8 @@ pub async fn run( rel, abs, keys, + delay: repeat.delay, + period: repeat.period, sender: interceptor_sender, }); @@ -278,6 +285,8 @@ struct Device { rel: HashSet, abs: HashMap, keys: HashSet, + delay: Option, + period: Option, sender: Sender, }