inputd: Add ConsumerHandle::read_events

This commit is contained in:
bjorn3
2025-03-15 17:07:22 +01:00
parent 56808dbfb1
commit b9d043f6e2
5 changed files with 69 additions and 71 deletions
+12 -28
View File
@@ -1,24 +1,8 @@
use graphics_ipc::v1::{Damage, V1GraphicsHandle};
use inputd::ConsumerHandle;
use libredox::errno::ESTALE;
use orbclient::Event;
use std::mem;
use std::os::fd::BorrowedFd;
use std::os::unix::io::AsRawFd;
use std::{io, slice};
use std::io;
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() * mem::size_of::<T>()),
)
.map(|count| count / mem::size_of::<T>())
}
}
use graphics_ipc::v1::{Damage, V1GraphicsHandle};
use inputd::{ConsumerHandle, ConsumerHandleEvent};
use orbclient::Event;
fn display_fd_map(display_handle: V1GraphicsHandle) -> io::Result<DisplayMap> {
let display_map = display_handle.map_display()?;
@@ -62,8 +46,14 @@ impl Display {
pub fn handle_input_events(&mut self) {
let mut events = [Event::new(); 16];
loop {
match read_to_slice(self.input_handle.inner(), &mut events) {
Err(err) if err.errno() == ESTALE => {
match self
.input_handle
.read_events(&mut events)
.expect("fbbootlogd: error while reading events")
{
ConsumerHandleEvent::Events(&[]) => break,
ConsumerHandleEvent::Events(_) => {}
ConsumerHandleEvent::Handoff => {
eprintln!("fbbootlogd: handoff requested");
let new_display_handle = match self.input_handle.open_display() {
@@ -85,12 +75,6 @@ impl Display {
}
}
}
Ok(0) => break,
Ok(_count) => {}
Err(err) => {
panic!("fbbootlogd: error while reading events: {err}");
}
}
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ fn inner(daemon: redox_daemon::Daemon) -> ! {
event_queue
.subscribe(
scheme.display.input_handle.inner().as_raw_fd() as usize,
scheme.display.input_handle.event_handle().as_raw_fd() as usize,
Source::Input,
event::EventFlags::READ,
)
+13 -28
View File
@@ -1,9 +1,9 @@
use event::EventQueue;
use libredox::errno::{EAGAIN, EINTR, ESTALE};
use inputd::ConsumerHandleEvent;
use libredox::errno::{EAGAIN, EINTR};
use orbclient::Event;
use redox_scheme::{CallRequest, RequestKind, Response, SignalBehavior, Socket};
use std::os::fd::{AsRawFd, BorrowedFd};
use std::{env, mem, slice};
use std::env;
use syscall::EVENT_READ;
use crate::scheme::{FbconScheme, VtIndex};
@@ -12,19 +12,6 @@ mod display;
mod scheme;
mod text;
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() * mem::size_of::<T>()),
)
.map(|count| count / mem::size_of::<T>())
}
}
fn main() {
let vt_ids = env::args()
.skip(1)
@@ -129,21 +116,19 @@ fn handle_event(
let mut events = [Event::new(); 16];
loop {
match read_to_slice(vt.display.input_handle.inner(), &mut events) {
Ok(0) => break,
Err(err) if err.errno() == ESTALE => {
vt.handle_handoff();
}
Ok(count) => {
let events = &mut events[..count];
for event in events.iter_mut() {
match vt
.display
.input_handle
.read_events(&mut events)
.expect("fbcond: Error while reading events")
{
ConsumerHandleEvent::Events(&[]) => break,
ConsumerHandleEvent::Events(events) => {
for event in events {
vt.input(event)
}
}
Err(err) => {
panic!("fbcond: Error while reading events: {err}");
}
ConsumerHandleEvent::Handoff => vt.handle_handoff(),
}
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ impl FbconScheme {
let display = Display::open_vt(vt_i).expect("Failed to open display for vt");
event_queue
.subscribe(
display.input_handle.inner().as_raw_fd() as usize,
display.input_handle.event_handle().as_raw_fd() as usize,
VtIndex(vt_i),
event::EventFlags::READ,
)
+42 -13
View File
@@ -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(())
}