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