kernel/device/input/
event_device.rs

1//! Event device implementation for input events
2//!
3//! This module provides an event device that implements the CharDevice trait
4//! for handling input events from keyboards, mice, touchscreens, etc.
5
6extern 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
14/// Static counters for device naming
15static 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
31/// Maximum number of events to buffer
32const EVENT_QUEUE_CAPACITY: usize = 64;
33
34/// Event device for input handling
35///
36/// This device provides a character device interface for reading input events.
37/// Events are buffered in a ring buffer and can be read by user space through
38/// standard read operations on the device file (e.g., /dev/input0).
39pub struct EventDevice {
40    /// Device name (e.g., "input0")
41    name: String,
42    /// Event queue (ring buffer)
43    queue: Mutex<VecDeque<InputEvent>>,
44    /// Waker for blocking reads
45    waker: Waker,
46    /// Non-blocking mode flag
47    nonblocking: Mutex<bool>,
48}
49
50impl EventDevice {
51    /// Create a new event device
52    ///
53    /// # Arguments
54    ///
55    /// * `device_type` - Device type ("keyboard", "mouse", "tablet", or "input")
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// let event_dev = Arc::new(EventDevice::new("keyboard"));
61    /// DeviceManager::get_manager().register_device(event_dev);
62    /// ```
63    pub fn new(device_type: &str) -> Self {
64        // Get incremented ID based on device type
65        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        // Generate device name
73        let name = alloc::format!("{}{}", device_type, id);
74
75        // Create a unique waker name based on the device name
76        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    /// Get the device name
87    ///
88    /// # Returns
89    ///
90    /// The device name (e.g., "keyboard0", "mouse0")
91    pub fn get_name(&self) -> &str {
92        &self.name
93    }
94
95    /// Push an input event into the queue
96    ///
97    /// This method should be called from interrupt handlers or device drivers
98    /// when a new input event occurs. If the queue is full, the oldest event
99    /// is dropped to make room for the new one.
100    ///
101    /// # Arguments
102    ///
103    /// * `type_` - Event type (EV_KEY, EV_REL, etc.)
104    /// * `code` - Event code (KEY_A, REL_X, etc.)
105    /// * `value` - Event value (1/0 for keys, movement delta, etc.)
106    ///
107    /// # Examples
108    ///
109    /// ```
110    /// // In a mouse driver interrupt handler
111    /// event_dev.push_event(EV_REL, REL_X, mouse_dx);
112    /// event_dev.push_event(EV_REL, REL_Y, mouse_dy);
113    /// event_dev.push_event(EV_SYN, SYN_REPORT, 0);
114    /// ```
115    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 queue is full, drop the oldest event
122            if q.len() >= EVENT_QUEUE_CAPACITY {
123                q.pop_front();
124            }
125
126            q.push_back(event);
127        }
128
129        // Wake up any waiting tasks
130        self.waker.wake_one();
131    }
132
133    /// Check if there are events available to read
134    fn has_events(&self) -> bool {
135        !self.queue.lock().is_empty()
136    }
137}
138
139// Implement Device trait for device registration
140impl 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
162// Implement CharDevice trait for character device operations
163impl CharDevice for EventDevice {
164    fn read_byte(&self) -> Option<u8> {
165        // Not suitable for byte-by-byte reading.
166        // Events should be read as complete InputEvent structures.
167        None
168    }
169
170    fn read(&self, buffer: &mut [u8]) -> usize {
171        let event_size = InputEvent::size();
172
173        // Buffer must be large enough to hold at least one event
174        if buffer.len() < event_size {
175            return 0;
176        }
177
178        // Try to read one event
179        {
180            let mut q = self.queue.lock();
181            if let Some(event) = q.pop_front() {
182                // Convert event structure to bytes
183                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        // No data available - check nonblocking mode
193        if *self.nonblocking.lock() {
194            // In non-blocking mode, return immediately with 0 bytes
195            return 0;
196        }
197
198        // In blocking mode, wait for data using waker
199        use crate::task::mytask;
200
201        if let Some(task) = mytask() {
202            self.waker.wait(task.get_id(), task.get_trapframe());
203
204            // After waking up, try to read again
205            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        // No task context or spurious wakeup
216        0
217    }
218
219    fn read_at(&self, _offset: u64, buffer: &mut [u8]) -> Result<usize, &'static str> {
220        // Delegate to read() which implements blocking
221        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
237// Implement Selectable trait for poll/select support
238impl 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        // Write is never ready for input devices
247        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        // Only support read interest
259        if !interest.read {
260            return SelectWaitOutcome::Ready;
261        }
262
263        // If data is already available, return immediately
264        if self.has_events() {
265            return SelectWaitOutcome::Ready;
266        }
267
268        // If in non-blocking mode, don't wait
269        if *self.nonblocking.lock() {
270            return SelectWaitOutcome::Ready;
271        }
272
273        // Block until data arrives or timeout
274        // Note: Current implementation doesn't support blocking in this context
275        // because Waker::wait() requires task context that we don't have here.
276        // For proper blocking behavior, the VFS layer should handle this.
277        // For now, return Ready to avoid blocking the caller.
278        if timeout_ticks.is_some() {
279            // TODO: Implement timeout support when Waker supports it
280            SelectWaitOutcome::TimedOut
281        } else {
282            // TODO: Properly implement blocking wait
283            // self.waker.wait() requires current_task_id and trapframe
284            // which are not available in this context.
285            // For now, return Ready immediately.
286            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
299// Implement required trait bounds for Device
300impl 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        // Device name should be "input" + counter (e.g., "input0", "input1", etc.)
322        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        // Push an event
331        dev.push_event(EV_REL, REL_X, 10);
332
333        // Should have events now
334        assert!(dev.has_events());
335
336        // Read the event
337        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        // Should have no more events
349        assert!(!dev.has_events());
350    }
351
352    #[test_case]
353    fn test_queue_overflow() {
354        let dev = EventDevice::new("input");
355
356        // Fill the queue beyond capacity
357        for i in 0..(EVENT_QUEUE_CAPACITY + 10) {
358            dev.push_event(EV_KEY, 0, i as i32);
359        }
360
361        // Queue should be at capacity
362        assert_eq!(dev.queue.lock().len(), EVENT_QUEUE_CAPACITY);
363
364        // Read first event - should be event #10 (first 10 were dropped)
365        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}