diff --git a/local/recipes/system/redbear-accessibility/source/src/main.rs b/local/recipes/system/redbear-accessibility/source/src/main.rs index e661e00805..9b9340c609 100644 --- a/local/recipes/system/redbear-accessibility/source/src/main.rs +++ b/local/recipes/system/redbear-accessibility/source/src/main.rs @@ -3,19 +3,25 @@ mod scheme; use scheme::AccessibilityScheme; use std::io::Write; +use redox_scheme::{RequestKind, SignalBehavior, Socket}; +use redox_scheme::scheme::{SchemeState, SchemeSync, register_sync_scheme}; + fn log_msg(level: &str, msg: &str) { let _ = writeln!(std::io::stderr(), "[accessibility] {} {}", level, msg); } fn main() { let mut scheme = AccessibilityScheme::new(); + let mut state = SchemeState::new(); - let socket = redox_scheme::Socket::create("accessibility") + let socket = Socket::create() + .expect("accessibility: failed to create scheme socket"); + register_sync_scheme(&socket, "accessibility", &mut scheme) .expect("accessibility: failed to register scheme:accessibility"); log_msg("INFO", "registered scheme:accessibility"); loop { - let request = match socket.next_request(redox_scheme::SignalBehavior::Restart) { + let request = match socket.next_request(SignalBehavior::Restart) { Ok(Some(r)) => r, Ok(None) => { log_msg("INFO", "scheme unmounted, exiting"); @@ -27,17 +33,19 @@ fn main() { } }; - match request.handle_scheme_block_mut(&mut scheme) { - Ok(response) => { - if let Err(e) = - socket.write_response(response, redox_scheme::SignalBehavior::Restart) - { - log_msg("ERROR", &format!("failed to write response: {}", e)); - } - } - Err(_request) => { - log_msg("ERROR", "unhandled scheme request"); + let req = match request.kind() { + RequestKind::Call(c) => c, + RequestKind::OnClose { id } => { + scheme.on_close(id); + state.on_close(id); + continue; } + _ => continue, + }; + + let response = req.handle_sync(&mut scheme, &mut state); + if let Err(e) = socket.write_response(response, SignalBehavior::Restart) { + log_msg("ERROR", &format!("failed to write response: {}", e)); } } } diff --git a/local/recipes/system/redbear-accessibility/source/src/scheme.rs b/local/recipes/system/redbear-accessibility/source/src/scheme.rs index fd3f846bf3..d40c68fafc 100644 --- a/local/recipes/system/redbear-accessibility/source/src/scheme.rs +++ b/local/recipes/system/redbear-accessibility/source/src/scheme.rs @@ -1,8 +1,11 @@ +use redox_scheme::{CallerCtx, OpenResult}; +use redox_scheme::scheme::SchemeSync; use std::collections::HashMap; use syscall::data::Stat; use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT}; use syscall::flag::{MODE_DIR, MODE_FILE}; +use syscall::schemev2::NewFdFlags; #[derive(Clone, Copy, Debug, PartialEq)] pub(crate) enum StickyKeyState { @@ -140,8 +143,22 @@ impl AccessibilityScheme { } } -impl redox_scheme::SchemeBlockMut for AccessibilityScheme { - fn open(&mut self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result> { +impl SchemeSync for AccessibilityScheme { + fn scheme_root(&mut self) -> Result { + let id = self.next_id; + self.next_id += 1; + self.handles.insert(id, Handle { kind: HandleKind::Root, offset: 0 }); + Ok(id) + } + + fn openat( + &mut self, + _dirfd: usize, + path: &str, + _flags: usize, + _fcntl_flags: u32, + _ctx: &CallerCtx, + ) -> Result { let cleaned = path.trim_matches('/'); let kind = match cleaned { "" => HandleKind::Root, @@ -154,13 +171,23 @@ impl redox_scheme::SchemeBlockMut for AccessibilityScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle { kind, offset: 0 }); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { - let (kind, offset) = { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _fcntl_flags: u32, + _ctx: &CallerCtx, + ) -> Result { + let kind = { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; - (handle.kind.clone(), handle.offset) + handle.kind.clone() }; let content: Vec = match &kind { @@ -211,18 +238,27 @@ impl redox_scheme::SchemeBlockMut for AccessibilityScheme { } }; - let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; + let offset = offset as usize; if offset >= content.len() { - return Ok(Some(0)); + return Ok(0); } let remaining = &content[offset..]; let to_copy = remaining.len().min(buf.len()); buf[..to_copy].copy_from_slice(&remaining[..to_copy]); - handle.offset += to_copy; - Ok(Some(to_copy)) + + let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; + handle.offset = offset + to_copy; + Ok(to_copy) } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _fcntl_flags: u32, + _ctx: &CallerCtx, + ) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; match &handle.kind { HandleKind::Config => { @@ -249,7 +285,7 @@ impl redox_scheme::SchemeBlockMut for AccessibilityScheme { } } } - Ok(Some(buf.len())) + Ok(buf.len()) } HandleKind::StickyKeys => { let input = String::from_utf8_lossy(buf); @@ -272,23 +308,18 @@ impl redox_scheme::SchemeBlockMut for AccessibilityScheme { .unwrap_or(0); let _ = self.filter_key(code, pressed, now_ms); } - Ok(Some(buf.len())) + Ok(buf.len()) } _ => Err(Error::new(EINVAL)), } } - fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; match &handle.kind { HandleKind::Root => stat.st_mode = MODE_DIR | 0o555, _ => stat.st_mode = MODE_FILE | 0o644, } - Ok(Some(0)) - } - - fn close(&mut self, id: usize) -> Result> { - self.handles.remove(&id); - Ok(Some(0)) + Ok(()) } }