use xkbcommon::xkb;
use qualia::{Illusion, KeyboardConfig, InputCode, InputValue};
use keymap::XkbKeymap;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct KeyMods {
pub depressed: u32,
pub latched: u32,
pub locked: u32,
pub effective: u32,
}
impl KeyMods {
pub fn default() -> Self {
KeyMods {
depressed: 0,
latched: 0,
locked: 0,
effective: 0,
}
}
pub fn new(depressed: u32, latched: u32, locked: u32, effective: u32) -> Self {
KeyMods {
depressed: depressed,
latched: latched,
locked: locked,
effective: effective,
}
}
}
pub struct KeyboardState {
xkb_state: xkb::State,
mods: KeyMods,
}
impl KeyboardState {
pub fn new(config: &KeyboardConfig) -> Result<Self, Illusion> {
let xkb_keymap = if let Some(xkb_keymap) = XkbKeymap::new(config) {
xkb_keymap
} else {
return Err(Illusion::General(format!("Failed to create key map")));
};
Ok(KeyboardState {
xkb_state: xkb::State::new(&xkb_keymap.keymap),
mods: KeyMods::default(),
})
}
pub fn update(&mut self, code: InputCode, value: InputValue) -> bool {
let direction = if value == 0 {
xkb::KeyDirection::Up
} else {
xkb::KeyDirection::Down
};
self.xkb_state.update_key(code as u32 + 8, direction);
let mods = KeyMods::new(self.xkb_state.serialize_mods(xkb::STATE_MODS_DEPRESSED),
self.xkb_state.serialize_mods(xkb::STATE_MODS_LATCHED),
self.xkb_state.serialize_mods(xkb::STATE_MODS_LOCKED),
self.xkb_state.serialize_mods(xkb::STATE_MODS_EFFECTIVE));
if mods != self.mods {
self.mods = mods;
true
} else {
false
}
}
pub fn get_mods(&self) -> KeyMods {
self.mods
}
}