Commit 3e28c9adf4bfe2f4792557ee45684181bd6e6d1c

Authored by Gerd Hoffmann
Committed by Anthony Liguori
1 parent 85c2c735

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.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 22 additions and 0 deletions
@@ -654,6 +654,11 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) @@ -654,6 +654,11 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
654 654
655 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h) 655 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
656 { 656 {
  657 + uint8_t *src_row;
  658 + uint8_t *dst_row;
  659 + int y,pitch,depth;
  660 +
  661 + /* send bitblit op to the vnc client */
657 vnc_write_u8(vs, 0); /* msg id */ 662 vnc_write_u8(vs, 0); /* msg id */
658 vnc_write_u8(vs, 0); 663 vnc_write_u8(vs, 0);
659 vnc_write_u16(vs, 1); /* number of rects */ 664 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 @@ -661,6 +666,23 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i
661 vnc_write_u16(vs, src_x); 666 vnc_write_u16(vs, src_x);
662 vnc_write_u16(vs, src_y); 667 vnc_write_u16(vs, src_y);
663 vnc_flush(vs); 668 vnc_flush(vs);
  669 +
  670 + /* do bitblit op on the local surface too */
  671 + pitch = ds_get_linesize(vs->ds);
  672 + depth = ds_get_bytes_per_pixel(vs->ds);
  673 + src_row = vs->server.ds->data + pitch * src_y + depth * src_x;
  674 + dst_row = vs->server.ds->data + pitch * dst_y + depth * dst_x;
  675 + if (dst_y > src_y) {
  676 + /* copy backwards */
  677 + src_row += pitch * (h-1);
  678 + dst_row += pitch * (h-1);
  679 + pitch = -pitch;
  680 + }
  681 + for (y = 0; y < h; y++) {
  682 + memmove(dst_row, src_row, w * depth);
  683 + src_row += pitch;
  684 + dst_row += pitch;
  685 + }
664 } 686 }
665 687
666 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) 688 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)