openloaf_rdev/
codes_conv.rs1#[cfg(target_os = "linux")]
2use crate::keycodes::linux::key_from_code as linux_key_from_code;
3#[cfg(target_os = "macos")]
4use crate::keycodes::macos::key_from_code as macos_key_from_code;
5use crate::keycodes::macos::virtual_keycodes::*;
6#[cfg(target_os = "windows")]
7use crate::keycodes::windows::key_from_scancode as win_key_from_scancode;
8#[cfg(target_os = "macos")]
9use crate::macos::map_keycode;
10use crate::{
11 keycodes::{
12 android::code_from_key as android_code_from_key,
13 linux::code_from_key as linux_code_from_key, macos::code_from_key as macos_code_from_key,
14 usb_hid::key_from_code as usb_hid_key_from_code,
15 windows::scancode_from_key as win_scancode_from_key,
16 },
17 Key, KeyCode,
18};
19
20macro_rules! conv_keycodes {
21 ($fnname:ident, $key_from_code:ident, $code_from_key:ident) => {
22 pub fn $fnname(code: u32) -> Option<KeyCode> {
23 let key = $key_from_code(code as _);
24 match key {
25 Key::Unknown(..) => None,
26 Key::RawKey(..) => None,
27 _ => $code_from_key(key).map(|c| c as KeyCode),
28 }
29 }
30 };
31}
32
33#[allow(non_upper_case_globals)]
34fn macos_iso_code_from_key(key: Key) -> Option<KeyCode> {
35 match macos_code_from_key(key)? {
36 kVK_ISO_Section => Some(kVK_ANSI_Grave),
37 kVK_ANSI_Grave => Some(kVK_ISO_Section),
38 code => Some(code as _),
39 }
40}
41
42#[cfg(target_os = "macos")]
43#[allow(non_upper_case_globals)]
44fn macos_keycode_from_code_(code: KeyCode) -> Key {
45 macos_key_from_code(map_keycode(code))
46}
47
48#[cfg(target_os = "windows")]
49conv_keycodes!(
50 win_scancode_to_linux_code,
51 win_key_from_scancode,
52 linux_code_from_key
53);
54#[cfg(target_os = "windows")]
55conv_keycodes!(
56 win_scancode_to_macos_code,
57 win_key_from_scancode,
58 macos_code_from_key
59);
60#[cfg(target_os = "windows")]
61conv_keycodes!(
63 win_scancode_to_macos_iso_code,
64 win_key_from_scancode,
65 macos_iso_code_from_key
66);
67#[cfg(target_os = "windows")]
68conv_keycodes!(
70 win_scancode_to_android_key_code,
71 win_key_from_scancode,
72 android_code_from_key
73);
74#[cfg(target_os = "linux")]
75conv_keycodes!(
76 linux_code_to_win_scancode,
77 linux_key_from_code,
78 win_scancode_from_key
79);
80#[cfg(target_os = "linux")]
81conv_keycodes!(
82 linux_code_to_macos_code,
83 linux_key_from_code,
84 macos_code_from_key
85);
86#[cfg(target_os = "linux")]
87conv_keycodes!(
89 linux_code_to_macos_iso_code,
90 linux_key_from_code,
91 macos_iso_code_from_key
92);
93#[cfg(target_os = "linux")]
94conv_keycodes!(
95 linux_code_to_android_key_code,
96 linux_key_from_code,
97 android_code_from_key
98);
99#[cfg(target_os = "macos")]
100conv_keycodes!(
101 macos_code_to_win_scancode,
102 macos_keycode_from_code_,
103 win_scancode_from_key
104);
105#[cfg(target_os = "macos")]
106conv_keycodes!(
107 macos_code_to_linux_code,
108 macos_keycode_from_code_,
109 linux_code_from_key
110);
111#[cfg(target_os = "macos")]
112conv_keycodes!(
113 macos_code_to_android_key_code,
114 macos_keycode_from_code_,
115 android_code_from_key
116);
117conv_keycodes!(
118 usb_hid_code_to_win_scancode,
119 usb_hid_key_from_code,
120 win_scancode_from_key
121);
122conv_keycodes!(
123 usb_hid_code_to_linux_code,
124 usb_hid_key_from_code,
125 linux_code_from_key
126);
127conv_keycodes!(
128 usb_hid_code_to_macos_code,
129 usb_hid_key_from_code,
130 macos_code_from_key
131);
132conv_keycodes!(
133 usb_hid_code_to_macos_iso_code,
134 usb_hid_key_from_code,
135 macos_iso_code_from_key
136);
137conv_keycodes!(
138 usb_hid_code_to_android_key_code,
139 usb_hid_key_from_code,
140 android_code_from_key
141);
142
143#[cfg(test)]
144mod test {
145 #[test]
146 fn test_usb_hid_code_to_macos_code() {
147 for code in 0..=65535 {
148 let key = crate::keycodes::macos::key_from_code(code);
149 if matches!(key, crate::Key::Unknown(..) | crate::Key::RawKey(..)) {
150 continue;
151 }
152 let usb_hid = crate::keycodes::usb_hid::code_from_key(key);
153 if let Some(usb_hid) = usb_hid {
154 if usb_hid == 0 {
155 continue;
156 }
157 if let Some(code2) = super::usb_hid_code_to_macos_code(usb_hid) {
158 assert_eq!(code, code2 as u32)
159 } else {
160 assert!(false, "We could not convert back code: {:?}", code);
161 }
162 }
163 }
164 }
165
166 #[test]
167 fn test_usb_hid_code_to_windows_scan_code() {
168 for code in 1..=65535 {
169 let key = crate::keycodes::windows::key_from_scancode(code);
170 if matches!(key, crate::Key::Unknown(..) | crate::Key::RawKey(..)) {
171 continue;
172 }
173 let usb_hid = crate::keycodes::usb_hid::code_from_key(key);
174 if let Some(usb_hid) = usb_hid {
175 if usb_hid == 0 {
176 continue;
177 }
178 if let Some(code2) = super::usb_hid_code_to_win_scancode(usb_hid) {
179 assert_eq!(code, code2 as u32)
180 } else {
181 assert!(false, "We could not convert back code: {:?}", code);
182 }
183 }
184 }
185 }
186
187 #[test]
188 fn test_usb_hid_code_to_linux_key_code() {
189 for code in 0..=65535 {
190 let key = crate::keycodes::linux::key_from_code(code);
191 if matches!(key, crate::Key::Unknown(..) | crate::Key::RawKey(..)) {
192 continue;
193 }
194 let usb_hid = crate::keycodes::usb_hid::code_from_key(key);
195 if let Some(usb_hid) = usb_hid {
196 if usb_hid == 0 {
197 continue;
198 }
199 if let Some(code2) = super::usb_hid_code_to_linux_code(usb_hid) {
200 assert_eq!(code, code2 as u32)
201 } else {
202 assert!(false, "We could not convert back code: {:?}", code);
203 }
204 }
205 }
206 }
207}