From 0789069afc5b8ca6b6e9ba7d6077c1ad8ac602fc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Dec 2024 14:58:39 +0100 Subject: [PATCH 1/5] input: Move all input drivers to a subdirectory --- Cargo.toml | 5 +++-- {ps2d => input/ps2d}/.gitignore | 0 {ps2d => input/ps2d}/Cargo.toml | 2 +- {ps2d => input/ps2d}/src/controller.rs | 0 {ps2d => input/ps2d}/src/keymap.rs | 0 {ps2d => input/ps2d}/src/main.rs | 0 {ps2d => input/ps2d}/src/state.rs | 0 {ps2d => input/ps2d}/src/vm.rs | 0 {usbhidd => input/usbhidd}/.gitignore | 0 {usbhidd => input/usbhidd}/Cargo.toml | 4 ++-- {usbhidd => input/usbhidd}/src/keymap.rs | 0 {usbhidd => input/usbhidd}/src/main.rs | 0 {usbhidd => input/usbhidd}/src/reqs.rs | 0 13 files changed, 6 insertions(+), 5 deletions(-) rename {ps2d => input/ps2d}/.gitignore (100%) rename {ps2d => input/ps2d}/Cargo.toml (84%) rename {ps2d => input/ps2d}/src/controller.rs (100%) rename {ps2d => input/ps2d}/src/keymap.rs (100%) rename {ps2d => input/ps2d}/src/main.rs (100%) rename {ps2d => input/ps2d}/src/state.rs (100%) rename {ps2d => input/ps2d}/src/vm.rs (100%) rename {usbhidd => input/usbhidd}/.gitignore (100%) rename {usbhidd => input/usbhidd}/Cargo.toml (84%) rename {usbhidd => input/usbhidd}/src/keymap.rs (100%) rename {usbhidd => input/usbhidd}/src/main.rs (100%) rename {usbhidd => input/usbhidd}/src/reqs.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index ed8c1bd82f..a8d2519edb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,10 @@ members = [ "common", "hwd", "pcid", - "ps2d", "vboxd", "xhcid", "usbctl", "usbhubd", - "usbhidd", "inputd", "virtio-core", @@ -23,6 +21,9 @@ members = [ "graphics/vesad", "graphics/virtio-gpud", + "input/ps2d", + "input/usbhidd", + "net/alxd", "net/driver-network", "net/e1000d", diff --git a/ps2d/.gitignore b/input/ps2d/.gitignore similarity index 100% rename from ps2d/.gitignore rename to input/ps2d/.gitignore diff --git a/ps2d/Cargo.toml b/input/ps2d/Cargo.toml similarity index 84% rename from ps2d/Cargo.toml rename to input/ps2d/Cargo.toml index 78f9dbe207..233e027e6f 100644 --- a/ps2d/Cargo.toml +++ b/input/ps2d/Cargo.toml @@ -11,4 +11,4 @@ redox_syscall = "0.5" redox-daemon = "0.1" libredox = "0.1.3" -common = { path = "../common" } +common = { path = "../../common" } diff --git a/ps2d/src/controller.rs b/input/ps2d/src/controller.rs similarity index 100% rename from ps2d/src/controller.rs rename to input/ps2d/src/controller.rs diff --git a/ps2d/src/keymap.rs b/input/ps2d/src/keymap.rs similarity index 100% rename from ps2d/src/keymap.rs rename to input/ps2d/src/keymap.rs diff --git a/ps2d/src/main.rs b/input/ps2d/src/main.rs similarity index 100% rename from ps2d/src/main.rs rename to input/ps2d/src/main.rs diff --git a/ps2d/src/state.rs b/input/ps2d/src/state.rs similarity index 100% rename from ps2d/src/state.rs rename to input/ps2d/src/state.rs diff --git a/ps2d/src/vm.rs b/input/ps2d/src/vm.rs similarity index 100% rename from ps2d/src/vm.rs rename to input/ps2d/src/vm.rs diff --git a/usbhidd/.gitignore b/input/usbhidd/.gitignore similarity index 100% rename from usbhidd/.gitignore rename to input/usbhidd/.gitignore diff --git a/usbhidd/Cargo.toml b/input/usbhidd/Cargo.toml similarity index 84% rename from usbhidd/Cargo.toml rename to input/usbhidd/Cargo.toml index 52a7b01ce9..0d5929a857 100644 --- a/usbhidd/Cargo.toml +++ b/input/usbhidd/Cargo.toml @@ -13,6 +13,6 @@ log = "0.4" orbclient = "0.3.47" redox_syscall = "0.5" rehid = { git = "https://gitlab.redox-os.org/redox-os/rehid.git" } -xhcid = { path = "../xhcid" } +xhcid = { path = "../../xhcid" } -common = { path = "../common" } +common = { path = "../../common" } diff --git a/usbhidd/src/keymap.rs b/input/usbhidd/src/keymap.rs similarity index 100% rename from usbhidd/src/keymap.rs rename to input/usbhidd/src/keymap.rs diff --git a/usbhidd/src/main.rs b/input/usbhidd/src/main.rs similarity index 100% rename from usbhidd/src/main.rs rename to input/usbhidd/src/main.rs diff --git a/usbhidd/src/reqs.rs b/input/usbhidd/src/reqs.rs similarity index 100% rename from usbhidd/src/reqs.rs rename to input/usbhidd/src/reqs.rs From e3eb5fbb5dda8c5c8880e42169f0af9f4c95f868 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Dec 2024 15:07:27 +0100 Subject: [PATCH 2/5] input/ps2d: Use redox_event --- Cargo.lock | 1 + input/ps2d/Cargo.toml | 1 + input/ps2d/src/main.rs | 63 +++++++++++++++++++----------------------- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d1329e6a3..cdb562c6cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1039,6 +1039,7 @@ dependencies = [ "log", "orbclient", "redox-daemon", + "redox_event", "redox_syscall", ] diff --git a/input/ps2d/Cargo.toml b/input/ps2d/Cargo.toml index 233e027e6f..212a3e078a 100644 --- a/input/ps2d/Cargo.toml +++ b/input/ps2d/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" bitflags = "1" log = "0.4" orbclient = "0.3.27" +redox_event = "0.4.1" redox_syscall = "0.5" redox-daemon = "0.1" libredox = "0.1.3" diff --git a/input/ps2d/src/main.rs b/input/ps2d/src/main.rs index 5455aaa161..7399bbd0a2 100644 --- a/input/ps2d/src/main.rs +++ b/input/ps2d/src/main.rs @@ -6,11 +6,12 @@ extern crate orbclient; extern crate syscall; use std::fs::OpenOptions; -use std::io::{Read, Write}; +use std::io::Read; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::AsRawFd; use std::{env, process}; +use event::{user_data, EventQueue}; use log::info; use syscall::call::iopl; @@ -54,11 +55,15 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .open("/scheme/input/producer") .expect("ps2d: failed to open /scheme/input/producer"); - let mut event_file = OpenOptions::new() - .read(true) - .write(true) - .open("/scheme/event") - .expect("ps2d: failed to open /scheme/event"); + user_data! { + enum Source { + Keyboard, + Mouse, + } + } + + let event_queue: EventQueue = + EventQueue::new().expect("ps2d: failed to create event queue"); let mut key_file = OpenOptions::new() .read(true) @@ -67,13 +72,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .open("/scheme/serio/0") .expect("ps2d: failed to open /scheme/serio/0"); - event_file - .write(&syscall::Event { - id: key_file.as_raw_fd() as usize, - flags: syscall::EVENT_READ, - data: 0, - }) - .expect("ps2d: failed to event /scheme/serio/0"); + event_queue + .subscribe( + key_file.as_raw_fd() as usize, + Source::Keyboard, + event::EventFlags::READ, + ) + .unwrap(); let mut mouse_file = OpenOptions::new() .read(true) @@ -82,13 +87,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .open("/scheme/serio/1") .expect("ps2d: failed to open /scheme/serio/1"); - event_file - .write(&syscall::Event { - id: mouse_file.as_raw_fd() as usize, - flags: syscall::EVENT_READ, - data: 1, - }) - .expect("ps2d: failed to event /scheme/serio/1"); + event_queue + .subscribe( + mouse_file.as_raw_fd() as usize, + Source::Mouse, + event::EventFlags::READ, + ) + .unwrap(); libredox::call::setrens(0, 0).expect("ps2d: failed to enter null namespace"); @@ -99,7 +104,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut ps2d = Ps2d::new(input, keymap); let mut data = [0; 256]; - loop { + for event in event_queue.map(|e| e.expect("ps2d: failed to get next event").user_data) { // There are some gotchas with ps/2 controllers that require this weird // way of doing things. You read key and mouse data from the same // place. There is a status register that may show you which the data @@ -109,19 +114,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { // Due to this, we have a kernel driver doing a small amount of work // to grab bytes and sort them based on the source - let mut event = syscall::Event::default(); - if event_file - .read(&mut event) - .expect("ps2d: failed to read event file") - == 0 - { - break; - } - - let (file, keyboard) = match event.data { - 0 => (&mut key_file, true), - 1 => (&mut mouse_file, false), - _ => continue, + let (file, keyboard) = match event { + Source::Keyboard => (&mut key_file, true), + Source::Mouse => (&mut mouse_file, false), }; loop { From aa35e573cf94157065b100225930caf5bc31c6d1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Dec 2024 15:28:34 +0100 Subject: [PATCH 3/5] input: Introduce ProducerHandle type --- Cargo.lock | 3 +++ graphics/bgad/Cargo.toml | 1 + graphics/bgad/src/main.rs | 3 ++- graphics/bgad/src/scheme.rs | 9 ++++--- input/ps2d/Cargo.toml | 1 + input/ps2d/src/main.rs | 6 ++--- input/ps2d/src/state.rs | 48 +++++++++++++++++-------------------- input/usbhidd/Cargo.toml | 1 + input/usbhidd/src/main.rs | 18 +++++++------- inputd/src/lib.rs | 13 ++++++++++ 10 files changed, 57 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cdb562c6cc..a56be31c9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,7 @@ name = "bgad" version = "0.1.0" dependencies = [ "common", + "inputd", "libredox", "orbclient", "pcid", @@ -1035,6 +1036,7 @@ version = "0.1.0" dependencies = [ "bitflags 1.3.2", "common", + "inputd", "libredox", "log", "orbclient", @@ -1594,6 +1596,7 @@ version = "0.1.0" dependencies = [ "bitflags 2.6.0", "common", + "inputd", "log", "orbclient", "redox_syscall", diff --git a/graphics/bgad/Cargo.toml b/graphics/bgad/Cargo.toml index 4e9fe1ae5f..eadf2c22f9 100644 --- a/graphics/bgad/Cargo.toml +++ b/graphics/bgad/Cargo.toml @@ -9,5 +9,6 @@ redox-daemon = "0.1" redox_syscall = "0.5" common = { path = "../../common" } +inputd = { path = "../../inputd" } pcid = { path = "../../pcid" } libredox = "0.1.3" diff --git a/graphics/bgad/src/main.rs b/graphics/bgad/src/main.rs index ad3a4fe393..a208db2b27 100644 --- a/graphics/bgad/src/main.rs +++ b/graphics/bgad/src/main.rs @@ -4,6 +4,7 @@ extern crate syscall; use std::fs::File; use std::io::{Read, Write}; +use inputd::ProducerHandle; use pcid_interface::PciFunctionHandle; use syscall::call::iopl; use syscall::data::Packet; @@ -35,7 +36,7 @@ fn main() { let mut scheme = BgaScheme { bga, - display: File::open("/scheme/input/producer").ok(), + display: ProducerHandle::new().ok(), }; scheme.update_size(); diff --git a/graphics/bgad/src/scheme.rs b/graphics/bgad/src/scheme.rs index 1a1315df0e..197f0ec01d 100644 --- a/graphics/bgad/src/scheme.rs +++ b/graphics/bgad/src/scheme.rs @@ -1,6 +1,5 @@ -use std::fs::File; -use std::io::Write; use std::str; +use inputd::ProducerHandle; use syscall::data::Stat; use syscall::{Error, Result, SchemeMut, EACCES, EINVAL, MODE_CHR}; @@ -8,14 +7,14 @@ use crate::bga::Bga; pub struct BgaScheme { pub bga: Bga, - pub display: Option, + pub display: Option, } impl BgaScheme { pub fn update_size(&mut self) { if let Some(ref mut display) = self.display { - let _ = display.write( - &orbclient::ResizeEvent { + let _ = display.write_event( + orbclient::ResizeEvent { width: self.bga.width() as u32, height: self.bga.height() as u32, } diff --git a/input/ps2d/Cargo.toml b/input/ps2d/Cargo.toml index 212a3e078a..9e3298eb17 100644 --- a/input/ps2d/Cargo.toml +++ b/input/ps2d/Cargo.toml @@ -13,3 +13,4 @@ redox-daemon = "0.1" libredox = "0.1.3" common = { path = "../../common" } +inputd = { path = "../../inputd" } diff --git a/input/ps2d/src/main.rs b/input/ps2d/src/main.rs index 7399bbd0a2..186904cf9a 100644 --- a/input/ps2d/src/main.rs +++ b/input/ps2d/src/main.rs @@ -12,6 +12,7 @@ use std::os::unix::io::AsRawFd; use std::{env, process}; use event::{user_data, EventQueue}; +use inputd::ProducerHandle; use log::info; use syscall::call::iopl; @@ -50,10 +51,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { info!("ps2d: using keymap '{}'", keymap_name); - let input = OpenOptions::new() - .write(true) - .open("/scheme/input/producer") - .expect("ps2d: failed to open /scheme/input/producer"); + let input = ProducerHandle::new().expect("ps2d: failed to open input producer"); user_data! { enum Source { diff --git a/input/ps2d/src/state.rs b/input/ps2d/src/state.rs index b25cec9455..711c7bfbbf 100644 --- a/input/ps2d/src/state.rs +++ b/input/ps2d/src/state.rs @@ -1,8 +1,4 @@ -use std::fs::File; -use std::io::Write; -use std::os::unix::io::AsRawFd; -use std::str; - +use inputd::ProducerHandle; use log::{error, warn}; use orbclient::{ButtonEvent, KeyEvent, MouseEvent, MouseRelativeEvent, ScrollEvent}; @@ -26,7 +22,7 @@ pub struct Ps2d char> { ps2: Ps2, vmmouse: bool, vmmouse_relative: bool, - input: File, + input: ProducerHandle, extended: bool, lshift: bool, rshift: bool, @@ -43,7 +39,7 @@ pub struct Ps2d char> { } impl char> Ps2d { - pub fn new(input: File, keymap: F) -> Self { + pub fn new(input: ProducerHandle, keymap: F) -> Self { let mut ps2 = Ps2::new(); let extra_packet = ps2.init().expect("ps2d: failed to initialize"); @@ -229,8 +225,8 @@ impl char> Ps2d { if scancode != 0 { self.input - .write( - &KeyEvent { + .write_event( + KeyEvent { character: (self.get_char)( ps2_scancode, self.lshift || self.rshift, @@ -263,8 +259,8 @@ impl char> Ps2d { if self.vmmouse_relative { if dx != 0 || dy != 0 { self.input - .write( - &MouseRelativeEvent { + .write_event( + MouseRelativeEvent { dx: dx as i32, dy: dy as i32, } @@ -279,15 +275,15 @@ impl char> Ps2d { self.mouse_x = x; self.mouse_y = y; self.input - .write(&MouseEvent { x, y }.to_event()) + .write_event(MouseEvent { x, y }.to_event()) .expect("ps2d: failed to write mouse event"); } }; if dz != 0 { self.input - .write( - &ScrollEvent { + .write_event( + ScrollEvent { x: 0, y: -(dz as i32), } @@ -307,11 +303,11 @@ impl char> Ps2d { self.mouse_middle = middle; self.mouse_right = right; self.input - .write( - &ButtonEvent { - left: left, - middle: middle, - right: right, + .write_event( + ButtonEvent { + left, + middle, + right, } .to_event(), ) @@ -355,13 +351,13 @@ impl char> Ps2d { if dx != 0 || dy != 0 { self.input - .write(&MouseRelativeEvent { dx: dx, dy: dy }.to_event()) + .write_event(MouseRelativeEvent { dx, dy }.to_event()) .expect("ps2d: failed to write mouse event"); } if dz != 0 { self.input - .write(&ScrollEvent { x: 0, y: dz }.to_event()) + .write_event(ScrollEvent { x: 0, y: dz }.to_event()) .expect("ps2d: failed to write scroll event"); } @@ -376,11 +372,11 @@ impl char> Ps2d { self.mouse_middle = middle; self.mouse_right = right; self.input - .write( - &ButtonEvent { - left: left, - middle: middle, - right: right, + .write_event( + ButtonEvent { + left, + middle, + right, } .to_event(), ) diff --git a/input/usbhidd/Cargo.toml b/input/usbhidd/Cargo.toml index 0d5929a857..0a3df4d43c 100644 --- a/input/usbhidd/Cargo.toml +++ b/input/usbhidd/Cargo.toml @@ -16,3 +16,4 @@ rehid = { git = "https://gitlab.redox-os.org/redox-os/rehid.git" } xhcid = { path = "../../xhcid" } common = { path = "../../common" } +inputd = { path = "../../inputd" } diff --git a/input/usbhidd/src/main.rs b/input/usbhidd/src/main.rs index ca19f1905d..ed79994e1a 100644 --- a/input/usbhidd/src/main.rs +++ b/input/usbhidd/src/main.rs @@ -1,8 +1,7 @@ use std::collections::VecDeque; use std::env; -use std::fs::File; -use std::io::{Read, Write}; +use inputd::ProducerHandle; use orbclient::KeyEvent as OrbKeyEvent; use rehid::{ report_desc::{self, ReportTy, REPORT_DESC_TY}, @@ -17,7 +16,7 @@ mod keymap; mod reqs; fn send_key_event( - display: &mut File, + display: &mut ProducerHandle, usage_page: u16, usage: u16, pressed: bool, @@ -159,7 +158,7 @@ fn send_key_event( pressed, }; - match display.write(&key_event.to_event()) { + match display.write_event(key_event.to_event()) { Ok(_) => (), Err(err) => { log::warn!("failed to send key event to orbital: {}", err); @@ -277,8 +276,7 @@ fn main() { let report_ty = ReportTy::Input; let report_id = 0; - let mut display = - File::open("/scheme/input/producer").expect("Failed to open orbital input socket"); + let mut display = ProducerHandle::new().expect("Failed to open input socket"); let mut endpoint_opt = match endp_desc_opt { Some((endp_num, _endp_desc)) => match handle.open_endpoint(endp_num as u8) { Ok(ok) => Some(ok), @@ -405,7 +403,7 @@ fn main() { y: mouse_pos.1 * 2, }; - match display.write(&mouse_event.to_event()) { + match display.write_event(mouse_event.to_event()) { Ok(_) => (), Err(err) => { log::warn!("failed to send mouse event to orbital: {}", err); @@ -419,7 +417,7 @@ fn main() { dy: mouse_dy, }; - match display.write(&mouse_event.to_event()) { + match display.write_event(mouse_event.to_event()) { Ok(_) => (), Err(err) => { log::warn!("failed to send mouse event to orbital: {}", err); @@ -430,7 +428,7 @@ fn main() { if scroll_y != 0 { let scroll_event = orbclient::event::ScrollEvent { x: 0, y: scroll_y }; - match display.write(&scroll_event.to_event()) { + match display.write_event(scroll_event.to_event()) { Ok(_) => (), Err(err) => { log::warn!("failed to send scroll event to orbital: {}", err); @@ -447,7 +445,7 @@ fn main() { middle: buttons[2], }; - match display.write(&button_event.to_event()) { + match display.write_event(button_event.to_event()) { Ok(_) => (), Err(err) => { log::warn!("failed to send button event to orbital: {}", err); diff --git a/inputd/src/lib.rs b/inputd/src/lib.rs index 8956964ed6..4bc019d4ad 100644 --- a/inputd/src/lib.rs +++ b/inputd/src/lib.rs @@ -162,3 +162,16 @@ impl Damage { self } } + +pub struct ProducerHandle(File); + +impl ProducerHandle { + pub fn new() -> Result { + File::open("/scheme/input/producer").map(ProducerHandle) + } + + pub fn write_event(&mut self, event: orbclient::Event) -> Result<(), Error> { + self.0.write(&event)?; + Ok(()) + } +} From f4897c59b46437d8fc0b5d55dcd3919d85f58e5c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Dec 2024 16:34:25 +0100 Subject: [PATCH 4/5] graphics/fbcond: Inline some helpers --- graphics/fbcond/src/display.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/graphics/fbcond/src/display.rs b/graphics/fbcond/src/display.rs index 2cd4d897dd..d38d99981e 100644 --- a/graphics/fbcond/src/display.rs +++ b/graphics/fbcond/src/display.rs @@ -157,22 +157,8 @@ impl Display { let url = String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String"); - let path = Self::url_parts(&url)?; - let (width, height) = Self::parse_display_path(path); + let path = url.split(':').nth(1).expect("Could not get path from url"); - Ok((display_file, width, height)) - } - - fn url_parts(url: &str) -> io::Result<&str> { - let mut url_parts = url.split(':'); - url_parts - .next() - .expect("Could not get scheme name from url"); - let path = url_parts.next().expect("Could not get path from url"); - Ok(path) - } - - fn parse_display_path(path: &str) -> (usize, usize) { let mut path_parts = path.split('/').skip(1); let width = path_parts .next() @@ -185,7 +171,7 @@ impl Display { .parse::() .unwrap_or(0); - (width, height) + Ok((display_file, width, height)) } pub fn resize(&mut self, width: usize, height: usize) { From 5a1648fdca13d5f7fa656fee98d01a55d1daa31e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 24 Dec 2024 16:56:11 +0100 Subject: [PATCH 5/5] graphics/fbcond: Migrate to redox-scheme --- Cargo.lock | 1 + graphics/fbcond/Cargo.toml | 1 + graphics/fbcond/src/main.rs | 109 +++++++++++++++------------------- graphics/fbcond/src/scheme.rs | 79 +++++++++++++----------- graphics/fbcond/src/text.rs | 8 +-- 5 files changed, 98 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a56be31c9d..fc46dcb053 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,6 +424,7 @@ dependencies = [ "orbclient", "ransid", "redox-daemon", + "redox-scheme", "redox_event", "redox_syscall", ] diff --git a/graphics/fbcond/Cargo.toml b/graphics/fbcond/Cargo.toml index 42e155eaac..a22c102f40 100644 --- a/graphics/fbcond/Cargo.toml +++ b/graphics/fbcond/Cargo.toml @@ -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" diff --git a/graphics/fbcond/src/main.rs b/graphics/fbcond/src/main.rs index 09c9a44478..11ac25cec2 100644 --- a/graphics/fbcond/src/main.rs +++ b/graphics/fbcond/src/main.rs @@ -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, + blocked: &mut Vec, 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 { diff --git a/graphics/fbcond/src/scheme.rs b/graphics/fbcond/src/scheme.rs index 4b8afe212e..1b37b6674c 100644 --- a/graphics/fbcond/src/scheme.rs +++ b/graphics/fbcond/src/scheme.rs @@ -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 { - 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 { +impl SchemeBlockMut for FbconScheme { + fn open( + &mut self, + path_str: &str, + flags: usize, + _uid: u32, + _gid: u32, + ) -> Result> { let vt_i = VtIndex(path_str.parse::().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 { + fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { 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 { + fn fevent( + &mut self, + id: usize, + flags: syscall::EventFlags, + ) -> Result> { 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 { + fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { 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 { + fn fsync(&mut self, id: usize) -> Result> { 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 { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { 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 { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { 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 { + fn close(&mut self, id: usize) -> Result> { self.handles.remove(&id).ok_or(Error::new(EBADF))?; - Ok(0) + Ok(Some(0)) } } diff --git a/graphics/fbcond/src/text.rs b/graphics/fbcond/src/text.rs index d62b15f502..bbe519b117 100644 --- a/graphics/fbcond/src/text.rs +++ b/graphics/fbcond/src/text.rs @@ -204,12 +204,8 @@ impl TextScreen { } } - pub fn can_read(&self) -> Option { - if self.input.is_empty() { - None - } else { - Some(self.input.len()) - } + pub fn can_read(&self) -> bool { + !self.input.is_empty() } }