1
0
Fork 0
forked from wry/wry
wry/src/kbvm.rs

101 lines
2.9 KiB
Rust

pub use jay_keyboard::{KbvmContext, KbvmError, KbvmMap, KbvmMapId, KbvmState};
use {
crate::{
backend::KeyState,
ifs::wl_seat::WlSeatGlobal,
utils::{syncqueue::SyncQueue, vecset::VecSet},
},
kbvm::{
Keycode,
state_machine::{Direction, Event},
},
std::{
cell::{Cell, RefCell},
rc::Rc,
},
};
pub struct PhysicalKeyboardState {
state: Rc<RefCell<KbvmState>>,
inner: RefCell<PkInner>,
events: SyncQueue<Event>,
flushing: Cell<bool>,
}
#[derive(Default)]
struct PkInner {
pressed_keys: VecSet<u32>,
event_stash: Vec<Event>,
}
impl PhysicalKeyboardState {
pub fn new(state: &Rc<RefCell<KbvmState>>) -> Self {
Self {
state: state.clone(),
inner: Default::default(),
events: Default::default(),
flushing: Cell::new(false),
}
}
fn flush(&self, time_usec: u64, seat: &Rc<WlSeatGlobal>) {
if self.flushing.replace(true) {
return;
}
seat.key_events(time_usec, &self.events, &self.state);
self.flushing.set(false);
}
pub fn update(&self, time_usec: u64, seat: &Rc<WlSeatGlobal>, key: u32, key_state: KeyState) {
{
let inner = &mut *self.inner.borrow_mut();
match key_state {
KeyState::Released => {
if !inner.pressed_keys.remove(&key) {
return;
}
}
KeyState::Pressed => {
if !inner.pressed_keys.insert(key) {
return;
}
}
KeyState::Repeated => {
return;
}
}
let state = &mut *self.state.borrow_mut();
state.map.state_machine.handle_key(
&mut state.state,
&mut inner.event_stash,
Keycode::from_evdev(key),
match key_state {
KeyState::Released => Direction::Up,
KeyState::Pressed => Direction::Down,
KeyState::Repeated => unreachable!(),
},
);
self.events.append(&mut inner.event_stash);
}
self.flush(time_usec, seat);
}
pub fn destroy(&self, time_usec: u64, seat: &Rc<WlSeatGlobal>) {
{
let inner = &mut *self.inner.borrow_mut();
let state = &mut *self.state.borrow_mut();
let sm = &state.map.state_machine;
while let Some(key) = inner.pressed_keys.pop() {
sm.handle_key(
&mut state.state,
&mut inner.event_stash,
Keycode::from_evdev(key),
Direction::Up,
);
}
self.events.append(&mut inner.event_stash);
}
self.flush(time_usec, seat);
}
}