WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] Qemu vnc WMVi support

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] Qemu vnc WMVi support
From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Date: Wed, 13 Feb 2008 14:34:40 +0000
Delivery-date: Wed, 13 Feb 2008 06:35:57 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.6 (X11/20071022)
Hi all,
the patch "qemu-vnc-wmvi.patch" adds support for the WMVi pseudoencoding in qemu vnc server. If the client implements it, it is supposed to be able to change colour depth when receiving a WMVi message.

Since I didn't know any client that supports it and I wanted to test the implementation before submitting any patch I also modified vncviewer to support WMVi. The patch "vncviewer-wmvi.patch" is meant to be applied to the realvnc vncviewer unix client version 4.1.2, using patch -p1.
Try executing vncviewer with FullColour=1 AutoSelect=0.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

Regards,

Stefano Stabellini
diff -r e85399173769 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Feb 12 16:59:08 2008 +0000
+++ b/tools/ioemu/vl.c  Wed Feb 13 12:41:42 2008 +0000
@@ -154,7 +154,6 @@ int nographic;
 int nographic;
 int vncviewer;
 int vncunused;
-int vncswitchbpp;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
 char *boot_device = NULL;
@@ -6560,7 +6559,6 @@ void help(void)
           "-vnc display    start a VNC server on display\n"
            "-vncviewer      start a vncviewer process for this domain\n"
            "-vncunused      bind the VNC server to an unused port\n"
-           "-vnc-switch-bpp VNC server closes connections when the guest OS 
changes colour depth\n"
 #ifndef NO_DAEMONIZE
           "-daemonize      daemonize QEMU after initializing\n"
 #endif
@@ -6662,7 +6660,6 @@ enum {
     QEMU_OPTION_acpi,
     QEMU_OPTION_vncviewer,
     QEMU_OPTION_vncunused,
-    QEMU_OPTION_vncswitchbpp,
     QEMU_OPTION_pci,
 };
 
