kernel/device/input/
event_device.rs1extern crate alloc;
7
8use alloc::collections::VecDeque;
9use alloc::string::String;
10use core::any::Any;
11use core::sync::atomic::{AtomicUsize, Ordering};
12use spin::Mutex;
13
14static KEYBOARD_COUNTER: AtomicUsize = AtomicUsize::new(0);
16static MOUSE_COUNTER: AtomicUsize = AtomicUsize::new(0);
17static TABLET_COUNTER: AtomicUsize = AtomicUsize::new(0);
18static INPUT_COUNTER: AtomicUsize = AtomicUsize::new(0);
19
20use crate::arch::Trapframe;
21use crate::device::char::CharDevice;
22use crate::device::{Device, DeviceType};
23use crate::object::capability::selectable::{
24 ReadyInterest, ReadySet, SelectWaitOutcome, Selectable,
25};
26use crate::object::capability::{ControlOps, MemoryMappingOps};
27use crate::sync::Waker;
28
29use super::InputEvent;
30
31const EVENT_QUEUE_CAPACITY: usize = 64;
33
34pub struct EventDevice {
40 name: String,
42 queue: Mutex<VecDeque<InputEvent>>,
44 waker: Waker,
46 nonblocking: Mutex<bool>,
48}
49
50impl EventDevice {
51 pub fn new(device_type: &str) -> Self {
64 let id = match device_type {
66 "keyboard" => KEYBOARD_COUNTER.fetch_add(1, Ordering::SeqCst),
67 "mouse" => MOUSE_COUNTER.fetch_add(1, Ordering::SeqCst),
68 "tablet" => TABLET_COUNTER.fetch_add(1, Ordering::SeqCst),
69 _ => INPUT_COUNTER.fetch_add(1, Ordering::SeqCst),
70 };
71
72 let name = alloc::format!("{}{}", device_type, id);
74
75 let waker_name = alloc::format!("event_{}", name).leak();
77
78 Self {
79 name,
80 queue: Mutex::new(VecDeque::with_capacity(EVENT_QUEUE_CAPACITY)),
81 waker: Waker::new_interruptible(waker_name),
82 nonblocking: Mutex::new(false),
83 }
84 }
85
86 pub fn get_name(&self) -> &str {
92 &self.name
93 }
94
95 pub fn push_event(&self, type_: u16, code: u16, value: i32) {
116 let event = InputEvent::new(type_, code, value);
117
118 {
119 let mut q = self.queue.lock();
120
121 if q.len() >= EVENT_QUEUE_CAPACITY {
123 q.pop_front();
124 }
125
126 q.push_back(event);
127 }
128
129 self.waker.wake_one();
131 }
132
133 fn has_events(&self) -> bool {
135 !self.queue.lock().is_empty()
136 }
137}
138
139impl Device for EventDevice {
141 fn device_type(&self) -> DeviceType {
142 DeviceType::Char
143 }
144
145 fn name(&self) -> &'static str {
146 "event_device"
147 }
148
149 fn as_any(&self) -> &dyn Any {
150 self
151 }
152
153 fn as_any_mut(&mut self) -> &mut dyn Any {
154 self
155 }
156
157 fn as_char_device(&self) -> Option<&dyn CharDevice> {
158 Some(self)
159 }
160}
161
162impl CharDevice for EventDevice {
164 fn read_byte(&self) -> Option<u8> {
165 None
168 }
169
170 fn read(&self, buffer: &mut [u8]) -> usize {
171 let event_size = InputEvent::size();
172
173 if buffer.len() < event_size {
175 return 0;
176 }
177
178 {
180 let mut q = self.queue.lock();
181 if let Some(event) = q.pop_front() {
182 let bytes = unsafe {
184 core::slice::from_raw_parts(&event as *const _ as *const u8, event_size)
185 };
186
187 buffer[..event_size].copy_from_slice(bytes);
188 return event_size;
189 }
190 }
191
192 if *self.nonblocking.lock() {
194 return 0;
196 }
197
198 use crate::task::mytask;
200
201 if let Some(task) = mytask() {
202 self.waker.wait(task.get_id(), task.get_trapframe());
203
204 let mut q = self.queue.lock();
206 if let Some(event) = q.pop_front() {
207 let bytes = unsafe {
208 core::slice::from_raw_parts(&event as *const _ as *const u8, event_size)
209 };
210 buffer[..event_size].copy_from_slice(bytes);
211 return event_size;
212 }
213 }
214
215 0
217 }
218
219 fn read_at(&self, _offset: u64, buffer: &mut [u8]) -> Result<usize, &'static str> {
220 Ok(self.read(buffer))
222 }
223
224 fn write_byte(&self, _byte: u8) -> Result<(), &'static str> {
225 Err("Write not supported on input event device")
226 }
227
228 fn can_read(&self) -> bool {
229 self.has_events()
230 }
231
232 fn can_write(&self) -> bool {
233 false
234 }
235}
236
237impl Selectable for EventDevice {
239 fn current_ready(&self, interest: ReadyInterest) -> ReadySet {
240 let mut set = ReadySet::none();
241
242 if interest.read {
243 set.read = self.has_events();
244 }
245
246 set.write = false;
248
249 set
250 }
251
252 fn wait_until_ready(
253 &self,
254 interest: ReadyInterest,
255 trapframe: &mut Trapframe,
256 timeout_ticks: Option<u64>,
257 ) -> SelectWaitOutcome {
258 if !interest.read {
260 return SelectWaitOutcome::Ready;
261 }
262
263 if self.has_events() {
265 return SelectWaitOutcome::Ready;
266 }
267
268 if *self.nonblocking.lock() {
270 return SelectWaitOutcome::Ready;
271 }
272
273 if timeout_ticks.is_some() {
279 SelectWaitOutcome::TimedOut
281 } else {
282 SelectWaitOutcome::Ready
287 }
288 }
289
290 fn set_nonblocking(&self, enabled: bool) {
291 *self.nonblocking.lock() = enabled;
292 }
293
294 fn is_nonblocking(&self) -> bool {
295 *self.nonblocking.lock()
296 }
297}
298
299impl ControlOps for EventDevice {}
301impl MemoryMappingOps for EventDevice {
302 fn get_mapping_info(
303 &self,
304 _offset: usize,
305 _length: usize,
306 ) -> Result<(usize, usize, bool), &'static str> {
307 Err("Memory mapping not supported for input event devices")
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use super::*;
314 use crate::device::input::event_types::*;
315 use crate::device::input::rel_codes::*;
316 use alloc::string::ToString;
317
318 #[test_case]
319 fn test_event_device_creation() {
320 let dev = EventDevice::new("input");
321 assert!(dev.name.starts_with("input"));
323 assert!(!dev.has_events());
324 }
325
326 #[test_case]
327 fn test_push_and_read_event() {
328 let dev = EventDevice::new("input");
329
330 dev.push_event(EV_REL, REL_X, 10);
332
333 assert!(dev.has_events());
335
336 let mut buffer = [0u8; InputEvent::size()];
338 let bytes_read = dev.read_at(0, &mut buffer).unwrap();
339
340 assert_eq!(bytes_read, InputEvent::size());
341
342 let event = unsafe { core::ptr::read(buffer.as_ptr() as *const InputEvent) };
343
344 assert_eq!(event.type_, EV_REL);
345 assert_eq!(event.code, REL_X);
346 assert_eq!(event.value, 10);
347
348 assert!(!dev.has_events());
350 }
351
352 #[test_case]
353 fn test_queue_overflow() {
354 let dev = EventDevice::new("input");
355
356 for i in 0..(EVENT_QUEUE_CAPACITY + 10) {
358 dev.push_event(EV_KEY, 0, i as i32);
359 }
360
361 assert_eq!(dev.queue.lock().len(), EVENT_QUEUE_CAPACITY);
363
364 let mut buffer = [0u8; InputEvent::size()];
366 dev.read_at(0, &mut buffer).unwrap();
367
368 let event = unsafe { core::ptr::read(buffer.as_ptr() as *const InputEvent) };
369
370 assert_eq!(event.value, 10);
371 }
372}