diff --git a/input/Cargo.toml b/input/Cargo.toml index c9aed36..1a2ec17 100644 --- a/input/Cargo.toml +++ b/input/Cargo.toml @@ -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"] } diff --git a/input/src/event_manager.rs b/input/src/event_manager.rs index 35463f8..2531154 100644 --- a/input/src/event_manager.rs +++ b/input/src/event_manager.rs @@ -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>, + receiver: UnboundedReceiver>, } 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 { - 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>, -) { +async fn handle_events(mut reader: EventReader, sender: UnboundedSender>) { loop { let result = match reader.read().await { Ok(event) => sender.send(Ok(event)).is_ok(), diff --git a/input/src/event_reader.rs b/input/src/event_reader.rs index 8dfa9fa..40fb177 100644 --- a/input/src/event_reader.rs +++ b/input/src/event_reader.rs @@ -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, 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 { + pub async fn read(&mut self) -> Result { 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); } }