1use anyhow::{format_err, Result};
6use fidl_fuchsia_input::{Key, KeymapId};
7use fidl_fuchsia_ui_input3::{KeyEventType, KeyMeaning, LockState, Modifiers, NonPrintableKey};
8use lazy_static::lazy_static;
9use log::{debug, error};
10use std::collections::{self, HashMap};
11
12mod defs;
13
14pub mod config;
15pub mod inverse_keymap;
16pub mod usages;
17
18lazy_static! {
19 pub static ref US_QWERTY: Keymap<'static> = Keymap::new(&defs::QWERTY_MAP);
21
22 pub static ref US_DVORAK: Keymap<'static> = Keymap::new(&defs::DVORAK_MAP);
24
25 pub static ref FR_AZERTY: Keymap<'static> = Keymap::new(&defs::FR_AZERTY_MAP);
27
28 pub static ref US_COLEMAK: Keymap<'static> = Keymap::new(&defs::COLEMAK_MAP);
30}
31
32pub fn select_keymap<'a>(keymap: &Option<String>) -> &'a Keymap<'a> {
35 match keymap {
36 Some(ref k) if k == "FR_AZERTY" => &FR_AZERTY,
37 Some(ref k) if k == "US_DVORAK" => &US_DVORAK,
38 Some(ref k) if k == "US_COLEMAK" => &US_COLEMAK,
39 _ => &US_QWERTY,
40 }
41}
42
43pub fn into_keymap_id(keymap: &str) -> KeymapId {
47 match keymap {
48 "FR_AZERTY" => KeymapId::FrAzerty,
49 "US_DVORAK" => KeymapId::UsDvorak,
50 "US_COLEMAK" => KeymapId::UsColemak,
51 _ => KeymapId::UsQwerty,
52 }
53}
54
55pub fn get_key_meaning(
67 key: &Option<Key>,
68 key_meaning: &Option<KeyMeaning>,
69 lock_state: &Option<LockState>,
70 modifiers: &Option<Modifiers>,
71) -> KeyMeaning {
72 key_meaning.unwrap_or_else(|| {
73 let lock_state =
78 LockStateKeys::new().with(lock_state.unwrap_or(LockState::from_bits_allow_unknown(0)));
79 let modifiers =
80 ModifierState::new().with(modifiers.unwrap_or(Modifiers::from_bits_allow_unknown(0)));
81 let key = key.unwrap_or(Key::Unknown);
82 US_QWERTY
83 .apply(key, &modifiers, &lock_state)
84 .unwrap_or(KeyMeaning::NonPrintableKey(NonPrintableKey::Unidentified))
85 })
86}
87
88pub(crate) const EMPTY_CODEPOINT: u32 = 0;
91
92pub struct Keymap<'a> {
94 map: &'a [Option<defs::KeyLevels>],
95}
96
97impl AsRef<[Option<defs::KeyLevels>]> for Keymap<'_> {
98 fn as_ref(&self) -> &[Option<defs::KeyLevels>] {
99 self.map
100 }
101}
102
103impl<'a> Keymap<'a> {
104 fn new(map: &'a [Option<defs::KeyLevels>]) -> Self {
106 Keymap { map }
107 }
108
109 fn try_into_nonprintable(&self, key: Key) -> Option<KeyMeaning> {
120 match key {
121 Key::Enter => Some(NonPrintableKey::Enter),
122 Key::Tab => Some(NonPrintableKey::Tab),
123 Key::Backspace => Some(NonPrintableKey::Backspace),
124 Key::Escape => Some(NonPrintableKey::Escape),
125 Key::Up => Some(NonPrintableKey::Up),
126 Key::Down => Some(NonPrintableKey::Down),
127 Key::Left => Some(NonPrintableKey::Left),
128 Key::Right => Some(NonPrintableKey::Right),
129 Key::End => Some(NonPrintableKey::End),
130 Key::Home => Some(NonPrintableKey::Home),
131 Key::PageUp => Some(NonPrintableKey::PageUp),
132 Key::PageDown => Some(NonPrintableKey::PageDown),
133 Key::RightAlt => Some(if std::ptr::eq(self, &*FR_AZERTY) {
134 NonPrintableKey::AltGraph
137 } else {
138 NonPrintableKey::Alt
139 }),
140 Key::LeftAlt => Some(NonPrintableKey::Alt),
141 Key::RightCtrl => Some(NonPrintableKey::Control),
142 Key::LeftCtrl => Some(NonPrintableKey::Control),
143 Key::CapsLock => Some(NonPrintableKey::CapsLock),
144 Key::LeftShift => Some(NonPrintableKey::Shift),
145 Key::RightShift => Some(NonPrintableKey::Shift),
146 Key::LeftMeta => Some(NonPrintableKey::Meta),
147 Key::RightMeta => Some(NonPrintableKey::Meta),
148 Key::NumLock => Some(NonPrintableKey::NumLock),
149 Key::ScrollLock => Some(NonPrintableKey::ScrollLock),
150 Key::F1 => Some(NonPrintableKey::F1),
151 Key::F2 => Some(NonPrintableKey::F2),
152 Key::F3 => Some(NonPrintableKey::F3),
153 Key::F4 => Some(NonPrintableKey::F4),
154 Key::F5 => Some(NonPrintableKey::F5),
155 Key::F6 => Some(NonPrintableKey::F6),
156 Key::F7 => Some(NonPrintableKey::F7),
157 Key::F8 => Some(NonPrintableKey::F8),
158 Key::F9 => Some(NonPrintableKey::F9),
159 Key::F10 => Some(NonPrintableKey::F10),
160 Key::F11 => Some(NonPrintableKey::F11),
161 Key::F12 => Some(NonPrintableKey::F12),
162
163 Key::AcBack => Some(NonPrintableKey::BrowserBack),
165 Key::AcRefresh => Some(NonPrintableKey::BrowserRefresh),
166 Key::AcFullScreenView => Some(NonPrintableKey::ZoomToggle),
167 Key::AcSelectTaskApplication => Some(NonPrintableKey::Select),
168 Key::BrightnessDown => Some(NonPrintableKey::BrightnessDown),
169 Key::BrightnessUp => Some(NonPrintableKey::BrightnessUp),
170 Key::PlayPause => Some(NonPrintableKey::MediaPlayPause),
171 Key::Mute => Some(NonPrintableKey::AudioVolumeMute),
172 Key::VolumeDown => Some(NonPrintableKey::AudioVolumeDown),
173 Key::VolumeUp => Some(NonPrintableKey::AudioVolumeUp),
174 _ => None,
175 }
176 .map(|k| KeyMeaning::NonPrintableKey(k))
177 }
178
179 pub fn apply(
181 &self,
182 key: Key,
183 modifier_state: &impl ModifierChecker,
184 lock_state: &impl LockStateChecker,
185 ) -> Option<KeyMeaning> {
186 let hid_usage = usages::input3_key_to_hid_usage(key);
187
188 self.hid_usage_to_code_point(hid_usage, modifier_state, lock_state)
191 .ok()
192 .and_then(|v| if v == EMPTY_CODEPOINT { None } else { Some(v) })
193 .map(KeyMeaning::Codepoint)
194 .or_else(|| self.try_into_nonprintable(key))
195 .or_else(|| {
196 debug!(
197 key:?,
198 hid_usage:?,
199 modifiers:? = modifier_state,
200 lock_state:?;
201 "keymaps::Keymap::apply: no KeyMeaning"
202 );
203 None
204 })
205 }
206
207 pub fn hid_usage_to_code_point(
211 &self,
212 hid_usage: u32,
213 modifier_state: &impl ModifierChecker,
214 lock_state: &impl LockStateChecker,
215 ) -> Result<u32> {
216 if (hid_usage as usize) < self.map.len() {
217 if let Some(ref map_entry) = self.map[hid_usage as usize] {
218 map_entry
219 .get_key(modifier_state, lock_state)
220 .map(|c| c as u32)
221 .ok_or_else(|| format_err!("Invalid USB HID code: {:?}", hid_usage))
222 } else {
223 Ok(EMPTY_CODEPOINT) }
225 } else {
226 Ok(EMPTY_CODEPOINT) }
228 }
229
230 pub fn hid_usage_to_code_point_for_mods(
231 &self,
232 hid_usage: u32,
233 shift: bool,
234 caps_lock: bool,
235 ) -> Option<u32> {
236 let modifier_state = ModifierState::new()
237 .with_if(Modifiers::LEFT_SHIFT, shift)
238 .with_if(Modifiers::RIGHT_SHIFT, shift);
239 let lock_state = LockStateKeys::new().with_if(LockState::CAPS_LOCK, caps_lock);
240 let code_point = self.hid_usage_to_code_point(hid_usage, &modifier_state, &lock_state);
241 match code_point {
242 Ok(EMPTY_CODEPOINT) => None,
243 Ok(c) => Some(c),
244 Err(_) => None,
245 }
246 }
247}
248
249pub trait ModifierChecker: std::fmt::Debug {
251 fn test(&self, value: Modifiers) -> bool;
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
259pub struct ModifierState {
260 state: Modifiers,
262}
263
264impl Default for ModifierState {
265 fn default() -> Self {
266 Self { state: Modifiers::empty() }
267 }
268}
269
270impl ModifierChecker for ModifierState {
271 fn test(&self, value: Modifiers) -> bool {
273 self.state.contains(value)
274 }
275}
276
277impl ModifierState {
278 pub fn new() -> Self {
281 Default::default()
282 }
283
284 pub fn with(self, value: Modifiers) -> Self {
289 let mut state = self.state;
290 state.insert(value);
291
292 match value {
294 Modifiers::LEFT_SHIFT | Modifiers::RIGHT_SHIFT => {
295 state.insert(Modifiers::SHIFT);
296 }
297 Modifiers::LEFT_ALT | Modifiers::RIGHT_ALT => {
298 state.insert(Modifiers::ALT);
299 }
300 Modifiers::LEFT_META | Modifiers::RIGHT_META => {
301 state.insert(Modifiers::META);
302 }
303 Modifiers::LEFT_CTRL | Modifiers::RIGHT_CTRL => {
304 state.insert(Modifiers::CTRL);
305 }
306 _ => {}
307 }
308 Self { state }
309 }
310
311 pub fn get_state(&self) -> Modifiers {
313 self.state.clone()
314 }
315
316 pub fn with_if(self, value: Modifiers, set: bool) -> Self {
321 match set {
322 false => self,
323 true => self.with(value),
324 }
325 }
326
327 pub fn update(&mut self, event: KeyEventType, key: Key) {
329 match event {
330 KeyEventType::Pressed | KeyEventType::Sync => match key {
333 Key::CapsLock => self.state.insert(Modifiers::CAPS_LOCK),
334 Key::NumLock => self.state.insert(Modifiers::NUM_LOCK),
335 Key::ScrollLock => self.state.insert(Modifiers::SCROLL_LOCK),
336 Key::LeftShift => {
343 self.state.insert(Modifiers::LEFT_SHIFT | Modifiers::SHIFT);
344 }
345 Key::RightShift => {
346 self.state.insert(Modifiers::RIGHT_SHIFT | Modifiers::SHIFT);
347 }
348 Key::LeftAlt => {
349 self.state.insert(Modifiers::LEFT_ALT | Modifiers::ALT);
350 }
351 Key::RightAlt => {
352 self.state.insert(Modifiers::RIGHT_ALT | Modifiers::ALT);
353 }
354 Key::LeftMeta => {
355 self.state.insert(Modifiers::LEFT_META | Modifiers::META);
356 }
357 Key::RightMeta => {
358 self.state.insert(Modifiers::RIGHT_META | Modifiers::META);
359 }
360 Key::LeftCtrl => {
361 self.state.insert(Modifiers::LEFT_CTRL | Modifiers::CTRL);
362 }
363 Key::RightCtrl => {
364 self.state.insert(Modifiers::RIGHT_CTRL | Modifiers::CTRL);
365 }
366 _ => {}
367 },
368 KeyEventType::Released | KeyEventType::Cancel => match key {
371 Key::CapsLock => {
372 self.state.remove(Modifiers::CAPS_LOCK);
373 }
374 Key::NumLock => self.state.remove(Modifiers::NUM_LOCK),
375 Key::ScrollLock => self.state.remove(Modifiers::SCROLL_LOCK),
376
377 Key::LeftShift => {
378 self.state.remove(Modifiers::LEFT_SHIFT);
379 if !self.state.contains(Modifiers::RIGHT_SHIFT) {
380 self.state.remove(Modifiers::SHIFT);
381 }
382 }
383 Key::RightShift => {
384 self.state.remove(Modifiers::RIGHT_SHIFT);
385 if !self.test(Modifiers::LEFT_SHIFT) {
386 self.state.remove(Modifiers::SHIFT);
387 }
388 }
389 Key::LeftAlt => {
390 self.state.remove(Modifiers::LEFT_ALT);
391 if !self.state.contains(Modifiers::RIGHT_ALT) {
392 self.state.remove(Modifiers::ALT);
393 }
394 }
395 Key::RightAlt => {
396 self.state.remove(Modifiers::RIGHT_ALT);
397 if !self.test(Modifiers::LEFT_ALT) {
398 self.state.remove(Modifiers::ALT);
399 }
400 }
401 Key::LeftMeta => {
402 self.state.remove(Modifiers::LEFT_META);
403 if !self.state.contains(Modifiers::RIGHT_META) {
404 self.state.remove(Modifiers::META);
405 }
406 }
407 Key::RightMeta => {
408 self.state.remove(Modifiers::RIGHT_META);
409 if !self.test(Modifiers::LEFT_META) {
410 self.state.remove(Modifiers::META);
411 }
412 }
413 Key::LeftCtrl => {
414 self.state.remove(Modifiers::LEFT_CTRL);
415 if !self.state.contains(Modifiers::RIGHT_CTRL) {
416 self.state.remove(Modifiers::CTRL);
417 }
418 }
419 Key::RightCtrl => {
420 self.state.remove(Modifiers::RIGHT_CTRL);
421 if !self.test(Modifiers::LEFT_CTRL) {
422 self.state.remove(Modifiers::CTRL);
423 }
424 }
425 _ => {}
426 },
427 }
428 }
429
430 pub fn update_with_key_meaning(&mut self, event: KeyEventType, key_meaning: KeyMeaning) {
432 match event {
433 KeyEventType::Pressed | KeyEventType::Sync => match key_meaning {
434 KeyMeaning::NonPrintableKey(NonPrintableKey::AltGraph) => {
435 self.state.insert(Modifiers::ALT_GRAPH)
436 }
437 _ => {}
438 },
439 KeyEventType::Released | KeyEventType::Cancel => match key_meaning {
440 KeyMeaning::NonPrintableKey(NonPrintableKey::AltGraph) => {
441 self.state.remove(Modifiers::ALT_GRAPH)
442 }
443 _ => {}
444 },
445 }
446 }
447}
448
449#[derive(Debug, Hash)]
451enum State {
452 LockPressed,
454 LockPressedAndReleased,
456 LockPressedSecondTime,
458}
459
460pub trait LockStateChecker: std::fmt::Debug {
462 fn test(&self, value: LockState) -> bool;
463}
464
465#[derive(Debug)]
480pub struct LockStateKeys {
481 state: HashMap<LockState, State>,
482}
483
484impl Default for LockStateKeys {
485 fn default() -> Self {
486 LockStateKeys { state: HashMap::new() }
487 }
488}
489
490impl LockStateChecker for LockStateKeys {
491 fn test(&self, value: LockState) -> bool {
493 self.state.contains_key(&value)
494 }
495}
496
497impl LockStateKeys {
498 pub fn new() -> Self {
501 Default::default()
502 }
503
504 pub fn with(self, value: LockState) -> Self {
508 let mut state = self.state;
509 state.insert(value, State::LockPressedAndReleased);
510 Self { state }
511 }
512
513 pub fn with_if(self, value: LockState, set: bool) -> Self {
518 match set {
519 false => self,
520 true => self.with(value),
521 }
522 }
523
524 pub fn update(&mut self, event: KeyEventType, key: Key) {
526 let lock_key = match key {
527 Key::CapsLock => LockState::CAPS_LOCK,
528 Key::NumLock => LockState::NUM_LOCK,
529 Key::ScrollLock => LockState::SCROLL_LOCK,
530 _ => LockState::from_bits_allow_unknown(0),
534 };
535 if lock_key == LockState::from_bits_allow_unknown(0) {
536 return;
537 }
538 let lock_state = self.state.get(&lock_key);
539 match (event, lock_state) {
540 (KeyEventType::Pressed, None) => {
541 self.state.insert(lock_key, State::LockPressed);
542 }
543 (KeyEventType::Pressed, Some(State::LockPressedAndReleased)) => {
544 self.state.insert(lock_key, State::LockPressedSecondTime);
545 }
546 (KeyEventType::Released, Some(State::LockPressed)) => {
547 self.state.insert(lock_key, State::LockPressedAndReleased);
548 }
549 (KeyEventType::Released, Some(State::LockPressedSecondTime)) => {
550 self.state.remove(&lock_key);
551 }
552
553 (KeyEventType::Pressed, Some(State::LockPressed))
555 | (KeyEventType::Pressed, Some(State::LockPressedSecondTime))
556 | (KeyEventType::Released, None)
557 | (KeyEventType::Released, Some(State::LockPressedAndReleased)) => {
558 error!(event:?, key:?, state:? = self.state; "unexpected state transition");
559 }
560
561 (_, __) => {}
563 }
564 }
565
566 pub fn get_state(&self) -> LockState {
568 self.state
569 .keys()
570 .map(|k| k.clone())
571 .fold(LockState::from_bits_allow_unknown(0), |acc, k| acc | k)
572 }
573}
574
575#[derive(Debug, Clone, Default)]
585pub struct KeyState {
586 ordinal_to_key: collections::BTreeMap<u64, Key>,
591 key_to_ordinal: collections::HashMap<Key, u64>,
595 next_ordinal: u64,
600}
601
602impl KeyState {
603 pub fn new() -> Self {
605 KeyState {
606 next_ordinal: 0,
607 key_to_ordinal: collections::HashMap::new(),
608 ordinal_to_key: collections::BTreeMap::new(),
609 }
610 }
611
612 pub fn update(&mut self, event: KeyEventType, key: Key) {
614 match event {
615 KeyEventType::Pressed | KeyEventType::Sync => {
616 if let None = self.key_to_ordinal.insert(key, self.next_ordinal) {
617 self.ordinal_to_key.insert(self.next_ordinal, key);
620 self.next_ordinal = self.next_ordinal + 1;
621 }
622 }
623 KeyEventType::Released | KeyEventType::Cancel => {
624 if let Some(ordinal) = self.key_to_ordinal.remove(&key) {
625 self.ordinal_to_key.remove_entry(&ordinal);
626 }
627 if self.key_to_ordinal.is_empty() {
629 assert!(self.ordinal_to_key.is_empty());
630 self.next_ordinal = 0;
631 }
632 }
633 }
634 }
635
636 pub fn is_pressed(&self, key: &Key) -> bool {
638 self.key_to_ordinal.contains_key(key)
639 }
640
641 pub fn pressed_any(&self, keys: &[Key]) -> bool {
643 keys.iter().any(|k| self.is_pressed(k))
644 }
645
646 pub fn pressed_all(&self, keys: &[Key]) -> bool {
648 keys.iter().all(|k| self.is_pressed(k))
649 }
650
651 pub fn get_set(&self) -> collections::BTreeSet<Key> {
653 let mut ret = collections::BTreeSet::new();
654 let _k = self.key_to_ordinal.keys().for_each(|k| {
655 ret.insert(*k);
656 });
657 ret
658 }
659
660 pub fn get_ordered_keys(&self) -> Vec<Key> {
663 self.ordinal_to_key.iter().map(|(_, key)| *key).collect()
665 }
666
667 pub fn clear(&mut self) {
669 self.next_ordinal = 0;
670 self.ordinal_to_key.clear();
671 self.key_to_ordinal.clear();
672 }
673}
674
675#[cfg(test)]
676mod tests {
677 use super::*;
678 use test_case::test_case;
679
680 const HID_USAGE_KEY_A: u32 = 0x04;
681 const HID_USAGE_KEY_B: u32 = 0x05;
682 const HID_USAGE_KEY_C: u32 = 0x06;
683 const HID_USAGE_KEY_K: u32 = 0x0e;
684 const HID_USAGE_KEY_L: u32 = 0x0f;
685 const HID_USAGE_KEY_M: u32 = 0x10;
686 const HID_USAGE_KEY_N: u32 = 0x11;
687 const HID_USAGE_KEY_Q: u32 = 0x14;
688 const HID_USAGE_KEY_U: u32 = 0x18;
689 const HID_USAGE_KEY_1: u32 = 0x1e;
690 const HID_USAGE_KEY_SEMICOLON: u32 = 0x33;
691
692 #[test]
694 fn caps_lock_effect() -> Result<()> {
695 assert_eq!(
696 '1' as u32,
697 US_QWERTY.hid_usage_to_code_point(
698 HID_USAGE_KEY_1,
699 &ModifierState::new(),
700 &LockStateKeys::new().with(LockState::CAPS_LOCK),
701 )?
702 );
703 assert_eq!(
704 '!' as u32,
705 US_QWERTY.hid_usage_to_code_point(
706 HID_USAGE_KEY_1,
707 &ModifierState::new().with(Modifiers::LEFT_SHIFT),
708 &LockStateKeys::new(),
709 )?
710 );
711 Ok(())
712 }
713
714 #[test]
715 fn spotcheck_us_qwerty_keymap() -> Result<()> {
716 assert_eq!(
717 'a' as u32,
718 US_QWERTY.hid_usage_to_code_point(
719 HID_USAGE_KEY_A,
720 &ModifierState::new(),
721 &LockStateKeys::new(),
722 )?
723 );
724 assert_eq!(
725 'a' as u32,
726 US_QWERTY.hid_usage_to_code_point(
727 HID_USAGE_KEY_A,
728 &ModifierState::new().with(Modifiers::CAPS_LOCK),
729 &LockStateKeys::new(),
730 )?
731 );
732 assert_eq!(
733 'A' as u32,
734 US_QWERTY.hid_usage_to_code_point(
735 HID_USAGE_KEY_A,
736 &ModifierState::new(),
737 &LockStateKeys::new().with(LockState::CAPS_LOCK),
738 )?
739 );
740 assert_eq!(
741 'A' as u32,
742 US_QWERTY.hid_usage_to_code_point(
743 HID_USAGE_KEY_A,
744 &ModifierState::new().with(Modifiers::RIGHT_SHIFT),
745 &LockStateKeys::new(),
746 )?
747 );
748 assert_eq!(
749 'A' as u32,
750 US_QWERTY.hid_usage_to_code_point(
751 HID_USAGE_KEY_A,
752 &ModifierState::new().with(Modifiers::LEFT_SHIFT),
753 &LockStateKeys::new(),
754 )?
755 );
756 Ok(())
757 }
758
759 #[test]
760 fn spotcheck_fr_azerty_keymap() -> Result<()> {
761 assert_eq!(
762 'a' as u32,
763 FR_AZERTY.hid_usage_to_code_point(
764 HID_USAGE_KEY_Q,
765 &ModifierState::new(),
766 &LockStateKeys::new(),
767 )?
768 );
769 assert_eq!(
770 'M' as u32,
771 FR_AZERTY.hid_usage_to_code_point(
772 HID_USAGE_KEY_SEMICOLON,
773 &ModifierState::new(),
774 &LockStateKeys::new().with(LockState::CAPS_LOCK),
775 )?
776 );
777 assert_eq!(
778 ',' as u32,
779 FR_AZERTY.hid_usage_to_code_point(
780 HID_USAGE_KEY_M,
781 &ModifierState::new(),
782 &LockStateKeys::new().with(LockState::CAPS_LOCK),
783 )?
784 );
785 Ok(())
786 }
787
788 #[test]
789 fn spotcheck_us_dvorak_keymap() -> Result<()> {
790 assert_eq!(
791 'a' as u32,
792 US_DVORAK.hid_usage_to_code_point(
793 HID_USAGE_KEY_A,
794 &ModifierState::default(),
795 &LockStateKeys::new(),
796 )?
797 );
798 assert_eq!(
799 'a' as u32,
800 US_DVORAK.hid_usage_to_code_point(
801 HID_USAGE_KEY_A,
802 &ModifierState::new().with(Modifiers::CAPS_LOCK),
803 &LockStateKeys::new(),
804 )?
805 );
806 assert_eq!(
807 'A' as u32,
808 US_DVORAK.hid_usage_to_code_point(
809 HID_USAGE_KEY_A,
810 &ModifierState::new(),
811 &LockStateKeys::new().with(LockState::CAPS_LOCK),
812 )?
813 );
814 assert_eq!(
815 'x' as u32,
816 US_DVORAK.hid_usage_to_code_point(
817 HID_USAGE_KEY_B,
818 &ModifierState::new(),
819 &LockStateKeys::new(),
820 )?
821 );
822 assert_eq!(
823 'X' as u32,
824 US_DVORAK.hid_usage_to_code_point(
825 HID_USAGE_KEY_B,
826 &ModifierState::new(),
827 &LockStateKeys::new().with(LockState::CAPS_LOCK),
828 )?
829 );
830 assert_eq!(
831 'X' as u32,
832 US_DVORAK.hid_usage_to_code_point(
833 HID_USAGE_KEY_B,
834 &ModifierState::new().with(Modifiers::LEFT_SHIFT),
835 &LockStateKeys::new(),
836 )?
837 );
838 assert_eq!(
839 'n' as u32,
840 US_DVORAK.hid_usage_to_code_point(
841 HID_USAGE_KEY_L,
842 &ModifierState::new(),
843 &LockStateKeys::new(),
844 )?
845 );
846 assert_eq!(
847 'N' as u32,
848 US_DVORAK.hid_usage_to_code_point(
849 HID_USAGE_KEY_L,
850 &ModifierState::new().with(Modifiers::LEFT_SHIFT),
851 &LockStateKeys::new(),
852 )?
853 );
854 assert_eq!(
855 'N' as u32,
856 US_DVORAK.hid_usage_to_code_point(
857 HID_USAGE_KEY_L,
858 &ModifierState::new(),
859 &LockStateKeys::new().with(LockState::CAPS_LOCK),
860 )?
861 );
862 assert_eq!(
863 '\'' as u32,
864 US_DVORAK.hid_usage_to_code_point(
865 HID_USAGE_KEY_Q,
866 &ModifierState::new(),
867 &LockStateKeys::new().with(LockState::CAPS_LOCK),
868 )?
869 );
870 Ok(())
871 }
872
873 #[test]
874 fn spotcheck_us_colemak_keymap() -> Result<()> {
875 assert_eq!(
876 'c' as u32,
877 US_COLEMAK.hid_usage_to_code_point(
878 HID_USAGE_KEY_C,
879 &ModifierState::new().with(Modifiers::CAPS_LOCK),
880 &LockStateKeys::new(),
881 )?
882 );
883 assert_eq!(
884 'O' as u32,
885 US_COLEMAK.hid_usage_to_code_point(
886 HID_USAGE_KEY_SEMICOLON,
887 &ModifierState::new(),
888 &LockStateKeys::new().with(LockState::CAPS_LOCK),
889 )?
890 );
891 assert_eq!(
892 'L' as u32,
893 US_COLEMAK.hid_usage_to_code_point(
894 HID_USAGE_KEY_U,
895 &ModifierState::new(),
896 &LockStateKeys::new().with(LockState::CAPS_LOCK),
897 )?
898 );
899 assert_eq!(
900 'e' as u32,
901 US_COLEMAK.hid_usage_to_code_point(
902 HID_USAGE_KEY_K,
903 &ModifierState::new(),
904 &LockStateKeys::new(),
905 )?
906 );
907 assert_eq!(
908 'M' as u32,
909 US_COLEMAK.hid_usage_to_code_point(
910 HID_USAGE_KEY_M,
911 &ModifierState::new(),
912 &LockStateKeys::new().with(LockState::CAPS_LOCK),
913 )?
914 );
915 assert_eq!(
916 'A' as u32,
917 US_COLEMAK.hid_usage_to_code_point(
918 HID_USAGE_KEY_A,
919 &ModifierState::new().with(Modifiers::LEFT_SHIFT),
920 &LockStateKeys::new(),
921 )?
922 );
923 assert_eq!(
924 'k' as u32,
925 US_COLEMAK.hid_usage_to_code_point(
926 HID_USAGE_KEY_N,
927 &ModifierState::new(),
928 &LockStateKeys::new(),
929 )?
930 );
931 Ok(())
932 }
933
934 #[test_case(Key::CapsLock, Modifiers::CAPS_LOCK; "CapsLock")]
937 #[test_case(Key::NumLock, Modifiers::NUM_LOCK; "NumLock")]
938 #[test_case(Key::ScrollLock, Modifiers::SCROLL_LOCK; "ScrollLock")]
939 #[test_case(Key::RightShift, Modifiers::RIGHT_SHIFT|Modifiers::SHIFT; "RightShift")]
944 #[test_case(Key::LeftShift, Modifiers::LEFT_SHIFT|Modifiers::SHIFT; "LeftShift")]
945 #[test_case(Key::RightAlt, Modifiers::RIGHT_ALT|Modifiers::ALT; "RightAlt")]
946 #[test_case(Key::LeftAlt, Modifiers::LEFT_ALT|Modifiers::ALT; "LeftAlt")]
947 #[test_case(Key::RightMeta, Modifiers::RIGHT_META|Modifiers::META; "RightMeta")]
948 #[test_case(Key::LeftMeta, Modifiers::LEFT_META|Modifiers::META; "LeftMeta")]
949 #[test_case(Key::RightCtrl, Modifiers::RIGHT_CTRL|Modifiers::CTRL; "RightCtrl")]
950 #[test_case(Key::LeftCtrl, Modifiers::LEFT_CTRL|Modifiers::CTRL; "LeftCtrl")]
951 fn test_caps_lock_modifier(key: Key, modifier: Modifiers) {
952 let mut modifier_state: ModifierState = Default::default();
953 assert!(!modifier_state.test(modifier));
954
955 modifier_state.update(KeyEventType::Pressed, key);
956 assert!(modifier_state.test(modifier));
957
958 modifier_state.update(KeyEventType::Released, key);
959 assert!(!modifier_state.test(modifier));
960
961 modifier_state.update(KeyEventType::Pressed, key);
962 assert!(modifier_state.test(modifier));
963
964 modifier_state.update(KeyEventType::Released, key);
965 assert!(!modifier_state.test(modifier));
966 }
967
968 #[test_case(Key::LeftShift, Key::RightShift, Modifiers::SHIFT; "Shift/LR")]
980 #[test_case(Key::RightShift, Key::LeftShift, Modifiers::SHIFT; "Shift/RL")]
981 #[test_case(Key::LeftAlt, Key::RightAlt, Modifiers::ALT; "Alt/LR")]
982 #[test_case(Key::RightAlt, Key::LeftAlt, Modifiers::ALT; "Alt/RL")]
983 #[test_case(Key::LeftMeta, Key::RightMeta, Modifiers::META; "Meta/LR")]
984 #[test_case(Key::RightMeta, Key::LeftMeta, Modifiers::META; "Meta/RL")]
985 #[test_case(Key::RightCtrl, Key::LeftCtrl, Modifiers::CTRL; "Ctrl/RL")]
986 #[test_case(Key::LeftCtrl, Key::RightCtrl, Modifiers::CTRL; "Ctrl/LR")]
987 fn test_sided_keys(key_a: Key, key_b: Key, modifier: Modifiers) {
988 let mut modifier_state = ModifierState::new();
989 assert!(
990 !modifier_state.test(modifier),
991 "state: {:?}, key_a: {:?}, key_b: {:?}",
992 &modifier_state,
993 &key_a,
994 &key_b
995 );
996
997 modifier_state.update(KeyEventType::Pressed, key_a);
998 assert!(
999 modifier_state.test(modifier),
1000 "state: {:?}, key_a: {:?}, key_b: {:?}",
1001 &modifier_state,
1002 &key_a,
1003 &key_b
1004 );
1005
1006 modifier_state.update(KeyEventType::Pressed, key_b);
1007 assert!(
1008 modifier_state.test(modifier),
1009 "state: {:?}, key_a: {:?}, key_b: {:?}",
1010 &modifier_state,
1011 &key_a,
1012 &key_b
1013 );
1014
1015 modifier_state.update(KeyEventType::Released, key_a);
1016 assert!(
1017 modifier_state.test(modifier),
1018 "state: {:?}, key_a: {:?}, key_b: {:?}",
1019 &modifier_state,
1020 &key_a,
1021 &key_b
1022 );
1023
1024 modifier_state.update(KeyEventType::Released, key_b);
1025 assert!(
1026 !modifier_state.test(modifier),
1027 "state: {:?}, key_a: {:?}, key_b: {:?}",
1028 &modifier_state,
1029 &key_a,
1030 &key_b
1031 );
1032 }
1033
1034 #[test_case(Key::CapsLock, LockState::CAPS_LOCK; "CapsLock")]
1039 #[test_case(Key::NumLock, LockState::NUM_LOCK; "NumLock")]
1040 #[test_case(Key::ScrollLock, LockState::SCROLL_LOCK; "ScrollLock")]
1041 fn test_lock_state(key: Key, lock_state: LockState) {
1042 let mut state: LockStateKeys = Default::default();
1043 assert!(!state.test(lock_state));
1044 assert_eq!(state.get_state(), LockState::from_bits_allow_unknown(0));
1045
1046 state.update(KeyEventType::Pressed, key);
1047 assert!(state.test(lock_state), "{:?}", state.get_state());
1048 assert_eq!(state.get_state(), lock_state);
1049
1050 state.update(KeyEventType::Released, key);
1051 assert!(state.test(lock_state), "{:?}", state.get_state());
1052 assert_eq!(state.get_state(), lock_state);
1053
1054 state.update(KeyEventType::Pressed, key);
1055 assert!(state.test(lock_state), "{:?}", state.get_state());
1056 assert_eq!(state.get_state(), lock_state);
1057
1058 state.update(KeyEventType::Released, key);
1059 assert!(!state.test(lock_state), "{:?}", state.get_state());
1060 assert_eq!(state.get_state(), LockState::from_bits_allow_unknown(0));
1061 }
1062
1063 #[test]
1064 fn test_modifier_tracker() {
1065 let mut modifier_state: ModifierState = Default::default();
1066 assert!(!modifier_state.test(Modifiers::SHIFT));
1067
1068 modifier_state.update(KeyEventType::Pressed, Key::LeftShift);
1069 assert!(modifier_state.test(Modifiers::SHIFT));
1070 modifier_state.update(KeyEventType::Released, Key::LeftShift);
1071 assert!(!modifier_state.test(Modifiers::SHIFT));
1072
1073 modifier_state.update(KeyEventType::Pressed, Key::RightShift);
1074 assert!(modifier_state.test(Modifiers::SHIFT));
1075 modifier_state.update(KeyEventType::Released, Key::RightShift);
1076 assert!(!modifier_state.test(Modifiers::SHIFT));
1077
1078 modifier_state.update(KeyEventType::Pressed, Key::CapsLock);
1079 assert!(!modifier_state.test(Modifiers::SHIFT));
1080 assert!(modifier_state.test(Modifiers::CAPS_LOCK));
1081 modifier_state.update(KeyEventType::Released, Key::CapsLock);
1082 assert!(!modifier_state.test(Modifiers::SHIFT));
1083 assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1084 modifier_state.update(KeyEventType::Pressed, Key::CapsLock);
1085 assert!(!modifier_state.test(Modifiers::SHIFT));
1086 assert!(modifier_state.test(Modifiers::CAPS_LOCK));
1087 modifier_state.update(KeyEventType::Released, Key::CapsLock);
1088 assert!(!modifier_state.test(Modifiers::SHIFT));
1089 assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1090 }
1091
1092 #[test]
1093 fn test_key_meaning_modifier_tracker() {
1094 let mut modifier_state: ModifierState = Default::default();
1095 assert!(!modifier_state.test(Modifiers::ALT_GRAPH));
1096
1097 modifier_state.update_with_key_meaning(
1098 KeyEventType::Pressed,
1099 KeyMeaning::NonPrintableKey(NonPrintableKey::AltGraph),
1100 );
1101 assert!(modifier_state.test(Modifiers::ALT_GRAPH));
1102 modifier_state.update_with_key_meaning(
1103 KeyEventType::Released,
1104 KeyMeaning::NonPrintableKey(NonPrintableKey::AltGraph),
1105 );
1106 assert!(!modifier_state.test(Modifiers::ALT_GRAPH));
1107 }
1108
1109 #[test]
1114 fn test_interleaved_caps_lock_and_shift() {
1115 let mut modifier_state: ModifierState = Default::default();
1116 assert!(!modifier_state.test(Modifiers::SHIFT));
1117
1118 modifier_state.update(KeyEventType::Pressed, Key::CapsLock);
1119 assert!(!modifier_state.test(Modifiers::SHIFT));
1120 assert!(modifier_state.test(Modifiers::CAPS_LOCK));
1121
1122 modifier_state.update(KeyEventType::Pressed, Key::LeftShift);
1123 assert!(modifier_state.test(Modifiers::SHIFT));
1124 assert!(modifier_state.test(Modifiers::CAPS_LOCK));
1125
1126 modifier_state.update(KeyEventType::Released, Key::CapsLock);
1127 assert!(modifier_state.test(Modifiers::SHIFT));
1128 assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1129
1130 modifier_state.update(KeyEventType::Released, Key::LeftShift);
1131 assert!(!modifier_state.test(Modifiers::SHIFT));
1133 assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1134
1135 modifier_state.update(KeyEventType::Pressed, Key::CapsLock);
1137 assert!(!modifier_state.test(Modifiers::SHIFT));
1138 assert!(modifier_state.test(Modifiers::CAPS_LOCK));
1139
1140 modifier_state.update(KeyEventType::Released, Key::CapsLock);
1141 assert!(!modifier_state.test(Modifiers::SHIFT));
1142 assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1143 }
1144
1145 #[test]
1146 fn key_state_tracker() {
1147 let mut t = KeyState::new();
1148 assert_eq!(false, t.is_pressed(&Key::Space));
1149 t.update(KeyEventType::Pressed, Key::Space);
1150 assert_eq!(true, t.is_pressed(&Key::Space));
1151
1152 t.update(KeyEventType::Released, Key::Space);
1153
1154 assert_eq!(false, t.is_pressed(&Key::Space));
1155
1156 t.update(KeyEventType::Sync, Key::Space);
1157 assert_eq!(true, t.is_pressed(&Key::Space));
1158
1159 t.update(KeyEventType::Cancel, Key::Space);
1160 assert_eq!(false, t.is_pressed(&Key::Space));
1161 }
1162
1163 #[test]
1164 fn key_state_tracker_any_and_all() {
1165 let mut t = KeyState::new();
1166
1167 assert_eq!(false, t.pressed_any(&vec![]));
1168 assert_eq!(true, t.pressed_all(&vec![]));
1169
1170 t.update(KeyEventType::Pressed, Key::Space);
1171 t.update(KeyEventType::Pressed, Key::Tab);
1172
1173 assert_eq!(true, t.pressed_any(&vec![Key::LeftShift, Key::Space,]));
1174 assert_eq!(false, t.pressed_any(&vec![Key::RightShift, Key::LeftShift]));
1175 assert_eq!(true, t.pressed_all(&vec![Key::Space,]));
1176 assert_eq!(true, t.pressed_all(&vec![Key::Space, Key::Tab,]));
1177
1178 let keys = t.get_set();
1179 assert_eq!(true, t.pressed_all(&vec![Key::Space, Key::Tab,]));
1180
1181 let mut expected = collections::BTreeSet::new();
1182 expected.insert(Key::Space);
1183 expected.insert(Key::Tab);
1184 assert_eq!(keys, expected, "want: {:?} was: {:?}", &expected, &keys);
1185 }
1186
1187 #[test_case(
1188 &US_QWERTY,
1189 Key::A,
1190 ModifierState::new(),
1191 LockStateKeys::new(),
1192 Some(KeyMeaning::Codepoint(97));
1193 "test basic mapping")
1194 ]
1195 #[test_case(
1196 &US_QWERTY,
1197 Key::A,
1198 ModifierState::new().with(Modifiers::LEFT_SHIFT),
1199 LockStateKeys::new(),
1200 Some(KeyMeaning::Codepoint(65));
1201 "test basic mapping - capital letter")
1202 ]
1203 #[test_case(
1204 &FR_AZERTY,
1207 Key::RightAlt,
1208 ModifierState::new(),
1209 LockStateKeys::new(),
1210 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::AltGraph));
1211 "test FR AZERTY right Alt mapping to AltGr")
1212 ]
1213 #[test_case(
1214 &US_QWERTY,
1215 Key::RightAlt,
1216 ModifierState::new(),
1217 LockStateKeys::new(),
1218 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Alt));
1219 "test US QWERTY right Alt mapping")
1220 ]
1221 #[test_case(
1222 &US_QWERTY,
1223 Key::AcFullScreenView,
1224 ModifierState::new(),
1225 LockStateKeys::new(),
1226 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::ZoomToggle));
1227 "Spot check multimedia keys")
1228 ]
1229 #[test_case(
1230 &US_QWERTY,
1231 Key::Tab,
1232 ModifierState::new(),
1233 LockStateKeys::new(),
1234 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Tab));
1235 "Tab")
1236 ]
1237 #[test_case(
1238 &US_QWERTY,
1239 Key::Enter,
1240 ModifierState::new(),
1241 LockStateKeys::new(),
1242 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Enter));
1243 "Enter")
1244 ]
1245 #[test_case(
1246 &US_QWERTY,
1247 Key::Backspace,
1248 ModifierState::new(),
1249 LockStateKeys::new(),
1250 Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Backspace));
1251 "Backspace")
1252 ]
1253 fn test_keymap_apply(
1254 keymap: &Keymap<'_>,
1255 key: Key,
1256 modifier_state: ModifierState,
1257 lock_state: LockStateKeys,
1258 expected: Option<KeyMeaning>,
1259 ) {
1260 let actual = keymap.apply(key, &modifier_state, &lock_state);
1261 assert_eq!(expected, actual, "expected: {:?}, actual: {:?}", expected, actual);
1262 }
1263
1264 #[test_case(
1265 Key::AcBack,
1266 KeyMeaning::NonPrintableKey(NonPrintableKey::BrowserBack);
1267 "BrowserBack"
1268 )
1269 ]
1270 #[test_case(
1271 Key::AcRefresh,
1272 KeyMeaning::NonPrintableKey(NonPrintableKey::BrowserRefresh);
1273 "BrowserRefresh"
1274 )
1275 ]
1276 #[test_case(
1277 Key::AcFullScreenView,
1278 KeyMeaning::NonPrintableKey(NonPrintableKey::ZoomToggle);
1279 "ZoomToggle"
1280 )
1281 ]
1282 #[test_case(
1283 Key::AcSelectTaskApplication,
1284 KeyMeaning::NonPrintableKey(NonPrintableKey::Select);
1285 "Select"
1286 )
1287 ]
1288 #[test_case(
1289 Key::BrightnessDown,
1290 KeyMeaning::NonPrintableKey(NonPrintableKey::BrightnessDown);
1291 "BrightnessDown"
1292 )
1293 ]
1294 #[test_case(
1295 Key::BrightnessUp,
1296 KeyMeaning::NonPrintableKey(NonPrintableKey::BrightnessUp);
1297 "BrightnessUp"
1298 )
1299 ]
1300 #[test_case(
1301 Key::PlayPause,
1302 KeyMeaning::NonPrintableKey(NonPrintableKey::MediaPlayPause);
1303 "MediaPlayPause"
1304 )
1305 ]
1306 #[test_case(
1307 Key::Mute,
1308 KeyMeaning::NonPrintableKey(NonPrintableKey::AudioVolumeMute);
1309 "AudioVolumeMute"
1310 )
1311 ]
1312 #[test_case(
1313 Key::VolumeUp,
1314 KeyMeaning::NonPrintableKey(NonPrintableKey::AudioVolumeUp);
1315 "AudioVolumeUp"
1316 )
1317 ]
1318 #[test_case(
1319 Key::VolumeDown,
1320 KeyMeaning::NonPrintableKey(NonPrintableKey::AudioVolumeDown);
1321 "AudioVolumeDown"
1322 )
1323 ]
1324 #[test_case(
1325 Key::Escape,
1326 KeyMeaning::NonPrintableKey(NonPrintableKey::Escape);
1327 "Escape"
1328 )
1329 ]
1330 #[test_case(
1331 Key::Enter,
1332 KeyMeaning::NonPrintableKey(NonPrintableKey::Enter);
1333 "Enter"
1334 )
1335 ]
1336 #[test_case(
1337 Key::Tab,
1338 KeyMeaning::NonPrintableKey(NonPrintableKey::Tab);
1339 "Tab"
1340 )
1341 ]
1342 #[test_case(
1343 Key::Backspace,
1344 KeyMeaning::NonPrintableKey(NonPrintableKey::Backspace);
1345 "Backspace"
1346 )
1347 ]
1348 fn spot_check_key_meanings(key: Key, expected: KeyMeaning) {
1349 let actual = US_QWERTY.apply(key, &ModifierState::new(), &LockStateKeys::new());
1350 assert_eq!(Some(expected), actual);
1351 }
1352
1353 #[test]
1365 fn key_ordering() {
1366 let mut t = KeyState::new();
1367
1368 t.update(KeyEventType::Pressed, Key::C);
1369 t.update(KeyEventType::Pressed, Key::A);
1370 t.update(KeyEventType::Pressed, Key::B);
1371 t.update(KeyEventType::Pressed, Key::D);
1372 t.update(KeyEventType::Pressed, Key::A);
1374
1375 t.update(KeyEventType::Released, Key::B);
1376
1377 assert_eq!(vec![Key::C, Key::A, Key::D], t.get_ordered_keys());
1378
1379 t.clear();
1380 let expected: Vec<Key> = vec![];
1381 assert_eq!(expected, t.get_ordered_keys());
1382 }
1383
1384 #[test]
1385 fn key_ordering_with_reset() {
1386 let mut t = KeyState::new();
1387
1388 t.update(KeyEventType::Pressed, Key::A);
1389 t.update(KeyEventType::Pressed, Key::B);
1390 t.update(KeyEventType::Released, Key::B);
1391 t.update(KeyEventType::Released, Key::A);
1392
1393 let expected: Vec<Key> = vec![];
1394 assert_eq!(expected, t.get_ordered_keys());
1395
1396 t.update(KeyEventType::Pressed, Key::C);
1397
1398 assert_eq!(vec![Key::C], t.get_ordered_keys());
1399
1400 t.update(KeyEventType::Pressed, Key::A);
1401
1402 assert_eq!(vec![Key::C, Key::A], t.get_ordered_keys());
1403 }
1404
1405 #[test]
1406 fn key_ordering_misuse() {
1407 let mut t = KeyState::new();
1408
1409 t.update(KeyEventType::Released, Key::B);
1410 t.update(KeyEventType::Pressed, Key::A);
1411 t.update(KeyEventType::Released, Key::A);
1412
1413 let expected: Vec<Key> = vec![];
1414 assert_eq!(expected, t.get_ordered_keys());
1415
1416 t.update(KeyEventType::Pressed, Key::C);
1417
1418 assert_eq!(vec![Key::C], t.get_ordered_keys());
1419
1420 t.update(KeyEventType::Pressed, Key::A);
1421
1422 assert_eq!(vec![Key::C, Key::A], t.get_ordered_keys());
1423
1424 t.update(KeyEventType::Pressed, Key::A);
1425 t.update(KeyEventType::Pressed, Key::B);
1426 t.update(KeyEventType::Pressed, Key::C);
1427
1428 assert_eq!(vec![Key::C, Key::A, Key::B], t.get_ordered_keys());
1429 }
1430}