rdp: misc improvements

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2024-07-24 22:00:13 +04:00
parent edc7c26a54
commit ccfef172f0
7 changed files with 37 additions and 29 deletions

View File

@ -45,7 +45,7 @@ impl<'d> Display<'d> {
.receive_name_owner_changed() .receive_name_owner_changed()
.await?; .await?;
loop { loop {
let list = Display::by_name(conn).await?; let list = Display::list_by_name(conn).await?;
if let Some(name) = name { if let Some(name) = name {
let res = list.get(name); let res = list.get(name);
if res.is_some() { if res.is_some() {
@ -61,7 +61,7 @@ impl<'d> Display<'d> {
} }
} }
pub async fn by_name(conn: &Connection) -> Result<HashMap<String, OwnedUniqueName>> { pub async fn list_by_name(conn: &Connection) -> Result<HashMap<String, OwnedUniqueName>> {
let mut hm = HashMap::new(); let mut hm = HashMap::new();
let list = match fdo::DBusProxy::new(conn) let list = match fdo::DBusProxy::new(conn)
.await? .await?
@ -93,7 +93,7 @@ impl<'d> Display<'d> {
D: TryInto<BusName<'d>>, D: TryInto<BusName<'d>>,
D::Error: Into<Error>, D::Error: Into<Error>,
{ {
let builder = fdo::ObjectManagerProxy::builder(conn); let builder = fdo::ObjectManagerProxy::builder(conn).destination("org.qemu")?;
let builder = if let Some(dest) = dest { let builder = if let Some(dest) = dest {
let dest = dest.try_into().map_err(Into::into)?; let dest = dest.try_into().map_err(Into::into)?;
builder.destination(dest)? builder.destination(dest)?
@ -101,7 +101,11 @@ impl<'d> Display<'d> {
builder builder
}; };
let proxy = builder.path("/org/qemu/Display1")?.build().await?; let proxy = builder.path("/org/qemu/Display1")?.build().await?;
let objects = proxy.get_managed_objects().await?; let objects = proxy
.get_managed_objects()
.await
.map_err(|e| Error::Failed(format!("Unreachable QEMU display ({})", e)))?;
// TODO: listen for changes // TODO: listen for changes
let inner = Inner { let inner = Inner {
// owner_changed, // owner_changed,
@ -121,6 +125,10 @@ impl<'d> Display<'d> {
&self.inner.conn &self.inner.conn
} }
pub fn destination(&self) -> &BusName<'_> {
self.inner.proxy.inner().destination()
}
#[cfg(windows)] #[cfg(windows)]
pub fn peer_pid(&self) -> u32 { pub fn peer_pid(&self) -> u32 {
self.inner.peer_pid self.inner.peer_pid

View File

@ -19,7 +19,7 @@ use ironrdp::{
}; };
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
use qemu_display::{zbus, Clipboard, ClipboardSelection}; use qemu_display::{Clipboard, ClipboardSelection, Display};
use tokio::{ use tokio::{
sync::{ sync::{
mpsc::{self, Receiver, Sender}, mpsc::{self, Receiver, Sender},
@ -335,8 +335,8 @@ impl Inner {
} }
impl ClipboardHandler { impl ClipboardHandler {
pub async fn connect(dbus: zbus::Connection) -> Result<Self> { pub async fn connect(display: &Display<'_>) -> Result<Self> {
let clipboard = Clipboard::new(&dbus).await?; let clipboard = Clipboard::new(display.connection()).await?;
let selection = ClipboardSelection::Clipboard; let selection = ClipboardSelection::Clipboard;
let (tx, rx) = tokio::sync::mpsc::channel(30); let (tx, rx) = tokio::sync::mpsc::channel(30);

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use qemu_display::{zbus, Console, ConsoleListenerHandler, Cursor, MouseSet, Scanout, Update}; use qemu_display::{Console, ConsoleListenerHandler, Cursor, Display, MouseSet, Scanout, Update};
use ironrdp::{ use ironrdp::{
connector::DesktopSize, connector::DesktopSize,
@ -20,8 +20,8 @@ struct DisplayUpdates {
} }
impl DisplayHandler { impl DisplayHandler {
pub async fn connect(dbus: zbus::Connection) -> Result<Self> { pub async fn connect(display: &Display<'_>) -> Result<Self> {
let console = Console::new(&dbus, 0).await?; let console = Console::new(display.connection(), 0).await?;
Ok(Self { console }) Ok(Self { console })
} }

View File

@ -1,4 +1,4 @@
use qemu_display::{zbus, Console, MouseButton}; use qemu_display::{Console, Display, MouseButton};
use ironrdp::server::{KeyboardEvent, MouseEvent, RdpServerInputHandler}; use ironrdp::server::{KeyboardEvent, MouseEvent, RdpServerInputHandler};
use tokio::{ use tokio::{
@ -79,8 +79,8 @@ async fn input_receive_task(mut rx: Receiver<InputEvent>, console: Console) {
} }
impl InputHandler { impl InputHandler {
pub async fn connect(dbus: zbus::Connection) -> anyhow::Result<InputHandler> { pub async fn connect(display: &Display<'_>) -> anyhow::Result<InputHandler> {
let console = Console::new(&dbus, 0).await?; let console = Console::new(display.connection(), 0).await?;
let (tx, rx) = tokio::sync::mpsc::channel(30); let (tx, rx) = tokio::sync::mpsc::channel(30);
let _task = task::spawn(async move { input_receive_task(rx, console).await }); let _task = task::spawn(async move { input_receive_task(rx, console).await });

View File

@ -6,7 +6,7 @@ mod sound;
use anyhow::{anyhow, Context, Error}; use anyhow::{anyhow, Context, Error};
use ironrdp::server::tokio_rustls::{rustls, TlsAcceptor}; use ironrdp::server::tokio_rustls::{rustls, TlsAcceptor};
use qemu_display::zbus; use qemu_display::{zbus, Display};
use rustls_pemfile::{certs, pkcs8_private_keys}; use rustls_pemfile::{certs, pkcs8_private_keys};
use std::{fs::File, io::BufReader, sync::Arc}; use std::{fs::File, io::BufReader, sync::Arc};
use tracing::debug; use tracing::debug;
@ -39,10 +39,12 @@ impl Server {
.map(|(cert, key)| acceptor(cert, key).unwrap()) .map(|(cert, key)| acceptor(cert, key).unwrap())
.ok_or_else(|| anyhow!("Failed to setup TLS"))?; .ok_or_else(|| anyhow!("Failed to setup TLS"))?;
let handler = InputHandler::connect(self.dbus.clone()).await?; let dbus_display = Display::new::<()>(&self.dbus, None).await?;
let display = DisplayHandler::connect(self.dbus.clone()).await?;
let clipboard = ClipboardHandler::connect(self.dbus.clone()).await?; let handler = InputHandler::connect(&dbus_display).await?;
let sound = match SoundHandler::connect::<()>(self.dbus.clone(), None).await { let display = DisplayHandler::connect(&dbus_display).await?;
let clipboard = ClipboardHandler::connect(&dbus_display).await?;
let sound = match SoundHandler::connect(&dbus_display).await {
Ok(h) => Some(h), Ok(h) => Some(h),
Err(e) => { Err(e) => {
debug!("Can't connect audio: {}", e); debug!("Can't connect audio: {}", e);

View File

@ -14,7 +14,7 @@ use ironrdp::{
}; };
use tokio::sync::mpsc; use tokio::sync::mpsc;
use qemu_display::{zbus, Audio, AudioOutHandler, PCMInfo, Volume}; use qemu_display::{Audio, AudioOutHandler, Display, PCMInfo, Volume};
use tracing::{debug, warn}; use tracing::{debug, warn};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -168,12 +168,9 @@ impl SoundServerFactory for SoundHandler {
} }
impl SoundHandler { impl SoundHandler {
pub async fn connect<D>(dbus: zbus::Connection, dest: Option<D>) -> Result<Self> pub async fn connect(display: &Display<'_>) -> Result<Self> {
where let audio =
D: TryInto<zbus::names::BusName<'static>>, Audio::new(display.connection(), Some(display.destination().to_owned())).await?;
D::Error: Into<qemu_display::Error>,
{
let audio = Audio::new(&dbus, dest).await?;
let inner = Arc::new(Mutex::new(Inner { let inner = Arc::new(Mutex::new(Inner {
start_time: Instant::now(), start_time: Instant::now(),
state: State::Init, state: State::Init,
@ -182,6 +179,7 @@ impl SoundHandler {
rdp_started: false, rdp_started: false,
})); }));
// TODO: register only after connection?
let handler = DBusHandler { let handler = DBusHandler {
inner: inner.clone(), inner: inner.clone(),
}; };

View File

@ -61,7 +61,7 @@ async fn display_from_opt(opt: Rc<RefCell<AppOptions>>) -> Option<Display<'stati
}); });
if opt.borrow().list { if opt.borrow().list {
let list = Display::by_name(&conn).await.unwrap(); let list = Display::list_by_name(&conn).await.unwrap();
for (name, dest) in list { for (name, dest) in list {
println!("{} (at {})", name, dest); println!("{} (at {})", name, dest);
} }
@ -204,11 +204,11 @@ impl App {
} }
}; };
let disp = display.clone(); let disp = display.clone();
let app = app_clone.clone();
MainContext::default().spawn_local(async move { MainContext::default().spawn_local(async move {
let mut changed = disp.receive_owner_changed().await.unwrap(); let mut changed = disp.receive_owner_changed().await.unwrap();
while let Some(name) = changed.next().await { let _ = changed.next().await;
dbg!(name); app.inner.app.quit();
}
}); });
let console = Console::new( let console = Console::new(