xref: /aosp_15_r20/external/crosvm/gpu_display/src/keycode_converter/mod.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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 
5 mod data;
6 
7 use std::collections::HashMap;
8 
9 use data::MapEntry;
10 use data::KEYCODE_MAP;
11 
12 /// Specifies which type of scancode to convert *from* in the KeycodeTranslator.
13 #[allow(dead_code)]
14 pub 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))]
22 pub struct KeycodeTranslator {
23     keycode_map: HashMap<u32, MapEntry>,
24 }
25 
26 #[cfg_attr(windows, allow(dead_code))]
27 impl KeycodeTranslator {
28     /// Create a new KeycodeTranslator that translates from the `from_type` type to Linux keycodes.
new(from_type: KeycodeTypes) -> KeycodeTranslator29     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.
translate(&self, from_code: u32) -> Option<u16>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)]
51 mod tests {
52     use crate::keycode_converter::KeycodeTranslator;
53     use crate::keycode_converter::KeycodeTypes;
54 
55     #[test]
test_translate_win_lin()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]
test_translate_missing_entry()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 }
72