aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorPeter Lieven <pl@kamp.de>2014-03-17 18:38:58 +0100
committerGerd Hoffmann <kraxel@redhat.com>2014-03-18 08:21:24 +0100
commit2f487a3d40faff1772e14da6b921900915501f9a (patch)
treeba7f86464074760b41354e7acbf97a68f17e8213 /ui
parent315b59344126beab85a62b53582794b14436a5a4 (diff)
downloadqemu-2f487a3d40faff1772e14da6b921900915501f9a.zip
qemu-2f487a3d40faff1772e14da6b921900915501f9a.tar.gz
qemu-2f487a3d40faff1772e14da6b921900915501f9a.tar.bz2
ui/vnc: fix vmware VGA incompatiblities
this fixes invalid rectangle updates observed after commit 12b316d with the vmware VGA driver. The issues occured because the server and client surface update seems to be out of sync at some points and the max width of the surface is not dividable by VNC_DIRTY_BITS_PER_PIXEL (16). Reported-by: Serge Hallyn <serge.hallyn@ubuntu.com> Signed-off-by: Peter Lieven <pl@kamp.de> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/vnc.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/ui/vnc.c b/ui/vnc.c
index 9c84b3e..5925774 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -888,7 +888,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
VncDisplay *vd = vs->vd;
VncJob *job;
int y;
- int height;
+ int height, width;
int n = 0;
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
@@ -907,6 +907,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
job = vnc_job_new(vs);
height = MIN(pixman_image_get_height(vd->server), vs->client_height);
+ width = MIN(pixman_image_get_width(vd->server), vs->client_width);
y = 0;
for (;;) {
@@ -925,8 +926,11 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
VNC_DIRTY_BPL(vs), x);
bitmap_clear(vs->dirty[y], x, x2 - x);
h = find_and_clear_dirty_height(vs, y, x, x2, height);
- n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
- (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
+ x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
+ if (x2 > x) {
+ n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
+ (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
+ }
}
vnc_job_push(job);