mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2025-03-07 15:25:04 +00:00
Add basic windows support
This commit is contained in:
parent
817d44e17a
commit
91a8549b70
@ -72,6 +72,8 @@ pub struct Audio {
|
|||||||
pub proxy: AudioProxy<'static>,
|
pub proxy: AudioProxy<'static>,
|
||||||
out_listener: Option<Connection>,
|
out_listener: Option<Connection>,
|
||||||
in_listener: Option<Connection>,
|
in_listener: Option<Connection>,
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
@ -233,12 +235,14 @@ impl<H: AudioInHandler> AudioInListener<H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Audio {
|
impl Audio {
|
||||||
pub async fn new(conn: &zbus::Connection) -> Result<Self> {
|
pub async fn new(conn: &zbus::Connection, #[cfg(windows)] peer_pid: u32) -> Result<Self> {
|
||||||
let proxy = AudioProxy::new(conn).await?;
|
let proxy = AudioProxy::new(conn).await?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
proxy,
|
proxy,
|
||||||
in_listener: None,
|
in_listener: None,
|
||||||
out_listener: None,
|
out_listener: None,
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +250,7 @@ impl Audio {
|
|||||||
let (p0, p1) = UnixStream::pair()?;
|
let (p0, p1) = UnixStream::pair()?;
|
||||||
let p0 = util::prepare_uds_pass(
|
let p0 = util::prepare_uds_pass(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
self.proxy.inner().connection(),
|
self.peer_pid,
|
||||||
&p0,
|
&p0,
|
||||||
)?;
|
)?;
|
||||||
self.proxy.register_out_listener(p0).await?;
|
self.proxy.register_out_listener(p0).await?;
|
||||||
@ -266,7 +270,7 @@ impl Audio {
|
|||||||
let (p0, p1) = UnixStream::pair()?;
|
let (p0, p1) = UnixStream::pair()?;
|
||||||
let p0 = util::prepare_uds_pass(
|
let p0 = util::prepare_uds_pass(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
self.proxy.inner().connection(),
|
self.peer_pid,
|
||||||
&p0,
|
&p0,
|
||||||
)?;
|
)?;
|
||||||
self.proxy.register_in_listener(p0).await?;
|
self.proxy.register_in_listener(p0).await?;
|
||||||
|
@ -54,10 +54,12 @@ pub struct Console {
|
|||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub mouse: MouseProxy<'static>,
|
pub mouse: MouseProxy<'static>,
|
||||||
listener: RefCell<Option<Connection>>,
|
listener: RefCell<Option<Connection>>,
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Console {
|
impl Console {
|
||||||
pub async fn new(conn: &Connection, idx: u32) -> Result<Self> {
|
pub async fn new(conn: &Connection, idx: u32, #[cfg(windows)] peer_pid: u32) -> Result<Self> {
|
||||||
let obj_path = ObjectPath::try_from(format!("/org/qemu/Display1/Console_{}", idx))?;
|
let obj_path = ObjectPath::try_from(format!("/org/qemu/Display1/Console_{}", idx))?;
|
||||||
let proxy = ConsoleProxy::builder(conn).path(&obj_path)?.build().await?;
|
let proxy = ConsoleProxy::builder(conn).path(&obj_path)?.build().await?;
|
||||||
let keyboard = KeyboardProxy::builder(conn)
|
let keyboard = KeyboardProxy::builder(conn)
|
||||||
@ -70,6 +72,8 @@ impl Console {
|
|||||||
keyboard,
|
keyboard,
|
||||||
mouse,
|
mouse,
|
||||||
listener: RefCell::new(None),
|
listener: RefCell::new(None),
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ impl Console {
|
|||||||
let (p0, p1) = UnixStream::pair()?;
|
let (p0, p1) = UnixStream::pair()?;
|
||||||
let p0 = util::prepare_uds_pass(
|
let p0 = util::prepare_uds_pass(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
self.proxy.inner().connection(),
|
self.peer_pid,
|
||||||
&p0,
|
&p0,
|
||||||
)?;
|
)?;
|
||||||
self.proxy.register_listener(p0).await?;
|
self.proxy.register_listener(p0).await?;
|
||||||
|
@ -25,6 +25,8 @@ struct Inner<'d> {
|
|||||||
proxy: fdo::ObjectManagerProxy<'d>,
|
proxy: fdo::ObjectManagerProxy<'d>,
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
objects: ManagedObjects,
|
objects: ManagedObjects,
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -82,7 +84,11 @@ impl<'d> Display<'d> {
|
|||||||
Ok(hm)
|
Ok(hm)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new<D>(conn: &Connection, dest: Option<D>) -> Result<Display<'d>>
|
pub async fn new<D>(
|
||||||
|
conn: &Connection,
|
||||||
|
dest: Option<D>,
|
||||||
|
#[cfg(windows)] peer_pid: u32,
|
||||||
|
) -> Result<Display<'d>>
|
||||||
where
|
where
|
||||||
D: TryInto<BusName<'d>>,
|
D: TryInto<BusName<'d>>,
|
||||||
D::Error: Into<Error>,
|
D::Error: Into<Error>,
|
||||||
@ -102,6 +108,8 @@ impl<'d> Display<'d> {
|
|||||||
proxy,
|
proxy,
|
||||||
conn: conn.clone(),
|
conn: conn.clone(),
|
||||||
objects,
|
objects,
|
||||||
|
#[cfg(windows)]
|
||||||
|
peer_pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -113,6 +121,11 @@ impl<'d> Display<'d> {
|
|||||||
&self.inner.conn
|
&self.inner.conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn peer_pid(&self) -> u32 {
|
||||||
|
self.inner.peer_pid
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(windows, feature = "qmp"))]
|
#[cfg(all(windows, feature = "qmp"))]
|
||||||
pub async fn new_qmp<P: AsRef<std::path::Path>>(path: P) -> Result<Display<'d>> {
|
pub async fn new_qmp<P: AsRef<std::path::Path>>(path: P) -> Result<Display<'d>> {
|
||||||
#![allow(non_snake_case, non_camel_case_types)]
|
#![allow(non_snake_case, non_camel_case_types)]
|
||||||
@ -163,7 +176,7 @@ impl<'d> Display<'d> {
|
|||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Self::new(&conn, Option::<String>::None).await
|
Self::new(&conn, Option::<String>::None, pid).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn receive_owner_changed(&self) -> Result<OwnerChangedStream<'_>> {
|
pub async fn receive_owner_changed(&self) -> Result<OwnerChangedStream<'_>> {
|
||||||
@ -179,7 +192,14 @@ impl<'d> Display<'d> {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(Audio::new(&self.inner.conn).await?))
|
Ok(Some(
|
||||||
|
Audio::new(
|
||||||
|
&self.inner.conn,
|
||||||
|
#[cfg(windows)]
|
||||||
|
self.peer_pid(),
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clipboard(&self) -> Result<Option<Clipboard>> {
|
pub async fn clipboard(&self) -> Result<Option<Clipboard>> {
|
||||||
|
@ -18,7 +18,7 @@ use windows::Win32::Networking::WinSock::SOCKET;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use windows::Win32::System::Threading::PROCESS_DUP_HANDLE;
|
use windows::Win32::System::Threading::PROCESS_DUP_HANDLE;
|
||||||
|
|
||||||
pub fn prepare_uds_pass(#[cfg(windows)] conn: &zbus::Connection, us: &UnixStream) -> Result<Fd> {
|
pub fn prepare_uds_pass(#[cfg(windows)] peer_pid: u32, us: &UnixStream) -> Result<Fd> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
Ok(us.as_raw_fd().into())
|
Ok(us.as_raw_fd().into())
|
||||||
@ -26,9 +26,7 @@ pub fn prepare_uds_pass(#[cfg(windows)] conn: &zbus::Connection, us: &UnixStream
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
// FIXME: we should use GetConnectionCredentials to work with a bus
|
let p = win32::ProcessHandle::open(Some(peer_pid as _), PROCESS_DUP_HANDLE)?;
|
||||||
let pid = conn.peer_pid()?.unwrap();
|
|
||||||
let p = win32::ProcessHandle::open(Some(pid as _), PROCESS_DUP_HANDLE)?;
|
|
||||||
p.duplicate_socket(SOCKET(us.as_raw_socket() as _))
|
p.duplicate_socket(SOCKET(us.as_raw_socket() as _))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,9 @@ impl ProcessHandle {
|
|||||||
process_id: Option<u32>,
|
process_id: Option<u32>,
|
||||||
desired_access: PROCESS_ACCESS_RIGHTS,
|
desired_access: PROCESS_ACCESS_RIGHTS,
|
||||||
) -> Result<Self, io::Error> {
|
) -> Result<Self, io::Error> {
|
||||||
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcess, PROCESS_QUERY_INFORMATION};
|
use windows::Win32::System::Threading::{
|
||||||
|
GetCurrentProcess, OpenProcess, PROCESS_QUERY_INFORMATION,
|
||||||
|
};
|
||||||
|
|
||||||
let process = if let Some(process_id) = process_id {
|
let process = if let Some(process_id) = process_id {
|
||||||
let desired_access = desired_access | PROCESS_QUERY_INFORMATION;
|
let desired_access = desired_access | PROCESS_QUERY_INFORMATION;
|
||||||
@ -51,8 +53,8 @@ impl ProcessHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_id(&self) -> crate::Result<u32> {
|
pub fn process_id(&self) -> crate::Result<u32> {
|
||||||
use windows::Win32::System::Threading::GetProcessId;
|
|
||||||
use windows::Win32::Foundation::GetLastError;
|
use windows::Win32::Foundation::GetLastError;
|
||||||
|
use windows::Win32::System::Threading::GetProcessId;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let pid = GetProcessId(self.0);
|
let pid = GetProcessId(self.0);
|
||||||
|
@ -73,7 +73,16 @@ async fn display_from_opt(opt: Arc<RefCell<AppOptions>>) -> Option<Display<'stat
|
|||||||
Display::lookup(&conn, wait, name.as_deref()).await.unwrap()
|
Display::lookup(&conn, wait, name.as_deref()).await.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Display::new(&conn, dest).await.unwrap())
|
Some(
|
||||||
|
Display::new(
|
||||||
|
&conn,
|
||||||
|
dest,
|
||||||
|
#[cfg(windows)]
|
||||||
|
unimplemented!(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
@ -195,7 +204,12 @@ impl App {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let console = Console::new(display.connection(), 0)
|
let console = Console::new(
|
||||||
|
display.connection(),
|
||||||
|
0,
|
||||||
|
#[cfg(windows)]
|
||||||
|
display.peer_pid(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get the QEMU console");
|
.expect("Failed to get the QEMU console");
|
||||||
let rdw = display::Display::new(console);
|
let rdw = display::Display::new(console);
|
||||||
@ -237,7 +251,7 @@ impl App {
|
|||||||
let (p0, p1) = UnixStream::pair().unwrap();
|
let (p0, p1) = UnixStream::pair().unwrap();
|
||||||
let fd = util::prepare_uds_pass(
|
let fd = util::prepare_uds_pass(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
c.proxy.inner().connection(),
|
display.peer_pid(),
|
||||||
&p1,
|
&p1,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user