asterinas/kernel/comps/input/src/lib.rs

130 lines
3.5 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
//! The input devices of Asterinas.
//!
//! This crate provides a comprehensive input subsystem for handling various input devices,
//! including keyboards, mice, etc. It implements an event-driven architecture similar to
//! the Linux input subsystem.
//!
//! # Architecture
//!
//! ```text
//! Input Device → Input Core → Input Handler
//! ↓ ↓ ↓
//! Hardware Event Router Event Consumer
//! (e.g., evdev)
//! ```
//!
//! # Example Usage
//!
//! ```
//! // Register an input device
//! let device = Arc::new(MyInputDevice::new());
//! let registered_device = input::register_device(device);
//!
//! // Register an input handler
//! let handler = Arc::new(MyInputHandler::new());
//! input::register_handler(handler);
//!
//! // Submit a key event from device
//! let key_event = InputEvent::from_key_and_status(linux_key, key_status);
//! registered_device.submit_events(&[key_event]);
//! ```
//!
#![no_std]
#![deny(unsafe_code)]
extern crate alloc;
pub mod event_type_codes;
mod input_core;
pub mod input_dev;
pub mod input_handler;
use alloc::{sync::Arc, vec::Vec};
use component::{ComponentInitError, init_component};
use ostd::sync::Mutex;
use spin::Once;
use self::input_core::InputCore;
use crate::{
input_dev::{InputDevice, RegisteredInputDevice},
input_handler::{InputHandlerClass, RegisteredInputHandlerClass},
};
/// Registers a handler class.
pub fn register_handler_class(
handler_class: Arc<dyn InputHandlerClass>,
) -> RegisteredInputHandlerClass {
let component = COMPONENT.get().unwrap();
component
.input_core
.lock()
.register_handler_class(handler_class.clone());
RegisteredInputHandlerClass(handler_class)
}
/// Unregisters a handler class.
pub(crate) fn unregister_handler_class(
handler_class: &Arc<dyn InputHandlerClass>,
) -> Option<Arc<dyn InputHandlerClass>> {
let component = COMPONENT.get().unwrap();
component
.input_core
.lock()
.unregister_handler_class(handler_class)
}
/// Registers an input device.
pub fn register_device(device: Arc<dyn InputDevice>) -> RegisteredInputDevice {
let component = COMPONENT.get().unwrap();
component.input_core.lock().register_device(device)
}
/// Unregisters an input device.
pub(crate) fn unregister_device(device: &Arc<dyn InputDevice>) -> Option<Arc<dyn InputDevice>> {
let component = COMPONENT.get().unwrap();
component.input_core.lock().unregister_device(device)
}
/// Counts the number of registered devices.
pub fn count_devices() -> usize {
let component = COMPONENT.get().unwrap();
component.input_core.lock().count_devices()
}
/// Counts the number of registered handler classes.
pub fn count_handler_class() -> usize {
let component = COMPONENT.get().unwrap();
component.input_core.lock().count_handler_class()
}
/// Gets all registered devices.
pub fn all_devices() -> Vec<Arc<dyn InputDevice>> {
let component = COMPONENT.get().unwrap();
component.input_core.lock().all_devices()
}
static COMPONENT: Once<Component> = Once::new();
#[init_component]
fn component_init() -> Result<(), ComponentInitError> {
let component = Component::init()?;
COMPONENT.call_once(|| component);
Ok(())
}
#[derive(Debug)]
struct Component {
input_core: Mutex<InputCore>,
}
impl Component {
pub fn init() -> Result<Self, ComponentInitError> {
Ok(Self {
input_core: Mutex::new(InputCore::new()),
})
}
}