From: Gerd Hoffmann Date: Mon, 27 Jul 2009 15:10:48 +0000 (+0200) Subject: BACKPORT: vnc: fix copyrect screen corruption X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74ccfe8b7e9c351b3196f68795126e76060903b3;p=thirdparty%2Fqemu.git BACKPORT: vnc: fix copyrect screen corruption When sending a copyrect command to the vnc client, we must also update the local server surface. Otherwise the server's and the client's idea of the screen content run out of sync and screen updates don't work correctly. [ backport: uses ds_get_data() instead of direct dereference ] Signed-off-by: Anthony Liguori Signed-off-by: Glauber Costa --- diff --git a/vnc.c b/vnc.c index 1d8ebe7b656..c0700c066e9 100644 --- a/vnc.c +++ b/vnc.c @@ -633,8 +633,14 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h) { + + uint8_t *src_row; + uint8_t *dst_row; + int y,pitch,depth; + vnc_update_client(vs); + /* send bitblit op to the vnc client */ vnc_write_u8(vs, 0); /* msg id */ vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); /* number of rects */ @@ -642,6 +648,23 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i vnc_write_u16(vs, src_x); vnc_write_u16(vs, src_y); vnc_flush(vs); + + /* do bitblit op on the local surface too */ + pitch = ds_get_linesize(vs->ds); + depth = ds_get_bytes_per_pixel(vs->ds); + src_row = ds_get_data(vs->ds) + pitch * src_y + depth * src_x; + dst_row = ds_get_data(vs->ds) + pitch * dst_y + depth * dst_x; + if (dst_y > src_y) { + /* copy backwards */ + src_row += pitch * (h-1); + dst_row += pitch * (h-1); + pitch = -pitch; + } + for (y = 0; y < h; y++) { + memmove(dst_row, src_row, w * depth); + src_row += pitch; + dst_row += pitch; + } } static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)