veridian_kernel/drivers/
input_event.rs1use core::sync::atomic::{AtomicUsize, Ordering};
8
9pub const EV_KEY: u16 = 0x01;
11pub const EV_REL: u16 = 0x02;
12#[allow(dead_code)] pub const EV_ABS: u16 = 0x03;
14
15pub const REL_X: u16 = 0x00;
17pub const REL_Y: u16 = 0x01;
18
19pub const BTN_LEFT: u16 = 0x110;
21pub const BTN_RIGHT: u16 = 0x111;
22pub const BTN_MIDDLE: u16 = 0x112;
23
24#[repr(C)]
26#[derive(Debug, Clone, Copy)]
27pub struct InputEvent {
28 pub timestamp: u64,
29 pub event_type: u16,
30 pub code: u16,
31 pub value: i32,
32}
33
34impl InputEvent {
35 pub const fn key(code: u16, pressed: bool) -> Self {
36 Self {
37 timestamp: 0, event_type: EV_KEY,
39 code,
40 value: if pressed { 1 } else { 0 },
41 }
42 }
43
44 pub const fn rel(code: u16, value: i32) -> Self {
45 Self {
46 timestamp: 0,
47 event_type: EV_REL,
48 code,
49 value,
50 }
51 }
52}
53
54const EVENT_BUFFER_SIZE: usize = 256;
56
57struct EventBuffer {
58 buf: [InputEvent; EVENT_BUFFER_SIZE],
59 head: AtomicUsize,
60 tail: AtomicUsize,
61}
62
63impl EventBuffer {
64 const fn new() -> Self {
65 Self {
66 buf: [InputEvent {
67 timestamp: 0,
68 event_type: 0,
69 code: 0,
70 value: 0,
71 }; EVENT_BUFFER_SIZE],
72 head: AtomicUsize::new(0),
73 tail: AtomicUsize::new(0),
74 }
75 }
76
77 fn push(&mut self, mut event: InputEvent) {
78 event.timestamp = crate::arch::timer::read_hw_timestamp();
79 let head = self.head.load(Ordering::Relaxed);
80 let next = (head + 1) & (EVENT_BUFFER_SIZE - 1);
81 let tail = self.tail.load(Ordering::Acquire);
82 if next == tail {
83 return; }
85 self.buf[head] = event;
86 self.head.store(next, Ordering::Release);
87 }
88
89 fn pop(&self) -> Option<InputEvent> {
90 let tail = self.tail.load(Ordering::Relaxed);
91 let head = self.head.load(Ordering::Acquire);
92 if tail == head {
93 return None;
94 }
95 let event = self.buf[tail];
96 self.tail
97 .store((tail + 1) & (EVENT_BUFFER_SIZE - 1), Ordering::Release);
98 Some(event)
99 }
100}
101
102unsafe impl Send for EventBuffer {}
105unsafe impl Sync for EventBuffer {}
106
107static EVENT_BUFFER: spin::Mutex<EventBuffer> = spin::Mutex::new(EventBuffer::new());
108
109pub fn push_event(event: InputEvent) {
113 EVENT_BUFFER.lock().push(event);
114}
115
116pub fn read_event() -> Option<InputEvent> {
118 EVENT_BUFFER.lock().pop()
119}
120
121pub fn poll_all() {
125 #[cfg(target_arch = "x86_64")]
127 {
128 for _ in 0..64 {
142 let status = unsafe { crate::arch::x86_64::inb(0x64) };
144 if (status & 0x01) == 0 {
145 break; }
147 if (status & 0x20) != 0 {
148 let byte = unsafe { crate::arch::x86_64::inb(0x60) };
151 crate::drivers::mouse::poll_mouse_byte(byte);
152 } else {
153 let scancode = unsafe { crate::arch::x86_64::inb(0x60) };
156 crate::drivers::keyboard::handle_scancode(scancode);
157 }
158 }
159 }
160
161 #[cfg(target_arch = "x86_64")]
163 {
164 while let Some(key_byte) = crate::drivers::keyboard::read_key() {
165 push_event(InputEvent::key(key_byte as u16, true));
166 }
167 }
168
169 #[cfg(target_arch = "x86_64")]
171 {
172 while let Some(mouse_event) = crate::drivers::mouse::read_event() {
173 if mouse_event.dx != 0 {
175 push_event(InputEvent::rel(REL_X, mouse_event.dx as i32));
176 }
177 if mouse_event.dy != 0 {
178 push_event(InputEvent::rel(REL_Y, mouse_event.dy as i32));
179 }
180 static PREV_BUTTONS: core::sync::atomic::AtomicU8 =
182 core::sync::atomic::AtomicU8::new(0);
183 let prev = PREV_BUTTONS.load(Ordering::Relaxed);
184 let changed = mouse_event.buttons ^ prev;
185 if (changed & super::mouse::BUTTON_LEFT) != 0 {
186 push_event(InputEvent::key(
187 BTN_LEFT,
188 (mouse_event.buttons & super::mouse::BUTTON_LEFT) != 0,
189 ));
190 }
191 if (changed & super::mouse::BUTTON_RIGHT) != 0 {
192 push_event(InputEvent::key(
193 BTN_RIGHT,
194 (mouse_event.buttons & super::mouse::BUTTON_RIGHT) != 0,
195 ));
196 }
197 if (changed & super::mouse::BUTTON_MIDDLE) != 0 {
198 push_event(InputEvent::key(
199 BTN_MIDDLE,
200 (mouse_event.buttons & super::mouse::BUTTON_MIDDLE) != 0,
201 ));
202 }
203 PREV_BUTTONS.store(mouse_event.buttons, Ordering::Relaxed);
204 }
205 }
206}