mirror of
https://github.com/htrefil/rkvm.git
synced 2025-01-30 20:34:13 +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
|
# 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"] }
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
.receiver
|
|
||||||
.recv()
|
.recv()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| Error::new(ErrorKind::Other, "All devices closed"))??;
|
.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(),
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read(&mut self) -> Result<input_event, Error> {
|
let uinput = unsafe { uinput.assume_init() };
|
||||||
|
Ok(Self {
|
||||||
|
file,
|
||||||
|
evdev,
|
||||||
|
uinput,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue