inputd: Add ConsumerHandle::read_events
This commit is contained in:
+42
-13
@@ -1,23 +1,44 @@
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Error, Read, Write};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::mem::size_of;
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd};
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::slice;
|
||||
|
||||
use libredox::flag::{O_CLOEXEC, O_NONBLOCK, O_RDWR};
|
||||
use orbclient::Event;
|
||||
use syscall::ESTALE;
|
||||
|
||||
fn read_to_slice<T: Copy>(
|
||||
file: BorrowedFd,
|
||||
buf: &mut [T],
|
||||
) -> Result<usize, libredox::error::Error> {
|
||||
unsafe {
|
||||
libredox::call::read(
|
||||
file.as_raw_fd() as usize,
|
||||
slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u8, buf.len() * size_of::<T>()),
|
||||
)
|
||||
.map(|count| count / size_of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
|
||||
std::slice::from_raw_parts((p as *const T) as *const u8, size_of::<T>())
|
||||
slice::from_raw_parts((p as *const T) as *const u8, size_of::<T>())
|
||||
}
|
||||
|
||||
unsafe fn any_as_u8_slice_mut<T: Sized>(p: &mut T) -> &mut [u8] {
|
||||
std::slice::from_raw_parts_mut((p as *mut T) as *mut u8, size_of::<T>())
|
||||
slice::from_raw_parts_mut((p as *mut T) as *mut u8, size_of::<T>())
|
||||
}
|
||||
|
||||
pub struct ConsumerHandle(File);
|
||||
|
||||
pub enum ConsumerHandleEvent<'a> {
|
||||
Events(&'a [Event]),
|
||||
Handoff,
|
||||
}
|
||||
|
||||
impl ConsumerHandle {
|
||||
pub fn new_vt() -> Result<Self, Error> {
|
||||
pub fn new_vt() -> io::Result<Self> {
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.custom_flags(O_NONBLOCK as i32)
|
||||
@@ -25,11 +46,11 @@ impl ConsumerHandle {
|
||||
Ok(Self(file))
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> BorrowedFd<'_> {
|
||||
pub fn event_handle(&self) -> BorrowedFd<'_> {
|
||||
self.0.as_fd()
|
||||
}
|
||||
|
||||
pub fn open_display(&self) -> Result<File, Error> {
|
||||
pub fn open_display(&self) -> io::Result<File> {
|
||||
let mut buffer = [0; 1024];
|
||||
let fd = self.0.as_raw_fd();
|
||||
let written = libredox::call::fpath(fd as usize, &mut buffer)?;
|
||||
@@ -49,6 +70,14 @@ impl ConsumerHandle {
|
||||
|
||||
Ok(display_file)
|
||||
}
|
||||
|
||||
pub fn read_events<'a>(&self, events: &'a mut [Event]) -> io::Result<ConsumerHandleEvent<'a>> {
|
||||
match read_to_slice(self.0.as_fd(), events) {
|
||||
Ok(count) => Ok(ConsumerHandleEvent::Events(&events[..count])),
|
||||
Err(err) if err.errno() == ESTALE => Ok(ConsumerHandleEvent::Handoff),
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -60,17 +89,17 @@ pub struct VtActivate {
|
||||
pub struct DisplayHandle(File);
|
||||
|
||||
impl DisplayHandle {
|
||||
pub fn new<S: Into<String>>(device_name: S) -> Result<Self, Error> {
|
||||
pub fn new<S: Into<String>>(device_name: S) -> io::Result<Self> {
|
||||
let path = format!("/scheme/input/handle/display/{}", device_name.into());
|
||||
Ok(Self(File::open(path)?))
|
||||
}
|
||||
|
||||
pub fn new_early<S: Into<String>>(device_name: S) -> Result<Self, Error> {
|
||||
pub fn new_early<S: Into<String>>(device_name: S) -> io::Result<Self> {
|
||||
let path = format!("/scheme/input/handle_early/display/{}", device_name.into());
|
||||
Ok(Self(File::open(path)?))
|
||||
}
|
||||
|
||||
pub fn read_vt_event(&mut self) -> Result<Option<VtEvent>, Error> {
|
||||
pub fn read_vt_event(&mut self) -> io::Result<Option<VtEvent>> {
|
||||
let mut event = VtEvent {
|
||||
kind: VtEventKind::Resize,
|
||||
vt: usize::MAX,
|
||||
@@ -97,12 +126,12 @@ impl DisplayHandle {
|
||||
pub struct ControlHandle(File);
|
||||
|
||||
impl ControlHandle {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
let path = format!("/scheme/input/control");
|
||||
Ok(Self(File::open(path)?))
|
||||
}
|
||||
|
||||
pub fn activate_vt(&mut self, vt: usize) -> Result<usize, Error> {
|
||||
pub fn activate_vt(&mut self, vt: usize) -> io::Result<usize> {
|
||||
let cmd = VtActivate { vt };
|
||||
self.0.write(unsafe { any_as_u8_slice(&cmd) })
|
||||
}
|
||||
@@ -129,11 +158,11 @@ pub struct VtEvent {
|
||||
pub struct ProducerHandle(File);
|
||||
|
||||
impl ProducerHandle {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
File::open("/scheme/input/producer").map(ProducerHandle)
|
||||
}
|
||||
|
||||
pub fn write_event(&mut self, event: orbclient::Event) -> Result<(), Error> {
|
||||
pub fn write_event(&mut self, event: orbclient::Event) -> io::Result<()> {
|
||||
self.0.write(&event)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user