vnc: update to async Console

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2021-04-19 17:52:01 +04:00
parent c77fbad908
commit 7866b11456
2 changed files with 33 additions and 22 deletions

View File

@ -15,3 +15,4 @@ zbus = { version = "2.0.0-beta" }
libc = "0.2.86" libc = "0.2.86"
image = "0.23.14" image = "0.23.14"
derivative = "2.2.0" derivative = "2.2.0"
async-io = "1.3.1"

View File

@ -84,17 +84,17 @@ impl Client {
self.has_update && self.req_update self.has_update && self.req_update
} }
fn key_event(&self, qnum: u32, down: bool) -> Result<(), Box<dyn Error>> { async fn key_event(&self, qnum: u32, down: bool) -> Result<(), Box<dyn Error>> {
let inner = self.server.inner.lock().unwrap(); let inner = self.server.inner.lock().unwrap();
if down { if down {
inner.console.keyboard.press(qnum)?; inner.console.keyboard.press(qnum).await?;
} else { } else {
inner.console.keyboard.release(qnum)?; inner.console.keyboard.release(qnum).await?;
} }
Ok(()) Ok(())
} }
fn handle_vnc_event(&mut self, event: VncEvent) -> Result<(), Box<dyn Error>> { async fn handle_vnc_event(&mut self, event: VncEvent) -> Result<(), Box<dyn Error>> {
match event { match event {
VncEvent::FramebufferUpdateRequest { .. } => { VncEvent::FramebufferUpdateRequest { .. } => {
self.req_update = true; self.req_update = true;
@ -102,7 +102,7 @@ impl Client {
} }
VncEvent::KeyEvent { key, down } => { VncEvent::KeyEvent { key, down } => {
if let Some(qnum) = KEYMAP_X112QNUM.get(key as usize) { if let Some(qnum) = KEYMAP_X112QNUM.get(key as usize) {
self.key_event(*qnum as u32, down)?; self.key_event(*qnum as u32, down).await?;
} }
} }
VncEvent::ExtendedKeyEvent { VncEvent::ExtendedKeyEvent {
@ -110,7 +110,7 @@ impl Client {
keysym: _, keysym: _,
keycode, keycode,
} => { } => {
self.key_event(keycode as u32, down)?; self.key_event(keycode as u32, down).await?;
} }
VncEvent::PointerEvent { VncEvent::PointerEvent {
button_mask, button_mask,
@ -121,15 +121,16 @@ impl Client {
let inner = self.server.inner.lock().unwrap(); let inner = self.server.inner.lock().unwrap();
for b in buttons.difference(&self.last_buttons) { for b in buttons.difference(&self.last_buttons) {
inner.console.mouse.press(*b)?; inner.console.mouse.press(*b).await?;
} }
for b in self.last_buttons.difference(&buttons) { for b in self.last_buttons.difference(&buttons) {
inner.console.mouse.release(*b)?; inner.console.mouse.release(*b).await?;
} }
if let Err(err) = inner if let Err(err) = inner
.console .console
.mouse .mouse
.set_abs_position(x_position as _, y_position as _) .set_abs_position(x_position as _, y_position as _)
.await
{ {
eprintln!("Error setting mouse position: {}", err); eprintln!("Error setting mouse position: {}", err);
} }
@ -159,7 +160,8 @@ impl Client {
inner inner
.console .console
.proxy .proxy
.set_ui_info(0, 0, 0, 0, width as _, height as _)?; .set_ui_info(0, 0, 0, 0, width as _, height as _)
.await?;
} }
// VncEvent::CutText(_) => {} // VncEvent::CutText(_) => {}
e => { e => {
@ -213,9 +215,9 @@ impl Client {
Ok(()) Ok(())
} }
fn handle_event(&mut self, event: Option<Event>) -> Result<bool, Box<dyn Error>> { async fn handle_event(&mut self, event: Option<Event>) -> Result<bool, Box<dyn Error>> {
match event { match event {
Some(Event::Vnc(e)) => self.handle_vnc_event(e)?, Some(Event::Vnc(e)) => self.handle_vnc_event(e).await?,
Some(Event::ConsoleUpdate(_)) => { Some(Event::ConsoleUpdate(_)) => {
self.has_update = true; self.has_update = true;
} }
@ -247,8 +249,9 @@ struct Server {
} }
impl Server { impl Server {
fn new(vm_name: String, console: Console) -> Result<Self, Box<dyn Error>> { async fn new(vm_name: String, console: Console) -> Result<Self, Box<dyn Error>> {
let (width, height) = (console.width()?, console.height()?); let width = console.width().await?;
let height = console.height().await?;
let image = BgraImage::new(width as _, height as _); let image = BgraImage::new(width as _, height as _);
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
Ok(Self { Ok(Self {
@ -272,14 +275,14 @@ impl Server {
Ok(()) Ok(())
} }
fn run_console(&self) -> Result<(), Box<dyn Error>> { async fn run_console(&self) -> Result<(), Box<dyn Error>> {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
if inner.console_thread.is_some() { if inner.console_thread.is_some() {
return Ok(()); return Ok(());
} }
let server = self.clone(); let server = self.clone();
let (console_rx, _ack) = inner.console.listen()?; let (console_rx, _ack) = inner.console.listen().await?;
let thread = thread::spawn(move || loop { let thread = thread::spawn(move || loop {
match console_rx.recv().unwrap() { match console_rx.recv().unwrap() {
@ -347,7 +350,7 @@ impl Server {
Ok(()) Ok(())
} }
fn handle_client(&self, stream: TcpStream) -> Result<(), Box<dyn Error>> { async fn handle_client(&self, stream: TcpStream) -> Result<(), Box<dyn Error>> {
let (width, height) = self.dimensions(); let (width, height) = self.dimensions();
let (vnc_server, share) = let (vnc_server, share) =
@ -374,7 +377,7 @@ impl Server {
}); });
let mut client = Client::new(self.clone(), vnc_server, share); let mut client = Client::new(self.clone(), vnc_server, share);
self.run_console()?; self.run_console().await?;
let rx = self.rx.lock().unwrap(); let rx = self.rx.lock().unwrap();
loop { loop {
let ev = if client.update_pending() { let ev = if client.update_pending() {
@ -388,7 +391,7 @@ impl Server {
} else { } else {
Some(rx.recv()?) Some(rx.recv()?)
}; };
if !client.handle_event(ev)? { if !client.handle_event(ev).await? {
break; break;
} }
} }
@ -463,7 +466,7 @@ fn image_from_vec(format: u32, width: u32, height: u32, stride: u32, data: Vec<u
.unwrap() .unwrap()
} }
fn main() -> Result<(), Box<dyn Error>> { async fn run() -> Result<(), Box<dyn Error>> {
let args = Cli::parse(); let args = Cli::parse();
let listener = TcpListener::bind::<std::net::SocketAddr>(args.address.into()).unwrap(); let listener = TcpListener::bind::<std::net::SocketAddr>(args.address.into()).unwrap();
@ -475,11 +478,18 @@ fn main() -> Result<(), Box<dyn Error>> {
.expect("Failed to connect to DBus"); .expect("Failed to connect to DBus");
let vm_name = VMProxy::new(&dbus)?.name()?; let vm_name = VMProxy::new(&dbus)?.name()?;
let console = Console::new(&dbus, 0).expect("Failed to get the console");
let server = Server::new(format!("qemu-vnc ({})", vm_name), console)?; let console = Console::new(&dbus.into(), 0)
.await
.expect("Failed to get the console");
let server = Server::new(format!("qemu-vnc ({})", vm_name), console).await?;
for stream in listener.incoming() { for stream in listener.incoming() {
server.handle_client(stream?)?; server.handle_client(stream?).await?;
} }
Ok(()) Ok(())
} }
fn main() {
async_io::block_on(run()).unwrap();
}