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}