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 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [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" libc = "0.2.77"
serde = { version = "1.0.117", features = ["derive"] } serde = { version = "1.0.117", features = ["derive"] }

View file

@ -1,14 +1,14 @@
use crate::event::Event; use crate::event::Event;
use crate::event_reader::EventReader; use crate::event_reader::EventReader;
use crate::event_writer::EventWriter; use crate::event_writer::EventWriter;
use crate::glue::input_event;
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use std::time::Duration;
use tokio::fs; use tokio::fs;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
pub struct EventManager { pub struct EventManager {
writer: EventWriter, writer: EventWriter,
receiver: UnboundedReceiver<Result<input_event, Error>>, receiver: UnboundedReceiver<Result<Event, Error>>,
} }
impl EventManager { impl EventManager {
@ -38,23 +38,18 @@ impl EventManager {
} }
let writer = EventWriter::new().await?; 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 }) Ok(EventManager { writer, receiver })
} }
pub async fn read(&mut self) -> Result<Event, Error> { pub async fn read(&mut self) -> Result<Event, Error> {
loop { self.receiver
let event = self .recv()
.receiver .await
.recv() .ok_or_else(|| Error::new(ErrorKind::Other, "All devices closed"))?
.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?;
}
} }
pub async fn write(&mut self, event: Event) -> Result<(), Error> { pub async fn write(&mut self, event: Event) -> Result<(), Error> {
@ -62,10 +57,7 @@ impl EventManager {
} }
} }
async fn handle_events( async fn handle_events(mut reader: EventReader, sender: UnboundedSender<Result<Event, Error>>) {
mut reader: EventReader,
sender: UnboundedSender<Result<input_event, Error>>,
) {
loop { loop {
let result = match reader.read().await { let result = match reader.read().await {
Ok(event) => sender.send(Ok(event)).is_ok(), 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::fs::{File, OpenOptions};
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@ -10,6 +11,7 @@ use tokio::io::unix::AsyncFd;
pub(crate) struct EventReader { pub(crate) struct EventReader {
file: AsyncFd<File>, file: AsyncFd<File>,
evdev: *mut libevdev, evdev: *mut libevdev,
uinput: *mut libevdev_uinput,
} }
impl EventReader { impl EventReader {
@ -41,10 +43,29 @@ impl EventReader {
return Err(Error::from_raw_os_error(-ret)); 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 { loop {
let result = self.file.readable().await?.with_io(|| { let result = self.file.readable().await?.with_io(|| {
let mut event = MaybeUninit::uninit(); let mut event = MaybeUninit::uninit();
@ -64,10 +85,28 @@ impl EventReader {
Ok(event) Ok(event)
}); });
match result { let event = match result {
Ok(event) => return Ok(event), Ok(event) => event,
Err(ref err) if err.kind() == ErrorKind::WouldBlock => {} Err(ref err) if err.kind() == ErrorKind::WouldBlock => continue,
Err(err) => return Err(err), 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 { impl Drop for EventReader {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
glue::libevdev_uinput_destroy(self.uinput);
glue::libevdev_free(self.evdev); glue::libevdev_free(self.evdev);
} }
} }