Improve unrecognized event forwarding

This commit is contained in:
htrefil 2020-10-29 19:22:01 +01:00
parent 1890bf1429
commit 90d2f2d88d
3 changed files with 58 additions and 26 deletions

View file

@ -7,7 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "0.3.2", features = ["fs", "io-util", "net", "sync", "rt"] }
tokio = { version = "0.3.2", features = ["fs", "io-util", "net", "sync", "rt", "time"] }
libc = "0.2.77"
serde = { version = "1.0.117", features = ["derive"] }

View file

@ -1,14 +1,14 @@
use crate::event::Event;
use crate::event_reader::EventReader;
use crate::event_writer::EventWriter;
use crate::glue::input_event;
use std::io::{Error, ErrorKind};
use std::time::Duration;
use tokio::fs;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
pub struct EventManager {
writer: EventWriter,
receiver: UnboundedReceiver<Result<input_event, Error>>,
receiver: UnboundedReceiver<Result<Event, Error>>,
}
impl EventManager {
@ -38,23 +38,18 @@ impl EventManager {
}
let writer = EventWriter::new().await?;
// Sleep for a while to give userspace time to register our devices.
tokio::time::sleep(Duration::from_secs(1)).await;
Ok(EventManager { writer, receiver })
}
pub async fn read(&mut self) -> Result<Event, Error> {
loop {
let event = self
.receiver
.recv()
.await
.ok_or_else(|| Error::new(ErrorKind::Other, "All devices closed"))??;
if let Some(event) = Event::from_raw(event) {
return Ok(event);
}
// Not understood. Write it back.
self.writer.write_raw(event).await?;
}
self.receiver
.recv()
.await
.ok_or_else(|| Error::new(ErrorKind::Other, "All devices closed"))?
}
pub async fn write(&mut self, event: Event) -> Result<(), Error> {
@ -62,10 +57,7 @@ impl EventManager {
}
}
async fn handle_events(
mut reader: EventReader,
sender: UnboundedSender<Result<input_event, Error>>,
) {
async fn handle_events(mut reader: EventReader, sender: UnboundedSender<Result<Event, Error>>) {
loop {
let result = match reader.read().await {
Ok(event) => sender.send(Ok(event)).is_ok(),

View file

@ -1,4 +1,5 @@
use crate::glue::{self, input_event, libevdev};
use crate::event::Event;
use crate::glue::{self, libevdev, libevdev_uinput};
use std::fs::{File, OpenOptions};
use std::io::{Error, ErrorKind};
use std::mem::MaybeUninit;
@ -10,6 +11,7 @@ use tokio::io::unix::AsyncFd;
pub(crate) struct EventReader {
file: AsyncFd<File>,
evdev: *mut libevdev,
uinput: *mut libevdev_uinput,
}
impl EventReader {
@ -41,10 +43,29 @@ impl EventReader {
return Err(Error::from_raw_os_error(-ret));
}
Ok(Self { file, evdev })
let mut uinput = MaybeUninit::uninit();
let ret = unsafe {
glue::libevdev_uinput_create_from_device(
evdev,
glue::libevdev_uinput_open_mode_LIBEVDEV_UINPUT_OPEN_MANAGED,
uinput.as_mut_ptr(),
)
};
if ret < 0 {
unsafe { glue::libevdev_free(evdev) };
return Err(Error::from_raw_os_error(-ret));
}
let uinput = unsafe { uinput.assume_init() };
Ok(Self {
file,
evdev,
uinput,
})
}
pub async fn read(&mut self) -> Result<input_event, Error> {
pub async fn read(&mut self) -> Result<Event, Error> {
loop {
let result = self.file.readable().await?.with_io(|| {
let mut event = MaybeUninit::uninit();
@ -64,10 +85,28 @@ impl EventReader {
Ok(event)
});
match result {
Ok(event) => return Ok(event),
Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}
let event = match result {
Ok(event) => event,
Err(ref err) if err.kind() == ErrorKind::WouldBlock => continue,
Err(err) => return Err(err),
};
if let Some(event) = Event::from_raw(event) {
return Ok(event);
}
// Not understood, write it back.
let ret = unsafe {
glue::libevdev_uinput_write_event(
self.uinput as *const _,
event.type_ as _,
event.code as _,
event.value,
)
};
if ret < 0 {
return Err(Error::from_raw_os_error(-ret));
}
}
}
@ -76,6 +115,7 @@ impl EventReader {
impl Drop for EventReader {
fn drop(&mut self) {
unsafe {
glue::libevdev_uinput_destroy(self.uinput);
glue::libevdev_free(self.evdev);
}
}