1use crate::error::Result;
7use crate::mapper::ScancodeMapper;
8use std::collections::HashSet;
9use std::time::Instant;
10use tracing::debug;
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
14pub struct KeyModifiers {
15 pub shift: bool,
17 pub ctrl: bool,
19 pub alt: bool,
21 pub meta: bool,
23 pub caps_lock: bool,
25 pub num_lock: bool,
27 pub scroll_lock: bool,
29}
30
31#[derive(Debug, Clone)]
33pub enum KeyboardEvent {
34 KeyDown {
36 keycode: u32,
38 scancode: u16,
40 modifiers: KeyModifiers,
42 timestamp: Instant,
44 },
45
46 KeyUp {
48 keycode: u32,
50 scancode: u16,
52 modifiers: KeyModifiers,
54 timestamp: Instant,
56 },
57
58 KeyRepeat {
60 keycode: u32,
62 scancode: u16,
64 modifiers: KeyModifiers,
66 timestamp: Instant,
68 },
69}
70
71pub struct KeyboardHandler {
73 mapper: ScancodeMapper,
75
76 pressed_keys: HashSet<u32>,
78
79 modifiers: KeyModifiers,
81
82 last_key_times: std::collections::HashMap<u32, Instant>,
84
85 repeat_delay_ms: u64,
87
88 repeat_rate_ms: u64,
90}
91
92impl KeyboardHandler {
93 pub fn new() -> Self {
95 Self {
96 mapper: ScancodeMapper::new(),
97 pressed_keys: HashSet::new(),
98 modifiers: KeyModifiers::default(),
99 last_key_times: std::collections::HashMap::new(),
100 repeat_delay_ms: 500,
101 repeat_rate_ms: 33,
102 }
103 }
104
105 pub fn handle_key_down(&mut self, scancode: u16, extended: bool, e1_prefix: bool) -> Result<KeyboardEvent> {
107 let keycode = self.mapper.translate_scancode(scancode as u32, extended, e1_prefix)?;
109
110 let timestamp = Instant::now();
111
112 let is_repeat = self.pressed_keys.contains(&keycode);
114
115 if is_repeat {
116 if let Some(last_time) = self.last_key_times.get(&keycode) {
118 let elapsed = timestamp.duration_since(*last_time).as_millis() as u64;
119 if elapsed < self.repeat_rate_ms {
120 debug!("Key repeat within rate limit: keycode {}", keycode);
122 return Ok(KeyboardEvent::KeyRepeat {
123 keycode,
124 scancode,
125 modifiers: self.modifiers,
126 timestamp,
127 });
128 }
129 }
130 }
131
132 self.pressed_keys.insert(keycode);
134 self.last_key_times.insert(keycode, timestamp);
135
136 self.update_modifiers(keycode, true);
138
139 debug!(
140 "Key down: scancode=0x{:04X}, keycode={}, modifiers={:?}",
141 scancode, keycode, self.modifiers
142 );
143
144 if is_repeat {
145 Ok(KeyboardEvent::KeyRepeat {
146 keycode,
147 scancode,
148 modifiers: self.modifiers,
149 timestamp,
150 })
151 } else {
152 Ok(KeyboardEvent::KeyDown {
153 keycode,
154 scancode,
155 modifiers: self.modifiers,
156 timestamp,
157 })
158 }
159 }
160
161 pub fn handle_key_up(&mut self, scancode: u16, extended: bool, e1_prefix: bool) -> Result<KeyboardEvent> {
163 let keycode = self.mapper.translate_scancode(scancode as u32, extended, e1_prefix)?;
165
166 let timestamp = Instant::now();
167
168 self.pressed_keys.remove(&keycode);
170 self.last_key_times.remove(&keycode);
171
172 self.update_modifiers(keycode, false);
174
175 debug!(
176 "Key up: scancode=0x{:04X}, keycode={}, modifiers={:?}",
177 scancode, keycode, self.modifiers
178 );
179
180 Ok(KeyboardEvent::KeyUp {
181 keycode,
182 scancode,
183 modifiers: self.modifiers,
184 timestamp,
185 })
186 }
187
188 fn update_modifiers(&mut self, keycode: u32, pressed: bool) {
190 #[allow(clippy::wildcard_imports)]
191 use crate::mapper::keycodes::*;
192
193 match keycode {
194 KEY_LEFTSHIFT | KEY_RIGHTSHIFT => {
195 if pressed {
196 self.modifiers.shift = true;
197 } else {
198 self.modifiers.shift = self.is_key_pressed(KEY_LEFTSHIFT) || self.is_key_pressed(KEY_RIGHTSHIFT);
200 }
201 }
202 KEY_LEFTCTRL | KEY_RIGHTCTRL => {
203 if pressed {
204 self.modifiers.ctrl = true;
205 } else {
206 self.modifiers.ctrl = self.is_key_pressed(KEY_LEFTCTRL) || self.is_key_pressed(KEY_RIGHTCTRL);
207 }
208 }
209 KEY_LEFTALT | KEY_RIGHTALT => {
210 if pressed {
211 self.modifiers.alt = true;
212 } else {
213 self.modifiers.alt = self.is_key_pressed(KEY_LEFTALT) || self.is_key_pressed(KEY_RIGHTALT);
214 }
215 }
216 KEY_LEFTMETA | KEY_RIGHTMETA => {
217 if pressed {
218 self.modifiers.meta = true;
219 } else {
220 self.modifiers.meta = self.is_key_pressed(KEY_LEFTMETA) || self.is_key_pressed(KEY_RIGHTMETA);
221 }
222 }
223 KEY_CAPSLOCK => {
224 if pressed {
225 self.modifiers.caps_lock = !self.modifiers.caps_lock;
226 }
227 }
228 KEY_NUMLOCK => {
229 if pressed {
230 self.modifiers.num_lock = !self.modifiers.num_lock;
231 }
232 }
233 KEY_SCROLLLOCK => {
234 if pressed {
235 self.modifiers.scroll_lock = !self.modifiers.scroll_lock;
236 }
237 }
238 _ => {}
239 }
240 }
241
242 pub fn is_key_pressed(&self, keycode: u32) -> bool {
244 self.pressed_keys.contains(&keycode)
245 }
246
247 pub fn modifiers(&self) -> KeyModifiers {
249 self.modifiers
250 }
251
252 pub fn set_layout(&mut self, layout: &str) {
254 self.mapper.set_layout(layout);
255 debug!("Keyboard layout changed to: {}", layout);
256 }
257
258 pub fn layout(&self) -> &str {
260 self.mapper.layout()
261 }
262
263 pub fn set_repeat_delay(&mut self, delay_ms: u64) {
265 self.repeat_delay_ms = delay_ms;
266 }
267
268 pub fn set_repeat_rate(&mut self, rate_ms: u64) {
270 self.repeat_rate_ms = rate_ms;
271 }
272
273 pub fn reset(&mut self) {
275 self.pressed_keys.clear();
276 self.last_key_times.clear();
277 self.modifiers = KeyModifiers::default();
278 debug!("Keyboard state reset");
279 }
280
281 pub fn pressed_key_count(&self) -> usize {
283 self.pressed_keys.len()
284 }
285
286 pub fn get_pressed_keys(&self) -> Vec<u32> {
288 self.pressed_keys.iter().copied().collect()
289 }
290}
291
292impl Default for KeyboardHandler {
293 fn default() -> Self {
294 Self::new()
295 }
296}
297
298#[cfg(test)]
299mod tests {
300 use super::*;
301
302 #[test]
303 fn test_keyboard_handler_creation() {
304 let handler = KeyboardHandler::new();
305 assert_eq!(handler.pressed_key_count(), 0);
306 assert!(!handler.modifiers().shift);
307 }
308
309 #[test]
310 fn test_key_press_release() {
311 let mut handler = KeyboardHandler::new();
312
313 let event = handler.handle_key_down(0x1E, false, false).unwrap();
315
316 match event {
317 KeyboardEvent::KeyDown { keycode, .. } => {
318 assert!(keycode > 0);
319 assert!(handler.is_key_pressed(keycode));
320 }
321 _ => panic!("Expected KeyDown event"),
322 }
323
324 assert_eq!(handler.pressed_key_count(), 1);
325
326 let event = handler.handle_key_up(0x1E, false, false).unwrap();
328
329 match event {
330 KeyboardEvent::KeyUp { keycode, .. } => {
331 assert!(!handler.is_key_pressed(keycode));
332 }
333 _ => panic!("Expected KeyUp event"),
334 }
335
336 assert_eq!(handler.pressed_key_count(), 0);
337 }
338
339 #[test]
340 fn test_modifier_tracking() {
341 let mut handler = KeyboardHandler::new();
342
343 handler.handle_key_down(0x2A, false, false).unwrap();
345 assert!(handler.modifiers().shift);
346
347 handler.handle_key_down(0x1D, false, false).unwrap();
349 assert!(handler.modifiers().ctrl);
350
351 handler.handle_key_up(0x2A, false, false).unwrap();
353 assert!(!handler.modifiers().shift);
354 assert!(handler.modifiers().ctrl);
355
356 handler.handle_key_up(0x1D, false, false).unwrap();
358 assert!(!handler.modifiers().ctrl);
359 }
360
361 #[test]
362 fn test_caps_lock_toggle() {
363 let mut handler = KeyboardHandler::new();
364
365 assert!(!handler.modifiers().caps_lock);
366
367 handler.handle_key_down(0x3A, false, false).unwrap();
369 assert!(handler.modifiers().caps_lock);
370
371 handler.handle_key_up(0x3A, false, false).unwrap();
373 assert!(handler.modifiers().caps_lock); handler.handle_key_down(0x3A, false, false).unwrap();
377 assert!(!handler.modifiers().caps_lock);
378 }
379
380 #[test]
381 fn test_multiple_modifiers() {
382 let mut handler = KeyboardHandler::new();
383
384 handler.handle_key_down(0x2A, false, false).unwrap(); handler.handle_key_down(0x1D, false, false).unwrap(); handler.handle_key_down(0x38, false, false).unwrap(); let mods = handler.modifiers();
390 assert!(mods.shift);
391 assert!(mods.ctrl);
392 assert!(mods.alt);
393 }
394
395 #[test]
396 fn test_both_shifts() {
397 let mut handler = KeyboardHandler::new();
398
399 handler.handle_key_down(0x2A, false, false).unwrap();
401 assert!(handler.modifiers().shift);
402
403 handler.handle_key_down(0x36, false, false).unwrap();
405 assert!(handler.modifiers().shift);
406
407 handler.handle_key_up(0x2A, false, false).unwrap();
409 assert!(handler.modifiers().shift); handler.handle_key_up(0x36, false, false).unwrap();
413 assert!(!handler.modifiers().shift);
414 }
415
416 #[test]
417 fn test_extended_key() {
418 let mut handler = KeyboardHandler::new();
419
420 let event = handler.handle_key_down(0x1D, true, false).unwrap();
422
423 match event {
424 KeyboardEvent::KeyDown { keycode, .. } => {
425 assert!(keycode > 0);
426 }
427 _ => panic!("Expected KeyDown event"),
428 }
429
430 assert!(handler.modifiers().ctrl);
431 }
432
433 #[test]
434 fn test_layout_change() {
435 let mut handler = KeyboardHandler::new();
436
437 assert_eq!(handler.layout(), "us");
438
439 handler.set_layout("de");
440 assert_eq!(handler.layout(), "de");
441 }
442
443 #[test]
444 fn test_reset() {
445 let mut handler = KeyboardHandler::new();
446
447 handler.handle_key_down(0x1E, false, false).unwrap(); handler.handle_key_down(0x2A, false, false).unwrap(); handler.handle_key_down(0x1D, false, false).unwrap(); assert!(handler.pressed_key_count() > 0);
453 assert!(handler.modifiers().shift);
454
455 handler.reset();
457
458 assert_eq!(handler.pressed_key_count(), 0);
459 assert!(!handler.modifiers().shift);
460 assert!(!handler.modifiers().ctrl);
461 }
462
463 #[test]
464 fn test_get_pressed_keys() {
465 let mut handler = KeyboardHandler::new();
466
467 handler.handle_key_down(0x1E, false, false).unwrap(); handler.handle_key_down(0x1F, false, false).unwrap(); let pressed = handler.get_pressed_keys();
471 assert_eq!(pressed.len(), 2);
472 }
473
474 #[test]
475 fn test_repeat_rate() {
476 let mut handler = KeyboardHandler::new();
477
478 handler.set_repeat_delay(100);
479 handler.set_repeat_rate(50);
480
481 assert_eq!(handler.repeat_delay_ms, 100);
482 assert_eq!(handler.repeat_rate_ms, 50);
483 }
484
485 #[test]
486 fn test_unknown_scancode() {
487 let mut handler = KeyboardHandler::new();
488
489 let result = handler.handle_key_down(0xFF, false, false);
491 assert!(result.is_err());
492 }
493
494 #[test]
495 fn test_function_keys() {
496 let mut handler = KeyboardHandler::new();
497
498 let event = handler.handle_key_down(0x3B, false, false).unwrap();
500 match event {
501 KeyboardEvent::KeyDown { keycode, .. } => {
502 assert!(keycode > 0);
503 }
504 _ => panic!("Expected KeyDown event"),
505 }
506
507 let event = handler.handle_key_down(0x58, false, false).unwrap();
509 match event {
510 KeyboardEvent::KeyDown { keycode, .. } => {
511 assert!(keycode > 0);
512 }
513 _ => panic!("Expected KeyDown event"),
514 }
515 }
516}