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
next 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.