1use crate::keycode::Keycode;
12use crate::localizer::Platform;
13use crate::named_key::NamedKey;
14use crate::scancode::Scancode;
15
16#[derive(Copy, Clone, Debug)]
18pub struct LayoutKey {
19 pub scancode: Scancode,
20 pub base: Option<char>,
23 pub shift: Option<char>,
25 pub altgr: Option<char>,
27 pub shift_altgr: Option<char>,
29 pub named: Option<NamedKey>,
32}
33
34impl LayoutKey {
35 pub const fn named(sc: Scancode, nk: NamedKey) -> Self {
37 Self {
38 scancode: sc,
39 base: None,
40 shift: None,
41 altgr: None,
42 shift_altgr: None,
43 named: Some(nk),
44 }
45 }
46
47 pub const fn printable(sc: Scancode, base: char, shift: char) -> Self {
49 Self {
50 scancode: sc,
51 base: Some(base),
52 shift: Some(shift),
53 altgr: None,
54 shift_altgr: None,
55 named: None,
56 }
57 }
58
59 pub const fn printable4(
61 sc: Scancode,
62 base: char,
63 shift: char,
64 altgr: char,
65 shift_altgr: char,
66 ) -> Self {
67 Self {
68 scancode: sc,
69 base: Some(base),
70 shift: Some(shift),
71 altgr: Some(altgr),
72 shift_altgr: Some(shift_altgr),
73 named: None,
74 }
75 }
76}
77
78#[derive(Copy, Clone, Debug)]
80pub struct Layout {
81 pub id: &'static str,
83 pub display_name: &'static str,
85 pub platform: Platform,
87 pub language: &'static str,
89 pub named_keys: &'static [LayoutKey],
91 pub printable_keys: &'static [LayoutKey],
93}
94
95impl Layout {
96 pub fn key(&self, sc: Scancode) -> Option<&'static LayoutKey> {
98 self.printable_keys
99 .iter()
100 .find(|k| k.scancode == sc)
101 .or_else(|| self.named_keys.iter().find(|k| k.scancode == sc))
102 }
103}
104
105pub const STD_NAMED_KEYS: &[LayoutKey] = &[
108 LayoutKey::named(Scancode::ESCAPE, NamedKey::Escape),
109 LayoutKey::named(Scancode::RETURN, NamedKey::Return),
110 LayoutKey::named(Scancode::BACKSPACE, NamedKey::Backspace),
111 LayoutKey::named(Scancode::TAB, NamedKey::Tab),
112 LayoutKey::named(Scancode::CAPSLOCK, NamedKey::CapsLock),
113 LayoutKey::named(Scancode::F1, NamedKey::F1),
114 LayoutKey::named(Scancode::F2, NamedKey::F2),
115 LayoutKey::named(Scancode::F3, NamedKey::F3),
116 LayoutKey::named(Scancode::F4, NamedKey::F4),
117 LayoutKey::named(Scancode::F5, NamedKey::F5),
118 LayoutKey::named(Scancode::F6, NamedKey::F6),
119 LayoutKey::named(Scancode::F7, NamedKey::F7),
120 LayoutKey::named(Scancode::F8, NamedKey::F8),
121 LayoutKey::named(Scancode::F9, NamedKey::F9),
122 LayoutKey::named(Scancode::F10, NamedKey::F10),
123 LayoutKey::named(Scancode::F11, NamedKey::F11),
124 LayoutKey::named(Scancode::F12, NamedKey::F12),
125 LayoutKey::named(Scancode::F13, NamedKey::F13),
126 LayoutKey::named(Scancode::F14, NamedKey::F14),
127 LayoutKey::named(Scancode::F15, NamedKey::F15),
128 LayoutKey::named(Scancode::F16, NamedKey::F16),
129 LayoutKey::named(Scancode::F17, NamedKey::F17),
130 LayoutKey::named(Scancode::F18, NamedKey::F18),
131 LayoutKey::named(Scancode::F19, NamedKey::F19),
132 LayoutKey::named(Scancode::F20, NamedKey::F20),
133 LayoutKey::named(Scancode::F21, NamedKey::F21),
134 LayoutKey::named(Scancode::F22, NamedKey::F22),
135 LayoutKey::named(Scancode::F23, NamedKey::F23),
136 LayoutKey::named(Scancode::F24, NamedKey::F24),
137 LayoutKey::named(Scancode::PRINT_SCREEN, NamedKey::PrintScreen),
138 LayoutKey::named(Scancode::SCROLL_LOCK, NamedKey::ScrollLock),
139 LayoutKey::named(Scancode::PAUSE, NamedKey::Pause),
140 LayoutKey::named(Scancode::INSERT, NamedKey::Insert),
141 LayoutKey::named(Scancode::HOME, NamedKey::Home),
142 LayoutKey::named(Scancode::PAGE_UP, NamedKey::PageUp),
143 LayoutKey::named(Scancode::DELETE, NamedKey::Delete),
144 LayoutKey::named(Scancode::END, NamedKey::End),
145 LayoutKey::named(Scancode::PAGE_DOWN, NamedKey::PageDown),
146 LayoutKey::named(Scancode::RIGHT, NamedKey::ArrowRight),
147 LayoutKey::named(Scancode::LEFT, NamedKey::ArrowLeft),
148 LayoutKey::named(Scancode::DOWN, NamedKey::ArrowDown),
149 LayoutKey::named(Scancode::UP, NamedKey::ArrowUp),
150 LayoutKey::named(Scancode::NUM_LOCK_CLEAR, NamedKey::NumLock),
151 LayoutKey::named(Scancode::KP_DIVIDE, NamedKey::KeypadDivide),
152 LayoutKey::named(Scancode::KP_MULTIPLY, NamedKey::KeypadMultiply),
153 LayoutKey::named(Scancode::KP_MINUS, NamedKey::KeypadMinus),
154 LayoutKey::named(Scancode::KP_PLUS, NamedKey::KeypadPlus),
155 LayoutKey::named(Scancode::KP_ENTER, NamedKey::KeypadEnter),
156 LayoutKey::named(Scancode::KP_1, NamedKey::Keypad1),
157 LayoutKey::named(Scancode::KP_2, NamedKey::Keypad2),
158 LayoutKey::named(Scancode::KP_3, NamedKey::Keypad3),
159 LayoutKey::named(Scancode::KP_4, NamedKey::Keypad4),
160 LayoutKey::named(Scancode::KP_5, NamedKey::Keypad5),
161 LayoutKey::named(Scancode::KP_6, NamedKey::Keypad6),
162 LayoutKey::named(Scancode::KP_7, NamedKey::Keypad7),
163 LayoutKey::named(Scancode::KP_8, NamedKey::Keypad8),
164 LayoutKey::named(Scancode::KP_9, NamedKey::Keypad9),
165 LayoutKey::named(Scancode::KP_0, NamedKey::Keypad0),
166 LayoutKey::named(Scancode::KP_PERIOD, NamedKey::KeypadPeriod),
167 LayoutKey::named(Scancode::KP_EQUALS, NamedKey::KeypadEquals),
168 LayoutKey::named(Scancode::APPLICATION, NamedKey::Application),
169 LayoutKey::named(Scancode::MENU, NamedKey::Menu),
170 LayoutKey::named(Scancode::SPACE, NamedKey::Space),
171 LayoutKey::named(Scancode::LCTRL, NamedKey::ControlLeft),
172 LayoutKey::named(Scancode::LSHIFT, NamedKey::ShiftLeft),
173 LayoutKey::named(Scancode::LALT, NamedKey::AltLeft),
174 LayoutKey::named(Scancode::LGUI, NamedKey::GuiLeft),
175 LayoutKey::named(Scancode::RCTRL, NamedKey::ControlRight),
176 LayoutKey::named(Scancode::RSHIFT, NamedKey::ShiftRight),
177 LayoutKey::named(Scancode::RALT, NamedKey::AltRight),
178 LayoutKey::named(Scancode::RGUI, NamedKey::GuiRight),
179];
180
181include!(concat!(env!("OUT_DIR"), "/cldr_layouts.rs"));
196
197pub fn get_layout(id: &str) -> Option<&'static Layout> {
200 CLDR_LAYOUTS
201 .iter()
202 .find(|l| l.id == id)
203 .or_else(|| CLDR3_LAYOUTS.iter().find(|l| l.id == id))
204 .copied()
205}
206
207pub fn all_layouts() -> &'static [&'static Layout] {
211 use std::sync::OnceLock;
212 static COMBINED: OnceLock<Vec<&'static Layout>> = OnceLock::new();
213 COMBINED
214 .get_or_init(|| {
215 let mut v: Vec<&'static Layout> = CLDR_LAYOUTS.to_vec();
216 v.extend(CLDR3_LAYOUTS.iter().copied());
217 v
218 })
219 .as_slice()
220}
221
222pub(crate) fn layout_key_base_keycode(k: &LayoutKey) -> Keycode {
225 if let Some(nk) = k.named {
226 named_key_keycode(nk)
227 } else if let Some(c) = k.base {
228 Keycode::from(c)
229 } else {
230 Keycode::UNKNOWN
231 }
232}
233
234pub(crate) fn named_key_keycode(nk: NamedKey) -> Keycode {
236 use NamedKey::*;
237 match nk {
238 Escape => Keycode::ESCAPE,
239 Return => Keycode::RETURN,
240 Tab => Keycode::TAB,
241 Space => Keycode::SPACE,
242 Backspace => Keycode::BACKSPACE,
243 Insert => Keycode::INSERT,
244 Delete => Keycode::DELETE,
245 Home => Keycode::HOME,
246 End => Keycode::END,
247 PageUp => Keycode::PAGE_UP,
248 PageDown => Keycode::PAGE_DOWN,
249 ArrowUp => Keycode::UP,
250 ArrowDown => Keycode::DOWN,
251 ArrowLeft => Keycode::LEFT,
252 ArrowRight => Keycode::RIGHT,
253 CapsLock => Keycode::CAPSLOCK,
254 NumLock => Keycode::NUM_LOCK_CLEAR,
255 ScrollLock => Keycode::SCROLL_LOCK,
256 PrintScreen => Keycode::PRINT_SCREEN,
257 Pause => Keycode::PAUSE,
258 Menu => Keycode::MENU,
259 Application => Keycode::APPLICATION,
260 ShiftLeft => Keycode::LSHIFT,
261 ShiftRight => Keycode::RSHIFT,
262 ControlLeft => Keycode::LCTRL,
263 ControlRight => Keycode::RCTRL,
264 AltLeft => Keycode::LALT,
265 AltRight => Keycode::RALT,
266 AltGr => Keycode::RALT,
267 GuiLeft => Keycode::LGUI,
268 GuiRight => Keycode::RGUI,
269 F1 => Keycode::F1,
270 F2 => Keycode::F2,
271 F3 => Keycode::F3,
272 F4 => Keycode::F4,
273 F5 => Keycode::F5,
274 F6 => Keycode::F6,
275 F7 => Keycode::F7,
276 F8 => Keycode::F8,
277 F9 => Keycode::F9,
278 F10 => Keycode::F10,
279 F11 => Keycode::F11,
280 F12 => Keycode::F12,
281 F13 => Keycode::F13,
282 F14 => Keycode::F14,
283 F15 => Keycode::F15,
284 F16 => Keycode::F16,
285 F17 => Keycode::F17,
286 F18 => Keycode::F18,
287 F19 => Keycode::F19,
288 F20 => Keycode::F20,
289 F21 => Keycode::F21,
290 F22 => Keycode::F22,
291 F23 => Keycode::F23,
292 F24 => Keycode::F24,
293 KeypadEnter => Keycode::KP_ENTER,
294 KeypadDivide => Keycode::KP_DIVIDE,
295 KeypadMultiply => Keycode::KP_MULTIPLY,
296 KeypadMinus => Keycode::KP_MINUS,
297 KeypadPlus => Keycode::KP_PLUS,
298 KeypadPeriod => Keycode::KP_PERIOD,
299 KeypadEquals => Keycode::KP_EQUALS,
300 Keypad0 => Keycode::KP_0,
301 Keypad1 => Keycode::KP_1,
302 Keypad2 => Keycode::KP_2,
303 Keypad3 => Keycode::KP_3,
304 Keypad4 => Keycode::KP_4,
305 Keypad5 => Keycode::KP_5,
306 Keypad6 => Keycode::KP_6,
307 Keypad7 => Keycode::KP_7,
308 Keypad8 => Keycode::KP_8,
309 Keypad9 => Keycode::KP_9,
310 }
311}