diff --git a/graphics/fbcond/src/main.rs b/graphics/fbcond/src/main.rs index 4393c9185c..7449d5a4d7 100644 --- a/graphics/fbcond/src/main.rs +++ b/graphics/fbcond/src/main.rs @@ -53,11 +53,13 @@ fn inner(daemon: redox_daemon::Daemon, vt_ids: &[usize]) -> ! { let mut scheme = FbconScheme::new(vt_ids, &mut event_queue); + let mut inputd_control_handle = inputd::ControlHandle::new().unwrap(); + libredox::call::setrens(0, 0).expect("fbcond: failed to enter null namespace"); daemon.ready().expect("failed to notify parent"); - scheme.inputd_handle.activate(1).unwrap(); + inputd_control_handle.activate_vt(1).unwrap(); let mut blocked = Vec::new(); diff --git a/graphics/fbcond/src/scheme.rs b/graphics/fbcond/src/scheme.rs index bd128f2e5a..9ff10d4dbe 100644 --- a/graphics/fbcond/src/scheme.rs +++ b/graphics/fbcond/src/scheme.rs @@ -36,13 +36,10 @@ pub struct FbconScheme { pub vts: BTreeMap, next_id: usize, pub handles: BTreeMap, - pub inputd_handle: inputd::Handle, } impl FbconScheme { pub fn new(vt_ids: &[usize], event_queue: &mut EventQueue) -> FbconScheme { - let inputd_handle = inputd::Handle::new("vesa").unwrap(); - let mut vts = BTreeMap::new(); for &vt_i in vt_ids { @@ -61,7 +58,6 @@ impl FbconScheme { vts, next_id: 0, handles: BTreeMap::new(), - inputd_handle, } } diff --git a/graphics/vesad/src/main.rs b/graphics/vesad/src/main.rs index 9b01e97624..6bbab330e1 100644 --- a/graphics/vesad/src/main.rs +++ b/graphics/vesad/src/main.rs @@ -86,11 +86,13 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[( let _ = File::open("/scheme/debug/disable-graphical-debug"); + let mut inputd_control_handle = inputd::ControlHandle::new().unwrap(); + libredox::call::setrens(0, 0).expect("vesad: failed to enter null namespace"); daemon.ready().expect("failed to notify parent"); - scheme.inputd_handle.activate(1).unwrap(); + inputd_control_handle.activate_vt(1).unwrap(); let mut blocked = Vec::new(); loop { diff --git a/graphics/vesad/src/scheme.rs b/graphics/vesad/src/scheme.rs index 65baf8dace..b3218b2834 100644 --- a/graphics/vesad/src/scheme.rs +++ b/graphics/vesad/src/scheme.rs @@ -32,12 +32,12 @@ pub struct DisplayScheme { pub vts: BTreeMap>, next_id: usize, pub handles: BTreeMap, - pub inputd_handle: inputd::Handle, + _inputd_handle: inputd::DisplayHandle, } impl DisplayScheme { pub fn new(framebuffers: Vec, spec: &[()]) -> DisplayScheme { - let mut inputd_handle = inputd::Handle::new("vesa").unwrap(); + let mut inputd_handle = inputd::DisplayHandle::new("vesa").unwrap(); let mut vts = BTreeMap::>::new(); @@ -47,7 +47,7 @@ impl DisplayScheme { let fb = &framebuffers[fb_i]; screens.insert(ScreenIndex(fb_i), GraphicScreen::new(fb.width, fb.height)); } - vts.insert(VtIndex(inputd_handle.register().unwrap()), screens); + vts.insert(VtIndex(inputd_handle.register_vt().unwrap()), screens); } DisplayScheme { @@ -56,7 +56,7 @@ impl DisplayScheme { vts, next_id: 0, handles: BTreeMap::new(), - inputd_handle, + _inputd_handle: inputd_handle, } } diff --git a/inputd/src/lib.rs b/inputd/src/lib.rs index 6c55e96949..1b1dc3a2ff 100644 --- a/inputd/src/lib.rs +++ b/inputd/src/lib.rs @@ -13,9 +13,9 @@ pub struct VtActivate { pub vt: usize, } -pub struct Handle(File); +pub struct DisplayHandle(File); -impl Handle { +impl DisplayHandle { pub fn new>(device_name: S) -> Result { let path = format!("/scheme/input/handle/display/{}", device_name.into()); Ok(Self(File::open(path)?)) @@ -23,11 +23,21 @@ impl Handle { // The return value is the display identifier. It will be used to uniquely // identify the display on activation events. - pub fn register(&mut self) -> Result { + pub fn register_vt(&mut self) -> Result { self.0.read(&mut []) } - pub fn activate(&mut self, vt: usize) -> Result { +} + +pub struct ControlHandle(File); + +impl ControlHandle { + pub fn new() -> Result { + let path = format!("/scheme/input/control"); + Ok(Self(File::open(path)?)) + } + + pub fn activate_vt(&mut self, vt: usize) -> Result { let cmd = VtActivate { vt }; self.0.write(unsafe { any_as_u8_slice(&cmd) }) } diff --git a/inputd/src/main.rs b/inputd/src/main.rs index 8aa562a888..66f204adae 100644 --- a/inputd/src/main.rs +++ b/inputd/src/main.rs @@ -13,7 +13,6 @@ use std::collections::BTreeMap; use std::fs::File; -use std::os::fd::AsRawFd; use std::sync::atomic::{AtomicUsize, Ordering}; use inputd::{Cmd, VtActivate}; @@ -31,9 +30,10 @@ enum Handle { notified: bool, vt: usize, }, - Device { + Display { device: String, }, + Control, } impl Handle { @@ -123,8 +123,9 @@ impl SchemeMut for InputScheme { } "handle" => { let display = path_parts.collect::>().join("."); - Handle::Device { device: display } + Handle::Display { device: display } } + "control" => Handle::Control, _ => { log::error!("inputd: invalid path {path}"); @@ -174,7 +175,7 @@ impl SchemeMut for InputScheme { Ok(copy) } - Handle::Device { device } => { + Handle::Display { device } => { assert!(buf.is_empty()); let vt = self.next_vt_id.fetch_add(1, Ordering::SeqCst); @@ -186,6 +187,10 @@ impl SchemeMut for InputScheme { log::error!("inputd: producer tried to read"); return Err(SysError::new(EINVAL)); } + Handle::Control => { + log::error!("inputd: control tried to read"); + return Err(SysError::new(EINVAL)); + } } } @@ -201,16 +206,15 @@ impl SchemeMut for InputScheme { let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?; match handle { - Handle::Device { device } => { + Handle::Control => { if buf.len() != core::mem::size_of::() { - log::error!("inputd: device tried to write incorrectly sized command"); + log::error!("inputd: control tried to write incorrectly sized command"); return Err(SysError::new(EINVAL)); } // SAFETY: We have verified the size of the buffer above. let cmd = unsafe { &*buf.as_ptr().cast::() }; - self.vts.insert(cmd.vt, Vt::new(device.clone(), cmd.vt)); self.pending_activate = Some(cmd.clone()); return Ok(buf.len()); @@ -220,6 +224,10 @@ impl SchemeMut for InputScheme { log::error!("inputd: consumer tried to write"); return Err(SysError::new(EINVAL)); } + Handle::Display { .. } => { + log::error!("inputd: display tried to write"); + return Err(SysError::new(EINVAL)); + } Handle::Producer => {} } @@ -340,8 +348,8 @@ impl SchemeMut for InputScheme { *notified = false; Ok(EventFlags::empty()) } - Handle::Producer | Handle::Device { .. } => { - log::error!("inputd: producer or device tried to use an event queue"); + Handle::Producer | Handle::Control | Handle::Display { .. } => { + log::error!("inputd: producer, control or display tried to use an event queue"); Err(SysError::new(EINVAL)) } } @@ -378,13 +386,16 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { } if let Some(cmd) = scheme.pending_activate.take() { - let vt = scheme.vts.get_mut(&cmd.vt).unwrap(); - // Failing to activate a VT is not a fatal error. - if let Err(err) = vt.send_command(Cmd::Activate { vt: vt.index }) { - log::error!("inputd: failed to activate VT #{}: {err}", vt.index) - } + if let Some(vt) = scheme.vts.get_mut(&cmd.vt) { + // Failing to activate a VT is not a fatal error. + if let Err(err) = vt.send_command(Cmd::Activate { vt: vt.index }) { + log::error!("inputd: failed to activate VT #{}: {err}", vt.index) + } - scheme.active_vt = Some(vt.index); + scheme.active_vt = Some(vt.index); + } else { + log::error!("inputd: failed to activate non-existent VT #{}", cmd.vt) + } } if !scheme.has_new_events { @@ -442,31 +453,11 @@ fn main() { "-A" => { let vt = args.next().unwrap().parse::().unwrap(); - let handle = File::open(format!("/scheme/input/consumer/{vt}")) - .expect("inputd: failed to open consumer handle"); - let mut display_path = [0; 4096]; - - let written = libredox::call::fpath(handle.as_raw_fd() as usize, &mut display_path) - .expect("inputd: fpath() failed"); - - assert!(written <= display_path.len()); - drop(handle); - - let display_path = std::str::from_utf8(&display_path[..written]) - .expect("inputd: display path UTF-8 validation failed"); - let display_name = display_path - .split('.') - .skip(1) - .next() - .expect("inputd: invalid display path"); - let display_scheme = display_name - .split(':') - .next() - .expect("inputd: invalid display path"); - - let mut handle = inputd::Handle::new(display_scheme) - .expect("inputd: failed to open display handle"); - handle.activate(vt).expect("inputd: failed to activate VT"); + let mut handle = + inputd::ControlHandle::new().expect("inputd: failed to open display handle"); + handle + .activate_vt(vt) + .expect("inputd: failed to activate VT"); } _ => panic!("inputd: invalid argument: {}", val),