All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Subject: Qemu vnc WMVi support
Date: Wed, 13 Feb 2008 14:34:40 +0000	[thread overview]
Message-ID: <47B30000.3000307@eu.citrix.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 656 bytes --]

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@eu.citrix.com>

Regards,

Stefano Stabellini

[-- Attachment #2: qemu-vnc-wmvi.patch --]
[-- Type: text/x-patch, Size: 8386 bytes --]

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 */

[-- Attachment #3: vncviewer-wmvi.patch --]
[-- Type: text/x-patch, Size: 5030 bytes --]

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);

[-- Attachment #4: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

             reply	other threads:[~2008-02-13 14:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-13 14:34 Stefano Stabellini [this message]
2008-02-13 16:19 ` Qemu vnc WMVi support Anthony Liguori
2008-02-13 16:27   ` Daniel P. Berrange
2008-02-14 11:03   ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47B30000.3000307@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.