emerald_kernel_user_link/
keyboard.rs

1pub const KEYBOARD_PATH: &str = "/devices/keyboard";
2
3pub mod modifier {
4    pub const SHIFT: u8 = 1 << 0;
5    pub const CTRL: u8 = 1 << 1;
6    pub const ALT: u8 = 1 << 2;
7
8    pub const CAPS_LOCK: u8 = 1 << 3;
9    pub const NUM_LOCK: u8 = 1 << 4;
10    pub const SCROLL_LOCK: u8 = 1 << 5;
11    pub const EXTENDED: u8 = 1 << 6;
12
13    // a way to compress the `bytes` value
14    pub const PRESSED: u8 = 1 << 7;
15}
16
17/// The index is `KeyType`
18const US_KEYTYPE_KEYMAP: [u8; 127] = [
19    0, 27, b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'-', b'=', b'\x08', b'\t',
20    b'q', b'w', b'e', b'r', b't', b'y', b'u', b'i', b'o', b'p', b'[', b']', b'\n', 0, b'a', b's',
21    b'd', b'f', b'g', b'h', b'j', b'k', b'l', b';', b'\'', b'`', 0, b'\\', b'z', b'x', b'c', b'v',
22    b'b', b'n', b'm', b',', b'.', b'/', 0, b'*', 0, b' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23    b'7', b'8', b'9', b'-', b'4', b'5', b'6', b'+', b'1', b'2', b'3', b'0', b'.', 0, 0, 0, 0, 0, 0,
24    0, b'\n', 0, 0, 0, 0, 0, 0, 0, 0, b'/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25    0, 0, 0, 0, 0, 0, 0, 0,
26];
27
28/// The index is `KeyType`
29const US_KEYTYPE_KEYMAP_SHIFTED: [u8; 127] = [
30    0, 27, b'!', b'@', b'#', b'$', b'%', b'^', b'&', b'*', b'(', b')', b'_', b'+', b'\x08', b'\t',
31    b'Q', b'W', b'E', b'R', b'T', b'Y', b'U', b'I', b'O', b'P', b'{', b'}', b'\n', 0, b'A', b'S',
32    b'D', b'F', b'G', b'H', b'J', b'K', b'L', b':', b'"', b'~', 0, b'|', b'Z', b'X', b'C', b'V',
33    b'B', b'N', b'M', b'<', b'>', b'?', 0, b'*', 0, b' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34    0, 0, b'-', 0, b'5', 0, b'+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36];
37
38#[repr(u8)]
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub enum KeyType {
41    // normal keys (mapped 1:1 with set 1 scan codes)
42    _None1,
43    Escape,
44    Num1,
45    Num2,
46    Num3,
47    Num4,
48    Num5,
49    Num6,
50    Num7,
51    Num8,
52    Num9,
53    Num0,
54    Minus,
55    Equals,
56    Backspace,
57    Tab,
58    Q,
59    W,
60    E,
61    R,
62    T,
63    Y,
64    U,
65    I,
66    O,
67    P,
68    LeftBracket,
69    RightBracket,
70    Enter,
71    LeftCtrl,
72    A,
73    S,
74    D,
75    F,
76    G,
77    H,
78    J,
79    K,
80    L,
81    Semicolon,
82    SingleQuote,
83    Backtick,
84    LeftShift,
85    Backslash,
86    Z,
87    X,
88    C,
89    V,
90    B,
91    N,
92    M,
93    Comma,
94    Dot,
95    Slash,
96    RightShift,
97    KeypadAsterisk,
98    LeftAlt,
99    Space,
100    CapsLock,
101    F1,
102    F2,
103    F3,
104    F4,
105    F5,
106    F6,
107    F7,
108    F8,
109    F9,
110    F10,
111    NumLock,
112    ScrollLock,
113    Keypad7,
114    Keypad8,
115    Keypad9,
116    KeypadMinus,
117    Keypad4,
118    Keypad5,
119    Keypad6,
120    KeypadPlus,
121    Keypad1,
122    Keypad2,
123    Keypad3,
124    Keypad0,
125    KeypadDot,
126    _None2,
127    _None3,
128    _None4,
129    F11,
130    F12,
131
132    // extended keys
133    MultimediaPreviousTrack,
134    MultimediaNextTrack,
135    KeypadEnter,
136    RightCtrl,
137    MultimediaMute,
138    Calculator,
139    MultimediaPlayPause,
140    MultimediaStop,
141    VolumeDown,
142    VolumeUp,
143    WWWHome,
144    KeypadSlash,
145    RightAlt,
146    Home,
147    UpArrow,
148    PageUp,
149    LeftArrow,
150    RightArrow,
151    End,
152    DownArrow,
153    PageDown,
154    Insert,
155    Delete,
156    LeftGUI,
157    RightGUI,
158    Application,
159    Power,
160    Sleep,
161    Wake,
162    WWWSearch,
163    WWWFavorites,
164    WWWRefresh,
165    WWWStop,
166    WWWForward,
167    WWWBack,
168    MyComputer,
169    Email,
170    MultimediaSelect,
171}
172
173impl KeyType {
174    pub fn virtual_key(&self, shifted: bool) -> Option<u8> {
175        let index = *self as usize;
176        let mappings = if shifted {
177            &US_KEYTYPE_KEYMAP_SHIFTED
178        } else {
179            &US_KEYTYPE_KEYMAP
180        };
181
182        assert!(index < mappings.len());
183        let value = mappings[index];
184
185        if value == 0 {
186            None
187        } else {
188            Some(value)
189        }
190    }
191}
192
193#[derive(Debug, Clone, Copy)]
194pub struct Key {
195    pub pressed: bool,
196    pub modifiers: u8,
197    pub key_type: KeyType,
198}
199
200impl Key {
201    pub const BYTES_SIZE: usize = 2;
202
203    /// # Safety
204    /// The `bytes` must be a valid representation of a `Key`
205    /// that has been created by `as_bytes`
206    pub unsafe fn from_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self {
207        let pressed = bytes[0] & modifier::PRESSED != 0;
208        let modifiers = bytes[0] & !modifier::PRESSED;
209        // Safety: we know that the `bytes` is a valid representation of `KeyType`
210        //         responsibility of the caller to ensure that
211        let key_type = core::mem::transmute::<u8, KeyType>(bytes[1]);
212
213        Self {
214            pressed,
215            modifiers,
216            key_type,
217        }
218    }
219
220    pub fn as_bytes(&self) -> [u8; 2] {
221        let mut bytes = [0; 2];
222        bytes[0] = (self.modifiers & !modifier::PRESSED)
223            | if self.pressed { modifier::PRESSED } else { 0 };
224        bytes[1] = self.key_type as u8;
225        bytes
226    }
227
228    pub fn virtual_char(&self) -> Option<u8> {
229        let shifted = self.modifiers & modifier::SHIFT != 0;
230        self.key_type.virtual_key(shifted)
231    }
232}