graphics/fbcond: Migrate to redox-scheme

This commit is contained in:
bjorn3
2024-12-24 16:56:11 +01:00
parent f4897c59b4
commit 5a1648fdca
5 changed files with 98 additions and 100 deletions
Generated
+1
View File
@@ -424,6 +424,7 @@ dependencies = [
"orbclient",
"ransid",
"redox-daemon",
"redox-scheme",
"redox_event",
"redox_syscall",
]
+1
View File
@@ -9,6 +9,7 @@ ransid = "0.4"
redox_event = "0.4"
redox_syscall = "0.5"
redox-daemon = "0.1"
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
inputd = { path = "../../inputd" }
libredox = "0.1.3"
+49 -60
View File
@@ -1,14 +1,12 @@
#![feature(io_error_more)]
use event::EventQueue;
use libredox::errno::ESTALE;
use libredox::errno::{EAGAIN, EINTR, ESTALE};
use orbclient::Event;
use std::fs::{File, OpenOptions};
use std::io::{ErrorKind, Read, Write};
use redox_scheme::{CallRequest, RequestKind, Response, SignalBehavior, Socket};
use std::os::fd::{AsRawFd, BorrowedFd};
use std::os::unix::fs::OpenOptionsExt;
use std::{env, mem, slice};
use syscall::{Packet, SchemeMut, EVENT_READ, O_NONBLOCK};
use syscall::EVENT_READ;
use crate::scheme::{FbconScheme, VtIndex};
@@ -42,16 +40,10 @@ fn inner(daemon: redox_daemon::Daemon, vt_ids: &[usize]) -> ! {
// FIXME listen for resize events from inputd and handle them
let mut socket = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.custom_flags(O_NONBLOCK as i32)
.open(":fbcon")
.expect("fbcond: failed to create fbcon scheme");
let mut socket = Socket::nonblock("fbcon").expect("fbcond: failed to create fbcon scheme");
event_queue
.subscribe(
socket.as_raw_fd().as_raw_fd() as usize,
socket.inner().raw(),
VtIndex::SCHEMA_SENTINEL,
event::EventFlags::READ,
)
@@ -91,37 +83,49 @@ fn inner(daemon: redox_daemon::Daemon, vt_ids: &[usize]) -> ! {
}
fn handle_event(
socket: &mut File,
socket: &mut Socket,
scheme: &mut FbconScheme,
blocked: &mut Vec<Packet>,
blocked: &mut Vec<CallRequest>,
event: VtIndex,
) {
match event {
VtIndex::SCHEMA_SENTINEL => {
loop {
let mut packet = Packet::default();
match socket.read(&mut packet) {
Ok(0) => break,
Err(err) if err.kind() == ErrorKind::WouldBlock => {
break;
let request = match socket.next_request(SignalBehavior::Restart) {
Ok(Some(request)) => request,
Ok(None) => {
// Scheme likely got unmounted
std::process::exit(0);
}
Ok(_) => {}
Err(err) => {
panic!("fbcond: failed to read display scheme: {err}");
}
}
Err(err) if err.errno == EAGAIN => break,
Err(err) => panic!("vesad: failed to read display scheme: {err}"),
};
// If it is a read packet, and there is no data, block it. Otherwise, handle packet
if packet.a == syscall::number::SYS_READ
&& packet.d > 0
&& scheme.can_read(packet.b).is_none()
{
blocked.push(packet);
} else {
scheme.handle(&mut packet);
socket
.write(&packet)
.expect("fbcond: failed to write display scheme");
match request.kind() {
RequestKind::Call(call_request) => {
if let Some(resp) = call_request.handle_scheme_block_mut(scheme) {
socket
.write_response(resp, SignalBehavior::Restart)
.expect("vesad: failed to write display scheme");
} else {
blocked.push(call_request);
}
}
RequestKind::Cancellation(cancellation_request) => {
if let Some(i) = blocked
.iter()
.position(|req| req.request().request_id() == cancellation_request.id)
{
let blocked_req = blocked.remove(i);
let resp = Response::new(&blocked_req, Err(syscall::Error::new(EINTR)));
socket
.write_response(resp, SignalBehavior::Restart)
.expect("vesad: failed to write display scheme");
}
}
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
unreachable!()
}
}
}
}
@@ -150,16 +154,15 @@ fn handle_event(
}
}
// If there are blocked readers, and data is available, handle them
// If there are blocked readers, try to handle them.
{
let mut i = 0;
while i < blocked.len() {
if scheme.can_read(blocked[i].b).is_some() {
let mut packet = blocked.remove(i);
scheme.handle(&mut packet);
if let Some(resp) = blocked[i].handle_scheme_block_mut(scheme) {
socket
.write(&packet)
.expect("fbcond: failed to write display scheme");
.write_response(resp, SignalBehavior::Restart)
.expect("vesad: failed to write display scheme");
blocked.remove(i);
} else {
i += 1;
}
@@ -171,30 +174,16 @@ fn handle_event(
continue;
}
// Can't use scheme.can_read() because we borrow handles as mutable.
// (and because it'd treat O_NONBLOCK sockets differently)
let count = scheme
let can_read = scheme
.vts
.get(&handle.vt_i)
.and_then(|console| console.can_read())
.unwrap_or(0);
.map_or(false, |console| console.can_read());
if count > 0 {
if can_read {
if !handle.notified_read {
handle.notified_read = true;
let event_packet = Packet {
id: 0,
pid: 0,
uid: 0,
gid: 0,
a: syscall::number::SYS_FEVENT,
b: *handle_id,
c: EVENT_READ.bits(),
d: count,
};
socket
.write(&event_packet)
.post_fevent(*handle_id, EVENT_READ.bits())
.expect("fbcond: failed to write display event");
}
} else {
+45 -34
View File
@@ -2,7 +2,8 @@ use std::collections::BTreeMap;
use std::os::fd::AsRawFd;
use event::{EventQueue, UserData};
use syscall::{Error, EventFlags, Result, SchemeMut, EBADF, EINVAL, ENOENT, O_NONBLOCK};
use redox_scheme::SchemeBlockMut;
use syscall::{Error, EventFlags, Result, EBADF, EINVAL, ENOENT, O_NONBLOCK};
use crate::display::Display;
use crate::text::TextScreen;
@@ -61,22 +62,6 @@ impl FbconScheme {
}
}
pub fn can_read(&self, id: usize) -> Option<usize> {
if let Some(handle) = self.handles.get(&id) {
if let Some(console) = self.vts.get(&handle.vt_i) {
console
.can_read()
.or(if handle.flags & O_NONBLOCK == O_NONBLOCK {
Some(0)
} else {
None
});
}
}
Some(0)
}
fn resize(&mut self, width: usize, height: usize, stride: usize) {
for console in self.vts.values_mut() {
console.resize(width, height);
@@ -84,8 +69,14 @@ impl FbconScheme {
}
}
impl SchemeMut for FbconScheme {
fn open(&mut self, path_str: &str, flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
impl SchemeBlockMut for FbconScheme {
fn open(
&mut self,
path_str: &str,
flags: usize,
_uid: u32,
_gid: u32,
) -> Result<Option<usize>> {
let vt_i = VtIndex(path_str.parse::<usize>().map_err(|_| Error::new(ENOENT))?);
if let Some(_console) = self.vts.get_mut(&vt_i) {
let id = self.next_id;
@@ -101,13 +92,13 @@ impl SchemeMut for FbconScheme {
},
);
Ok(id)
Ok(Some(id))
} else {
Err(Error::new(ENOENT))
}
}
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
if !buf.is_empty() {
return Err(Error::new(EINVAL));
}
@@ -123,19 +114,23 @@ impl SchemeMut for FbconScheme {
self.handles.insert(new_id, handle);
Ok(new_id)
Ok(Some(new_id))
}
fn fevent(&mut self, id: usize, flags: syscall::EventFlags) -> Result<syscall::EventFlags> {
fn fevent(
&mut self,
id: usize,
flags: syscall::EventFlags,
) -> Result<Option<syscall::EventFlags>> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
handle.notified_read = false;
handle.events = flags;
Ok(syscall::EventFlags::empty())
Ok(Some(syscall::EventFlags::empty()))
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let path_str = format!("fbcon:{}", handle.vt_i.0);
@@ -148,37 +143,53 @@ impl SchemeMut for FbconScheme {
i += 1;
}
Ok(i)
Ok(Some(i))
}
fn fsync(&mut self, id: usize) -> Result<usize> {
fn fsync(&mut self, id: usize) -> Result<Option<usize>> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
return Ok(0);
return Ok(Some(0));
}
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
fn read(
&mut self,
id: usize,
buf: &mut [u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<Option<usize>> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if let Some(screen) = self.vts.get_mut(&handle.vt_i) {
return screen.read(buf);
if !screen.can_read() && handle.flags & O_NONBLOCK != O_NONBLOCK {
return Ok(None);
} else {
return screen.read(buf).map(Some);
}
}
Err(Error::new(EBADF))
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
fn write(
&mut self,
id: usize,
buf: &[u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<Option<usize>> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if let Some(console) = self.vts.get_mut(&handle.vt_i) {
console.write(buf)
console.write(buf).map(Some)
} else {
Err(Error::new(EBADF))
}
}
fn close(&mut self, id: usize) -> Result<usize> {
fn close(&mut self, id: usize) -> Result<Option<usize>> {
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
Ok(0)
Ok(Some(0))
}
}
+2 -6
View File
@@ -204,12 +204,8 @@ impl TextScreen {
}
}
pub fn can_read(&self) -> Option<usize> {
if self.input.is_empty() {
None
} else {
Some(self.input.len())
}
pub fn can_read(&self) -> bool {
!self.input.is_empty()
}
}