Commit 6cec5487990bf3f1f22b3fcb871978255e92ae0d

Authored by aliguori
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
@@ -124,11 +124,8 @@ struct VncState @@ -124,11 +124,8 @@ struct VncState
124 int csock; 124 int csock;
125 DisplayState *ds; 125 DisplayState *ds;
126 int need_update; 126 int need_update;
127 - int width;  
128 - int height;  
129 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS]; 127 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
130 char *old_data; 128 char *old_data;
131 - int depth; /* internal VNC frame buffer byte per pixel */  
132 int has_resize; 129 int has_resize;
133 int has_hextile; 130 int has_hextile;
134 int has_pointer_type_change; 131 int has_pointer_type_change;
@@ -165,10 +162,7 @@ struct VncState @@ -165,10 +162,7 @@ struct VncState
165 /* current output mode information */ 162 /* current output mode information */
166 VncWritePixels *write_pixels; 163 VncWritePixels *write_pixels;
167 VncSendHextileTile *send_hextile_tile; 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 CaptureVoiceOut *audio_cap; 167 CaptureVoiceOut *audio_cap;
174 struct audsettings as; 168 struct audsettings as;
@@ -271,10 +265,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) @@ -271,10 +265,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
271 w += (x % 16); 265 w += (x % 16);
272 x -= (x % 16); 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 for (; y < h; y++) 273 for (; y < h; y++)
280 for (i = 0; i < w; i += 16) 274 for (i = 0; i < w; i += 16)
@@ -304,13 +298,13 @@ static void vnc_dpy_resize(DisplayState *ds) @@ -304,13 +298,13 @@ static void vnc_dpy_resize(DisplayState *ds)
304 exit(1); 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 console_color_init(ds); 302 console_color_init(ds);
309 vnc_colordepth(ds); 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 if (size_changed) { 307 if (size_changed) {
312 - vs->width = ds_get_width(ds);  
313 - vs->height = ds_get_height(ds);  
314 if (vs->csock != -1 && vs->has_resize) { 308 if (vs->csock != -1 && vs->has_resize) {
315 vnc_write_u8(vs, 0); /* msg id */ 309 vnc_write_u8(vs, 0); /* msg id */
316 vnc_write_u8(vs, 0); 310 vnc_write_u8(vs, 0);
@@ -335,21 +329,21 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) @@ -335,21 +329,21 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
335 { 329 {
336 uint8_t r, g, b; 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 case 1: 342 case 1:
349 buf[0] = v; 343 buf[0] = v;
350 break; 344 break;
351 case 2: 345 case 2:
352 - if (vs->pix_big_endian) { 346 + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
353 buf[0] = v >> 8; 347 buf[0] = v >> 8;
354 buf[1] = v; 348 buf[1] = v;
355 } else { 349 } else {
@@ -359,7 +353,7 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) @@ -359,7 +353,7 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
359 break; 353 break;
360 default: 354 default:
361 case 4: 355 case 4:
362 - if (vs->pix_big_endian) { 356 + if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
363 buf[0] = v >> 24; 357 buf[0] = v >> 24;
364 buf[1] = v >> 16; 358 buf[1] = v >> 16;
365 buf[2] = v >> 8; 359 buf[2] = v >> 8;
@@ -378,29 +372,29 @@ static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) @@ -378,29 +372,29 @@ static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
378 { 372 {
379 uint8_t buf[4]; 373 uint8_t buf[4];
380 374
381 - if (vs->depth == 4) { 375 + if (vs->serverds.pf.bytes_per_pixel == 4) {
382 uint32_t *pixels = pixels1; 376 uint32_t *pixels = pixels1;
383 int n, i; 377 int n, i;
384 n = size >> 2; 378 n = size >> 2;
385 for(i = 0; i < n; i++) { 379 for(i = 0; i < n; i++) {
386 vnc_convert_pixel(vs, buf, pixels[i]); 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 uint16_t *pixels = pixels1; 384 uint16_t *pixels = pixels1;
391 int n, i; 385 int n, i;
392 n = size >> 1; 386 n = size >> 1;
393 for(i = 0; i < n; i++) { 387 for(i = 0; i < n; i++) {
394 vnc_convert_pixel(vs, buf, pixels[i]); 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 uint8_t *pixels = pixels1; 392 uint8_t *pixels = pixels1;
399 int n, i; 393 int n, i;
400 n = size; 394 n = size;
401 for(i = 0; i < n; i++) { 395 for(i = 0; i < n; i++) {
402 vnc_convert_pixel(vs, buf, pixels[i]); 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 } else { 399 } else {
406 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); 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,9 +408,9 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h
414 408
415 vnc_framebuffer_update(vs, x, y, w, h, 0); 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 for (i = 0; i < h; i++) { 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 row += ds_get_linesize(vs->ds); 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,8 +459,8 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i
465 459
466 vnc_framebuffer_update(vs, x, y, w, h, 5); 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 has_fg = has_bg = 0; 464 has_fg = has_bg = 0;
471 for (j = y; j < (y + h); j += 16) { 465 for (j = y; j < (y + h); j += 16) {
472 for (i = x; i < (x + w); i += 16) { 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,7 +501,7 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x)
507 { 501 {
508 int h; 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 int tmp_x; 505 int tmp_x;
512 if (!vnc_get_bit(vs->dirty_row[y + h], last_x)) 506 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
513 break; 507 break;
@@ -533,14 +527,14 @@ static void vnc_update_client(void *opaque) @@ -533,14 +527,14 @@ static void vnc_update_client(void *opaque)
533 527
534 vga_hw_update(); 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 /* Walk through the dirty map and eliminate tiles that 532 /* Walk through the dirty map and eliminate tiles that
539 really aren't dirty */ 533 really aren't dirty */
540 row = ds_get_data(vs->ds); 534 row = ds_get_data(vs->ds);
541 old_row = vs->old_data; 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 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) { 538 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
545 int x; 539 int x;
546 uint8_t *ptr; 540 uint8_t *ptr;
@@ -550,15 +544,15 @@ static void vnc_update_client(void *opaque) @@ -550,15 +544,15 @@ static void vnc_update_client(void *opaque)
550 old_ptr = (char*)old_row; 544 old_ptr = (char*)old_row;
551 545
552 for (x = 0; x < ds_get_width(vs->ds); x += 16) { 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 vnc_clear_bit(vs->dirty_row[y], (x / 16)); 548 vnc_clear_bit(vs->dirty_row[y], (x / 16));
555 } else { 549 } else {
556 has_dirty = 1; 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,10 +572,10 @@ static void vnc_update_client(void *opaque)
578 saved_offset = vs->output.offset; 572 saved_offset = vs->output.offset;
579 vnc_write_u16(vs, 0); 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 int x; 576 int x;
583 int last_x = -1; 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 if (vnc_get_bit(vs->dirty_row[y], x)) { 579 if (vnc_get_bit(vs->dirty_row[y], x)) {
586 if (last_x == -1) { 580 if (last_x == -1) {
587 last_x = x; 581 last_x = x;
@@ -1163,7 +1157,7 @@ static void framebuffer_update_request(VncState *vs, int incremental, @@ -1163,7 +1157,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
1163 for (i = 0; i < h; i++) { 1157 for (i = 0; i < h; i++) {
1164 vnc_set_bits(vs->dirty_row[y_position + i], 1158 vnc_set_bits(vs->dirty_row[y_position + i],
1165 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS); 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 old_row += ds_get_linesize(vs->ds); 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,75 +1226,66 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1232 check_pointer_type_change(vs, kbd_mouse_is_absolute()); 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 static void set_pixel_format(VncState *vs, 1262 static void set_pixel_format(VncState *vs,
1236 int bits_per_pixel, int depth, 1263 int bits_per_pixel, int depth,
1237 int big_endian_flag, int true_color_flag, 1264 int big_endian_flag, int true_color_flag,
1238 int red_max, int green_max, int blue_max, 1265 int red_max, int green_max, int blue_max,
1239 int red_shift, int green_shift, int blue_shift) 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 if (!true_color_flag) { 1268 if (!true_color_flag) {
1249 - fail:  
1250 vnc_client_error(vs); 1269 vnc_client_error(vs);
1251 return; 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 vga_hw_invalidate(); 1290 vga_hw_invalidate();
1306 vga_hw_update(); 1291 vga_hw_update();
@@ -1309,9 +1294,8 @@ static void set_pixel_format(VncState *vs, @@ -1309,9 +1294,8 @@ static void set_pixel_format(VncState *vs,
1309 static void pixel_format_message (VncState *vs) { 1294 static void pixel_format_message (VncState *vs) {
1310 char pad[3] = { 0, 0, 0 }; 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 #ifdef WORDS_BIGENDIAN 1300 #ifdef WORDS_BIGENDIAN
1317 vnc_write_u8(vs, 1); /* big-endian-flag */ 1301 vnc_write_u8(vs, 1); /* big-endian-flag */
@@ -1319,39 +1303,20 @@ static void pixel_format_message (VncState *vs) { @@ -1319,39 +1303,20 @@ static void pixel_format_message (VncState *vs) {
1319 vnc_write_u8(vs, 0); /* big-endian-flag */ 1303 vnc_write_u8(vs, 0); /* big-endian-flag */
1320 #endif 1304 #endif
1321 vnc_write_u8(vs, 1); /* true-color-flag */ 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 vs->send_hextile_tile = send_hextile_tile_32; 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 vs->send_hextile_tile = send_hextile_tile_16; 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 vs->send_hextile_tile = send_hextile_tile_8; 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 vs->write_pixels = vnc_write_pixels_copy; 1320 vs->write_pixels = vnc_write_pixels_copy;
1356 1321
1357 vnc_write(vs, pad, 3); /* padding */ 1322 vnc_write(vs, pad, 3); /* padding */
@@ -1364,47 +1329,8 @@ static void vnc_dpy_setdata(DisplayState *ds) @@ -1364,47 +1329,8 @@ static void vnc_dpy_setdata(DisplayState *ds)
1364 1329
1365 static void vnc_colordepth(DisplayState *ds) 1330 static void vnc_colordepth(DisplayState *ds)
1366 { 1331 {
1367 - int host_big_endian_flag;  
1368 struct VncState *vs = ds->opaque; 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 if (vs->csock != -1 && vs->has_WMVi) { 1334 if (vs->csock != -1 && vs->has_WMVi) {
1409 /* Sending a WMVi message to notify the client*/ 1335 /* Sending a WMVi message to notify the client*/
1410 vnc_write_u8(vs, 0); /* msg id */ 1336 vnc_write_u8(vs, 0); /* msg id */
@@ -1414,34 +1340,7 @@ static void vnc_colordepth(DisplayState *ds) @@ -1414,34 +1340,7 @@ static void vnc_colordepth(DisplayState *ds)
1414 pixel_format_message(vs); 1340 pixel_format_message(vs);
1415 vnc_flush(vs); 1341 vnc_flush(vs);
1416 } else { 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,8 +1485,6 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1586 char buf[1024]; 1485 char buf[1024];
1587 int size; 1486 int size;
1588 1487
1589 - vs->width = ds_get_width(vs->ds);  
1590 - vs->height = ds_get_height(vs->ds);  
1591 vnc_write_u16(vs, ds_get_width(vs->ds)); 1488 vnc_write_u16(vs, ds_get_width(vs->ds));
1592 vnc_write_u16(vs, ds_get_height(vs->ds)); 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,7 +13,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
13 void *last_fg_, 13 void *last_fg_,
14 int *has_bg, int *has_fg) 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 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_bg_; 19 pixel_t *last_bg = (pixel_t *)last_bg_;
@@ -24,7 +24,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, @@ -24,7 +24,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
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[(vs->pix_bpp + 2) * 16 * 16]; 27 + uint8_t data[(vs->clientds.pf.bytes_per_pixel + 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
@@ -132,7 +132,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, @@ -132,7 +132,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
132 has_color = 0; 132 has_color = 0;
133 #ifdef GENERIC 133 #ifdef GENERIC
134 vnc_convert_pixel(vs, data + n_data, color); 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 #else 136 #else
137 memcpy(data + n_data, &color, sizeof(color)); 137 memcpy(data + n_data, &color, sizeof(color));
138 n_data += sizeof(pixel_t); 138 n_data += sizeof(pixel_t);
@@ -152,7 +152,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, @@ -152,7 +152,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
152 if (has_color) { 152 if (has_color) {
153 #ifdef GENERIC 153 #ifdef GENERIC
154 vnc_convert_pixel(vs, data + n_data, color); 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 #else 156 #else
157 memcpy(data + n_data, &color, sizeof(color)); 157 memcpy(data + n_data, &color, sizeof(color));
158 n_data += sizeof(pixel_t); 158 n_data += sizeof(pixel_t);
@@ -197,7 +197,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, @@ -197,7 +197,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
197 } 197 }
198 } else { 198 } else {
199 for (j = 0; j < h; j++) { 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 row += ds_get_linesize(vs->ds); 201 row += ds_get_linesize(vs->ds);
202 } 202 }
203 } 203 }