mirror of
https://github.com/htrefil/rkvm.git
synced 2024-12-27 09:58:13 +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,
|
rel,
|
||||||
abs,
|
abs,
|
||||||
keys,
|
keys,
|
||||||
|
delay,
|
||||||
|
period,
|
||||||
} => {
|
} => {
|
||||||
let entry = writers.entry(id);
|
let entry = writers.entry(id);
|
||||||
if let Entry::Occupied(_) = entry {
|
if let Entry::Occupied(_) = entry {
|
||||||
|
@ -141,6 +143,8 @@ pub async fn run(
|
||||||
.rel(rel)?
|
.rel(rel)?
|
||||||
.abs(abs)?
|
.abs(abs)?
|
||||||
.key(keys)?
|
.key(keys)?
|
||||||
|
.delay(delay)?
|
||||||
|
.period(period)?
|
||||||
.build()
|
.build()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
mod caps;
|
mod caps;
|
||||||
|
|
||||||
pub use caps::{AbsCaps, KeyCaps, RelCaps};
|
pub use caps::{AbsCaps, KeyCaps, RelCaps, Repeat};
|
||||||
|
|
||||||
use crate::abs::{AbsAxis, AbsEvent, ToolType};
|
use crate::abs::{AbsAxis, AbsEvent, ToolType};
|
||||||
use crate::convert::Convert;
|
use crate::convert::Convert;
|
||||||
|
@ -137,6 +137,10 @@ impl Interceptor {
|
||||||
KeyCaps::new(self)
|
KeyCaps::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn repeat(&self) -> Repeat {
|
||||||
|
Repeat::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
async fn read_raw(&mut self) -> Result<(u16, u16, i32), Error> {
|
async fn read_raw(&mut self) -> Result<(u16, u16, i32), Error> {
|
||||||
let file = self.evdev.file().unwrap();
|
let file = self.evdev.file().unwrap();
|
||||||
|
|
||||||
|
@ -234,7 +238,10 @@ impl Interceptor {
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
// We do not use ErrorKind::ResourceBusy because it is a nightly-only API.
|
// We do not use ErrorKind::ResourceBusy because it is a nightly-only API.
|
||||||
let err = if ret == -libc::EBUSY {
|
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
|
OpenError::NotAppliable
|
||||||
} else {
|
} else {
|
||||||
Error::from_raw_os_error(-ret).into()
|
Error::from_raw_os_error(-ret).into()
|
||||||
|
|
|
@ -155,3 +155,51 @@ impl Iterator for KeyCaps<'_> {
|
||||||
None
|
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::abs::{AbsAxis, AbsEvent, AbsInfo};
|
||||||
use crate::convert::Convert;
|
use crate::convert::Convert;
|
||||||
use crate::evdev::Evdev;
|
use crate::evdev::Evdev;
|
||||||
|
@ -236,6 +238,50 @@ impl WriterBuilder {
|
||||||
Ok(self)
|
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> {
|
pub async fn build(self) -> Result<Writer, Error> {
|
||||||
Writer::from_evdev(&self.evdev).await
|
Writer::from_evdev(&self.evdev).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ pub enum Update {
|
||||||
rel: HashSet<RelAxis>,
|
rel: HashSet<RelAxis>,
|
||||||
abs: HashMap<AbsAxis, AbsInfo>,
|
abs: HashMap<AbsAxis, AbsInfo>,
|
||||||
keys: HashSet<Key>,
|
keys: HashSet<Key>,
|
||||||
|
delay: Option<i32>,
|
||||||
|
period: Option<i32>,
|
||||||
},
|
},
|
||||||
DestroyDevice {
|
DestroyDevice {
|
||||||
id: usize,
|
id: usize,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
pub struct Version(u16);
|
pub struct Version(u16);
|
||||||
|
|
||||||
impl Version {
|
impl Version {
|
||||||
pub const CURRENT: Self = Self(4);
|
pub const CURRENT: Self = Self(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Version {
|
impl Display for Version {
|
||||||
|
|
|
@ -79,6 +79,8 @@ pub async fn run(
|
||||||
rel: device.rel.clone(),
|
rel: device.rel.clone(),
|
||||||
abs: device.abs.clone(),
|
abs: device.abs.clone(),
|
||||||
keys: device.keys.clone(),
|
keys: device.keys.clone(),
|
||||||
|
delay: device.delay,
|
||||||
|
period: device.period,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -109,6 +111,7 @@ pub async fn run(
|
||||||
let rel = interceptor.rel().collect::<HashSet<_>>();
|
let rel = interceptor.rel().collect::<HashSet<_>>();
|
||||||
let abs = interceptor.abs().collect::<HashMap<_,_>>();
|
let abs = interceptor.abs().collect::<HashMap<_,_>>();
|
||||||
let keys = interceptor.key().collect::<HashSet<_>>();
|
let keys = interceptor.key().collect::<HashSet<_>>();
|
||||||
|
let repeat = interceptor.repeat();
|
||||||
|
|
||||||
for (_, (sender, _)) in &clients {
|
for (_, (sender, _)) in &clients {
|
||||||
let update = Update::CreateDevice {
|
let update = Update::CreateDevice {
|
||||||
|
@ -120,6 +123,8 @@ pub async fn run(
|
||||||
rel: rel.clone(),
|
rel: rel.clone(),
|
||||||
abs: abs.clone(),
|
abs: abs.clone(),
|
||||||
keys: keys.clone(),
|
keys: keys.clone(),
|
||||||
|
delay: repeat.delay,
|
||||||
|
period: repeat.period,
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = sender.send(update).await;
|
let _ = sender.send(update).await;
|
||||||
|
@ -134,6 +139,8 @@ pub async fn run(
|
||||||
rel,
|
rel,
|
||||||
abs,
|
abs,
|
||||||
keys,
|
keys,
|
||||||
|
delay: repeat.delay,
|
||||||
|
period: repeat.period,
|
||||||
sender: interceptor_sender,
|
sender: interceptor_sender,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -278,6 +285,8 @@ struct Device {
|
||||||
rel: HashSet<RelAxis>,
|
rel: HashSet<RelAxis>,
|
||||||
abs: HashMap<AbsAxis, AbsInfo>,
|
abs: HashMap<AbsAxis, AbsInfo>,
|
||||||
keys: HashSet<Key>,
|
keys: HashSet<Key>,
|
||||||
|
delay: Option<i32>,
|
||||||
|
period: Option<i32>,
|
||||||
sender: Sender<Event>,
|
sender: Sender<Event>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue