summaryrefslogtreecommitdiffstats
path: root/rsnix/src/fs.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-01 19:34:40 +0200
committersalmonik <salmonik@tuta.io>2026-08-01 19:34:40 +0200
commit9b9758e5ee2564b04685eadf2b9ce23dd1060b86 (patch)
tree57fce9e715510ec70df70dc399b4440f3480fd77 /rsnix/src/fs.rs
parentfix pi-lens warnings: unwraps, shell SC2046, dup code (fmtbuf/scripts/hexdump... (diff)
downloadrs-dos-9b9758e5ee2564b04685eadf2b9ce23dd1060b86.tar.gz
rs-dos-9b9758e5ee2564b04685eadf2b9ce23dd1060b86.zip
rsnix v0.4.0: GUI input foundation — PS/2 mouse + scheduler message queues
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 <id>` routes real IRQ12 events into a task's queue, jobs shows q=. `make test-msg` + `make test-disk` regression pass.
Diffstat (limited to 'rsnix/src/fs.rs')
-rw-r--r--rsnix/src/fs.rs38
1 files changed, 38 insertions, 0 deletions
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 {
46 Zero, 46 Zero,
47 Console, 47 Console,
48 Serial, 48 Serial,
49 Mouse,
49} 50}
50 51
51enum NodeData { 52enum NodeData {
@@ -171,6 +172,12 @@ pub fn init() -> (usize, usize) {
171 FileType::Char, 172 FileType::Char,
172 NodeData::Char(CharDevice::Serial), 173 NodeData::Char(CharDevice::Serial),
173 ); 174 );
175 add(
176 "mouse",
177 Some(dev),
178 FileType::Char,
179 NodeData::Char(CharDevice::Mouse),
180 );
174 181
175 add( 182 add(
176 "motd", 183 "motd",
@@ -700,11 +707,42 @@ fn dev_text(dev: CharDevice, _pos: u64) -> String {
700 CharDevice::Version => version_text(), 707 CharDevice::Version => version_text(),
701 CharDevice::Meminfo => meminfo_text(), 708 CharDevice::Meminfo => meminfo_text(),
702 CharDevice::Klog => crate::klog::dump(), 709 CharDevice::Klog => crate::klog::dump(),
710 CharDevice::Mouse => mouse_text(),
703 CharDevice::Null | CharDevice::Console | CharDevice::Serial => String::new(), 711 CharDevice::Null | CharDevice::Console | CharDevice::Serial => String::new(),
704 CharDevice::Zero => String::new(), 712 CharDevice::Zero => String::new(),
705 } 713 }
706} 714}
707 715
716/// Render `/dev/mouse`: drain every pending PS/2 event (up to 32) into one
717/// line each, so `cat /dev/mouse` shows the movement that happened since
718/// the last read. Falls back to a clear message when there is no device or
719/// nothing pending.
720fn mouse_text() -> String {
721 if !crate::ps2::mouse_present() {
722 return String::from("mouse: no PS/2 mouse\n");
723 }
724 let mut s = String::new();
725 for _ in 0..32 {
726 let Some(ev) = crate::ps2::try_poll_mouse() else {
727 break;
728 };
729 let mut b = String::new();
730 b.push(if ev.left { 'L' } else { '-' });
731 b.push(if ev.right { 'R' } else { '-' });
732 b.push(if ev.middle { 'M' } else { '-' });
733 s.push_str(&alloc::format!(
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}
745
708// --- self-test ------------------------------------------------------------ 746// --- self-test ------------------------------------------------------------
709 747
710pub fn self_test() -> bool { 748pub fn self_test() -> bool {