morpheus_bootloader/tui/
input.rs

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
use crate::SimpleTextInputProtocol;

#[repr(C)]
pub struct InputKey {
    pub scan_code: u16,
    pub unicode_char: u16,
}

// Scan codes for special keys
pub const SCAN_UP: u16 = 0x01;
pub const SCAN_DOWN: u16 = 0x02;
pub const SCAN_RIGHT: u16 = 0x03;
pub const SCAN_LEFT: u16 = 0x04;
pub const SCAN_ESC: u16 = 0x17;

// ASCII codes
pub const KEY_ENTER: u16 = 0x0D;
pub const KEY_SPACE: u16 = 0x20;

pub struct Keyboard {
    input: *mut SimpleTextInputProtocol,
}

impl Keyboard {
    pub fn new(input: *mut SimpleTextInputProtocol) -> Self {
        Self { input }
    }

    pub fn read_key(&mut self) -> Option<InputKey> {
        unsafe {
            let mut key = InputKey {
                scan_code: 0,
                unicode_char: 0,
            };

            let status = ((*self.input).read_key_stroke)(self.input, &mut key);

            // EFI_SUCCESS = 0
            if status == 0 {
                Some(key)
            } else {
                None
            }
        }
    }

    pub fn wait_for_key(&mut self) -> InputKey {
        loop {
            if let Some(key) = self.read_key() {
                return key;
            }
            // Small delay to avoid spinning
            for _ in 0..10000 {
                unsafe {
                    core::ptr::read_volatile(&0);
                }
            }
        }
    }

    // Poll for key with a small delay for animation loops (approx 60Hz)
    pub fn poll_key_with_delay(&mut self) -> Option<InputKey> {
        let key = self.read_key();

        // Delay for ~16ms (60 FPS) - increased from 10k to 100k iterations
        for _ in 0..100000 {
            unsafe {
                core::ptr::read_volatile(&0);
            }
        }

        key
    }
}