poppin/kernel/src/std/input.rs
2024-09-02 17:51:10 +03:00

48 lines
1.4 KiB
Rust

use alloc::collections::{btree_set::BTreeSet, vec_deque::VecDeque};
use pc_keyboard::{KeyCode, KeyEvent, KeyState};
use spin::Mutex;
use crate::events::{Event, EVENTMAN};
static mut KEYS_PRESSED: Mutex<BTreeSet<KeyCode>> = Mutex::new(BTreeSet::new());
static mut KEY_BUF: VecDeque<KeyEvent> = VecDeque::new();
const KEY_BUF_MAX_LEN: usize = 32;
pub(super) unsafe fn init() {
EVENTMAN.lock().add_listener(crate::events::Event::Ps2KeyEvent(None), |e| {
let Event::Ps2KeyEvent(ke) = e else {panic!()};
if let Some(ke) = ke {
if KEY_BUF.len() > KEY_BUF_MAX_LEN {
KEY_BUF.pop_front();
}
KEY_BUF.push_back(ke.clone());
}
Ok(())
})
}
// TODO: It is possible for `KEY_BUF` to get overfilled and lose data and make keys stuck.
// Possibly run this every now an again somehow
unsafe fn process_events() {
while !KEY_BUF.is_empty() {
if let Some(ke) = KEY_BUF.pop_front() {
match ke.state {
KeyState::Down => {
KEYS_PRESSED.lock().insert(ke.code);
}
KeyState::Up => {
KEYS_PRESSED.lock().remove(&ke.code);
}
_ => ()
}
}
}
}
pub fn is_key_down(key: KeyCode) -> bool {
unsafe {
process_events();
return KEYS_PRESSED.lock().contains(&key);
}
}