Files
2026-01-14 08:58:46 +02:00

157 lines
3.7 KiB
Rust

#![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<Result<(), Error>> {
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<usize, Error> {
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<usize, Error> {
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<usize, Error> {
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<usize, Error> {
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<Result<(), Error>> {
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<usize, Error> {
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<usize, Error> {
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<usize, Error> {
let _ = option;
let _ = buffer;
let _ = len;
Err(Error::InvalidOperation)
}
fn is_terminal(&self) -> bool {
false
}
}
static KEYBOARD_INPUT_QUEUE: LossyRingQueue<KeyboardKeyEvent> = LossyRingQueue::with_capacity(32);
static MOUSE_INPUT_QUEUE: LossyRingQueue<MouseEvent> = LossyRingQueue::with_capacity(64);
static KEYBOARD_DEVICE: OneTimeInit<Arc<KeyboardDevice>> = OneTimeInit::new();
static MOUSE_DEVICE: OneTimeInit<Arc<MouseDevice>> = OneTimeInit::new();
pub fn setup_keyboard() -> Arc<KeyboardDevice> {
KEYBOARD_DEVICE
.or_init_with(|| Arc::new(KeyboardDevice))
.clone()
}
pub fn setup_mouse() -> Arc<MouseDevice> {
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);
}