summaryrefslogtreecommitdiffstats
path: root/rsnix/src/sched.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-17 18:56:04 +0200
committersalmonik <salmonik@tuta.io>2026-08-17 18:56:04 +0200
commit5558e3509d020a0e021a77f0617044497b2f2aee (patch)
treecd7b6cee9f7c327f9fae7ad9ac27602d1a97b222 /rsnix/src/sched.rs
parentUSB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening (diff)
downloadrs-dos-5558e3509d020a0e021a77f0617044497b2f2aee.tar.gz
rs-dos-5558e3509d020a0e021a77f0617044497b2f2aee.zip
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
Diffstat (limited to '')
-rw-r--r--rsnix/src/sched.rs59
1 files changed, 37 insertions, 22 deletions
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;
59pub enum TaskMsg { 59pub enum TaskMsg {
60 Key(crate::ps2::KeyEvent), 60 Key(crate::ps2::KeyEvent),
61 Mouse(crate::ps2::MouseEvent), 61 Mouse(crate::ps2::MouseEvent),
62 AppMouse(crate::ps2::AppMouseEvent),
63 Focus(bool),
64 Close,
62 Timer, 65 Timer,
63 User(u64), 66 User(u64),
64} 67}
@@ -94,6 +97,11 @@ pub fn msg_describe(msg: &TaskMsg) -> alloc::string::String {
94 if m.left { "L" } else { "-" }, 97 if m.left { "L" } else { "-" },
95 if m.right { "R" } else { "-" } 98 if m.right { "R" } else { "-" }
96 ), 99 ),
100 TaskMsg::AppMouse(m) => {
101 alloc::format!("AppMouse({},{} {:?} b={:#x})", m.x, m.y, m.kind, m.buttons)
102 }
103 TaskMsg::Focus(f) => alloc::format!("Focus({})", f),
104 TaskMsg::Close => "Close".into(),
97 TaskMsg::Timer => "Timer".into(), 105 TaskMsg::Timer => "Timer".into(),
98 TaskMsg::User(n) => alloc::format!("User({})", n), 106 TaskMsg::User(n) => alloc::format!("User({})", n),
99 } 107 }
@@ -179,7 +187,10 @@ struct SpinWatch {
179 last_rsp: usize, 187 last_rsp: usize,
180 same: u32, 188 same: u32,
181} 189}
182const SPIN_WATCH_INIT: SpinWatch = SpinWatch { last_rsp: 0, same: 0 }; 190const SPIN_WATCH_INIT: SpinWatch = SpinWatch {
191 last_rsp: 0,
192 same: 0,
193};
183static mut SPIN_WATCH: [SpinWatch; MAX_TASKS] = [SPIN_WATCH_INIT; MAX_TASKS]; 194static mut SPIN_WATCH: [SpinWatch; MAX_TASKS] = [SPIN_WATCH_INIT; MAX_TASKS];
184/// A spinning background task is interrupted at roughly half the tick rate 195/// A spinning background task is interrupted at roughly half the tick rate
185/// (it alternates with idle), so 1500 hits is ~30 s of wall time. 196/// (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<usize> {
381 }; 392 };
382 let ok = spawn_at(id, entry, name); 393 let ok = spawn_at(id, entry, name);
383 unlock(); 394 unlock();
384 if ok { 395 if ok { Some(id) } else { None }
385 Some(id)
386 } else {
387 None
388 }
389} 396}
390 397
391unsafe fn reap(id: usize) { 398unsafe fn reap(id: usize) {
@@ -698,10 +705,12 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra
698 } 705 }
699 let ra = *(fp as *const u64).add(1); // [rbp+8] = return address 706 let ra = *(fp as *const u64).add(1); // [rbp+8] = return address
700 if let Some((start, end)) = filter 707 if let Some((start, end)) = filter
701 && ra >= start as u64 && ra < end as u64 { 708 && ra >= start as u64
702 bt[bn] = ra; 709 && ra < end as u64
703 bn += 1; 710 {
704 } 711 bt[bn] = ra;
712 bn += 1;
713 }
705 let nfp = *(fp as *const u64); 714 let nfp = *(fp as *const u64);
706 if nfp <= fp { 715 if nfp <= fp {
707 break; // chain must grow upward 716 break; // chain must grow upward
@@ -715,19 +724,21 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra
715 while p + 8 <= limit && bn < bt.len() { 724 while p + 8 <= limit && bn < bt.len() {
716 let v = *(p as *const u64); 725 let v = *(p as *const u64);
717 if let Some((start, end)) = filter 726 if let Some((start, end)) = filter
718 && v >= start as u64 && v < end as u64 { 727 && v >= start as u64
719 let mut dup = false; 728 && v < end as u64
720 for i in 0..bn { 729 {
721 if bt[i] == v { 730 let mut dup = false;
722 dup = true; 731 for i in 0..bn {
723 break; 732 if bt[i] == v {
724 } 733 dup = true;
725 } 734 break;
726 if !dup {
727 bt[bn] = v;
728 bn += 1;
729 } 735 }
730 } 736 }
737 if !dup {
738 bt[bn] = v;
739 bn += 1;
740 }
741 }
731 p += 8; 742 p += 8;
732 } 743 }
733 } 744 }
@@ -842,7 +853,11 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra
842 &mut w, 853 &mut w,
843 core::format_args!( 854 core::format_args!(
844 "rax={:#x} rcx={:#x} rdx={:#x} rsi={:#x} rdi={:#x}", 855 "rax={:#x} rcx={:#x} rdx={:#x} rsi={:#x} rdi={:#x}",
845 frame.rax, frame.rcx, frame.rdx, frame.rsi, frame.rdi 856 frame.rax,
857 frame.rcx,
858 frame.rdx,
859 frame.rsi,
860 frame.rdi
846 ), 861 ),
847 ); 862 );
848 w.len() 863 w.len()