emerald_runtime/
keyboard.rs

1use std::{fs::File, io::Read, thread::sleep};
2
3use kernel_user_link::keyboard::KEYBOARD_PATH;
4pub use kernel_user_link::keyboard::{modifier, Key, KeyType};
5
6pub struct Keyboard {
7    file: File,
8}
9
10impl Keyboard {
11    pub fn new() -> Self {
12        let file = File::open(KEYBOARD_PATH).unwrap();
13        Keyboard { file }
14    }
15
16    pub fn get_key_event(&mut self) -> Option<Key> {
17        let mut buf = [0; Key::BYTES_SIZE];
18        if self.file.read(&mut buf).unwrap() == Key::BYTES_SIZE {
19            // Safety: we are using the same size as the Key struct
20            // and this is provided by the kernel, so it must
21            // be valid
22            Some(unsafe { Key::from_bytes(buf) })
23        } else {
24            None
25        }
26    }
27
28    pub fn iter_keys(&mut self) -> impl Iterator<Item = Key> + '_ {
29        std::iter::from_fn(move || self.get_key_event())
30    }
31
32    // TODO: this is a temporary solution, we should use a better way to wait for input
33    pub fn wait_for_input(&mut self) -> Key {
34        loop {
35            if let Some(key) = self.get_key_event() {
36                return key;
37            }
38            sleep(std::time::Duration::from_millis(10));
39        }
40    }
41}