mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-17 10:51:28 +03:00
enable conditional compilation for all backends
To reduce binary size one can now enable only specific backends, e.g. wayland or x11 via cargo features Additionally adds stubs for libei and xdg-desktop-portal backends
This commit is contained in:
25
Cargo.toml
25
Cargo.toml
@@ -15,12 +15,25 @@ serde_derive = "1.0"
|
|||||||
threadpool = "1.8"
|
threadpool = "1.8"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
wayland-client = { version="0.30.0" }
|
wayland-client = { version="0.30.0", optional = true }
|
||||||
wayland-protocols = { version="0.30.0", features=["client", "staging", "unstable"] }
|
wayland-protocols = { version="0.30.0", features=["client", "staging", "unstable"], optional = true }
|
||||||
wayland-protocols-wlr = { version="0.1.0", features=["client"] }
|
wayland-protocols-wlr = { version="0.1.0", features=["client"], optional = true }
|
||||||
wayland-protocols-misc = { version="0.1.0", features=["client"] }
|
wayland-protocols-misc = { version="0.1.0", features=["client"], optional = true }
|
||||||
wayland-protocols-plasma = { version="0.1.0", features=["client"] }
|
wayland-protocols-plasma = { version="0.1.0", features=["client"], optional = true }
|
||||||
x11 = { version = "2.21.0", features = ["xlib", "xtest"] }
|
x11 = { version = "2.21.0", features = ["xlib", "xtest"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3.9", features = ["winuser"] }
|
winapi = { version = "0.3.9", features = ["winuser"] }
|
||||||
|
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "wayland", "x11", "xdg_desktop_portal", "libei" ]
|
||||||
|
wayland = [
|
||||||
|
"dep:wayland-client",
|
||||||
|
"dep:wayland-protocols",
|
||||||
|
"dep:wayland-protocols-wlr",
|
||||||
|
"dep:wayland-protocols-misc",
|
||||||
|
"dep:wayland-protocols-plasma" ]
|
||||||
|
x11 = [ "dep:x11" ]
|
||||||
|
xdg_desktop_portal = []
|
||||||
|
libei = []
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
port = 42069
|
port = 42069
|
||||||
|
backend = "wlroots"
|
||||||
|
|
||||||
# [client.right]
|
# [client.right]
|
||||||
# host_name = "localhost"
|
# host_name = "localhost"
|
||||||
|
|||||||
@@ -1,14 +1,2 @@
|
|||||||
#[cfg(windows)]
|
pub mod consumer;
|
||||||
pub mod windows;
|
pub mod producer;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
pub mod wayland;
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
pub mod x11;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum Backend {
|
|
||||||
X11,
|
|
||||||
WAYLAND,
|
|
||||||
}
|
|
||||||
|
|||||||
14
src/backend/consumer.rs
Normal file
14
src/backend/consumer.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#[cfg(windows)]
|
||||||
|
pub mod windows;
|
||||||
|
|
||||||
|
#[cfg(feature="x11")]
|
||||||
|
pub mod x11;
|
||||||
|
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
pub mod wlroots;
|
||||||
|
|
||||||
|
#[cfg(feature = "xdg_desktop_portal")]
|
||||||
|
pub mod xdg_desktop_portal;
|
||||||
|
|
||||||
|
#[cfg(feature = "libei")]
|
||||||
|
pub mod libei;
|
||||||
9
src/backend/consumer/libei.rs
Normal file
9
src/backend/consumer/libei.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
|
use crate::{event::Event, client::{ClientHandle, Client}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) fn run(_consume_rx: Receiver<(Event, ClientHandle)>, _clients: Vec<Client>) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
@@ -35,13 +35,8 @@ use tempfile;
|
|||||||
use crate::event::{Event, KeyboardEvent, PointerEvent};
|
use crate::event::{Event, KeyboardEvent, PointerEvent};
|
||||||
|
|
||||||
enum VirtualInputManager {
|
enum VirtualInputManager {
|
||||||
Wlroots {
|
Wlroots { vpm: VpManager, vkm: VkManager },
|
||||||
vpm: VpManager,
|
Kde { fake_input: OrgKdeKwinFakeInput },
|
||||||
vkm: VkManager,
|
|
||||||
},
|
|
||||||
Kde {
|
|
||||||
fake_input: OrgKdeKwinFakeInput,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// App State, implements Dispatch event handlers
|
// App State, implements Dispatch event handlers
|
||||||
@@ -72,16 +67,21 @@ impl App {
|
|||||||
let virtual_input_manager = match (vpm, vkm, fake_input) {
|
let virtual_input_manager = match (vpm, vkm, fake_input) {
|
||||||
(Ok(vpm), Ok(vkm), _) => VirtualInputManager::Wlroots { vpm, vkm },
|
(Ok(vpm), Ok(vkm), _) => VirtualInputManager::Wlroots { vpm, vkm },
|
||||||
(_, _, Ok(fake_input)) => {
|
(_, _, Ok(fake_input)) => {
|
||||||
fake_input.authenticate("lan-mouse".into(), "Allow remote clients to control this devices".into());
|
fake_input.authenticate(
|
||||||
|
"lan-mouse".into(),
|
||||||
|
"Allow remote clients to control this devices".into(),
|
||||||
|
);
|
||||||
VirtualInputManager::Kde { fake_input }
|
VirtualInputManager::Kde { fake_input }
|
||||||
},
|
}
|
||||||
(Err(e1), Err(e2), Err(e3)) => {
|
(Err(e1), Err(e2), Err(e3)) => {
|
||||||
eprintln!("zwlr_virtual_pointer_v1: {e1}");
|
eprintln!("zwlr_virtual_pointer_v1: {e1}");
|
||||||
eprintln!("zwp_virtual_keyboard_v1: {e2}");
|
eprintln!("zwp_virtual_keyboard_v1: {e2}");
|
||||||
eprintln!("org_kde_kwin_fake_input: {e3}");
|
eprintln!("org_kde_kwin_fake_input: {e3}");
|
||||||
panic!("neither wlroots nor kde input emulation protocol supported!")
|
panic!("neither wlroots nor kde input emulation protocol supported!")
|
||||||
},
|
}
|
||||||
_ => { panic!() }
|
_ => {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let input_for_client: HashMap<ClientHandle, VirtualInput> = HashMap::new();
|
let input_for_client: HashMap<ClientHandle, VirtualInput> = HashMap::new();
|
||||||
@@ -152,28 +152,22 @@ impl App {
|
|||||||
buf.flush().unwrap();
|
buf.flush().unwrap();
|
||||||
keyboard.keymap(1, f.as_raw_fd(), data.len() as u32);
|
keyboard.keymap(1, f.as_raw_fd(), data.len() as u32);
|
||||||
|
|
||||||
let vinput = VirtualInput::Wlroots{ pointer, keyboard };
|
let vinput = VirtualInput::Wlroots { pointer, keyboard };
|
||||||
|
|
||||||
self.input_for_client.insert(client.handle, vinput);
|
self.input_for_client.insert(client.handle, vinput);
|
||||||
|
}
|
||||||
},
|
|
||||||
VirtualInputManager::Kde { fake_input } => {
|
VirtualInputManager::Kde { fake_input } => {
|
||||||
let fake_input = fake_input.clone();
|
let fake_input = fake_input.clone();
|
||||||
let vinput = VirtualInput::Kde { fake_input };
|
let vinput = VirtualInput::Kde { fake_input };
|
||||||
self.input_for_client.insert(client.handle, vinput);
|
self.input_for_client.insert(client.handle, vinput);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VirtualInput {
|
enum VirtualInput {
|
||||||
Wlroots {
|
Wlroots { pointer: Vp, keyboard: Vk },
|
||||||
pointer: Vp,
|
Kde { fake_input: OrgKdeKwinFakeInput },
|
||||||
keyboard: Vk,
|
|
||||||
},
|
|
||||||
Kde {
|
|
||||||
fake_input: OrgKdeKwinFakeInput,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VirtualInput {
|
impl VirtualInput {
|
||||||
@@ -185,17 +179,18 @@ impl VirtualInput {
|
|||||||
time,
|
time,
|
||||||
relative_x,
|
relative_x,
|
||||||
relative_y,
|
relative_y,
|
||||||
} => {
|
} => match self {
|
||||||
match self {
|
VirtualInput::Wlroots {
|
||||||
VirtualInput::Wlroots { pointer, keyboard:_ } => {
|
pointer,
|
||||||
pointer.motion(time, relative_x, relative_y);
|
keyboard: _,
|
||||||
pointer.frame();
|
} => {
|
||||||
},
|
pointer.motion(time, relative_x, relative_y);
|
||||||
VirtualInput::Kde { fake_input } => {
|
pointer.frame();
|
||||||
fake_input.pointer_motion(relative_y, relative_y);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
VirtualInput::Kde { fake_input } => {
|
||||||
|
fake_input.pointer_motion(relative_y, relative_y);
|
||||||
|
}
|
||||||
|
},
|
||||||
PointerEvent::Button {
|
PointerEvent::Button {
|
||||||
time,
|
time,
|
||||||
button,
|
button,
|
||||||
@@ -203,70 +198,80 @@ impl VirtualInput {
|
|||||||
} => {
|
} => {
|
||||||
let state: ButtonState = state.try_into().unwrap();
|
let state: ButtonState = state.try_into().unwrap();
|
||||||
match self {
|
match self {
|
||||||
VirtualInput::Wlroots { pointer, keyboard:_ } => {
|
VirtualInput::Wlroots {
|
||||||
|
pointer,
|
||||||
|
keyboard: _,
|
||||||
|
} => {
|
||||||
pointer.button(time, button, state);
|
pointer.button(time, button, state);
|
||||||
pointer.frame();
|
pointer.frame();
|
||||||
},
|
}
|
||||||
VirtualInput::Kde { fake_input } => {
|
VirtualInput::Kde { fake_input } => {
|
||||||
fake_input.button(button, state as u32);
|
fake_input.button(button, state as u32);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PointerEvent::Axis { time, axis, value } => {
|
PointerEvent::Axis { time, axis, value } => {
|
||||||
let axis: Axis = (axis as u32).try_into().unwrap();
|
let axis: Axis = (axis as u32).try_into().unwrap();
|
||||||
match self {
|
match self {
|
||||||
VirtualInput::Wlroots { pointer, keyboard:_ } => {
|
VirtualInput::Wlroots {
|
||||||
|
pointer,
|
||||||
|
keyboard: _,
|
||||||
|
} => {
|
||||||
pointer.axis(time, axis, value);
|
pointer.axis(time, axis, value);
|
||||||
pointer.frame();
|
pointer.frame();
|
||||||
},
|
}
|
||||||
VirtualInput::Kde { fake_input } => {
|
VirtualInput::Kde { fake_input } => {
|
||||||
fake_input.axis(axis as u32, value);
|
fake_input.axis(axis as u32, value);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PointerEvent::Frame {} => {
|
PointerEvent::Frame {} => match self {
|
||||||
match self {
|
VirtualInput::Wlroots {
|
||||||
VirtualInput::Wlroots { pointer, keyboard:_ } => {
|
pointer,
|
||||||
pointer.frame();
|
keyboard: _,
|
||||||
},
|
} => {
|
||||||
VirtualInput::Kde { fake_input:_ } => { },
|
pointer.frame();
|
||||||
}
|
}
|
||||||
}
|
VirtualInput::Kde { fake_input: _ } => {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Event::Keyboard(e) => match e {
|
Event::Keyboard(e) => match e {
|
||||||
KeyboardEvent::Key { time, key, state } => {
|
KeyboardEvent::Key { time, key, state } => match self {
|
||||||
match self {
|
VirtualInput::Wlroots {
|
||||||
VirtualInput::Wlroots { pointer:_, keyboard } => {
|
pointer: _,
|
||||||
keyboard.key(time, key, state as u32);
|
keyboard,
|
||||||
},
|
} => {
|
||||||
VirtualInput::Kde { fake_input } => {
|
keyboard.key(time, key, state as u32);
|
||||||
fake_input.keyboard_key(key, state as u32);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
VirtualInput::Kde { fake_input } => {
|
||||||
|
fake_input.keyboard_key(key, state as u32);
|
||||||
|
}
|
||||||
|
},
|
||||||
KeyboardEvent::Modifiers {
|
KeyboardEvent::Modifiers {
|
||||||
mods_depressed,
|
mods_depressed,
|
||||||
mods_latched,
|
mods_latched,
|
||||||
mods_locked,
|
mods_locked,
|
||||||
group,
|
group,
|
||||||
} => {
|
} => match self {
|
||||||
match self {
|
VirtualInput::Wlroots {
|
||||||
VirtualInput::Wlroots { pointer:_, keyboard } => {
|
pointer: _,
|
||||||
keyboard.modifiers(mods_depressed, mods_latched, mods_locked, group);
|
keyboard,
|
||||||
},
|
} => {
|
||||||
VirtualInput::Kde { fake_input:_ } => { },
|
keyboard.modifiers(mods_depressed, mods_latched, mods_locked, group);
|
||||||
}
|
}
|
||||||
}
|
VirtualInput::Kde { fake_input: _ } => {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Event::Release() => {
|
Event::Release() => match self {
|
||||||
match self {
|
VirtualInput::Wlroots {
|
||||||
VirtualInput::Wlroots { pointer:_, keyboard } => {
|
pointer: _,
|
||||||
keyboard.modifiers(77, 0, 0, 0);
|
keyboard,
|
||||||
keyboard.modifiers(0, 0, 0, 0);
|
} => {
|
||||||
},
|
keyboard.modifiers(77, 0, 0, 0);
|
||||||
VirtualInput::Kde { fake_input:_ } => {},
|
keyboard.modifiers(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
VirtualInput::Kde { fake_input: _ } => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
9
src/backend/consumer/xdg_desktop_portal.rs
Normal file
9
src/backend/consumer/xdg_desktop_portal.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
|
use crate::{event::Event, client::{ClientHandle, Client}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) fn run(_consume_rx: Receiver<(Event, ClientHandle)>, _clients: Vec<Client>) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
6
src/backend/producer.rs
Normal file
6
src/backend/producer.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
pub mod wayland;
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub mod windows;
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
|
pub mod x11;
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
pub mod consumer;
|
|
||||||
pub mod producer;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
pub mod consumer;
|
|
||||||
pub mod producer;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
pub mod consumer;
|
|
||||||
pub mod producer;
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use crate::{config, dns};
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq, Clone, Copy)]
|
#[derive(Eq, Hash, PartialEq, Clone, Copy)]
|
||||||
pub enum Position {
|
pub enum Position {
|
||||||
Left,
|
Left,
|
||||||
@@ -34,19 +36,56 @@ pub struct ClientManager {
|
|||||||
pub type ClientHandle = u32;
|
pub type ClientHandle = u32;
|
||||||
|
|
||||||
impl ClientManager {
|
impl ClientManager {
|
||||||
|
fn add_client(&mut self, client: &config::Client, pos: Position) {
|
||||||
|
let ip = match client.ip {
|
||||||
|
Some(ip) => ip,
|
||||||
|
None => match &client.host_name {
|
||||||
|
Some(host_name) => match dns::resolve(host_name) {
|
||||||
|
Ok(ip) => ip,
|
||||||
|
Err(e) => panic!("{}", e),
|
||||||
|
},
|
||||||
|
None => panic!("neither ip nor hostname specified"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let addr = SocketAddr::new(ip, client.port.unwrap_or(42069));
|
||||||
|
self.register_client(addr, pos);
|
||||||
|
}
|
||||||
|
|
||||||
fn new_id(&mut self) -> ClientHandle {
|
fn new_id(&mut self) -> ClientHandle {
|
||||||
self.next_id += 1;
|
self.next_id += 1;
|
||||||
self.next_id
|
self.next_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new(config: &config::Config) -> Self {
|
||||||
ClientManager {
|
|
||||||
|
let mut client_manager = ClientManager {
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
clients: Vec::new(),
|
clients: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// add clients from config
|
||||||
|
for client in vec![
|
||||||
|
&config.client.left,
|
||||||
|
&config.client.right,
|
||||||
|
&config.client.top,
|
||||||
|
&config.client.bottom,
|
||||||
|
] {
|
||||||
|
if let Some(client) = client {
|
||||||
|
let pos = match client {
|
||||||
|
client if Some(client) == config.client.left.as_ref() => Position::Left,
|
||||||
|
client if Some(client) == config.client.right.as_ref() => Position::Right,
|
||||||
|
client if Some(client) == config.client.top.as_ref() => Position::Top,
|
||||||
|
client if Some(client) == config.client.bottom.as_ref() => Position::Bottom,
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
client_manager.add_client(client, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_manager
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_client(&mut self, addr: SocketAddr, pos: Position) {
|
pub fn register_client(&mut self, addr: SocketAddr, pos: Position) {
|
||||||
let handle = self.new_id();
|
let handle = self.new_id();
|
||||||
let client = Client { addr, pos, handle };
|
let client = Client { addr, pos, handle };
|
||||||
self.clients.push(client);
|
self.clients.push(client);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use toml;
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub client: Clients,
|
pub client: Clients,
|
||||||
pub port: Option<u16>,
|
pub port: Option<u16>,
|
||||||
|
pub backend: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
|||||||
70
src/consumer.rs
Normal file
70
src/consumer.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
use std::{thread::{JoinHandle, self}, env, sync::mpsc::Receiver};
|
||||||
|
|
||||||
|
use crate::{backend::consumer, client::{Client, ClientHandle}, event::Event};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Backend {
|
||||||
|
Wlroots,
|
||||||
|
X11,
|
||||||
|
RemoteDesktopPortal,
|
||||||
|
Libei,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(consume_rx: Receiver<(Event, ClientHandle)>, clients: Vec<Client>, backend: Option<String>) -> JoinHandle<()> {
|
||||||
|
thread::Builder::new()
|
||||||
|
.name("event consumer".into())
|
||||||
|
.spawn(move || {
|
||||||
|
#[cfg(windows)]
|
||||||
|
consumer::windows::run(consume_rx, clients);
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let backend = match env::var("XDG_SESSION_TYPE") {
|
||||||
|
Ok(session_type) => match session_type.as_str() {
|
||||||
|
"x11" => Backend::X11,
|
||||||
|
"wayland" => {
|
||||||
|
match backend {
|
||||||
|
Some(backend) => match backend.as_str() {
|
||||||
|
"wlroots" => Backend::Wlroots,
|
||||||
|
"libei" => Backend::Libei,
|
||||||
|
"xdg_desktop_portal" => Backend::RemoteDesktopPortal,
|
||||||
|
backend => panic!("invalid backend: {}", backend)
|
||||||
|
}
|
||||||
|
// default to wlroots backend for now
|
||||||
|
_ => Backend::Wlroots,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("unknown XDG_SESSION_TYPE"),
|
||||||
|
},
|
||||||
|
Err(_) => panic!("could not detect session type: XDG_SESSION_TYPE environment variable not set!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
match backend {
|
||||||
|
Backend::Libei => {
|
||||||
|
#[cfg(not(feature = "libei"))]
|
||||||
|
panic!("feature libei not enabled");
|
||||||
|
#[cfg(feature = "libei")]
|
||||||
|
consumer::libei::run(consume_rx, clients);
|
||||||
|
},
|
||||||
|
Backend::RemoteDesktopPortal => {
|
||||||
|
#[cfg(not(feature = "xdg_desktop_portal"))]
|
||||||
|
panic!("feature xdg_desktop_portal not enabled");
|
||||||
|
#[cfg(feature = "xdg_desktop_portal")]
|
||||||
|
consumer::xdg_desktop_portal::run(consume_rx, clients);
|
||||||
|
},
|
||||||
|
Backend::Wlroots => {
|
||||||
|
#[cfg(not(feature = "wayland"))]
|
||||||
|
panic!("feature wayland not enabled");
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
consumer::wlroots::run(consume_rx, clients);
|
||||||
|
},
|
||||||
|
Backend::X11 => {
|
||||||
|
#[cfg(not(feature = "x11"))]
|
||||||
|
panic!("feature x11 not enabled");
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
|
consumer::x11::run(consume_rx, clients);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
@@ -4,4 +4,7 @@ pub mod dns;
|
|||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
|
|
||||||
|
pub mod consumer;
|
||||||
|
pub mod producer;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
|
|||||||
107
src/main.rs
107
src/main.rs
@@ -1,34 +1,11 @@
|
|||||||
use std::{net::SocketAddr, sync::mpsc, thread};
|
use std::sync::mpsc;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use lan_mouse::{
|
use lan_mouse::{
|
||||||
client::{ClientManager, Position},
|
client::ClientManager,
|
||||||
config, dns, event, request,
|
consumer, producer,
|
||||||
|
config, event, request,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
use lan_mouse::backend::windows;
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
use lan_mouse::backend::{wayland, x11, Backend};
|
|
||||||
|
|
||||||
fn add_client(client_manager: &mut ClientManager, client: &config::Client, pos: Position) {
|
|
||||||
let ip = match client.ip {
|
|
||||||
Some(ip) => ip,
|
|
||||||
None => match &client.host_name {
|
|
||||||
Some(host_name) => match dns::resolve(host_name) {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// parse config file
|
// parse config file
|
||||||
let config = config::Config::new("config.toml").unwrap();
|
let config = config::Config::new("config.toml").unwrap();
|
||||||
@@ -42,83 +19,15 @@ pub fn main() {
|
|||||||
// event channel for consuming events
|
// event channel for consuming events
|
||||||
let (consume_tx, consume_rx) = mpsc::sync_channel(128);
|
let (consume_tx, consume_rx) = mpsc::sync_channel(128);
|
||||||
|
|
||||||
let mut client_manager = ClientManager::new();
|
// create client manager
|
||||||
|
let mut client_manager = ClientManager::new(&config);
|
||||||
// add clients from config
|
|
||||||
for client in vec![
|
|
||||||
&config.client.left,
|
|
||||||
&config.client.right,
|
|
||||||
&config.client.top,
|
|
||||||
&config.client.bottom,
|
|
||||||
] {
|
|
||||||
if let Some(client) = client {
|
|
||||||
let pos = match client {
|
|
||||||
client if Some(client) == config.client.left.as_ref() => Position::Left,
|
|
||||||
client if Some(client) == config.client.right.as_ref() => Position::Right,
|
|
||||||
client if Some(client) == config.client.top.as_ref() => Position::Top,
|
|
||||||
client if Some(client) == config.client.bottom.as_ref() => Position::Bottom,
|
|
||||||
_ => panic!(),
|
|
||||||
};
|
|
||||||
add_client(&mut client_manager, client, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start receiving client connection requests
|
// start receiving client connection requests
|
||||||
let (request_server, request_thread) = request::Server::listen(port).unwrap();
|
let (request_server, request_thread) = request::Server::listen(port).unwrap();
|
||||||
|
|
||||||
let clients = client_manager.get_clients();
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
let backend = match env::var("XDG_SESSION_TYPE") {
|
|
||||||
Ok(session_type) => match session_type.as_str() {
|
|
||||||
"x11" => Backend::X11,
|
|
||||||
"wayland" => Backend::WAYLAND,
|
|
||||||
_ => panic!("unknown XDG_SESSION_TYPE"),
|
|
||||||
},
|
|
||||||
Err(_) => panic!("could not detect session type"),
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
println!("using backend: windows");
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
println!(
|
|
||||||
"using backend: {}",
|
|
||||||
match backend {
|
|
||||||
Backend::X11 => "x11",
|
|
||||||
Backend::WAYLAND => "wayland",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// start producing and consuming events
|
// start producing and consuming events
|
||||||
let event_producer = thread::Builder::new()
|
let event_producer = producer::start(produce_tx, client_manager.get_clients(), request_server);
|
||||||
.name("event producer".into())
|
let event_consumer = consumer::start(consume_rx, client_manager.get_clients(), config.backend);
|
||||||
.spawn(move || {
|
|
||||||
#[cfg(windows)]
|
|
||||||
windows::producer::run(produce_tx, request_server, clients);
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
match backend {
|
|
||||||
Backend::X11 => x11::producer::run(produce_tx, request_server, clients),
|
|
||||||
Backend::WAYLAND => wayland::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(move || {
|
|
||||||
#[cfg(windows)]
|
|
||||||
windows::consumer::run(consume_rx, clients);
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
match backend {
|
|
||||||
Backend::X11 => x11::consumer::run(consume_rx, clients),
|
|
||||||
Backend::WAYLAND => wayland::consumer::run(consume_rx, clients),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// start sending and receiving events
|
// start sending and receiving events
|
||||||
let event_server = event::server::Server::new(port);
|
let event_server = event::server::Server::new(port);
|
||||||
|
|||||||
52
src/producer.rs
Normal file
52
src/producer.rs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#[cfg(unix)]
|
||||||
|
use std::env;
|
||||||
|
use std::{thread::{JoinHandle, self}, sync::mpsc::SyncSender};
|
||||||
|
|
||||||
|
use crate::{client::{Client, ClientHandle}, event::Event, request::Server};
|
||||||
|
|
||||||
|
use crate::backend::producer;
|
||||||
|
|
||||||
|
enum Backend {
|
||||||
|
Wayland,
|
||||||
|
X11,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(
|
||||||
|
produce_tx: SyncSender<(Event, ClientHandle)>,
|
||||||
|
clients: Vec<Client>,
|
||||||
|
request_server: Server,
|
||||||
|
) -> JoinHandle<()> {
|
||||||
|
thread::Builder::new()
|
||||||
|
.name("event producer".into())
|
||||||
|
.spawn(move || {
|
||||||
|
#[cfg(windows)]
|
||||||
|
producer::windows::run(produce_tx, request_server, clients);
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let backend = match env::var("XDG_SESSION_TYPE") {
|
||||||
|
Ok(session_type) => match session_type.as_str() {
|
||||||
|
"x11" => Backend::X11,
|
||||||
|
"wayland" => Backend::Wayland,
|
||||||
|
_ => panic!("unknown XDG_SESSION_TYPE"),
|
||||||
|
},
|
||||||
|
Err(_) => panic!("could not detect session type: XDG_SESSION_TYPE environment variable not set!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
match backend {
|
||||||
|
Backend::X11 => {
|
||||||
|
#[cfg(not(feature = "x11"))]
|
||||||
|
panic!("feature x11 not enabled");
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
|
producer::x11::run(produce_tx, request_server, clients);
|
||||||
|
}
|
||||||
|
Backend::Wayland => {
|
||||||
|
#[cfg(not(feature = "wayland"))]
|
||||||
|
panic!("feature wayland not enabled");
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
producer::wayland::run(produce_tx, request_server, clients);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user