#![no_std] extern crate alloc; use core::task::{Context, Poll}; use alloc::{boxed::Box, sync::Arc}; use async_trait::async_trait; use device_api::device::Device; use libk::{device::char::CharDevice, vfs::FileReadiness}; use libk_util::{OneTimeInit, ring::LossyRingQueue}; use yggdrasil_abi::{ error::Error, io::{KeyboardKeyEvent, MouseEvent}, }; #[derive(Clone, Copy)] pub struct KeyboardDevice; #[derive(Clone, Copy)] pub struct MouseDevice; impl FileReadiness for KeyboardDevice { fn poll_read(&self, cx: &mut Context<'_>) -> Poll> { KEYBOARD_INPUT_QUEUE.poll_readable(cx).map(Ok) } } impl Device for KeyboardDevice { fn display_name(&self) -> &str { "Keyboard input pseudo-device" } } #[async_trait] impl CharDevice for KeyboardDevice { async fn read(&self, buf: &mut [u8]) -> Result { if buf.len() < 4 { return Ok(0); } let ev = KEYBOARD_INPUT_QUEUE.read().await; buf[..4].copy_from_slice(&ev.as_bytes()); Ok(4) } fn read_nonblocking(&self, buf: &mut [u8]) -> Result { if buf.len() < 4 { return Ok(0); } let ev = KEYBOARD_INPUT_QUEUE.try_read().ok_or(Error::WouldBlock)?; buf[..4].copy_from_slice(&ev.as_bytes()); Ok(4) } fn is_writeable(&self) -> bool { false } fn device_request(&self, option: u32, buffer: &mut [u8], len: usize) -> Result { let _ = option; let _ = buffer; let _ = len; Err(Error::InvalidOperation) } fn is_terminal(&self) -> bool { false } } impl MouseDevice { fn write_report(buf: &mut [u8], report: &MouseEvent) -> Result { buf[0] = report.dx as u8; buf[1] = report.dy as u8; buf[2] = report.buttons; buf[3] = 0; Ok(4) } } impl FileReadiness for MouseDevice { fn poll_read(&self, cx: &mut Context<'_>) -> Poll> { MOUSE_INPUT_QUEUE.poll_readable(cx).map(Ok) } } impl Device for MouseDevice { fn display_name(&self) -> &str { "Mouse input pseudo-device" } } #[async_trait] impl CharDevice for MouseDevice { async fn read(&self, buf: &mut [u8]) -> Result { if buf.len() < 4 { return Ok(0); } let ev = MOUSE_INPUT_QUEUE.read().await; Self::write_report(buf, &ev) } fn read_nonblocking(&self, buf: &mut [u8]) -> Result { if buf.len() < 4 { return Ok(0); } let ev = MOUSE_INPUT_QUEUE.try_read().ok_or(Error::WouldBlock)?; Self::write_report(buf, &ev) } fn is_writeable(&self) -> bool { false } fn device_request(&self, option: u32, buffer: &mut [u8], len: usize) -> Result { let _ = option; let _ = buffer; let _ = len; Err(Error::InvalidOperation) } fn is_terminal(&self) -> bool { false } } static KEYBOARD_INPUT_QUEUE: LossyRingQueue = LossyRingQueue::with_capacity(32); static MOUSE_INPUT_QUEUE: LossyRingQueue = LossyRingQueue::with_capacity(64); static KEYBOARD_DEVICE: OneTimeInit> = OneTimeInit::new(); static MOUSE_DEVICE: OneTimeInit> = OneTimeInit::new(); pub fn setup_keyboard() -> Arc { KEYBOARD_DEVICE .or_init_with(|| Arc::new(KeyboardDevice)) .clone() } pub fn setup_mouse() -> Arc { MOUSE_DEVICE.or_init_with(|| Arc::new(MouseDevice)).clone() } pub fn send_mouse_event(ev: MouseEvent) { MOUSE_INPUT_QUEUE.write(ev); } pub fn send_keyboard_event(ev: KeyboardKeyEvent) { KEYBOARD_INPUT_QUEUE.write(ev); }