From 08c5230df3a8269e06ef5ae9b91e34f215866f81 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Thu, 12 Jun 2025 01:48:48 -0500 Subject: [PATCH] rearchitechtured for multiple channels --- client/src/app.rs | 9 +++++---- client/src/input/inputs.rs | 15 ++++++--------- client/src/input/keyboard.rs | 15 +++++++++++---- client/src/input/mouse.rs | 20 +++++++++++++++++--- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/client/src/app.rs b/client/src/app.rs index 0d31304..1cc0650 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -22,7 +22,8 @@ impl NavkaClientApp { .nth(1) .or_else(|| std::env::var("NAVKA_SERVER_ADDR").ok()) .unwrap_or_else(|| "http://127.0.0.1:50051".to_owned()); - let mut aggregator = InputAggregator::new(dev_mode); + let (tx, _rx) = mpsc::channel::(64); + let mut aggregator = InputAggregator::new(dev_mode, tx); aggregator.init()?; // discover & grab Ok(Self { @@ -99,8 +100,8 @@ impl NavkaClientApp { // fresh channel for aggregator => we do this with new (tx, rx) let (tx, rx) = mpsc::channel::(64); - let mut aggregator = InputAggregator::new(dev_mode, tx.clone()); - + let _unused = InputAggregator::new(self.dev_mode, tx.clone()); // TODO: wire this up properly + let outbound = ReceiverStream::new(rx); let response = match client.stream(Request::new(outbound)).await { Ok(r) => r, @@ -116,7 +117,7 @@ impl NavkaClientApp { while let Some(res) = inbound.message().await.transpose() { match res { Ok(report) => { - tracing::debug!(?report.data, "server inbound"); + tracing::debug!(?report.kind, "server inbound"); }, Err(e) => { error!("Inbound error: {e}"); diff --git a/client/src/input/inputs.rs b/client/src/input/inputs.rs index dfb7f99..35148b1 100644 --- a/client/src/input/inputs.rs +++ b/client/src/input/inputs.rs @@ -3,7 +3,7 @@ use anyhow::{bail, Context, Result}; use evdev::{Device, EventType, KeyCode, RelativeAxisCode}; use tokio::time::{interval, Duration}; -use tokio::sync::mpsc::{self, Sender}; +use tokio::sync::mpsc::Sender; use tracing::{debug, info}; use navka_common::navka::HidReport; @@ -18,7 +18,7 @@ use crate::input::microphone::MicrophoneCapture; /// spawns specialized aggregator objects, and can also /// create stubs for camera/microphone logic if needed. pub struct InputAggregator { - tx: Sender, + tx: Sender, pub dev_mode: bool, keyboards: Vec, mice: Vec, @@ -27,8 +27,9 @@ pub struct InputAggregator { } impl InputAggregator { - pub fn new(dev_mode: bool) -> Self { + pub fn new(dev_mode: bool, tx: Sender) -> Self { Self { + tx, dev_mode, keyboards: Vec::new(), mice: Vec::new(), @@ -73,7 +74,7 @@ impl InputAggregator { // pass dev_mode to aggregator // let kbd_agg = KeyboardAggregator::new(dev, self.dev_mode); - let kbd_agg = KeyboardAggregator::new(dev.clone(), self.dev_mode, self.tx.clone()); + let kbd_agg = KeyboardAggregator::new(dev, self.dev_mode, self.tx.clone()); self.keyboards.push(kbd_agg); found_any = true; continue; @@ -83,7 +84,7 @@ impl InputAggregator { info!("Grabbed mouse {:?}", dev.name().unwrap_or("UNKNOWN")); // let mouse_agg = MouseAggregator::new(dev);np - let mouse_agg = MouseAggregator::new(dev.clone(), self.tx.clone()); + let mouse_agg = MouseAggregator::new(dev, self.tx.clone()); self.mice.push(mouse_agg); found_any = true; continue; @@ -124,10 +125,6 @@ impl InputAggregator { } } -pub fn new(dev_mode: bool, tx: Sender) -> Self { - Self { tx, dev_mode, keyboards: Vec::new(), mice: Vec::new(), camera: None, mic: None } -} - #[derive(Debug)] struct Classification { keyboard: Option<()>, diff --git a/client/src/input/keyboard.rs b/client/src/input/keyboard.rs index db19626..dd9753a 100644 --- a/client/src/input/keyboard.rs +++ b/client/src/input/keyboard.rs @@ -2,7 +2,9 @@ use std::collections::HashSet; use evdev::{Device, InputEvent, KeyCode, EventType}; +use tokio::sync::mpsc::Sender; use tracing::{warn, error, info, debug}; +use navka_common::navka::HidReport; use crate::input::keymap::{keycode_to_usage, is_modifier}; @@ -19,7 +21,7 @@ impl KeyboardAggregator { let _ = dev.set_nonblocking(true); Self { dev, - tx: Sender, + tx, dev_mode, pressed_keys: HashSet::new(), } @@ -74,6 +76,7 @@ impl KeyboardAggregator { // TODO: send this somewhere (e.g. an mpsc::Sender) // For now, just log: debug!(?report, "Keyboard HID report"); + self.send_report(report); // optional: magic chord if self.is_magic_chord() { warn!("Magic chord pressed => exit aggregator??"); @@ -104,9 +107,13 @@ impl KeyboardAggregator { bytes } - let _ = self.tx.try_send(HidReport { - kind: Some(navka_common::navka::hid_report::Kind::KeyboardReport(report.to_vec())), - }); + fn send_report(&self, report: [u8; 8]) { + let _ = self.tx.try_send(HidReport { + kind: Some(navka_common::navka::hid_report::Kind::KeyboardReport( + report.to_vec(), + )), + }); + } fn is_magic_chord(&self) -> bool { self.pressed_keys.contains(&KeyCode::KEY_LEFTCTRL) diff --git a/client/src/input/mouse.rs b/client/src/input/mouse.rs index ed747f2..6eb6491 100644 --- a/client/src/input/mouse.rs +++ b/client/src/input/mouse.rs @@ -1,7 +1,9 @@ // client/src/input/mouse.rs -use evdev::{Device, InputEvent, EventType, RelativeAxisCode}; -use tracing::error; +use evdev::{Device, InputEvent, EventType, KeyCode, RelativeAxisCode}; +use tokio::sync::mpsc::Sender; +use tracing::{error, debug}; +use navka_common::navka::HidReport; /// Aggregator for a single mouse device pub struct MouseAggregator { @@ -14,11 +16,23 @@ pub struct MouseAggregator { } impl MouseAggregator { - pub fn new(dev: Device) -> Self { + pub fn new(dev: Device, tx: Sender) -> Self { Self { dev, + tx, + buttons: 0, dx: 0, dy: 0, + wheel: 0, + } + } + + /// helper to set or clear a mouse button bit + fn set_btn(&mut self, idx: usize, pressed: bool) { + if pressed { + self.buttons |= 1 << idx; + } else { + self.buttons &= !(1 << idx); } }