From: Ian Jackson Date: Tue, 10 Mar 2009 18:04:43 +0000 (+0000) Subject: exploiting the new interface in vnc.c (Stefano Stabellini) X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e6c1dbc212aa15c1dbf2dd50cec65c1c8bf0f977;p=xenclient%2Fioemu.git exploiting the new interface in vnc.c (Stefano Stabellini) This patch exploits the new DisplaySurface and PixelFormat structures in vnc, making the code easier to read allowing further improvements. Compared to the last version I fixed a bug that prevented the hextile encoding from working properly. Signed-off-by: Stefano Stabellini Signed-off-by: Anthony Liguori As adapted by Stefano to qemu-xen-unstable in his posting: [Xen-devel] [PATCH 5 of 13] exploiting the new interface in vnc.c --- diff --git a/console.c b/console.c index df55aa44..4dbdc912 100644 --- a/console.c +++ b/console.c @@ -1310,6 +1310,9 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp) pf.rshift = 0; pf.gshift = 8; pf.bshift = 16; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; break; case 32: pf.rmask = 0x0000FF00; @@ -1324,6 +1327,10 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp) pf.rshift = 8; pf.gshift = 16; pf.bshift = 24; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + pf.abits = 8; break; default: break; @@ -1352,6 +1359,9 @@ PixelFormat qemu_default_pixelformat(int bpp) pf.rshift = 11; pf.gshift = 5; pf.bshift = 0; + pf.rbits = 5; + pf.gbits = 6; + pf.bbits = 5; break; case 24: pf.rmask = 0x00FF0000; @@ -1363,6 +1373,9 @@ PixelFormat qemu_default_pixelformat(int bpp) pf.rshift = 16; pf.gshift = 8; pf.bshift = 0; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; case 32: pf.rmask = 0x00FF0000; pf.gmask = 0x0000FF00; @@ -1375,6 +1388,10 @@ PixelFormat qemu_default_pixelformat(int bpp) pf.rshift = 16; pf.gshift = 8; pf.bshift = 0; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + pf.abits = 8; break; default: break; diff --git a/console.h b/console.h index 2591a97a..2d7ca730 100644 --- a/console.h +++ b/console.h @@ -77,6 +77,7 @@ struct PixelFormat { uint32_t rmask, gmask, bmask, amask; uint8_t rshift, gshift, bshift, ashift; uint8_t rmax, gmax, bmax, amax; + uint8_t rbits, gbits, bbits, abits; }; struct DisplaySurface { diff --git a/vnc.c b/vnc.c index 7dba060e..52e46274 100644 --- a/vnc.c +++ b/vnc.c @@ -74,6 +74,12 @@ static void vnc_debug_gnutls_log(int level, const char* str) { #define VNC_DEBUG(fmt, ...) do { } while (0) #endif +#define count_bits(c, v) { \ + for (c = 0; v; v >>= 1) \ + { \ + c += v & 1; \ + } \ +} typedef struct Buffer { @@ -162,8 +168,6 @@ struct VncState int lsock; int csock; DisplayState *ds; - int width; - int height; uint64_t *dirty_row; /* screen regions which are possibly dirty */ int dirty_pixel_shift; uint64_t *update_row; /* outstanding updates */ @@ -173,7 +177,6 @@ struct VncState int update_requested; /* the client requested an update */ uint8_t *old_data; - int depth; /* internal VNC frame buffer byte per pixel */ int has_resize; int has_hextile; int has_pointer_type_change; @@ -214,10 +217,7 @@ struct VncState /* current output mode information */ VncWritePixels *write_pixels; VncSendHextileTile *send_hextile_tile; - int pix_bpp, pix_big_endian; - int red_shift, red_max, red_shift1, red_max1; - int green_shift, green_max, green_shift1, green_max1; - int blue_shift, blue_max, blue_shift1, blue_max1; + DisplaySurface clientds, serverds; VncReadEvent *read_handler; size_t read_handler_expect; @@ -351,10 +351,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) { VncState *vs = ds->opaque; - x = MIN(x, vs->width); - y = MIN(y, vs->height); - w = MIN(w, vs->width - x); - h = MIN(h, vs->height - y); + x = MIN(x, vs->serverds.width); + y = MIN(y, vs->serverds.height); + w = MIN(w, vs->serverds.width - x); + h = MIN(h, vs->serverds.height - y); set_bits_in_row(vs, vs->dirty_row, x, y, w, h); } @@ -385,13 +385,13 @@ static void vnc_dpy_resize(DisplayState *ds) exit(1); } - if (ds_get_bytes_per_pixel(ds) != vs->depth) + if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel) console_color_init(ds); vnc_colordepth(ds); - size_changed = ds_get_width(ds) != vs->width || ds_get_height(ds) != vs->height; + size_changed = ds_get_width(ds) != vs->serverds.width || + ds_get_height(ds) != vs->serverds.height; + vs->serverds = *(ds->surface); if (vs->csock != -1 && vs->has_resize && size_changed) { - vs->width = ds_get_width(ds); - vs->height = ds_get_height(ds); if (vs->update_requested) { vnc_write_u8(vs, 0); /* msg id */ vnc_write_u8(vs, 0); @@ -420,62 +420,72 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) { uint8_t r, g, b; - r = ((v >> vs->red_shift1) & vs->red_max1) * (vs->red_max + 1) / (vs->red_max1 + 1); - g = ((v >> vs->green_shift1) & vs->green_max1) * (vs->green_max + 1) / (vs->green_max1 + 1); - b = ((v >> vs->blue_shift1) & vs->blue_max1) * (vs->blue_max + 1) / (vs->blue_max1 + 1); - switch(vs->pix_bpp) { + r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >> + vs->serverds.pf.rbits); + g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >> + vs->serverds.pf.gbits); + b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >> + vs->serverds.pf.bbits); + v = (r << vs->clientds.pf.rshift) | + (g << vs->clientds.pf.gshift) | + (b << vs->clientds.pf.bshift); + switch(vs->clientds.pf.bytes_per_pixel) { case 1: - buf[0] = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); + buf[0] = v; break; case 2: - { - uint16_t *p = (uint16_t *) buf; - *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); - if (vs->pix_big_endian) { - *p = htons(*p); + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { + buf[0] = v >> 8; + buf[1] = v; + } else { + buf[1] = v >> 8; + buf[0] = v; } - } break; default: case 4: - { - uint32_t *p = (uint32_t *) buf; - *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); - if (vs->pix_big_endian) { - *p = htonl(*p); + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { + buf[0] = v >> 24; + buf[1] = v >> 16; + buf[2] = v >> 8; + buf[3] = v; + } else { + buf[3] = v >> 24; + buf[2] = v >> 16; + buf[1] = v >> 8; + buf[0] = v; } break; } - } } static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) { uint8_t buf[4]; - if (vs->depth == 4) { + if (vs->serverds.pf.bytes_per_pixel == 4) { uint32_t *pixels = pixels1; int n, i; n = size >> 2; for(i = 0; i < n; i++) { vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->pix_bpp); + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); } - } else if (vs->depth == 2) { + } else if (vs->serverds.pf.bytes_per_pixel == 2) { uint16_t *pixels = pixels1; int n, i; n = size >> 1; for(i = 0; i < n; i++) { vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->pix_bpp); + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); } - } else if (vs->depth == 1) { + } else if (vs->serverds.pf.bytes_per_pixel == 1) { uint8_t *pixels = pixels1; int n, i; n = size; for(i = 0; i < n; i++) { vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->pix_bpp); + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); } } else { fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); @@ -489,9 +499,9 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h vnc_framebuffer_update(vs, x, y, w, h, 0); - row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth; + row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); for (i = 0; i < h; i++) { - vs->write_pixels(vs, row, w * vs->depth); + vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); row += ds_get_linesize(vs->ds); } } @@ -540,8 +550,8 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i vnc_framebuffer_update(vs, x, y, w, h, 5); - last_fg = (void *) malloc(vs->depth); - last_bg = (void *) malloc(vs->depth); + last_fg = (void *) malloc(vs->serverds.pf.bytes_per_pixel); + last_bg = (void *) malloc(vs->serverds.pf.bytes_per_pixel); has_fg = has_bg = 0; for (j = y; j < (y + h); j += 16) { for (i = x; i < (x + w); i += 16) { @@ -618,7 +628,7 @@ static void _vnc_update_client(void *opaque) int n_rectangles; int saved_offset; int maxx, maxy; - int tile_bytes = vs->depth * DP2X(vs, 1); + int tile_bytes = vs->serverds.pf.bytes_per_pixel * DP2X(vs, 1); if (!vs->update_requested || vs->csock == -1) return; @@ -638,7 +648,7 @@ static void _vnc_update_client(void *opaque) now = qemu_get_clock(rt_clock); - if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS)) + if (vs->serverds.width != DP2X(vs, DIRTY_PIXEL_BITS)) width_mask = (1ULL << X2DP_UP(vs, ds_get_width(vs->ds))) - 1; else width_mask = ~(0ULL); @@ -1541,81 +1551,79 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) check_pointer_type_change(vs, kbd_mouse_is_absolute()); } +static void set_pixel_conversion(VncState *vs) +{ + if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && + !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) { + vs->write_pixels = vnc_write_pixels_copy; + switch (vs->ds->surface->pf.bits_per_pixel) { + case 8: + vs->send_hextile_tile = send_hextile_tile_8; + break; + case 16: + vs->send_hextile_tile = send_hextile_tile_16; + break; + case 32: + vs->send_hextile_tile = send_hextile_tile_32; + break; + } + } else { + vs->write_pixels = vnc_write_pixels_generic; + switch (vs->ds->surface->pf.bits_per_pixel) { + case 8: + vs->send_hextile_tile = send_hextile_tile_generic_8; + break; + case 16: + vs->send_hextile_tile = send_hextile_tile_generic_16; + break; + case 32: + vs->send_hextile_tile = send_hextile_tile_generic_32; + break; + } + } +} + static void set_pixel_format(VncState *vs, int bits_per_pixel, int depth, int big_endian_flag, int true_color_flag, int red_max, int green_max, int blue_max, int red_shift, int green_shift, int blue_shift) { - int host_big_endian_flag; - -#ifdef WORDS_BIGENDIAN - host_big_endian_flag = 1; -#else - host_big_endian_flag = 0; -#endif if (!true_color_flag) { - fail: vnc_client_error(vs); return; } - if (bits_per_pixel == 32 && - bits_per_pixel == vs->depth * 8 && - host_big_endian_flag == big_endian_flag && - red_max == 0xff && green_max == 0xff && blue_max == 0xff && - red_shift == 16 && green_shift == 8 && blue_shift == 0) { - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_32; - } else - if (bits_per_pixel == 16 && - bits_per_pixel == vs->depth * 8 && - host_big_endian_flag == big_endian_flag && - red_max == 31 && green_max == 63 && blue_max == 31 && - red_shift == 11 && green_shift == 5 && blue_shift == 0) { - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_16; - } else - if (bits_per_pixel == 8 && - bits_per_pixel == vs->depth * 8 && - red_max == 7 && green_max == 7 && blue_max == 3 && - red_shift == 5 && green_shift == 2 && blue_shift == 0) { - vs->depth = 1; - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_8; - } else - { - /* generic and slower case */ - if (bits_per_pixel != 8 && - bits_per_pixel != 16 && - bits_per_pixel != 32) - goto fail; - if (vs->depth == 4) { - vs->send_hextile_tile = send_hextile_tile_generic_32; - } else if (vs->depth == 2) { - vs->send_hextile_tile = send_hextile_tile_generic_16; - } else { - vs->send_hextile_tile = send_hextile_tile_generic_8; - } - - vs->pix_big_endian = big_endian_flag; - vs->write_pixels = vnc_write_pixels_generic; - } - - vs->red_shift = red_shift; - vs->red_max = red_max; - vs->green_shift = green_shift; - vs->green_max = green_max; - vs->blue_shift = blue_shift; - vs->blue_max = blue_max; - vs->pix_bpp = bits_per_pixel / 8; + + vs->clientds = vs->serverds; + vs->clientds.pf.rmax = red_max; + count_bits(vs->clientds.pf.rbits, red_max); + vs->clientds.pf.rshift = red_shift; + vs->clientds.pf.rmask = red_max << red_shift; + vs->clientds.pf.gmax = green_max; + count_bits(vs->clientds.pf.gbits, green_max); + vs->clientds.pf.gshift = green_shift; + vs->clientds.pf.gmask = green_max << green_shift; + vs->clientds.pf.bmax = blue_max; + count_bits(vs->clientds.pf.bbits, blue_max); + vs->clientds.pf.bshift = blue_shift; + vs->clientds.pf.bmask = blue_max << blue_shift; + vs->clientds.pf.bits_per_pixel = bits_per_pixel; + vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8; + vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; + vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00; + + set_pixel_conversion(vs); + + vga_hw_invalidate(); + vga_hw_update(); } static void pixel_format_message (VncState *vs) { char pad[3] = { 0, 0, 0 }; - vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ - if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ - else vnc_write_u8(vs, vs->depth * 8); /* depth */ + vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */ + vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */ #ifdef WORDS_BIGENDIAN vnc_write_u8(vs, 1); /* big-endian-flag */ @@ -1623,41 +1631,22 @@ static void pixel_format_message (VncState *vs) { vnc_write_u8(vs, 0); /* big-endian-flag */ #endif vnc_write_u8(vs, 1); /* true-color-flag */ - if (vs->depth == 4) { - vnc_write_u16(vs, 0xFF); /* red-max */ - vnc_write_u16(vs, 0xFF); /* green-max */ - vnc_write_u16(vs, 0xFF); /* blue-max */ - vnc_write_u8(vs, 16); /* red-shift */ - vnc_write_u8(vs, 8); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ + vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */ + vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */ + vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */ + vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */ + vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */ + vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */ + if (vs->ds->surface->pf.bits_per_pixel == 32) vs->send_hextile_tile = send_hextile_tile_32; - } else if (vs->depth == 2) { - vnc_write_u16(vs, 31); /* red-max */ - vnc_write_u16(vs, 63); /* green-max */ - vnc_write_u16(vs, 31); /* blue-max */ - vnc_write_u8(vs, 11); /* red-shift */ - vnc_write_u8(vs, 5); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ + else if (vs->ds->surface->pf.bits_per_pixel == 16) vs->send_hextile_tile = send_hextile_tile_16; - } else if (vs->depth == 1) { - /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ - vnc_write_u16(vs, 7); /* red-max */ - vnc_write_u16(vs, 7); /* green-max */ - vnc_write_u16(vs, 3); /* blue-max */ - vnc_write_u8(vs, 5); /* red-shift */ - vnc_write_u8(vs, 2); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ + else if (vs->ds->surface->pf.bits_per_pixel == 8) vs->send_hextile_tile = send_hextile_tile_8; - } - vs->red_max = vs->red_max1; - vs->green_max = vs->green_max1; - vs->blue_max = vs->blue_max1; - vs->red_shift = vs->red_shift1; - vs->green_shift = vs->green_shift1; - vs->blue_shift = vs->blue_shift1; - vs->pix_bpp = vs->depth * 8; + vs->clientds = *(vs->ds->surface); + vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG; vs->write_pixels = vnc_write_pixels_copy; - + vnc_write(vs, pad, 3); /* padding */ } @@ -1668,46 +1657,8 @@ static void vnc_dpy_setdata(DisplayState *ds) static void vnc_colordepth(DisplayState *ds) { - int host_big_endian_flag; struct VncState *vs = ds->opaque; -#ifdef WORDS_BIGENDIAN - host_big_endian_flag = 1; -#else - host_big_endian_flag = 0; -#endif - - switch (ds_get_bits_per_pixel(ds)) { - case 8: - vs->depth = 1; - vs->red_max1 = 7; - vs->green_max1 = 7; - vs->blue_max1 = 3; - vs->red_shift1 = 5; - vs->green_shift1 = 2; - vs->blue_shift1 = 0; - break; - case 16: - vs->depth = 2; - vs->red_max1 = 31; - vs->green_max1 = 63; - vs->blue_max1 = 31; - vs->red_shift1 = 11; - vs->green_shift1 = 5; - vs->blue_shift1 = 0; - break; - case 32: - vs->depth = 4; - vs->red_max1 = 255; - vs->green_max1 = 255; - vs->blue_max1 = 255; - vs->red_shift1 = 16; - vs->green_shift1 = 8; - vs->blue_shift1 = 0; - break; - default: - return; - } if (vs->switchbpp) { vnc_client_error(vs); } else if (vs->csock != -1 && vs->has_WMVi) { @@ -1724,34 +1675,7 @@ static void vnc_colordepth(DisplayState *ds) enqueue_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669); } } else { - if (vs->pix_bpp == 4 && vs->depth == 4 && - host_big_endian_flag == vs->pix_big_endian && - vs->red_max == 0xff && vs->green_max == 0xff && vs->blue_max == 0xff && - vs->red_shift == 16 && vs->green_shift == 8 && vs->blue_shift == 0) { - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_32; - } else if (vs->pix_bpp == 2 && vs->depth == 2 && - host_big_endian_flag == vs->pix_big_endian && - vs->red_max == 31 && vs->green_max == 63 && vs->blue_max == 31 && - vs->red_shift == 11 && vs->green_shift == 5 && vs->blue_shift == 0) { - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_16; - } else if (vs->pix_bpp == 1 && vs->depth == 1 && - host_big_endian_flag == vs->pix_big_endian && - vs->red_max == 7 && vs->green_max == 7 && vs->blue_max == 3 && - vs->red_shift == 5 && vs->green_shift == 2 && vs->blue_shift == 0) { - vs->write_pixels = vnc_write_pixels_copy; - vs->send_hextile_tile = send_hextile_tile_8; - } else { - if (vs->depth == 4) { - vs->send_hextile_tile = send_hextile_tile_generic_32; - } else if (vs->depth == 2) { - vs->send_hextile_tile = send_hextile_tile_generic_16; - } else { - vs->send_hextile_tile = send_hextile_tile_generic_8; - } - vs->write_pixels = vnc_write_pixels_generic; - } + set_pixel_conversion(vs); } } @@ -1845,8 +1769,6 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) vga_hw_update(); - vs->width = ds_get_width(vs->ds); - vs->height = ds_get_height(vs->ds); vnc_write_u16(vs, ds_get_width(vs->ds)); vnc_write_u16(vs, ds_get_height(vs->ds)); diff --git a/vnchextile.h b/vnchextile.h index a495b8a6..d2b8f525 100644 --- a/vnchextile.h +++ b/vnchextile.h @@ -13,7 +13,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, void *last_fg_, int *has_bg, int *has_fg) { - uint8_t *row = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth); + uint8_t *row = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds)); pixel_t *irow = (pixel_t *)row; int j, i; pixel_t *last_bg = (pixel_t *)last_bg_; @@ -24,7 +24,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, int bg_count = 0; int fg_count = 0; int flags = 0; - uint8_t data[(vs->pix_bpp + 2) * 16 * 16]; + uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16]; int n_data = 0; int n_subtiles = 0; @@ -132,7 +132,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, has_color = 0; #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); - n_data += vs->pix_bpp; + n_data += vs->clientds.pf.bytes_per_pixel; #else memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); @@ -152,7 +152,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, if (has_color) { #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); - n_data += vs->pix_bpp; + n_data += vs->clientds.pf.bytes_per_pixel; #else memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); @@ -197,7 +197,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, } } else { for (j = 0; j < h; j++) { - vs->write_pixels(vs, row, w * vs->depth); + vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); row += ds_get_linesize(vs->ds); } }