mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-17 06:47:49 +00:00
Implement a ScancodeStream type
This commit is contained in:
@@ -1,4 +1,47 @@
|
||||
use conquer_once::spin::OnceCell;
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use futures_util::stream::{Stream, StreamExt};
|
||||
use core::{pin::Pin, task::{Context, Poll}};
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
use crate::print;
|
||||
|
||||
static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();
|
||||
|
||||
pub struct ScancodeStream;
|
||||
|
||||
impl ScancodeStream {
|
||||
pub fn new() -> Self {
|
||||
SCANCODE_QUEUE.try_init_once(|| ArrayQueue::new(100))
|
||||
.expect("ScancodeStream::new should only be called once");
|
||||
ScancodeStream
|
||||
}
|
||||
|
||||
pub async fn print_keypresses(mut self) {
|
||||
let mut keyboard = Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore);
|
||||
|
||||
while let Some(scancode) = self.next().await {
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||
match key {
|
||||
DecodedKey::Unicode(character) => print!("{}", character),
|
||||
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for ScancodeStream {
|
||||
type Item = u8;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, context: &mut Context) -> Poll<Option<u8>> {
|
||||
let queue = SCANCODE_QUEUE
|
||||
.try_get()
|
||||
.expect("scancode queue not initialized");
|
||||
match queue.pop() {
|
||||
Ok(scancode) => Poll::Ready(Some(scancode)),
|
||||
Err(crossbeam_queue::PopError) => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user