1 | use std::iter::Enumerate; |
2 | use std::slice::Iter; |
3 | |
4 | use super::*; |
5 | |
6 | pub struct Keymap { |
7 | keys: [u8; 32], |
8 | } |
9 | |
10 | pub struct KeymapIter<'a> { |
11 | iter: Enumerate<Iter<'a, u8>>, |
12 | index: usize, |
13 | item: Option<u8>, |
14 | } |
15 | |
16 | impl Keymap { |
17 | pub fn iter(&self) -> KeymapIter<'_> { |
18 | KeymapIter { iter: self.keys.iter().enumerate(), index: 0, item: None } |
19 | } |
20 | } |
21 | |
22 | impl<'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 | |
31 | impl 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 | // Remove the first bit; save the rest for further iterations |
52 | 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 | |
61 | impl XConnection { |
62 | pub fn query_keymap(&self) -> Keymap { |
63 | let mut keys: [u8; 32] = [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 | |
73 | fn first_bit(b: u8) -> u8 { |
74 | 1 << b.trailing_zeros() |
75 | } |
76 | |