feat(display): input routed via display server to focused app; input Subscribe; uses caps badged + Delegate

This commit is contained in:
2026-10-27 16:38:16 +01:00
parent 64ec5df379
commit 2845d190f0
18 changed files with 286 additions and 26 deletions

View File

@@ -5,25 +5,50 @@ extern crate libkos;
use types::bounded::CapSlot;
/// Where init put them (see init's manifest: own endpoint, then `uses`).
const EP: CapSlot = CapSlot::const_new(0);
const INPUT: CapSlot = CapSlot::const_new(1);
#[unsafe(no_mangle)]
extern "C" fn main() {
let ep = CapSlot::const_new(0);
// Init hands over the GPU, or nothing if the machine has none.
let dev = libkos::device::receive_device(ep);
let dev = libkos::device::receive_device(EP);
let input = subscribe_to_input();
if let Some(fb) = dev.mmio.and_then(driver_framebuffer_virtio::VirtioFramebuffer::try_new) {
run_virtio(fb, ep);
run_virtio(fb, input);
}
libkos::println!("display: no GPU, running headless");
run_headless(ep);
run_headless(input);
}
/// Has the input server signal this thread whenever events arrive; the
/// server then passes them on to the app in focus.
fn subscribe_to_input() -> Option<CapSlot> {
use types::badge::Badge;
use types::permission::{Permission, PermissionSet};
let notify = libkos::syscall::create_notification().ok()?;
libkos::syscall::bind_notification(notify).ok()?;
let signal = PermissionSet::empty().with(Permission::Write).with(Permission::Delegate);
let copy = libkos::syscall::mint(notify, Badge::NONE, signal).ok()?;
let sent = libkos::syscall::call(INPUT, [types::input::SUBSCRIBE, 0, 0, 0], Some(copy));
libkos::syscall::drop_cap(copy);
sent.ok().map(|_| INPUT)
}
fn server<F: port_framebuffer::Framebuffer>(fb: F, input: Option<CapSlot>) -> display_server::server::DisplayServer<F> {
match input {
Some(input) => display_server::server::DisplayServer::with_input(fb, input),
None => display_server::server::DisplayServer::new(fb),
}
}
#[inline(never)]
fn run_virtio(mut fb: driver_framebuffer_virtio::VirtioFramebuffer, ep: CapSlot) -> ! {
fn run_virtio(mut fb: driver_framebuffer_virtio::VirtioFramebuffer, input: Option<CapSlot>) -> ! {
use port_framebuffer::Framebuffer;
fb.clear(types::display::Color::rgb(30, 30, 60));
fb.flush();
let mut srv = display_server::server::DisplayServer::new(fb);
server_framework::serve(&mut srv, ep)
let mut srv = server(fb, input);
server_framework::serve(&mut srv, EP)
}
/// No GPU: clients still get answers (and the dimensions they draw for);
@@ -52,7 +77,7 @@ impl port_framebuffer::Framebuffer for Headless {
}
#[inline(never)]
fn run_headless(ep: CapSlot) -> ! {
let mut srv = display_server::server::DisplayServer::new(Headless);
server_framework::serve(&mut srv, ep)
fn run_headless(input: Option<CapSlot>) -> ! {
let mut srv = server(Headless, input);
server_framework::serve(&mut srv, EP)
}