mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-10 10:21:27 +03:00
Merge pull request #1 from ferdinandschober/conditional-compilation-of-backends
enable conditional compilation for all 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(all(unix, feature="x11"))]
|
||||||
|
pub mod x11;
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "wayland"))]
|
||||||
|
pub mod wlroots;
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "xdg_desktop_portal"))]
|
||||||
|
pub mod xdg_desktop_portal;
|
||||||
|
|
||||||
|
#[cfg(all(unix, 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(all(unix, feature = "wayland"))]
|
||||||
|
pub mod wayland;
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub mod windows;
|
||||||
|
#[cfg(all(unix, 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