extern crate alloc; use core::{ pin::Pin, task::{Context, Poll}, }; use super::{print, println}; use crossbeam::queue::ArrayQueue; use futures_util::{task::AtomicWaker, Stream}; use spin::Once; static KBD_QUEUE: Once> = Once::new(); static WAKER: AtomicWaker = AtomicWaker::new(); pub fn add_scancode(scancode: u8) { if let Some(queue) = KBD_QUEUE.get() { if let Err(_) = queue.push(scancode) { println!("WARNING: scancode queue full; dropping keyboard input"); } else { println!("waking waker"); WAKER.wake(); } } else { println!("WARNING: scancode queue not initialised"); } } pub struct ScanCodeStream { _private: (), } impl ScanCodeStream { pub fn new() -> Self { KBD_QUEUE.call_once(|| ArrayQueue::new(5)); ScanCodeStream { _private: () } } } impl Stream for ScanCodeStream { type Item = u8; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let queue = KBD_QUEUE.get().expect("scancode queue not initialized"); print!("polling or smth"); // fast path if let Some(scancode) = queue.pop() { return Poll::Ready(Some(scancode)); } WAKER.register(&cx.waker()); match queue.pop() { Some(scancode) => { print!("scancode found"); WAKER.take(); Poll::Ready(Some(scancode)) } None => { print!("returning"); Poll::Pending } } } } use futures_util::stream::StreamExt; use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1}; pub async fn print_keypresses() { let mut scancodes = ScanCodeStream::new(); let mut keyboard = Keyboard::new( ScancodeSet1::new(), layouts::Us104Key, HandleControl::Ignore, ); println!("OK!!!"); while let Some(scancode) = scancodes.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), } } } } }