Merge branch 'vt_to_go' into 'master'

Implicitly create a new VT for each consumer

See merge request redox-os/drivers!244
This commit is contained in:
Jeremy Soller
2025-03-03 17:42:10 +00:00
5 changed files with 31 additions and 46 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ pub struct Display {
impl Display {
pub fn open_first_vt() -> io::Result<Self> {
let input_handle = ConsumerHandle::for_vt(1)?;
let input_handle = ConsumerHandle::new_vt()?;
let map = match input_handle.open_display() {
Ok(display) => {
+1 -1
View File
@@ -14,7 +14,7 @@ pub struct DisplayMap {
impl Display {
pub fn open_vt(vt: usize) -> io::Result<Self> {
let input_handle = ConsumerHandle::for_vt(vt)?;
let input_handle = ConsumerHandle::new_vt()?;
if let Ok(display_handle) = Self::open_display(&input_handle) {
let map = display_handle
+2 -12
View File
@@ -15,12 +15,6 @@ mod framebuffer;
mod scheme;
fn main() {
let mut spec = Vec::new();
for _ in env::args().skip(1) {
spec.push(());
}
if env::var("FRAMEBUFFER_WIDTH").is_err() {
println!("vesad: No boot framebuffer");
return;
@@ -78,16 +72,12 @@ fn main() {
};
}
redox_daemon::Daemon::new(|daemon| inner(daemon, framebuffers, &spec))
redox_daemon::Daemon::new(|daemon| inner(daemon, framebuffers))
.expect("failed to create daemon");
}
fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec<FrameBuffer>, spec: &[()]) -> ! {
fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec<FrameBuffer>) -> ! {
let mut inputd_display_handle = DisplayHandle::new_early("vesa").unwrap();
for &() in spec.iter() {
inputd_display_handle.register_vt().unwrap();
}
let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned());
user_data! {
+2 -8
View File
@@ -17,11 +17,11 @@ unsafe fn any_as_u8_slice_mut<T: Sized>(p: &mut T) -> &mut [u8] {
pub struct ConsumerHandle(File);
impl ConsumerHandle {
pub fn for_vt(vt: usize) -> Result<Self, Error> {
pub fn new_vt() -> Result<Self, Error> {
let file = OpenOptions::new()
.read(true)
.custom_flags(O_NONBLOCK as i32)
.open(format!("/scheme/input/consumer/{vt}"))?;
.open(format!("/scheme/input/consumer"))?;
Ok(Self(file))
}
@@ -70,12 +70,6 @@ impl DisplayHandle {
Ok(Self(File::open(path)?))
}
// The return value is the display identifier. It will be used to uniquely
// identify the display on activation events.
pub fn register_vt(&mut self) -> Result<usize, Error> {
self.0.read(&mut [])
}
pub fn read_vt_event(&mut self) -> Result<Option<VtEvent>, Error> {
let mut event = VtEvent {
kind: VtEventKind::Resize,
+25 -24
View File
@@ -131,17 +131,19 @@ impl Scheme for InputScheme {
let handle_ty = match command {
"producer" => Handle::Producer,
"consumer" => {
let target = path_parts
.next()
.and_then(|x| x.parse::<usize>().ok())
.ok_or(SysError::new(EINVAL))?;
let vt = self.next_vt_id.fetch_add(1, Ordering::Relaxed);
self.vts.insert(vt);
if self.active_vt.is_none() {
self.switch_vt(vt);
}
Handle::Consumer {
events: EventFlags::empty(),
pending: Vec::new(),
needs_handoff: false,
notified: false,
vt: target,
vt,
}
}
"handle" | "handle_early" => {
@@ -258,24 +260,8 @@ impl Scheme for InputScheme {
Ok(copy)
}
Handle::Display {
pending, device, ..
} => {
// FIXME Create new VT through a write instead and return a NewVt event on read
// This allows also returning events for VT (de)activation from the display handle
// rather than pushing them to the graphics driver.
if buf.is_empty() {
// Trying to do an empty read creates a new VT.
let vt = self.next_vt_id.fetch_add(1, Ordering::SeqCst);
log::info!("inputd: created VT #{vt} for {device}");
self.vts.insert(vt);
if self.active_vt.is_none() {
self.switch_vt(vt);
}
Ok(vt)
} else if buf.len() % size_of::<VtEvent>() == 0 {
Handle::Display { pending, .. } => {
if buf.len() % size_of::<VtEvent>() == 0 {
let copy = core::cmp::min(pending.len(), buf.len() / size_of::<VtEvent>());
for (i, event) in pending.drain(..copy).enumerate() {
@@ -472,7 +458,22 @@ impl Scheme for InputScheme {
}
}
fn close(&mut self, _id: usize) -> syscall::Result<usize> {
fn close(&mut self, id: usize) -> syscall::Result<usize> {
let handle = self.handles.get(&id).ok_or(SysError::new(EINVAL))?;
match *handle {
Handle::Consumer { vt, .. } => {
self.vts.remove(&vt);
if self.active_vt == Some(vt) {
if let Some(&new_vt) = self.vts.last() {
self.switch_vt(new_vt);
} else {
self.active_vt = None;
}
}
}
_ => {}
}
Ok(0)
}
}