winit/platform_impl/linux/x11/util/
keys.rs
1use std::iter::Enumerate;
2use std::slice::Iter;
3
4use super::*;
5
6pub struct Keymap {
7 keys: [u8; 32],
8}
9
10pub struct KeymapIter<'a> {
11 iter: Enumerate<Iter<'a, u8>>,
12 index: usize,
13 item: Option<u8>,
14}
15
16impl Keymap {
17 pub fn iter(&self) -> KeymapIter<'_> {
18 KeymapIter { iter: self.keys.iter().enumerate(), index: 0, item: None }
19 }
20}
21
22impl<'a> IntoIterator for &'a Keymap {
23 type IntoIter = KeymapIter<'a>;
24 type Item = ffi::KeyCode;
25
26 fn into_iter(self) -> Self::IntoIter {
27 self.iter()
28 }
29}
30
31impl Iterator for KeymapIter<'_> {
32 type Item = ffi::KeyCode;
33
34 fn next(&mut self) -> Option<ffi::KeyCode> {
35 if self.item.is_none() {
36 for (index, &item) in self.iter.by_ref() {
37 if item != 0 {
38 self.index = index;
39 self.item = Some(item);
40 break;
41 }
42 }
43 }
44
45 self.item.take().map(|item| {
46 debug_assert!(item != 0);
47
48 let bit = first_bit(item);
49
50 if item != bit {
51 self.item = Some(item ^ bit);
53 }
54
55 let shift = bit.trailing_zeros() + (self.index * 8) as u32;
56 shift as ffi::KeyCode
57 })
58 }
59}
60
61impl XConnection {
62 pub fn query_keymap(&self) -> Keymap {
63 let mut keys = [0; 32];
64
65 unsafe {
66 (self.xlib.XQueryKeymap)(self.display, keys.as_mut_ptr() as *mut c_char);
67 }
68
69 Keymap { keys }
70 }
71}
72
73fn first_bit(b: u8) -> u8 {
74 1 << b.trailing_zeros()
75}