feat(display): input routed via display server to focused app; input Subscribe; uses caps badged + Delegate
This commit is contained in:
@@ -50,3 +50,23 @@ pub fn draw_text(ep: CapSlot, x: ScreenCoord, y: ScreenCoord, fg: Color, bg: Col
|
||||
/// The display server's character cell, in pixels.
|
||||
pub const CELL_WIDTH: usize = 8;
|
||||
pub const CELL_HEIGHT: usize = 16;
|
||||
|
||||
/// Takes input focus: returns a notification signalled whenever events
|
||||
/// arrive; read them with `poll_input`.
|
||||
pub fn subscribe_input(ep: CapSlot) -> Option<CapSlot> {
|
||||
use types::badge::Badge;
|
||||
use types::permission::{Permission, PermissionSet};
|
||||
let notify = syscall::create_notification().ok()?;
|
||||
// Signal only (Delegate just to send it; the transfer strips it).
|
||||
let signal = PermissionSet::empty().with(Permission::Write).with(Permission::Delegate);
|
||||
let copy = syscall::mint(notify, Badge::NONE, signal).ok()?;
|
||||
let sent = syscall::call(ep, [types::display::input::SUBSCRIBE, 0, 0, 0], Some(copy));
|
||||
syscall::drop_cap(copy);
|
||||
(sent.ok()?.words()[0] == 0).then_some(notify)
|
||||
}
|
||||
|
||||
/// The next input event, if this process has focus and one is waiting.
|
||||
pub fn poll_input(ep: CapSlot) -> Option<crate::input::InputEvent> {
|
||||
let words = syscall::request(ep, [types::display::input::POLL, 0, 0, 0]).ok()?;
|
||||
crate::input::decode(words)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,11 @@ fn decode_key(kind: usize, extra: usize) -> Option<Key> {
|
||||
}
|
||||
|
||||
pub fn poll_event(ep: CapSlot) -> Option<InputEvent> {
|
||||
let [tag, kind, extra, _] = syscall::request(ep, [0; 4]).ok()?;
|
||||
decode(syscall::request(ep, [0; 4]).ok()?)
|
||||
}
|
||||
|
||||
/// An event as the input server words it.
|
||||
pub fn decode([tag, kind, extra, _]: [usize; 4]) -> Option<InputEvent> {
|
||||
match tag {
|
||||
0 => None,
|
||||
1 => decode_key(kind, extra).map(InputEvent::KeyDown),
|
||||
|
||||
Reference in New Issue
Block a user