move lan-mouse protocol to separate crate (#178)

This commit is contained in:
Ferdinand Schober
2024-08-11 16:51:47 +02:00
committed by GitHub
parent fe06ca1fae
commit 19c2c4327f
28 changed files with 451 additions and 545 deletions

View File

@@ -4,11 +4,7 @@ use std::task::{Context, Poll};
use async_trait::async_trait;
use futures_core::Stream;
use input_event::Event;
use crate::CaptureError;
use super::{Capture, CaptureHandle, Position};
use super::{Capture, CaptureError, CaptureEvent, CaptureHandle, Position};
pub struct DummyInputCapture {}
@@ -44,7 +40,7 @@ impl Capture for DummyInputCapture {
}
impl Stream for DummyInputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Pending

View File

@@ -30,6 +30,23 @@ mod dummy;
pub type CaptureHandle = u64;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CaptureEvent {
/// capture on this capture handle is now active
Begin,
/// input event coming from capture handle
Input(Event),
}
impl Display for CaptureEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CaptureEvent::Begin => write!(f, "begin capture"),
CaptureEvent::Input(e) => write!(f, "{e}"),
}
}
}
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
pub enum Position {
Left,
@@ -147,7 +164,7 @@ impl InputCapture {
}
impl Stream for InputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(
mut self: std::pin::Pin<&mut Self>,
@@ -155,7 +172,11 @@ impl Stream for InputCapture {
) -> Poll<Option<Self::Item>> {
match self.capture.poll_next_unpin(cx) {
Poll::Ready(e) => {
if let Some(Ok((_, Event::Keyboard(KeyboardEvent::Key { key, state, .. })))) = e {
if let Some(Ok((
_,
CaptureEvent::Input(Event::Keyboard(KeyboardEvent::Key { key, state, .. })),
))) = e
{
self.update_pressed_keys(key, state);
}
Poll::Ready(e)
@@ -166,7 +187,7 @@ impl Stream for InputCapture {
}
#[async_trait]
trait Capture: Stream<Item = Result<(CaptureHandle, Event), CaptureError>> + Unpin {
trait Capture: Stream<Item = Result<(CaptureHandle, CaptureEvent), CaptureError>> + Unpin {
/// create a new client with the given id
async fn create(&mut self, id: CaptureHandle, pos: Position) -> Result<(), CaptureError>;
@@ -183,7 +204,7 @@ trait Capture: Stream<Item = Result<(CaptureHandle, Event), CaptureError>> + Unp
async fn create_backend(
backend: Backend,
) -> Result<
Box<dyn Capture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
Box<dyn Capture<Item = Result<(CaptureHandle, CaptureEvent), CaptureError>>>,
CaptureCreationError,
> {
match backend {
@@ -204,7 +225,7 @@ async fn create_backend(
async fn create(
backend: Option<Backend>,
) -> Result<
Box<dyn Capture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
Box<dyn Capture<Item = Result<(CaptureHandle, CaptureEvent), CaptureError>>>,
CaptureCreationError,
> {
if let Some(backend) = backend {

View File

@@ -36,6 +36,8 @@ use once_cell::sync::Lazy;
use input_event::Event;
use crate::CaptureEvent;
use super::{
error::{CaptureError, LibeiCaptureCreationError, ReisConvertEventStreamError},
Capture as LanMouseInputCapture, CaptureHandle, Position,
@@ -56,7 +58,7 @@ enum LibeiNotifyEvent {
pub struct LibeiInputCapture<'a> {
input_capture: Pin<Box<InputCapture<'a>>>,
capture_task: JoinHandle<Result<(), CaptureError>>,
event_rx: Receiver<(CaptureHandle, Event)>,
event_rx: Receiver<(CaptureHandle, CaptureEvent)>,
notify_capture: Sender<LibeiNotifyEvent>,
notify_release: Arc<Notify>,
cancellation_token: CancellationToken,
@@ -201,7 +203,7 @@ async fn connect_to_eis(
async fn libei_event_handler(
mut ei_event_stream: EiConvertEventStream,
context: ei::Context,
event_tx: Sender<(CaptureHandle, Event)>,
event_tx: Sender<(CaptureHandle, CaptureEvent)>,
release_session: Arc<Notify>,
current_client: Rc<Cell<Option<CaptureHandle>>>,
) -> Result<(), CaptureError> {
@@ -258,7 +260,7 @@ async fn do_capture(
mut capture_event: Receiver<LibeiNotifyEvent>,
notify_release: Arc<Notify>,
session: Option<(Session<'_, InputCapture<'_>>, BitFlags<Capabilities>)>,
event_tx: Sender<(CaptureHandle, Event)>,
event_tx: Sender<(CaptureHandle, CaptureEvent)>,
cancellation_token: CancellationToken,
) -> Result<(), CaptureError> {
let mut session = session.map(|s| s.0);
@@ -354,7 +356,7 @@ async fn do_capture(
async fn do_capture_session(
input_capture: &InputCapture<'_>,
session: &mut Session<'_, InputCapture<'_>>,
event_tx: &Sender<(CaptureHandle, Event)>,
event_tx: &Sender<(CaptureHandle, CaptureEvent)>,
active_clients: &[(CaptureHandle, Position)],
next_barrier_id: &mut u32,
notify_release: &Notify,
@@ -423,7 +425,7 @@ async fn do_capture_session(
current_client.replace(Some(client));
// client entered => send event
event_tx.send((client, Event::Enter())).await.expect("no channel");
event_tx.send((client, CaptureEvent::Begin)).await.expect("no channel");
tokio::select! {
_ = notify_release.notified() => { /* capture release */
@@ -554,7 +556,7 @@ async fn handle_ei_event(
ei_event: EiEvent,
current_client: Option<CaptureHandle>,
context: &ei::Context,
event_tx: &Sender<(CaptureHandle, Event)>,
event_tx: &Sender<(CaptureHandle, CaptureEvent)>,
release_session: &Notify,
) -> Result<(), CaptureError> {
match ei_event {
@@ -575,7 +577,7 @@ async fn handle_ei_event(
_ => {
if let Some(handle) = current_client {
for event in Event::from_ei_event(ei_event) {
event_tx.send((handle, event)).await.expect("no channel");
event_tx.send((handle, CaptureEvent::Input(event))).await.expect("no channel");
}
}
}
@@ -627,7 +629,7 @@ impl<'a> Drop for LibeiInputCapture<'a> {
}
impl<'a> Stream for LibeiInputCapture<'a> {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.capture_task.poll_unpin(cx) {

View File

@@ -1,9 +1,9 @@
use crate::{
error::MacOSInputCaptureCreationError, Capture, CaptureError, CaptureHandle, Position,
error::MacOSInputCaptureCreationError, Capture, CaptureError, CaptureEvent, CaptureHandle,
Position,
};
use async_trait::async_trait;
use futures_core::Stream;
use input_event::Event;
use std::pin::Pin;
use std::task::{Context, Poll};
@@ -16,7 +16,7 @@ impl MacOSInputCapture {
}
impl Stream for MacOSInputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Pending

View File

@@ -60,7 +60,7 @@ use wayland_client::{
use input_event::{Event, KeyboardEvent, PointerEvent};
use crate::CaptureError;
use crate::{CaptureError, CaptureEvent};
use super::{
error::{LayerShellCaptureCreationError, WaylandBindError},
@@ -108,7 +108,7 @@ struct State {
wayland_fd: RawFd,
read_guard: Option<ReadEventsGuard>,
qh: QueueHandle<Self>,
pending_events: VecDeque<(CaptureHandle, Event)>,
pending_events: VecDeque<(CaptureHandle, CaptureEvent)>,
output_info: Vec<(WlOutput, OutputInfo)>,
scroll_discrete_pending: bool,
}
@@ -585,7 +585,7 @@ impl Capture for WaylandInputCapture {
}
impl Stream for WaylandInputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
if let Some(event) = self.0.get_mut().state.pending_events.pop_front() {
@@ -694,7 +694,7 @@ impl Dispatch<WlPointer, ()> for State {
.iter()
.find(|(w, _c)| w.surface == surface)
.unwrap();
app.pending_events.push_back((*client, Event::Enter()));
app.pending_events.push_back((*client, CaptureEvent::Begin));
}
wl_pointer::Event::Leave { .. } => {
/* There are rare cases, where when a window is opened in
@@ -718,11 +718,11 @@ impl Dispatch<WlPointer, ()> for State {
let (_, client) = app.focused.as_ref().unwrap();
app.pending_events.push_back((
*client,
Event::Pointer(PointerEvent::Button {
CaptureEvent::Input(Event::Pointer(PointerEvent::Button {
time,
button,
state: u32::from(state),
}),
})),
));
}
wl_pointer::Event::Axis { time, axis, value } => {
@@ -735,11 +735,11 @@ impl Dispatch<WlPointer, ()> for State {
} else {
app.pending_events.push_back((
*client,
Event::Pointer(PointerEvent::Axis {
CaptureEvent::Input(Event::Pointer(PointerEvent::Axis {
time,
axis: u32::from(axis) as u8,
value,
}),
})),
));
}
}
@@ -748,10 +748,10 @@ impl Dispatch<WlPointer, ()> for State {
app.scroll_discrete_pending = true;
app.pending_events.push_back((
*client,
Event::Pointer(PointerEvent::AxisDiscrete120 {
CaptureEvent::Input(Event::Pointer(PointerEvent::AxisDiscrete120 {
axis: u32::from(axis) as u8,
value: value120,
}),
})),
));
}
wl_pointer::Event::Frame {} => {
@@ -787,11 +787,11 @@ impl Dispatch<WlKeyboard, ()> for State {
if let Some(client) = client {
app.pending_events.push_back((
*client,
Event::Keyboard(KeyboardEvent::Key {
CaptureEvent::Input(Event::Keyboard(KeyboardEvent::Key {
time,
key,
state: u32::from(state) as u8,
}),
})),
));
}
}
@@ -805,12 +805,12 @@ impl Dispatch<WlKeyboard, ()> for State {
if let Some(client) = client {
app.pending_events.push_back((
*client,
Event::Keyboard(KeyboardEvent::Modifiers {
mods_depressed,
mods_latched,
mods_locked,
CaptureEvent::Input(Event::Keyboard(KeyboardEvent::Modifiers {
depressed: mods_depressed,
latched: mods_latched,
locked: mods_locked,
group,
}),
})),
));
}
}
@@ -840,7 +840,7 @@ impl Dispatch<ZwpRelativePointerV1, ()> for State {
let time = (((utime_hi as u64) << 32 | utime_lo as u64) / 1000) as u32;
app.pending_events.push_back((
*client,
Event::Pointer(PointerEvent::Motion { time, dx, dy }),
CaptureEvent::Input(Event::Pointer(PointerEvent::Motion { time, dx, dy })),
));
}
}

View File

@@ -37,7 +37,7 @@ use input_event::{
Event, KeyboardEvent, PointerEvent, BTN_BACK, BTN_FORWARD, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
};
use super::{Capture, CaptureError, CaptureHandle, Position};
use super::{Capture, CaptureError, CaptureEvent, CaptureHandle, Position};
enum Request {
Create(CaptureHandle, Position),
@@ -45,7 +45,7 @@ enum Request {
}
pub struct WindowsInputCapture {
event_rx: Receiver<(CaptureHandle, Event)>,
event_rx: Receiver<(CaptureHandle, CaptureEvent)>,
msg_thread: Option<std::thread::JoinHandle<()>>,
}
@@ -100,7 +100,7 @@ impl Capture for WindowsInputCapture {
static mut REQUEST_BUFFER: Mutex<Vec<Request>> = Mutex::new(Vec::new());
static mut ACTIVE_CLIENT: Option<CaptureHandle> = None;
static mut CLIENT_FOR_POS: Lazy<HashMap<Position, CaptureHandle>> = Lazy::new(HashMap::new);
static mut EVENT_TX: Option<Sender<(CaptureHandle, Event)>> = None;
static mut EVENT_TX: Option<Sender<(CaptureHandle, CaptureEvent)>> = None;
static mut EVENT_THREAD_ID: AtomicU32 = AtomicU32::new(0);
unsafe fn set_event_tid(tid: u32) {
EVENT_THREAD_ID.store(tid, Ordering::SeqCst);
@@ -249,7 +249,7 @@ fn clamp_to_display_bounds(prev_point: (i32, i32), point: (i32, i32)) -> (i32, i
(x.clamp(min_x, max_x), y.clamp(min_y, max_y))
}
unsafe fn send_blocking(event: Event) {
unsafe fn send_blocking(event: CaptureEvent) {
if let Some(active) = ACTIVE_CLIENT {
block_on(async move {
let _ = EVENT_TX.as_ref().unwrap().send((active, event)).await;
@@ -291,7 +291,7 @@ unsafe fn check_client_activation(wparam: WPARAM, lparam: LPARAM) -> bool {
/* notify main thread */
log::debug!("ENTERED @ {prev_pos:?} -> {curr_pos:?}");
send_blocking(Event::Enter());
send_blocking(CaptureEvent::Begin);
ret
}
@@ -313,7 +313,7 @@ unsafe extern "system" fn mouse_proc(ncode: i32, wparam: WPARAM, lparam: LPARAM)
let Some(pointer_event) = to_mouse_event(wparam, lparam) else {
return LRESULT(1);
};
let event = (client, Event::Pointer(pointer_event));
let event = (client, CaptureEvent::Input(Event::Pointer(pointer_event)));
/* notify mainthread (drop events if sending too fast) */
if let Err(e) = EVENT_TX.as_ref().unwrap().try_send(event) {
@@ -334,7 +334,7 @@ unsafe extern "system" fn kybrd_proc(ncode: i32, wparam: WPARAM, lparam: LPARAM)
let Some(key_event) = to_key_event(wparam, lparam) else {
return LRESULT(1);
};
let event = (client, Event::Keyboard(key_event));
let event = (client, CaptureEvent::Input(Event::Keyboard(key_event)));
if let Err(e) = EVENT_TX.as_ref().unwrap().try_send(event) {
log::warn!("e: {e}");
@@ -614,7 +614,7 @@ impl WindowsInputCapture {
}
impl Stream for WindowsInputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match ready!(self.event_rx.poll_recv(cx)) {
None => Poll::Ready(None),

View File

@@ -3,13 +3,10 @@ use std::task::Poll;
use async_trait::async_trait;
use futures_core::Stream;
use crate::CaptureError;
use super::Capture;
use input_event::Event;
use super::error::X11InputCaptureCreationError;
use super::{CaptureHandle, Position};
use super::{
error::X11InputCaptureCreationError, Capture, CaptureError, CaptureEvent, CaptureHandle,
Position,
};
pub struct X11InputCapture {}
@@ -39,7 +36,7 @@ impl Capture for X11InputCapture {
}
impl Stream for X11InputCapture {
type Item = Result<(CaptureHandle, Event), CaptureError>;
type Item = Result<(CaptureHandle, CaptureEvent), CaptureError>;
fn poll_next(
self: std::pin::Pin<&mut Self>,