From ba304898b8e177d90afb58d201b4c3dd3c927c48 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 27 Aug 2026 17:23:34 +0200 Subject: GUI: window/event exports, paint binary, event-loop gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rsapi: WmEvent (kind=u8 enum: 0=key, 1=mouse, 2=focus, 3=close), WmKeyKind (Char/Enter/Backspace/F1-F4/…), WmMouseEvent (x/y/buttons), WindowInfo (ptr/w/h). Five new exports: wm_create, wm_buffer, wm_flush, wm_destroy, wm_recv (non-blocking TaskMsg dispatch → WmEvent). Shell: abi_wm_* wrappers bridge rsapi types to rsnix::wm and sched::recv(); wm_recv translates TaskMsg::Key/Mouse/Focus/Close into flat WmEvent union. bins/paint: gate binary — create_window + buffer + event loop with Bresenham line drawing, color select (1-8), clear (c), F4 close. All via wm_* ABI exports. Fully migrated: date, mem, pci, cat, ls, mkdir, touch, rm, klog, info, paint (11 external binaries in /bin/cli/ + 3 gate binaries). --- shell/src/lib.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'shell/src/lib.rs') diff --git a/shell/src/lib.rs b/shell/src/lib.rs index 11f5786..6de056c 100644 --- a/shell/src/lib.rs +++ b/shell/src/lib.rs @@ -1126,6 +1126,98 @@ fn abi_kernel_version(out: &mut rsapi::KernelVersion) { out.patch = patch; } + +/// ABI: create a window via the window manager. +fn abi_wm_create(title: rsapi::Line, w: u32, h: u32) -> i32 { + let s = title.as_str(); + match rsnix::wm::create_window(s, w as usize, h as usize) { + Some(id) => id as i32, + None => -1, + } +} + +/// ABI: get window pixel buffer info. +fn abi_wm_buffer(id: i32, out: &mut rsapi::WindowInfo) -> bool { + match rsnix::wm::buffer(id as usize) { + Some((ptr, w, h)) => { + out.ptr = ptr; + out.w = w as u32; + out.h = h as u32; + true + } + None => false, + } +} + +/// ABI: composite window to screen. +fn abi_wm_flush(id: i32) { + rsnix::wm::flush(id as usize); +} + +/// ABI: destroy a window. +fn abi_wm_destroy(id: i32) { + rsnix::wm::destroy(id as usize); +} + +/// ABI: non-blocking receive of one WM event. +fn abi_wm_recv(out: &mut rsapi::WmEvent) -> bool { + use rsnix::ps2::KeyEvent; + match rsnix::sched::recv() { + None => false, + Some(msg) => { + match msg { + rsnix::sched::TaskMsg::Key(k) => { + out.kind = 0; + match k { + KeyEvent::Char(c) => { + out.key_kind = rsapi::WmKeyKind::Char; + out.key_char = c as u8; + } + KeyEvent::Enter => { out.key_kind = rsapi::WmKeyKind::Enter; } + KeyEvent::Backspace => { out.key_kind = rsapi::WmKeyKind::Backspace; } + KeyEvent::Tab => { out.key_kind = rsapi::WmKeyKind::Tab; } + KeyEvent::Escape => { out.key_kind = rsapi::WmKeyKind::Escape; } + KeyEvent::Ctrl('c') => { out.key_kind = rsapi::WmKeyKind::CtrlC; } + KeyEvent::ArrowUp => { out.key_kind = rsapi::WmKeyKind::ArrowUp; } + KeyEvent::ArrowDown => { out.key_kind = rsapi::WmKeyKind::ArrowDown; } + KeyEvent::ArrowLeft => { out.key_kind = rsapi::WmKeyKind::ArrowLeft; } + KeyEvent::ArrowRight => { out.key_kind = rsapi::WmKeyKind::ArrowRight; } + KeyEvent::Home => { out.key_kind = rsapi::WmKeyKind::Home; } + KeyEvent::End => { out.key_kind = rsapi::WmKeyKind::End; } + KeyEvent::PageUp => { out.key_kind = rsapi::WmKeyKind::PageUp; } + KeyEvent::PageDown => { out.key_kind = rsapi::WmKeyKind::PageDown; } + KeyEvent::Delete => { out.key_kind = rsapi::WmKeyKind::Delete; } + KeyEvent::F(1) => { out.key_kind = rsapi::WmKeyKind::F1; } + KeyEvent::F(2) => { out.key_kind = rsapi::WmKeyKind::F2; } + KeyEvent::F(3) => { out.key_kind = rsapi::WmKeyKind::F3; } + KeyEvent::F(4) => { out.key_kind = rsapi::WmKeyKind::F4; } + _ => { out.key_kind = rsapi::WmKeyKind::Unknown; } + } + out.key_char = 0; + true + } + rsnix::sched::TaskMsg::AppMouse(m) => { + out.kind = 1; + out.mouse.x = m.x; + out.mouse.y = m.y; + out.mouse.buttons = m.buttons; + true + } + rsnix::sched::TaskMsg::Focus(f) => { + out.kind = 2; + out.focused = f; + true + } + rsnix::sched::TaskMsg::Close => { + out.kind = 3; + true + } + _ => false, + } + } + } +} + /// Construct the Exports table for this invocation. v2 fields are /// populated at runtime (binary callbacks → shell → kernel). fn build_exports() -> rsapi::Exports { @@ -1150,6 +1242,11 @@ fn build_exports() -> rsapi::Exports { pci_device: abi_pci_device, klog_dump: abi_klog_dump, kernel_version: abi_kernel_version, + wm_create: abi_wm_create, + wm_buffer: abi_wm_buffer, + wm_flush: abi_wm_flush, + wm_destroy: abi_wm_destroy, + wm_recv: abi_wm_recv, } } -- cgit v1.2.3