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