| 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 | |