yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
5d360b
From 3fa0b44ff46eccd3c22729a6e5d4ed044d22ab8a Mon Sep 17 00:00:00 2001
5d360b
From: "Daniel P. Berrange" <berrange@redhat.com>
5d360b
Date: Thu, 8 Feb 2018 17:50:28 +0100
5d360b
Subject: [PATCH 14/27] ui: fix refresh of VNC server surface
5d360b
5d360b
RH-Author: Daniel P. Berrange <berrange@redhat.com>
5d360b
Message-id: <20180208175041.5634-15-berrange@redhat.com>
5d360b
Patchwork-id: 78948
5d360b
O-Subject: [RHEL-7.5 qemu-kvm PATCH v1 14/27] ui: fix refresh of VNC server surface
5d360b
Bugzilla: 1527405
5d360b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
5d360b
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
5d360b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
5d360b
From: "Daniel P. Berrange" <berrange@redhat.com>
5d360b
5d360b
In previous commit
5d360b
5d360b
  commit c7628bff4138ce906a3620d12e0820c1cf6c140d
5d360b
  Author: Gerd Hoffmann <kraxel@redhat.com>
5d360b
  Date:   Fri Oct 30 12:10:09 2015 +0100
5d360b
5d360b
    vnc: only alloc server surface with clients connected
5d360b
5d360b
the VNC server was changed so that the 'vd->server' pixman
5d360b
image was only allocated when a client is connected.
5d360b
5d360b
Since then if a client disconnects and then reconnects to
5d360b
the VNC server all they will see is a black screen until
5d360b
they do something that triggers a refresh. On a graphical
5d360b
desktop this is not often noticed since there's many things
5d360b
going on which cause a refresh. On a plain text console it
5d360b
is really obvious since nothing refreshes frequently.
5d360b
5d360b
The problem is that the VNC server didn't update the guest
5d360b
dirty bitmap, so still believes its server image is in sync
5d360b
with the guest contents.
5d360b
5d360b
To fix this we must explicitly mark the entire guest desktop
5d360b
as dirty after re-creating the server surface. Move this
5d360b
logic into vnc_update_server_surface() so it is guaranteed
5d360b
to be call in all code paths that re-create the surface
5d360b
instead of only in vnc_dpy_switch()
5d360b
5d360b
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
5d360b
Reviewed-by: Peter Lieven <pl@kamp.de>
5d360b
Tested-by: Peter Lieven <pl@kamp.de>
5d360b
Message-id: 1471365032-18096-1-git-send-email-berrange@redhat.com
5d360b
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5d360b
(cherry picked from commit b69a553b4af9bc87a8b2e0a7b7a7de4cc7f0557e)
5d360b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
---
5d360b
 ui/vnc.c | 20 +++++++++++---------
5d360b
 1 file changed, 11 insertions(+), 9 deletions(-)
5d360b
5d360b
diff --git a/ui/vnc.c b/ui/vnc.c
5d360b
index dc09089..ec7bb0c 100644
5d360b
--- a/ui/vnc.c
5d360b
+++ b/ui/vnc.c
5d360b
@@ -617,6 +617,8 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
5d360b
 
5d360b
 static void vnc_update_server_surface(VncDisplay *vd)
5d360b
 {
5d360b
+    int width, height;
5d360b
+
5d360b
     qemu_pixman_image_unref(vd->server);
5d360b
     vd->server = NULL;
5d360b
 
5d360b
@@ -624,10 +626,15 @@ static void vnc_update_server_surface(VncDisplay *vd)
5d360b
         return;
5d360b
     }
5d360b
 
5d360b
+    width = vnc_width(vd);
5d360b
+    height = vnc_height(vd);
5d360b
     vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
5d360b
-                                          vnc_width(vd),
5d360b
-                                          vnc_height(vd),
5d360b
+                                          width, height,
5d360b
                                           NULL, 0);
5d360b
+
5d360b
+    memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
5d360b
+    vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
5d360b
+                       width, height);
5d360b
 }
5d360b
 
5d360b
 static void vnc_dpy_switch(DisplayChangeListener *dcl,
5d360b
@@ -635,7 +642,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
5d360b
 {
5d360b
     VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
5d360b
     VncState *vs;
5d360b
-    int width, height;
5d360b
 
5d360b
     vnc_abort_display_jobs(vd);
5d360b
     vd->ds = surface;
5d360b
@@ -647,11 +653,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
5d360b
     qemu_pixman_image_unref(vd->guest.fb);
5d360b
     vd->guest.fb = pixman_image_ref(surface->image);
5d360b
     vd->guest.format = surface->format;
5d360b
-    width = vnc_width(vd);
5d360b
-    height = vnc_height(vd);
5d360b
-    memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
5d360b
-    vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
5d360b
-                       width, height);
5d360b
 
5d360b
     QTAILQ_FOREACH(vs, &vd->clients, next) {
5d360b
         vnc_colordepth(vs);
5d360b
@@ -661,7 +662,8 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
5d360b
         }
5d360b
         memset(vs->dirty, 0x00, sizeof(vs->dirty));
5d360b
         vnc_set_area_dirty(vs->dirty, vd, 0, 0,
5d360b
-                           width, height);
5d360b
+                           vnc_width(vd),
5d360b
+                           vnc_height(vd));
5d360b
     }
5d360b
 }
5d360b
 
5d360b
-- 
5d360b
1.8.3.1
5d360b