1use std::{iter::Enumerate, slice::Iter};
2
3use super::*;
4
5pub struct Keymap {
6 keys: [u8; 32],
7}
8
9pub struct KeymapIter<'a> {
10 iter: Enumerate<Iter<'a, u8>>,
11 index: usize,
12 item: Option<u8>,
13}
14
15impl 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
25impl<'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
34impl 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
64impl 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
76fn first_bit(b: u8) -> u8 {
77 1 << b.trailing_zeros()
78}
79