feat(userspace): terminal server + shell desktop; US keymap w/ shift; libkos allocator multi-page fix; panics print
This commit is contained in:
13
crates/apps/shell/Cargo.toml
Normal file
13
crates/apps/shell/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "shell"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "shell"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
types = { workspace = true }
|
||||
libkos = { workspace = true }
|
||||
48
crates/apps/shell/src/main.rs
Normal file
48
crates/apps/shell/src/main.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
//! The shell, for now built-ins only; running programs comes next.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
|
||||
use libkos::{print, println};
|
||||
use types::bounded::CapSlot;
|
||||
|
||||
/// Init's manifest gives it the terminal first.
|
||||
const TERMINAL: CapSlot = CapSlot::const_new(0);
|
||||
|
||||
fn run(line: &str) {
|
||||
let mut words = line.split_ascii_whitespace();
|
||||
match words.next() {
|
||||
None => {}
|
||||
Some("help") => {
|
||||
println!("built-ins: help, echo <text>, clear");
|
||||
}
|
||||
Some("echo") => {
|
||||
let mut first = true;
|
||||
for w in words {
|
||||
print!("{}{}", if first { "" } else { " " }, w);
|
||||
first = false;
|
||||
}
|
||||
println!();
|
||||
}
|
||||
Some("clear") => libkos::terminal::clear(TERMINAL),
|
||||
Some(other) => println!("shell: {}: not found", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
// Everything this shell prints goes to the terminal.
|
||||
libkos::start::set_log(Some(TERMINAL));
|
||||
println!("k-os shell. Type 'help'.");
|
||||
let mut buf = [0u8; 256];
|
||||
loop {
|
||||
print!("$ ");
|
||||
let n = libkos::terminal::read_line(TERMINAL, &mut buf);
|
||||
match core::str::from_utf8(&buf[..n]) {
|
||||
Ok(line) => run(line.trim_end_matches('\n')),
|
||||
Err(_) => println!("shell: not text"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,16 +67,17 @@ extern "C" fn main() {
|
||||
fn handle_input(snake: &mut Snake) {
|
||||
// Drain all pending events, apply the latest direction
|
||||
loop {
|
||||
let Ok([tag, kind, _, _]) = syscall::request(DISPLAY_EP, [types::display::input::POLL, 0, 0, 0]) else {
|
||||
let Ok([tag, kind, ch, _]) = syscall::request(DISPLAY_EP, [types::display::input::POLL, 0, 0, 0]) else {
|
||||
break;
|
||||
};
|
||||
if tag == 0 { break; } // NoEvent — queue drained
|
||||
if tag == 1 {
|
||||
match kind {
|
||||
0 => snake.set_direction(Direction::Up),
|
||||
1 => snake.set_direction(Direction::Down),
|
||||
2 => snake.set_direction(Direction::Left),
|
||||
3 => snake.set_direction(Direction::Right),
|
||||
// Arrows, or WASD (kind 9 is a character).
|
||||
match (kind, ch as u8) {
|
||||
(0, _) | (9, b'w') => snake.set_direction(Direction::Up),
|
||||
(1, _) | (9, b's') => snake.set_direction(Direction::Down),
|
||||
(2, _) | (9, b'a') => snake.set_direction(Direction::Left),
|
||||
(3, _) | (9, b'd') => snake.set_direction(Direction::Right),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user