Add input module: broadcast keyboard events over IPC
Programs can now subscribe to keyboard events (key_down/key_up/key_press) and drivers can broadcast them, through a new user-space input service. The delivery model is forced by danos IPC: a synchronous rendezvous holds one pending reply, so a server cannot park N subscribers blocked in a "wait for next event" call — delivery must be push. But a synchronous push has no timeout and the kernel never wakes a sender parked on a dead peer's endpoint, so one dying subscriber would hang all input. So this lands the roadmap's planned asynchronous buffered send and builds the service on it: - ipc_send (syscall 26): non-blocking post to an endpoint's bounded payload ring, delivered through reply_wait as a buffered message (notify_message_bit). A full ring drops the oldest. It can never hang on a dead/slow peer. - input-protocol + runtime.input helpers (subscribe/next, connectSource/ publish) — the first real consumer of M13 capability passing: a subscriber hands the service its own endpoint as a capability. - input service (fan-out via ipc_send, dead-subscriber pruning), a synthetic input-source, and input-test; the ps2-bus keyboard driver publishes to it. Real IRQ1 scancode decoding (which must live in the bus, the PNP0303 owner) is a documented follow-up; the source is synthetic for now. - build/init wiring, an `input` QEMU case, and docs/input.md. Full QEMU suite 48/48, including the new input case and every IPC/endpoint regression (ipc, ipc-call, ipc-cap, vfs, hpet, bus, irqfree).
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
//! system/services/input-test — the input service's client and test oracle, the input
|
||||
//! counterpart of vfs-test. It `subscribe`s to the input service, then loops receiving the
|
||||
//! events a source broadcasts. Once it has received at least one event it heartbeats
|
||||
//! `"input-test: ok"` (repeatedly), which the in-kernel `input` test case watches for on
|
||||
//! the serial log: seeing it proves an event travelled source -> service -> subscriber
|
||||
//! over IPC and arrived intact.
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const input = runtime.input;
|
||||
const system = runtime.system;
|
||||
|
||||
fn writeLine(comptime fmt: []const u8, arguments: anytype) void {
|
||||
var line: [128]u8 = undefined;
|
||||
_ = system.write(std.fmt.bufPrint(&line, fmt, arguments) catch return);
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
var listener = input.subscribe() orelse {
|
||||
_ = system.write("input-test: could not subscribe\n");
|
||||
return;
|
||||
};
|
||||
_ = system.write("input-test: subscribed\n");
|
||||
|
||||
var received: usize = 0;
|
||||
while (true) {
|
||||
const event = listener.next() orelse continue;
|
||||
received += 1;
|
||||
// Report the round trip. The kernel test matches the "input-test: ok" prefix and
|
||||
// requires it to recur, so the source staying up keeps this beating.
|
||||
const kind: input.EventKind = @enumFromInt(event.kind);
|
||||
writeLine("input-test: ok received {d} last kind={s} code={d} char={d}\n", .{ received, @tagName(kind), event.keycode, event.character });
|
||||
}
|
||||
}
|
||||
|
||||
pub const panic = runtime.panic;
|
||||
comptime {
|
||||
_ = &runtime.start._start;
|
||||
}
|
||||
Reference in New Issue
Block a user