/ src / task / keyboard.rs
keyboard.rs
 1  use conquer_once::spin::OnceCell;
 2  use crossbeam_queue::ArrayQueue;
 3  use crate::println;
 4  use core::{pin::Pin, task::{Context, Poll}};
 5  use futures_util::stream::Stream;
 6  use futures_util::task::AtomicWaker;
 7  use futures_util::stream::StreamExt;
 8  use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
 9  use crate::print;
10  
11  static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();
12  
13  pub(crate) fn add_scancode(scancode: u8) {
14      if let Ok(queue) = SCANCODE_QUEUE.try_get() {
15          if let Err(_) = queue.push(scancode) {
16              println!("WARNING: scancode queue full; dropping keyboard input");
17          } else {
18              WAKER.wake();
19          }
20      } else {
21          println!("WARNING: scancode queue uninitialized");
22      }
23  }
24  
25  static WAKER: AtomicWaker = AtomicWaker::new();
26  
27  pub struct ScancodeStream {
28      _private: (),
29  }
30  
31  impl ScancodeStream {
32      pub fn new() -> Self {
33          SCANCODE_QUEUE.try_init_once(|| ArrayQueue::new(100))
34              .expect("ScancodeStream::new should only be called once");
35          ScancodeStream { _private: () }
36      }
37  }
38  
39  impl Stream for ScancodeStream {
40      type Item = u8;
41  
42      fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<u8>> {
43          let queue = SCANCODE_QUEUE
44              .try_get()
45              .expect("scancode queue not initialized");
46  
47          if let Some(scancode) = queue.pop() {
48              return Poll::Ready(Some(scancode));
49          }
50  
51          WAKER.register(&cx.waker());
52          match queue.pop() {
53              Some(scancode) => {
54                  WAKER.take();
55                  Poll::Ready(Some(scancode))
56              }
57              None => Poll::Pending,
58          }     
59      }
60  }
61  
62  pub async fn print_keypresses() {
63      let mut scancodes = ScancodeStream::new();
64      let mut keyboard = Keyboard::new(ScancodeSet1::new(),
65      layouts::Us104Key, HandleControl::Ignore);
66  
67      while let Some(scancode) = scancodes.next().await {
68          if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
69              if let Some(key) = keyboard.process_keyevent(key_event) {
70                  match key {
71                      DecodedKey::Unicode(character) => print!("{}", character),
72                      DecodedKey::RawKey(key) => print!("{:?}", key),
73                  }
74              }
75          }
76      }
77  }