Use crossbeam-queue and AtomicWaker for async keypress handling

This commit is contained in:
Philipp Oppermann
2020-02-28 17:46:29 +01:00
parent 6329274f02
commit 786a7a6922
8 changed files with 163 additions and 22 deletions

48
src/driver/keyboard.rs Normal file
View File

@@ -0,0 +1,48 @@
use crate::{interrupts, print};
use core::future::Future;
use core::{
pin::Pin,
task::{Context, Poll},
};
use pc_keyboard::{layouts, DecodedKey, Keyboard, ScancodeSet1};
fn next_scancode() -> impl Future<Output = u8> {
NextScancode
}
struct NextScancode;
impl Future for NextScancode {
type Output = u8;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<u8> {
let scancodes = interrupts::SCANCODE_QUEUE
.try_get()
.expect("scancode queue not initialized");
// fast path
if let Ok(scancode) = scancodes.pop() {
return Poll::Ready(scancode);
}
interrupts::KEYBOARD_INTERRUPT_WAKER.register(&cx.waker());
match scancodes.pop() {
Ok(scancode) => Poll::Ready(scancode),
Err(crossbeam_queue::PopError) => Poll::Pending,
}
}
}
pub async fn print_keypresses() {
let mut keyboard = Keyboard::new(layouts::Us104Key, ScancodeSet1);
loop {
if let Ok(Some(key_event)) = keyboard.add_byte(next_scancode().await) {
if let Some(key) = keyboard.process_keyevent(key_event) {
match key {
DecodedKey::Unicode(character) => print!("{}", character),
DecodedKey::RawKey(key) => print!("{:?}", key),
}
}
}
}
}