mirror of
https://github.com/rustdesk/qemu-display.git
synced 2025-07-01 15:25:29 +00:00
WIP: reconnect
This commit is contained in:
parent
5bee9ea7f3
commit
13db197622
@ -2,23 +2,30 @@ use futures::stream::{self, StreamExt};
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::{TryFrom, TryInto},
|
convert::{TryFrom, TryInto},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use zbus::{
|
use zbus::{
|
||||||
fdo,
|
fdo,
|
||||||
fdo::ManagedObjects,
|
fdo::ManagedObjects,
|
||||||
names::{BusName, OwnedUniqueName, UniqueName, WellKnownName},
|
names::{BusName, OwnedUniqueName, UniqueName, WellKnownName},
|
||||||
Connection,
|
Connection, OwnerChangedStream,
|
||||||
};
|
};
|
||||||
use zvariant::OwnedObjectPath;
|
use zvariant::OwnedObjectPath;
|
||||||
|
|
||||||
use crate::{Audio, Chardev, Clipboard, Error, Result, UsbRedir, VMProxy};
|
use crate::{Audio, Chardev, Clipboard, Error, Result, UsbRedir, VMProxy};
|
||||||
|
|
||||||
pub struct Display {
|
struct Inner<'d> {
|
||||||
|
proxy: fdo::ObjectManagerProxy<'d>,
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
objects: ManagedObjects,
|
objects: ManagedObjects,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
#[derive(Clone)]
|
||||||
|
pub struct Display<'d> {
|
||||||
|
inner: Arc<Inner<'d>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> Display<'d> {
|
||||||
pub async fn lookup(
|
pub async fn lookup(
|
||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
wait: bool,
|
wait: bool,
|
||||||
@ -68,7 +75,7 @@ impl Display {
|
|||||||
Ok(hm)
|
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
|
where
|
||||||
D: TryInto<BusName<'d>>,
|
D: TryInto<BusName<'d>>,
|
||||||
D::Error: Into<Error>,
|
D::Error: Into<Error>,
|
||||||
@ -78,47 +85,58 @@ impl Display {
|
|||||||
} else {
|
} else {
|
||||||
"org.qemu".try_into().unwrap()
|
"org.qemu".try_into().unwrap()
|
||||||
};
|
};
|
||||||
let objects = fdo::ObjectManagerProxy::builder(conn)
|
let proxy = fdo::ObjectManagerProxy::builder(conn)
|
||||||
.destination(dest)?
|
.destination(dest)?
|
||||||
.path("/org/qemu/Display1")?
|
.path("/org/qemu/Display1")?
|
||||||
.build()
|
.build()
|
||||||
.await?
|
|
||||||
.get_managed_objects()
|
|
||||||
.await?;
|
.await?;
|
||||||
// TODO: listen for changes ?
|
let objects = proxy.get_managed_objects().await?;
|
||||||
Ok(Self {
|
// TODO: listen for changes
|
||||||
|
let inner = Inner {
|
||||||
|
// owner_changed,
|
||||||
|
proxy,
|
||||||
conn: conn.clone(),
|
conn: conn.clone(),
|
||||||
objects,
|
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>> {
|
pub async fn audio(&self) -> Result<Option<Audio>> {
|
||||||
if !self
|
if !self
|
||||||
|
.inner
|
||||||
.objects
|
.objects
|
||||||
.contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Audio").unwrap())
|
.contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Audio").unwrap())
|
||||||
{
|
{
|
||||||
return Ok(None);
|
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>> {
|
pub async fn clipboard(&self) -> Result<Option<Clipboard>> {
|
||||||
if !self
|
if !self
|
||||||
|
.inner
|
||||||
.objects
|
.objects
|
||||||
.contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Clipboard").unwrap())
|
.contains_key(&OwnedObjectPath::try_from("/org/qemu/Display1/Clipboard").unwrap())
|
||||||
{
|
{
|
||||||
return Ok(None);
|
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> {
|
pub async fn chardevs(&self) -> Vec<Chardev> {
|
||||||
stream::iter(&self.objects)
|
stream::iter(&self.inner.objects)
|
||||||
.filter_map(|(p, _ifaces)| async move {
|
.filter_map(|(p, _ifaces)| async move {
|
||||||
match p.strip_prefix("/org/qemu/Display1/Chardev_") {
|
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,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use futures_util::StreamExt;
|
||||||
use gio::ApplicationFlags;
|
use gio::ApplicationFlags;
|
||||||
use glib::MainContext;
|
use glib::MainContext;
|
||||||
use gtk::{gio, glib, prelude::*};
|
use gtk::{gio, glib, prelude::*};
|
||||||
@ -153,7 +154,16 @@ impl App {
|
|||||||
|
|
||||||
Display::lookup(&conn, wait, name.as_deref()).await.unwrap()
|
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)
|
let console = Console::new(&conn, 0)
|
||||||
.await
|
.await
|
||||||
|
Loading…
x
Reference in New Issue
Block a user