mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 11:59:59 +03:00
Abstract Event Types into a general struct
Ground work for supporting different input / emulation backends
This commit is contained in:
@@ -6,6 +6,7 @@ port = 42069
|
||||
|
||||
[client.left]
|
||||
host_name = "Osmium"
|
||||
ip = "192.168.178.114"
|
||||
port = 42069
|
||||
|
||||
# [client.right]
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
546
src/event.rs
546
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<u8>;
|
||||
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<u8>) -> Self;
|
||||
}
|
||||
|
||||
impl Encode for wl_pointer::Event {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
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<u8> {
|
||||
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<u8> {
|
||||
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<u8>) -> 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<u8> for PointerEventType {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
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<u8> for KeyboardEventType {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
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<Vec<u8>> for &Event {
|
||||
fn into(self) -> Vec<u8> {
|
||||
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<Vec<u8>> for Event {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
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<Vec<u8>> for &PointerEvent {
|
||||
fn into(self) -> Vec<u8> {
|
||||
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<Vec<u8>> for PointerEvent {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(data: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
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<Vec<u8>> for &KeyboardEvent {
|
||||
fn into(self) -> Vec<u8> {
|
||||
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<Vec<u8>> for KeyboardEvent {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn try_from(data: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
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(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<App>(&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<ClientHandle, VirtualInput> = 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);
|
||||
|
||||
@@ -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<Client>,
|
||||
) {
|
||||
pub fn run(tx: SyncSender<(Event, ClientHandle)>, server: request::Server, clients: Vec<Client>) {
|
||||
let conn = Connection::connect_to_env().expect("could not connect to wayland compositor");
|
||||
let (g, mut queue) = registry_queue_init::<App>(&conn).expect("failed to initialize wl_registry");
|
||||
let (g, mut queue) =
|
||||
registry_queue_init::<App>(&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<App>
|
||||
qh: &QueueHandle<App>,
|
||||
) {
|
||||
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<wl_pointer::WlPointer, ()> 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<wl_keyboard::WlKeyboard, ()> 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<ZwpRelativePointerV1, ()> 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<ZwlrLayerSurfaceV1, ()> for App {
|
||||
_: &QueueHandle<Self>,
|
||||
) {
|
||||
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<wl_registry::WlRegistry, GlobalListContents> for App {
|
||||
_data: &GlobalListContents,
|
||||
_conn: &Connection,
|
||||
_qhandle: &QueueHandle<Self>,
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
// don't emit any events
|
||||
|
||||
@@ -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<dyn Error>> {
|
||||
pub fn run(
|
||||
self,
|
||||
client_manager: &mut ClientManager,
|
||||
produce_rx: Receiver<(Event, ClientHandle)>,
|
||||
consume_tx: SyncSender<(Event, ClientHandle)>,
|
||||
) -> Result<(JoinHandle<()>, JoinHandle<()>), Box<dyn Error>> {
|
||||
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<E: Encode>(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<u8> = (&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<dyn Error>> {
|
||||
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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod client;
|
||||
pub mod config;
|
||||
pub mod dns;
|
||||
pub mod event;
|
||||
pub mod request;
|
||||
pub mod client;
|
||||
|
||||
24
src/main.rs
24
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();
|
||||
|
||||
|
||||
@@ -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<Vec<u8>> {
|
||||
@@ -96,7 +96,7 @@ pub fn request_data(addr: SocketAddr, req: Request) -> Option<Vec<u8>> {
|
||||
// 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<Vec<u8>> {
|
||||
}
|
||||
Some(data)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user