static void vnc_dpy_copy(DisplayChangeListener *dcl,

                         int src_x, int src_y,

                         int dst_x, int dst_y, int w, int h)

{

    VncDisplay *vd = container_of(dcl, VncDisplay, dcl);

    VncState *vs, *vn;

    uint8_t *src_row;

    uint8_t *dst_row;

    int i, x, y, pitch, inc, w_lim, s;

    int cmp_bytes;









    vnc_refresh_server_surface(vd);

    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {

        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

            vs->force_update = 1;

            vnc_update_client(vs, 1, true);

            /* vs might be free()ed here */









    /* do bitblit op on the local surface too */

    pitch = vnc_server_fb_stride(vd);

    src_row = vnc_server_fb_ptr(vd, src_x, src_y);

    dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);

    y = dst_y;

    inc = 1;

    if (dst_y > src_y) {

        /* copy backwards */

        src_row += pitch * (h-1);

        dst_row += pitch * (h-1);

        pitch = -pitch;

        y = dst_y + h - 1;

        inc = -1;


    w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));

    if (w_lim < 0) {

        w_lim = w;

    } else {

        w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);


    for (i = 0; i < h; i++) {

        for (x = 0; x <= w_lim;

                x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {

            if (x == w_lim) {

                if ((s = w - w_lim) == 0)

                    break;

            } else if (!x) {

                s = (VNC_DIRTY_PIXELS_PER_BIT -

                    (dst_x % VNC_DIRTY_PIXELS_PER_BIT));

                s = MIN(s, w_lim);

            } else {

                s = VNC_DIRTY_PIXELS_PER_BIT;


            cmp_bytes = s * VNC_SERVER_FB_BYTES;

            if (memcmp(src_row, dst_row, cmp_bytes) == 0)

                continue;

            memmove(dst_row, src_row, cmp_bytes);

            QTAILQ_FOREACH(vs, &vd->clients, next) {

                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

                    set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),

                            vs->dirty[y]);




        src_row += pitch - w * VNC_SERVER_FB_BYTES;

        dst_row += pitch - w * VNC_SERVER_FB_BYTES;

        y += inc;




    QTAILQ_FOREACH(vs, &vd->clients, next) {

        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

            vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);


