feat(userspace): programs in /bin w/o .elf; bin manifests (needs = display) so shell runs snake; Ctrl+C kills foreground via terminal interrupt notification; ctrl keys; sleep

This commit is contained in:
2026-10-27 21:16:00 +01:00
parent 1fc5a54f06
commit 83809bbe94
33 changed files with 608 additions and 121 deletions

View File

@@ -4,6 +4,17 @@ use port_input_device::Key;
pub const LEFT_SHIFT: u16 = 42;
pub const RIGHT_SHIFT: u16 = 54;
pub const LEFT_CTRL: u16 = 29;
pub const RIGHT_CTRL: u16 = 97;
/// A letter typed with Ctrl held is its control character, as on a
/// terminal: Ctrl+C is 3. Anything else is itself.
pub fn with_ctrl(key: Key) -> Key {
match key {
Key::Char(c) if c.is_ascii_alphabetic() => Key::Char(c.to_ascii_lowercase() & 0x1f),
k => k,
}
}
/// Rows of the main block: the first key's code, then each key unshifted
/// and shifted.
@@ -41,6 +52,14 @@ pub fn key(code: u16, shift: bool) -> Option<Key> {
mod tests {
use super::*;
#[test]
fn ctrl_letters_are_control_characters() {
assert_eq!(with_ctrl(Key::Char(b'c')), Key::Char(3));
assert_eq!(with_ctrl(Key::Char(b'C')), Key::Char(3));
assert_eq!(with_ctrl(Key::Char(b'1')), Key::Char(b'1'));
assert_eq!(with_ctrl(Key::Enter), Key::Enter);
}
#[test]
fn letters_digits_and_shift() {
assert_eq!(key(35, false), Some(Key::Char(b'h')));

View File

@@ -31,6 +31,7 @@ pub struct VirtioInputDevice {
next_avail: u16,
evbuf_pa: usize,
shift: bool,
ctrl: bool,
}
impl VirtioInputDevice {
@@ -48,7 +49,7 @@ impl VirtioInputDevice {
let evbuf_pa = libkos::device::dma(1, EVBUF_VA).ok()?;
hw_virtio::mmio::init_legacy_device(&regs, vq_pa, QUEUE_SIZE as u32);
let mut dev = Self { last_used: 0, next_avail: 0, evbuf_pa, shift: false };
let mut dev = Self { last_used: 0, next_avail: 0, evbuf_pa, shift: false, ctrl: false };
dev.fill_queue();
Some(dev)
}
@@ -139,8 +140,13 @@ impl InputDevice for VirtioInputDevice {
self.shift = ev_value != 0;
continue;
}
if ev_type == EV_KEY && matches!(ev_code, keymap::LEFT_CTRL | keymap::RIGHT_CTRL) {
self.ctrl = ev_value != 0;
continue;
}
if ev_type == EV_KEY {
if let Some(key) = keymap::key(ev_code, self.shift) {
let key = keymap::key(ev_code, self.shift).map(|k| if self.ctrl { keymap::with_ctrl(k) } else { k });
if let Some(key) = key {
if ev_value == KEY_PRESS {
return Some(InputEvent::KeyDown(key));
} else if ev_value == 0 {