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. --- rsdos/src/main.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'rsdos') diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs index 6d2fa4a..e5fb6dd 100644 --- a/rsdos/src/main.rs +++ b/rsdos/src/main.rs @@ -420,10 +420,79 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut t.set_window(id); } rsnix::wm::spawn_input_pump(); + // Register the terminal-spawn callback so F1 in the WM creates a + // windowed shell. The task lives here in rsdos (which depends on + // both rsnix and shell). + unsafe { + rsnix::wm::SPAWN_TERMINAL_CB = Some(terminal_task); + } shell::run(); } +/// Callback registered with the WM for F1. Stores the spawn arguments +/// and spawns the terminal task (can't block the input pump). +static mut TERM_TITLE_BUF: [u8; 64] = [0u8; 64]; +static mut TERM_TITLE_LEN: usize = 0; +static mut TERM_W: usize = 0; +static mut TERM_H: usize = 0; + +fn terminal_task(title: &str, w: usize, h: usize) { + rsnix::serial_println!("term: callback invoked title='{}' {}x{}", title, w, h); + // Copy title into static buffer so the spawned task can see it. + let bytes = title.as_bytes(); + let n = bytes.len().min(63); + unsafe { + TERM_TITLE_BUF[..n].copy_from_slice(&bytes[..n]); + TERM_TITLE_BUF[n] = 0; + TERM_TITLE_LEN = n; + TERM_W = w; + TERM_H = h; + } + match rsnix::sched::spawn(terminal_entry, "term") { + Some(id) => rsnix::serial_println!("term: spawned task {}", id), + None => rsnix::serial_println!("term: spawn FAILED"), + } +} + +/// The actual terminal task — reads args from statics, creates a window, +/// and runs the shell. +fn terminal_entry() { + use rsnix::vt::Terminal; + let (w, h) = unsafe { (TERM_W, TERM_H) }; + let title = unsafe { core::str::from_utf8_unchecked(&TERM_TITLE_BUF[..TERM_TITLE_LEN]) }; + rsnix::serial_println!("term: entry title='{}' {}x{}", title, w, h); + let Some(win_id) = rsnix::wm::create_window(title, w, h) else { + rsnix::serial_println!("term: create_window FAILED"); + return; + }; + rsnix::serial_println!("term: win_id={}", win_id); + let Some((buf, ww, hh)) = rsnix::wm::buffer(win_id) else { + rsnix::serial_println!("term: buffer FAILED"); + rsnix::wm::destroy(win_id); + return; + }; + rsnix::serial_println!("term: buffer {:?} {}x{}", buf as *mut u32, ww, hh); + + // Build a Terminal that renders into the WM-allocated buffer. + let mut term = Terminal::from_buffer(buf as *mut u32, ww, hh); + term.set_window(win_id); + rsnix::serial_println!("term: terminal created, entering shell"); + + // Redirect all vt output (gop_print!, put_char, …) to this terminal. + rsnix::vt::set_active(&mut term as *mut Terminal); + + // Run the shell — it owns input, line editing, and command execution. + shell::run_windowed(); + + // Shell exited (^D or window close). Clean up. + rsnix::serial_println!("term: shell exited, cleaning up"); + rsnix::vt::set_active(core::ptr::null_mut()); + drop(term); + rsnix::wm::destroy(win_id); + rsnix::serial_println!("term: done"); +} + // --------------------------------------------------------------------------- // Print a memory summary from the stashed memory map // --------------------------------------------------------------------------- -- cgit v1.2.3