From 95a84c8cbf34b0bcc0e77ee1ea32816cfa3656c5 Mon Sep 17 00:00:00 2001 From: Anhad Singh Date: Sat, 15 Jul 2023 16:29:48 +1000 Subject: [PATCH] inputd: fix failure to switch VT after inital switch Signed-off-by: Anhad Singh --- inputd/src/main.rs | 45 ++++++++++++++-------------- vesad/src/scheme.rs | 72 +++++++++++++++++---------------------------- 2 files changed, 49 insertions(+), 68 deletions(-) diff --git a/inputd/src/main.rs b/inputd/src/main.rs index a963789c06..b06a0c247d 100644 --- a/inputd/src/main.rs +++ b/inputd/src/main.rs @@ -44,7 +44,7 @@ struct InputScheme { vts: BTreeMap>, super_key: bool, - active_vt: Option<(Arc, File)>, + active_vt: Option<(Arc, File, usize /* VT index */)>, } impl InputScheme { @@ -156,38 +156,37 @@ impl SchemeMut for InputScheme { _ => continue, } + let deactivate = |vt, current| { + // Drop the old active VT first. + // + // TODO(andypython): This can be drastically improved by introducting something + // like ioctl() to the display scheme. + let deactivate = format!("display/{}:{current}/deactivate", vt); + let _ = File::open(&deactivate); + }; + if let Some(new_active) = new_active_opt { if let Some(vt) = self.vts.get(&new_active) { // If the VT is already active, don't do anything. - if let Some(current) = self.active_vt.as_ref() { - if vt == ¤t.0 { + if let Some((vt, _, current)) = self.active_vt.as_ref() { + if new_active == *current { continue; } + + deactivate(vt, *current); + } else { + let id = self.next_vt_id.load(Ordering::SeqCst) - 1; + let vt = self.vts.get(&id).unwrap(); + + deactivate(vt, id); } - + // Result: display/virtio-gpu:3/acvtivate let activate = format!("display/{vt}:{new_active}/activate"); - log::info!("inputd: switching to VT #{new_active} ({activate})"); - - // Drop the old active VT first. - // - // TODO(andypython): This can be drastically improved by introducting something - // like ioctl() to the display scheme. - for (vt, device) in self.vts.iter() { - if vt == &new_active { - continue; - } - - let deactivate = format!("display/{device}:{}/deactivate", vt); - let _ = File::open(&deactivate); - - if device.contains("virtio") { - break; - } - } + log::info!("inputd: switching to VT #{new_active} (`{activate}`)"); let file = File::open(&activate).unwrap(); - self.active_vt = Some((vt.clone(), file)); + self.active_vt = Some((vt.clone(), file, new_active)); } else { log::warn!("inputd: switch to non-existent VT #{new_active} was requested"); } diff --git a/vesad/src/scheme.rs b/vesad/src/scheme.rs index 493eb7888e..7577ace6fc 100644 --- a/vesad/src/scheme.rs +++ b/vesad/src/scheme.rs @@ -10,10 +10,10 @@ use crate::{ screen::{Screen, GraphicScreen, TextScreen}, }; -#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Debug)] pub struct VtIndex(usize); -#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Debug)] pub struct ScreenIndex(usize); #[derive(Clone)] @@ -144,61 +144,43 @@ impl DisplayScheme { } impl SchemeMut for DisplayScheme { - fn open(&mut self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result { - if path_str == "input" { - if uid == 0 { + fn open(&mut self, path_str: &str, flags: usize, _uid: u32, _gid: u32) -> Result { + let mut parts = path_str.split('/'); + let mut vt_screen = parts.next().unwrap_or("").split('.'); + let vt_i = VtIndex( + vt_screen.next().unwrap_or("").parse::().unwrap_or(1) + ); + let screen_i = ScreenIndex( + vt_screen.next().unwrap_or("").parse::().unwrap_or(0) + ); + if let Some(screens) = self.vts.get_mut(&vt_i) { + if let Some(screen) = screens.get_mut(&screen_i) { + for cmd in parts { + if cmd == "activate" { + self.active = vt_i; + screen.redraw( + self.onscreens[screen_i.0], + self.framebuffers[screen_i.0].stride + ); + } + } + let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle { - kind: HandleKind::Input, - flags: flags, + kind: HandleKind::Screen(vt_i, screen_i), + flags, events: EventFlags::empty(), notified_read: false }); Ok(id) - } else { - Err(Error::new(EACCES)) - } - } else { - let mut parts = path_str.split('/'); - let mut vt_screen = parts.next().unwrap_or("").split('.'); - let vt_i = VtIndex( - vt_screen.next().unwrap_or("").parse::().unwrap_or(1) - ); - let screen_i = ScreenIndex( - vt_screen.next().unwrap_or("").parse::().unwrap_or(0) - ); - if let Some(screens) = self.vts.get_mut(&vt_i) { - if let Some(screen) = screens.get_mut(&screen_i) { - for cmd in parts { - if cmd == "activate" { - self.active = vt_i; - screen.redraw( - self.onscreens[screen_i.0], - self.framebuffers[screen_i.0].stride - ); - } - } - - let id = self.next_id; - self.next_id += 1; - - self.handles.insert(id, Handle { - kind: HandleKind::Screen(vt_i, screen_i), - flags: flags, - events: EventFlags::empty(), - notified_read: false - }); - - Ok(id) - } else { - Err(Error::new(ENOENT)) - } } else { Err(Error::new(ENOENT)) } + } else { + Err(Error::new(ENOENT)) } }