Skip to main content

halley_config/keybinds/
codes.rs

1use super::{WHEEL_DOWN_CODE, WHEEL_UP_CODE};
2
3pub fn key_name_to_evdev(name: &str) -> Option<u32> {
4    match name.trim().to_ascii_lowercase().as_str() {
5        "none" => Some(0),
6
7        "escape" | "esc" => Some(1),
8        "1" => Some(2),
9        "2" => Some(3),
10        "3" => Some(4),
11        "4" => Some(5),
12        "5" => Some(6),
13        "6" => Some(7),
14        "7" => Some(8),
15        "8" => Some(9),
16        "9" => Some(10),
17        "0" => Some(11),
18        "minus" | "-" => Some(12),
19        "equal" | "=" => Some(13),
20        "backspace" => Some(14),
21        "tab" => Some(15),
22
23        "q" => Some(16),
24        "w" => Some(17),
25        "e" => Some(18),
26        "r" => Some(19),
27        "t" => Some(20),
28        "y" => Some(21),
29        "u" => Some(22),
30        "i" => Some(23),
31        "o" => Some(24),
32        "p" => Some(25),
33        "leftbrace" | "[" => Some(26),
34        "rightbrace" | "]" => Some(27),
35        "enter" | "return" => Some(28),
36
37        "a" => Some(30),
38        "s" => Some(31),
39        "d" => Some(32),
40        "f" => Some(33),
41        "g" => Some(34),
42        "h" => Some(35),
43        "j" => Some(36),
44        "k" => Some(37),
45        "l" => Some(38),
46        "semicolon" | ";" => Some(39),
47        "apostrophe" | "'" => Some(40),
48        "grave" | "`" => Some(41),
49        "backslash" | "\\" => Some(43),
50
51        "z" => Some(44),
52        "x" => Some(45),
53        "c" => Some(46),
54        "v" => Some(47),
55        "b" => Some(48),
56        "n" => Some(49),
57        "m" => Some(50),
58        "comma" | "," => Some(51),
59        "dot" | "period" | "." => Some(52),
60        "slash" | "/" => Some(53),
61
62        "space" => Some(57),
63
64        "f1" => Some(59),
65        "f2" => Some(60),
66        "f3" => Some(61),
67        "f4" => Some(62),
68        "f5" => Some(63),
69        "f6" => Some(64),
70        "f7" => Some(65),
71        "f8" => Some(66),
72        "f9" => Some(67),
73        "f10" => Some(68),
74        "f11" => Some(87),
75        "f12" => Some(88),
76
77        "home" => Some(102),
78        "up" => Some(103),
79        "pageup" => Some(104),
80        "left" => Some(105),
81        "right" => Some(106),
82        "end" => Some(107),
83        "down" => Some(108),
84        "pagedown" => Some(109),
85        "insert" => Some(110),
86        "delete" => Some(111),
87
88        "mouseleft" | "leftmouse" | "leftbutton" | "btnleft" | "btn_left" => Some(272),
89        "mouseright" | "rightmouse" | "rightbutton" | "btnright" | "btn_right" => Some(273),
90        "mousemiddle" | "middlemouse" | "middlebutton" | "btnmiddle" | "btn_middle" => Some(274),
91        "mouse4" | "mouseback" | "sidebutton" | "btnside" | "btn_side" => Some(275),
92        "mouse5" | "mouseforward" | "extrabutton" | "btnextra" | "btn_extra" => Some(276),
93        "mousewheelup" | "wheelup" | "scrollup" => Some(WHEEL_UP_CODE),
94        "mousewheeldown" | "wheeldown" | "scrolldown" => Some(WHEEL_DOWN_CODE),
95
96        "xf86audiomute" | "audiomute" | "mute" => Some(113),
97        "xf86audiolowervolume" | "audiolowervolume" | "volumedown" => Some(114),
98        "xf86audioraisevolume" | "audioraisevolume" | "volumeup" => Some(115),
99        "xf86audiostop" | "audiostop" | "stopmedia" => Some(166),
100        "xf86audioplay" | "audioplay" | "playpause" => Some(164),
101        "xf86audioprev" | "audioprev" | "previoussong" => Some(165),
102        "xf86audionext" | "audionext" | "nextsong" => Some(163),
103        "xf86audiorecord" | "audiorecord" => Some(167),
104        "xf86audiorewind" | "audiorewind" | "rewind" => Some(168),
105        "xf86homepage" | "homepage" => Some(172),
106        "xf86search" | "search" => Some(217),
107        "xf86monbrightnessdown" | "brightnessdown" => Some(224),
108        "xf86monbrightnessup" | "brightnessup" => Some(225),
109        "xf86mail" | "mail" => Some(155),
110        "xf86calculator" | "calculator" => Some(140),
111        "xf86sleep" | "sleep" => Some(142),
112        "xf86audiopause" | "audiopause" => Some(201),
113        "xf86audiomicmute" | "audiomicmute" | "micmute" => Some(248),
114
115        _ => None,
116    }
117}
118
119#[inline]
120pub fn is_pointer_button_code(code: u32) -> bool {
121    matches!(code, 272..=276)
122}
123
124#[inline]
125pub fn is_wheel_code(code: u32) -> bool {
126    matches!(code, WHEEL_UP_CODE | WHEEL_DOWN_CODE)
127}
128
129pub fn evdev_to_key_name(code: u32) -> &'static str {
130    match code {
131        0 => "None",
132        1 => "Escape",
133        2 => "1",
134        3 => "2",
135        4 => "3",
136        5 => "4",
137        6 => "5",
138        7 => "6",
139        8 => "7",
140        9 => "8",
141        10 => "9",
142        11 => "0",
143        12 => "Minus",
144        13 => "Equal",
145        14 => "Backspace",
146        15 => "Tab",
147        16 => "Q",
148        17 => "W",
149        18 => "E",
150        19 => "R",
151        20 => "T",
152        21 => "Y",
153        22 => "U",
154        23 => "I",
155        24 => "O",
156        25 => "P",
157        26 => "[",
158        27 => "]",
159        28 => "Return",
160        30 => "A",
161        31 => "S",
162        32 => "D",
163        33 => "F",
164        34 => "G",
165        35 => "H",
166        36 => "J",
167        37 => "K",
168        38 => "L",
169        39 => ";",
170        40 => "'",
171        41 => "`",
172        43 => "\\",
173        44 => "Z",
174        45 => "X",
175        46 => "C",
176        47 => "V",
177        48 => "B",
178        49 => "N",
179        50 => "M",
180        51 => "Comma",
181        52 => "Period",
182        53 => "Slash",
183        57 => "Space",
184        59 => "F1",
185        60 => "F2",
186        61 => "F3",
187        62 => "F4",
188        63 => "F5",
189        64 => "F6",
190        65 => "F7",
191        66 => "F8",
192        67 => "F9",
193        68 => "F10",
194        87 => "F11",
195        88 => "F12",
196        102 => "Home",
197        103 => "Up",
198        104 => "PageUp",
199        105 => "Left",
200        106 => "Right",
201        107 => "End",
202        108 => "Down",
203        109 => "PageDown",
204        110 => "Insert",
205        111 => "Delete",
206        140 => "XF86Calculator",
207        142 => "XF86Sleep",
208        155 => "XF86Mail",
209        113 => "XF86AudioMute",
210        114 => "XF86AudioLowerVolume",
211        115 => "XF86AudioRaiseVolume",
212        163 => "XF86AudioNext",
213        164 => "XF86AudioPlay",
214        165 => "XF86AudioPrev",
215        166 => "XF86AudioStop",
216        167 => "XF86AudioRecord",
217        168 => "XF86AudioRewind",
218        172 => "XF86HomePage",
219        201 => "XF86AudioPause",
220        217 => "XF86Search",
221        224 => "XF86MonBrightnessDown",
222        225 => "XF86MonBrightnessUp",
223        248 => "XF86AudioMicMute",
224        272 => "MouseLeft",
225        273 => "MouseRight",
226        274 => "MouseMiddle",
227        275 => "MouseBack",
228        276 => "MouseForward",
229        WHEEL_UP_CODE => "MouseWheelUp",
230        WHEEL_DOWN_CODE => "MouseWheelDown",
231        _ => "?",
232    }
233}
234
235#[cfg(test)]
236mod tests {
237    use super::{WHEEL_DOWN_CODE, WHEEL_UP_CODE, evdev_to_key_name, key_name_to_evdev};
238    use crate::keybinds::{parse_chord, parse_modifiers};
239
240    #[test]
241    fn generic_alt_modifier_matches_either_side_in_config() {
242        let mods = parse_modifiers("alt").expect("alt should parse");
243        assert!(mods.alt);
244        assert!(!mods.left_alt);
245        assert!(!mods.right_alt);
246
247        let (chord_mods, key) = parse_chord("alt+r").expect("alt+r should parse");
248        assert!(chord_mods.alt);
249        assert_eq!(key, 19);
250    }
251
252    #[test]
253    fn mouse_button_aliases_resolve_to_pointer_button_codes() {
254        assert_eq!(key_name_to_evdev("mouseleft"), Some(272));
255        assert_eq!(key_name_to_evdev("btn_right"), Some(273));
256        assert_eq!(key_name_to_evdev("middlemouse"), Some(274));
257        assert_eq!(key_name_to_evdev("mouseback"), Some(275));
258        assert_eq!(key_name_to_evdev("mouseforward"), Some(276));
259        assert_eq!(key_name_to_evdev("mousewheelup"), Some(WHEEL_UP_CODE));
260        assert_eq!(key_name_to_evdev("mousewheeldown"), Some(WHEEL_DOWN_CODE));
261    }
262
263    #[test]
264    fn xf86_media_aliases_resolve_to_expected_codes() {
265        assert_eq!(key_name_to_evdev("XF86AudioMute"), Some(113));
266        assert_eq!(key_name_to_evdev("XF86AudioStop"), Some(166));
267        assert_eq!(key_name_to_evdev("XF86AudioPause"), Some(201));
268        assert_eq!(key_name_to_evdev("XF86AudioMicMute"), Some(248));
269        assert_eq!(key_name_to_evdev("XF86MonBrightnessUp"), Some(225));
270    }
271
272    #[test]
273    fn reverse_lookup_uses_canonical_names_for_new_codes() {
274        assert_eq!(evdev_to_key_name(272), "MouseLeft");
275        assert_eq!(evdev_to_key_name(275), "MouseBack");
276        assert_eq!(evdev_to_key_name(WHEEL_UP_CODE), "MouseWheelUp");
277        assert_eq!(evdev_to_key_name(WHEEL_DOWN_CODE), "MouseWheelDown");
278        assert_eq!(evdev_to_key_name(166), "XF86AudioStop");
279        assert_eq!(evdev_to_key_name(248), "XF86AudioMicMute");
280    }
281}