From f545fe26862b8a91118fd788f6edfb355a68d2e3 Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Wed, 8 Feb 2023 00:41:25 +0100 Subject: [PATCH] Abstract Event Types into a general struct Ground work for supporting different input / emulation backends --- config.toml | 1 + src/client.rs | 7 +- src/event.rs | 546 +++++++++++++++++++++++++++++++----------- src/event/consumer.rs | 81 ++++--- src/event/producer.rs | 168 +++++++++---- src/event/server.rs | 157 +++++++----- src/lib.rs | 2 +- src/main.rs | 24 +- src/request.rs | 11 +- 9 files changed, 688 insertions(+), 309 deletions(-) diff --git a/config.toml b/config.toml index 4f56ad4..13be4f6 100644 --- a/config.toml +++ b/config.toml @@ -6,6 +6,7 @@ port = 42069 [client.left] host_name = "Osmium" +ip = "192.168.178.114" port = 42069 # [client.right] diff --git a/src/client.rs b/src/client.rs index 896faab..2865516 100644 --- a/src/client.rs +++ b/src/client.rs @@ -2,7 +2,10 @@ use std::net::SocketAddr; #[derive(Eq, Hash, PartialEq, Clone, Copy)] pub enum Position { - Left, Right, Top, Bottom, + Left, + Right, + Top, + Bottom, } #[derive(Clone, Copy)] @@ -31,7 +34,6 @@ pub struct ClientManager { pub type ClientHandle = u32; impl ClientManager { - fn new_id(&mut self) -> ClientHandle { self.next_id += 1; self.next_id @@ -54,4 +56,3 @@ impl ClientManager { self.clients.clone() } } - diff --git a/src/event.rs b/src/event.rs index c7cfcca..b73e1e6 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1,154 +1,428 @@ -pub mod producer; +use std::{error::Error, fmt}; + pub mod consumer; +pub mod producer; pub mod server; -/* - * TODO: currently the wayland events are encoded - * directly with no generalized event format -*/ -use wayland_client::{protocol::{wl_pointer, wl_keyboard}, WEnum}; - -pub trait Encode { - fn encode(&self) -> Vec; +pub enum PointerEvent { + Motion { + time: u32, + relative_x: f64, + relative_y: f64, + }, + Button { + time: u32, + button: u32, + state: u32, + }, + Axis { + time: u32, + axis: u8, + value: f64, + }, + Frame {}, } -pub trait Decode { - fn decode(buf: Vec) -> Self; -} - -impl Encode for wl_pointer::Event { - fn encode(&self) -> Vec { - let mut buf = Vec::new(); - match *self { - Self::Motion { - time: t, - surface_x: x, - surface_y: y, - } => { - buf.push(0u8); - buf.extend_from_slice(t.to_ne_bytes().as_ref()); - buf.extend_from_slice(x.to_ne_bytes().as_ref()); - buf.extend_from_slice(y.to_ne_bytes().as_ref()); - } - Self::Button { - serial: _, - time: t, - button: b, - state: s, - } => { - buf.push(1u8); - buf.extend_from_slice(t.to_ne_bytes().as_ref()); - buf.extend_from_slice(b.to_ne_bytes().as_ref()); - buf.push(u32::from(s) as u8); - } - Self::Axis { - time: t, - axis: a, - value: v, - } => { - buf.push(2u8); - buf.extend_from_slice(t.to_ne_bytes().as_ref()); - buf.push(u32::from(a) as u8); - buf.extend_from_slice(v.to_ne_bytes().as_ref()); - } - Self::Frame {} => { - buf.push(3u8); - } - _ => todo!(), - } - buf - } -} - -impl Encode for wl_keyboard::Event { - fn encode(&self) -> Vec { - let mut buf = Vec::new(); - match self { - Self::Key { - serial: _, - time: t, - key: k, - state: s, - } => { - buf.push(4u8); - buf.extend_from_slice(t.to_ne_bytes().as_ref()); - buf.extend_from_slice(k.to_ne_bytes().as_ref()); - buf.push(u32::from(*s) as u8); - } - Self::Modifiers { - serial: _, - mods_depressed, - mods_latched, - mods_locked, - group, - } => { - buf.push(5u8); - buf.extend_from_slice(mods_depressed.to_ne_bytes().as_ref()); - buf.extend_from_slice(mods_latched.to_ne_bytes().as_ref()); - buf.extend_from_slice(mods_locked.to_ne_bytes().as_ref()); - buf.extend_from_slice(group.to_ne_bytes().as_ref()); - } - _ => todo!(), - } - buf - } +pub enum KeyboardEvent { + Key { + time: u32, + key: u32, + state: u8, + }, + Modifiers { + mods_depressed: u32, + mods_latched: u32, + mods_locked: u32, + group: u32, + }, } pub enum Event { - Pointer(wl_pointer::Event), - Keyboard(wl_keyboard::Event), + Pointer(PointerEvent), + Keyboard(KeyboardEvent), Release(), } -impl Encode for Event { - fn encode(&self) -> Vec { - match self { - Event::Pointer(p) => p.encode(), - Event::Keyboard(k) => k.encode(), - Event::Release() => vec![6u8], - } - } -} - unsafe impl Send for Event {} unsafe impl Sync for Event {} -impl Decode for Event { - fn decode(buf: Vec) -> Self { - match buf[0] { - 0 => Self::Pointer(wl_pointer::Event::Motion { - time: u32::from_ne_bytes(buf[1..5].try_into().unwrap()), - surface_x: f64::from_ne_bytes(buf[5..13].try_into().unwrap()), - surface_y: f64::from_ne_bytes(buf[13..21].try_into().unwrap()), - }), - 1 => Self::Pointer(wl_pointer::Event::Button { - serial: 0, - time: (u32::from_ne_bytes(buf[1..5].try_into().unwrap())), - button: (u32::from_ne_bytes(buf[5..9].try_into().unwrap())), - state: (WEnum::Value(wl_pointer::ButtonState::try_from(buf[9] as u32).unwrap())), - }), - 2 => Self::Pointer(wl_pointer::Event::Axis { - time: (u32::from_ne_bytes(buf[1..5].try_into().unwrap())), - axis: (WEnum::Value(wl_pointer::Axis::try_from(buf[5] as u32).unwrap())), - value: (f64::from_ne_bytes(buf[6..14].try_into().unwrap())), - }), - 3 => Self::Pointer(wl_pointer::Event::Frame {}), - 4 => Self::Keyboard(wl_keyboard::Event::Key { - serial: 0, - time: u32::from_ne_bytes(buf[1..5].try_into().unwrap()), - key: u32::from_ne_bytes(buf[5..9].try_into().unwrap()), - state: WEnum::Value(wl_keyboard::KeyState::try_from(buf[9] as u32).unwrap()), - }), - 5 => Self::Keyboard(wl_keyboard::Event::Modifiers { - serial: 0, - mods_depressed: u32::from_ne_bytes(buf[1..5].try_into().unwrap()), - mods_latched: u32::from_ne_bytes(buf[5..9].try_into().unwrap()), - mods_locked: u32::from_ne_bytes(buf[9..13].try_into().unwrap()), - group: u32::from_ne_bytes(buf[13..17].try_into().unwrap()), - }), - 6 => Self::Release(), - _ => panic!("protocol violation"), +impl Event { + fn event_type(&self) -> EventType { + match self { + Self::Pointer(_) => EventType::POINTER, + Self::Keyboard(_) => EventType::KEYBOARD, + Self::Release() => EventType::RELEASE, } } } +impl PointerEvent { + fn event_type(&self) -> PointerEventType { + match self { + Self::Motion { .. } => PointerEventType::MOTION, + Self::Button { .. } => PointerEventType::BUTTON, + Self::Axis { .. } => PointerEventType::AXIS, + Self::Frame { .. } => PointerEventType::FRAME, + } + } +} + +impl KeyboardEvent { + fn event_type(&self) -> KeyboardEventType { + match self { + KeyboardEvent::Key { .. } => KeyboardEventType::KEY, + KeyboardEvent::Modifiers { .. } => KeyboardEventType::MODIFIERS, + } + } +} + +enum PointerEventType { + MOTION, + BUTTON, + AXIS, + FRAME, +} +enum KeyboardEventType { + KEY, + MODIFIERS, +} +enum EventType { + POINTER, + KEYBOARD, + RELEASE, +} + +impl TryFrom for PointerEventType { + type Error = Box; + + fn try_from(value: u8) -> Result { + match value { + x if x == Self::MOTION as u8 => Ok(Self::MOTION), + x if x == Self::BUTTON as u8 => Ok(Self::BUTTON), + x if x == Self::AXIS as u8 => Ok(Self::AXIS), + x if x == Self::FRAME as u8 => Ok(Self::FRAME), + _ => Err(Box::new(ProtocolError { + msg: format!("invalid pointer event type {}", value), + })), + } + } +} + +impl TryFrom for KeyboardEventType { + type Error = Box; + + fn try_from(value: u8) -> Result { + match value { + x if x == Self::KEY as u8 => Ok(Self::KEY), + x if x == Self::MODIFIERS as u8 => Ok(Self::MODIFIERS), + _ => Err(Box::new(ProtocolError { + msg: format!("invalid keyboard event type {}", value), + })), + } + } +} + +impl Into> for &Event { + fn into(self) -> Vec { + let event_id = vec![self.event_type() as u8]; + let event_data = match self { + Event::Pointer(p) => p.into(), + Event::Keyboard(k) => k.into(), + Event::Release() => vec![], + }; + vec![event_id, event_data].concat() + } +} + +#[derive(Debug)] +struct ProtocolError { + msg: String, +} + +impl fmt::Display for ProtocolError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Protocol violation: {}", self.msg) + } +} +impl Error for ProtocolError {} + +impl TryFrom> for Event { + type Error = Box; + + fn try_from(value: Vec) -> Result { + let event_id = u8::from_be_bytes(value[..1].try_into()?); + match event_id { + i if i == (EventType::POINTER as u8) => Ok(Event::Pointer(value.try_into()?)), + i if i == (EventType::KEYBOARD as u8) => Ok(Event::Keyboard(value.try_into()?)), + i if i == (EventType::RELEASE as u8) => Ok(Event::Release()), + _ => Err(Box::new(ProtocolError { + msg: format!("invalid event_id {}", event_id), + })), + } + } +} + +impl Into> for &PointerEvent { + fn into(self) -> Vec { + let id = vec![self.event_type() as u8]; + let data = match self { + PointerEvent::Motion { + time, + relative_x, + relative_y, + } => { + let time = time.to_be_bytes(); + let relative_x = relative_x.to_be_bytes(); + let relative_y = relative_y.to_be_bytes(); + vec![&time[..], &relative_x[..], &relative_y[..]].concat() + } + PointerEvent::Button { + time, + button, + state, + } => { + let time = time.to_be_bytes(); + let button = button.to_be_bytes(); + let state = state.to_be_bytes(); + vec![&time[..], &button[..], &state[..]].concat() + } + PointerEvent::Axis { time, axis, value } => { + let time = time.to_be_bytes(); + let axis = axis.to_be_bytes(); + let value = value.to_be_bytes(); + vec![&time[..], &axis[..], &value[..]].concat() + } + PointerEvent::Frame {} => { + vec![] + } + }; + vec![id, data].concat() + } +} + +impl TryFrom> for PointerEvent { + type Error = Box; + + fn try_from(data: Vec) -> Result { + match data.get(1) { + Some(id) => { + let event_type = match id.to_owned().try_into() { + Ok(event_type) => event_type, + Err(e) => return Err(e), + }; + match event_type { + PointerEventType::MOTION => { + let time = match data.get(2..6) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 2".into(), + })) + } + }; + let relative_x = match data.get(6..14) { + Some(d) => f64::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 8 Bytes at index 6".into(), + })) + } + }; + let relative_y = match data.get(14..22) { + Some(d) => f64::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 8 Bytes at index 14".into(), + })) + } + }; + Ok(Self::Motion { + time, + relative_x, + relative_y, + }) + } + PointerEventType::BUTTON => { + let time = match data.get(2..6) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 2".into(), + })) + } + }; + let button = match data.get(6..10) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 10".into(), + })) + } + }; + let state = match data.get(10..14) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 14".into(), + })) + } + }; + Ok(Self::Button { time, button, state }) + }, + PointerEventType::AXIS => { + let time = match data.get(2..6) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 2".into(), + })) + } + }; + let axis = match data.get(6) { + Some(d) => *d, + None => { + return Err(Box::new(ProtocolError{ + msg: "Expected 1 Byte at index 6".into(), + })); + } + }; + let value = match data.get(7..15) { + Some(d) => f64::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError{ + msg: "Expected 8 Bytes at index 7".into(), + })); + } + }; + Ok(Self::Axis { time, axis, value }) + }, + PointerEventType::FRAME => { + Ok(Self::Frame {}) + }, + } + } + None => Err(Box::new(ProtocolError { + msg: "Expected an element at index 0".into(), + })), + } + } +} + +impl Into> for &KeyboardEvent { + fn into(self) -> Vec { + let id = vec![self.event_type() as u8]; + let data = match self { + KeyboardEvent::Key { + time, + key, + state, + } => { + let time = time.to_be_bytes(); + let key = key.to_be_bytes(); + let state = state.to_be_bytes(); + vec![&time[..], &key[..], &state[..]].concat() + } + KeyboardEvent::Modifiers { + mods_depressed, + mods_latched, + mods_locked, + group, + } => { + let mods_depressed = mods_depressed.to_be_bytes(); + let mods_latched = mods_latched.to_be_bytes(); + let mods_locked = mods_locked.to_be_bytes(); + let group = group.to_be_bytes(); + vec![ + &mods_depressed[..], + &mods_latched[..], + &mods_locked[..], + &group[..], + ] + .concat() + } + }; + vec![id, data].concat() + } +} + +impl TryFrom> for KeyboardEvent { + type Error = Box; + + fn try_from(data: Vec) -> Result { + match data.get(1) { + Some(id) => { + let event_type = match id.to_owned().try_into() { + Ok(event_type) => event_type, + Err(e) => return Err(e), + }; + match event_type { + KeyboardEventType::KEY => { + let time = match data.get(2..6) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 6".into(), + })) + } + }; + let key = match data.get(6..10) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 10".into(), + })) + } + }; + let state = match data.get(10) { + Some(d) => *d, + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 1 Bytes at index 14".into(), + })) + } + }; + Ok(KeyboardEvent::Key { time, key, state }) + } + KeyboardEventType::MODIFIERS => { + let mods_depressed = match data.get(2..6) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 6".into(), + })) + } + }; + let mods_latched = match data.get(6..10) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 10".into(), + })) + } + }; + let mods_locked = match data.get(10..14) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 14".into(), + })) + } + }; + let group = match data.get(14..18) { + Some(d) => u32::from_be_bytes(d.try_into().unwrap()), + None => { + return Err(Box::new(ProtocolError { + msg: "Expected 4 Bytes at index 18".into(), + })) + } + }; + Ok(KeyboardEvent::Modifiers { mods_depressed, mods_latched, mods_locked, group }) + }, + } + } + None => Err(Box::new(ProtocolError { + msg: "Expected an element at index 0".into(), + })) + } + } +} diff --git a/src/event/consumer.rs b/src/event/consumer.rs index 32356cb..3c6301d 100644 --- a/src/event/consumer.rs +++ b/src/event/consumer.rs @@ -1,14 +1,15 @@ use crate::client::{Client, ClientHandle}; use crate::request::{self, Request}; use std::collections::HashMap; +use std::sync::mpsc::Receiver; use std::time::Duration; use std::{io, thread}; -use std::sync::mpsc::Receiver; use std::{ io::{BufWriter, Write}, os::unix::prelude::AsRawFd, }; +use wayland_client::protocol::wl_pointer::{Axis, ButtonState}; use wayland_protocols_wlr::virtual_pointer::v1::client::{ zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1 as VpManager, zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1 as Vp, @@ -22,13 +23,13 @@ use wayland_protocols_misc::zwp_virtual_keyboard_v1::client::{ use wayland_client::{ delegate_noop, globals::{registry_queue_init, GlobalListContents}, - protocol::{wl_keyboard, wl_pointer, wl_registry, wl_seat}, + protocol::{wl_registry, wl_seat}, Connection, Dispatch, EventQueue, QueueHandle, }; use tempfile; -use super::Event; +use super::{Event, KeyboardEvent, PointerEvent}; // App State, implements Dispatch event handlers struct App { @@ -52,11 +53,23 @@ impl App { let (globals, queue) = registry_queue_init::(&conn).unwrap(); let qh = queue.handle(); - let vpm: VpManager = globals.bind(&qh, 1..=1, ()).expect("zwlr_virtual_pointer_manager_v1 protocol is required to emulate mouse input"); - let vkm: VkManager = globals.bind(&qh, 1..=1, ()).expect("zwp_virtual_keyboard_manager_v1 protocol is required to emulate keyboard input"); + let vpm: VpManager = globals + .bind(&qh, 1..=1, ()) + .expect("zwlr_virtual_pointer_manager_v1 protocol is required to emulate mouse input"); + let vkm: VkManager = globals.bind(&qh, 1..=1, ()).expect( + "zwp_virtual_keyboard_manager_v1 protocol is required to emulate keyboard input", + ); let input_for_client: HashMap = HashMap::new(); let seat: wl_seat::WlSeat = globals.bind(&qh, 7..=8, ()).unwrap(); - let mut app = App { input_for_client, seat, event_rx, vpm, vkm, queue, qh }; + let mut app = App { + input_for_client, + seat, + event_rx, + vpm, + vkm, + queue, + qh, + }; for client in clients { app.add_client(client); } @@ -65,7 +78,7 @@ impl App { pub fn run(&mut self) { loop { - let (event, client) = self.event_rx.recv().unwrap(); + let (event, client) = self.event_rx.recv().expect("event receiver unavailable"); if let Some(virtual_input) = self.input_for_client.get(&client) { virtual_input.consume_event(event).unwrap(); if let Err(e) = self.queue.flush() { @@ -76,7 +89,6 @@ impl App { } fn add_client(&mut self, client: Client) { - // create virtual input devices let pointer: Vp = self.vpm.create_virtual_pointer(None, &self.qh, ()); let keyboard: Vk = self.vkm.create_virtual_keyboard(&self.seat, &self.qh, ()); @@ -106,7 +118,6 @@ impl App { self.input_for_client.insert(client.handle, vinput); } - } struct VirtualInput { @@ -115,59 +126,53 @@ struct VirtualInput { } impl VirtualInput { -/// main loop handling udp packets + /// main loop handling udp packets fn consume_event(&self, event: Event) -> std::io::Result<()> { match event { Event::Pointer(e) => match e { - wl_pointer::Event::Motion { + PointerEvent::Motion { time, - surface_x, - surface_y, + relative_x, + relative_y, } => { - self.pointer.motion(time, surface_x, surface_y); + self.pointer.motion(time, relative_x, relative_y); self.pointer.frame(); } - wl_pointer::Event::Button { - serial: _, - time: t, - button: b, - state: s, + PointerEvent::Button { + time, + button, + state, } => { - self.pointer.button(t, b, s.into_result().unwrap()); + let state: ButtonState = state.try_into().unwrap(); + self.pointer.button(time, button, state); self.pointer.frame(); } - wl_pointer::Event::Axis { - time: t, - axis: a, - value: v, - } => { - self.pointer.axis(t, a.into_result().unwrap(), v); + PointerEvent::Axis { time, axis, value } => { + let axis: Axis = (axis as u32).try_into().unwrap(); + self.pointer.axis(time, axis, value); self.pointer.frame(); } - wl_pointer::Event::Frame => { + PointerEvent::Frame {} => { self.pointer.frame(); } - _ => todo!(), }, Event::Keyboard(e) => match e { - wl_keyboard::Event::Key { - serial: _, - time: t, - key: k, - state: s, + KeyboardEvent::Key { + time, + key, + state, } => { - self.keyboard.key(t, k, u32::from(s)); + self.keyboard.key(time, key, state as u32); } - wl_keyboard::Event::Modifiers { - serial: _, + KeyboardEvent::Modifiers { mods_depressed, mods_latched, mods_locked, group, } => { - self.keyboard.modifiers(mods_depressed, mods_latched, mods_locked, group); + self.keyboard + .modifiers(mods_depressed, mods_latched, mods_locked, group); } - _ => todo!(), }, Event::Release() => { self.keyboard.modifiers(77, 0, 0, 0); diff --git a/src/event/producer.rs b/src/event/producer.rs index 3ea54f9..8cb8f51 100644 --- a/src/event/producer.rs +++ b/src/event/producer.rs @@ -1,11 +1,18 @@ -use crate::{request, client::{ClientHandle, Position, Client}}; +use crate::{ + client::{Client, ClientHandle, Position}, + request, +}; use memmap::Mmap; use std::{ fs::File, io::{BufWriter, Write}, - os::unix::prelude::{AsRawFd, FromRawFd}, sync::mpsc::SyncSender, rc::Rc, thread, time::Duration, + os::unix::prelude::{AsRawFd, FromRawFd}, + rc::Rc, + sync::mpsc::SyncSender, + thread, + time::Duration, }; use wayland_protocols::wp::{ @@ -29,18 +36,19 @@ use wayland_protocols_wlr::layer_shell::v1::client::{ }; use wayland_client::{ + backend::WaylandError, delegate_noop, globals::{registry_queue_init, GlobalListContents}, protocol::{ wl_buffer, wl_compositor, wl_keyboard, wl_pointer, wl_region, wl_registry, wl_seat, wl_shm, wl_shm_pool, wl_surface, }, - Connection, Dispatch, QueueHandle, WEnum, DispatchError, backend::WaylandError, + Connection, Dispatch, DispatchError, QueueHandle, WEnum, }; use tempfile; -use super::Event; +use super::{Event, KeyboardEvent, PointerEvent}; struct Globals { compositor: wl_compositor::WlCompositor, @@ -119,27 +127,20 @@ impl Window { } } -pub fn run( - tx: SyncSender<(Event, ClientHandle)>, - server: request::Server, - clients: Vec, -) { +pub fn run(tx: SyncSender<(Event, ClientHandle)>, server: request::Server, clients: Vec) { let conn = Connection::connect_to_env().expect("could not connect to wayland compositor"); - let (g, mut queue) = registry_queue_init::(&conn).expect("failed to initialize wl_registry"); + let (g, mut queue) = + registry_queue_init::(&conn).expect("failed to initialize wl_registry"); let qh = queue.handle(); let compositor: wl_compositor::WlCompositor = g .bind(&qh, 4..=5, ()) .expect("wl_compositor >= v4 not supported"); - let shm: wl_shm::WlShm = g - .bind(&qh, 1..=1, ()) - .expect("wl_shm v1 not supported"); + let shm: wl_shm::WlShm = g.bind(&qh, 1..=1, ()).expect("wl_shm v1 not supported"); let layer_shell: ZwlrLayerShellV1 = g .bind(&qh, 3..=4, ()) .expect("zwlr_layer_shell_v1 >= v3 not supported - required to display a surface at the edge of the screen"); - let seat: wl_seat::WlSeat = g - .bind(&qh, 7..=8, ()) - .expect("wl_seat >= v7 not supported"); + let seat: wl_seat::WlSeat = g.bind(&qh, 7..=8, ()).expect("wl_seat >= v7 not supported"); let pointer_constraints: ZwpPointerConstraintsV1 = g .bind(&qh, 1..=1, ()) .expect("zwp_pointer_constraints_v1 not supported"); @@ -181,15 +182,19 @@ pub fn run( while app.running { match queue.blocking_dispatch(&mut app) { - Ok(_) => { }, + Ok(_) => {} Err(DispatchError::Backend(WaylandError::Io(e))) => { eprintln!("Wayland Error: {}", e); thread::sleep(Duration::from_millis(500)); - }, + } Err(DispatchError::Backend(e)) => { panic!("{}", e); } - Err(DispatchError::BadMessage{ sender_id, interface, opcode }) => { + Err(DispatchError::BadMessage { + sender_id, + interface, + opcode, + }) => { panic!("bad message {}, {} , {}", sender_id, interface, opcode); } } @@ -206,13 +211,12 @@ fn draw(f: &mut File, (width, height): (u32, u32)) { } impl App { - fn grab( &mut self, surface: &wl_surface::WlSurface, pointer: &wl_pointer::WlPointer, serial: u32, - qh: &QueueHandle + qh: &QueueHandle, ) { let (window, _) = self.focused.as_ref().unwrap(); @@ -220,7 +224,9 @@ impl App { pointer.set_cursor(serial, None, 0, 0); // capture input - window.layer_surface.set_keyboard_interactivity(KeyboardInteractivity::Exclusive); + window + .layer_surface + .set_keyboard_interactivity(KeyboardInteractivity::Exclusive); window.surface.commit(); // lock pointer @@ -260,7 +266,9 @@ impl App { let (window, _client) = self.focused.as_ref().unwrap(); // ungrab surface - window.layer_surface.set_keyboard_interactivity(KeyboardInteractivity::None); + window + .layer_surface + .set_keyboard_interactivity(KeyboardInteractivity::None); window.surface.commit(); // release pointer @@ -328,35 +336,62 @@ impl Dispatch for App { surface_y: _, } => { // get client corresponding to the focused surface - + { - let (window, client) = app.client_for_window + let (window, client) = app + .client_for_window .iter() - .find(|(w,_c)| w.surface == surface) + .find(|(w, _c)| w.surface == surface) .unwrap(); app.focused = Some((window.clone(), *client)); app.grab(&surface, pointer, serial.clone(), qh); } - let (_, client) = app.client_for_window + let (_, client) = app + .client_for_window .iter() - .find(|(w,_c)| w.surface == surface) + .find(|(w, _c)| w.surface == surface) .unwrap(); app.tx.send((Event::Release(), *client)).unwrap(); } wl_pointer::Event::Leave { .. } => { app.ungrab(); } - wl_pointer::Event::Button { .. } => { + wl_pointer::Event::Button { + serial: _, + time, + button, + state, + } => { let (_, client) = app.focused.as_ref().unwrap(); - app.tx.send((Event::Pointer(event), *client)).unwrap(); + app.tx + .send(( + Event::Pointer(PointerEvent::Button { + time, + button, + state: u32::from(state), + }), + *client, + )) + .unwrap(); } - wl_pointer::Event::Axis { .. } => { + wl_pointer::Event::Axis { time, axis, value } => { let (_, client) = app.focused.as_ref().unwrap(); - app.tx.send((Event::Pointer(event), *client)).unwrap(); + app.tx + .send(( + Event::Pointer(PointerEvent::Axis { + time, + axis: u32::from(axis) as u8, + value, + }), + *client, + )) + .unwrap(); } - wl_pointer::Event::Frame { .. } => { + wl_pointer::Event::Frame {} => { let (_, client) = app.focused.as_ref().unwrap(); - app.tx.send((Event::Pointer(event), *client)).unwrap(); + app.tx + .send((Event::Pointer(PointerEvent::Frame {}), *client)) + .unwrap(); } _ => {} } @@ -377,14 +412,44 @@ impl Dispatch for App { None => (None, None), }; match event { - wl_keyboard::Event::Key { .. } => { + wl_keyboard::Event::Key { + serial: _, + time, + key, + state, + } => { if let Some(client) = client { - app.tx.send((Event::Keyboard(event), *client)).unwrap(); + app.tx + .send(( + Event::Keyboard(KeyboardEvent::Key { + time, + key, + state: u32::from(state) as u8, + }), + *client, + )) + .unwrap(); } } - wl_keyboard::Event::Modifiers { mods_depressed, .. } => { + wl_keyboard::Event::Modifiers { + serial: _, + mods_depressed, + mods_latched, + mods_locked, + group, + } => { if let Some(client) = client { - app.tx.send((Event::Keyboard(event), *client)).unwrap(); + app.tx + .send(( + Event::Keyboard(KeyboardEvent::Modifiers { + mods_depressed, + mods_latched, + mods_locked, + group, + }), + *client, + )) + .unwrap(); } if mods_depressed == 77 { // ctrl shift super alt @@ -424,15 +489,16 @@ impl Dispatch for App { { if let Some((_window, client)) = &app.focused { let time = (((utime_hi as u64) << 32 | utime_lo as u64) / 1000) as u32; - app.tx.send(( - Event::Pointer(wl_pointer::Event::Motion { - time, - surface_x, - surface_y, - }), - *client, - )).unwrap(); - + app.tx + .send(( + Event::Pointer(PointerEvent::Motion { + time, + relative_x: surface_x, + relative_y: surface_y, + }), + *client, + )) + .unwrap(); } } } @@ -448,9 +514,10 @@ impl Dispatch for App { _: &QueueHandle, ) { if let zwlr_layer_surface_v1::Event::Configure { serial, .. } = event { - let (window, _client) = app.client_for_window + let (window, _client) = app + .client_for_window .iter() - .find(|(w,_c)| &w.layer_surface == layer_surface) + .find(|(w, _c)| &w.layer_surface == layer_surface) .unwrap(); // client corresponding to the layer_surface let surface = &window.surface; @@ -473,7 +540,8 @@ impl Dispatch for App { _data: &GlobalListContents, _conn: &Connection, _qhandle: &QueueHandle, - ) {} + ) { + } } // don't emit any events diff --git a/src/event/server.rs b/src/event/server.rs index 3eeb3e2..8cbd651 100644 --- a/src/event/server.rs +++ b/src/event/server.rs @@ -1,13 +1,18 @@ use std::{ - net::{UdpSocket, SocketAddr}, + collections::HashMap, error::Error, - sync::{mpsc::{SyncSender, Receiver}, atomic::{AtomicBool, Ordering}, Arc}, - thread::{self, JoinHandle}, collections::HashMap, + net::{SocketAddr, UdpSocket}, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::{Receiver, SyncSender}, + Arc, + }, + thread::{self, JoinHandle}, }; use crate::client::{ClientHandle, ClientManager}; -use super::{Event, Encode, Decode}; +use super::Event; pub struct Server { listen_addr: SocketAddr, @@ -18,10 +23,18 @@ impl Server { pub fn new(port: u16) -> Self { let listen_addr = SocketAddr::new("0.0.0.0".parse().unwrap(), port); let sending = Arc::new(AtomicBool::new(false)); - Server { listen_addr, sending } + Server { + listen_addr, + sending, + } } - pub fn run(self, client_manager: &mut ClientManager, produce_rx: Receiver<(Event, ClientHandle)>, consume_tx: SyncSender<(Event, ClientHandle)>) -> Result<(JoinHandle<()>, JoinHandle<()>), Box> { + pub fn run( + self, + client_manager: &mut ClientManager, + produce_rx: Receiver<(Event, ClientHandle)>, + consume_tx: SyncSender<(Event, ClientHandle)>, + ) -> Result<(JoinHandle<()>, JoinHandle<()>), Box> { let udp_socket = UdpSocket::bind(self.listen_addr)?; let rx = udp_socket.try_clone().unwrap(); let tx = udp_socket; @@ -33,44 +46,54 @@ impl Server { println!("{}: {}", client.handle, client.addr); client_for_socket.insert(client.addr, client.handle); } - let receiver = thread::Builder::new().name("event receiver".into()).spawn(move || { - loop { - let (event, addr) = match Server::receive_event(&rx) { - Some(e) => e, - None => { continue }, - }; + let receiver = thread::Builder::new() + .name("event receiver".into()) + .spawn(move || { + loop { + let (event, addr) = match Server::receive_event(&rx) { + Ok(e) => e, + Err(e) => { + eprintln!("{}", e); + continue; + } + }; - let client_handle = match client_for_socket.get(&addr) { - Some(c) => *c, - None => { - println!("Allow connection from {:?}? [Y/n]", addr); - continue - }, - }; + let client_handle = match client_for_socket.get(&addr) { + Some(c) => *c, + None => { + println!("Allow connection from {:?}? [Y/n]", addr); + continue; + } + }; - // There is a race condition between loading this - // value and handling the event: - // In the meantime a event could be produced, which - // should theoretically disable receiving of events. - // - // This is however not a huge problem, as some - // events that make it through are not a large problem - if sending.load(Ordering::Acquire) { - // ignore received events when in sending state - // if release event is received, switch state to receiving - if let Event::Release() = event { - sending.store(false, Ordering::Release); - consume_tx.send((event, client_handle)).expect("event consumer unavailable"); + // There is a race condition between loading this + // value and handling the event: + // In the meantime a event could be produced, which + // should theoretically disable receiving of events. + // + // This is however not a huge problem, as some + // events that make it through are not a large problem + if sending.load(Ordering::Acquire) { + // ignore received events when in sending state + // if release event is received, switch state to receiving + if let Event::Release() = event { + sending.store(false, Ordering::Release); + consume_tx + .send((event, client_handle)) + .expect("event consumer unavailable"); + } + } else { + if let Event::Release() = event { + sending.store(false, Ordering::Release); + } + // we retrieve all events + consume_tx + .send((event, client_handle)) + .expect("event consumer unavailable"); } - } else { - if let Event::Release() = event { - sending.store(false, Ordering::Release); - } - // we retrieve all events - consume_tx.send((event, client_handle)).expect("event consumer unavailable"); } - } - }).unwrap(); + }) + .unwrap(); let sending = self.sending.clone(); @@ -78,42 +101,46 @@ impl Server { for client in client_manager.get_clients() { socket_for_client.insert(client.handle, client.addr); } - let sender = thread::Builder::new().name("event sender".into()).spawn(move || { - loop { - let (event, client_handle) = produce_rx.recv().expect("event producer unavailable"); - let addr = match socket_for_client.get(&client_handle) { - Some(addr) => addr, - None => continue, - }; + let sender = thread::Builder::new() + .name("event sender".into()) + .spawn(move || { + loop { + let (event, client_handle) = + produce_rx.recv().expect("event producer unavailable"); + let addr = match socket_for_client.get(&client_handle) { + Some(addr) => addr, + None => continue, + }; - if sending.load(Ordering::Acquire) { - Server::send_event(&tx, event, *addr); - } else { - // only accept enter event - if let Event::Release() = event { - // set state to sending, to ignore incoming events - // and enable sending of events - sending.store(true, Ordering::Release); + if sending.load(Ordering::Acquire) { Server::send_event(&tx, event, *addr); + } else { + // only accept enter event + if let Event::Release() = event { + // set state to sending, to ignore incoming events + // and enable sending of events + sending.store(true, Ordering::Release); + Server::send_event(&tx, event, *addr); + } } } - } - }).unwrap(); + }) + .unwrap(); Ok((receiver, sender)) } - fn send_event(tx: &UdpSocket, e: E, addr: SocketAddr) { - if let Err(e) = tx.send_to(&e.encode(), addr) { + fn send_event(tx: &UdpSocket, e: Event, addr: SocketAddr) { + let data: Vec = (&e).into(); + if let Err(e) = tx.send_to(&data[..], addr) { eprintln!("{}", e); } } - fn receive_event(rx: &UdpSocket) -> Option<(Event, SocketAddr)> { - let mut buf = vec![0u8; 21]; - if let Ok((_amt, src)) = rx.recv_from(&mut buf) { - Some((Event::decode(buf), src)) - } else { - None + fn receive_event(rx: &UdpSocket) -> Result<(Event, SocketAddr), Box> { + let mut buf = vec![0u8; 22]; + match rx.recv_from(&mut buf) { + Ok((_amt, src)) => Ok((Event::try_from(buf)?, src)), + Err(e) => Err(Box::new(e)), } } } diff --git a/src/lib.rs b/src/lib.rs index ae9b9bf..507ebb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ +pub mod client; pub mod config; pub mod dns; pub mod event; pub mod request; -pub mod client; diff --git a/src/main.rs b/src/main.rs index 4d0ad55..1536a66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ -use std::{sync::mpsc, thread, net::SocketAddr}; +use std::{net::SocketAddr, sync::mpsc, thread}; use lan_mouse::{ - event::{self, producer, consumer}, - config, + client::{ClientManager, Position}, + config, dns, + event::{self, consumer, producer}, request, - client::{ClientManager, Position}, dns, }; fn add_client(client_manager: &mut ClientManager, client: &config::Client, pos: Position) { @@ -16,7 +16,7 @@ fn add_client(client_manager: &mut ClientManager, client: &config::Client, pos: Err(e) => panic!("{}", e), }, None => panic!("neither ip nor hostname specified"), - } + }, }; let addr = SocketAddr::new(ip, client.port.unwrap_or(42069)); client_manager.add_client(addr, pos); @@ -64,19 +64,23 @@ pub fn main() { let event_producer = thread::Builder::new() .name("event producer".into()) .spawn(|| { - producer::run(produce_tx, request_server, clients); - }).unwrap(); + producer::run(produce_tx, request_server, clients); + }) + .unwrap(); let clients = client_manager.get_clients(); let event_consumer = thread::Builder::new() .name("event consumer".into()) .spawn(|| { - consumer::run(consume_rx, clients); - }).unwrap(); + consumer::run(consume_rx, clients); + }) + .unwrap(); // start sending and receiving events let event_server = event::server::Server::new(port); - let (receiver, sender) = event_server.run(&mut client_manager, produce_rx, consume_tx).unwrap(); + let (receiver, sender) = event_server + .run(&mut client_manager, produce_rx, consume_tx) + .unwrap(); request_thread.join().unwrap(); diff --git a/src/request.rs b/src/request.rs index b90cbb8..082f473 100644 --- a/src/request.rs +++ b/src/request.rs @@ -1,8 +1,9 @@ use std::{ - net::{TcpListener, SocketAddr, TcpStream}, - io::prelude::*, - collections::HashMap, sync::{RwLock, Arc}, + collections::HashMap, error::Error, + io::prelude::*, + net::{SocketAddr, TcpListener, TcpStream}, + sync::{Arc, RwLock}, thread::{self, JoinHandle}, }; @@ -80,7 +81,6 @@ impl Server { pub fn offer_data(&self, req: Request, d: Mmap) { self.data.write().unwrap().insert(req, d); } - } pub fn request_data(addr: SocketAddr, req: Request) -> Option> { @@ -96,7 +96,7 @@ pub fn request_data(addr: SocketAddr, req: Request) -> Option> { // write the request to the socket // convert to u32 let req: u32 = req as u32; - if let Err(e) = sock.write(&req.to_ne_bytes()) { + if let Err(e) = sock.write(&req.to_ne_bytes()) { eprintln!("{}", e); return None; } @@ -127,4 +127,3 @@ pub fn request_data(addr: SocketAddr, req: Request) -> Option> { } Some(data) } -