mirror of
https://github.com/htrefil/rkvm.git
synced 2024-12-26 09:58:32 +01:00
Add support for key autorepeat (EV_REP - REP_DELAY and REP_PERIOD)
This commit is contained in:
parent
1c148cf3a3
commit
607e1fb14c
7 changed files with 119 additions and 3 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -155,3 +155,51 @@ impl Iterator for KeyCaps<'_> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Repeat {
|
||||
pub delay: Option<i32>,
|
||||
pub period: Option<i32>,
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<i32>) -> Result<Self, Error> {
|
||||
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<i32>) -> Result<Self, Error> {
|
||||
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, Error> {
|
||||
Writer::from_evdev(&self.evdev).await
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ pub enum Update {
|
|||
rel: HashSet<RelAxis>,
|
||||
abs: HashMap<AbsAxis, AbsInfo>,
|
||||
keys: HashSet<Key>,
|
||||
delay: Option<i32>,
|
||||
period: Option<i32>,
|
||||
},
|
||||
DestroyDevice {
|
||||
id: usize,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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::<HashSet<_>>();
|
||||
let abs = interceptor.abs().collect::<HashMap<_,_>>();
|
||||
let keys = interceptor.key().collect::<HashSet<_>>();
|
||||
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<RelAxis>,
|
||||
abs: HashMap<AbsAxis, AbsInfo>,
|
||||
keys: HashSet<Key>,
|
||||
delay: Option<i32>,
|
||||
period: Option<i32>,
|
||||
sender: Sender<Event>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue