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 if pressed => {
224 self.modifiers.caps_lock = !self.modifiers.caps_lock;
225 }
226 KEY_NUMLOCK if pressed => {
227 self.modifiers.num_lock = !self.modifiers.num_lock;
228 }
229 KEY_SCROLLLOCK if pressed => {
230 self.modifiers.scroll_lock = !self.modifiers.scroll_lock;
231 }
232 _ => {}
233 }
234 }
235
236 pub fn is_key_pressed(&self, keycode: u32) -> bool {
238 self.pressed_keys.contains(&keycode)
239 }
240
241 pub fn modifiers(&self) -> KeyModifiers {
243 self.modifiers
244 }
245
246 pub fn set_layout(&mut self, layout: &str) {
248 self.mapper.set_layout(layout);
249 debug!("Keyboard layout changed to: {}", layout);
250 }
251
252 pub fn layout(&self) -> &str {
254 self.mapper.layout()
255 }
256
257 pub fn set_repeat_delay(&mut self, delay_ms: u64) {
259 self.repeat_delay_ms = delay_ms;
260 }
261
262 pub fn set_repeat_rate(&mut self, rate_ms: u64) {
264 self.repeat_rate_ms = rate_ms;
265 }
266
267 pub fn reset(&mut self) {
269 self.pressed_keys.clear();
270 self.last_key_times.clear();
271 self.modifiers = KeyModifiers::default();
272 debug!("Keyboard state reset");
273 }
274
275 pub fn pressed_key_count(&self) -> usize {
277 self.pressed_keys.len()
278 }
279
280 pub fn get_pressed_keys(&self) -> Vec<u32> {
282 self.pressed_keys.iter().copied().collect()
283 }
284}
285
286impl Default for KeyboardHandler {
287 fn default() -> Self {
288 Self::new()
289 }
290}
291
292#[cfg(test)]
293mod tests {
294 use super::*;
295
296 #[test]
297 fn test_keyboard_handler_creation() {
298 let handler = KeyboardHandler::new();
299 assert_eq!(handler.pressed_key_count(), 0);
300 assert!(!handler.modifiers().shift);
301 }
302
303 #[test]
304 fn test_key_press_release() {
305 let mut handler = KeyboardHandler::new();
306
307 let event = handler.handle_key_down(0x1E, false, false).unwrap();
309
310 match event {
311 KeyboardEvent::KeyDown { keycode, .. } => {
312 assert!(keycode > 0);
313 assert!(handler.is_key_pressed(keycode));
314 }
315 _ => panic!("Expected KeyDown event"),
316 }
317
318 assert_eq!(handler.pressed_key_count(), 1);
319
320 let event = handler.handle_key_up(0x1E, false, false).unwrap();
322
323 match event {
324 KeyboardEvent::KeyUp { keycode, .. } => {
325 assert!(!handler.is_key_pressed(keycode));
326 }
327 _ => panic!("Expected KeyUp event"),
328 }
329
330 assert_eq!(handler.pressed_key_count(), 0);
331 }
332
333 #[test]
334 fn test_modifier_tracking() {
335 let mut handler = KeyboardHandler::new();
336
337 handler.handle_key_down(0x2A, false, false).unwrap();
339 assert!(handler.modifiers().shift);
340
341 handler.handle_key_down(0x1D, false, false).unwrap();
343 assert!(handler.modifiers().ctrl);
344
345 handler.handle_key_up(0x2A, false, false).unwrap();
347 assert!(!handler.modifiers().shift);
348 assert!(handler.modifiers().ctrl);
349
350 handler.handle_key_up(0x1D, false, false).unwrap();
352 assert!(!handler.modifiers().ctrl);
353 }
354
355 #[test]
356 fn test_caps_lock_toggle() {
357 let mut handler = KeyboardHandler::new();
358
359 assert!(!handler.modifiers().caps_lock);
360
361 handler.handle_key_down(0x3A, false, false).unwrap();
363 assert!(handler.modifiers().caps_lock);
364
365 handler.handle_key_up(0x3A, false, false).unwrap();
367 assert!(handler.modifiers().caps_lock); handler.handle_key_down(0x3A, false, false).unwrap();
371 assert!(!handler.modifiers().caps_lock);
372 }
373
374 #[test]
375 fn test_multiple_modifiers() {
376 let mut handler = KeyboardHandler::new();
377
378 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();
384 assert!(mods.shift);
385 assert!(mods.ctrl);
386 assert!(mods.alt);
387 }
388
389 #[test]
390 fn test_both_shifts() {
391 let mut handler = KeyboardHandler::new();
392
393 handler.handle_key_down(0x2A, false, false).unwrap();
395 assert!(handler.modifiers().shift);
396
397 handler.handle_key_down(0x36, false, false).unwrap();
399 assert!(handler.modifiers().shift);
400
401 handler.handle_key_up(0x2A, false, false).unwrap();
403 assert!(handler.modifiers().shift); handler.handle_key_up(0x36, false, false).unwrap();
407 assert!(!handler.modifiers().shift);
408 }
409
410 #[test]
411 fn test_extended_key() {
412 let mut handler = KeyboardHandler::new();
413
414 let event = handler.handle_key_down(0x1D, true, false).unwrap();
416
417 match event {
418 KeyboardEvent::KeyDown { keycode, .. } => {
419 assert!(keycode > 0);
420 }
421 _ => panic!("Expected KeyDown event"),
422 }
423
424 assert!(handler.modifiers().ctrl);
425 }
426
427 #[test]
428 fn test_layout_change() {
429 let mut handler = KeyboardHandler::new();
430
431 assert_eq!(handler.layout(), "us");
432
433 handler.set_layout("de");
434 assert_eq!(handler.layout(), "de");
435 }
436
437 #[test]
438 fn test_reset() {
439 let mut handler = KeyboardHandler::new();
440
441 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);
447 assert!(handler.modifiers().shift);
448
449 handler.reset();
451
452 assert_eq!(handler.pressed_key_count(), 0);
453 assert!(!handler.modifiers().shift);
454 assert!(!handler.modifiers().ctrl);
455 }
456
457 #[test]
458 fn test_get_pressed_keys() {
459 let mut handler = KeyboardHandler::new();
460
461 handler.handle_key_down(0x1E, false, false).unwrap(); handler.handle_key_down(0x1F, false, false).unwrap(); let pressed = handler.get_pressed_keys();
465 assert_eq!(pressed.len(), 2);
466 }
467
468 #[test]
469 fn test_repeat_rate() {
470 let mut handler = KeyboardHandler::new();
471
472 handler.set_repeat_delay(100);
473 handler.set_repeat_rate(50);
474
475 assert_eq!(handler.repeat_delay_ms, 100);
476 assert_eq!(handler.repeat_rate_ms, 50);
477 }
478
479 #[test]
480 fn test_unknown_scancode() {
481 let mut handler = KeyboardHandler::new();
482
483 let result = handler.handle_key_down(0xFF, false, false);
485 assert!(result.is_err());
486 }
487
488 #[test]
489 fn test_function_keys() {
490 let mut handler = KeyboardHandler::new();
491
492 let event = handler.handle_key_down(0x3B, false, false).unwrap();
494 match event {
495 KeyboardEvent::KeyDown { keycode, .. } => {
496 assert!(keycode > 0);
497 }
498 _ => panic!("Expected KeyDown event"),
499 }
500
501 let event = handler.handle_key_down(0x58, false, false).unwrap();
503 match event {
504 KeyboardEvent::KeyDown { keycode, .. } => {
505 assert!(keycode > 0);
506 }
507 _ => panic!("Expected KeyDown event"),
508 }
509 }
510}