keymaps/
usages.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
5/// Standard [USB HID] usages.
6///
7/// [USB HID]: https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum Usages {
10    HidUsageKeyErrorRollover = 0x01,
11    HidUsageKeyPostFail = 0x02,
12    HidUsageKeyErrorUndef = 0x03,
13    HidUsageKeyA = 0x04,
14    HidUsageKeyB = 0x05,
15    HidUsageKeyC = 0x06,
16    HidUsageKeyD = 0x07,
17    HidUsageKeyE = 0x08,
18    HidUsageKeyF = 0x09,
19    HidUsageKeyG = 0x0A,
20    HidUsageKeyH = 0x0B,
21    HidUsageKeyI = 0x0C,
22    HidUsageKeyJ = 0x0D,
23    HidUsageKeyK = 0x0E,
24    HidUsageKeyL = 0x0F,
25    HidUsageKeyM = 0x10,
26    HidUsageKeyN = 0x11,
27    HidUsageKeyO = 0x12,
28    HidUsageKeyP = 0x13,
29    HidUsageKeyQ = 0x14,
30    HidUsageKeyR = 0x15,
31    HidUsageKeyS = 0x16,
32    HidUsageKeyT = 0x17,
33    HidUsageKeyU = 0x18,
34    HidUsageKeyV = 0x19,
35    HidUsageKeyW = 0x1A,
36    HidUsageKeyX = 0x1B,
37    HidUsageKeyY = 0x1C,
38    HidUsageKeyZ = 0x1D,
39    HidUsageKey1 = 0x1E,
40    HidUsageKey2 = 0x1F,
41    HidUsageKey3 = 0x20,
42    HidUsageKey4 = 0x21,
43    HidUsageKey5 = 0x22,
44    HidUsageKey6 = 0x23,
45    HidUsageKey7 = 0x24,
46    HidUsageKey8 = 0x25,
47    HidUsageKey9 = 0x26,
48    HidUsageKey0 = 0x27,
49    HidUsageKeyEnter = 0x28,
50    HidUsageKeyEsc = 0x29,
51    HidUsageKeyBackspace = 0x2A,
52    HidUsageKeyTab = 0x2B,
53    HidUsageKeySpace = 0x2C,
54    HidUsageKeyMinus = 0x2D,
55    HidUsageKeyEqual = 0x2E,
56    HidUsageKeyLeftbrace = 0x2F,
57    HidUsageKeyRightbrace = 0x30,
58    HidUsageKeyBackslash = 0x31,
59    HidUsageKeyNonUsOctothorpe = 0x32,
60    HidUsageKeySemicolon = 0x33,
61    HidUsageKeyApostrophe = 0x34,
62    HidUsageKeyGrave = 0x35,
63    HidUsageKeyComma = 0x36,
64    HidUsageKeyDot = 0x37,
65    HidUsageKeySlash = 0x38,
66    HidUsageKeyCapslock = 0x39,
67    HidUsageKeyF1 = 0x3A,
68    HidUsageKeyF2 = 0x3B,
69    HidUsageKeyF3 = 0x3C,
70    HidUsageKeyF4 = 0x3D,
71    HidUsageKeyF5 = 0x3E,
72    HidUsageKeyF6 = 0x3F,
73    HidUsageKeyF7 = 0x40,
74    HidUsageKeyF8 = 0x41,
75    HidUsageKeyF9 = 0x42,
76    HidUsageKeyF10 = 0x43,
77    HidUsageKeyF11 = 0x44,
78    HidUsageKeyF12 = 0x45,
79    HidUsageKeyPrintscreen = 0x46,
80    HidUsageKeyScrolllock = 0x47,
81    HidUsageKeyPause = 0x48,
82    HidUsageKeyInsert = 0x49,
83    HidUsageKeyHome = 0x4A,
84    HidUsageKeyPageup = 0x4B,
85    HidUsageKeyDelete = 0x4C,
86    HidUsageKeyEnd = 0x4D,
87    HidUsageKeyPagedown = 0x4E,
88    HidUsageKeyRight = 0x4F,
89    HidUsageKeyLeft = 0x50,
90    HidUsageKeyDown = 0x51,
91    HidUsageKeyUp = 0x52,
92    HidUsageKeyNumlock = 0x53,
93    HidUsageKeyKpSlash = 0x54,
94    HidUsageKeyKpAsterisk = 0x55,
95    HidUsageKeyKpMinus = 0x56,
96    HidUsageKeyKpPlus = 0x57,
97    HidUsageKeyKpEnter = 0x58,
98    HidUsageKeyKp1 = 0x59,
99    HidUsageKeyKp2 = 0x5A,
100    HidUsageKeyKp3 = 0x5B,
101    HidUsageKeyKp4 = 0x5C,
102    HidUsageKeyKp5 = 0x5D,
103    HidUsageKeyKp6 = 0x5E,
104    HidUsageKeyKp7 = 0x5F,
105    HidUsageKeyKp8 = 0x60,
106    HidUsageKeyKp9 = 0x61,
107    HidUsageKeyKp0 = 0x62,
108    HidUsageKeyKpDot = 0x63,
109    HidUsageKeyNonUsBackslash = 0x64,
110    HidUsageKeyLeftCtrl = 0xE0,
111    HidUsageKeyLeftShift = 0xE1,
112    HidUsageKeyLeftAlt = 0xE2,
113    HidUsageKeyLeftGui = 0xE3,
114    HidUsageKeyRightCtrl = 0xE4,
115    HidUsageKeyRightShift = 0xE5,
116    HidUsageKeyRightAlt = 0xE6,
117    HidUsageKeyRightGui = 0xE7,
118    // TODO: The following two values are incorrect and are not actually USB HID codes, but are
119    //       currently the values that appear in hid/usages.h. Eventually we will want to migrate to
120    //       fuchsia.ui.input.Key.
121    HidUsageKeyVolUp = 0xE8,
122    HidUsageKeyVolDown = 0xE9,
123}
124
125/// Converts a [`Key`] to the corresponding USB HID code.
126///
127/// Note: This is only needed while keyboard input is transitioned away from Scenic.
128///
129/// # Parameters
130/// - `key`: The key to convert to its HID equivalent.
131pub fn input3_key_to_hid_usage(key: fidl_fuchsia_input::Key) -> u32 {
132    fidl_fuchsia_input::Key::into_primitive(key) & 0xFFFF
133}
134
135/// Converts a USB HID Usage ID to the corresponding input3 [`Key`].
136///
137/// The Usage ID is interpreted in the context of Usage Page 0x07 ("Keyboard/Keypad"),
138/// except that:
139/// * 0xe8 is interpreted as Usage Page 0x0c, Usage ID 0xe9 (Volume Increment)
140/// * 0xe9 is interpreted as Usage Page 0x0c, Usage ID 0xea (Volume Decrement)
141///
142/// These exceptions provide backwards compatibility with Root Presenter's input
143/// pipeline.
144///
145/// # Parameters
146/// - `usage_id`: The Usage ID to convert to its input3 [`Key`] equivalent.
147///
148/// # Future directions
149/// Per https://fxbug.dev/42142534, this method will be replaced with a method that deals in
150/// `fuchsia.input.Key`s, instead of HID Usage IDs.
151pub fn hid_usage_to_input3_key(usage_id: u16) -> Option<fidl_fuchsia_input::Key> {
152    if usage_id == Usages::HidUsageKeyVolUp as u16 {
153        Some(fidl_fuchsia_input::Key::MediaVolumeIncrement)
154    } else if usage_id == Usages::HidUsageKeyVolDown as u16 {
155        Some(fidl_fuchsia_input::Key::MediaVolumeDecrement)
156    } else {
157        fidl_fuchsia_input::Key::from_primitive(u32::from(usage_id) | 0x0007_0000)
158    }
159}
160
161#[cfg(test)]
162mod tests {
163    use super::*;
164    use test_case::test_case;
165
166    #[test]
167    fn input3_key_to_hid() {
168        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::A), 0x4);
169        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::Key1), 0x1e);
170        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::Enter), 0x28);
171        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::F1), 0x3a);
172        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::PrintScreen), 0x46);
173        assert_eq!(input3_key_to_hid_usage(fidl_fuchsia_input::Key::Keypad1), 0x59);
174    }
175
176    #[test_case(Usages::HidUsageKeyVolUp => fidl_fuchsia_input::Key::MediaVolumeIncrement; "volume_up")]
177    #[test_case(Usages::HidUsageKeyVolDown => fidl_fuchsia_input::Key::MediaVolumeDecrement; "volume_down")]
178    #[test_case(Usages::HidUsageKeyA => fidl_fuchsia_input::Key::A; "letter_a")]
179    fn hid_usage_to_input3_key(usage: Usages) -> fidl_fuchsia_input::Key {
180        super::hid_usage_to_input3_key(usage as u16).expect("conversion yielded None")
181    }
182}