From 13db197622262dc8aae045e3a9c8b04d31f62d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 17 Dec 2021 18:22:30 +0400 Subject: [PATCH] WIP: reconnect --- qemu-display/src/display.rs | 44 ++++++++++++++++++++++++++----------- qemu-rdw/src/main.rs | 12 +++++++++- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/qemu-display/src/display.rs b/qemu-display/src/display.rs index fe9e83c..42e6ef9 100644 --- a/qemu-display/src/display.rs +++ b/qemu-display/src/display.rs @@ -2,23 +2,30 @@ use futures::stream::{self, StreamExt}; use std::{ collections::HashMap, convert::{TryFrom, TryInto}, + sync::Arc, }; use zbus::{ fdo, fdo::ManagedObjects, names::{BusName, OwnedUniqueName, UniqueName, WellKnownName}, - Connection, + Connection, OwnerChangedStream, }; use zvariant::OwnedObjectPath; use crate::{Audio, Chardev, Clipboard, Error, Result, UsbRedir, VMProxy}; -pub struct Display { +struct Inner<'d> { + proxy: fdo::ObjectManagerProxy<'d>, conn: Connection, objects: ManagedObjects, } -impl Display { +#[derive(Clone)] +pub struct Display<'d> { + inner: Arc>, +} + +impl<'d> Display<'d> { pub async fn lookup( conn: &Connection, wait: bool, @@ -68,7 +75,7 @@ impl Display { Ok(hm) } - pub async fn new<'d, D>(conn: &Connection, dest: Option) -> Result + pub async fn new(conn: &Connection, dest: Option) -> Result> where D: TryInto>, D::Error: Into, @@ -78,47 +85,58 @@ impl Display { } else { "org.qemu".try_into().unwrap() }; - let objects = fdo::ObjectManagerProxy::builder(conn) + let proxy = fdo::ObjectManagerProxy::builder(conn) .destination(dest)? .path("/org/qemu/Display1")? .build() - .await? - .get_managed_objects() .await?; - // TODO: listen for changes ? - Ok(Self { + let objects = proxy.get_managed_objects().await?; + // TODO: listen for changes + let inner = Inner { + // owner_changed, + proxy, conn: conn.clone(), objects, + }; + + Ok(Self { + inner: Arc::new(inner), }) } + pub async fn receive_owner_changed(&self) -> Result> { + Ok(self.inner.proxy.receive_owner_changed().await?) + } + pub async fn audio(&self) -> Result> { if !self + .inner .objects .contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Audio").unwrap()) { return Ok(None); } - Ok(Some(Audio::new(&self.conn).await?)) + Ok(Some(Audio::new(&self.inner.conn).await?)) } pub async fn clipboard(&self) -> Result> { if !self + .inner .objects .contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Clipboard").unwrap()) { return Ok(None); } - Ok(Some(Clipboard::new(&self.conn).await?)) + Ok(Some(Clipboard::new(&self.inner.conn).await?)) } pub async fn chardevs(&self) -> Vec { - stream::iter(&self.objects) + stream::iter(&self.inner.objects) .filter_map(|(p, _ifaces)| async move { match p.strip_prefix("/org/qemu/Display1/Chardev_") { - Some(id) => Chardev::new(&self.conn, id).await.ok(), + Some(id) => Chardev::new(&self.inner.conn, id).await.ok(), _ => None, } }) diff --git a/qemu-rdw/src/main.rs b/qemu-rdw/src/main.rs index f4c5b18..80bd2fa 100644 --- a/qemu-rdw/src/main.rs +++ b/qemu-rdw/src/main.rs @@ -1,3 +1,4 @@ +use futures_util::StreamExt; use gio::ApplicationFlags; use glib::MainContext; use gtk::{gio, glib, prelude::*}; @@ -153,7 +154,16 @@ impl App { Display::lookup(&conn, wait, name.as_deref()).await.unwrap() }; - let display = Display::new(&conn, dest.as_ref()).await.unwrap(); + + let display = Display::new(&conn, dest).await.unwrap(); + + let disp = display.clone(); + MainContext::default().spawn_local(async move { + let mut changed = disp.receive_owner_changed().await.unwrap(); + while let Some(name) = changed.next().await { + dbg!(name); + } + }); let console = Console::new(&conn, 0) .await