summaryrefslogtreecommitdiffstats
path: root/rsnix/src/fs.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-01 19:52:05 +0200
committersalmonik <salmonik@tuta.io>2026-08-01 19:52:05 +0200
commit819778f292ee4e1294603b98662e083e49e23463 (patch)
tree8df31b678432d2a89cac8e0d50f271a75a3882b5 /rsnix/src/fs.rs
parentrsnix v0.4.0: GUI input foundation — PS/2 mouse + scheduler message queues (diff)
downloadrs-dos-819778f292ee4e1294603b98662e083e49e23463.tar.gz
rs-dos-819778f292ee4e1294603b98662e083e49e23463.zip
rsnix v0.5.0: graphics layer + cursor compositor
The first visible GUI surface: real rect primitives, a single shadow→display push path, and an on-screen mouse cursor that can never race the text surface. gop: - fill_rect + push_rect(x,y,w,h): every raster op rasterises into the RAM shadow, then push_rect copies the rect to the display (write-only, still never read) and composites the cursor on top. blit_glyph and scroll shifts now route through it. - cursor overlay: 12x16 pointer (const-fn built from column lists) drawn white with a black offset outline; position in one AtomicU64 (x:high 32, y:low 32) — unpack masks the low word (a bare 'as usize' cast is a no-op on 64-bit). The cursor never enters the shadow, so erasing is just a shadow push of the old rect. - cursor_redraw after scroll shifts and once at spawn (the vt diff never re-blits idle cells). cursor task (task 2, spawned at boot when a mouse is present): - owns the PS/2 ring; polls every 10 ms, moves the cursor (clamped), tracks buttons, and forwards every event to a task's queue when 'mouse <id>' armed it (the window-manager input path). - /dev/mouse is now a position device (x/y/buttons snapshot); 'mouse' watches the cursor live (prints on change); 'cursor' prints one-shot state; 'gfx' draws a status-bar demo; 'gfx check' is an in-kernel pixel self-test (shadow readback, display readback, cursor overlay purity) — PASS/FAIL per stage. Tests (headless QEMU + monitor injection): - make test-gfx (new): all four compositor checks PASS. - make test-mouse (rewritten): cursor tracks mouse_move deltas, buttons ride along, /dev/mouse snapshot, live watch, real-event queue routing. - make test-msg: task numbering shifted (cursor is task 2; msgrecv is task 3) — updated, still PASS. - make test-disk regression re-passes. 0 build warnings.
Diffstat (limited to '')
-rw-r--r--rsnix/src/fs.rs37
1 files changed, 13 insertions, 24 deletions
diff --git a/rsnix/src/fs.rs b/rsnix/src/fs.rs
index 0b7a772..5fc6d7a 100644
--- a/rsnix/src/fs.rs
+++ b/rsnix/src/fs.rs
@@ -713,34 +713,23 @@ fn dev_text(dev: CharDevice, _pos: u64) -> String {
713 } 713 }
714} 714}
715 715
716/// Render `/dev/mouse`: drain every pending PS/2 event (up to 32) into one 716/// Render `/dev/mouse`: the current cursor state (position + buttons).
717/// line each, so `cat /dev/mouse` shows the movement that happened since 717/// The cursor task owns the PS/2 ring, so this is a position device —
718/// the last read. Falls back to a clear message when there is no device or 718/// the GUI-correct semantic — rather than an event drain.
719/// nothing pending.
720fn mouse_text() -> String { 719fn mouse_text() -> String {
721 if !crate::ps2::mouse_present() { 720 if !crate::ps2::mouse_present() {
722 return String::from("mouse: no PS/2 mouse\n"); 721 return String::from("mouse: no PS/2 mouse\n");
723 } 722 }
724 let mut s = String::new(); 723 let (x, y) = crate::gop::cursor_pos();
725 for _ in 0..32 { 724 let b = crate::gop::cursor_buttons();
726 let Some(ev) = crate::ps2::try_poll_mouse() else { 725 alloc::format!(
727 break; 726 "x={} y={} buttons={}{}{}\n",
728 }; 727 x,
729 let mut b = String::new(); 728 y,
730 b.push(if ev.left { 'L' } else { '-' }); 729 if b & 1 != 0 { 'L' } else { '-' },
731 b.push(if ev.right { 'R' } else { '-' }); 730 if b & 2 != 0 { 'R' } else { '-' },
732 b.push(if ev.middle { 'M' } else { '-' }); 731 if b & 4 != 0 { 'M' } else { '-' }
733 s.push_str(&alloc::format!( 732 )
734 "dx={:+} dy={:+} buttons={}\n",
735 ev.dx,
736 ev.dy,
737 b
738 ));
739 }
740 if s.is_empty() {
741 s.push_str("mouse: no events\n");
742 }
743 s
744} 733}
745 734
746// --- self-test ------------------------------------------------------------ 735// --- self-test ------------------------------------------------------------