- added a new libary libm containing procedural macros for the kernel.
these should be used to include external files and resources in the kernel binary
at compile time.
- libm currently supports loading psf-1 formatted fonts
- added two fonts that are included in the binary at compile time
- refactored libk to make the crate structure more organised and maintainable in future.
new structure:
- drivers (hardware interaction)
- resources (consts and statics included either manually or via macros)
- std (standard functions for higher level interaction with the os, for example creating windows)
- added geometry.rs
- provides the Vec2<T> struct for use with dimensions, coordinates etc.
- added window.rs
- provides the Window struct for rendering the state of an application to the screen
- added application.rs
- provides the Application trait for custom programs to implement in order to run
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
use core::{
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use crossbeam::queue::ArrayQueue;
|
||||
use futures_util::{Stream, StreamExt, task::AtomicWaker};
|
||||
use pc_keyboard::{DecodedKey, HandleControl, Keyboard, ScancodeSet1, layouts};
|
||||
use spin::Once;
|
||||
|
||||
use crate::println;
|
||||
|
||||
use super::print;
|
||||
|
||||
static KBD_QUEUE: Once<ArrayQueue<u8>> = 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 {
|
||||
WAKER.wake();
|
||||
}
|
||||
} else {
|
||||
println!("WARNING: scancode queue not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
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<Option<Self::Item>> {
|
||||
let queue = KBD_QUEUE.get().unwrap();
|
||||
|
||||
if let Some(scancode) = queue.pop() {
|
||||
return Poll::Ready(Some(scancode));
|
||||
}
|
||||
|
||||
WAKER.register(&cx.waker());
|
||||
|
||||
match queue.pop() {
|
||||
Some(scancode) => {
|
||||
WAKER.take();
|
||||
Poll::Ready(Some(scancode))
|
||||
}
|
||||
None => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn print_keypresses() {
|
||||
let mut scancodes = ScancodeStream::new();
|
||||
let mut keyboard = Keyboard::new(
|
||||
ScancodeSet1::new(),
|
||||
layouts::Uk105Key,
|
||||
HandleControl::Ignore,
|
||||
);
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user