From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MVRqv-0004hq-Ud for qemu-devel@nongnu.org; Mon, 27 Jul 2009 11:11:01 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MVRqr-0004eT-Aa for qemu-devel@nongnu.org; Mon, 27 Jul 2009 11:11:01 -0400 Received: from [199.232.76.173] (port=55736 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MVRqr-0004eK-6Z for qemu-devel@nongnu.org; Mon, 27 Jul 2009 11:10:57 -0400 Received: from mx2.redhat.com ([66.187.237.31]:43849) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MVRqq-0004DN-M3 for qemu-devel@nongnu.org; Mon, 27 Jul 2009 11:10:56 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6RFAtb8006987 for ; Mon, 27 Jul 2009 11:10:55 -0400 From: Gerd Hoffmann Date: Mon, 27 Jul 2009 17:10:48 +0200 Message-Id: <1248707448-29648-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH] vnc: fix copyrect screen corruption List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann 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. --- vnc.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/vnc.c b/vnc.c index de0ff87..a50ee0c 100644 --- a/vnc.c +++ b/vnc.c @@ -654,6 +654,11 @@ 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; + + /* 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 */ @@ -661,6 +666,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 = vs->server.ds->data + pitch * src_y + depth * src_x; + dst_row = vs->server.ds->data + 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) -- 1.6.2.5