From 377997c6d2eff531846c713a434b8367b00a07ed Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Tue, 3 Sep 2024 00:52:48 +0200 Subject: [PATCH] extract frontend crate --- Cargo.lock | 56 +++- Cargo.toml | 28 +- README.md | 2 +- build.rs | 8 - lan-mouse-cli/Cargo.toml | 18 + .../cli => lan-mouse-cli/src}/command.rs | 2 +- .../cli.rs => lan-mouse-cli/src/lib.rs | 144 ++++---- lan-mouse-gtk/Cargo.toml | 18 + lan-mouse-gtk/build.rs | 8 + .../resources}/client_row.ui | 0 .../resources}/de.feschber.LanMouse.svg | 0 .../resources}/resources.gresource.xml | 0 .../resources}/window.ui | 0 .../src}/client_object.rs | 2 +- .../src}/client_object/imp.rs | 2 +- .../gtk => lan-mouse-gtk/src}/client_row.rs | 2 +- .../src}/client_row/imp.rs | 0 .../gtk.rs => lan-mouse-gtk/src/lib.rs | 57 +--- .../gtk => lan-mouse-gtk/src}/window.rs | 44 +-- .../gtk => lan-mouse-gtk/src}/window/imp.rs | 12 +- lan-mouse-ipc/Cargo.toml | 16 + lan-mouse-ipc/src/connect.rs | 89 +++++ lan-mouse-ipc/src/connect_async.rs | 104 ++++++ lan-mouse-ipc/src/lib.rs | 262 +++++++++++++++ lan-mouse-ipc/src/listen.rs | 147 +++++++++ src/capture_test.rs | 9 +- src/client.rs | 131 +------- src/config.rs | 26 +- src/dns.rs | 3 +- src/emulation_test.rs | 12 +- src/frontend.rs | 307 ------------------ src/lib.rs | 1 - src/main.rs | 60 +++- src/server.rs | 117 +++---- src/server/capture_task.rs | 14 +- src/server/emulation_task.rs | 9 +- src/server/ping_task.rs | 2 +- 37 files changed, 959 insertions(+), 753 deletions(-) create mode 100644 lan-mouse-cli/Cargo.toml rename {src/frontend/cli => lan-mouse-cli/src}/command.rs (99%) rename src/frontend/cli.rs => lan-mouse-cli/src/lib.rs (69%) create mode 100644 lan-mouse-gtk/Cargo.toml create mode 100644 lan-mouse-gtk/build.rs rename {resources => lan-mouse-gtk/resources}/client_row.ui (100%) rename {resources => lan-mouse-gtk/resources}/de.feschber.LanMouse.svg (100%) rename {resources => lan-mouse-gtk/resources}/resources.gresource.xml (100%) rename {resources => lan-mouse-gtk/resources}/window.ui (100%) rename {src/frontend/gtk => lan-mouse-gtk/src}/client_object.rs (94%) rename {src/frontend/gtk => lan-mouse-gtk/src}/client_object/imp.rs (96%) rename {src/frontend/gtk => lan-mouse-gtk/src}/client_row.rs (99%) rename {src/frontend/gtk => lan-mouse-gtk/src}/client_row/imp.rs (100%) rename src/frontend/gtk.rs => lan-mouse-gtk/src/lib.rs (74%) rename {src/frontend/gtk => lan-mouse-gtk/src}/window.rs (91%) rename {src/frontend/gtk => lan-mouse-gtk/src}/window/imp.rs (94%) create mode 100644 lan-mouse-ipc/Cargo.toml create mode 100644 lan-mouse-ipc/src/connect.rs create mode 100644 lan-mouse-ipc/src/connect_async.rs create mode 100644 lan-mouse-ipc/src/lib.rs create mode 100644 lan-mouse-ipc/src/listen.rs delete mode 100644 src/frontend.rs diff --git a/Cargo.lock b/Cargo.lock index dc36c3f..5979fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1313,21 +1313,17 @@ dependencies = [ name = "lan-mouse" version = "0.9.1" dependencies = [ - "anyhow", - "async-channel", "clap", - "endi", "env_logger", "futures", - "glib-build-tools", - "gtk4", "hickory-resolver", - "hostname 0.4.0", "input-capture", "input-emulation", "input-event", + "lan-mouse-cli", + "lan-mouse-gtk", + "lan-mouse-ipc", "lan-mouse-proto", - "libadwaita", "libc", "local-channel", "log", @@ -1340,6 +1336,41 @@ dependencies = [ "toml", ] +[[package]] +name = "lan-mouse-cli" +version = "0.1.0" +dependencies = [ + "futures", + "lan-mouse-ipc", + "tokio", +] + +[[package]] +name = "lan-mouse-gtk" +version = "0.1.0" +dependencies = [ + "async-channel", + "glib-build-tools", + "gtk4", + "hostname 0.4.0", + "lan-mouse-ipc", + "libadwaita", + "log", +] + +[[package]] +name = "lan-mouse-ipc" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + [[package]] name = "lan-mouse-proto" version = "0.1.0" @@ -2090,6 +2121,17 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" diff --git a/Cargo.toml b/Cargo.toml index 698eccc..5e36f4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,13 @@ [workspace] -members = ["input-capture", "input-emulation", "input-event", "lan-mouse-proto"] +members = [ + "input-capture", + "input-emulation", + "input-event", + "lan-mouse-ipc", + "lan-mouse-cli", + "lan-mouse-gtk", + "lan-mouse-proto", +] [package] name = "lan-mouse" @@ -17,12 +25,14 @@ lto = "fat" input-event = { path = "input-event", version = "0.2.1" } input-emulation = { path = "input-emulation", version = "0.2.1", default-features = false } input-capture = { path = "input-capture", version = "0.2.0", default-features = false } +lan-mouse-cli = { path = "lan-mouse-cli", version = "0.1.0" } +lan-mouse-gtk = { path = "lan-mouse-gtk", version = "0.1.0", optional = true } +lan-mouse-ipc = { path = "lan-mouse-ipc", version = "0.1.0" } lan-mouse-proto = { path = "lan-mouse-proto", version = "0.1.0" } hickory-resolver = "0.24.1" toml = "0.8" serde = { version = "1.0", features = ["derive"] } -anyhow = "1.0.71" log = "0.4.20" env_logger = "0.11.3" serde_json = "1.0.107" @@ -38,16 +48,7 @@ tokio = { version = "1.32.0", features = [ ] } futures = "0.3.28" clap = { version = "4.4.11", features = ["derive"] } -gtk = { package = "gtk4", version = "0.9.0", features = [ - "v4_2", -], optional = true } -adw = { package = "libadwaita", version = "0.7.0", features = [ - "v1_1", -], optional = true } -async-channel = { version = "2.1.1", optional = true } -hostname = "0.4.0" slab = "0.4.9" -endi = "1.1.0" thiserror = "1.0.61" tokio-util = "0.7.11" local-channel = "0.1.5" @@ -55,13 +56,10 @@ local-channel = "0.1.5" [target.'cfg(unix)'.dependencies] libc = "0.2.148" -[build-dependencies] -glib-build-tools = { version = "0.20.0", optional = true } - [features] default = ["wayland", "x11", "xdg_desktop_portal", "libei", "gtk"] wayland = ["input-capture/wayland", "input-emulation/wayland"] x11 = ["input-capture/x11", "input-emulation/x11"] xdg_desktop_portal = ["input-emulation/xdg_desktop_portal"] libei = ["input-event/libei", "input-capture/libei", "input-emulation/libei"] -gtk = ["dep:gtk", "dep:adw", "dep:async-channel", "dep:glib-build-tools"] +gtk = ["dep:lan-mouse-gtk"] diff --git a/README.md b/README.md index a64c132..135bb1a 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ sudo cp target/release/lan-mouse /usr/local/bin/ # install app icon sudo mkdir -p /usr/local/share/icons/hicolor/scalable/apps -sudo cp resources/de.feschber.LanMouse.svg /usr/local/share/icons/hicolor/scalable/apps +sudo cp lan-mouse-gtk/resources/de.feschber.LanMouse.svg /usr/local/share/icons/hicolor/scalable/apps # update icon cache gtk-update-icon-cache /usr/local/share/icons/hicolor/ diff --git a/build.rs b/build.rs index 48d1848..7c4ba47 100644 --- a/build.rs +++ b/build.rs @@ -12,12 +12,4 @@ fn main() { let git_describe = String::from_utf8(git_describe.stdout).unwrap(); println!("cargo::rustc-env=GIT_DESCRIBE={git_describe}"); - - // composite_templates - #[cfg(feature = "gtk")] - glib_build_tools::compile_resources( - &["resources"], - "resources/resources.gresource.xml", - "lan-mouse.gresource", - ); } diff --git a/lan-mouse-cli/Cargo.toml b/lan-mouse-cli/Cargo.toml new file mode 100644 index 0000000..90c6e23 --- /dev/null +++ b/lan-mouse-cli/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "lan-mouse-cli" +description = "CLI Frontend for lan-mouse" +version = "0.1.0" +edition = "2021" +license = "GPL-3.0-or-later" +repository = "https://github.com/feschber/lan-mouse" + +[dependencies] +futures = "0.3.30" +lan-mouse-ipc = { path = "../lan-mouse-ipc", version = "0.1.0" } +tokio = { version = "1.32.0", features = [ + "io-util", + "io-std", + "macros", + "net", + "rt", +] } diff --git a/src/frontend/cli/command.rs b/lan-mouse-cli/src/command.rs similarity index 99% rename from src/frontend/cli/command.rs rename to lan-mouse-cli/src/command.rs index 6d49ca1..2bbb906 100644 --- a/src/frontend/cli/command.rs +++ b/lan-mouse-cli/src/command.rs @@ -3,7 +3,7 @@ use std::{ str::{FromStr, SplitWhitespace}, }; -use crate::client::{ClientHandle, Position}; +use lan_mouse_ipc::{ClientHandle, Position}; pub(super) enum CommandType { NoCommand, diff --git a/src/frontend/cli.rs b/lan-mouse-cli/src/lib.rs similarity index 69% rename from src/frontend/cli.rs rename to lan-mouse-cli/src/lib.rs index 4224bb4..9347f14 100644 --- a/src/frontend/cli.rs +++ b/lan-mouse-cli/src/lib.rs @@ -1,58 +1,41 @@ -use anyhow::{anyhow, Result}; +use futures::StreamExt; use tokio::{ - io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader}, + io::{AsyncBufReadExt, BufReader}, task::LocalSet, }; -#[cfg(windows)] -use tokio::net::tcp::{ReadHalf, WriteHalf}; -#[cfg(unix)] -use tokio::net::unix::{ReadHalf, WriteHalf}; - use std::io::{self, Write}; -use crate::{ - client::{ClientConfig, ClientHandle, ClientState}, - config::DEFAULT_PORT, -}; - use self::command::{Command, CommandType}; -use super::{FrontendEvent, FrontendRequest}; +use lan_mouse_ipc::{ + AsyncFrontendEventReader, AsyncFrontendRequestWriter, ClientConfig, ClientHandle, ClientState, + FrontendEvent, FrontendRequest, IpcError, DEFAULT_PORT, +}; mod command; -pub fn run() -> Result<()> { - let Ok(stream) = super::wait_for_service() else { - return Err(anyhow!("Could not connect to lan-mouse-socket")); - }; - +pub fn run() -> Result<(), IpcError> { let runtime = tokio::runtime::Builder::new_current_thread() .enable_io() .enable_time() .build()?; runtime.block_on(LocalSet::new().run_until(async move { - stream.set_nonblocking(true)?; - #[cfg(unix)] - let mut stream = tokio::net::UnixStream::from_std(stream)?; - #[cfg(windows)] - let mut stream = tokio::net::TcpStream::from_std(stream)?; - let (rx, tx) = stream.split(); - + let (rx, tx) = lan_mouse_ipc::connect_async().await?; let mut cli = Cli::new(rx, tx); cli.run().await }))?; Ok(()) } -struct Cli<'a> { +struct Cli { clients: Vec<(ClientHandle, ClientConfig, ClientState)>, - rx: ReadHalf<'a>, - tx: WriteHalf<'a>, + rx: AsyncFrontendEventReader, + tx: AsyncFrontendRequestWriter, } -impl<'a> Cli<'a> { - fn new(rx: ReadHalf<'a>, tx: WriteHalf<'a>) -> Cli<'a> { +impl Cli { + fn new(rx: AsyncFrontendEventReader, tx: AsyncFrontendRequestWriter) -> Cli { Self { clients: vec![], rx, @@ -60,19 +43,21 @@ impl<'a> Cli<'a> { } } - async fn run(&mut self) -> Result<()> { + async fn run(&mut self) -> Result<(), IpcError> { let stdin = tokio::io::stdin(); let stdin = BufReader::new(stdin); let mut stdin = stdin.lines(); /* initial state sync */ - let request = FrontendRequest::Enumerate(); - self.send_request(request).await?; - self.clients = loop { - let event = self.await_event().await?; - if let FrontendEvent::Enumerate(clients) = event { - break clients; + match self.rx.next().await { + Some(Ok(e)) => { + if let FrontendEvent::Enumerate(clients) = e { + break clients; + } + } + Some(Err(e)) => return Err(e), + None => return Ok(()), } }; @@ -92,18 +77,18 @@ impl<'a> Cli<'a> { }; self.execute(cmd).await?; } - event = self.await_event() => { - let event = event?; - self.handle_event(event); + event = self.rx.next() => { + if let Some(event) = event { + self.handle_event(event?); + } } } } } - async fn update_client(&mut self, handle: ClientHandle) -> Result<()> { - self.send_request(FrontendRequest::GetState(handle)).await?; - loop { - let event = self.await_event().await?; + async fn update_client(&mut self, handle: ClientHandle) -> Result<(), IpcError> { + self.tx.request(FrontendRequest::GetState(handle)).await?; + while let Some(Ok(event)) = self.rx.next().await { self.handle_event(event.clone()); if let FrontendEvent::State(_, _, _) | FrontendEvent::NoSuchClient(_) = event { break; @@ -112,22 +97,23 @@ impl<'a> Cli<'a> { Ok(()) } - async fn execute(&mut self, cmd: Command) -> Result<()> { + async fn execute(&mut self, cmd: Command) -> Result<(), IpcError> { match cmd { Command::None => {} Command::Connect(pos, host, port) => { let request = FrontendRequest::Create; - self.send_request(request).await?; + self.tx.request(request).await?; let handle = loop { - let event = self.await_event().await?; - match event { - FrontendEvent::Created(h, c, s) => { - self.clients.push((h, c, s)); - break h; - } - _ => { - self.handle_event(event); - continue; + if let Some(Ok(event)) = self.rx.next().await { + match event { + FrontendEvent::Created(h, c, s) => { + self.clients.push((h, c, s)); + break h; + } + _ => { + self.handle_event(event); + continue; + } } } }; @@ -136,35 +122,36 @@ impl<'a> Cli<'a> { FrontendRequest::UpdatePort(handle, port.unwrap_or(DEFAULT_PORT)), FrontendRequest::UpdatePosition(handle, pos), ] { - self.send_request(request).await?; + self.tx.request(request).await?; } self.update_client(handle).await?; } Command::Disconnect(id) => { - self.send_request(FrontendRequest::Delete(id)).await?; + self.tx.request(FrontendRequest::Delete(id)).await?; loop { - let event = self.await_event().await?; - self.handle_event(event.clone()); - if let FrontendEvent::Deleted(_) = event { - self.handle_event(event); - break; + if let Some(Ok(event)) = self.rx.next().await { + self.handle_event(event.clone()); + if let FrontendEvent::Deleted(_) = event { + self.handle_event(event); + break; + } } } } Command::Activate(id) => { - self.send_request(FrontendRequest::Activate(id, true)) - .await?; + self.tx.request(FrontendRequest::Activate(id, true)).await?; self.update_client(id).await?; } Command::Deactivate(id) => { - self.send_request(FrontendRequest::Activate(id, false)) + self.tx + .request(FrontendRequest::Activate(id, false)) .await?; self.update_client(id).await?; } Command::List => { - self.send_request(FrontendRequest::Enumerate()).await?; - loop { - let event = self.await_event().await?; + self.tx.request(FrontendRequest::Enumerate()).await?; + while let Some(e) = self.rx.next().await { + let event = e?; self.handle_event(event.clone()); if let FrontendEvent::Enumerate(_) = event { break; @@ -173,12 +160,12 @@ impl<'a> Cli<'a> { } Command::SetHost(handle, host) => { let request = FrontendRequest::UpdateHostname(handle, Some(host.clone())); - self.send_request(request).await?; + self.tx.request(request).await?; self.update_client(handle).await?; } Command::SetPort(handle, port) => { let request = FrontendRequest::UpdatePort(handle, port.unwrap_or(DEFAULT_PORT)); - self.send_request(request).await?; + self.tx.request(request).await?; self.update_client(handle).await?; } Command::Help => { @@ -291,23 +278,6 @@ impl<'a> Cli<'a> { eprintln!(); } } - - async fn send_request(&mut self, request: FrontendRequest) -> io::Result<()> { - let json = serde_json::to_string(&request).unwrap(); - let bytes = json.as_bytes(); - let len = bytes.len(); - self.tx.write_u64(len as u64).await?; - self.tx.write_all(bytes).await?; - Ok(()) - } - - async fn await_event(&mut self) -> Result { - let len = self.rx.read_u64().await?; - let mut buf = vec![0u8; len as usize]; - self.rx.read_exact(&mut buf).await?; - let event: FrontendEvent = serde_json::from_slice(&buf)?; - Ok(event) - } } fn prompt() -> io::Result<()> { diff --git a/lan-mouse-gtk/Cargo.toml b/lan-mouse-gtk/Cargo.toml new file mode 100644 index 0000000..d6266c6 --- /dev/null +++ b/lan-mouse-gtk/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "lan-mouse-gtk" +description = "GTK4 / Libadwaita Frontend for lan-mouse" +version = "0.1.0" +edition = "2021" +license = "GPL-3.0-or-later" +repository = "https://github.com/feschber/lan-mouse" + +[dependencies] +gtk = { package = "gtk4", version = "0.9.0", features = ["v4_2"] } +adw = { package = "libadwaita", version = "0.7.0", features = ["v1_1"] } +async-channel = { version = "2.1.1" } +hostname = "0.4.0" +log = "0.4.20" +lan-mouse-ipc = { path = "../lan-mouse-ipc", version = "0.1.0" } + +[build-dependencies] +glib-build-tools = { version = "0.20.0" } diff --git a/lan-mouse-gtk/build.rs b/lan-mouse-gtk/build.rs new file mode 100644 index 0000000..bf1a701 --- /dev/null +++ b/lan-mouse-gtk/build.rs @@ -0,0 +1,8 @@ +fn main() { + // composite_templates + glib_build_tools::compile_resources( + &["resources"], + "resources/resources.gresource.xml", + "lan-mouse.gresource", + ); +} diff --git a/resources/client_row.ui b/lan-mouse-gtk/resources/client_row.ui similarity index 100% rename from resources/client_row.ui rename to lan-mouse-gtk/resources/client_row.ui diff --git a/resources/de.feschber.LanMouse.svg b/lan-mouse-gtk/resources/de.feschber.LanMouse.svg similarity index 100% rename from resources/de.feschber.LanMouse.svg rename to lan-mouse-gtk/resources/de.feschber.LanMouse.svg diff --git a/resources/resources.gresource.xml b/lan-mouse-gtk/resources/resources.gresource.xml similarity index 100% rename from resources/resources.gresource.xml rename to lan-mouse-gtk/resources/resources.gresource.xml diff --git a/resources/window.ui b/lan-mouse-gtk/resources/window.ui similarity index 100% rename from resources/window.ui rename to lan-mouse-gtk/resources/window.ui diff --git a/src/frontend/gtk/client_object.rs b/lan-mouse-gtk/src/client_object.rs similarity index 94% rename from src/frontend/gtk/client_object.rs rename to lan-mouse-gtk/src/client_object.rs index a9da3b1..9f148fd 100644 --- a/src/frontend/gtk/client_object.rs +++ b/lan-mouse-gtk/src/client_object.rs @@ -3,7 +3,7 @@ mod imp; use adw::subclass::prelude::*; use gtk::glib::{self, Object}; -use crate::client::{ClientConfig, ClientHandle, ClientState}; +use lan_mouse_ipc::{ClientConfig, ClientHandle, ClientState}; glib::wrapper! { pub struct ClientObject(ObjectSubclass); diff --git a/src/frontend/gtk/client_object/imp.rs b/lan-mouse-gtk/src/client_object/imp.rs similarity index 96% rename from src/frontend/gtk/client_object/imp.rs rename to lan-mouse-gtk/src/client_object/imp.rs index 03e9e95..fbcd5db 100644 --- a/src/frontend/gtk/client_object/imp.rs +++ b/lan-mouse-gtk/src/client_object/imp.rs @@ -5,7 +5,7 @@ use gtk::glib; use gtk::prelude::*; use gtk::subclass::prelude::*; -use crate::client::ClientHandle; +use lan_mouse_ipc::ClientHandle; use super::ClientData; diff --git a/src/frontend/gtk/client_row.rs b/lan-mouse-gtk/src/client_row.rs similarity index 99% rename from src/frontend/gtk/client_row.rs rename to lan-mouse-gtk/src/client_row.rs index 58e11cf..bcbad7e 100644 --- a/src/frontend/gtk/client_row.rs +++ b/lan-mouse-gtk/src/client_row.rs @@ -4,7 +4,7 @@ use adw::prelude::*; use adw::subclass::prelude::*; use gtk::glib::{self, Object}; -use crate::config::DEFAULT_PORT; +use lan_mouse_ipc::DEFAULT_PORT; use super::ClientObject; diff --git a/src/frontend/gtk/client_row/imp.rs b/lan-mouse-gtk/src/client_row/imp.rs similarity index 100% rename from src/frontend/gtk/client_row/imp.rs rename to lan-mouse-gtk/src/client_row/imp.rs diff --git a/src/frontend/gtk.rs b/lan-mouse-gtk/src/lib.rs similarity index 74% rename from src/frontend/gtk.rs rename to lan-mouse-gtk/src/lib.rs index b691141..066ead2 100644 --- a/src/frontend/gtk.rs +++ b/lan-mouse-gtk/src/lib.rs @@ -2,16 +2,13 @@ mod client_object; mod client_row; mod window; -use std::{ - env, - io::{ErrorKind, Read}, - process, str, -}; +use std::{env, process, str}; -use crate::frontend::gtk::window::Window; +use window::Window; + +use lan_mouse_ipc::FrontendEvent; use adw::Application; -use endi::{Endian, ReadBytes}; use gtk::{ gdk::Display, glib::clone, prelude::*, subclass::prelude::ObjectSubclassIsExt, IconTheme, }; @@ -19,8 +16,6 @@ use gtk::{gio, glib, prelude::ApplicationExt}; use self::client_object::ClientObject; -use super::FrontendEvent; - pub fn run() -> glib::ExitCode { log::debug!("running gtk frontend"); #[cfg(windows)] @@ -65,15 +60,8 @@ fn load_icons() { fn build_ui(app: &Application) { log::debug!("connecting to lan-mouse-socket"); - let mut rx = match super::wait_for_service() { - Ok(stream) => stream, - Err(e) => { - log::error!("could not connect to lan-mouse-socket: {e}"); - process::exit(1); - } - }; - let tx = match rx.try_clone() { - Ok(sock) => sock, + let (mut frontend_rx, frontend_tx) = match lan_mouse_ipc::connect() { + Ok(conn) => conn, Err(e) => { log::error!("{e}"); process::exit(1); @@ -84,35 +72,18 @@ fn build_ui(app: &Application) { let (sender, receiver) = async_channel::bounded(10); gio::spawn_blocking(move || { - match loop { - // read length - let len = match rx.read_u64(Endian::Big) { - Ok(l) => l, - Err(e) if e.kind() == ErrorKind::UnexpectedEof => break Ok(()), - Err(e) => break Err(e), - }; - - // read payload - let mut buf = vec![0u8; len as usize]; - match rx.read_exact(&mut buf) { - Ok(_) => (), - Err(e) if e.kind() == ErrorKind::UnexpectedEof => break Ok(()), - Err(e) => break Err(e), - }; - - // parse json - let json = str::from_utf8(&buf).unwrap(); - match serde_json::from_str(json) { - Ok(notify) => sender.send_blocking(notify).unwrap(), - Err(e) => log::error!("{e}"), + while let Some(e) = frontend_rx.next_event() { + match e { + Ok(e) => sender.send_blocking(e).unwrap(), + Err(e) => { + log::error!("{e}"); + break; + } } - } { - Ok(()) => {} - Err(e) => log::error!("{e}"), } }); - let window = Window::new(app, tx); + let window = Window::new(app, frontend_tx); glib::spawn_future_local(clone!( #[weak] diff --git a/src/frontend/gtk/window.rs b/lan-mouse-gtk/src/window.rs similarity index 91% rename from src/frontend/gtk/window.rs rename to lan-mouse-gtk/src/window.rs index aeb1b49..febc838 100644 --- a/src/frontend/gtk/window.rs +++ b/lan-mouse-gtk/src/window.rs @@ -1,16 +1,7 @@ mod imp; -use std::io::Write; - -#[cfg(unix)] -use std::os::unix::net::UnixStream; - -#[cfg(windows)] -use std::net::TcpStream; - use adw::prelude::*; use adw::subclass::prelude::*; -use endi::{Endian, WriteBytes}; use glib::{clone, Object}; use gtk::{ gio, @@ -18,13 +9,12 @@ use gtk::{ ListBox, NoSelection, }; -use crate::{ - client::{ClientConfig, ClientHandle, ClientState, Position}, - config::DEFAULT_PORT, - frontend::{gtk::client_object::ClientObject, FrontendRequest}, +use lan_mouse_ipc::{ + ClientConfig, ClientHandle, ClientState, FrontendRequest, FrontendRequestWriter, Position, + DEFAULT_PORT, }; -use super::client_row::ClientRow; +use super::{client_object::ClientObject, client_row::ClientRow}; glib::wrapper! { pub struct Window(ObjectSubclass) @@ -34,13 +24,13 @@ glib::wrapper! { } impl Window { - pub(crate) fn new( - app: &adw::Application, - #[cfg(unix)] tx: UnixStream, - #[cfg(windows)] tx: TcpStream, - ) -> Self { + pub(crate) fn new(app: &adw::Application, conn: FrontendRequestWriter) -> Self { let window: Self = Object::builder().property("application", app).build(); - window.imp().stream.borrow_mut().replace(tx); + window + .imp() + .frontend_request_writer + .borrow_mut() + .replace(conn); window } @@ -292,16 +282,10 @@ impl Window { self.request(FrontendRequest::Delete(client.handle())); } - pub fn request(&self, event: FrontendRequest) { - let json = serde_json::to_string(&event).unwrap(); - log::debug!("requesting: {json}"); - let mut stream = self.imp().stream.borrow_mut(); - let stream = stream.as_mut().unwrap(); - let bytes = json.as_bytes(); - if let Err(e) = stream.write_u64(Endian::Big, bytes.len() as u64) { - log::error!("error sending message: {e}"); - }; - if let Err(e) = stream.write(bytes) { + pub fn request(&self, request: FrontendRequest) { + let mut requester = self.imp().frontend_request_writer.borrow_mut(); + let requester = requester.as_mut().unwrap(); + if let Err(e) = requester.request(request) { log::error!("error sending message: {e}"); }; } diff --git a/src/frontend/gtk/window/imp.rs b/lan-mouse-gtk/src/window/imp.rs similarity index 94% rename from src/frontend/gtk/window/imp.rs rename to lan-mouse-gtk/src/window/imp.rs index d520e46..b038242 100644 --- a/src/frontend/gtk/window/imp.rs +++ b/lan-mouse-gtk/src/window/imp.rs @@ -1,17 +1,12 @@ use std::cell::{Cell, RefCell}; -#[cfg(windows)] -use std::net::TcpStream; -#[cfg(unix)] -use std::os::unix::net::UnixStream; - use adw::subclass::prelude::*; use adw::{prelude::*, ActionRow, PreferencesGroup, ToastOverlay}; use glib::subclass::InitializingObject; use gtk::glib::clone; use gtk::{gdk, gio, glib, Button, CompositeTemplate, Entry, Label, ListBox}; -use crate::config::DEFAULT_PORT; +use lan_mouse_ipc::{FrontendRequestWriter, DEFAULT_PORT}; #[derive(CompositeTemplate, Default)] #[template(resource = "/de/feschber/LanMouse/window.ui")] @@ -41,10 +36,7 @@ pub struct Window { #[template_child] pub input_capture_button: TemplateChild