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 654  
655 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 662 vnc_write_u8(vs, 0); /* msg id */
658 663 vnc_write_u8(vs, 0);
659 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 666 vnc_write_u16(vs, src_x);
662 667 vnc_write_u16(vs, src_y);
663 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 688 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
... ...