mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2024-12-22 13:45:18 +00:00
WIP: reconnect
This commit is contained in:
parent
5bee9ea7f3
commit
13db197622
@ -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<Inner<'d>>,
|
||||
}
|
||||
|
||||
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<D>) -> Result<Self>
|
||||
pub async fn new<D>(conn: &Connection, dest: Option<D>) -> Result<Display<'d>>
|
||||
where
|
||||
D: TryInto<BusName<'d>>,
|
||||
D::Error: Into<Error>,
|
||||
@ -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<OwnerChangedStream<'_>> {
|
||||
Ok(self.inner.proxy.receive_owner_changed().await?)
|
||||
}
|
||||
|
||||
pub async fn audio(&self) -> Result<Option<Audio>> {
|
||||
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<Option<Clipboard>> {
|
||||
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<Chardev> {
|
||||
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,
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user