[Qemu-devel] VNC cross-endian failures

2006-05-12 Thread Troy Benjegerdes
The VNC protocol says the server is is supposed to send the data in the
format the client wants, however the current implementation sends vnc
data in the server native format.

What is the best way to fix this? Using -bgr is not right since that
will mess up same-endian clients.


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] VNC cross-endian failures

2006-05-12 Thread Fabrice Bellard

Troy Benjegerdes wrote:

The VNC protocol says the server is is supposed to send the data in the
format the client wants, however the current implementation sends vnc
data in the server native format.

What is the best way to fix this? Using -bgr is not right since that
will mess up same-endian clients.


A fix will be commited ASAP...

Fabrice.


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] VNC cross-endian failures

2006-05-12 Thread Troy Benjegerdes
Much better.

I did have one bogon after running xvncview on a big-endian host,
closing it, then starting it on a little-endian host that resulted in
this from realvnc:

Rect too big: 24832x33024 at 8448,16640 exceeds 640x480
 main:Rect too big




On Sat, May 13, 2006 at 01:02:47AM +0200, Fabrice Bellard wrote:
 Troy Benjegerdes wrote:
 The VNC protocol says the server is is supposed to send the data in the
 format the client wants, however the current implementation sends vnc
 data in the server native format.
 
 What is the best way to fix this? Using -bgr is not right since that
 will mess up same-endian clients.
 
 Try the attached patch.
 
 Fabrice.

 Index: vnc.c
 ===
 RCS file: /sources/qemu/qemu/vnc.c,v
 retrieving revision 1.5
 diff -u -w -r1.5 vnc.c
 --- vnc.c 3 May 2006 21:18:59 -   1.5
 +++ vnc.c 12 May 2006 22:54:21 -
 @@ -42,6 +42,14 @@
  
  typedef int VncReadEvent(VncState *vs, char *data, size_t len);
  
 +typedef void VncWritePixels(VncState *vs, void *data, int size);
 +
 +typedef void VncSendHextileTile(VncState *vs,
 +int x, int y, int w, int h,
 +uint32_t *last_bg, 
 +uint32_t *last_fg,
 +int *has_bg, int *has_fg);
 +
  struct VncState
  {
  QEMUTimer *timer;
 @@ -53,12 +61,19 @@
  int height;
  uint64_t dirty_row[768];
  char *old_data;
 -int depth;
 +int depth; /* internal VNC frame buffer byte per pixel */
  int has_resize;
  int has_hextile;
  Buffer output;
  Buffer input;
  kbd_layout_t *kbd_layout;
 +/* current output mode information */
 +VncWritePixels *write_pixels;
 +VncSendHextileTile *send_hextile_tile;
 +int pix_bpp, pix_big_endian;
 +int red_shift, red_max, red_shift1;
 +int green_shift, green_max, green_shift1;
 +int blue_shift, blue_max, blue_shift1;
  
  VncReadEvent *read_handler;
  size_t read_handler_expect;
 @@ -130,6 +145,66 @@
  }
  }
  
 +/* fastest code */
 +static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
 +{
 +vnc_write(vs, pixels, size);
 +}
 +
 +/* slowest but generic code. */
 +static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
 +{
 +unsigned int r, g, b;
 +
 +r = (v  vs-red_shift1)  vs-red_max;
 +g = (v  vs-green_shift1)  vs-green_max;
 +b = (v  vs-blue_shift1)  vs-blue_max;
 +v = (r  vs-red_shift) | 
 +(g  vs-green_shift) | 
 +(b  vs-blue_shift);
 +switch(vs-pix_bpp) {
 +case 1:
 +buf[0] = v;
 +break;
 +case 2:
 +if (vs-pix_big_endian) {
 +buf[0] = v  8;
 +buf[1] = v;
 +} else {
 +buf[1] = v  8;
 +buf[0] = v;
 +}
 +break;
 +default:
 +case 4:
 +if (vs-pix_big_endian) {
 +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)
 +{
 +uint32_t *pixels = pixels1;
 +uint8_t buf[4];
 +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);
 +}
 +}
 +
  static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, 
 int h)
  {
  int i;
 @@ -139,7 +214,7 @@
  
  row = vs-ds-data + y * vs-ds-linesize + x * vs-depth;
  for (i = 0; i  h; i++) {
 - vnc_write(vs, row, w * vs-depth);
 + vs-write_pixels(vs, row, w * vs-depth);
   row += vs-ds-linesize;
  }
  }
 @@ -162,35 +237,26 @@
  #include vnchextile.h
  #undef BPP
  
 +#define GENERIC
 +#define BPP 32
 +#include vnchextile.h
 +#undef BPP
 +#undef GENERIC
 +
  static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int 
 w, int h)
  {
  int i, j;
  int has_fg, has_bg;
  uint32_t last_fg32, last_bg32;
 -uint16_t last_fg16, last_bg16;
 -uint8_t last_fg8, last_bg8;
  
  vnc_framebuffer_update(vs, x, y, w, h, 5);
  
  has_fg = has_bg = 0;
  for (j = y; j  (y + h); j += 16) {
   for (i = x; i  (x + w); i += 16) {
 - switch (vs-depth) {
 - case 1:
 - send_hextile_tile_8(vs, i, j, MIN(16, x + w - i), MIN(16, y + h 
 - j),
 - last_bg8, last_fg8, has_bg, has_fg);
 - break;
 - case 2:
 - send_hextile_tile_16(vs, i, j, MIN(16, x + w - i), MIN(16, y + 
 h - j),
 -  last_bg16, last_fg16, has_bg, has_fg);
 - break;
 - case 4:
 - send_hextile_tile_32(vs, i, j,