// client/src/input/mouse.rs use evdev::{Device, InputEvent, EventType, RelativeAxisCode}; use tracing::error; /// Aggregator for a single mouse device pub struct MouseAggregator { dev: Device, tx: Sender, buttons: u8, dx: i8, dy: i8, wheel: i8, } impl MouseAggregator { pub fn new(dev: Device) -> Self { Self { dev, dx: 0, dy: 0, } } pub fn process_events(&mut self) { let events_vec: Vec = match self.dev.fetch_events() { Ok(it) => it.collect(), Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { return; } Err(e) => { error!("Mouse device read error: {e}"); return; } }; for ev in events_vec { self.handle_event(ev); } } fn handle_event(&mut self, ev: InputEvent) { match ev.event_type() { EventType::RELATIVE => { /* fill dx/dy/wheel as i8 */ } EventType::KEY => { // buttons are REPORTED as KEYS (BTN_LEFT…) let pressed = ev.value() != 0; match ev.code() { c if c == KeyCode::BTN_LEFT.0 => self.set_btn(0, pressed), c if c == KeyCode::BTN_RIGHT.0 => self.set_btn(1, pressed), c if c == KeyCode::BTN_MIDDLE.0=> self.set_btn(2, pressed), _ => {} } } _ => {} } // whenever we changed something, emit: let rep = [self.buttons, self.dx as u8, self.dy as u8, self.wheel as u8]; let _ = self.tx.try_send(HidReport { kind: Some(navka_common::navka::hid_report::Kind::MouseReport(rep.to_vec())), }); // reset deltas so we send *relative* movement self.dx = 0; self.dy = 0; self.wheel = 0; } }