1
2use device::Device;
3
4use ffi::*;
5use libc::{c_int, input_event};
6
7use std::fs::File;
8use std::io::Read;
9use std::collections::HashMap;
10
11const DOWN: i32 = 1;
13const UP: i32 = 0;
14const INVERT_KEY_FLAG: char = '^';
15const CAPS_MODIFY_KEY_FLAG: char = '*';
16const HALF_KEY_SEPARATOR: char = ':';
17
18const LEFTSHIFT_INDEX: usize = KEY_LEFTSHIFT as usize;
19const RIGHTSHIFT_INDEX: usize = KEY_RIGHTSHIFT as usize;
20const CAPSLOCK_INDEX: usize = KEY_CAPSLOCK as usize;
21
22const KEY_LEFTSHIFT_U16: u16 = KEY_LEFTSHIFT as u16;
23const KEY_RIGHTSHIFT_U16: u16 = KEY_RIGHTSHIFT as u16;
24const KEY_CAPSLOCK_U16: u16 = KEY_CAPSLOCK as u16;
25
26trait KeyMapper {
27 fn send_event(&self, key_state: &[bool], event: &mut input_event, device: &Device);
28}
29
30pub struct KeyMaps {
31 keymaps: Vec<Box<KeyMapper>>,
32 keymap_index_keys: HashMap<u16, usize>,
33 switch_layout_keys: Vec<usize>,
34 key_state: [bool; KEY_MAX],
35 revert_default_key: u16,
36 revert_keymap_index: usize,
37 chosen_keymap_index: usize,
39 current_keymap_index: usize,
40}
41
42fn parse_key(key_map: &HashMap<&'static str, *const c_int>, key: &str) -> u16 {
43 match key_map.get(key.trim_matches(|c: char| c.is_whitespace() || c == INVERT_KEY_FLAG || c == CAPS_MODIFY_KEY_FLAG)) {
44 Some(key_code) => *key_code as u16,
45 None => panic!("unknown key: {}", key.trim())
46 }
47}
48
49fn parse_keymap_numeric(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec<u16> {
50 keymap.split(",").map(|k| parse_key(key_map, k)).collect()
51}
52
53fn parse_key_half_inverted(key_map: &HashMap<&'static str, *const c_int>, key: &str) -> HalfInvertedKey {
54 HalfInvertedKey {
55 code: parse_key(key_map, key),
56 invert_shift: key.contains(INVERT_KEY_FLAG),
57 capslock_nomodify: key.contains(CAPS_MODIFY_KEY_FLAG),
58 }
59}
60
61fn parse_keymap_u16(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec<u16> {
63 keymap.split(",").map(|k| parse_key(key_map, k)).collect()
64}
65
66fn parse_keymap(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec<Key> {
68 keymap.split(",").map(|k| {
69 let ret: Key = if k.contains(HALF_KEY_SEPARATOR) {
70 let keys: Vec<&str> = k.split(HALF_KEY_SEPARATOR).collect();
71 if keys.len() != 2 {
72 panic!("split key can only have 2 keys, 1 :, has {} keys", keys.len());
73 }
74 let mut shift_half = parse_key_half_inverted(key_map, keys[1]);
75 shift_half.invert_shift = !shift_half.invert_shift;
76 Key::FullKey(parse_key_half_inverted(key_map, keys[0]), shift_half)
77 } else if k.contains(INVERT_KEY_FLAG) || k.contains(CAPS_MODIFY_KEY_FLAG) {
78 Key::HalfKey(parse_key_half_inverted(key_map, k))
79 } else {
80 Key::Direct(parse_key(key_map, k))
81 };
82 ret
83 }).collect()
84}
85
86impl KeyMaps {
87 pub fn from_cfg<P: AsRef<Path>>(key_map: &HashMap<&'static str, *const c_int>, path: P) -> KeyMaps {
88 let key_map_config = parse_cfg(path).expect("provided config cannot be found/parsed");
89 KeyMaps::new(key_map, key_map_config)
90 }
91
92 pub fn new(key_map: &HashMap<&'static str, *const c_int>, config: KeymapConfig) -> KeyMaps {
93 if config.keymaps.len() < 2 {
94 panic!("must have at least 2 keymaps (original and mapped) but only have {},", config.keymaps.len());
95 }
96 if config.default_keymap_index >= config.keymaps.len() || config.revert_keymap_index >= config.keymaps.len() {
97 panic!("default_keymap_index ({}) and revert_keymap_index ({}) must be less than keymaps length ({}),", config.default_keymap_index, config.revert_keymap_index, config.keymaps.len());
98 }
99 let base_keymap = parse_keymap_numeric(key_map, &config.keymaps[0]);
100 let mut keymaps: Vec<Box<KeyMapper>> = vec!(Box::new(Key::Noop)); let mut keymap_index_keys: HashMap<u16, usize> = HashMap::new();
103 for (x, v) in config.keymaps.iter().enumerate() {
104 keymap_index_keys.insert(*key_map.get(&*x.to_string()).unwrap() as u16, x);
105 if x == 0 {
106 continue;
107 }
108 if v.contains(HALF_KEY_SEPARATOR) || v.contains(INVERT_KEY_FLAG) || v.contains(CAPS_MODIFY_KEY_FLAG) {
109 let v = parse_keymap(key_map, v);
111 let mut keymap = KeyMap::new();
112 let mut i: usize = 0;
113 for key_code in v {
114 keymap.map(base_keymap[i], key_code);
116 i = i + 1;
117 if i > base_keymap.len() {
118 panic!("all keymaps must be the same length, keymap index 0 length: {}, index {} length: {},", base_keymap.len(), x, i);
119 }
120 }
121 keymaps.push(Box::new(keymap));
122 } else {
123 let v = parse_keymap_u16(key_map, v);
125 let mut keymap = CodeKeyMap::new();
126 let mut i: usize = 0;
127 for key_code in v {
128 keymap.map(base_keymap[i], key_code);
129 i = i + 1;
130 if i > base_keymap.len() {
131 panic!("all keymaps must be the same length, keymap index 0 length: {}, index {} length: {},", base_keymap.len(), x, i);
132 }
133 }
134 keymaps.push(Box::new(keymap));
135 }
136 }
137 KeyMaps {
141 keymaps: keymaps,
142 keymap_index_keys: keymap_index_keys,
143 switch_layout_keys: config.switch_layout_keys.iter().map(|k| parse_key(key_map, k) as usize).collect(),
144 key_state: [false; KEY_MAX],
145 revert_default_key: parse_key(key_map, &config.revert_default_key),
147 revert_keymap_index: config.revert_keymap_index,
148 chosen_keymap_index: config.default_keymap_index,
149 current_keymap_index: config.default_keymap_index,
150 }
151 }
152}
153
154impl KeyMaps {
156 pub fn send_event(&mut self, mut event: &mut input_event, device: &Device) {
157 if event.value != 2 {
159 if event.code == KEY_CAPSLOCK_U16 {
161 if event.value == DOWN {
162 self.key_state[CAPSLOCK_INDEX] = !self.key_state[CAPSLOCK_INDEX];
163 }
164 } else {
165 self.key_state[event.code as usize] = event.value == DOWN;
166 }
167 let mut switch_layout_keys_pressed = true;
168 for layout_switch_key in self.switch_layout_keys.iter_mut() {
169 if !self.key_state[*layout_switch_key] {
170 switch_layout_keys_pressed = false;
171 break;
172 }
173 }
174 if switch_layout_keys_pressed {
176 let new_index = self.keymap_index_keys.get(&event.code);
177 if new_index.is_some() {
178 self.chosen_keymap_index = *new_index.unwrap();
179 self.current_keymap_index = self.chosen_keymap_index; return; }
182 }
183 if event.code == self.revert_default_key {
184 match event.value {
185 DOWN => self.current_keymap_index = self.revert_keymap_index,
187 UP => self.current_keymap_index = self.chosen_keymap_index,
188 _ => () }
190 }
191 }
192 self.keymaps[self.current_keymap_index].send_event(&self.key_state, &mut event, device);
193 }
194}
195
196const KEY_MAX: usize = 249;
198
199struct KeyMap {
200 keymap: [Key; KEY_MAX],
202}
203
204impl KeyMap {
205 pub fn new() -> Self {
206 let keymap : [Key; KEY_MAX] = [Key::Noop; KEY_MAX];
210 KeyMap {
228 keymap: keymap
229 }
230 }
231 pub fn map(&mut self, from: u16, to: Key) {
237 self.keymap[from as usize] = to;
238 }
239}
240
241impl KeyMapper for KeyMap {
242 fn send_event(&self, key_state: &[bool], event: &mut input_event, device: &Device) {
243 self.keymap[event.code as usize].send_event(key_state, event, device);
244 }
247}
248
249struct CodeKeyMap {
250 keymap: [u16; KEY_MAX],
252}
253
254impl CodeKeyMap {
255 pub fn new() -> Self {
256 let mut keymap = [0u16; KEY_MAX];
257 for (x, v) in keymap.iter_mut().enumerate() {
264 *v = x as u16;
265 }
266 CodeKeyMap {
268 keymap: keymap
269 }
270 }
271
272 pub fn map(&mut self, from: u16, to: u16) {
273 self.keymap[from as usize] = to;
274 }
275}
276
277impl KeyMapper for CodeKeyMap {
278 fn send_event(&self, key_state: &[bool], event: &mut input_event, device: &Device) {
279 self.keymap[event.code as usize].send_event(key_state, event, device);
280 }
281}
282
283#[allow(unused_variables)]
284impl KeyMapper for u16 {
285 fn send_event(&self, key_state: &[bool], mut event: &mut input_event, device: &Device) {
286 event.code = *self;
287 device.write_event(event).expect("could not write event?");
288 }
289}
290
291#[derive(Clone, Copy)]
293struct HalfInvertedKey {
294 code: u16,
295 invert_shift: bool,
297 capslock_nomodify: bool,
299 }
301
302impl HalfInvertedKey {
303 fn send_key(&self, key_state: &[bool], event: &mut input_event, device: &Device, left_shift: bool, right_shift: bool, caps_lock: bool) {
304 let code = self.code;
305 let value = event.value;
306 let mut invert_shift = self.invert_shift;
307 if value == DOWN {
308 if caps_lock && self.capslock_nomodify {
309 invert_shift = !invert_shift;
310 }
311 if invert_shift {
312 if left_shift {
313 event.code = KEY_LEFTSHIFT_U16;
314 event.value = UP;
315 } else if right_shift {
316 event.code = KEY_RIGHTSHIFT_U16;
317 event.value = UP;
318 } else {
319 event.code = KEY_LEFTSHIFT_U16;
320 event.value = DOWN;
321 }
322 device.write_event(event).expect("could not write event?");
324 event.code = code; event.value = value;
326 }
327 }
328 code.send_event(key_state, event, device);
329 if value == UP {
330 if caps_lock && self.capslock_nomodify {
331 invert_shift = !invert_shift;
332 }
333 if invert_shift {
334 if left_shift {
335 event.code = KEY_LEFTSHIFT_U16;
336 event.value = DOWN;
337 } else if right_shift {
338 event.code = KEY_RIGHTSHIFT_U16;
339 event.value = DOWN;
340 } else {
341 event.code = KEY_LEFTSHIFT_U16;
342 event.value = UP;
343 }
344 device.write_event(event).expect("could not write event?");
346 event.code = code; event.value = value;
349 }
350 }
351 }
352}
353
354impl KeyMapper for HalfInvertedKey {
355 fn send_event(&self, key_state: &[bool], event: &mut input_event, device: &Device) {
356 let left_shift = key_state[LEFTSHIFT_INDEX];
357 let right_shift = key_state[RIGHTSHIFT_INDEX];
358 let caps_lock = key_state[CAPSLOCK_INDEX];
359 self.send_key(key_state, event, device, left_shift, right_shift, caps_lock);
360 }
361}
362
363#[derive(Clone, Copy)]
364enum Key {
365 Noop,
366 Direct(u16),
367 HalfKey(HalfInvertedKey),
368 FullKey(HalfInvertedKey, HalfInvertedKey),
369}
370
371impl KeyMapper for Key {
372 fn send_event(&self, key_state: &[bool], event: &mut input_event, device: &Device) {
373 match *self {
374 Key::Noop => {
375 device.write_event(event).expect("could not write event?");
376 },
377 Key::Direct(code) => {
378 code.send_event(key_state, event, device);
379 },
380 Key::HalfKey(ref key_half) => {
381 key_half.send_event(key_state, event, device);
382 },
383 Key::FullKey(ref noshift_half, ref shift_half) => {
384 let left_shift = key_state[LEFTSHIFT_INDEX];
385 let right_shift = key_state[RIGHTSHIFT_INDEX];
386 let caps_lock = key_state[CAPSLOCK_INDEX];
387 if caps_lock != (left_shift || right_shift) {
388 shift_half.send_key(key_state, event, device, left_shift, right_shift, caps_lock);
389 } else {
390 noshift_half.send_key(key_state, event, device, left_shift, right_shift, caps_lock);
391 }
392 },
393 }
394 }
395}
396
397extern crate toml;
398
399use std::path::Path;
400
401#[derive(Deserialize, Debug)]
402pub struct KeymapConfig {
403 switch_layout_keys: Vec<String>,
404 revert_default_key: String,
405 revert_keymap_index: usize,
406 default_keymap_index: usize,
407 keymaps: Vec<String>
408}
409
410use std::io::{Error, ErrorKind};
419
420fn parse_cfg<P: AsRef<Path>>(path: P) -> Result<KeymapConfig, Error> {
421 let mut f = File::open(path)?;
422 let mut input = String::new();
423 f.read_to_string(&mut input)?;
424 match toml::from_str(&input) {
426 Ok(toml) => Ok(toml),
427 Err(_) => Err(Error::new(ErrorKind::Other, "oh no!"))
428 }
429}
430
431impl KeyMaps {
432 pub fn key_map() -> HashMap<&'static str, *const c_int> {
433 [
434 ("RESERVED", KEY_RESERVED),
437 ("ESC", KEY_ESC),
438 ("1", KEY_1),
439 ("2", KEY_2),
440 ("3", KEY_3),
441 ("4", KEY_4),
442 ("5", KEY_5),
443 ("6", KEY_6),
444 ("7", KEY_7),
445 ("8", KEY_8),
446 ("9", KEY_9),
447 ("10", KEY_10),
448 ("MINUS", KEY_MINUS),
449 ("EQUAL", KEY_EQUAL),
450 ("BACKSPACE", KEY_BACKSPACE),
451 ("TAB", KEY_TAB),
452 ("Q", KEY_Q),
453 ("W", KEY_W),
454 ("E", KEY_E),
455 ("R", KEY_R),
456 ("T", KEY_T),
457 ("Y", KEY_Y),
458 ("U", KEY_U),
459 ("I", KEY_I),
460 ("O", KEY_O),
461 ("P", KEY_P),
462 ("LEFTBRACE", KEY_LEFTBRACE),
463 ("RIGHTBRACE", KEY_RIGHTBRACE),
464 ("ENTER", KEY_ENTER),
465 ("LEFTCTRL", KEY_LEFTCTRL),
466 ("A", KEY_A),
467 ("S", KEY_S),
468 ("D", KEY_D),
469 ("F", KEY_F),
470 ("G", KEY_G),
471 ("H", KEY_H),
472 ("J", KEY_J),
473 ("K", KEY_K),
474 ("L", KEY_L),
475 ("SEMICOLON", KEY_SEMICOLON),
476 ("APOSTROPHE", KEY_APOSTROPHE),
477 ("GRAVE", KEY_GRAVE),
478 ("LEFTSHIFT", KEY_LEFTSHIFT),
479 ("BACKSLASH", KEY_BACKSLASH),
480 ("Z", KEY_Z),
481 ("X", KEY_X),
482 ("C", KEY_C),
483 ("V", KEY_V),
484 ("B", KEY_B),
485 ("N", KEY_N),
486 ("M", KEY_M),
487 ("COMMA", KEY_COMMA),
488 ("DOT", KEY_DOT),
489 ("SLASH", KEY_SLASH),
490 ("RIGHTSHIFT", KEY_RIGHTSHIFT),
491 ("KPASTERISK", KEY_KPASTERISK),
492 ("LEFTALT", KEY_LEFTALT),
493 ("SPACE", KEY_SPACE),
494 ("CAPSLOCK", KEY_CAPSLOCK),
495 ("F1", KEY_F1),
496 ("F2", KEY_F2),
497 ("F3", KEY_F3),
498 ("F4", KEY_F4),
499 ("F5", KEY_F5),
500 ("F6", KEY_F6),
501 ("F7", KEY_F7),
502 ("F8", KEY_F8),
503 ("F9", KEY_F9),
504 ("F10", KEY_F10),
505 ("NUMLOCK", KEY_NUMLOCK),
506 ("SCROLLLOCK", KEY_SCROLLLOCK),
507 ("KP7", KEY_KP7),
508 ("KP8", KEY_KP8),
509 ("KP9", KEY_KP9),
510 ("KPMINUS", KEY_KPMINUS),
511 ("KP4", KEY_KP4),
512 ("KP5", KEY_KP5),
513 ("KP6", KEY_KP6),
514 ("KPPLUS", KEY_KPPLUS),
515 ("KP1", KEY_KP1),
516 ("KP2", KEY_KP2),
517 ("KP3", KEY_KP3),
518 ("KP0", KEY_KP0),
519 ("KPDOT", KEY_KPDOT),
520 ("ZENKAKUHANKAKU", KEY_ZENKAKUHANKAKU),
521 ("102ND", KEY_102ND),
522 ("F11", KEY_F11),
523 ("F12", KEY_F12),
524 ("RO", KEY_RO),
525 ("KATAKANA", KEY_KATAKANA),
526 ("HIRAGANA", KEY_HIRAGANA),
527 ("HENKAN", KEY_HENKAN),
528 ("KATAKANAHIRAGANA", KEY_KATAKANAHIRAGANA),
529 ("MUHENKAN", KEY_MUHENKAN),
530 ("KPJPCOMMA", KEY_KPJPCOMMA),
531 ("KPENTER", KEY_KPENTER),
532 ("RIGHTCTRL", KEY_RIGHTCTRL),
533 ("KPSLASH", KEY_KPSLASH),
534 ("SYSRQ", KEY_SYSRQ),
535 ("RIGHTALT", KEY_RIGHTALT),
536 ("LINEFEED", KEY_LINEFEED),
537 ("HOME", KEY_HOME),
538 ("UP", KEY_UP),
539 ("PAGEUP", KEY_PAGEUP),
540 ("LEFT", KEY_LEFT),
541 ("RIGHT", KEY_RIGHT),
542 ("END", KEY_END),
543 ("DOWN", KEY_DOWN),
544 ("PAGEDOWN", KEY_PAGEDOWN),
545 ("INSERT", KEY_INSERT),
546 ("DELETE", KEY_DELETE),
547 ("MACRO", KEY_MACRO),
548 ("MUTE", KEY_MUTE),
549 ("VOLUMEDOWN", KEY_VOLUMEDOWN),
550 ("VOLUMEUP", KEY_VOLUMEUP),
551 ("POWER", KEY_POWER),
552 ("KPEQUAL", KEY_KPEQUAL),
553 ("KPPLUSMINUS", KEY_KPPLUSMINUS),
554 ("PAUSE", KEY_PAUSE),
555 ("SCALE", KEY_SCALE),
556 ("KPCOMMA", KEY_KPCOMMA),
557 ("HANGEUL", KEY_HANGEUL),
558 ("HANGUEL", KEY_HANGUEL),
559 ("HANGEUL", KEY_HANGEUL),
560 ("HANJA", KEY_HANJA),
561 ("YEN", KEY_YEN),
562 ("LEFTMETA", KEY_LEFTMETA),
563 ("RIGHTMETA", KEY_RIGHTMETA),
564 ("COMPOSE", KEY_COMPOSE),
565 ("STOP", KEY_STOP),
566 ("AGAIN", KEY_AGAIN),
567 ("PROPS", KEY_PROPS),
568 ("UNDO", KEY_UNDO),
569 ("FRONT", KEY_FRONT),
570 ("COPY", KEY_COPY),
571 ("OPEN", KEY_OPEN),
572 ("PASTE", KEY_PASTE),
573 ("FIND", KEY_FIND),
574 ("CUT", KEY_CUT),
575 ("HELP", KEY_HELP),
576 ("MENU", KEY_MENU),
577 ("CALC", KEY_CALC),
578 ("SETUP", KEY_SETUP),
579 ("SLEEP", KEY_SLEEP),
580 ("WAKEUP", KEY_WAKEUP),
581 ("FILE", KEY_FILE),
582 ("SENDFILE", KEY_SENDFILE),
583 ("DELETEFILE", KEY_DELETEFILE),
584 ("XFER", KEY_XFER),
585 ("PROG1", KEY_PROG1),
586 ("PROG2", KEY_PROG2),
587 ("WWW", KEY_WWW),
588 ("MSDOS", KEY_MSDOS),
589 ("COFFEE", KEY_COFFEE),
590 ("SCREENLOCK", KEY_SCREENLOCK),
591 ("COFFEE", KEY_COFFEE),
592 ("ROTATE_DISPLAY", KEY_ROTATE_DISPLAY),
593 ("DIRECTION", KEY_DIRECTION),
594 ("ROTATE_DISPLAY", KEY_ROTATE_DISPLAY),
595 ("CYCLEWINDOWS", KEY_CYCLEWINDOWS),
596 ("MAIL", KEY_MAIL),
597 ("BOOKMARKS", KEY_BOOKMARKS),
598 ("COMPUTER", KEY_COMPUTER),
599 ("BACK", KEY_BACK),
600 ("FORWARD", KEY_FORWARD),
601 ("CLOSECD", KEY_CLOSECD),
602 ("EJECTCD", KEY_EJECTCD),
603 ("EJECTCLOSECD", KEY_EJECTCLOSECD),
604 ("NEXTSONG", KEY_NEXTSONG),
605 ("PLAYPAUSE", KEY_PLAYPAUSE),
606 ("PREVIOUSSONG", KEY_PREVIOUSSONG),
607 ("STOPCD", KEY_STOPCD),
608 ("RECORD", KEY_RECORD),
609 ("REWIND", KEY_REWIND),
610 ("PHONE", KEY_PHONE),
611 ("ISO", KEY_ISO),
612 ("CONFIG", KEY_CONFIG),
613 ("HOMEPAGE", KEY_HOMEPAGE),
614 ("REFRESH", KEY_REFRESH),
615 ("EXIT", KEY_EXIT),
616 ("MOVE", KEY_MOVE),
617 ("EDIT", KEY_EDIT),
618 ("SCROLLUP", KEY_SCROLLUP),
619 ("SCROLLDOWN", KEY_SCROLLDOWN),
620 ("KPLEFTPAREN", KEY_KPLEFTPAREN),
621 ("KPRIGHTPAREN", KEY_KPRIGHTPAREN),
622 ("NEW", KEY_NEW),
623 ("REDO", KEY_REDO),
624 ("F13", KEY_F13),
625 ("F14", KEY_F14),
626 ("F15", KEY_F15),
627 ("F16", KEY_F16),
628 ("F17", KEY_F17),
629 ("F18", KEY_F18),
630 ("F19", KEY_F19),
631 ("F20", KEY_F20),
632 ("F21", KEY_F21),
633 ("F22", KEY_F22),
634 ("F23", KEY_F23),
635 ("F24", KEY_F24),
636 ("PLAYCD", KEY_PLAYCD),
637 ("PAUSECD", KEY_PAUSECD),
638 ("PROG3", KEY_PROG3),
639 ("PROG4", KEY_PROG4),
640 ("DASHBOARD", KEY_DASHBOARD),
641 ("SUSPEND", KEY_SUSPEND),
642 ("CLOSE", KEY_CLOSE),
643 ("PLAY", KEY_PLAY),
644 ("FASTFORWARD", KEY_FASTFORWARD),
645 ("BASSBOOST", KEY_BASSBOOST),
646 ("PRINT", KEY_PRINT),
647 ("HP", KEY_HP),
648 ("CAMERA", KEY_CAMERA),
649 ("SOUND", KEY_SOUND),
650 ("QUESTION", KEY_QUESTION),
651 ("EMAIL", KEY_EMAIL),
652 ("CHAT", KEY_CHAT),
653 ("SEARCH", KEY_SEARCH),
654 ("CONNECT", KEY_CONNECT),
655 ("FINANCE", KEY_FINANCE),
656 ("SPORT", KEY_SPORT),
657 ("SHOP", KEY_SHOP),
658 ("ALTERASE", KEY_ALTERASE),
659 ("CANCEL", KEY_CANCEL),
660 ("BRIGHTNESSDOWN", KEY_BRIGHTNESSDOWN),
661 ("BRIGHTNESSUP", KEY_BRIGHTNESSUP),
662 ("MEDIA", KEY_MEDIA),
663 ("SWITCHVIDEOMODE", KEY_SWITCHVIDEOMODE),
664 ("KBDILLUMTOGGLE", KEY_KBDILLUMTOGGLE),
665 ("KBDILLUMDOWN", KEY_KBDILLUMDOWN),
666 ("KBDILLUMUP", KEY_KBDILLUMUP),
667 ("SEND", KEY_SEND),
668 ("REPLY", KEY_REPLY),
669 ("FORWARDMAIL", KEY_FORWARDMAIL),
670 ("SAVE", KEY_SAVE),
671 ("DOCUMENTS", KEY_DOCUMENTS),
672 ("BATTERY", KEY_BATTERY),
673 ("BLUETOOTH", KEY_BLUETOOTH),
674 ("WLAN", KEY_WLAN),
675 ("UWB", KEY_UWB),
676 ("UNKNOWN", KEY_UNKNOWN),
677 ("VIDEO_NEXT", KEY_VIDEO_NEXT),
678 ("VIDEO_PREV", KEY_VIDEO_PREV),
679 ("BRIGHTNESS_CYCLE", KEY_BRIGHTNESS_CYCLE),
680 ("BRIGHTNESS_AUTO", KEY_BRIGHTNESS_AUTO),
681 ("BRIGHTNESS_ZERO", KEY_BRIGHTNESS_ZERO),
682 ("BRIGHTNESS_AUTO", KEY_BRIGHTNESS_AUTO),
683 ("DISPLAY_OFF", KEY_DISPLAY_OFF),
684 ("WWAN", KEY_WWAN),
685 ("WIMAX", KEY_WIMAX),
686 ("WWAN", KEY_WWAN),
687 ("RFKILL", KEY_RFKILL),
688 ("MICMUTE", KEY_MICMUTE),
689 ("PSCR", KEY_SYSRQ),
691 ("SLCK", KEY_SCROLLLOCK),
692 ("BRK", KEY_PAUSE),
693 ("GRV", KEY_GRAVE),
694 ("0", KEY_10), ("MINS", KEY_MINUS),
696 ("EQL", KEY_EQUAL),
697 ("BSPC", KEY_BACKSPACE),
698 ("LBRC", KEY_LEFTBRACE),
699 ("RBRC", KEY_RIGHTBRACE),
700 ("BSLS", KEY_BACKSLASH),
701 ("SCLN", KEY_SEMICOLON),
702 ("QUOT", KEY_APOSTROPHE),
703 ("ENT", KEY_ENTER),
704 ("COMM", KEY_COMMA),
705 ("DOT", KEY_DOT),
706 ("SLSH", KEY_SLASH),
707 ("CAPS", KEY_CAPSLOCK),
708 ("LSFT", KEY_LEFTSHIFT),
709 ("RSFT", KEY_RIGHTSHIFT),
710 ("SPC", KEY_SPACE),
711 ("APP", KEY_COMPOSE),
712 ("LCTL", KEY_LEFTCTRL),
713 ("RCTL", KEY_RIGHTCTRL),
714 ("LALT", KEY_LEFTALT),
715 ("RALT", KEY_RIGHTALT),
716 ("LGUI", KEY_LEFTMETA),
717 ("RGUI", KEY_RIGHTMETA),
718 ("INS", KEY_INSERT),
719 ("PGUP", KEY_PAGEUP),
720 ("PGDN", KEY_PAGEDOWN),
721 ("DEL", KEY_DELETE),
722 ("RGHT", KEY_RIGHT),
723 ("NLCK", KEY_NUMLOCK),
724 ("PSLS", KEY_KPSLASH),
725 ("PAST", KEY_KPASTERISK),
726 ("PMNS", KEY_KPMINUS),
727 ("P7", KEY_KP7),
728 ("P8", KEY_KP8),
729 ("P9", KEY_KP9),
730 ("P4", KEY_KP4),
731 ("P5", KEY_KP5),
732 ("P6", KEY_KP6),
733 ("PPLS", KEY_KPPLUS),
734 ("P1", KEY_KP1),
735 ("P2", KEY_KP2),
736 ("P3", KEY_KP3),
737 ("P0", KEY_KP0),
738 ("PDOT", KEY_KPDOT),
739 ("PENT", KEY_KPENTER),
740 ].iter().cloned().map(|(m, v)| (m, v as *const c_int)).collect()
741 }
742}