//! paint — drawing canvas via the GUI exports table. //! //! Keys: 1-8 select color, c clears to black. Mouse draws when pressed. #![no_std] #![no_main] #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop { core::hint::spin_loop(); } } const W: u32 = 640; const H: u32 = 400; const fn pack(r: u8, g: u8, b: u8) -> u32 { ((r as u32) << 16) | ((g as u32) << 8) | (b as u32) } const PALETTE: [u32; 9] = [ pack(255, 255, 255), // 1 white pack(255, 0, 0), // 2 red pack(0, 255, 0), // 3 green pack(0, 0, 255), // 4 blue pack(255, 255, 0), // 5 yellow pack(255, 0, 255), // 6 magenta pack(0, 255, 255), // 7 cyan pack(255, 128, 0), // 8 orange pack(0, 0, 0), // clear (black) ]; #[unsafe(no_mangle)] pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 { // Create window let title = b"paint"; let win = (exports.wm_create)(rsapi::Line { ptr: title.as_ptr(), len: title.len() }, W, H); if win < 0 { return 1; } // Get pixel buffer let mut info = rsapi::WindowInfo { ptr: core::ptr::null_mut(), w: 0, h: 0 }; if !(exports.wm_buffer)(win, &mut info) { (exports.wm_destroy)(win); return 1; } let buf = info.ptr; let bw = info.w as usize; let bh = info.h as usize; let mut color: usize = 0; let mut last_x: i32 = -1; let mut last_y: i32 = -1; let mut ev = rsapi::WmEvent { kind: 0, key_kind: rsapi::WmKeyKind::Char, key_char: 0, mouse: rsapi::WmMouseEvent { x: 0, y: 0, buttons: 0 }, focused: false, _pad: [0; 4], }; // Event loop loop { if !(exports.wm_recv)(&mut ev) { continue; } match ev.kind { 0 => { // Key event match ev.key_kind { rsapi::WmKeyKind::Char => { match ev.key_char { b'1'..=b'8' => color = (ev.key_char - b'1') as usize, b'c' => { unsafe { let n = bw * bh; let p = buf as *mut u32; for i in 0..n { *p.add(i) = 0; } } (exports.wm_flush)(win); } _ => {} } } rsapi::WmKeyKind::F4 => break, _ => {} } } 1 => { // Mouse event let m = &ev.mouse; if m.buttons & 1 != 0 { // Left button: draw pixel at (m.x, m.y) if m.x >= 0 && m.y >= 0 && (m.x as usize) < bw && (m.y as usize) < bh { unsafe { *buf.add(m.y as usize * bw + m.x as usize) = PALETTE[color % PALETTE.len()]; } // Connect with last point (line drawing) if last_x >= 0 { let lx = last_x; let ly = last_y; let dx = (m.x - lx).abs(); let sx = if lx < m.x { 1 } else { -1 }; let dy = -(m.y - ly).abs(); let sy = if ly < m.y { 1 } else { -1 }; let mut err = dx + dy; let mut cx = lx; let mut cy = ly; loop { if cx >= 0 && cy >= 0 && (cx as usize) < bw && (cy as usize) < bh { unsafe { *buf.add(cy as usize * bw + cx as usize) = PALETTE[color % PALETTE.len()]; } } if cx == m.x && cy == m.y { break; } let e2 = 2 * err; if e2 >= dy { err += dy; cx += sx; } if e2 <= dx { err += dx; cy += sy; } } } (exports.wm_flush)(win); last_x = m.x; last_y = m.y; } } else { last_x = -1; last_y = -1; } } 2 => {} // focus 3 => break, // close _ => {} } } (exports.wm_destroy)(win); 0 }