ui: fix refresh of VNC server surface
In previous commit commitstable-2.6c7628bff41
Author: Gerd Hoffmann <kraxel@redhat.com> Date: Fri Oct 30 12:10:09 2015 +0100 vnc: only alloc server surface with clients connected the VNC server was changed so that the 'vd->server' pixman image was only allocated when a client is connected. Since then if a client disconnects and then reconnects to the VNC server all they will see is a black screen until they do something that triggers a refresh. On a graphical desktop this is not often noticed since there's many things going on which cause a refresh. On a plain text console it is really obvious since nothing refreshes frequently. The problem is that the VNC server didn't update the guest dirty bitmap, so still believes its server image is in sync with the guest contents. To fix this we must explicitly mark the entire guest desktop as dirty after re-creating the server surface. Move this logic into vnc_update_server_surface() so it is guaranteed to be call in all code paths that re-create the surface instead of only in vnc_dpy_switch() Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Peter Lieven <pl@kamp.de> Tested-by: Peter Lieven <pl@kamp.de> Message-id: 1471365032-18096-1-git-send-email-berrange@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> (cherry picked from commitb69a553b4a
) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
parent
3b9717a62b
commit
d00d89a685
20
ui/vnc.c
20
ui/vnc.c
|
@ -687,6 +687,8 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
|
|||
|
||||
static void vnc_update_server_surface(VncDisplay *vd)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
qemu_pixman_image_unref(vd->server);
|
||||
vd->server = NULL;
|
||||
|
||||
|
@ -694,10 +696,15 @@ static void vnc_update_server_surface(VncDisplay *vd)
|
|||
return;
|
||||
}
|
||||
|
||||
width = vnc_width(vd);
|
||||
height = vnc_height(vd);
|
||||
vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
|
||||
vnc_width(vd),
|
||||
vnc_height(vd),
|
||||
width, height,
|
||||
NULL, 0);
|
||||
|
||||
memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
|
||||
vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
||||
|
@ -705,7 +712,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
|||
{
|
||||
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
|
||||
VncState *vs;
|
||||
int width, height;
|
||||
|
||||
vnc_abort_display_jobs(vd);
|
||||
vd->ds = surface;
|
||||
|
@ -717,11 +723,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
|||
qemu_pixman_image_unref(vd->guest.fb);
|
||||
vd->guest.fb = pixman_image_ref(surface->image);
|
||||
vd->guest.format = surface->format;
|
||||
width = vnc_width(vd);
|
||||
height = vnc_height(vd);
|
||||
memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
|
||||
vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
|
||||
width, height);
|
||||
|
||||
QTAILQ_FOREACH(vs, &vd->clients, next) {
|
||||
vnc_colordepth(vs);
|
||||
|
@ -731,7 +732,8 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
|||
}
|
||||
memset(vs->dirty, 0x00, sizeof(vs->dirty));
|
||||
vnc_set_area_dirty(vs->dirty, vd, 0, 0,
|
||||
width, height);
|
||||
vnc_width(vd),
|
||||
vnc_height(vd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue