rfb/
keysym.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4//
5// Copyright 2022 Oxide Computer Company
6
7pub use ascii::AsciiChar;
8use ascii::ToAsciiChar;
9use KeySym::*;
10
11// ascii characters have the same values as their keysym
12const ASCII_MAX: u32 = 0x7f;
13
14const KEYSYM_BACKSPACE: u32 = 0xff08;
15const KEYSYM_TAB: u32 = 0xff09;
16const KEYSYM_RETURN_ENTER: u32 = 0xff0d;
17const KEYSYM_ESCAPE: u32 = 0xff1b;
18const KEYSYM_INSERT: u32 = 0xff63;
19const KEYSYM_DELETE: u32 = 0xffff;
20const KEYSYM_HOME: u32 = 0xff50;
21const KEYSYM_END: u32 = 0xff57;
22const KEYSYM_PAGE_UP: u32 = 0xff55;
23const KEYSYM_PAGE_DOWN: u32 = 0xff56;
24const KEYSYM_PRINT: u32 = 0xff61;
25const KEYSYM_PAUSE: u32 = 0xff13;
26const KEYSYM_CAPS_LOCK: u32 = 0xffe5;
27const KEYSYM_SUPER_LEFT: u32 = 0xffeb;
28const KEYSYM_SUPER_RIGHT: u32 = 0xffec;
29const KEYSYM_MENU: u32 = 0xff67;
30
31const KEYSYM_LEFT: u32 = 0xff51;
32const KEYSYM_UP: u32 = 0xff52;
33const KEYSYM_RIGHT: u32 = 0xff53;
34const KEYSYM_DOWN: u32 = 0xff54;
35// function keys are in the range: 0xffbe to 0xffc9, in order
36const KEYSYM_F1: u32 = 0xffbe;
37const KEYSYM_F12: u32 = 0xffc9;
38const KEYSYM_SHIFT_LEFT: u32 = 0xffe1;
39const KEYSYM_SHIFT_RIGHT: u32 = 0xffe2;
40const KEYSYM_CTRL_LEFT: u32 = 0xffe3;
41const KEYSYM_CTRL_RIGHT: u32 = 0xffe4;
42
43// XXX(JPH): do we need to support meta keys?
44
45const KEYSYM_ALT_LEFT: u32 = 0xffe9;
46const KEYSYM_ALT_RIGHT: u32 = 0xffea;
47const KEYSYM_SCROLL_LOCK: u32 = 0xff14;
48const KEYSYM_NUM_LOCK: u32 = 0xff7f;
49
50const KEYSYM_KP_ENTER: u32 = 0xff8d;
51const KEYSYM_KP_SLASH: u32 = 0xffaf;
52const KEYSYM_KP_ASTERISK: u32 = 0xffaa;
53const KEYSYM_KP_MINUS: u32 = 0xffad;
54const KEYSYM_KP_PLUS: u32 = 0xffab;
55const KEYSYM_KP_7: u32 = 0xffb7;
56const KEYSYM_KP_HOME: u32 = 0xff95;
57const KEYSYM_KP_8: u32 = 0xffb8;
58const KEYSYM_KP_UP: u32 = 0xff97;
59const KEYSYM_KP_9: u32 = 0xffb9;
60const KEYSYM_KP_PGUP: u32 = 0xff9a;
61const KEYSYM_KP_4: u32 = 0xffb4;
62const KEYSYM_KP_LEFT: u32 = 0xff96;
63const KEYSYM_KP_5: u32 = 0xffb5;
64const KEYSYM_KP_EMPTY: u32 = 0xff9d;
65const KEYSYM_KP_6: u32 = 0xffb6;
66const KEYSYM_KP_RIGHT: u32 = 0xff98;
67const KEYSYM_KP_1: u32 = 0xffb1;
68const KEYSYM_KP_END: u32 = 0xff9c;
69const KEYSYM_KP_2: u32 = 0xffb2;
70const KEYSYM_KP_DOWN: u32 = 0xff99;
71const KEYSYM_KP_3: u32 = 0xffb3;
72const KEYSYM_KP_PGDOWN: u32 = 0xff9b;
73const KEYSYM_KP_0: u32 = 0xffb0;
74const KEYSYM_KP_INSERT: u32 = 0xff9e;
75const KEYSYM_KP_PERIOD: u32 = 0xffae;
76const KEYSYM_KP_DELETE: u32 = 0xff9f;
77
78#[derive(Debug, Copy, Clone)]
79pub enum KeySym {
80    Ascii(ascii::AsciiChar),
81    Backspace,
82    Tab,
83    ReturnOrEnter,
84    Escape,
85    Insert,
86    Delete,
87    Home,
88    End,
89    PageUp,
90    PageDown,
91    Print,
92    Pause,
93    CapsLock,
94
95    // "super" = windows/command key
96    SuperLeft,
97    SuperRight,
98
99    // usb-only
100    Menu,
101
102    Left,
103    Up,
104    Right,
105    Down,
106
107    FunctionKey(u8),
108
109    ShiftLeft,
110    ShiftRight,
111    ControlLeft,
112    ControlRight,
113    AltLeft,
114    AltRight,
115    ScrollLock,
116
117    // Number Keypad
118    NumLock,
119    KeypadSlash,
120    KeypadAsterisk,
121    KeypadMinus,
122    KeypadPlus,
123    KeypadEnter,
124    KeypadPeriod,
125    KeypadDelete,
126    Keypad0,
127    KeypadInsert,
128    Keypad1,
129    KeypadEnd,
130    Keypad2,
131    KeypadDown,
132    Keypad3,
133    KeypadPgDown,
134    Keypad4,
135    KeypadLeft,
136    Keypad5,
137    KeypadEmpty,
138    Keypad6,
139    KeypadRight,
140    Keypad7,
141    KeypadHome,
142    Keypad8,
143    KeypadUp,
144    Keypad9,
145    KeypadPgUp,
146}
147
148#[derive(Debug, thiserror::Error)]
149#[error("unknown keysym: 0x{0:x}")]
150pub struct KeySymError(u32);
151
152impl TryFrom<u32> for KeySym {
153    type Error = KeySymError;
154
155    fn try_from(value: u32) -> Result<Self, Self::Error> {
156        match value {
157            // SAFETY: we're within the valid ascii range
158            0..=ASCII_MAX => Ok(Ascii(unsafe { value.to_ascii_char_unchecked() })),
159            KEYSYM_BACKSPACE => Ok(Backspace),
160            KEYSYM_TAB => Ok(Tab),
161            KEYSYM_RETURN_ENTER => Ok(ReturnOrEnter),
162            KEYSYM_ESCAPE => Ok(Escape),
163            KEYSYM_INSERT => Ok(Insert),
164            KEYSYM_DELETE => Ok(Delete),
165            KEYSYM_HOME => Ok(Home),
166            KEYSYM_END => Ok(End),
167            KEYSYM_PAGE_UP => Ok(PageUp),
168            KEYSYM_PRINT => Ok(Print),
169            KEYSYM_PAUSE => Ok(Pause),
170            KEYSYM_CAPS_LOCK => Ok(CapsLock),
171            KEYSYM_SUPER_LEFT => Ok(SuperLeft),
172            KEYSYM_SUPER_RIGHT => Ok(SuperRight),
173            KEYSYM_MENU => Ok(Menu),
174
175            KEYSYM_PAGE_DOWN => Ok(PageDown),
176            KEYSYM_LEFT => Ok(Left),
177            KEYSYM_UP => Ok(Up),
178            KEYSYM_RIGHT => Ok(Right),
179            KEYSYM_DOWN => Ok(Down),
180
181            f if (f >= KEYSYM_F1 && f <= KEYSYM_F12) => {
182                let n = f - KEYSYM_F1 + 1;
183                // TODO: handle cast
184                Ok(FunctionKey(n as u8))
185            }
186
187            KEYSYM_SHIFT_LEFT => Ok(ShiftLeft),
188            KEYSYM_SHIFT_RIGHT => Ok(ShiftRight),
189            KEYSYM_CTRL_LEFT => Ok(ControlLeft),
190            KEYSYM_CTRL_RIGHT => Ok(ControlRight),
191            KEYSYM_ALT_LEFT => Ok(AltLeft),
192            KEYSYM_ALT_RIGHT => Ok(AltRight),
193
194            KEYSYM_SCROLL_LOCK => Ok(ScrollLock),
195            KEYSYM_NUM_LOCK => Ok(NumLock),
196
197            KEYSYM_KP_ENTER => Ok(KeypadEnter),
198            KEYSYM_KP_SLASH => Ok(KeypadSlash),
199            KEYSYM_KP_ASTERISK => Ok(KeypadAsterisk),
200            KEYSYM_KP_MINUS => Ok(KeypadMinus),
201            KEYSYM_KP_PLUS => Ok(KeypadPlus),
202            KEYSYM_KP_7 => Ok(Keypad7),
203            KEYSYM_KP_HOME => Ok(KeypadHome),
204            KEYSYM_KP_8 => Ok(Keypad8),
205            KEYSYM_KP_UP => Ok(KeypadUp),
206            KEYSYM_KP_9 => Ok(Keypad9),
207            KEYSYM_KP_PGUP => Ok(KeypadPgUp),
208            KEYSYM_KP_4 => Ok(Keypad4),
209            KEYSYM_KP_LEFT => Ok(KeypadLeft),
210            KEYSYM_KP_5 => Ok(Keypad5),
211            KEYSYM_KP_EMPTY => Ok(KeypadEmpty),
212            KEYSYM_KP_6 => Ok(Keypad6),
213            KEYSYM_KP_RIGHT => Ok(KeypadRight),
214            KEYSYM_KP_1 => Ok(Keypad1),
215            KEYSYM_KP_END => Ok(KeypadEnd),
216            KEYSYM_KP_2 => Ok(Keypad2),
217            KEYSYM_KP_DOWN => Ok(KeypadDown),
218            KEYSYM_KP_3 => Ok(Keypad3),
219            KEYSYM_KP_PGDOWN => Ok(KeypadPgDown),
220            KEYSYM_KP_0 => Ok(Keypad0),
221            KEYSYM_KP_INSERT => Ok(KeypadInsert),
222            KEYSYM_KP_PERIOD => Ok(KeypadPeriod),
223            KEYSYM_KP_DELETE => Ok(KeypadDelete),
224
225            _ => Err(KeySymError(value)),
226        }
227    }
228}