|
|
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 |
|