feat(display): input routed via display server to focused app; input Subscribe; uses caps badged + Delegate
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user