From 5558e3509d020a0e021a77f0617044497b2f2aee Mon Sep 17 00:00:00 2001 From: salmonik Date: Mon, 17 Aug 2026 18:56:04 +0200 Subject: Windowed GUI: wm module, input routing, and the paint app - Add the wm window-manager facility per ADR 0004: overlapping pixel-surface windows, damage-rectangle compositing, WM-drawn title bar, focus/minimize/close, and F1-F4 keybindings - Add gop shadow compositing primitives and vt::repaint_region so the console stays layer 0 beneath windows - Route mouse (absolute coords, press/release edges) and keyboard (focus-aware input pump) to the focused window - Add the rspaint drawing-program crate (pen, 8 colors, clear) and shell draw/windows/restore commands - Extend TaskMsg with AppMouse/Focus/Close and document the design in CONTEXT.md + ADR 0004 --- rsnix/src/sched.rs | 59 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'rsnix/src/sched.rs') diff --git a/rsnix/src/sched.rs b/rsnix/src/sched.rs index 259ddf6..39ecb65 100644 --- a/rsnix/src/sched.rs +++ b/rsnix/src/sched.rs @@ -59,6 +59,9 @@ const MSG_CAP: usize = 16; pub enum TaskMsg { Key(crate::ps2::KeyEvent), Mouse(crate::ps2::MouseEvent), + AppMouse(crate::ps2::AppMouseEvent), + Focus(bool), + Close, Timer, User(u64), } @@ -94,6 +97,11 @@ pub fn msg_describe(msg: &TaskMsg) -> alloc::string::String { if m.left { "L" } else { "-" }, if m.right { "R" } else { "-" } ), + TaskMsg::AppMouse(m) => { + alloc::format!("AppMouse({},{} {:?} b={:#x})", m.x, m.y, m.kind, m.buttons) + } + TaskMsg::Focus(f) => alloc::format!("Focus({})", f), + TaskMsg::Close => "Close".into(), TaskMsg::Timer => "Timer".into(), TaskMsg::User(n) => alloc::format!("User({})", n), } @@ -179,7 +187,10 @@ struct SpinWatch { last_rsp: usize, same: u32, } -const SPIN_WATCH_INIT: SpinWatch = SpinWatch { last_rsp: 0, same: 0 }; +const SPIN_WATCH_INIT: SpinWatch = SpinWatch { + last_rsp: 0, + same: 0, +}; static mut SPIN_WATCH: [SpinWatch; MAX_TASKS] = [SPIN_WATCH_INIT; MAX_TASKS]; /// A spinning background task is interrupted at roughly half the tick rate /// (it alternates with idle), so 1500 hits is ~30 s of wall time. @@ -381,11 +392,7 @@ pub fn spawn(entry: fn(), name: &str) -> Option { }; let ok = spawn_at(id, entry, name); unlock(); - if ok { - Some(id) - } else { - None - } + if ok { Some(id) } else { None } } unsafe fn reap(id: usize) { @@ -698,10 +705,12 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra } let ra = *(fp as *const u64).add(1); // [rbp+8] = return address if let Some((start, end)) = filter - && ra >= start as u64 && ra < end as u64 { - bt[bn] = ra; - bn += 1; - } + && ra >= start as u64 + && ra < end as u64 + { + bt[bn] = ra; + bn += 1; + } let nfp = *(fp as *const u64); if nfp <= fp { break; // chain must grow upward @@ -715,19 +724,21 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra while p + 8 <= limit && bn < bt.len() { let v = *(p as *const u64); if let Some((start, end)) = filter - && v >= start as u64 && v < end as u64 { - let mut dup = false; - for i in 0..bn { - if bt[i] == v { - dup = true; - break; - } - } - if !dup { - bt[bn] = v; - bn += 1; + && v >= start as u64 + && v < end as u64 + { + let mut dup = false; + for i in 0..bn { + if bt[i] == v { + dup = true; + break; } } + if !dup { + bt[bn] = v; + bn += 1; + } + } p += 8; } } @@ -842,7 +853,11 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra &mut w, core::format_args!( "rax={:#x} rcx={:#x} rdx={:#x} rsi={:#x} rdi={:#x}", - frame.rax, frame.rcx, frame.rdx, frame.rsi, frame.rdi + frame.rax, + frame.rcx, + frame.rdx, + frame.rsi, + frame.rdi ), ); w.len() -- cgit v1.2.3