diff --git a/Cargo.toml b/Cargo.toml index e411127..30f77ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,6 @@ members = [ default-members = ["qemu-rdw"] [patch.crates-io] -zbus = { git = 'https://gitlab.freedesktop.org/dbus/zbus.git' } -zvariant = { git = 'https://gitlab.freedesktop.org/dbus/zbus.git' } +zbus = { git = 'https://gitlab.freedesktop.org/elmarco/zbus.git', branch = 'proxy-prop' } +zvariant = { git = 'https://gitlab.freedesktop.org/elmarco/zbus.git', branch = 'proxy-prop' } vnc = { git = 'https://github.com/elmarco/rust-vnc', branch = 'server' } diff --git a/qemu-display-listener/Cargo.toml b/qemu-display-listener/Cargo.toml index 0025a9b..48681dd 100644 --- a/qemu-display-listener/Cargo.toml +++ b/qemu-display-listener/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +log = "0.4" derivative = "2.2.0" zbus = { version = "2.0.0-beta", features = ["xml"] } zvariant = { version = "2.4.0", features = ["serde_bytes"] } @@ -16,3 +17,4 @@ enumflags2 = { version = "0.6.4", features = ["serde"] } serde = { version = "1.0.123", features = ["derive"] } serde_repr = "0.1.6" serde_bytes = "0.11.5" +futures-util = { version = "0.3.8", features = ["async-await-macro"] } diff --git a/qemu-display-listener/src/console.rs b/qemu-display-listener/src/console.rs index 908c0b1..d60dea0 100644 --- a/qemu-display-listener/src/console.rs +++ b/qemu-display-listener/src/console.rs @@ -54,9 +54,12 @@ pub struct Console { impl Console { pub async fn new(conn: &zbus::azync::Connection, idx: u32) -> Result { let obj_path = format!("/org/qemu/Display1/Console_{}", idx); - let proxy = AsyncConsoleProxy::new_for_owned_path(conn.clone(), obj_path.clone())?; - let keyboard = AsyncKeyboardProxy::new_for_owned_path(conn.clone(), obj_path.clone())?; - let mouse = AsyncMouseProxy::new_for_owned_path(conn.clone(), obj_path)?; + let mut proxy = AsyncConsoleProxy::new_for_owned_path(conn.clone(), obj_path.clone())?; + proxy.cache_properties().await; + let mut keyboard = AsyncKeyboardProxy::new_for_owned_path(conn.clone(), obj_path.clone())?; + keyboard.cache_properties().await; + let mut mouse = AsyncMouseProxy::new_for_owned_path(conn.clone(), obj_path)?; + mouse.cache_properties().await; Ok(Self { proxy, keyboard, @@ -64,6 +67,31 @@ impl Console { }) } + pub async fn dispatch_signals(&self) -> Result<()> { + use futures_util::{future::FutureExt, select}; + + select!( + msg = self.proxy.next_signal().fuse() => { + if let Some(msg) = msg? { + log::debug!("Ignoring {:?}", msg); + } + return Ok(()); + }, + msg = self.keyboard.next_signal().fuse() => { + if let Some(msg) = msg? { + log::debug!("Ignoring {:?}", msg); + } + return Ok(()); + }, + msg = self.mouse.next_signal().fuse() => { + if let Some(msg) = msg? { + log::debug!("Ignoring {:?}", msg); + } + return Ok(()); + } + ); + } + pub async fn label(&self) -> Result { Ok(self.proxy.label().await?) } diff --git a/qemu-rdw/Cargo.toml b/qemu-rdw/Cargo.toml index 3dfaebd..f1d148a 100644 --- a/qemu-rdw/Cargo.toml +++ b/qemu-rdw/Cargo.toml @@ -15,3 +15,4 @@ qemu-display-listener = { path = "../qemu-display-listener", features = ["glib"] keycodemap = { path = "../keycodemap" } gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs" } rdw = { git = "https://gitlab.gnome.org/malureau/rdw.git" } +futures-util = "0.3.13" diff --git a/qemu-rdw/src/display_qemu.rs b/qemu-rdw/src/display_qemu.rs index 9cacbad..6747dbe 100644 --- a/qemu-rdw/src/display_qemu.rs +++ b/qemu-rdw/src/display_qemu.rs @@ -1,4 +1,4 @@ -use glib::{clone, subclass::prelude::*, translate::*, MainContext}; +use glib::{clone, subclass::prelude::*, MainContext}; use gtk::{glib, prelude::*}; use once_cell::sync::OnceCell; @@ -8,8 +8,9 @@ use rdw::DisplayExt; mod imp { use super::*; + use futures_util::future::FutureExt; use gtk::subclass::prelude::*; - use std::os::unix::io::IntoRawFd; + use std::{convert::TryInto, os::unix::io::IntoRawFd}; #[repr(C)] pub struct RdwDisplayQemuClass { @@ -140,6 +141,7 @@ mod imp { MainContext::default().spawn_local(clone!(@weak widget => async move { let self_ = Self::from_instance(&widget); let console = self_.console.get().unwrap(); + let (rx, wait_tx) = console .glib_listen() .await @@ -206,6 +208,19 @@ mod imp { Continue(true) }) ); + + console.mouse.connect_is_absolute_changed(clone!(@strong widget => @default-panic, move |v| { + widget.set_mouse_absolute(v.map_or(true, |v| v.try_into().unwrap_or(true))); + async move { + }.boxed() + })).await.unwrap(); + + loop { + if let Err(e) = console.dispatch_signals().await { + log::warn!("Console dispatching error: {}", e); + break; + } + } })); } } diff --git a/qemu-rdw/src/main.rs b/qemu-rdw/src/main.rs index f6fcd61..484aecd 100644 --- a/qemu-rdw/src/main.rs +++ b/qemu-rdw/src/main.rs @@ -1,4 +1,3 @@ -use std::error::Error; use gio::ApplicationFlags; use glib::{clone, MainContext}; use gtk::{gio, glib, prelude::*}; @@ -12,7 +11,9 @@ fn main() { let app = gtk::Application::new(Some("org.qemu.rdw.demo"), ApplicationFlags::NON_UNIQUE); - let conn: zbus::azync::Connection = Connection::new_session().expect("Failed to connect to DBus").into(); + let conn: zbus::azync::Connection = Connection::new_session() + .expect("Failed to connect to DBus") + .into(); app.connect_activate(move |app| { let window = gtk::ApplicationWindow::new(app);