From 9b9758e5ee2564b04685eadf2b9ce23dd1060b86 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sat, 1 Aug 2026 19:34:40 +0200 Subject: rsnix v0.4.0: GUI input foundation — PS/2 mouse + scheduler message queues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mouse (IRQ12, stream mode): ByteRing generalized for both PS/2 devices, ISR routes data-port bytes by the controller's aux bit; mouse_init with bounded-ACK handshake (boots without a mouse); packet decoder with bit-3 resync, screen-relative deltas, buttons. Exposed as /dev/mouse, the `mouse` stream command, and `make test-mouse`. Message queues (ADR 0003's GUI-era primitive): every task gets a static 16-slot TaskMsg ring; send/recv/recv_blocking with direct wake + tick scan safety net for the lost-wakeup race; `msgrecv`/`send` commands, `mouse ` routes real IRQ12 events into a task's queue, jobs shows q=. `make test-msg` + `make test-disk` regression pass. --- rsnix/src/fs.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'rsnix/src/fs.rs') diff --git a/rsnix/src/fs.rs b/rsnix/src/fs.rs index b560bfa..0b7a772 100644 --- a/rsnix/src/fs.rs +++ b/rsnix/src/fs.rs @@ -46,6 +46,7 @@ enum CharDevice { Zero, Console, Serial, + Mouse, } enum NodeData { @@ -171,6 +172,12 @@ pub fn init() -> (usize, usize) { FileType::Char, NodeData::Char(CharDevice::Serial), ); + add( + "mouse", + Some(dev), + FileType::Char, + NodeData::Char(CharDevice::Mouse), + ); add( "motd", @@ -700,11 +707,42 @@ fn dev_text(dev: CharDevice, _pos: u64) -> String { CharDevice::Version => version_text(), CharDevice::Meminfo => meminfo_text(), CharDevice::Klog => crate::klog::dump(), + CharDevice::Mouse => mouse_text(), CharDevice::Null | CharDevice::Console | CharDevice::Serial => String::new(), CharDevice::Zero => String::new(), } } +/// Render `/dev/mouse`: drain every pending PS/2 event (up to 32) into one +/// line each, so `cat /dev/mouse` shows the movement that happened since +/// the last read. Falls back to a clear message when there is no device or +/// nothing pending. +fn mouse_text() -> String { + if !crate::ps2::mouse_present() { + return String::from("mouse: no PS/2 mouse\n"); + } + let mut s = String::new(); + for _ in 0..32 { + let Some(ev) = crate::ps2::try_poll_mouse() else { + break; + }; + let mut b = String::new(); + b.push(if ev.left { 'L' } else { '-' }); + b.push(if ev.right { 'R' } else { '-' }); + b.push(if ev.middle { 'M' } else { '-' }); + s.push_str(&alloc::format!( + "dx={:+} dy={:+} buttons={}\n", + ev.dx, + ev.dy, + b + )); + } + if s.is_empty() { + s.push_str("mouse: no events\n"); + } + s +} + // --- self-test ------------------------------------------------------------ pub fn self_test() -> bool { -- cgit v1.2.3