Commit 7eac3a87f132dd68139a6fe29b81c25c4c00e96d
1 parent
82b36dc3
vnc dynamic resolution (Stefano Stabellini)
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5229 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
177 additions
and
53 deletions
vnc.c
@@ -71,8 +71,8 @@ typedef void VncWritePixels(VncState *vs, void *data, int size); | @@ -71,8 +71,8 @@ typedef void VncWritePixels(VncState *vs, void *data, int size); | ||
71 | 71 | ||
72 | typedef void VncSendHextileTile(VncState *vs, | 72 | typedef void VncSendHextileTile(VncState *vs, |
73 | int x, int y, int w, int h, | 73 | int x, int y, int w, int h, |
74 | - uint32_t *last_bg, | ||
75 | - uint32_t *last_fg, | 74 | + void *last_bg, |
75 | + void *last_fg, | ||
76 | int *has_bg, int *has_fg); | 76 | int *has_bg, int *has_fg); |
77 | 77 | ||
78 | #define VNC_MAX_WIDTH 2048 | 78 | #define VNC_MAX_WIDTH 2048 |
@@ -164,9 +164,9 @@ struct VncState | @@ -164,9 +164,9 @@ struct VncState | ||
164 | VncWritePixels *write_pixels; | 164 | VncWritePixels *write_pixels; |
165 | VncSendHextileTile *send_hextile_tile; | 165 | VncSendHextileTile *send_hextile_tile; |
166 | int pix_bpp, pix_big_endian; | 166 | int pix_bpp, pix_big_endian; |
167 | - int red_shift, red_max, red_shift1; | ||
168 | - int green_shift, green_max, green_shift1; | ||
169 | - int blue_shift, blue_max, blue_shift1; | 167 | + int client_red_shift, client_red_max, server_red_shift, server_red_max; |
168 | + int client_green_shift, client_green_max, server_green_shift, server_green_max; | ||
169 | + int client_blue_shift, client_blue_max, server_blue_shift, server_blue_max; | ||
170 | 170 | ||
171 | VncReadEvent *read_handler; | 171 | VncReadEvent *read_handler; |
172 | size_t read_handler_expect; | 172 | size_t read_handler_expect; |
@@ -208,6 +208,8 @@ static void vnc_flush(VncState *vs); | @@ -208,6 +208,8 @@ static void vnc_flush(VncState *vs); | ||
208 | static void vnc_update_client(void *opaque); | 208 | static void vnc_update_client(void *opaque); |
209 | static void vnc_client_read(void *opaque); | 209 | static void vnc_client_read(void *opaque); |
210 | 210 | ||
211 | +static void vnc_colordepth(DisplayState *ds, int depth); | ||
212 | + | ||
211 | static inline void vnc_set_bit(uint32_t *d, int k) | 213 | static inline void vnc_set_bit(uint32_t *d, int k) |
212 | { | 214 | { |
213 | d[k >> 5] |= 1 << (k & 0x1f); | 215 | d[k >> 5] |= 1 << (k & 0x1f); |
@@ -330,14 +332,17 @@ static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) | @@ -330,14 +332,17 @@ static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) | ||
330 | /* slowest but generic code. */ | 332 | /* slowest but generic code. */ |
331 | static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) | 333 | static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) |
332 | { | 334 | { |
333 | - unsigned int r, g, b; | ||
334 | - | ||
335 | - r = (v >> vs->red_shift1) & vs->red_max; | ||
336 | - g = (v >> vs->green_shift1) & vs->green_max; | ||
337 | - b = (v >> vs->blue_shift1) & vs->blue_max; | ||
338 | - v = (r << vs->red_shift) | | ||
339 | - (g << vs->green_shift) | | ||
340 | - (b << vs->blue_shift); | 335 | + uint8_t r, g, b; |
336 | + | ||
337 | + r = ((v >> vs->server_red_shift) & vs->server_red_max) * (vs->client_red_max + 1) / | ||
338 | + (vs->server_red_max + 1); | ||
339 | + g = ((v >> vs->server_green_shift) & vs->server_green_max) * (vs->client_green_max + 1) / | ||
340 | + (vs->server_green_max + 1); | ||
341 | + b = ((v >> vs->server_blue_shift) & vs->server_blue_max) * (vs->client_blue_max + 1) / | ||
342 | + (vs->server_blue_max + 1); | ||
343 | + v = (r << vs->client_red_shift) | | ||
344 | + (g << vs->client_green_shift) | | ||
345 | + (b << vs->client_blue_shift); | ||
341 | switch(vs->pix_bpp) { | 346 | switch(vs->pix_bpp) { |
342 | case 1: | 347 | case 1: |
343 | buf[0] = v; | 348 | buf[0] = v; |
@@ -370,14 +375,34 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) | @@ -370,14 +375,34 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) | ||
370 | 375 | ||
371 | static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) | 376 | static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) |
372 | { | 377 | { |
373 | - uint32_t *pixels = pixels1; | ||
374 | uint8_t buf[4]; | 378 | uint8_t buf[4]; |
375 | - int n, i; | ||
376 | 379 | ||
377 | - n = size >> 2; | ||
378 | - for(i = 0; i < n; i++) { | ||
379 | - vnc_convert_pixel(vs, buf, pixels[i]); | ||
380 | - vnc_write(vs, buf, vs->pix_bpp); | 380 | + if (vs->depth == 4) { |
381 | + uint32_t *pixels = pixels1; | ||
382 | + int n, i; | ||
383 | + n = size >> 2; | ||
384 | + for(i = 0; i < n; i++) { | ||
385 | + vnc_convert_pixel(vs, buf, pixels[i]); | ||
386 | + vnc_write(vs, buf, vs->pix_bpp); | ||
387 | + } | ||
388 | + } else if (vs->depth == 2) { | ||
389 | + uint16_t *pixels = pixels1; | ||
390 | + int n, i; | ||
391 | + n = size >> 1; | ||
392 | + for(i = 0; i < n; i++) { | ||
393 | + vnc_convert_pixel(vs, buf, pixels[i]); | ||
394 | + vnc_write(vs, buf, vs->pix_bpp); | ||
395 | + } | ||
396 | + } else if (vs->depth == 1) { | ||
397 | + uint8_t *pixels = pixels1; | ||
398 | + int n, i; | ||
399 | + n = size; | ||
400 | + for(i = 0; i < n; i++) { | ||
401 | + vnc_convert_pixel(vs, buf, pixels[i]); | ||
402 | + vnc_write(vs, buf, vs->pix_bpp); | ||
403 | + } | ||
404 | + } else { | ||
405 | + fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); | ||
381 | } | 406 | } |
382 | } | 407 | } |
383 | 408 | ||
@@ -414,6 +439,18 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) | @@ -414,6 +439,18 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) | ||
414 | #undef BPP | 439 | #undef BPP |
415 | 440 | ||
416 | #define GENERIC | 441 | #define GENERIC |
442 | +#define BPP 8 | ||
443 | +#include "vnchextile.h" | ||
444 | +#undef BPP | ||
445 | +#undef GENERIC | ||
446 | + | ||
447 | +#define GENERIC | ||
448 | +#define BPP 16 | ||
449 | +#include "vnchextile.h" | ||
450 | +#undef BPP | ||
451 | +#undef GENERIC | ||
452 | + | ||
453 | +#define GENERIC | ||
417 | #define BPP 32 | 454 | #define BPP 32 |
418 | #include "vnchextile.h" | 455 | #include "vnchextile.h" |
419 | #undef BPP | 456 | #undef BPP |
@@ -423,18 +460,23 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i | @@ -423,18 +460,23 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i | ||
423 | { | 460 | { |
424 | int i, j; | 461 | int i, j; |
425 | int has_fg, has_bg; | 462 | int has_fg, has_bg; |
426 | - uint32_t last_fg32, last_bg32; | 463 | + uint8_t *last_fg, *last_bg; |
427 | 464 | ||
428 | vnc_framebuffer_update(vs, x, y, w, h, 5); | 465 | vnc_framebuffer_update(vs, x, y, w, h, 5); |
429 | 466 | ||
467 | + last_fg = (uint8_t *) malloc(vs->depth); | ||
468 | + last_bg = (uint8_t *) malloc(vs->depth); | ||
430 | has_fg = has_bg = 0; | 469 | has_fg = has_bg = 0; |
431 | for (j = y; j < (y + h); j += 16) { | 470 | for (j = y; j < (y + h); j += 16) { |
432 | for (i = x; i < (x + w); i += 16) { | 471 | for (i = x; i < (x + w); i += 16) { |
433 | vs->send_hextile_tile(vs, i, j, | 472 | vs->send_hextile_tile(vs, i, j, |
434 | MIN(16, x + w - i), MIN(16, y + h - j), | 473 | MIN(16, x + w - i), MIN(16, y + h - j), |
435 | - &last_bg32, &last_fg32, &has_bg, &has_fg); | 474 | + last_bg, last_fg, &has_bg, &has_fg); |
436 | } | 475 | } |
437 | } | 476 | } |
477 | + free(last_fg); | ||
478 | + free(last_bg); | ||
479 | + | ||
438 | } | 480 | } |
439 | 481 | ||
440 | static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) | 482 | static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) |
@@ -1133,17 +1175,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | @@ -1133,17 +1175,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | ||
1133 | check_pointer_type_change(vs, kbd_mouse_is_absolute()); | 1175 | check_pointer_type_change(vs, kbd_mouse_is_absolute()); |
1134 | } | 1176 | } |
1135 | 1177 | ||
1136 | -static int compute_nbits(unsigned int val) | ||
1137 | -{ | ||
1138 | - int n; | ||
1139 | - n = 0; | ||
1140 | - while (val != 0) { | ||
1141 | - n++; | ||
1142 | - val >>= 1; | ||
1143 | - } | ||
1144 | - return n; | ||
1145 | -} | ||
1146 | - | ||
1147 | static void set_pixel_format(VncState *vs, | 1178 | static void set_pixel_format(VncState *vs, |
1148 | int bits_per_pixel, int depth, | 1179 | int bits_per_pixel, int depth, |
1149 | int big_endian_flag, int true_color_flag, | 1180 | int big_endian_flag, int true_color_flag, |
@@ -1163,6 +1194,7 @@ static void set_pixel_format(VncState *vs, | @@ -1163,6 +1194,7 @@ static void set_pixel_format(VncState *vs, | ||
1163 | return; | 1194 | return; |
1164 | } | 1195 | } |
1165 | if (bits_per_pixel == 32 && | 1196 | if (bits_per_pixel == 32 && |
1197 | + bits_per_pixel == vs->depth * 8 && | ||
1166 | host_big_endian_flag == big_endian_flag && | 1198 | host_big_endian_flag == big_endian_flag && |
1167 | red_max == 0xff && green_max == 0xff && blue_max == 0xff && | 1199 | red_max == 0xff && green_max == 0xff && blue_max == 0xff && |
1168 | red_shift == 16 && green_shift == 8 && blue_shift == 0) { | 1200 | red_shift == 16 && green_shift == 8 && blue_shift == 0) { |
@@ -1171,6 +1203,7 @@ static void set_pixel_format(VncState *vs, | @@ -1171,6 +1203,7 @@ static void set_pixel_format(VncState *vs, | ||
1171 | vs->send_hextile_tile = send_hextile_tile_32; | 1203 | vs->send_hextile_tile = send_hextile_tile_32; |
1172 | } else | 1204 | } else |
1173 | if (bits_per_pixel == 16 && | 1205 | if (bits_per_pixel == 16 && |
1206 | + bits_per_pixel == vs->depth * 8 && | ||
1174 | host_big_endian_flag == big_endian_flag && | 1207 | host_big_endian_flag == big_endian_flag && |
1175 | red_max == 31 && green_max == 63 && blue_max == 31 && | 1208 | red_max == 31 && green_max == 63 && blue_max == 31 && |
1176 | red_shift == 11 && green_shift == 5 && blue_shift == 0) { | 1209 | red_shift == 11 && green_shift == 5 && blue_shift == 0) { |
@@ -1179,6 +1212,7 @@ static void set_pixel_format(VncState *vs, | @@ -1179,6 +1212,7 @@ static void set_pixel_format(VncState *vs, | ||
1179 | vs->send_hextile_tile = send_hextile_tile_16; | 1212 | vs->send_hextile_tile = send_hextile_tile_16; |
1180 | } else | 1213 | } else |
1181 | if (bits_per_pixel == 8 && | 1214 | if (bits_per_pixel == 8 && |
1215 | + bits_per_pixel == vs->depth * 8 && | ||
1182 | red_max == 7 && green_max == 7 && blue_max == 3 && | 1216 | red_max == 7 && green_max == 7 && blue_max == 3 && |
1183 | red_shift == 5 && green_shift == 2 && blue_shift == 0) { | 1217 | red_shift == 5 && green_shift == 2 && blue_shift == 0) { |
1184 | vs->depth = 1; | 1218 | vs->depth = 1; |
@@ -1191,28 +1225,116 @@ static void set_pixel_format(VncState *vs, | @@ -1191,28 +1225,116 @@ static void set_pixel_format(VncState *vs, | ||
1191 | bits_per_pixel != 16 && | 1225 | bits_per_pixel != 16 && |
1192 | bits_per_pixel != 32) | 1226 | bits_per_pixel != 32) |
1193 | goto fail; | 1227 | goto fail; |
1194 | - vs->depth = 4; | ||
1195 | - vs->red_shift = red_shift; | ||
1196 | - vs->red_max = red_max; | ||
1197 | - vs->red_shift1 = 24 - compute_nbits(red_max); | ||
1198 | - vs->green_shift = green_shift; | ||
1199 | - vs->green_max = green_max; | ||
1200 | - vs->green_shift1 = 16 - compute_nbits(green_max); | ||
1201 | - vs->blue_shift = blue_shift; | ||
1202 | - vs->blue_max = blue_max; | ||
1203 | - vs->blue_shift1 = 8 - compute_nbits(blue_max); | ||
1204 | - vs->pix_bpp = bits_per_pixel / 8; | 1228 | + if (vs->depth == 4) { |
1229 | + vs->send_hextile_tile = send_hextile_tile_generic_32; | ||
1230 | + } else if (vs->depth == 2) { | ||
1231 | + vs->send_hextile_tile = send_hextile_tile_generic_16; | ||
1232 | + } else { | ||
1233 | + vs->send_hextile_tile = send_hextile_tile_generic_8; | ||
1234 | + } | ||
1235 | + | ||
1205 | vs->pix_big_endian = big_endian_flag; | 1236 | vs->pix_big_endian = big_endian_flag; |
1206 | vs->write_pixels = vnc_write_pixels_generic; | 1237 | vs->write_pixels = vnc_write_pixels_generic; |
1207 | - vs->send_hextile_tile = send_hextile_tile_generic; | ||
1208 | } | 1238 | } |
1209 | 1239 | ||
1210 | - vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); | 1240 | + vs->client_red_shift = red_shift; |
1241 | + vs->client_red_max = red_max; | ||
1242 | + vs->client_green_shift = green_shift; | ||
1243 | + vs->client_green_max = green_max; | ||
1244 | + vs->client_blue_shift = blue_shift; | ||
1245 | + vs->client_blue_max = blue_max; | ||
1246 | + vs->pix_bpp = bits_per_pixel / 8; | ||
1211 | 1247 | ||
1212 | vga_hw_invalidate(); | 1248 | vga_hw_invalidate(); |
1213 | vga_hw_update(); | 1249 | vga_hw_update(); |
1214 | } | 1250 | } |
1215 | 1251 | ||
1252 | +static void vnc_colordepth(DisplayState *ds, int depth) | ||
1253 | +{ | ||
1254 | + int host_big_endian_flag; | ||
1255 | + struct VncState *vs = ds->opaque; | ||
1256 | + | ||
1257 | + switch (depth) { | ||
1258 | + case 24: | ||
1259 | + if (ds->depth == 32) return; | ||
1260 | + depth = 32; | ||
1261 | + break; | ||
1262 | + case 15: | ||
1263 | + case 8: | ||
1264 | + case 0: | ||
1265 | + return; | ||
1266 | + default: | ||
1267 | + break; | ||
1268 | + } | ||
1269 | + | ||
1270 | +#ifdef WORDS_BIGENDIAN | ||
1271 | + host_big_endian_flag = 1; | ||
1272 | +#else | ||
1273 | + host_big_endian_flag = 0; | ||
1274 | +#endif | ||
1275 | + | ||
1276 | + switch (depth) { | ||
1277 | + case 8: | ||
1278 | + vs->depth = depth / 8; | ||
1279 | + vs->server_red_max = 7; | ||
1280 | + vs->server_green_max = 7; | ||
1281 | + vs->server_blue_max = 3; | ||
1282 | + vs->server_red_shift = 5; | ||
1283 | + vs->server_green_shift = 2; | ||
1284 | + vs->server_blue_shift = 0; | ||
1285 | + break; | ||
1286 | + case 16: | ||
1287 | + vs->depth = depth / 8; | ||
1288 | + vs->server_red_max = 31; | ||
1289 | + vs->server_green_max = 63; | ||
1290 | + vs->server_blue_max = 31; | ||
1291 | + vs->server_red_shift = 11; | ||
1292 | + vs->server_green_shift = 5; | ||
1293 | + vs->server_blue_shift = 0; | ||
1294 | + break; | ||
1295 | + case 32: | ||
1296 | + vs->depth = 4; | ||
1297 | + vs->server_red_max = 255; | ||
1298 | + vs->server_green_max = 255; | ||
1299 | + vs->server_blue_max = 255; | ||
1300 | + vs->server_red_shift = 16; | ||
1301 | + vs->server_green_shift = 8; | ||
1302 | + vs->server_blue_shift = 0; | ||
1303 | + break; | ||
1304 | + default: | ||
1305 | + return; | ||
1306 | + } | ||
1307 | + | ||
1308 | + if (vs->pix_bpp == 4 && vs->depth == 4 && | ||
1309 | + host_big_endian_flag == vs->pix_big_endian && | ||
1310 | + vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff && | ||
1311 | + vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) { | ||
1312 | + vs->write_pixels = vnc_write_pixels_copy; | ||
1313 | + vs->send_hextile_tile = send_hextile_tile_32; | ||
1314 | + } else if (vs->pix_bpp == 2 && vs->depth == 2 && | ||
1315 | + host_big_endian_flag == vs->pix_big_endian && | ||
1316 | + vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 && | ||
1317 | + vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) { | ||
1318 | + vs->write_pixels = vnc_write_pixels_copy; | ||
1319 | + vs->send_hextile_tile = send_hextile_tile_16; | ||
1320 | + } else if (vs->pix_bpp == 1 && vs->depth == 1 && | ||
1321 | + host_big_endian_flag == vs->pix_big_endian && | ||
1322 | + vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 && | ||
1323 | + vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) { | ||
1324 | + vs->write_pixels = vnc_write_pixels_copy; | ||
1325 | + vs->send_hextile_tile = send_hextile_tile_8; | ||
1326 | + } else { | ||
1327 | + if (vs->depth == 4) { | ||
1328 | + vs->send_hextile_tile = send_hextile_tile_generic_32; | ||
1329 | + } else if (vs->depth == 2) { | ||
1330 | + vs->send_hextile_tile = send_hextile_tile_generic_16; | ||
1331 | + } else { | ||
1332 | + vs->send_hextile_tile = send_hextile_tile_generic_8; | ||
1333 | + } | ||
1334 | + vs->write_pixels = vnc_write_pixels_generic; | ||
1335 | + } | ||
1336 | +} | ||
1337 | + | ||
1216 | static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) | 1338 | static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) |
1217 | { | 1339 | { |
1218 | int i; | 1340 | int i; |
@@ -1316,7 +1438,9 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) | @@ -1316,7 +1438,9 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) | ||
1316 | vnc_write_u16(vs, vs->ds->height); | 1438 | vnc_write_u16(vs, vs->ds->height); |
1317 | 1439 | ||
1318 | vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ | 1440 | vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ |
1319 | - vnc_write_u8(vs, vs->depth * 8); /* depth */ | 1441 | + if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ |
1442 | + else vnc_write_u8(vs, vs->depth * 8); /* depth */ | ||
1443 | + | ||
1320 | #ifdef WORDS_BIGENDIAN | 1444 | #ifdef WORDS_BIGENDIAN |
1321 | vnc_write_u8(vs, 1); /* big-endian-flag */ | 1445 | vnc_write_u8(vs, 1); /* big-endian-flag */ |
1322 | #else | 1446 | #else |
@@ -2006,7 +2130,6 @@ void vnc_display_init(DisplayState *ds) | @@ -2006,7 +2130,6 @@ void vnc_display_init(DisplayState *ds) | ||
2006 | 2130 | ||
2007 | vs->lsock = -1; | 2131 | vs->lsock = -1; |
2008 | vs->csock = -1; | 2132 | vs->csock = -1; |
2009 | - vs->depth = 4; | ||
2010 | vs->last_x = -1; | 2133 | vs->last_x = -1; |
2011 | vs->last_y = -1; | 2134 | vs->last_y = -1; |
2012 | 2135 | ||
@@ -2027,6 +2150,7 @@ void vnc_display_init(DisplayState *ds) | @@ -2027,6 +2150,7 @@ void vnc_display_init(DisplayState *ds) | ||
2027 | vs->ds->dpy_resize = vnc_dpy_resize; | 2150 | vs->ds->dpy_resize = vnc_dpy_resize; |
2028 | vs->ds->dpy_refresh = NULL; | 2151 | vs->ds->dpy_refresh = NULL; |
2029 | 2152 | ||
2153 | + vnc_colordepth(vs->ds, 32); | ||
2030 | vnc_dpy_resize(vs->ds, 640, 400); | 2154 | vnc_dpy_resize(vs->ds, 640, 400); |
2031 | } | 2155 | } |
2032 | 2156 |
vnchextile.h
@@ -2,29 +2,29 @@ | @@ -2,29 +2,29 @@ | ||
2 | #define CONCAT(a, b) CONCAT_I(a, b) | 2 | #define CONCAT(a, b) CONCAT_I(a, b) |
3 | #define pixel_t CONCAT(uint, CONCAT(BPP, _t)) | 3 | #define pixel_t CONCAT(uint, CONCAT(BPP, _t)) |
4 | #ifdef GENERIC | 4 | #ifdef GENERIC |
5 | -#define NAME generic | 5 | +#define NAME CONCAT(generic_, BPP) |
6 | #else | 6 | #else |
7 | #define NAME BPP | 7 | #define NAME BPP |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, | 10 | static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
11 | int x, int y, int w, int h, | 11 | int x, int y, int w, int h, |
12 | - uint32_t *last_bg32, | ||
13 | - uint32_t *last_fg32, | 12 | + void *last_bg_, |
13 | + void *last_fg_, | ||
14 | int *has_bg, int *has_fg) | 14 | int *has_bg, int *has_fg) |
15 | { | 15 | { |
16 | uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); | 16 | uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); |
17 | pixel_t *irow = (pixel_t *)row; | 17 | pixel_t *irow = (pixel_t *)row; |
18 | int j, i; | 18 | int j, i; |
19 | - pixel_t *last_bg = (pixel_t *)last_bg32; | ||
20 | - pixel_t *last_fg = (pixel_t *)last_fg32; | 19 | + pixel_t *last_bg = (pixel_t *)last_bg_; |
20 | + pixel_t *last_fg = (pixel_t *)last_fg_; | ||
21 | pixel_t bg = 0; | 21 | pixel_t bg = 0; |
22 | pixel_t fg = 0; | 22 | pixel_t fg = 0; |
23 | int n_colors = 0; | 23 | int n_colors = 0; |
24 | int bg_count = 0; | 24 | int bg_count = 0; |
25 | int fg_count = 0; | 25 | int fg_count = 0; |
26 | int flags = 0; | 26 | int flags = 0; |
27 | - uint8_t data[(sizeof(pixel_t) + 2) * 16 * 16]; | 27 | + uint8_t data[(vs->pix_bpp + 2) * 16 * 16]; |
28 | int n_data = 0; | 28 | int n_data = 0; |
29 | int n_subtiles = 0; | 29 | int n_subtiles = 0; |
30 | 30 |