pc_keyboard/scancodes/
set2.rs

1//! Scan Code Set 2 support
2
3use crate::{
4    DecodeState, Error, KeyCode, KeyEvent, KeyState, ScancodeSet, EXTENDED2_KEY_CODE,
5    EXTENDED_KEY_CODE, KEY_RELEASE_CODE,
6};
7
8/// Contains the implementation of Scancode Set 2.
9///
10/// See the OS dev wiki: <https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_2>
11/// Additional reference: <https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html>
12pub struct ScancodeSet2 {
13    state: DecodeState,
14}
15
16impl ScancodeSet2 {
17    /// Construct a new [`ScancodeSet2`] decoder.
18    pub const fn new() -> ScancodeSet2 {
19        ScancodeSet2 {
20            state: DecodeState::Start,
21        }
22    }
23
24    /// Implements the single byte codes for Set 2.
25    fn map_scancode(code: u8) -> Result<KeyCode, Error> {
26        match code {
27            0x00 => Ok(KeyCode::TooManyKeys),
28            0x01 => Ok(KeyCode::F9),
29            // 0x02
30            0x03 => Ok(KeyCode::F5),
31            0x04 => Ok(KeyCode::F3),
32            0x05 => Ok(KeyCode::F1),
33            0x06 => Ok(KeyCode::F2),
34            0x07 => Ok(KeyCode::F12),
35            0x09 => Ok(KeyCode::F10),
36            0x0A => Ok(KeyCode::F8),
37            0x0B => Ok(KeyCode::F6),
38            0x0C => Ok(KeyCode::F4),
39            0x0D => Ok(KeyCode::Tab),
40            0x0E => Ok(KeyCode::Oem8),
41            0x11 => Ok(KeyCode::LAlt),
42            0x12 => Ok(KeyCode::LShift),
43            0x13 => Ok(KeyCode::Oem11),
44            0x14 => Ok(KeyCode::LControl),
45            0x15 => Ok(KeyCode::Q),
46            0x16 => Ok(KeyCode::Key1),
47            0x1A => Ok(KeyCode::Z),
48            0x1B => Ok(KeyCode::S),
49            0x1C => Ok(KeyCode::A),
50            0x1D => Ok(KeyCode::W),
51            0x1E => Ok(KeyCode::Key2),
52            0x21 => Ok(KeyCode::C),
53            0x22 => Ok(KeyCode::X),
54            0x23 => Ok(KeyCode::D),
55            0x24 => Ok(KeyCode::E),
56            0x25 => Ok(KeyCode::Key4),
57            0x26 => Ok(KeyCode::Key3),
58            0x29 => Ok(KeyCode::Spacebar),
59            0x2A => Ok(KeyCode::V),
60            0x2B => Ok(KeyCode::F),
61            0x2C => Ok(KeyCode::T),
62            0x2D => Ok(KeyCode::R),
63            0x2E => Ok(KeyCode::Key5),
64            0x31 => Ok(KeyCode::N),
65            0x32 => Ok(KeyCode::B),
66            0x33 => Ok(KeyCode::H),
67            0x34 => Ok(KeyCode::G),
68            0x35 => Ok(KeyCode::Y),
69            0x36 => Ok(KeyCode::Key6),
70            0x3A => Ok(KeyCode::M),
71            0x3B => Ok(KeyCode::J),
72            0x3C => Ok(KeyCode::U),
73            0x3D => Ok(KeyCode::Key7),
74            0x3E => Ok(KeyCode::Key8),
75            0x41 => Ok(KeyCode::OemComma),
76            0x42 => Ok(KeyCode::K),
77            0x43 => Ok(KeyCode::I),
78            0x44 => Ok(KeyCode::O),
79            0x45 => Ok(KeyCode::Key0),
80            0x46 => Ok(KeyCode::Key9),
81            0x49 => Ok(KeyCode::OemPeriod),
82            0x4A => Ok(KeyCode::Oem2),
83            0x4B => Ok(KeyCode::L),
84            0x4C => Ok(KeyCode::Oem1),
85            0x4D => Ok(KeyCode::P),
86            0x4E => Ok(KeyCode::OemMinus),
87            0x51 => Ok(KeyCode::Oem12),
88            0x52 => Ok(KeyCode::Oem3),
89            0x54 => Ok(KeyCode::Oem4),
90            0x55 => Ok(KeyCode::OemPlus),
91            0x58 => Ok(KeyCode::CapsLock),
92            0x59 => Ok(KeyCode::RShift),
93            0x5A => Ok(KeyCode::Return),
94            0x5B => Ok(KeyCode::Oem6),
95            0x5D => Ok(KeyCode::Oem7),
96            0x61 => Ok(KeyCode::Oem5),
97            0x64 => Ok(KeyCode::Oem10),
98            0x66 => Ok(KeyCode::Backspace),
99            0x67 => Ok(KeyCode::Oem9),
100            0x69 => Ok(KeyCode::Numpad1),
101            0x6A => Ok(KeyCode::Oem13),
102            0x6B => Ok(KeyCode::Numpad4),
103            0x6C => Ok(KeyCode::Numpad7),
104            0x70 => Ok(KeyCode::Numpad0),
105            0x71 => Ok(KeyCode::NumpadPeriod),
106            0x72 => Ok(KeyCode::Numpad2),
107            0x73 => Ok(KeyCode::Numpad5),
108            0x74 => Ok(KeyCode::Numpad6),
109            0x75 => Ok(KeyCode::Numpad8),
110            0x76 => Ok(KeyCode::Escape),
111            0x77 => Ok(KeyCode::NumpadLock),
112            0x78 => Ok(KeyCode::F11),
113            0x79 => Ok(KeyCode::NumpadAdd),
114            0x7A => Ok(KeyCode::Numpad3),
115            0x7B => Ok(KeyCode::NumpadSubtract),
116            0x7C => Ok(KeyCode::NumpadMultiply),
117            0x7D => Ok(KeyCode::Numpad9),
118            0x7E => Ok(KeyCode::ScrollLock),
119            0x7F => Ok(KeyCode::SysRq),
120            0x83 => Ok(KeyCode::F7),
121            0xAA => Ok(KeyCode::PowerOnTestOk),
122            _ => Err(Error::UnknownKeyCode),
123        }
124    }
125
126    /// Implements the extended byte codes for set 2 (prefixed with E0)
127    fn map_extended_scancode(code: u8) -> Result<KeyCode, Error> {
128        match code {
129            0x11 => Ok(KeyCode::RAltGr),
130            0x12 => Ok(KeyCode::RAlt2),
131            0x14 => Ok(KeyCode::RControl),
132            0x15 => Ok(KeyCode::PrevTrack),
133            0x1F => Ok(KeyCode::LWin),
134            0x21 => Ok(KeyCode::VolumeDown),
135            0x23 => Ok(KeyCode::Mute),
136            0x27 => Ok(KeyCode::RWin),
137            0x2B => Ok(KeyCode::Calculator),
138            0x2F => Ok(KeyCode::Apps),
139            0x32 => Ok(KeyCode::VolumeUp),
140            0x34 => Ok(KeyCode::Play),
141            0x3A => Ok(KeyCode::WWWHome),
142            0x3B => Ok(KeyCode::Stop),
143            0x4A => Ok(KeyCode::NumpadDivide),
144            0x4D => Ok(KeyCode::NextTrack),
145            0x5A => Ok(KeyCode::NumpadEnter),
146            0x69 => Ok(KeyCode::End),
147            0x6B => Ok(KeyCode::ArrowLeft),
148            0x6C => Ok(KeyCode::Home),
149            0x70 => Ok(KeyCode::Insert),
150            0x71 => Ok(KeyCode::Delete),
151            0x72 => Ok(KeyCode::ArrowDown),
152            0x74 => Ok(KeyCode::ArrowRight),
153            0x75 => Ok(KeyCode::ArrowUp),
154            0x7A => Ok(KeyCode::PageDown),
155            0x7C => Ok(KeyCode::PrintScreen),
156            0x7D => Ok(KeyCode::PageUp),
157            _ => Err(Error::UnknownKeyCode),
158        }
159    }
160
161    /// Implements the alternate extended byte codes for set 2 (prefixed with E1)
162    fn map_extended2_scancode(code: u8) -> Result<KeyCode, Error> {
163        match code {
164            0x14 => Ok(KeyCode::RControl2),
165            _ => Err(Error::UnknownKeyCode),
166        }
167    }
168}
169
170impl ScancodeSet for ScancodeSet2 {
171    /// Implements state logic for scancode set 2
172    ///
173    /// ## Start:
174    /// * F0 => Goto Release
175    /// * E0 => Goto Extended
176    /// * E1 => Goto Extended2
177    /// * xx => Key Down Event
178    ///
179    /// ## Release:
180    /// * xxx => Key Up Event
181    ///
182    /// ## Extended:
183    /// * F0 => Goto Release-Extended
184    /// * xx => Extended Key Down Event
185    ///
186    /// ## Release-Extended:
187    /// * xxx => Extended Key Up Event
188    ///
189    /// ## Extended2:
190    /// * F0 => Goto Release-Extended2
191    /// * xx => Extended2 Key Down Event
192    ///
193    /// ## Release-Extended2:
194    /// * xxx => Extended2 Key Up Event
195    fn advance_state(&mut self, code: u8) -> Result<Option<KeyEvent>, Error> {
196        match self.state {
197            DecodeState::Start => match code {
198                EXTENDED_KEY_CODE => {
199                    self.state = DecodeState::Extended;
200                    Ok(None)
201                }
202                EXTENDED2_KEY_CODE => {
203                    self.state = DecodeState::Extended2;
204                    Ok(None)
205                }
206                KEY_RELEASE_CODE => {
207                    self.state = DecodeState::Release;
208                    Ok(None)
209                }
210                _ => {
211                    let keycode = Self::map_scancode(code)?;
212                    if keycode == KeyCode::TooManyKeys || keycode == KeyCode::PowerOnTestOk {
213                        Ok(Some(KeyEvent::new(keycode, KeyState::SingleShot)))
214                    } else {
215                        Ok(Some(KeyEvent::new(
216                            Self::map_scancode(code)?,
217                            KeyState::Down,
218                        )))
219                    }
220                }
221            },
222            DecodeState::Release => {
223                self.state = DecodeState::Start;
224                Ok(Some(KeyEvent::new(Self::map_scancode(code)?, KeyState::Up)))
225            }
226            DecodeState::Extended => match code {
227                KEY_RELEASE_CODE => {
228                    self.state = DecodeState::ExtendedRelease;
229                    Ok(None)
230                }
231                _ => {
232                    self.state = DecodeState::Start;
233
234                    let keycode = Self::map_extended_scancode(code)?;
235                    Ok(Some(KeyEvent::new(keycode, KeyState::Down)))
236                }
237            },
238            DecodeState::ExtendedRelease => {
239                self.state = DecodeState::Start;
240                Ok(Some(KeyEvent::new(
241                    Self::map_extended_scancode(code)?,
242                    KeyState::Up,
243                )))
244            }
245            DecodeState::Extended2 => match code {
246                KEY_RELEASE_CODE => {
247                    self.state = DecodeState::Extended2Release;
248                    Ok(None)
249                }
250                _ => {
251                    self.state = DecodeState::Start;
252                    Ok(Some(KeyEvent::new(
253                        Self::map_extended2_scancode(code)?,
254                        KeyState::Down,
255                    )))
256                }
257            },
258            DecodeState::Extended2Release => {
259                self.state = DecodeState::Start;
260                Ok(Some(KeyEvent::new(
261                    Self::map_extended2_scancode(code)?,
262                    KeyState::Up,
263                )))
264            }
265        }
266    }
267}
268
269impl Default for ScancodeSet2 {
270    fn default() -> Self {
271        ScancodeSet2::new()
272    }
273}
274
275#[cfg(test)]
276mod test {
277    use super::*;
278
279    #[test]
280    fn validate_scancodes() {
281        let mut codes = Vec::new();
282        let mut errs = Vec::new();
283        for code in 0x00..=0xFF {
284            let r = ScancodeSet2::map_scancode(code);
285            match r {
286                Ok(c) => codes.push(c),
287                Err(_) => errs.push(code),
288            }
289        }
290        codes.sort();
291        println!("{:?}", codes);
292        assert_eq!(codes.len(), 94);
293        assert_eq!(errs.len(), 162);
294    }
295}