Commit 6cec5487990bf3f1f22b3fcb871978255e92ae0d
1 parent
7d957bd8
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 <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6337 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
108 additions
and
211 deletions
vnc.c
... | ... | @@ -124,11 +124,8 @@ struct VncState |
124 | 124 | int csock; |
125 | 125 | DisplayState *ds; |
126 | 126 | int need_update; |
127 | - int width; | |
128 | - int height; | |
129 | 127 | uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS]; |
130 | 128 | char *old_data; |
131 | - int depth; /* internal VNC frame buffer byte per pixel */ | |
132 | 129 | int has_resize; |
133 | 130 | int has_hextile; |
134 | 131 | int has_pointer_type_change; |
... | ... | @@ -165,10 +162,7 @@ struct VncState |
165 | 162 | /* current output mode information */ |
166 | 163 | VncWritePixels *write_pixels; |
167 | 164 | VncSendHextileTile *send_hextile_tile; |
168 | - int pix_bpp, pix_big_endian; | |
169 | - int client_red_shift, client_red_max, server_red_shift, server_red_max; | |
170 | - int client_green_shift, client_green_max, server_green_shift, server_green_max; | |
171 | - int client_blue_shift, client_blue_max, server_blue_shift, server_blue_max; | |
165 | + DisplaySurface clientds, serverds; | |
172 | 166 | |
173 | 167 | CaptureVoiceOut *audio_cap; |
174 | 168 | struct audsettings as; |
... | ... | @@ -271,10 +265,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) |
271 | 265 | w += (x % 16); |
272 | 266 | x -= (x % 16); |
273 | 267 | |
274 | - x = MIN(x, vs->width); | |
275 | - y = MIN(y, vs->height); | |
276 | - w = MIN(x + w, vs->width) - x; | |
277 | - h = MIN(h, vs->height); | |
268 | + x = MIN(x, vs->serverds.width); | |
269 | + y = MIN(y, vs->serverds.height); | |
270 | + w = MIN(x + w, vs->serverds.width) - x; | |
271 | + h = MIN(h, vs->serverds.height); | |
278 | 272 | |
279 | 273 | for (; y < h; y++) |
280 | 274 | for (i = 0; i < w; i += 16) |
... | ... | @@ -304,13 +298,13 @@ static void vnc_dpy_resize(DisplayState *ds) |
304 | 298 | exit(1); |
305 | 299 | } |
306 | 300 | |
307 | - if (ds_get_bytes_per_pixel(ds) != vs->depth) | |
301 | + if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel) | |
308 | 302 | console_color_init(ds); |
309 | 303 | vnc_colordepth(ds); |
310 | - size_changed = ds_get_width(ds) != vs->width || ds_get_height(ds) != vs->height; | |
304 | + size_changed = ds_get_width(ds) != vs->serverds.width || | |
305 | + ds_get_height(ds) != vs->serverds.height; | |
306 | + vs->serverds = *(ds->surface); | |
311 | 307 | if (size_changed) { |
312 | - vs->width = ds_get_width(ds); | |
313 | - vs->height = ds_get_height(ds); | |
314 | 308 | if (vs->csock != -1 && vs->has_resize) { |
315 | 309 | vnc_write_u8(vs, 0); /* msg id */ |
316 | 310 | vnc_write_u8(vs, 0); |
... | ... | @@ -335,21 +329,21 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) |
335 | 329 | { |
336 | 330 | uint8_t r, g, b; |
337 | 331 | |
338 | - r = ((v >> vs->server_red_shift) & vs->server_red_max) * (vs->client_red_max + 1) / | |
339 | - (vs->server_red_max + 1); | |
340 | - g = ((v >> vs->server_green_shift) & vs->server_green_max) * (vs->client_green_max + 1) / | |
341 | - (vs->server_green_max + 1); | |
342 | - b = ((v >> vs->server_blue_shift) & vs->server_blue_max) * (vs->client_blue_max + 1) / | |
343 | - (vs->server_blue_max + 1); | |
344 | - v = (r << vs->client_red_shift) | | |
345 | - (g << vs->client_green_shift) | | |
346 | - (b << vs->client_blue_shift); | |
347 | - switch(vs->pix_bpp) { | |
332 | + r = ((v >> vs->serverds.pf.rshift) & vs->serverds.pf.rmax) * (vs->clientds.pf.rmax + 1) / | |
333 | + (vs->serverds.pf.rmax + 1); | |
334 | + g = ((v >> vs->serverds.pf.gshift) & vs->serverds.pf.gmax) * (vs->clientds.pf.gmax + 1) / | |
335 | + (vs->serverds.pf.gmax + 1); | |
336 | + b = ((v >> vs->serverds.pf.bshift) & vs->serverds.pf.bmax) * (vs->clientds.pf.bmax + 1) / | |
337 | + (vs->serverds.pf.bmax + 1); | |
338 | + v = (r << vs->clientds.pf.rshift) | | |
339 | + (g << vs->clientds.pf.gshift) | | |
340 | + (b << vs->clientds.pf.bshift); | |
341 | + switch(vs->clientds.pf.bytes_per_pixel) { | |
348 | 342 | case 1: |
349 | 343 | buf[0] = v; |
350 | 344 | break; |
351 | 345 | case 2: |
352 | - if (vs->pix_big_endian) { | |
346 | + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { | |
353 | 347 | buf[0] = v >> 8; |
354 | 348 | buf[1] = v; |
355 | 349 | } else { |
... | ... | @@ -359,7 +353,7 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) |
359 | 353 | break; |
360 | 354 | default: |
361 | 355 | case 4: |
362 | - if (vs->pix_big_endian) { | |
356 | + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { | |
363 | 357 | buf[0] = v >> 24; |
364 | 358 | buf[1] = v >> 16; |
365 | 359 | buf[2] = v >> 8; |
... | ... | @@ -378,29 +372,29 @@ static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) |
378 | 372 | { |
379 | 373 | uint8_t buf[4]; |
380 | 374 | |
381 | - if (vs->depth == 4) { | |
375 | + if (vs->serverds.pf.bytes_per_pixel == 4) { | |
382 | 376 | uint32_t *pixels = pixels1; |
383 | 377 | int n, i; |
384 | 378 | n = size >> 2; |
385 | 379 | for(i = 0; i < n; i++) { |
386 | 380 | vnc_convert_pixel(vs, buf, pixels[i]); |
387 | - vnc_write(vs, buf, vs->pix_bpp); | |
381 | + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); | |
388 | 382 | } |
389 | - } else if (vs->depth == 2) { | |
383 | + } else if (vs->serverds.pf.bytes_per_pixel == 2) { | |
390 | 384 | uint16_t *pixels = pixels1; |
391 | 385 | int n, i; |
392 | 386 | n = size >> 1; |
393 | 387 | for(i = 0; i < n; i++) { |
394 | 388 | vnc_convert_pixel(vs, buf, pixels[i]); |
395 | - vnc_write(vs, buf, vs->pix_bpp); | |
389 | + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); | |
396 | 390 | } |
397 | - } else if (vs->depth == 1) { | |
391 | + } else if (vs->serverds.pf.bytes_per_pixel == 1) { | |
398 | 392 | uint8_t *pixels = pixels1; |
399 | 393 | int n, i; |
400 | 394 | n = size; |
401 | 395 | for(i = 0; i < n; i++) { |
402 | 396 | vnc_convert_pixel(vs, buf, pixels[i]); |
403 | - vnc_write(vs, buf, vs->pix_bpp); | |
397 | + vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); | |
404 | 398 | } |
405 | 399 | } else { |
406 | 400 | fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); |
... | ... | @@ -414,9 +408,9 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h |
414 | 408 | |
415 | 409 | vnc_framebuffer_update(vs, x, y, w, h, 0); |
416 | 410 | |
417 | - row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth; | |
411 | + row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); | |
418 | 412 | for (i = 0; i < h; i++) { |
419 | - vs->write_pixels(vs, row, w * vs->depth); | |
413 | + vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); | |
420 | 414 | row += ds_get_linesize(vs->ds); |
421 | 415 | } |
422 | 416 | } |
... | ... | @@ -465,8 +459,8 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i |
465 | 459 | |
466 | 460 | vnc_framebuffer_update(vs, x, y, w, h, 5); |
467 | 461 | |
468 | - last_fg = (uint8_t *) malloc(vs->depth); | |
469 | - last_bg = (uint8_t *) malloc(vs->depth); | |
462 | + last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); | |
463 | + last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); | |
470 | 464 | has_fg = has_bg = 0; |
471 | 465 | for (j = y; j < (y + h); j += 16) { |
472 | 466 | for (i = x; i < (x + w); i += 16) { |
... | ... | @@ -507,7 +501,7 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x) |
507 | 501 | { |
508 | 502 | int h; |
509 | 503 | |
510 | - for (h = 1; h < (vs->height - y); h++) { | |
504 | + for (h = 1; h < (vs->serverds.height - y); h++) { | |
511 | 505 | int tmp_x; |
512 | 506 | if (!vnc_get_bit(vs->dirty_row[y + h], last_x)) |
513 | 507 | break; |
... | ... | @@ -533,14 +527,14 @@ static void vnc_update_client(void *opaque) |
533 | 527 | |
534 | 528 | vga_hw_update(); |
535 | 529 | |
536 | - vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS); | |
530 | + vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS); | |
537 | 531 | |
538 | 532 | /* Walk through the dirty map and eliminate tiles that |
539 | 533 | really aren't dirty */ |
540 | 534 | row = ds_get_data(vs->ds); |
541 | 535 | old_row = vs->old_data; |
542 | 536 | |
543 | - for (y = 0; y < vs->height; y++) { | |
537 | + for (y = 0; y < ds_get_height(vs->ds); y++) { | |
544 | 538 | if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) { |
545 | 539 | int x; |
546 | 540 | uint8_t *ptr; |
... | ... | @@ -550,15 +544,15 @@ static void vnc_update_client(void *opaque) |
550 | 544 | old_ptr = (char*)old_row; |
551 | 545 | |
552 | 546 | for (x = 0; x < ds_get_width(vs->ds); x += 16) { |
553 | - if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) { | |
547 | + if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) { | |
554 | 548 | vnc_clear_bit(vs->dirty_row[y], (x / 16)); |
555 | 549 | } else { |
556 | 550 | has_dirty = 1; |
557 | - memcpy(old_ptr, ptr, 16 * vs->depth); | |
551 | + memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)); | |
558 | 552 | } |
559 | 553 | |
560 | - ptr += 16 * vs->depth; | |
561 | - old_ptr += 16 * vs->depth; | |
554 | + ptr += 16 * ds_get_bytes_per_pixel(vs->ds); | |
555 | + old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds); | |
562 | 556 | } |
563 | 557 | } |
564 | 558 | |
... | ... | @@ -578,10 +572,10 @@ static void vnc_update_client(void *opaque) |
578 | 572 | saved_offset = vs->output.offset; |
579 | 573 | vnc_write_u16(vs, 0); |
580 | 574 | |
581 | - for (y = 0; y < vs->height; y++) { | |
575 | + for (y = 0; y < vs->serverds.height; y++) { | |
582 | 576 | int x; |
583 | 577 | int last_x = -1; |
584 | - for (x = 0; x < vs->width / 16; x++) { | |
578 | + for (x = 0; x < vs->serverds.width / 16; x++) { | |
585 | 579 | if (vnc_get_bit(vs->dirty_row[y], x)) { |
586 | 580 | if (last_x == -1) { |
587 | 581 | last_x = x; |
... | ... | @@ -1163,7 +1157,7 @@ static void framebuffer_update_request(VncState *vs, int incremental, |
1163 | 1157 | for (i = 0; i < h; i++) { |
1164 | 1158 | vnc_set_bits(vs->dirty_row[y_position + i], |
1165 | 1159 | (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS); |
1166 | - memset(old_row, 42, ds_get_width(vs->ds) * vs->depth); | |
1160 | + memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds)); | |
1167 | 1161 | old_row += ds_get_linesize(vs->ds); |
1168 | 1162 | } |
1169 | 1163 | } |
... | ... | @@ -1232,75 +1226,66 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
1232 | 1226 | check_pointer_type_change(vs, kbd_mouse_is_absolute()); |
1233 | 1227 | } |
1234 | 1228 | |
1229 | +static void set_pixel_conversion(VncState *vs) | |
1230 | +{ | |
1231 | + if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == | |
1232 | + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && | |
1233 | + !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) { | |
1234 | + vs->write_pixels = vnc_write_pixels_copy; | |
1235 | + switch (vs->ds->surface->pf.bits_per_pixel) { | |
1236 | + case 8: | |
1237 | + vs->send_hextile_tile = send_hextile_tile_8; | |
1238 | + break; | |
1239 | + case 16: | |
1240 | + vs->send_hextile_tile = send_hextile_tile_16; | |
1241 | + break; | |
1242 | + case 32: | |
1243 | + vs->send_hextile_tile = send_hextile_tile_32; | |
1244 | + break; | |
1245 | + } | |
1246 | + } else { | |
1247 | + vs->write_pixels = vnc_write_pixels_generic; | |
1248 | + switch (vs->ds->surface->pf.bits_per_pixel) { | |
1249 | + case 8: | |
1250 | + vs->send_hextile_tile = send_hextile_tile_generic_8; | |
1251 | + break; | |
1252 | + case 16: | |
1253 | + vs->send_hextile_tile = send_hextile_tile_generic_16; | |
1254 | + break; | |
1255 | + case 32: | |
1256 | + vs->send_hextile_tile = send_hextile_tile_generic_32; | |
1257 | + break; | |
1258 | + } | |
1259 | + } | |
1260 | +} | |
1261 | + | |
1235 | 1262 | static void set_pixel_format(VncState *vs, |
1236 | 1263 | int bits_per_pixel, int depth, |
1237 | 1264 | int big_endian_flag, int true_color_flag, |
1238 | 1265 | int red_max, int green_max, int blue_max, |
1239 | 1266 | int red_shift, int green_shift, int blue_shift) |
1240 | 1267 | { |
1241 | - int host_big_endian_flag; | |
1242 | - | |
1243 | -#ifdef WORDS_BIGENDIAN | |
1244 | - host_big_endian_flag = 1; | |
1245 | -#else | |
1246 | - host_big_endian_flag = 0; | |
1247 | -#endif | |
1248 | 1268 | if (!true_color_flag) { |
1249 | - fail: | |
1250 | 1269 | vnc_client_error(vs); |
1251 | 1270 | return; |
1252 | 1271 | } |
1253 | - if (bits_per_pixel == 32 && | |
1254 | - bits_per_pixel == vs->depth * 8 && | |
1255 | - host_big_endian_flag == big_endian_flag && | |
1256 | - red_max == 0xff && green_max == 0xff && blue_max == 0xff && | |
1257 | - red_shift == 16 && green_shift == 8 && blue_shift == 0) { | |
1258 | - vs->depth = 4; | |
1259 | - vs->write_pixels = vnc_write_pixels_copy; | |
1260 | - vs->send_hextile_tile = send_hextile_tile_32; | |
1261 | - } else | |
1262 | - if (bits_per_pixel == 16 && | |
1263 | - bits_per_pixel == vs->depth * 8 && | |
1264 | - host_big_endian_flag == big_endian_flag && | |
1265 | - red_max == 31 && green_max == 63 && blue_max == 31 && | |
1266 | - red_shift == 11 && green_shift == 5 && blue_shift == 0) { | |
1267 | - vs->depth = 2; | |
1268 | - vs->write_pixels = vnc_write_pixels_copy; | |
1269 | - vs->send_hextile_tile = send_hextile_tile_16; | |
1270 | - } else | |
1271 | - if (bits_per_pixel == 8 && | |
1272 | - bits_per_pixel == vs->depth * 8 && | |
1273 | - red_max == 7 && green_max == 7 && blue_max == 3 && | |
1274 | - red_shift == 5 && green_shift == 2 && blue_shift == 0) { | |
1275 | - vs->depth = 1; | |
1276 | - vs->write_pixels = vnc_write_pixels_copy; | |
1277 | - vs->send_hextile_tile = send_hextile_tile_8; | |
1278 | - } else | |
1279 | - { | |
1280 | - /* generic and slower case */ | |
1281 | - if (bits_per_pixel != 8 && | |
1282 | - bits_per_pixel != 16 && | |
1283 | - bits_per_pixel != 32) | |
1284 | - goto fail; | |
1285 | - if (vs->depth == 4) { | |
1286 | - vs->send_hextile_tile = send_hextile_tile_generic_32; | |
1287 | - } else if (vs->depth == 2) { | |
1288 | - vs->send_hextile_tile = send_hextile_tile_generic_16; | |
1289 | - } else { | |
1290 | - vs->send_hextile_tile = send_hextile_tile_generic_8; | |
1291 | - } | |
1292 | 1272 | |
1293 | - vs->pix_big_endian = big_endian_flag; | |
1294 | - vs->write_pixels = vnc_write_pixels_generic; | |
1295 | - } | |
1273 | + vs->clientds = vs->serverds; | |
1274 | + vs->clientds.pf.rmax = red_max; | |
1275 | + vs->clientds.pf.rshift = red_shift; | |
1276 | + vs->clientds.pf.rmask = red_max << red_shift; | |
1277 | + vs->clientds.pf.gmax = green_max; | |
1278 | + vs->clientds.pf.gshift = green_shift; | |
1279 | + vs->clientds.pf.gmask = green_max << green_shift; | |
1280 | + vs->clientds.pf.bmax = blue_max; | |
1281 | + vs->clientds.pf.bshift = blue_shift; | |
1282 | + vs->clientds.pf.bmask = blue_max << blue_shift; | |
1283 | + vs->clientds.pf.bits_per_pixel = bits_per_pixel; | |
1284 | + vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8; | |
1285 | + vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; | |
1286 | + vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00; | |
1296 | 1287 | |
1297 | - vs->client_red_shift = red_shift; | |
1298 | - vs->client_red_max = red_max; | |
1299 | - vs->client_green_shift = green_shift; | |
1300 | - vs->client_green_max = green_max; | |
1301 | - vs->client_blue_shift = blue_shift; | |
1302 | - vs->client_blue_max = blue_max; | |
1303 | - vs->pix_bpp = bits_per_pixel / 8; | |
1288 | + set_pixel_conversion(vs); | |
1304 | 1289 | |
1305 | 1290 | vga_hw_invalidate(); |
1306 | 1291 | vga_hw_update(); |
... | ... | @@ -1309,9 +1294,8 @@ static void set_pixel_format(VncState *vs, |
1309 | 1294 | static void pixel_format_message (VncState *vs) { |
1310 | 1295 | char pad[3] = { 0, 0, 0 }; |
1311 | 1296 | |
1312 | - vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ | |
1313 | - if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ | |
1314 | - else vnc_write_u8(vs, vs->depth * 8); /* depth */ | |
1297 | + vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */ | |
1298 | + vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */ | |
1315 | 1299 | |
1316 | 1300 | #ifdef WORDS_BIGENDIAN |
1317 | 1301 | vnc_write_u8(vs, 1); /* big-endian-flag */ |
... | ... | @@ -1319,39 +1303,20 @@ static void pixel_format_message (VncState *vs) { |
1319 | 1303 | vnc_write_u8(vs, 0); /* big-endian-flag */ |
1320 | 1304 | #endif |
1321 | 1305 | vnc_write_u8(vs, 1); /* true-color-flag */ |
1322 | - if (vs->depth == 4) { | |
1323 | - vnc_write_u16(vs, 0xFF); /* red-max */ | |
1324 | - vnc_write_u16(vs, 0xFF); /* green-max */ | |
1325 | - vnc_write_u16(vs, 0xFF); /* blue-max */ | |
1326 | - vnc_write_u8(vs, 16); /* red-shift */ | |
1327 | - vnc_write_u8(vs, 8); /* green-shift */ | |
1328 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1306 | + vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */ | |
1307 | + vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */ | |
1308 | + vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */ | |
1309 | + vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */ | |
1310 | + vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */ | |
1311 | + vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */ | |
1312 | + if (vs->ds->surface->pf.bits_per_pixel == 32) | |
1329 | 1313 | vs->send_hextile_tile = send_hextile_tile_32; |
1330 | - } else if (vs->depth == 2) { | |
1331 | - vnc_write_u16(vs, 31); /* red-max */ | |
1332 | - vnc_write_u16(vs, 63); /* green-max */ | |
1333 | - vnc_write_u16(vs, 31); /* blue-max */ | |
1334 | - vnc_write_u8(vs, 11); /* red-shift */ | |
1335 | - vnc_write_u8(vs, 5); /* green-shift */ | |
1336 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1314 | + else if (vs->ds->surface->pf.bits_per_pixel == 16) | |
1337 | 1315 | vs->send_hextile_tile = send_hextile_tile_16; |
1338 | - } else if (vs->depth == 1) { | |
1339 | - /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ | |
1340 | - vnc_write_u16(vs, 7); /* red-max */ | |
1341 | - vnc_write_u16(vs, 7); /* green-max */ | |
1342 | - vnc_write_u16(vs, 3); /* blue-max */ | |
1343 | - vnc_write_u8(vs, 5); /* red-shift */ | |
1344 | - vnc_write_u8(vs, 2); /* green-shift */ | |
1345 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1316 | + else if (vs->ds->surface->pf.bits_per_pixel == 8) | |
1346 | 1317 | vs->send_hextile_tile = send_hextile_tile_8; |
1347 | - } | |
1348 | - vs->client_red_max = vs->server_red_max; | |
1349 | - vs->client_green_max = vs->server_green_max; | |
1350 | - vs->client_blue_max = vs->server_blue_max; | |
1351 | - vs->client_red_shift = vs->server_red_shift; | |
1352 | - vs->client_green_shift = vs->server_green_shift; | |
1353 | - vs->client_blue_shift = vs->server_blue_shift; | |
1354 | - vs->pix_bpp = vs->depth * 8; | |
1318 | + vs->clientds = *(vs->ds->surface); | |
1319 | + vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG; | |
1355 | 1320 | vs->write_pixels = vnc_write_pixels_copy; |
1356 | 1321 | |
1357 | 1322 | vnc_write(vs, pad, 3); /* padding */ |
... | ... | @@ -1364,47 +1329,8 @@ static void vnc_dpy_setdata(DisplayState *ds) |
1364 | 1329 | |
1365 | 1330 | static void vnc_colordepth(DisplayState *ds) |
1366 | 1331 | { |
1367 | - int host_big_endian_flag; | |
1368 | 1332 | struct VncState *vs = ds->opaque; |
1369 | 1333 | |
1370 | -#ifdef WORDS_BIGENDIAN | |
1371 | - host_big_endian_flag = 1; | |
1372 | -#else | |
1373 | - host_big_endian_flag = 0; | |
1374 | -#endif | |
1375 | - | |
1376 | - switch (ds_get_bits_per_pixel(ds)) { | |
1377 | - case 8: | |
1378 | - vs->depth = 1; | |
1379 | - vs->server_red_max = 7; | |
1380 | - vs->server_green_max = 7; | |
1381 | - vs->server_blue_max = 3; | |
1382 | - vs->server_red_shift = 5; | |
1383 | - vs->server_green_shift = 2; | |
1384 | - vs->server_blue_shift = 0; | |
1385 | - break; | |
1386 | - case 16: | |
1387 | - vs->depth = 2; | |
1388 | - vs->server_red_max = 31; | |
1389 | - vs->server_green_max = 63; | |
1390 | - vs->server_blue_max = 31; | |
1391 | - vs->server_red_shift = 11; | |
1392 | - vs->server_green_shift = 5; | |
1393 | - vs->server_blue_shift = 0; | |
1394 | - break; | |
1395 | - case 32: | |
1396 | - vs->depth = 4; | |
1397 | - vs->server_red_max = 255; | |
1398 | - vs->server_green_max = 255; | |
1399 | - vs->server_blue_max = 255; | |
1400 | - vs->server_red_shift = 16; | |
1401 | - vs->server_green_shift = 8; | |
1402 | - vs->server_blue_shift = 0; | |
1403 | - break; | |
1404 | - default: | |
1405 | - return; | |
1406 | - } | |
1407 | - | |
1408 | 1334 | if (vs->csock != -1 && vs->has_WMVi) { |
1409 | 1335 | /* Sending a WMVi message to notify the client*/ |
1410 | 1336 | vnc_write_u8(vs, 0); /* msg id */ |
... | ... | @@ -1414,34 +1340,7 @@ static void vnc_colordepth(DisplayState *ds) |
1414 | 1340 | pixel_format_message(vs); |
1415 | 1341 | vnc_flush(vs); |
1416 | 1342 | } else { |
1417 | - if (vs->pix_bpp == 4 && vs->depth == 4 && | |
1418 | - host_big_endian_flag == vs->pix_big_endian && | |
1419 | - vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff && | |
1420 | - vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) { | |
1421 | - vs->write_pixels = vnc_write_pixels_copy; | |
1422 | - vs->send_hextile_tile = send_hextile_tile_32; | |
1423 | - } else if (vs->pix_bpp == 2 && vs->depth == 2 && | |
1424 | - host_big_endian_flag == vs->pix_big_endian && | |
1425 | - vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 && | |
1426 | - vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) { | |
1427 | - vs->write_pixels = vnc_write_pixels_copy; | |
1428 | - vs->send_hextile_tile = send_hextile_tile_16; | |
1429 | - } else if (vs->pix_bpp == 1 && vs->depth == 1 && | |
1430 | - host_big_endian_flag == vs->pix_big_endian && | |
1431 | - vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 && | |
1432 | - vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) { | |
1433 | - vs->write_pixels = vnc_write_pixels_copy; | |
1434 | - vs->send_hextile_tile = send_hextile_tile_8; | |
1435 | - } else { | |
1436 | - if (vs->depth == 4) { | |
1437 | - vs->send_hextile_tile = send_hextile_tile_generic_32; | |
1438 | - } else if (vs->depth == 2) { | |
1439 | - vs->send_hextile_tile = send_hextile_tile_generic_16; | |
1440 | - } else { | |
1441 | - vs->send_hextile_tile = send_hextile_tile_generic_8; | |
1442 | - } | |
1443 | - vs->write_pixels = vnc_write_pixels_generic; | |
1444 | - } | |
1343 | + set_pixel_conversion(vs); | |
1445 | 1344 | } |
1446 | 1345 | } |
1447 | 1346 | |
... | ... | @@ -1586,8 +1485,6 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) |
1586 | 1485 | char buf[1024]; |
1587 | 1486 | int size; |
1588 | 1487 | |
1589 | - vs->width = ds_get_width(vs->ds); | |
1590 | - vs->height = ds_get_height(vs->ds); | |
1591 | 1488 | vnc_write_u16(vs, ds_get_width(vs->ds)); |
1592 | 1489 | vnc_write_u16(vs, ds_get_height(vs->ds)); |
1593 | 1490 | ... | ... |
vnchextile.h
... | ... | @@ -13,7 +13,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
13 | 13 | void *last_fg_, |
14 | 14 | int *has_bg, int *has_fg) |
15 | 15 | { |
16 | - uint8_t *row = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth); | |
16 | + uint8_t *row = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds)); | |
17 | 17 | pixel_t *irow = (pixel_t *)row; |
18 | 18 | int j, i; |
19 | 19 | pixel_t *last_bg = (pixel_t *)last_bg_; |
... | ... | @@ -24,7 +24,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
24 | 24 | int bg_count = 0; |
25 | 25 | int fg_count = 0; |
26 | 26 | int flags = 0; |
27 | - uint8_t data[(vs->pix_bpp + 2) * 16 * 16]; | |
27 | + uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16]; | |
28 | 28 | int n_data = 0; |
29 | 29 | int n_subtiles = 0; |
30 | 30 | |
... | ... | @@ -132,7 +132,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
132 | 132 | has_color = 0; |
133 | 133 | #ifdef GENERIC |
134 | 134 | vnc_convert_pixel(vs, data + n_data, color); |
135 | - n_data += vs->pix_bpp; | |
135 | + n_data += vs->clientds.pf.bytes_per_pixel; | |
136 | 136 | #else |
137 | 137 | memcpy(data + n_data, &color, sizeof(color)); |
138 | 138 | n_data += sizeof(pixel_t); |
... | ... | @@ -152,7 +152,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
152 | 152 | if (has_color) { |
153 | 153 | #ifdef GENERIC |
154 | 154 | vnc_convert_pixel(vs, data + n_data, color); |
155 | - n_data += vs->pix_bpp; | |
155 | + n_data += vs->clientds.pf.bytes_per_pixel; | |
156 | 156 | #else |
157 | 157 | memcpy(data + n_data, &color, sizeof(color)); |
158 | 158 | n_data += sizeof(pixel_t); |
... | ... | @@ -197,7 +197,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, |
197 | 197 | } |
198 | 198 | } else { |
199 | 199 | for (j = 0; j < h; j++) { |
200 | - vs->write_pixels(vs, row, w * vs->depth); | |
200 | + vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); | |
201 | 201 | row += ds_get_linesize(vs->ds); |
202 | 202 | } |
203 | 203 | } | ... | ... |