inputd: fix failure to switch VT after inital switch
Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
+22
-23
@@ -44,7 +44,7 @@ struct InputScheme {
|
||||
|
||||
vts: BTreeMap<usize, Arc<String>>,
|
||||
super_key: bool,
|
||||
active_vt: Option<(Arc<String>, File)>,
|
||||
active_vt: Option<(Arc<String>, 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");
|
||||
}
|
||||
|
||||
+27
-45
@@ -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<usize> {
|
||||
if path_str == "input" {
|
||||
if uid == 0 {
|
||||
fn open(&mut self, path_str: &str, flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
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::<usize>().unwrap_or(1)
|
||||
);
|
||||
let screen_i = ScreenIndex(
|
||||
vt_screen.next().unwrap_or("").parse::<usize>().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::<usize>().unwrap_or(1)
|
||||
);
|
||||
let screen_i = ScreenIndex(
|
||||
vt_screen.next().unwrap_or("").parse::<usize>().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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user