From cb17c57452ccd2ccca77e99098402d4b9f61c0a5 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 20 Aug 2026 13:47:10 +0200 Subject: wm: F1 spawns a windowed shell — real shell, not a duplicate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architecture: - vt: ACTIVE terminal redirect — when set, all gop_print!/put_char/write_str go there instead of HOME. Terminal::from_buffer() renders into a WM-owned pixel buffer. - tty: read_line_from_queue() — canonical-mode line input from the task's own message queue (TaskMsg::Key). Returns None on Close. - shell: run_windowed() — same shell as the console but reads from the message queue. Returns on ^D or window close. - wm: F1 calls SPAWN_TERMINAL_CB (set by rsdos). No shell logic in the WM. - rsdos: terminal_task callback + terminal_entry task — creates a 640x400 chrome window, wires up Terminal::from_buffer, sets ACTIVE, runs shell::run_windowed(), cleans up on exit. - shell: 'term' debug command that invokes the callback directly and logs each step to serial. --- shell/src/lib.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'shell/src/lib.rs') diff --git a/shell/src/lib.rs b/shell/src/lib.rs index f1addd9..6077f35 100644 --- a/shell/src/lib.rs +++ b/shell/src/lib.rs @@ -93,6 +93,30 @@ pub fn run() -> ! { } } +/// Run a shell instance inside a windowed terminal. Same as `run()` but +/// reads from the task's message queue (Fed by the WM input pump) and +/// writes to the active terminal (set by the caller via `vt::set_active`). +/// Returns when the window is closed (Close message or ^D on empty line). +pub fn run_windowed() { + term_println(&alloc::format!("rs-dos v{}", env!("CARGO_PKG_VERSION"))); + loop { + rsnix::vt::sync_scroll(); + term_print("> "); + match tty::read_line_from_queue() { + None => return, // window closed + Some(LineInput::Interrupted) => continue, + Some(LineInput::Eof) => return, // ^D in windowed mode = close + Some(LineInput::Line(line)) => { + let trimmed = line.trim(); + if trimmed.is_empty() { + continue; + } + execute(trimmed); + } + } + } +} + // --------------------------------------------------------------------------- // Diagnostics and command output go straight to terminal + serial, never // through the filter pipeline and never into a file sink. These helpers @@ -741,6 +765,7 @@ write `{} TIL `", "rm" => cmd_rm(&parsed), "edit" => cmd_edit(&parsed), "draw" => cmd_draw(&parsed), + "term" => cmd_term(&parsed), "windows" => cmd_windows(&parsed), "restore" => cmd_restore(&parsed), "bg" => cmd_bg(&parsed), @@ -800,6 +825,7 @@ fn cmd_help(_p: &Parsed) { touch - create an empty file rm - remove a file or empty dir edit - full-screen editor (^S save, ^X exit, ^W search) + term - spawn a windowed terminal (F1 also works) halt - halt the system (hlt loop) poweroff - shut down via ACPI (ResetSystem) exit - alias for poweroff @@ -1401,6 +1427,26 @@ fn cmd_draw(_p: &Parsed) { } } +fn cmd_term(_p: &Parsed) { + // Debug: check if the callback is registered. + let cb_set = unsafe { core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB).read().is_some() }; + term_println(&alloc::format!("term: SPAWN_TERMINAL_CB set = {}", cb_set)); + if !cb_set { + term_err("term: callback not registered — cannot spawn"); + return; + } + // Invoke the callback directly (same as F1). + let (cw, ch) = rsnix::gop::pixel_dims(); + let w = 640usize.min(cw); + let h = 400usize.min(ch); + term_println(&alloc::format!("term: requesting window {}x{}", w, h)); + unsafe { + let cb = core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB).read().unwrap(); + cb("term dbg", w, h); + } + term_println("term: callback returned (task should be spawning)"); +} + fn cmd_windows(_p: &Parsed) { let list = rsnix::wm::list(); if list.is_empty() { -- cgit v1.2.3