From 8908c33603660c71ab5cfddff0d58cf0f6e9fa37 Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Fri, 12 Jul 2024 12:07:30 +0200 Subject: [PATCH] move libei event conversion to event crate --- Cargo.lock | 1 + Cargo.toml | 2 +- input-capture/src/libei.rs | 142 +----------------------------------- input-event/Cargo.toml | 5 ++ input-event/src/lib.rs | 3 + input-event/src/libei.rs | 146 +++++++++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 140 deletions(-) create mode 100644 input-event/src/libei.rs diff --git a/Cargo.lock b/Cargo.lock index 09893f9..4714f34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1246,6 +1246,7 @@ dependencies = [ "futures-core", "log", "num_enum", + "reis", "serde", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 2df769d..3ce9ee7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,5 +61,5 @@ default = ["wayland", "x11", "xdg_desktop_portal", "libei", "gtk"] wayland = ["input-capture/wayland", "input-emulation/wayland"] x11 = ["input-capture/x11", "input-emulation/x11"] xdg_desktop_portal = ["input-emulation/xdg_desktop_portal"] -libei = ["input-capture/libei", "input-emulation/libei"] +libei = ["input-event/libei", "input-capture/libei", "input-emulation/libei"] gtk = ["dep:gtk", "dep:adw", "dep:async-channel", "dep:glib-build-tools"] diff --git a/input-capture/src/libei.rs b/input-capture/src/libei.rs index 19ff10c..06fdc6a 100644 --- a/input-capture/src/libei.rs +++ b/input-capture/src/libei.rs @@ -8,8 +8,7 @@ use ashpd::{ use async_trait::async_trait; use futures::{FutureExt, StreamExt}; use reis::{ - ei::{self, keyboard::KeyState}, - eis::button::ButtonState, + ei, event::{DeviceCapability, EiEvent}, tokio::{EiConvertEventStream, EiEventStream}, }; @@ -35,7 +34,7 @@ use tokio_util::sync::CancellationToken; use futures_core::Stream; use once_cell::sync::Lazy; -use input_event::{Event, KeyboardEvent, PointerEvent}; +use input_event::Event; use super::{ error::{CaptureError, LibeiCaptureCreationError, ReisConvertEventStreamError}, @@ -521,7 +520,7 @@ async fn handle_ei_event( } _ => { if let Some(handle) = current_client { - for event in to_input_events(ei_event).into_iter() { + for event in Event::from_ei_event(ei_event) { event_tx.send((handle, event)).await.expect("no channel"); } } @@ -530,141 +529,6 @@ async fn handle_ei_event( Ok(()) } -/* not pretty but saves a heap allocation */ -enum Events { - None, - One(Event), - Two(Event, Event), -} - -impl Events { - fn into_iter(self) -> impl Iterator { - EventIterator::new(self) - } -} - -struct EventIterator { - events: [Option; 2], - pos: usize, -} - -impl EventIterator { - fn new(events: Events) -> Self { - let events = match events { - Events::None => [None, None], - Events::One(e) => [Some(e), None], - Events::Two(e, f) => [Some(e), Some(f)], - }; - Self { events, pos: 0 } - } -} - -impl Iterator for EventIterator { - type Item = Event; - - fn next(&mut self) -> Option { - let res = if self.pos >= self.events.len() { - None - } else { - self.events[self.pos] - }; - self.pos += 1; - res - } -} - -fn to_input_events(ei_event: EiEvent) -> Events { - match ei_event { - EiEvent::KeyboardModifiers(mods) => { - let modifier_event = KeyboardEvent::Modifiers { - mods_depressed: mods.depressed, - mods_latched: mods.latched, - mods_locked: mods.locked, - group: mods.group, - }; - Events::One(Event::Keyboard(modifier_event)) - } - EiEvent::Frame(_) => Events::None, /* FIXME */ - EiEvent::PointerMotion(motion) => { - let motion_event = PointerEvent::Motion { - time: motion.time as u32, - dx: motion.dx as f64, - dy: motion.dy as f64, - }; - Events::One(Event::Pointer(motion_event)) - } - EiEvent::PointerMotionAbsolute(_) => Events::None, - EiEvent::Button(button) => { - let button_event = PointerEvent::Button { - time: button.time as u32, - button: button.button, - state: match button.state { - ButtonState::Released => 0, - ButtonState::Press => 1, - }, - }; - Events::One(Event::Pointer(button_event)) - } - EiEvent::ScrollDelta(delta) => { - let dy = Event::Pointer(PointerEvent::Axis { - time: 0, - axis: 0, - value: delta.dy as f64, - }); - let dx = Event::Pointer(PointerEvent::Axis { - time: 0, - axis: 1, - value: delta.dx as f64, - }); - if delta.dy != 0. && delta.dx != 0. { - Events::Two(dy, dx) - } else if delta.dy != 0. { - Events::One(dy) - } else if delta.dx != 0. { - Events::One(dx) - } else { - Events::None - } - } - EiEvent::ScrollStop(_) => Events::None, /* TODO */ - EiEvent::ScrollCancel(_) => Events::None, /* TODO */ - EiEvent::ScrollDiscrete(scroll) => { - let dy = Event::Pointer(PointerEvent::AxisDiscrete120 { - axis: 0, - value: scroll.discrete_dy, - }); - let dx = Event::Pointer(PointerEvent::AxisDiscrete120 { - axis: 1, - value: scroll.discrete_dx, - }); - if scroll.discrete_dy != 0 && scroll.discrete_dx != 0 { - Events::Two(dy, dx) - } else if scroll.discrete_dy != 0 { - Events::One(dy) - } else if scroll.discrete_dx != 0 { - Events::One(dx) - } else { - Events::None - } - } - EiEvent::KeyboardKey(key) => { - let key_event = KeyboardEvent::Key { - key: key.key, - state: match key.state { - KeyState::Press => 1, - KeyState::Released => 0, - }, - time: key.time as u32, - }; - Events::One(Event::Keyboard(key_event)) - } - EiEvent::TouchDown(_) => Events::None, /* TODO */ - EiEvent::TouchUp(_) => Events::None, /* TODO */ - EiEvent::TouchMotion(_) => Events::None, /* TODO */ - _ => Events::None, - } -} - #[async_trait] impl<'a> LanMouseInputCapture for LibeiInputCapture<'a> { async fn create(&mut self, handle: CaptureHandle, pos: Position) -> Result<(), CaptureError> { diff --git a/input-event/Cargo.toml b/input-event/Cargo.toml index 82d6f6b..8b9285d 100644 --- a/input-event/Cargo.toml +++ b/input-event/Cargo.toml @@ -12,3 +12,8 @@ log = "0.4.22" num_enum = "0.7.2" serde = { version = "1.0", features = ["derive"] } thiserror = "1.0.61" +reis = { version = "0.2.0", optional = true } + +[features] +default = ["libei"] +libei = ["dep:reis"] diff --git a/input-event/src/lib.rs b/input-event/src/lib.rs index c66c214..240b0f2 100644 --- a/input-event/src/lib.rs +++ b/input-event/src/lib.rs @@ -5,6 +5,9 @@ pub mod error; pub mod proto; pub mod scancode; +#[cfg(feature = "libei")] +mod libei; + // FIXME pub const BTN_LEFT: u32 = 0x110; pub const BTN_RIGHT: u32 = 0x111; diff --git a/input-event/src/libei.rs b/input-event/src/libei.rs new file mode 100644 index 0000000..51e6368 --- /dev/null +++ b/input-event/src/libei.rs @@ -0,0 +1,146 @@ +use reis::{ + ei::{button::ButtonState, keyboard::KeyState}, + event::EiEvent, +}; + +use crate::{Event, KeyboardEvent, PointerEvent}; + +impl Event { + pub fn from_ei_event(ei_event: EiEvent) -> impl Iterator { + to_input_events(ei_event).into_iter() + } +} + +enum Events { + None, + One(Event), + Two(Event, Event), +} + +impl Events { + fn into_iter(self) -> impl Iterator { + EventIterator::new(self) + } +} + +struct EventIterator { + events: [Option; 2], + pos: usize, +} + +impl EventIterator { + fn new(events: Events) -> Self { + let events = match events { + Events::None => [None, None], + Events::One(e) => [Some(e), None], + Events::Two(e, f) => [Some(e), Some(f)], + }; + Self { events, pos: 0 } + } +} + +impl Iterator for EventIterator { + type Item = Event; + + fn next(&mut self) -> Option { + let res = if self.pos >= self.events.len() { + None + } else { + self.events[self.pos] + }; + self.pos += 1; + res + } +} + +fn to_input_events(ei_event: EiEvent) -> Events { + match ei_event { + EiEvent::KeyboardModifiers(mods) => { + let modifier_event = KeyboardEvent::Modifiers { + mods_depressed: mods.depressed, + mods_latched: mods.latched, + mods_locked: mods.locked, + group: mods.group, + }; + Events::One(Event::Keyboard(modifier_event)) + } + EiEvent::Frame(_) => Events::None, /* FIXME */ + EiEvent::PointerMotion(motion) => { + let motion_event = PointerEvent::Motion { + time: motion.time as u32, + dx: motion.dx as f64, + dy: motion.dy as f64, + }; + Events::One(Event::Pointer(motion_event)) + } + EiEvent::PointerMotionAbsolute(_) => Events::None, + EiEvent::Button(button) => { + let button_event = PointerEvent::Button { + time: button.time as u32, + button: button.button, + state: match button.state { + ButtonState::Released => 0, + ButtonState::Press => 1, + }, + }; + Events::One(Event::Pointer(button_event)) + } + EiEvent::ScrollDelta(delta) => { + let dy = Event::Pointer(PointerEvent::Axis { + time: 0, + axis: 0, + value: delta.dy as f64, + }); + let dx = Event::Pointer(PointerEvent::Axis { + time: 0, + axis: 1, + value: delta.dx as f64, + }); + if delta.dy != 0. && delta.dx != 0. { + Events::Two(dy, dx) + } else if delta.dy != 0. { + Events::One(dy) + } else if delta.dx != 0. { + Events::One(dx) + } else { + Events::None + } + } + EiEvent::ScrollStop(_) => Events::None, /* TODO */ + EiEvent::ScrollCancel(_) => Events::None, /* TODO */ + EiEvent::ScrollDiscrete(scroll) => { + let dy = Event::Pointer(PointerEvent::AxisDiscrete120 { + axis: 0, + value: scroll.discrete_dy, + }); + let dx = Event::Pointer(PointerEvent::AxisDiscrete120 { + axis: 1, + value: scroll.discrete_dx, + }); + if scroll.discrete_dy != 0 && scroll.discrete_dx != 0 { + Events::Two(dy, dx) + } else if scroll.discrete_dy != 0 { + Events::One(dy) + } else if scroll.discrete_dx != 0 { + Events::One(dx) + } else { + Events::None + } + } + EiEvent::KeyboardKey(key) => { + let key_event = KeyboardEvent::Key { + key: key.key, + state: match key.state { + KeyState::Press => 1, + KeyState::Released => 0, + }, + time: key.time as u32, + }; + Events::One(Event::Keyboard(key_event)) + } + EiEvent::TouchDown(_) => Events::None, /* TODO */ + EiEvent::TouchUp(_) => Events::None, /* TODO */ + EiEvent::TouchMotion(_) => Events::None, /* TODO */ + _ => Events::None, + } +}