gpu_display/keycode_converter/
mod.rs

1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5mod data;
6
7use std::collections::HashMap;
8
9use data::MapEntry;
10use data::KEYCODE_MAP;
11
12/// Specifies which type of scancode to convert *from* in the KeycodeTranslator.
13#[allow(dead_code)]
14pub enum KeycodeTypes {
15    XkbScancode,
16    WindowsScancode,
17    MacScancode,
18}
19
20/// Translates scancodes of a particular type into Linux keycodes.
21#[cfg_attr(windows, allow(dead_code))]
22pub struct KeycodeTranslator {
23    keycode_map: HashMap<u32, MapEntry>,
24}
25
26#[cfg_attr(windows, allow(dead_code))]
27impl KeycodeTranslator {
28    /// Create a new KeycodeTranslator that translates from the `from_type` type to Linux keycodes.
29    pub fn new(from_type: KeycodeTypes) -> KeycodeTranslator {
30        let mut kcm: HashMap<u32, MapEntry> = HashMap::new();
31        for entry in KEYCODE_MAP.iter() {
32            kcm.insert(
33                match from_type {
34                    KeycodeTypes::XkbScancode => entry.xkb,
35                    KeycodeTypes::WindowsScancode => entry.win,
36                    KeycodeTypes::MacScancode => entry.mac,
37                },
38                *entry,
39            );
40        }
41        KeycodeTranslator { keycode_map: kcm }
42    }
43
44    /// Translates the scancode in `from_code` into a Linux keycode.
45    pub fn translate(&self, from_code: u32) -> Option<u16> {
46        Some(self.keycode_map.get(&from_code)?.linux_keycode)
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::keycode_converter::KeycodeTranslator;
53    use crate::keycode_converter::KeycodeTypes;
54
55    #[test]
56    fn test_translate_win_lin() {
57        let translator = KeycodeTranslator::new(KeycodeTypes::WindowsScancode);
58        let translated_code = translator.translate(0x47);
59        assert!(translated_code.is_some());
60        assert_eq!(translated_code.unwrap(), 71);
61    }
62
63    #[test]
64    fn test_translate_missing_entry() {
65        let translator = KeycodeTranslator::new(KeycodeTypes::WindowsScancode);
66
67        // No keycodes are this large.
68        let translated_code = translator.translate(0x9999999);
69        assert!(translated_code.is_none());
70    }
71}