keymaps/
lib.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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    /// A US QWERTY keymap.
20    pub static ref US_QWERTY: Keymap<'static> = Keymap::new(&defs::QWERTY_MAP);
21
22    /// A US DVORAK keymap.
23    pub static ref US_DVORAK: Keymap<'static> = Keymap::new(&defs::DVORAK_MAP);
24
25    /// A FR AZERTY keymap.
26    pub static ref FR_AZERTY: Keymap<'static> = Keymap::new(&defs::FR_AZERTY_MAP);
27
28    /// A US COLEMAK keymap.
29    pub static ref US_COLEMAK: Keymap<'static> = Keymap::new(&defs::COLEMAK_MAP);
30}
31
32/// Gets a keymap based on the supplied `keymap` selector.  If no keymap is
33/// found the fallback is always US QWERTY.
34pub 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
43/// Converts the keymap string into a supported `KeymapId`.
44///
45/// An unknown keymap string always becomes [KeymapId::UsQwerty].
46pub 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
55/// Extracts key meaning in accordance with the Fuchsia key event API specification.
56///
57/// Key meaning is returned verbatim if defined; otherwise, the US QWERTY keymap is
58/// applied to the supplied `key` and the currently active modifiers and lock state.
59///
60/// These usually come from a `fidl.fuchsia.ui.input3/KeyEvent`, so you can simply
61/// pass its components in if you have one. But, a valid `KeyEvent` is not required,
62/// and the caller can fill each of the parameters at will.
63///
64/// If neither the key nor the key meaning are defined, an "unidentified"
65/// nonprintable key meaning is returned.
66pub 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        // Specification note: If key meaning is unset, then the key meaning
74        // must be recovered from the hardware key by applying the US_QWERTY
75        // keymap to the hardware key value, using the currently applicable
76        // modifier and lock state.
77        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
88/// A codepoint returned by [hid_usage_to_code_point] for HID usages that do
89/// not have an associated code point, e.g. Alt.
90pub(crate) const EMPTY_CODEPOINT: u32 = 0;
91
92/// A Us Qwerty keymap
93pub 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    /// Creates a new keymap.
105    fn new(map: &'a [Option<defs::KeyLevels>]) -> Self {
106        Keymap { map }
107    }
108
109    /// Attaches a fixed [KeyMeaning] to the given [Key] if one exists.
110    ///
111    /// These are mostly the default key meanings of keys on a US QWERTY keyboard.
112    /// As such, we must try the key to key meaning mapping coming from the keymap first,
113    /// to allow the keymap the option to move these keys around when this is desired.
114    ///
115    /// We do not really expect these to happen frequently in standardized keymaps,
116    /// but custom keymaps might do this (e.g. mapping Esc to CapsLock), and in
117    /// general we should avoid putting arbitrary constraints on key maps if such
118    /// are not necessary.
119    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                // Used for Chromium testing - not yet handled consistently and
135                // seriously.
136                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            // Multimedia keys, UI keys, browser keys etc.
164            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    /// Applies the keymap to the given key.
180    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        // Try to apply the keymap first. Failing that, try fixed nonprintable
189        // keys.
190        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    /// Converts a HID usage for a key to a Unicode code point where such a code point exists, based on
208    /// a US QWERTY keyboard layout.  Returns EMPTY_CODEPOINT if a code point does not exist (e.g. Alt),
209    /// and an error in case the mapping somehow fails.
210    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) // No code point provided by a keymap, e.g. Enter.
224            }
225        } else {
226            Ok(EMPTY_CODEPOINT) // No code point available, e.g. Shift, Alt, etc.
227        }
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
249/// A trait for something that can be tested for modifier presence.
250pub trait ModifierChecker: std::fmt::Debug {
251    fn test(&self, value: Modifiers) -> bool;
252}
253
254/// Tracks the current state of "significant" modifier keys.
255///
256/// Currently, a modifier key is "significant" if it affects the mapping of a
257/// Fuchsia key to a key meaning.
258#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
259pub struct ModifierState {
260    /// The internal modifier state.
261    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    /// Test if the modifier state contains the modifiers from `value`.
272    fn test(&self, value: Modifiers) -> bool {
273        self.state.contains(value)
274    }
275}
276
277impl ModifierState {
278    /// Creates a new [ModifierState] initializes with the default state (no
279    /// modifiers are actuated).
280    pub fn new() -> Self {
281        Default::default()
282    }
283
284    /// Unconditionally adds the given modifier into the modifier state as
285    /// actuated.
286    ///
287    /// Returns `Self` for chaining.
288    pub fn with(self, value: Modifiers) -> Self {
289        let mut state = self.state;
290        state.insert(value);
291
292        // For "sided" modifiers, maintain the "side-less" bit invariant too.
293        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    /// Retrieves the modifier state.
312    pub fn get_state(&self) -> Modifiers {
313        self.state.clone()
314    }
315
316    /// Adds `modifier` into the modifier state as actuated, if `set` is true.
317    /// Otherwise makes no changes to [ModifierState].
318    ///
319    /// Returns `Self` for chaining.
320    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    /// Update the modifier tracker state with this event.
328    pub fn update(&mut self, event: KeyEventType, key: Key) {
329        match event {
330            // PRESSED event is a regular key press.
331            // SYNC event is an update to key presses after a focus regain.
332            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                // These modifiers are not defined in Key.
337                // Key::Function
338                // Key::Symbol
339
340                // For "sided" modifiers, we must also maintain the "side-less"
341                // bit. Here, and everywhere below.
342                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            // PRESSED event is a regular key release.
369            // CANCEL event is an update to key presses after a focus loss.
370            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    /// Update the modifier tracker with this event.
431    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// The state of each lock key.
450#[derive(Debug, Hash)]
451enum State {
452    // Lock was pressed.  (aka S1, see below)
453    LockPressed,
454    // Lock was pressed and released. (aka S2)
455    LockPressedAndReleased,
456    // Lock was pressed for the second time in a row.  (aka S3)
457    LockPressedSecondTime,
458}
459
460/// A lock state checker.
461pub trait LockStateChecker: std::fmt::Debug {
462    fn test(&self, value: LockState) -> bool;
463}
464
465/// The lock state of the lock keys.
466///
467/// Consult the state diagram below for the intended state transition.  The
468/// state encoding is given in [State].
469///
470/// ```ignore
471/// Key    """""""\_________/"""""""""""\_________/""""
472/// State  -------<    S1  ><     S2   ><    S3   >----
473/// ```
474///
475/// Any other state is not explicitly accounted for: the state of "the lock is
476/// not active" is encoded by not having a record of the key state.  This
477/// allows us to implement the state machine for an arbitrary number of lock
478/// keys.
479#[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    /// Returns true if the lock state value is set.
492    fn test(&self, value: LockState) -> bool {
493        self.state.contains_key(&value)
494    }
495}
496
497impl LockStateKeys {
498    /// Creates a new [LockStateKeys] initializes with the default state (no
499    /// modifiers are actuated).
500    pub fn new() -> Self {
501        Default::default()
502    }
503
504    /// Unconditionally adds the given lock state as actuated.
505    ///
506    /// Returns `Self` for chaining.
507    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    /// Adds `value` into the modifier state as actuated, if `set` is true.
514    /// Otherwise makes no changes to [LockStateKeys].
515    ///
516    /// Returns `Self` for chaining.
517    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    /// Update the modifier tracker state with this event.
525    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            // FUNCTION_LOCK
531            // SYMBOL_LOCK
532            // etc.
533            _ => 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            // These should not happen.
554            (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            // SYNC and CANCEL don't change the lock state.
562            (_, __) => {}
563        }
564    }
565
566    /// Gets the recorded lock state.
567    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/// Tracks the current state of all the keyboard keys.
576///
577/// This is repetitive code, so perhaps better handle it here.  You can feed
578/// the keyboard events into its [KeyState::update] method.
579///
580/// [KeyState] keeps track of the ordering the keys were pressed, and you can
581/// call [KeyState::get_ordered_keys] to get a sequence of currently pressed
582/// keys, in the order they were pressed.  This is useful for emitting keyboard
583/// events that must happen in a very particular ordering.
584#[derive(Debug, Clone, Default)]
585pub struct KeyState {
586    // Using BTreeSet for deterministic key iteration ordering.
587    /// A collection that predictably iterates over all the keys in the order
588    /// they were pressed.
589    // Must iterate through key-value pairs in the order of increasing keys.
590    ordinal_to_key: collections::BTreeMap<u64, Key>,
591    /// Backwards map for quickly finding the ordinal of a specific key.
592    // A bidirectional map could work here, but we don't use one yet on Fuchsia,
593    // avoiding a new dependency with two maps.
594    key_to_ordinal: collections::HashMap<Key, u64>,
595    /// The next new pressed key will get this ordinal.
596    // The ordinal increments with each unique key, but is reset back to zero
597    // when no keys are pressed.  This should be enough to not overflow in any
598    // realistic scenarios.
599    next_ordinal: u64,
600}
601
602impl KeyState {
603    /// Creates a new [KeyState]
604    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    /// Updates the key tracking state with the given key event pair.
613    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                    // Only if the inserted key was not in the set of pressed
618                    // keys.
619                    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 no keys remain in the pressed set, reset the ordinal.
628                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    /// Returns true if `key` is noted as pressed.
637    pub fn is_pressed(&self, key: &Key) -> bool {
638        self.key_to_ordinal.contains_key(key)
639    }
640
641    /// Returns `true` if at least one key from `keys` is pressed.
642    pub fn pressed_any(&self, keys: &[Key]) -> bool {
643        keys.iter().any(|k| self.is_pressed(k))
644    }
645
646    /// Returns `true` if all keys from `keys` are pressed.
647    pub fn pressed_all(&self, keys: &[Key]) -> bool {
648        keys.iter().all(|k| self.is_pressed(k))
649    }
650
651    /// Gets all the keys from the set.
652    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    /// Gets the list of all currently pressed keys, in the order they were
661    /// pressed.
662    pub fn get_ordered_keys(&self) -> Vec<Key> {
663        // Iteration MUST produce keys in a strictly increasing sequence.
664        self.ordinal_to_key.iter().map(|(_, key)| *key).collect()
665    }
666
667    /// Clears the state of [Self], and expunges any stored key presses.
668    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    // The effects of Shift and CapsLock on keys are different for non-letters.
693    #[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    // CapsLock ______/""""""""\_______/"""""""""\_______
935    // Modifier ______/""""""""\_______/"""""""""\______
936    #[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    // Key::Function
940    // Key::Symbol
941    // Key::AltGraph
942    // Test "sided" modifiers.
943    #[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    // Interleaved use of sided modifiers sets and resets the "non-sided"
969    // modifier bit correctly.
970    //
971    // KeyA      """""\____________/""""""""""""""""
972    //                :
973    // KeyB      """""""""""\_____________/"""""""""
974    //                :                   :
975    // Modifier  """""\___________________/"""""""""
976    //
977    // KeyA is the first of the two sided keys, and KeyB is the second of the
978    // two sided keys.
979    #[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    // Check that the lock state is set and reset properly.
1035    //
1036    // Key       ______/""""""""\_______/"""""""""\_______
1037    // LockState ______/""""""""""""""""""""""""""\______
1038    #[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    // CapsLock            ________/""""""""""\_______/"""""\_____
1110    // LeftShift           ____________/"""""""""""\______________
1111    // is_shift_active     ____________/"""""""""""\______________
1112    // is_caps_lock_active ________/""""""""""\_______/"""""\_____
1113    #[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        // Caps Lock is still active...
1132        assert!(!modifier_state.test(Modifiers::SHIFT));
1133        assert!(!modifier_state.test(Modifiers::CAPS_LOCK));
1134
1135        // Press and release Caps Lock again.
1136        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        // This test case is needed for Chromium integration.
1205        // See https://fxbug.dev/42061371.
1206        &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 that the keys are ordered in the sequence they were pressed.
1354    //
1355    // A ____/"""""""""""""""
1356    // B _______/"""""""\____
1357    // C __/"""""""""""""""""
1358    // D __________/"""""""""
1359    //
1360    // KeyState::get_ordered_keys() => [C, A, D]
1361    //
1362    // since out of the keys that are still pressed, C, A and D were actuated
1363    // in that order.
1364    #[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        // Repeated
1373        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}