lesavka/client/src/input/mouse.rs

88 lines
3.0 KiB
Rust
Raw Normal View History

2025-06-08 22:24:14 -05:00
// client/src/input/mouse.rs
2025-06-17 20:54:31 -05:00
use evdev::{Device, EventType, InputEvent, KeyCode, RelativeAxisCode};
use tokio::sync::broadcast::{self, Sender};
use tracing::{debug, error, warn};
2025-06-15 22:33:44 -05:00
2025-06-17 08:17:23 -05:00
use navka_common::navka::MouseReport;
2025-06-08 22:24:14 -05:00
pub struct MouseAggregator {
dev: Device,
2025-06-17 20:54:31 -05:00
tx: Sender<MouseReport>,
dev_mode: bool,
buttons: u8,
2025-06-16 20:40:03 -05:00
last_buttons: u8,
2025-06-17 20:54:31 -05:00
dx: i8,
dy: i8,
wheel: i8,
2025-06-08 22:24:14 -05:00
}
impl MouseAggregator {
2025-06-17 08:17:23 -05:00
pub fn new(dev: Device, dev_mode: bool, tx: Sender<MouseReport>) -> Self {
Self { dev, tx, dev_mode, buttons:0, last_buttons:0, dx:0, dy:0, wheel:0 }
2025-06-12 01:48:48 -05:00
}
2025-06-17 20:54:31 -05:00
#[inline] fn slog(&self, f: impl FnOnce()) { if self.dev_mode { f() } }
2025-06-08 22:24:14 -05:00
pub fn process_events(&mut self) {
2025-06-17 20:54:31 -05:00
let result = self.dev.fetch_events();
let evts: Vec<InputEvent> = match result {
2025-06-11 00:37:01 -05:00
Ok(it) => it.collect(),
2025-06-17 20:54:31 -05:00
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => return,
Err(e) => { if self.dev_mode { error!("mouse read err: {e}"); } return }
2025-06-11 00:37:01 -05:00
};
2025-06-17 20:54:31 -05:00
if self.dev_mode && !evts.is_empty() {
debug!("🖱️ {} evts from {}", evts.len(), self.dev.name().unwrap_or("?"));
2025-06-08 22:24:14 -05:00
}
2025-06-17 20:54:31 -05:00
for e in evts {
match e.event_type() {
EventType::KEY => match e.code() {
c if c == KeyCode::BTN_LEFT.0 => self.set_btn(0, e.value()),
c if c == KeyCode::BTN_RIGHT.0 => self.set_btn(1, e.value()),
c if c == KeyCode::BTN_MIDDLE.0 => self.set_btn(2, e.value()),
2025-06-15 20:19:27 -05:00
_ => {}
},
2025-06-17 20:54:31 -05:00
EventType::RELATIVE => match e.code() {
c if c == RelativeAxisCode::REL_X.0 =>
self.dx = self.dx.saturating_add(e.value().clamp(-127,127) as i8),
c if c == RelativeAxisCode::REL_Y.0 =>
self.dy = self.dy.saturating_add(e.value().clamp(-127,127) as i8),
c if c == RelativeAxisCode::REL_WHEEL.0 =>
self.wheel = self.wheel.saturating_add(e.value().clamp(-1,1) as i8),
_ => {}
},
2025-06-17 20:54:31 -05:00
EventType::SYNCHRONIZATION => self.flush(),
_ => {}
2025-06-08 22:24:14 -05:00
}
}
}
2025-06-17 20:54:31 -05:00
fn flush(&mut self) {
if self.dx==0 && self.dy==0 && self.wheel==0 && self.buttons==self.last_buttons {
2025-06-16 20:40:03 -05:00
return;
}
2025-06-15 20:19:27 -05:00
2025-06-17 20:54:31 -05:00
let pkt = [
self.buttons,
2025-06-17 20:54:31 -05:00
self.dx.clamp(-127,127) as u8,
self.dy.clamp(-127,127) as u8,
self.wheel as u8,
];
2025-06-17 20:54:31 -05:00
if let Err(broadcast::error::SendError(_)) =
self.tx.send(MouseReport { data: pkt.to_vec() })
{ if self.dev_mode { warn!("❌ no HID receiver (mouse)"); } }
else if self.dev_mode { debug!("📤 mouse {:?}", pkt) }
2025-06-17 20:54:31 -05:00
self.dx=0; self.dy=0; self.wheel=0; self.last_buttons=self.buttons;
}
#[inline] fn set_btn(&mut self, bit: u8, val: i32) {
if val!=0 { self.buttons |= 1<<bit } else { self.buttons &= !(1<<bit) }
2025-06-15 21:39:07 -05:00
}
2025-06-08 22:24:14 -05:00
}
2025-06-17 20:54:31 -05:00