inputd: correctly pass on resize events
Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
+89
-18
@@ -1,6 +1,7 @@
|
||||
#![feature(iter_next_chunk)]
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{Error, Read};
|
||||
use std::mem;
|
||||
|
||||
pub struct Handle(File);
|
||||
|
||||
@@ -19,33 +20,103 @@ impl Handle {
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum CommandTy {
|
||||
enum CmdTy {
|
||||
Unknown = 0,
|
||||
|
||||
Activate,
|
||||
Deactivate,
|
||||
Resize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Command {
|
||||
pub ty: CommandTy,
|
||||
pub value: usize,
|
||||
impl From<u8> for CmdTy {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
1 => CmdTy::Activate,
|
||||
2 => CmdTy::Deactivate,
|
||||
3 => CmdTy::Resize,
|
||||
_ => CmdTy::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub fn new(ty: CommandTy, value: usize) -> Self {
|
||||
Self { ty, value }
|
||||
}
|
||||
pub enum Cmd {
|
||||
// TODO(andypython): #VT should really need to be a `u8`.
|
||||
Activate(usize /* #VT */),
|
||||
Deactivate(usize /* #VT */),
|
||||
Resize {
|
||||
// TODO(andypython): do we really need to pass the VT here?
|
||||
vt: usize,
|
||||
|
||||
/// ## Panics
|
||||
/// This function panics if the buffer is not `sizeof::<Command>()` bytes wide.
|
||||
pub fn parse<'a>(buffer: &'a [u8]) -> &'a Command {
|
||||
assert_eq!(buffer.len(), core::mem::size_of::<Command>());
|
||||
unsafe { &*(buffer.as_ptr() as *const Command) }
|
||||
}
|
||||
width: u32,
|
||||
height: u32,
|
||||
stride: u32,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn into_bytes(self) -> [u8; mem::size_of::<Command>()] {
|
||||
unsafe { core::mem::transmute(self) }
|
||||
impl Cmd {
|
||||
fn ty(&self) -> CmdTy {
|
||||
match self {
|
||||
Cmd::Activate(_) => CmdTy::Activate,
|
||||
Cmd::Deactivate(_) => CmdTy::Deactivate,
|
||||
Cmd::Resize { .. } => CmdTy::Resize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_comand(file: &mut File, command: Cmd) -> Result<(), syscall::Error> {
|
||||
use std::os::fd::AsRawFd;
|
||||
|
||||
let mut result = vec![];
|
||||
result.push(command.ty() as u8);
|
||||
|
||||
match command {
|
||||
Cmd::Activate(vt) | Cmd::Deactivate(vt) => result.extend_from_slice(&vt.to_le_bytes()),
|
||||
Cmd::Resize {
|
||||
vt,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
} => {
|
||||
result.extend_from_slice(&vt.to_le_bytes());
|
||||
result.extend(width.to_le_bytes());
|
||||
result.extend(height.to_le_bytes());
|
||||
result.extend(stride.to_le_bytes());
|
||||
}
|
||||
};
|
||||
|
||||
let written = syscall::write(file.as_raw_fd() as usize, &result)?;
|
||||
|
||||
// XXX: Ensure all of the data is written.
|
||||
assert_eq!(written, result.len());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_command(buffer: &[u8]) -> Option<Cmd> {
|
||||
const U32_SIZE: usize = core::mem::size_of::<u32>();
|
||||
const USIZE_SIZE: usize = core::mem::size_of::<usize>();
|
||||
|
||||
let mut parser = buffer.iter().cloned();
|
||||
|
||||
let command = CmdTy::from(parser.next()?);
|
||||
let vt = usize::from_le_bytes(parser.next_chunk::<USIZE_SIZE>().ok()?);
|
||||
|
||||
match command {
|
||||
CmdTy::Activate => Some(Cmd::Activate(vt)),
|
||||
CmdTy::Deactivate => Some(Cmd::Deactivate(vt)),
|
||||
CmdTy::Resize => {
|
||||
let width = parser.next_chunk::<U32_SIZE>().ok()?;
|
||||
let height = parser.next_chunk::<U32_SIZE>().ok()?;
|
||||
let stride = parser.next_chunk::<U32_SIZE>().ok()?;
|
||||
|
||||
Some(Cmd::Resize {
|
||||
vt,
|
||||
width: u32::from_le_bytes(width),
|
||||
height: u32::from_le_bytes(height),
|
||||
stride: u32::from_le_bytes(stride),
|
||||
})
|
||||
}
|
||||
|
||||
CmdTy::Unknown => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-13
@@ -13,11 +13,12 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use inputd::{Command, CommandTy};
|
||||
use inputd::Cmd;
|
||||
|
||||
use orbclient::{Event, EventOption};
|
||||
use syscall::{Error as SysError, EventFlags, Packet, SchemeMut, EINVAL};
|
||||
|
||||
@@ -166,15 +167,25 @@ impl SchemeMut for InputScheme {
|
||||
_ => (),
|
||||
},
|
||||
|
||||
EventOption::Resize(resize_event) => {
|
||||
if let Some((_, file, current)) = self.active_vt.as_mut() {
|
||||
inputd::send_comand(
|
||||
file,
|
||||
Cmd::Resize {
|
||||
vt: current.clone(),
|
||||
width: resize_event.width,
|
||||
height: resize_event.height,
|
||||
|
||||
// TODO(andypython): Figure out how to get the stride.
|
||||
stride: resize_event.width,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
let deactivate = |file: &mut File, id: usize| -> io::Result<()> {
|
||||
let command = Command::new(CommandTy::Deactivate, id).into_bytes();
|
||||
file.write(&command)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if let Some(new_active) = new_active_opt {
|
||||
if let Some(vt) = self.vts.get(&new_active).cloned() {
|
||||
if let Some((_, file, current)) = self.active_vt.as_mut() {
|
||||
@@ -183,20 +194,19 @@ impl SchemeMut for InputScheme {
|
||||
continue;
|
||||
}
|
||||
|
||||
deactivate(file, *current).unwrap();
|
||||
inputd::send_comand(file, Cmd::Deactivate(*current))?;
|
||||
} else {
|
||||
let id = self.next_vt_id.load(Ordering::SeqCst) - 1;
|
||||
let mut vt = File::open(self.vts.get_mut(&id).unwrap().as_ref()).unwrap();
|
||||
|
||||
deactivate(&mut vt, id).unwrap();
|
||||
inputd::send_comand(&mut vt, Cmd::Deactivate(id))?;
|
||||
}
|
||||
|
||||
log::info!("inputd: switching to VT #{new_active} (`{vt}`)");
|
||||
|
||||
let mut file = File::open(vt.as_ref()).unwrap();
|
||||
file.write(&Command::new(CommandTy::Activate, new_active).into_bytes())
|
||||
.unwrap();
|
||||
|
||||
inputd::send_comand(&mut file, Cmd::Activate(new_active))?;
|
||||
self.active_vt = Some((vt.clone(), file, new_active));
|
||||
} else {
|
||||
log::warn!("inputd: switch to non-existent VT #{new_active} was requested");
|
||||
@@ -294,7 +304,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> {
|
||||
last_allocated == *vt
|
||||
};
|
||||
|
||||
// The activate VT is not the same as the VT that the consumer is listening to
|
||||
// The activate VT is not the same as the VT that the consumer is listening to
|
||||
// for events.
|
||||
if !should_notify {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user