This commit is contained in:
Brad Stein 2025-06-28 17:55:15 -05:00
parent 60cee23d08
commit 820ba97b76
5 changed files with 26 additions and 16 deletions

View File

@ -15,6 +15,7 @@ pub struct InputAggregator {
mou_tx: Sender<MouseReport>,
dev_mode: bool,
released: bool,
magic_active: bool,
keyboards: Vec<KeyboardAggregator>,
mice: Vec<MouseAggregator>,
camera: Option<CameraCapture>,
@ -25,7 +26,7 @@ impl InputAggregator {
pub fn new(dev_mode: bool,
kbd_tx: Sender<KeyboardReport>,
mou_tx: Sender<MouseReport>) -> Self {
Self { kbd_tx, mou_tx, dev_mode, released: false,
Self { kbd_tx, mou_tx, dev_mode, released: false, magic_active: false,
keyboards: Vec::new(), mice: Vec::new(),
camera: None, mic: None }
}
@ -105,15 +106,14 @@ impl InputAggregator {
// Example approach: poll each aggregator in a simple loop
let mut tick = interval(Duration::from_millis(10));
loop {
let mut want_toggle = false;
let magic_now = self.keyboards.iter().any(|k| k.magic_grab());
let mut want_kill = false;
for kbd in &mut self.keyboards {
kbd.process_events();
want_toggle |= kbd.magic_grab();
want_kill |= kbd.magic_kill();
}
if want_toggle { self.toggle_grab(); }
if magic_now && !self.magic_active { self.toggle_grab(); }
if want_kill {
warn!("🧙 magic chord - killing 🪄 AVADA KEDAVRA!!! 💥💀⚰️");
std::process::exit(0);
@ -122,21 +122,22 @@ impl InputAggregator {
for mouse in &mut self.mice {
mouse.process_events();
}
// camera / mic stubs could go here
// camera / mic stubs go here
self.magic_active = magic_now;
tick.tick().await;
}
}
fn toggle_grab(&mut self) {
if self.released {
for k in &mut self.keyboards { k.grab(); }
for m in &mut self.mice { m.grab(); }
tracing::info!("🧙 magic chord - restricting devices 🪄 IMPERIUS!!! 🎮🔒");
} else {
for k in &mut self.keyboards { k.ungrab(); }
for m in &mut self.mice { m.ungrab(); }
tracing::info!("🧙 magic chord - freeing devices 🪄 EXPELLIARMUS!!! 🔓🕊️");
}
for k in &mut self.keyboards { k.set_grab(self.released); }
for m in &mut self.mice { m.set_grab(self.released); }
self.released = !self.released;
}
}

View File

@ -26,8 +26,9 @@ impl KeyboardAggregator {
Self { dev, tx, dev_mode, pressed_keys: HashSet::new()}
}
pub fn grab(&mut self) { let _ = self.dev.grab(); }
pub fn ungrab(&mut self) { let _ = self.dev.ungrab(); }
pub fn set_grab(&mut self, grab: bool) {
let _ = if grab { self.dev.grab() } else { self.dev.ungrab() };
}
pub fn process_events(&mut self) {
// --- first fetch, then log (avoids aliasing borrow) ---

View File

@ -28,8 +28,9 @@ impl MouseAggregator {
}
#[inline] fn slog(&self, f: impl FnOnce()) { if self.dev_mode { f() } }
pub fn grab(&mut self) { let _ = self.dev.grab(); }
pub fn ungrab(&mut self) { let _ = self.dev.ungrab(); }
pub fn set_grab(&mut self, grab: bool) {
let _ = if grab { self.dev.grab() } else { self.dev.ungrab() };
}
pub fn process_events(&mut self) {
let evts: Vec<InputEvent> = match self.dev.fetch_events() {

View File

@ -105,7 +105,7 @@ After=network.target lesavka-core.service
[Service]
ExecStart=/usr/local/bin/lesavka-server
Restart=always
Environment=RUST_LOG=lesavka_server=trace,lesavka_server::video=trace,lesavka_server::usb_gadget=info
Environment=RUST_LOG=lesavka_server::video=trace,lesavka_server::usb_gadget=info,lesavka_server=info
Environment=RUST_BACKTRACE=1
Restart=always
RestartSec=5

View File

@ -28,12 +28,19 @@ pub async fn eye_ball(
// appsink name=sink emit-signals=true drop=true sync=false"
// );
let desc = format!(
"v4l2src device={dev} io-mode=mmap ! videorate skip-to-first=true ! \
queue2 max-size-buffers=0 max-size-bytes=0 min-threshold-time=10000000 ! \
"v4l2src device={dev} io-mode=mmap ! \
queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 ! \
video/x-h264,stream-format=byte-stream,alignment=au,profile=high ! \
h264parse config-interval=1 ! \
appsink name=sink emit-signals=true drop=false sync=false"
);
// let desc = format!(
// "v4l2src device={dev} io-mode=mmap ! videorate skip-to-first=true ! \
// queue2 max-size-buffers=0 max-size-bytes=0 min-threshold-time=10000000 ! \
// video/x-h264,stream-format=byte-stream,alignment=au,profile=high ! \
// h264parse config-interval=1 ! \
// appsink name=sink emit-signals=true drop=false sync=false"
// );
let pipeline = gst::parse::launch(&desc)?
.downcast::<gst::Pipeline>()