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