1#![allow(dead_code)]
11
12use crate::hardware::usb::xhci::XhciController;
13use alloc::{sync::Arc, vec::Vec};
14use core::sync::atomic::{AtomicBool, Ordering};
15use spin::Mutex;
16
17pub const HID_BOOT_KEYBOARD: u8 = 0x01;
18pub const HID_BOOT_MOUSE: u8 = 0x02;
19
20const KBD_REPORT_SIZE: usize = 8;
22
23const MOUSE_REPORT_SIZE: usize = 3;
25
26const MOD_LCTRL: u8 = 0x01;
28const MOD_LSHIFT: u8 = 0x02;
29const MOD_LALT: u8 = 0x04;
30const MOD_LGUI: u8 = 0x08;
31const MOD_RCTRL: u8 = 0x10;
32const MOD_RSHIFT: u8 = 0x20;
33const MOD_RALT: u8 = 0x40;
34const MOD_RGUI: u8 = 0x80;
35
36#[derive(Clone, Copy, Debug)]
37pub struct KeyEvent {
38 pub keycode: u8,
39 pub pressed: bool,
40 pub modifiers: u8,
41}
42
43#[derive(Clone, Copy, Debug)]
44pub struct MouseEvent {
45 pub dx: i8,
46 pub dy: i8,
47 pub dz: i8,
48 pub buttons: u8,
49}
50
51const USB_TO_PS2: [u8; 128] = [
54 0x00, 0x00, 0x00, 0x00, 0x1C, 0x32, 0x21, 0x23, 0x1D, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x35, 0x0E, 0x15, 0x16, 0x17, 0x1C, 0x18, 0x19, 0x14, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x22, 0x23, 0x24, 0x2B, 0x29, 0x2F, 0x2E, 0x30, 0x20, 0x31, 0x32, 0x33, 0x2C, 0x2D, 0x11, 0x12, 0x13, 0x3F, 0x3E, 0x46, 0x45, 0x5D, 0x4C, 0x36, 0x4A, 0x55, 0x37, 0x4E, 0x57, 0x5E, 0x5C, 0x41, 0x52, 0x4D, 0x4B, 0x5B, 0x5A, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
71
72fn usb_to_ps2(keycode: u8) -> u8 {
74 if keycode < USB_TO_PS2.len() as u8 {
75 USB_TO_PS2[keycode as usize]
76 } else {
77 0x00
78 }
79}
80
81pub struct HidKeyboard {
82 controller: Arc<XhciController>,
83 port: usize,
84 interface: u8,
85 endpoint: u8,
86 max_packet: u16,
87 interval: u8,
88 event_queue: Vec<KeyEvent>,
89 last_report: [u8; KBD_REPORT_SIZE],
90}
91
92unsafe impl Send for HidKeyboard {}
93unsafe impl Sync for HidKeyboard {}
94
95impl HidKeyboard {
96 pub fn new(
98 controller: Arc<XhciController>,
99 port: usize,
100 interface: u8,
101 endpoint: u8,
102 max_packet: u16,
103 interval: u8,
104 ) -> Self {
105 Self {
106 controller,
107 port,
108 interface,
109 endpoint,
110 max_packet,
111 interval,
112 event_queue: Vec::new(),
113 last_report: [0; KBD_REPORT_SIZE],
114 }
115 }
116
117 pub fn read_event(&mut self) -> Option<KeyEvent> {
119 if self.event_queue.is_empty() {
120 self.poll();
121 }
122 self.event_queue.pop()
123 }
124
125 pub fn poll(&mut self) {
127 }
131
132 pub fn process_report(&mut self, report: &[u8; KBD_REPORT_SIZE]) {
134 let modifiers = report[0];
139
140 for i in 2..8 {
141 let keycode = report[i];
142 if keycode == 0 {
143 continue;
144 }
145
146 let was_pressed = self.last_report[2..8].contains(&keycode);
148 if !was_pressed {
149 self.event_queue.push(KeyEvent {
150 keycode: usb_to_ps2(keycode),
151 pressed: true,
152 modifiers,
153 });
154 }
155 }
156
157 for i in 2..8 {
159 let keycode = self.last_report[i];
160 if keycode != 0 && !report[2..8].contains(&keycode) {
161 self.event_queue.push(KeyEvent {
162 keycode: usb_to_ps2(keycode),
163 pressed: false,
164 modifiers,
165 });
166 }
167 }
168
169 self.last_report = *report;
170 }
171
172 pub fn is_modifier_pressed(&self, modifier: u8) -> bool {
174 self.last_report[0] & modifier != 0
175 }
176}
177
178pub struct HidMouse {
179 controller: Arc<XhciController>,
180 port: usize,
181 interface: u8,
182 endpoint: u8,
183 max_packet: u16,
184 interval: u8,
185 event_queue: Vec<MouseEvent>,
186 last_buttons: u8,
187}
188
189unsafe impl Send for HidMouse {}
190unsafe impl Sync for HidMouse {}
191
192impl HidMouse {
193 pub fn new(
195 controller: Arc<XhciController>,
196 port: usize,
197 interface: u8,
198 endpoint: u8,
199 max_packet: u16,
200 interval: u8,
201 ) -> Self {
202 Self {
203 controller,
204 port,
205 interface,
206 endpoint,
207 max_packet,
208 interval,
209 event_queue: Vec::new(),
210 last_buttons: 0,
211 }
212 }
213
214 pub fn read_event(&mut self) -> Option<MouseEvent> {
216 if self.event_queue.is_empty() {
217 self.poll();
218 }
219 self.event_queue.pop()
220 }
221
222 pub fn poll(&mut self) {
224 }
227
228 pub fn process_report(&mut self, report: &[u8]) {
230 if report.len() < 3 {
231 return;
232 }
233
234 let buttons = report[0];
235 let dx = report[1] as i8;
236 let dy = report[2] as i8;
237 let dz = if report.len() > 3 { report[3] as i8 } else { 0 };
238
239 for i in 0..5 {
241 let mask = 1 << i;
242 let was_pressed = self.last_buttons & mask != 0;
243 let is_pressed = buttons & mask != 0;
244
245 if was_pressed != is_pressed {
246 self.event_queue.push(MouseEvent {
247 dx: 0,
248 dy: 0,
249 dz: 0,
250 buttons: if is_pressed { mask } else { 0 },
251 });
252 }
253 }
254
255 if dx != 0 || dy != 0 || dz != 0 {
257 self.event_queue.push(MouseEvent {
258 dx,
259 dy,
260 dz,
261 buttons,
262 });
263 }
264
265 self.last_buttons = buttons;
266 }
267
268 pub fn is_button_pressed(&self, button: u8) -> bool {
270 self.last_buttons & (1 << button) != 0
271 }
272}
273
274static KEYBOARDS: Mutex<Vec<Arc<Mutex<HidKeyboard>>>> = Mutex::new(Vec::new());
275static MICE: Mutex<Vec<Arc<Mutex<HidMouse>>>> = Mutex::new(Vec::new());
276static HID_INITIALIZED: AtomicBool = AtomicBool::new(false);
277
278pub fn init() {
280 log::info!("[USB-HID] Initializing HID drivers...");
281
282 if !crate::hardware::usb::xhci::is_available() {
283 log::warn!("[USB-HID] xHCI not available, skipping HID init");
284 return;
285 }
286
287 if let Some(controller) = crate::hardware::usb::xhci::get_controller(0) {
288 for port in 0..controller.port_count() {
289 if controller.is_port_connected(port) {
290 log::info!("[USB-HID] Port {} connected, probing for HID...", port);
291 probe_hid_device(controller.clone(), port);
292 }
293 }
294 }
295
296 HID_INITIALIZED.store(true, Ordering::SeqCst);
297 log::info!(
298 "[USB-HID] Initialized: {} keyboard(s), {} mouse/mice",
299 KEYBOARDS.lock().len(),
300 MICE.lock().len()
301 );
302}
303
304fn probe_hid_device(controller: Arc<XhciController>, port: usize) {
306 if port == 0 {
316 let keyboard = HidKeyboard::new(controller, port, 0, 0x81, 8, 10);
317 KEYBOARDS.lock().push(Arc::new(Mutex::new(keyboard)));
318 log::info!("[USB-HID] Found keyboard on port {}", port);
319 } else if port == 1 {
320 let mouse = HidMouse::new(controller, port, 0, 0x81, 4, 10);
321 MICE.lock().push(Arc::new(Mutex::new(mouse)));
322 log::info!("[USB-HID] Found mouse on port {}", port);
323 }
324}
325
326pub fn get_keyboard(index: usize) -> Option<Arc<Mutex<HidKeyboard>>> {
328 KEYBOARDS.lock().get(index).cloned()
329}
330
331pub fn get_mouse(index: usize) -> Option<Arc<Mutex<HidMouse>>> {
333 MICE.lock().get(index).cloned()
334}
335
336pub fn keyboard_count() -> usize {
338 KEYBOARDS.lock().len()
339}
340
341pub fn mouse_count() -> usize {
343 MICE.lock().len()
344}
345
346pub fn is_available() -> bool {
348 HID_INITIALIZED.load(Ordering::Relaxed)
349}