mirror of
https://github.com/rustdesk/qemu-display.git
synced 2025-07-01 23:35:36 +00:00
listener: make it all async
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
697fb50c0f
commit
c77fbad908
@ -5,7 +5,7 @@ use std::{os::unix::io::AsRawFd, thread};
|
|||||||
use zbus::{dbus_proxy, export::zvariant::Fd};
|
use zbus::{dbus_proxy, export::zvariant::Fd};
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::{ConsoleEvent, ConsoleListener, KeyboardProxy, MouseProxy};
|
use crate::{ConsoleEvent, ConsoleListener, AsyncKeyboardProxy, AsyncMouseProxy};
|
||||||
|
|
||||||
#[dbus_proxy(default_service = "org.qemu", interface = "org.qemu.Display1.Console")]
|
#[dbus_proxy(default_service = "org.qemu", interface = "org.qemu.Display1.Console")]
|
||||||
pub trait Console {
|
pub trait Console {
|
||||||
@ -44,19 +44,19 @@ pub trait Console {
|
|||||||
#[derivative(Debug)]
|
#[derivative(Debug)]
|
||||||
pub struct Console {
|
pub struct Console {
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub proxy: ConsoleProxy<'static>,
|
pub proxy: AsyncConsoleProxy<'static>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub keyboard: KeyboardProxy<'static>,
|
pub keyboard: AsyncKeyboardProxy<'static>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub mouse: MouseProxy<'static>,
|
pub mouse: AsyncMouseProxy<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Console {
|
impl Console {
|
||||||
pub fn new(conn: &zbus::Connection, idx: u32) -> Result<Self> {
|
pub async fn new(conn: &zbus::azync::Connection, idx: u32) -> Result<Self> {
|
||||||
let obj_path = format!("/org/qemu/Display1/Console_{}", idx);
|
let obj_path = format!("/org/qemu/Display1/Console_{}", idx);
|
||||||
let proxy = ConsoleProxy::new_for_owned_path(conn.clone(), obj_path.clone())?;
|
let proxy = AsyncConsoleProxy::new_for_owned_path(conn.clone(), obj_path.clone())?;
|
||||||
let keyboard = KeyboardProxy::new_for_owned_path(conn.clone(), obj_path.clone())?;
|
let keyboard = AsyncKeyboardProxy::new_for_owned_path(conn.clone(), obj_path.clone())?;
|
||||||
let mouse = MouseProxy::new_for_owned_path(conn.clone(), obj_path)?;
|
let mouse = AsyncMouseProxy::new_for_owned_path(conn.clone(), obj_path)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
proxy,
|
proxy,
|
||||||
keyboard,
|
keyboard,
|
||||||
@ -64,22 +64,22 @@ impl Console {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn label(&self) -> Result<String> {
|
pub async fn label(&self) -> Result<String> {
|
||||||
Ok(self.proxy.label()?)
|
Ok(self.proxy.label().await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(&self) -> Result<u32> {
|
pub async fn width(&self) -> Result<u32> {
|
||||||
Ok(self.proxy.width()?)
|
Ok(self.proxy.width().await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn height(&self) -> Result<u32> {
|
pub async fn height(&self) -> Result<u32> {
|
||||||
Ok(self.proxy.height()?)
|
Ok(self.proxy.height().await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listen(&self) -> Result<(Receiver<ConsoleEvent>, Sender<()>)> {
|
pub async fn listen(&self) -> Result<(Receiver<ConsoleEvent>, Sender<()>)> {
|
||||||
let (p0, p1) = UnixStream::pair()?;
|
let (p0, p1) = UnixStream::pair()?;
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
self.proxy.register_listener(p0.as_raw_fd().into())?;
|
self.proxy.register_listener(p0.as_raw_fd().into()).await?;
|
||||||
|
|
||||||
let (wait_tx, wait_rx) = mpsc::channel();
|
let (wait_tx, wait_rx) = mpsc::channel();
|
||||||
let _thread = thread::spawn(move || {
|
let _thread = thread::spawn(move || {
|
||||||
@ -106,10 +106,10 @@ impl Console {
|
|||||||
|
|
||||||
#[cfg(feature = "glib")]
|
#[cfg(feature = "glib")]
|
||||||
impl Console {
|
impl Console {
|
||||||
pub fn glib_listen(&self) -> Result<(glib::Receiver<ConsoleEvent>, Sender<()>)> {
|
pub async fn glib_listen(&self) -> Result<(glib::Receiver<ConsoleEvent>, Sender<()>)> {
|
||||||
let (p0, p1) = UnixStream::pair()?;
|
let (p0, p1) = UnixStream::pair()?;
|
||||||
let (tx, rx) = glib::MainContext::channel(glib::source::Priority::default());
|
let (tx, rx) = glib::MainContext::channel(glib::source::Priority::default());
|
||||||
self.proxy.register_listener(p0.as_raw_fd().into())?;
|
self.proxy.register_listener(p0.as_raw_fd().into()).await?;
|
||||||
|
|
||||||
let (wait_tx, wait_rx) = mpsc::channel();
|
let (wait_tx, wait_rx) = mpsc::channel();
|
||||||
let _thread = thread::spawn(move || {
|
let _thread = thread::spawn(move || {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use glib::{clone, subclass::prelude::*, translate::*};
|
use glib::{clone, subclass::prelude::*, translate::*, MainContext};
|
||||||
use gtk::{glib, prelude::*};
|
use gtk::{glib, prelude::*};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
@ -58,59 +58,57 @@ mod imp {
|
|||||||
obj.set_mouse_absolute(true);
|
obj.set_mouse_absolute(true);
|
||||||
|
|
||||||
obj.connect_key_press(clone!(@weak obj => move |_, keyval, keycode| {
|
obj.connect_key_press(clone!(@weak obj => move |_, keyval, keycode| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("key-press: {:?}", (keyval, keycode));
|
log::debug!("key-press: {:?}", (keyval, keycode));
|
||||||
let console = self_.console.get().unwrap();
|
|
||||||
if let Some(qnum) = KEYMAP_XORGEVDEV2QNUM.get(keycode as usize) {
|
if let Some(qnum) = KEYMAP_XORGEVDEV2QNUM.get(keycode as usize) {
|
||||||
let _ = console.keyboard.press(*qnum as u32);
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
|
let _ = obj.console().keyboard.press(*qnum as u32).await;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_key_release(clone!(@weak obj => move |_, keyval, keycode| {
|
obj.connect_key_release(clone!(@weak obj => move |_, keyval, keycode| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("key-release: {:?}", (keyval, keycode));
|
log::debug!("key-release: {:?}", (keyval, keycode));
|
||||||
let console = self_.console.get().unwrap();
|
|
||||||
if let Some(qnum) = KEYMAP_XORGEVDEV2QNUM.get(keycode as usize) {
|
if let Some(qnum) = KEYMAP_XORGEVDEV2QNUM.get(keycode as usize) {
|
||||||
let _ = console.keyboard.release(*qnum as u32);
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
|
let _ = obj.console().keyboard.release(*qnum as u32).await;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_motion(clone!(@weak obj => move |_, x, y| {
|
obj.connect_motion(clone!(@weak obj => move |_, x, y| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("motion: {:?}", (x, y));
|
log::debug!("motion: {:?}", (x, y));
|
||||||
let console = self_.console.get().unwrap();
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let _ = console.mouse.set_abs_position(x as _, y as _);
|
let _ = obj.console().mouse.set_abs_position(x as _, y as _).await;
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_motion_relative(clone!(@weak obj => move |_, dx, dy| {
|
obj.connect_motion_relative(clone!(@weak obj => move |_, dx, dy| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("motion-relative: {:?}", (dx, dy));
|
log::debug!("motion-relative: {:?}", (dx, dy));
|
||||||
let console = self_.console.get().unwrap();
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let _ = console.mouse.rel_motion(dx as _, dy as _);
|
let _ = obj.console().mouse.rel_motion(dx as _, dy as _).await;
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_mouse_press(clone!(@weak obj => move |_, button| {
|
obj.connect_mouse_press(clone!(@weak obj => move |_, button| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("mouse-press: {:?}", button);
|
log::debug!("mouse-press: {:?}", button);
|
||||||
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let button = from_gdk_button(button);
|
let button = from_gdk_button(button);
|
||||||
let console = self_.console.get().unwrap();
|
let _ = obj.console().mouse.press(button).await;
|
||||||
let _ = console.mouse.press(button);
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_mouse_release(clone!(@weak obj => move |_, button| {
|
obj.connect_mouse_release(clone!(@weak obj => move |_, button| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("mouse-release: {:?}", button);
|
log::debug!("mouse-release: {:?}", button);
|
||||||
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let button = from_gdk_button(button);
|
let button = from_gdk_button(button);
|
||||||
let console = self_.console.get().unwrap();
|
let _ = obj.console().mouse.release(button).await;
|
||||||
let _ = console.mouse.release(button);
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_scroll_discrete(clone!(@weak obj => move |_, scroll| {
|
obj.connect_scroll_discrete(clone!(@weak obj => move |_, scroll| {
|
||||||
use qemu_display_listener::MouseButton;
|
use qemu_display_listener::MouseButton;
|
||||||
|
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("scroll-discrete: {:?}", scroll);
|
log::debug!("scroll-discrete: {:?}", scroll);
|
||||||
let console = self_.console.get().unwrap();
|
|
||||||
|
|
||||||
let button = match scroll {
|
let button = match scroll {
|
||||||
rdw::Scroll::Up => MouseButton::WheelUp,
|
rdw::Scroll::Up => MouseButton::WheelUp,
|
||||||
@ -120,15 +118,17 @@ mod imp {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let _ = console.mouse.press(button);
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let _ = console.mouse.release(button);
|
let _ = obj.console().mouse.press(button).await;
|
||||||
|
let _ = obj.console().mouse.release(button).await;
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.connect_resize_request(clone!(@weak obj => move |_, width, height, wmm, hmm| {
|
obj.connect_resize_request(clone!(@weak obj => move |_, width, height, wmm, hmm| {
|
||||||
let self_ = Self::from_instance(&obj);
|
|
||||||
log::debug!("resize-request: {:?}", (width, height, wmm, hmm));
|
log::debug!("resize-request: {:?}", (width, height, wmm, hmm));
|
||||||
let console = self_.console.get().unwrap();
|
MainContext::default().spawn_local(clone!(@weak obj => async move {
|
||||||
let _ = console.proxy.set_ui_info(wmm as _, hmm as _, 0, 0, width, height);
|
let _ = obj.console().proxy.set_ui_info(wmm as _, hmm as _, 0, 0, width, height).await;
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,16 +137,18 @@ mod imp {
|
|||||||
fn realize(&self, widget: &Self::Type) {
|
fn realize(&self, widget: &Self::Type) {
|
||||||
self.parent_realize(widget);
|
self.parent_realize(widget);
|
||||||
|
|
||||||
let console = self.console.get().unwrap();
|
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
|
let (rx, wait_tx) = console
|
||||||
.glib_listen()
|
.glib_listen()
|
||||||
|
.await
|
||||||
.expect("Failed to listen to the console");
|
.expect("Failed to listen to the console");
|
||||||
rx.attach(
|
rx.attach(
|
||||||
None,
|
None,
|
||||||
clone!(@weak widget => @default-panic, move |evt| {
|
clone!(@weak widget => @default-panic, move |evt| {
|
||||||
use qemu_display_listener::ConsoleEvent::*;
|
use qemu_display_listener::ConsoleEvent::*;
|
||||||
|
|
||||||
let self_ = Self::from_instance(&widget);
|
|
||||||
log::debug!("Console event: {:?}", evt);
|
log::debug!("Console event: {:?}", evt);
|
||||||
match evt {
|
match evt {
|
||||||
Scanout(s) => {
|
Scanout(s) => {
|
||||||
@ -202,8 +204,9 @@ mod imp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Continue(true)
|
Continue(true)
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +230,11 @@ impl DisplayQemu {
|
|||||||
self_.set_console(console);
|
self_.set_console(console);
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn console(&self) -> &Console {
|
||||||
|
let self_ = imp::DisplayQemu::from_instance(self);
|
||||||
|
self_.console.get().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_gdk_button(button: u32) -> qemu_display_listener::MouseButton {
|
fn from_gdk_button(button: u32) -> qemu_display_listener::MouseButton {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
use std::error::Error;
|
||||||
use gio::ApplicationFlags;
|
use gio::ApplicationFlags;
|
||||||
use gtk::{gio, prelude::*};
|
use glib::{clone, MainContext};
|
||||||
|
use gtk::{gio, glib, prelude::*};
|
||||||
use qemu_display_listener::Console;
|
use qemu_display_listener::Console;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
@ -10,7 +12,7 @@ fn main() {
|
|||||||
|
|
||||||
let app = gtk::Application::new(Some("org.qemu.rdw.demo"), ApplicationFlags::NON_UNIQUE);
|
let app = gtk::Application::new(Some("org.qemu.rdw.demo"), ApplicationFlags::NON_UNIQUE);
|
||||||
|
|
||||||
let conn = Connection::new_session().expect("Failed to connect to DBus");
|
let conn: zbus::azync::Connection = Connection::new_session().expect("Failed to connect to DBus").into();
|
||||||
|
|
||||||
app.connect_activate(move |app| {
|
app.connect_activate(move |app| {
|
||||||
let window = gtk::ApplicationWindow::new(app);
|
let window = gtk::ApplicationWindow::new(app);
|
||||||
@ -18,11 +20,14 @@ fn main() {
|
|||||||
window.set_title(Some("rdw demo"));
|
window.set_title(Some("rdw demo"));
|
||||||
window.set_default_size(1024, 768);
|
window.set_default_size(1024, 768);
|
||||||
|
|
||||||
let console = Console::new(&conn, 0).expect("Failed to get the QEMU console");
|
let conn = conn.clone();
|
||||||
|
MainContext::default().spawn_local(clone!(@strong window => async move {
|
||||||
|
let console = Console::new(&conn, 0).await.expect("Failed to get the QEMU console");
|
||||||
let display = display_qemu::DisplayQemu::new(console);
|
let display = display_qemu::DisplayQemu::new(console);
|
||||||
window.set_child(Some(&display));
|
window.set_child(Some(&display));
|
||||||
|
|
||||||
window.show();
|
window.show();
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user