@@ -6746,7 +6743,6 @@ const QEMUOption qemu_options[] = {
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
     { "vncviewer", 0, QEMU_OPTION_vncviewer },
     { "vncunused", 0, QEMU_OPTION_vncunused },
-    { "vnc-switch-bpp", 0, QEMU_OPTION_vncswitchbpp },
 
     /* temporary options */
     { "usb", 0, QEMU_OPTION_usb },
@@ -7164,7 +7160,6 @@ int main(int argc, char **argv)
     nographic = 0;
     vncviewer = 0;
     vncunused = 0;
-    vncswitchbpp = 0;
     kernel_filename = NULL;
     kernel_cmdline = "";
 #ifndef CONFIG_DM
@@ -7595,9 +7590,6 @@ int main(int argc, char **argv)
             case QEMU_OPTION_vncunused:
                 vncunused++;
                 break;
-            case QEMU_OPTION_vncswitchbpp:
-                vncswitchbpp++;
-                break;
             case QEMU_OPTION_pci:
                 direct_pci = optarg;
                 break;
@@ -7830,7 +7822,6 @@ int main(int argc, char **argv)
     } else if (vnc_display != NULL || vncunused != 0) {
        int vnc_display_port;
        char password[20];
-        ds->switchbpp = vncswitchbpp;
        vnc_display_init(ds);
        xenstore_read_vncpasswd(domid, password, sizeof(password));
        vnc_display_password(ds, password);
diff -r e85399173769 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Tue Feb 12 16:59:08 2008 +0000
+++ b/tools/ioemu/vnc.c Wed Feb 13 13:59:04 2008 +0000
@@ -157,6 +157,7 @@ struct VncState
     int has_resize;
     int has_hextile;
     int has_pointer_type_change;
+    int has_WMVi;
     int absolute;
     int last_x;
     int last_y;
@@ -1310,6 +1311,7 @@ static void set_encodings(VncState *vs, 
     vs->has_hextile = 0;
     vs->has_resize = 0;
     vs->has_pointer_type_change = 0;
+    vs->has_WMVi = 0;
     vs->absolute = -1;
     vs->ds->dpy_copy = NULL;
 
@@ -1330,6 +1332,8 @@ static void set_encodings(VncState *vs, 
        case -257:
            vs->has_pointer_type_change = 1;
            break;
+        case 0x574D5669:
+            vs->has_WMVi = 1;
        default:
            break;
        }
@@ -1408,6 +1412,57 @@ static void set_pixel_format(VncState *v
 
     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 */
+
+#ifdef WORDS_BIGENDIAN
+    vnc_write_u8(vs, 1);             /* big-endian-flag */
+#else
+    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 */
+        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 */
+        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 */
+        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->write_pixels = vnc_write_pixels_copy;
+        
+    vnc_write(vs, pad, 3);           /* padding */
 }
 
 static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
@@ -1457,6 +1512,14 @@ static void vnc_dpy_colourdepth(DisplayS
     }
     if (ds->switchbpp) {
         vnc_client_error(vs);
+    } else if (vs->csock != -1 && vs->has_WMVi) {
+        /* Sending a WMVi message to notify the client*/
+        vnc_write_u8(vs, 0);  /* msg id */
+        vnc_write_u8(vs, 0);
+        vnc_write_u16(vs, 1); /* number of rects */
+        vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
+        pixel_format_message(vs);
+        vnc_flush(vs);
     } else {
         if (vs->pix_bpp == 4 && vs->depth == 4 &&
             host_big_endian_flag == vs->pix_big_endian &&
@@ -1578,7 +1641,6 @@ static int protocol_client_init(VncState
 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
 {
     size_t l;
-    char pad[3] = { 0, 0, 0 };
 
     vga_hw_update();
 
@@ -1587,45 +1649,7 @@ static int protocol_client_init(VncState
     vnc_write_u16(vs, vs->ds->width);
     vnc_write_u16(vs, vs->ds->height);
 
-    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 */
-
-#ifdef WORDS_BIGENDIAN
-    vnc_write_u8(vs, 1);             /* big-endian-flag */
-#else
-    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 */
-        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 */
-        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 */
-        vs->send_hextile_tile = send_hextile_tile_8;
-    }
-    vs->write_pixels = vnc_write_pixels_copy;
-       
-    vnc_write(vs, pad, 3);           /* padding */
+    pixel_format_message(vs);
 
     l = strlen(domain_name); 
     vnc_write_u32(vs, l);        
@@ -2436,6 +2460,8 @@ int vnc_display_open(DisplayState *ds, c
        options++;
        if (strncmp(options, "password", 8) == 0) {
            password = 1; /* Require password auth */
+        } else if (strncmp(options, "switchbpp", 9) == 0) {
+            ds->switchbpp = 1;
 #if CONFIG_VNC_TLS
        } else if (strncmp(options, "tls", 3) == 0) {
            tls = 1; /* Require TLS */
diff -upr vnc-4_1_2-unixsrc/common/rfb/CMsgReaderV3.cxx 
../vnc-4_1_2-unixsrc-new/common/rfb/CMsgReaderV3.cxx
--- vnc-4_1_2-unixsrc/common/rfb/CMsgReaderV3.cxx       2006-05-15 
17:56:20.000000000 +0100
+++ ../vnc-4_1_2-unixsrc-new/common/rfb/CMsgReaderV3.cxx        2008-02-13 
14:13:05.000000000 +0000
@@ -74,6 +74,13 @@ void CMsgReaderV3::readMsg()
     case pseudoEncodingDesktopSize:
       handler->setDesktopSize(w, h);
       break;
+    case pseudoEncodingWMVi:
+    {
+      PixelFormat pf;
+      pf.read(is);
+      handler->setPixelFormat(pf);
+    }
+      break;
     case pseudoEncodingCursor:
       readSetCursor(w, h, Point(x,y));
       break;
diff -upr vnc-4_1_2-unixsrc/common/rfb/CMsgWriter.cxx 
../vnc-4_1_2-unixsrc-new/common/rfb/CMsgWriter.cxx
--- vnc-4_1_2-unixsrc/common/rfb/CMsgWriter.cxx 2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/common/rfb/CMsgWriter.cxx  2008-02-13 
14:13:32.000000000 +0000
@@ -64,6 +64,8 @@ void CMsgWriter::writeSetEncodings(int p
     encodings[nEncodings++] = pseudoEncodingCursor;
   if (cp->supportsDesktopResize)
     encodings[nEncodings++] = pseudoEncodingDesktopSize;
+  if (cp->supportsWMVi)
+    encodings[nEncodings++] = pseudoEncodingWMVi;
   if (Decoder::supported(preferredEncoding)) {
     encodings[nEncodings++] = preferredEncoding;
   }
diff -upr vnc-4_1_2-unixsrc/common/rfb/ConnParams.cxx 
../vnc-4_1_2-unixsrc-new/common/rfb/ConnParams.cxx
--- vnc-4_1_2-unixsrc/common/rfb/ConnParams.cxx 2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/common/rfb/ConnParams.cxx  2008-02-13 
14:14:14.000000000 +0000
@@ -88,6 +88,7 @@ void ConnParams::setEncodings(int nEncod
   useCopyRect = false;
   supportsLocalCursor = false;
   supportsDesktopResize = false;
+  supportsWMVi = false;
   currentEncoding_ = encodingRaw;
 
   for (int i = nEncodings-1; i >= 0; i--) {
@@ -99,6 +100,8 @@ void ConnParams::setEncodings(int nEncod
       supportsLocalCursor = true;
     else if (encodings[i] == pseudoEncodingDesktopSize)
       supportsDesktopResize = true;
+    else if (encodings[i] == pseudoEncodingWMVi)
+      supportsWMVi = true;
     else if (encodings[i] <= encodingMax && Encoder::supported(encodings[i]))
       currentEncoding_ = encodings[i];
   }
diff -upr vnc-4_1_2-unixsrc/common/rfb/ConnParams.h 
../vnc-4_1_2-unixsrc-new/common/rfb/ConnParams.h
--- vnc-4_1_2-unixsrc/common/rfb/ConnParams.h   2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/common/rfb/ConnParams.h    2008-02-13 
14:14:33.000000000 +0000
@@ -71,6 +71,7 @@ namespace rfb {
 
     bool supportsLocalCursor;
     bool supportsDesktopResize;
+    bool supportsWMVi;
 
   private:
 
diff -upr vnc-4_1_2-unixsrc/common/rfb/encodings.h 
../vnc-4_1_2-unixsrc-new/common/rfb/encodings.h
--- vnc-4_1_2-unixsrc/common/rfb/encodings.h    2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/common/rfb/encodings.h     2008-02-13 
14:14:58.000000000 +0000
@@ -31,6 +31,7 @@ namespace rfb {
 
   const unsigned int pseudoEncodingCursor = 0xffffff11;
   const unsigned int pseudoEncodingDesktopSize = 0xffffff21;
+  const unsigned int pseudoEncodingWMVi = 0x574D5669;
 
   int encodingNum(const char* name);
   const char* encodingName(unsigned int num);
diff -upr vnc-4_1_2-unixsrc/unix/vncviewer/CConn.cxx 
../vnc-4_1_2-unixsrc-new/unix/vncviewer/CConn.cxx
--- vnc-4_1_2-unixsrc/unix/vncviewer/CConn.cxx  2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/unix/vncviewer/CConn.cxx   2008-02-13 
14:15:51.000000000 +0000
@@ -75,6 +75,7 @@ CConn::CConn(Display* dpy_, int argc_, c
     autoSelect = false;
   }
   cp.supportsDesktopResize = true;
+  cp.supportsWMVi = true;
   cp.supportsLocalCursor = useLocalCursor;
   initMenu();
 
@@ -260,6 +261,17 @@ void CConn::setDesktopSize(int w, int h)
   }
 }
 
+// setPixelFormat is called upon receving a WMVi message
+void CConn::setPixelFormat(const PixelFormat &pf) {
+  cp.setPF(pf);
+  if (desktop) {
+    char str[256];
+    desktop->setPF(pf);
+    desktop->getPF().print(str, 256);
+    vlog.info("Using pixel format %s",str);
+   }
+ }
+
 // framebufferUpdateEnd() is called at the end of an update.
 // For each rectangle, the FdInStream will have timed the speed
 // of the connection, allowing us to select format and encoding
diff -upr vnc-4_1_2-unixsrc/unix/vncviewer/CConn.h 
../vnc-4_1_2-unixsrc-new/unix/vncviewer/CConn.h
--- vnc-4_1_2-unixsrc/unix/vncviewer/CConn.h    2006-05-15 17:56:20.000000000 
+0100
+++ ../vnc-4_1_2-unixsrc-new/unix/vncviewer/CConn.h     2008-02-13 
14:16:17.000000000 +0000
@@ -26,6 +26,7 @@
 #include <rfb/Exception.h>
 #include <rfb/UserPasswdGetter.h>
 #include <rdr/FdInStream.h>
+#include <rfb/PixelFormat.h>
 #include <list>
 
 #include "TXWindow.h"
@@ -74,6 +75,7 @@ public:
   rfb::CSecurity* getCSecurity(int secType);
   void serverInit();
   void setDesktopSize(int w, int h);
+  void setPixelFormat(const rfb::PixelFormat& pf);
   void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
   void bell();
   void serverCutText(const char* str, int len);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>