i8042/
keyboard.rs

1use pc_keyboard::{
2    layouts::Us104Key, DecodedKey, HandleControl, Keyboard as PcKeyboard, ScancodeSet1,
3    ScancodeSet2,
4};
5
6#[derive(Debug, PartialEq, Eq)]
7pub(crate) enum KeyboardKind {
8    MF2,
9    Short,
10    N97,
11    K122,
12    MF2Emul,
13    JapG,
14    JapP,
15    JapA,
16    Sun,
17}
18
19enum SomeKeyboard {
20    Set1(PcKeyboard<Us104Key, ScancodeSet1>),
21    Set2(PcKeyboard<Us104Key, ScancodeSet2>),
22}
23
24impl SomeKeyboard {
25    fn handle_data(&mut self, data: u8) -> Option<DecodedKey> {
26        macro_rules! get_kbd {
27            ($k:ident, $e:expr) => {{
28                match self {
29                    SomeKeyboard::Set1(k) => {
30                        let $k = k;
31                        $e
32                    }
33                    SomeKeyboard::Set2(k) => {
34                        let $k = k;
35                        $e
36                    }
37                }
38            }};
39        }
40
41        if let Ok(Some(event)) = get_kbd!(k, k.add_byte(data)) {
42            get_kbd!(k, k.process_keyevent(event))
43        } else {
44            None
45        }
46    }
47}
48
49impl core::fmt::Debug for SomeKeyboard {
50    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
51        write!(f, "SomeKeyboard")?;
52        Ok(())
53    }
54}
55
56#[derive(Debug)]
57enum State {
58    Disabled,
59    Init(Init),
60    Normal(SomeKeyboard),
61}
62
63#[derive(Debug)]
64enum Init {
65    ReqScancodeSetAck,
66    ReqScancodeSetRsp,
67    EnableAck(u8),
68}
69
70#[derive(Debug)]
71pub(crate) struct Keyboard {
72    state: State,
73}
74
75impl Keyboard {
76    pub(crate) fn new(kind: KeyboardKind) -> (Option<u8>, Self) {
77        if kind == KeyboardKind::MF2 {
78            (
79                Some(0xF0),
80                Self {
81                    state: State::Init(Init::ReqScancodeSetAck),
82                },
83            )
84        } else {
85            (
86                None,
87                Self {
88                    state: State::Disabled,
89                },
90            )
91        }
92    }
93
94    pub(crate) fn handle_data(&mut self, data: u8) -> (Option<u8>, Option<DecodedKey>) {
95        match self.state {
96            State::Disabled => (None, None),
97            State::Init(ref mut init) => match init {
98                Init::ReqScancodeSetAck => {
99                    self.state = State::Init(Init::ReqScancodeSetRsp);
100                    (Some(0x00), None)
101                }
102                Init::ReqScancodeSetRsp => match data {
103                    1 | 2 | 3 => {
104                        self.state = State::Init(Init::EnableAck(data));
105                        (Some(0xF4), None)
106                    }
107                    0xFA => (None, None),
108                    _ => {
109                        self.state = State::Disabled;
110                        (None, None)
111                    }
112                },
113                Init::EnableAck(set) => match data {
114                    0xFA => {
115                        let keyboard = match set {
116                            1 => SomeKeyboard::Set1(PcKeyboard::new(
117                                ScancodeSet1::new(),
118                                Us104Key,
119                                HandleControl::Ignore,
120                            )),
121                            2 => SomeKeyboard::Set2(PcKeyboard::new(
122                                ScancodeSet2::new(),
123                                Us104Key,
124                                HandleControl::Ignore,
125                            )),
126                            3 => {
127                                self.state = State::Disabled;
128                                return (None, None);
129                            }
130                            _ => {
131                                self.state = State::Disabled;
132                                return (None, None);
133                            }
134                        };
135
136                        self.state = State::Normal(keyboard);
137                        (None, None)
138                    }
139                    _ => {
140                        self.state = State::Disabled;
141                        (None, None)
142                    }
143                },
144            },
145            State::Normal(ref mut keyboard) => match data {
146                0x00 | 0xFF | 0xAA | 0xFC | 0xFD | 0xEE | 0xFA | 0xFE => (None, None),
147                _ => {
148                    let key = keyboard.handle_data(data);
149                    (None, key)
150                }
151            },
152        }
153    }
154}