mirror of
https://github.com/htrefil/rkvm.git
synced 2025-01-18 10:26:12 +01:00
Improve unrecognized event forwarding
This commit is contained in:
parent
1890bf1429
commit
90d2f2d88d
3 changed files with 58 additions and 26 deletions
|
@ -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"] }
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue