1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
//! 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
}
|