* [Qemu-devel] [PATCH 0/7] Add zlib support to VNC server @ 2009-01-30 14:38 Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel Alright, this is my tight alternative ;). In order to make the qemu VNC server usable over low bandwidth connections, we need to support some encodings that perform better under these constaints. One that is really easy to implement and pretty commonly implemented in clients is zlib. Zlib takes the raw output, sends it through zlib and sends that over the wire. For me, bandwidth usage was a lot less than hextile's. Of course, this isn't going to be the last of the encodings I'll implement, but it's a pretty good start - hopefully better than jpeg tight, since zlib is completely lossless. Alexander Graf (7): Split VNC defines to vnc.h Use VNC protocol defines Fix invalid #if in vnc.c when debugging is enabled Add some tight awareness to vnc.c Move buffer functions up Move the framebuffer update package out Add zlib encoding support vnc.c | 333 ++++++++++++++++++++++++++++++++++++++++++----------------------- vnc.h | 112 ++++++++++++++++++++++ 2 files changed, 326 insertions(+), 119 deletions(-) create mode 100644 vnc.h ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h 2009-01-30 14:38 [Qemu-devel] [PATCH 0/7] Add zlib support to VNC server Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf 2009-02-02 15:58 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori 0 siblings, 2 replies; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel The VNC protocol contains quite some constants, some of which are currently hardcoded in the vnc.c code. This is not exactly pretty. Let's move all those constants out to vnc.h, so they are clearly separated. While at it, I also included other defines that will be used later in this patch series. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 36 +-------------------- vnc.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 vnc.h diff --git a/vnc.c b/vnc.c index 2b3a6eb..e88f38f 100644 --- a/vnc.c +++ b/vnc.c @@ -32,6 +32,7 @@ #define VNC_REFRESH_INTERVAL (1000 / 30) +#include "vnc.h" #include "vnc_keysym.h" #include "keymaps.c" #include "d3des.h" @@ -88,41 +89,6 @@ typedef void VncSendHextileTile(VncState *vs, #define VNC_AUTH_CHALLENGE_SIZE 16 -enum { - VNC_AUTH_INVALID = 0, - VNC_AUTH_NONE = 1, - VNC_AUTH_VNC = 2, - VNC_AUTH_RA2 = 5, - VNC_AUTH_RA2NE = 6, - VNC_AUTH_TIGHT = 16, - VNC_AUTH_ULTRA = 17, - VNC_AUTH_TLS = 18, - VNC_AUTH_VENCRYPT = 19 -}; - -#ifdef CONFIG_VNC_TLS -enum { - VNC_WIREMODE_CLEAR, - VNC_WIREMODE_TLS, -}; - -enum { - VNC_AUTH_VENCRYPT_PLAIN = 256, - VNC_AUTH_VENCRYPT_TLSNONE = 257, - VNC_AUTH_VENCRYPT_TLSVNC = 258, - VNC_AUTH_VENCRYPT_TLSPLAIN = 259, - VNC_AUTH_VENCRYPT_X509NONE = 260, - VNC_AUTH_VENCRYPT_X509VNC = 261, - VNC_AUTH_VENCRYPT_X509PLAIN = 262, -}; - -#define X509_CA_CERT_FILE "ca-cert.pem" -#define X509_CA_CRL_FILE "ca-crl.pem" -#define X509_SERVER_KEY_FILE "server-key.pem" -#define X509_SERVER_CERT_FILE "server-cert.pem" - -#endif /* CONFIG_VNC_TLS */ - struct VncState { QEMUTimer *timer; diff --git a/vnc.h b/vnc.h new file mode 100644 index 0000000..56c6a8f --- /dev/null +++ b/vnc.h @@ -0,0 +1,112 @@ +#ifndef __VNCTIGHT_H +#define __VNCTIGHT_H + +/***************************************************************************** + * + * Authentication modes + * + *****************************************************************************/ + +enum { + VNC_AUTH_INVALID = 0, + VNC_AUTH_NONE = 1, + VNC_AUTH_VNC = 2, + VNC_AUTH_RA2 = 5, + VNC_AUTH_RA2NE = 6, + VNC_AUTH_TIGHT = 16, + VNC_AUTH_ULTRA = 17, + VNC_AUTH_TLS = 18, + VNC_AUTH_VENCRYPT = 19 +}; + +#ifdef CONFIG_VNC_TLS +enum { + VNC_WIREMODE_CLEAR, + VNC_WIREMODE_TLS, +}; + +enum { + VNC_AUTH_VENCRYPT_PLAIN = 256, + VNC_AUTH_VENCRYPT_TLSNONE = 257, + VNC_AUTH_VENCRYPT_TLSVNC = 258, + VNC_AUTH_VENCRYPT_TLSPLAIN = 259, + VNC_AUTH_VENCRYPT_X509NONE = 260, + VNC_AUTH_VENCRYPT_X509VNC = 261, + VNC_AUTH_VENCRYPT_X509PLAIN = 262, +}; + +#define X509_CA_CERT_FILE "ca-cert.pem" +#define X509_CA_CRL_FILE "ca-crl.pem" +#define X509_SERVER_KEY_FILE "server-key.pem" +#define X509_SERVER_CERT_FILE "server-cert.pem" + +#endif /* CONFIG_VNC_TLS */ + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define VNC_ENCODING_RAW 0x00000000 +#define VNC_ENCODING_COPYRECT 0x00000001 +#define VNC_ENCODING_RRE 0x00000002 +#define VNC_ENCODING_CORRE 0x00000004 +#define VNC_ENCODING_HEXTILE 0x00000005 +#define VNC_ENCODING_ZLIB 0x00000006 +#define VNC_ENCODING_TIGHT 0x00000007 +#define VNC_ENCODING_ZLIBHEX 0x00000008 +#define VNC_ENCODING_TRLE 0x0000000f +#define VNC_ENCODING_ZRLE 0x00000010 +#define VNC_ENCODING_ZYWRLE 0x00000011 +#define VNC_ENCODING_COMPRESSLEVEL0 0xFFFFFF00 /* -256 */ +#define VNC_ENCODING_QUALITYLEVEL0 0xFFFFFFE0 /* -32 */ +#define VNC_ENCODING_XCURSOR 0xFFFFFF10 /* -240 */ +#define VNC_ENCODING_RICH_CURSOR 0xFFFFFF11 /* -239 */ +#define VNC_ENCODING_POINTER_POS 0xFFFFFF18 /* -232 */ +#define VNC_ENCODING_LASTRECT 0xFFFFFF20 /* -224 */ +#define VNC_ENCODING_DESKTOPRESIZE 0xFFFFFF21 /* -223 */ +#define VNC_ENCODING_POINTER_TYPE_CHANGE 0XFFFFFEFF /* -257 */ +#define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE /* -258 */ +#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */ +#define VNC_ENCODING_WMVi 0x574D5669 + +/***************************************************************************** + * + * Other tight constants + * + *****************************************************************************/ + +/* + * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC. + */ + +#define VNC_TIGHT_CCB_RESET_MASK (0x0f) +#define VNC_TIGHT_CCB_TYPE_MASK (0x0f << 4) +#define VNC_TIGHT_CCB_TYPE_FILL (0x08 << 4) +#define VNC_TIGHT_CCB_TYPE_JPEG (0x09 << 4) +#define VNC_TIGHT_CCB_BASIC_MAX (0x07 << 4) +#define VNC_TIGHT_CCB_BASIC_ZLIB (0x03 << 4) +#define VNC_TIGHT_CCB_BASIC_FILTER (0x04 << 4) + +/***************************************************************************** + * + * Features + * + *****************************************************************************/ + +#define VNC_FEATURE_RESIZE 0 +#define VNC_FEATURE_HEXTILE 1 +#define VNC_FEATURE_POINTER_TYPE_CHANGE 2 +#define VNC_FEATURE_WMVI 3 +#define VNC_FEATURE_TIGHT 4 +#define VNC_FEATURE_ZLIB 5 + +#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE) +#define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE) +#define VNC_FEATURE_POINTER_TYPE_CHANGE_MASK (1 << VNC_FEATURE_POINTER_TYPE_CHANGE) +#define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI) +#define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT) +#define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB) + +#endif /* __VNCTIGHT_H */ -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/7] Use VNC protocol defines 2009-01-30 14:38 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf 2009-02-02 15:58 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori 1 sibling, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel Now that we have nice defines for all sorts of constants, let's use them! This patch also takes the "feature variables", currently called has_* into a single feature int. This way adding new features is a lot easier and doesn't clutter the VncState struct. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 97 +++++++++++++++++++++++++++++++++------------------------------- 1 files changed, 50 insertions(+), 47 deletions(-) diff --git a/vnc.c b/vnc.c index e88f38f..6b885d3 100644 --- a/vnc.c +++ b/vnc.c @@ -98,10 +98,7 @@ struct VncState int need_update; uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS]; char *old_data; - int has_resize; - int has_hextile; - int has_pointer_type_change; - int has_WMVi; + uint32_t features; int absolute; int last_x; int last_y; @@ -164,6 +161,10 @@ void do_info_vnc(void) } } +static inline uint32_t vnc_has_feature(VncState *vs, int feature) { + return (vs->features & (1 << feature)); +} + /* TODO 1) Get the queue working for IO. 2) there is some weirdness when using the -S option (the screen is grey @@ -277,11 +278,12 @@ static void vnc_dpy_resize(DisplayState *ds) ds_get_height(ds) != vs->serverds.height; vs->serverds = *(ds->surface); if (size_changed) { - if (vs->csock != -1 && vs->has_resize) { + if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) { 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_get_width(ds), ds_get_height(ds), -223); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), + VNC_ENCODING_DESKTOPRESIZE); vnc_flush(vs); } } @@ -378,7 +380,7 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h int i; uint8_t *row; - vnc_framebuffer_update(vs, x, y, w, h, 0); + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); for (i = 0; i < h; i++) { @@ -429,7 +431,7 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i int has_fg, has_bg; uint8_t *last_fg, *last_bg; - vnc_framebuffer_update(vs, x, y, w, h, 5); + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); @@ -448,7 +450,7 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - if (vs->has_hextile) + if (vnc_has_feature(vs, VNC_FEATURE_HEXTILE)) send_framebuffer_update_hextile(vs, x, y, w, h); else send_framebuffer_update_raw(vs, x, y, w, h); @@ -463,7 +465,7 @@ static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_ vnc_write_u8(vs, 0); /* msg id */ vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); /* number of rects */ - vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1); + vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT); vnc_write_u16(vs, src_x); vnc_write_u16(vs, src_y); vnc_flush(vs); @@ -919,12 +921,13 @@ static void client_cut_text(VncState *vs, size_t len, uint8_t *text) static void check_pointer_type_change(VncState *vs, int absolute) { - if (vs->has_pointer_type_change && vs->absolute != absolute) { + if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) { vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); vnc_framebuffer_update(vs, absolute, 0, - ds_get_width(vs->ds), ds_get_height(vs->ds), -257); + ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_POINTER_TYPE_CHANGE); vnc_flush(vs); } vs->absolute = absolute; @@ -950,7 +953,7 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y) kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1), y * 0x7FFF / (ds_get_height(vs->ds) - 1), dz, buttons); - } else if (vs->has_pointer_type_change) { + } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) { x -= 0x7FFF; y -= 0x7FFF; @@ -1140,7 +1143,8 @@ static void send_ext_key_event_ack(VncState *vs) vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); - vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -258); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_EXT_KEY_EVENT); vnc_flush(vs); } @@ -1149,50 +1153,50 @@ static void send_ext_audio_ack(VncState *vs) vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); - vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -259); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_AUDIO); vnc_flush(vs); } static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) { int i; + unsigned int enc = 0; - vs->has_hextile = 0; - vs->has_resize = 0; - vs->has_pointer_type_change = 0; - vs->has_WMVi = 0; + vs->features = 0; vs->absolute = -1; dcl->dpy_copy = NULL; for (i = n_encodings - 1; i >= 0; i--) { - switch (encodings[i]) { - case 0: /* Raw */ - vs->has_hextile = 0; - break; - case 1: /* CopyRect */ - dcl->dpy_copy = vnc_copy; - break; - case 5: /* Hextile */ - vs->has_hextile = 1; - break; - case -223: /* DesktopResize */ - vs->has_resize = 1; - break; - case -257: - vs->has_pointer_type_change = 1; - break; - case -258: + enc = encodings[i]; + switch (enc) { + case VNC_ENCODING_RAW: + break; + case VNC_ENCODING_COPYRECT: + dcl->dpy_copy = vnc_copy; + break; + case VNC_ENCODING_HEXTILE: + vs->features |= VNC_FEATURE_HEXTILE_MASK; + break; + case VNC_ENCODING_DESKTOPRESIZE: + vs->features |= VNC_FEATURE_RESIZE_MASK; + break; + case VNC_ENCODING_POINTER_TYPE_CHANGE: + vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK; + break; + case VNC_ENCODING_EXT_KEY_EVENT: send_ext_key_event_ack(vs); break; - case -259: + case VNC_ENCODING_AUDIO: send_ext_audio_ack(vs); break; - case 0x574D5669: - vs->has_WMVi = 1; + case VNC_ENCODING_WMVi: + vs->features |= VNC_FEATURE_WMVI_MASK; break; - default: - break; - } + default: + VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); + break; + } } check_pointer_type_change(vs, kbd_mouse_is_absolute()); @@ -1306,12 +1310,13 @@ static void vnc_colordepth(DisplayState *ds) { struct VncState *vs = ds->opaque; - if (vs->csock != -1 && vs->has_WMVi) { + if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_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_get_width(ds), ds_get_height(ds), 0x574D5669); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), + VNC_ENCODING_WMVi); pixel_format_message(vs); vnc_flush(vs); } else { @@ -2079,9 +2084,7 @@ static void vnc_connect(VncState *vs) vnc_read_when(vs, protocol_version, 12); memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds)); memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); - vs->has_resize = 0; - vs->has_hextile = 0; - vs->has_WMVi = 0; + vs->features = 0; dcl->dpy_copy = NULL; vnc_update_client(vs); reset_keys(vs); -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled 2009-01-30 14:38 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 4/7] Add some tight awareness to vnc.c Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel While running with debugging enabled, I found an #if testing for an undefined value, not defined(value). This patch fixes that. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/vnc.c b/vnc.c index 6b885d3..4b17f85 100644 --- a/vnc.c +++ b/vnc.c @@ -47,7 +47,7 @@ #ifdef _VNC_DEBUG #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) -#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2 +#if defined(CONFIG_VNC_TLS) && _VNC_DEBUG >= 2 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */ static void vnc_debug_gnutls_log(int level, const char* str) { VNC_DEBUG("%d %s", level, str); -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 4/7] Add some tight awareness to vnc.c 2009-01-30 14:38 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 5/7] Move buffer functions up Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel This patch enables the vnc server to understand fundamental tight extensions. It changes from a "Hextile or not" scheme when sending framebuffer updates to a "preferred encoding", namely the last one set. While this is not perfect, as actually a list of "preferred encodings" should be kept, it's good enough for now. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/vnc.c b/vnc.c index 4b17f85..31ea131 100644 --- a/vnc.c +++ b/vnc.c @@ -103,6 +103,10 @@ struct VncState int last_x; int last_y; + uint32_t vnc_encoding; + uint8_t tight_quality; + uint8_t tight_compression; + int major; int minor; @@ -450,10 +454,14 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - if (vnc_has_feature(vs, VNC_FEATURE_HEXTILE)) + switch(vs->vnc_encoding) { + case VNC_ENCODING_HEXTILE: send_framebuffer_update_hextile(vs, x, y, w, h); - else + break; + default: send_framebuffer_update_raw(vs, x, y, w, h); + break; + } } static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) @@ -1164,6 +1172,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) unsigned int enc = 0; vs->features = 0; + vs->vnc_encoding = 0; + vs->tight_compression = 9; + vs->tight_quality = 9; vs->absolute = -1; dcl->dpy_copy = NULL; @@ -1171,12 +1182,14 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) enc = encodings[i]; switch (enc) { case VNC_ENCODING_RAW: + vs->vnc_encoding = enc; break; case VNC_ENCODING_COPYRECT: dcl->dpy_copy = vnc_copy; break; case VNC_ENCODING_HEXTILE: vs->features |= VNC_FEATURE_HEXTILE_MASK; + vs->vnc_encoding = enc; break; case VNC_ENCODING_DESKTOPRESIZE: vs->features |= VNC_FEATURE_RESIZE_MASK; @@ -1193,6 +1206,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) case VNC_ENCODING_WMVi: vs->features |= VNC_FEATURE_WMVI_MASK; break; + case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9: + vs->tight_compression = (enc & 0x0F); + break; + case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9: + vs->tight_quality = (enc & 0x0F); + break; default: VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); break; -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 5/7] Move buffer functions up 2009-01-30 14:38 ` [Qemu-devel] [PATCH 4/7] Add some tight awareness to vnc.c Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 6/7] Move the framebuffer update package out Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel We will need to use buffer functions in code that will end up being below the current buffer functions. In order to not introduce any function stub defines, let's just move them up. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 66 ++++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 33 insertions(+), 33 deletions(-) diff --git a/vnc.c b/vnc.c index 31ea131..b3b4bfd 100644 --- a/vnc.c +++ b/vnc.c @@ -263,6 +263,39 @@ static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, vnc_write_s32(vs, encoding); } +static void buffer_reserve(Buffer *buffer, size_t len) +{ + if ((buffer->capacity - buffer->offset) < len) { + buffer->capacity += (len + 1024); + buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity); + if (buffer->buffer == NULL) { + fprintf(stderr, "vnc: out of memory\n"); + exit(1); + } + } +} + +static int buffer_empty(Buffer *buffer) +{ + return buffer->offset == 0; +} + +static uint8_t *buffer_end(Buffer *buffer) +{ + return buffer->buffer + buffer->offset; +} + +static void buffer_reset(Buffer *buffer) +{ + buffer->offset = 0; +} + +static void buffer_append(Buffer *buffer, const void *data, size_t len) +{ + memcpy(buffer->buffer + buffer->offset, data, len); + buffer->offset += len; +} + static void vnc_dpy_resize(DisplayState *ds) { int size_changed; @@ -598,39 +631,6 @@ static int vnc_listen_poll(void *opaque) return 0; } -static void buffer_reserve(Buffer *buffer, size_t len) -{ - if ((buffer->capacity - buffer->offset) < len) { - buffer->capacity += (len + 1024); - buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity); - if (buffer->buffer == NULL) { - fprintf(stderr, "vnc: out of memory\n"); - exit(1); - } - } -} - -static int buffer_empty(Buffer *buffer) -{ - return buffer->offset == 0; -} - -static uint8_t *buffer_end(Buffer *buffer) -{ - return buffer->buffer + buffer->offset; -} - -static void buffer_reset(Buffer *buffer) -{ - buffer->offset = 0; -} - -static void buffer_append(Buffer *buffer, const void *data, size_t len) -{ - memcpy(buffer->buffer + buffer->offset, data, len); - buffer->offset += len; -} - /* audio */ static void audio_capture_notify(void *opaque, audcnotification_e cmd) { -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 6/7] Move the framebuffer update package out 2009-01-30 14:38 ` [Qemu-devel] [PATCH 5/7] Move buffer functions up Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 7/7] Add zlib encoding support Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel Currently the send_framebuffer_update_raw and send_framebuffer_update_hextile respectively send a send_framebuffer_update packet themselves. We need to reuse send_framebuffer_update_raw for zlib encoding though, so let's move it out. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/vnc.c b/vnc.c index b3b4bfd..b91ecff 100644 --- a/vnc.c +++ b/vnc.c @@ -417,8 +417,6 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h int i; uint8_t *row; - vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); - row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); for (i = 0; i < h; i++) { vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds)); @@ -468,8 +466,6 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i int has_fg, has_bg; uint8_t *last_fg, *last_bg; - vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); - last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); has_fg = has_bg = 0; @@ -489,9 +485,11 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { switch(vs->vnc_encoding) { case VNC_ENCODING_HEXTILE: + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); send_framebuffer_update_hextile(vs, x, y, w, h); break; default: + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); send_framebuffer_update_raw(vs, x, y, w, h); break; } -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 7/7] Add zlib encoding support 2009-01-30 14:38 ` [Qemu-devel] [PATCH 6/7] Move the framebuffer update package out Alexander Graf @ 2009-01-30 14:38 ` Alexander Graf 0 siblings, 0 replies; 10+ messages in thread From: Alexander Graf @ 2009-01-30 14:38 UTC (permalink / raw) To: qemu-devel This patch adds zlib encoding support for VNC. It basically runs the raw traffic through zlib, providing a pretty good compression ratio. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 109 insertions(+), 0 deletions(-) diff --git a/vnc.c b/vnc.c index b91ecff..fa9195d 100644 --- a/vnc.c +++ b/vnc.c @@ -29,6 +29,7 @@ #include "qemu_socket.h" #include "qemu-timer.h" #include "audio/audio.h" +#include <zlib.h> #define VNC_REFRESH_INTERVAL (1000 / 30) @@ -144,6 +145,10 @@ struct VncState size_t read_handler_expect; /* input */ uint8_t modifiers_state[256]; + + Buffer zlib; + Buffer zlib_tmp; + z_stream zlib_stream[4]; }; static VncState *vnc_state; /* needed for info vnc */ @@ -481,9 +486,108 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i } +static void vnc_zlib_init(VncState *vs) +{ + int i; + for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++) + vs->zlib_stream[i].opaque = NULL; +} + +static void vnc_zlib_start(VncState *vs) +{ + buffer_reset(&vs->zlib); + + // make the output buffer be the zlib buffer, so we can compress it later + vs->zlib_tmp = vs->output; + vs->output = vs->zlib; +} + +static int vnc_zlib_stop(VncState *vs, int stream_id) +{ + z_streamp zstream = &vs->zlib_stream[stream_id]; + int previous_out; + + // switch back to normal output/zlib buffers + vs->zlib = vs->output; + vs->output = vs->zlib_tmp; + + // compress the zlib buffer + + // initialize the stream + // XXX need one stream per session + if (zstream->opaque != vs) { + int err; + + VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id); + VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs); + zstream->zalloc = Z_NULL; + zstream->zfree = Z_NULL; + + err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS, + MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + + if (err != Z_OK) { + fprintf(stderr, "VNC: error initializing zlib\n"); + return -1; + } + + zstream->opaque = vs; + } + + // XXX what to do if tight_compression changed in between? + + // reserve memory in output buffer + buffer_reserve(&vs->output, vs->zlib.offset + 64); + + // set pointers + zstream->next_in = vs->zlib.buffer; + zstream->avail_in = vs->zlib.offset; + zstream->next_out = vs->output.buffer + vs->output.offset; + zstream->avail_out = vs->output.capacity - vs->output.offset; + zstream->data_type = Z_BINARY; + previous_out = zstream->total_out; + + // start encoding + if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) { + fprintf(stderr, "VNC: error during zlib compression\n"); + return -1; + } + + vs->output.offset = vs->output.capacity - zstream->avail_out; + return zstream->total_out - previous_out; +} + +static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h) +{ + int old_offset, new_offset, bytes_written; + + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB); + + // remember where we put in the follow-up size + old_offset = vs->output.offset; + vnc_write_s32(vs, 0); + + // compress the stream + vnc_zlib_start(vs); + send_framebuffer_update_raw(vs, x, y, w, h); + bytes_written = vnc_zlib_stop(vs, 0); + + if (bytes_written == -1) + return; + + // hack in the size + new_offset = vs->output.offset; + vs->output.offset = old_offset; + vnc_write_u32(vs, bytes_written); + vs->output.offset = new_offset; +} + static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { switch(vs->vnc_encoding) { + case VNC_ENCODING_ZLIB: + send_framebuffer_update_zlib(vs, x, y, w, h); + break; case VNC_ENCODING_HEXTILE: vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); send_framebuffer_update_hextile(vs, x, y, w, h); @@ -1169,6 +1273,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) int i; unsigned int enc = 0; + vnc_zlib_init(vs); vs->features = 0; vs->vnc_encoding = 0; vs->tight_compression = 9; @@ -1189,6 +1294,10 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->features |= VNC_FEATURE_HEXTILE_MASK; vs->vnc_encoding = enc; break; + case VNC_ENCODING_ZLIB: + vs->features |= VNC_FEATURE_ZLIB_MASK; + vs->vnc_encoding = enc; + break; case VNC_ENCODING_DESKTOPRESIZE: vs->features |= VNC_FEATURE_RESIZE_MASK; break; -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h 2009-01-30 14:38 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf @ 2009-02-02 15:58 ` Anthony Liguori 1 sibling, 0 replies; 10+ messages in thread From: Anthony Liguori @ 2009-02-02 15:58 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > The VNC protocol contains quite some constants, some of which are > currently hardcoded in the vnc.c code. This is not exactly pretty. > > Let's move all those constants out to vnc.h, so they are clearly > separated. While at it, I also included other defines that will be > used later in this patch series. > > Signed-off-by: Alexander Graf <agraf@suse.de> > Applied all. Thanks. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 0/7] Add tight support to VNC @ 2009-01-29 11:24 Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel The current tight implementation only supports raw and hextile encodings. While this is perfectly fine for local networks, it would be good to support tight encodings for remote access as well. This patchset implements fundamental tight protocol and tight encoding support, implementing jpeg compression. Using this set as a basis, other tight encodings can be easily added as well, like ZRLE or ZLIBHEX. I will work on that, but this is intrusive enough for one set already ;-). Alexander Graf (7): Split VNC defines to vnc.h Use VNC protocol defines Fix invalid #if in vnc.c when debugging is enabled Make vnc buffer big-chunk aware Split vnc authentication code Add tight protocol awareness to vnc.c Add tight encoding (jpeg) to vnc.c Makefile.target | 4 + configure | 25 +++ vnc.c | 500 ++++++++++++++++++++++++++++++++++++++++++------------- vnc.h | 130 ++++++++++++++ 4 files changed, 539 insertions(+), 120 deletions(-) create mode 100644 vnc.h ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h 2009-01-29 11:24 [Qemu-devel] [PATCH 0/7] Add tight support to VNC Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel The VNC protocol contains quite some constants, some of which are currently hardcoded in the vnc.c code. This is not exactly pretty. Let's move all those constants out to vnc.h, so they are clearly separated. While at it, I also included other defines that will be used later in this patch series. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 36 +----------------- vnc.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 35 deletions(-) create mode 100644 vnc.h diff --git a/vnc.c b/vnc.c index 2b3a6eb..e88f38f 100644 --- a/vnc.c +++ b/vnc.c @@ -32,6 +32,7 @@ #define VNC_REFRESH_INTERVAL (1000 / 30) +#include "vnc.h" #include "vnc_keysym.h" #include "keymaps.c" #include "d3des.h" @@ -88,41 +89,6 @@ typedef void VncSendHextileTile(VncState *vs, #define VNC_AUTH_CHALLENGE_SIZE 16 -enum { - VNC_AUTH_INVALID = 0, - VNC_AUTH_NONE = 1, - VNC_AUTH_VNC = 2, - VNC_AUTH_RA2 = 5, - VNC_AUTH_RA2NE = 6, - VNC_AUTH_TIGHT = 16, - VNC_AUTH_ULTRA = 17, - VNC_AUTH_TLS = 18, - VNC_AUTH_VENCRYPT = 19 -}; - -#ifdef CONFIG_VNC_TLS -enum { - VNC_WIREMODE_CLEAR, - VNC_WIREMODE_TLS, -}; - -enum { - VNC_AUTH_VENCRYPT_PLAIN = 256, - VNC_AUTH_VENCRYPT_TLSNONE = 257, - VNC_AUTH_VENCRYPT_TLSVNC = 258, - VNC_AUTH_VENCRYPT_TLSPLAIN = 259, - VNC_AUTH_VENCRYPT_X509NONE = 260, - VNC_AUTH_VENCRYPT_X509VNC = 261, - VNC_AUTH_VENCRYPT_X509PLAIN = 262, -}; - -#define X509_CA_CERT_FILE "ca-cert.pem" -#define X509_CA_CRL_FILE "ca-crl.pem" -#define X509_SERVER_KEY_FILE "server-key.pem" -#define X509_SERVER_CERT_FILE "server-cert.pem" - -#endif /* CONFIG_VNC_TLS */ - struct VncState { QEMUTimer *timer; diff --git a/vnc.h b/vnc.h new file mode 100644 index 0000000..ae69bc3 --- /dev/null +++ b/vnc.h @@ -0,0 +1,130 @@ +#ifndef __VNCTIGHT_H +#define __VNCTIGHT_H + +/***************************************************************************** + * + * Authentication modes + * + *****************************************************************************/ + +enum { + VNC_AUTH_INVALID = 0, + VNC_AUTH_NONE = 1, + VNC_AUTH_VNC = 2, + VNC_AUTH_RA2 = 5, + VNC_AUTH_RA2NE = 6, + VNC_AUTH_TIGHT = 16, + VNC_AUTH_ULTRA = 17, + VNC_AUTH_TLS = 18, + VNC_AUTH_VENCRYPT = 19 +}; + +#define VNC_AUTH_NONE_SIG "NOAUTH__" +#define VNC_AUTH_VNC_SIG "VNCAUTH_" + +#ifdef CONFIG_VNC_TLS +enum { + VNC_WIREMODE_CLEAR, + VNC_WIREMODE_TLS, +}; + +enum { + VNC_AUTH_VENCRYPT_PLAIN = 256, + VNC_AUTH_VENCRYPT_TLSNONE = 257, + VNC_AUTH_VENCRYPT_TLSVNC = 258, + VNC_AUTH_VENCRYPT_TLSPLAIN = 259, + VNC_AUTH_VENCRYPT_X509NONE = 260, + VNC_AUTH_VENCRYPT_X509VNC = 261, + VNC_AUTH_VENCRYPT_X509PLAIN = 262, +}; + +#define X509_CA_CERT_FILE "ca-cert.pem" +#define X509_CA_CRL_FILE "ca-crl.pem" +#define X509_SERVER_KEY_FILE "server-key.pem" +#define X509_SERVER_CERT_FILE "server-cert.pem" + +#endif /* CONFIG_VNC_TLS */ + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define VNC_ENCODING_RAW 0x00000000 +#define VNC_ENCODING_COPYRECT 0x00000001 +#define VNC_ENCODING_RRE 0x00000002 +#define VNC_ENCODING_CORRE 0x00000004 +#define VNC_ENCODING_HEXTILE 0x00000005 +#define VNC_ENCODING_ZLIB 0x00000006 +#define VNC_ENCODING_TIGHT 0x00000007 +#define VNC_ENCODING_ZLIBHEX 0x00000008 +#define VNC_ENCODING_ZRLE 0x00000010 +#define VNC_ENCODING_COMPRESSLEVEL0 0xFFFFFF00 +#define VNC_ENCODING_QUALITYLEVEL0 0xFFFFFFE0 +#define VNC_ENCODING_XCURSOR 0xFFFFFF10 +#define VNC_ENCODING_RICH_CURSOR 0xFFFFFF11 +#define VNC_ENCODING_POINTER_POS 0xFFFFFF18 +#define VNC_ENCODING_LASTRECT 0xFFFFFF20 +#define VNC_ENCODING_DESKTOPRESIZE 0xFFFFFF21 +#define VNC_ENCODING_POINTER_TYPE_CHANGE 0XFFFFFEFF +#define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE +#define VNC_ENCODING_AUDIO 0XFFFFFEFD +#define VNC_ENCODING_WMVi 0x574D5669 + +/* signatures for basic encoding types */ +#define VNC_ENCODING_RAW_SIG "RAW_____" +#define VNC_ENCODING_COPYRECT_SIG "COPYRECT" +#define VNC_ENCODING_RRE_SIG "RRE_____" +#define VNC_ENCODING_CORRE_SIG "CORRE___" +#define VNC_ENCODING_HEXTILE_SIG "HEXTILE_" +#define VNC_ENCODING_ZLIB_SIG "ZLIB____" +#define VNC_ENCODING_TIGHT_SIG "TIGHT___" +#define VNC_ENCODING_ZLIBHEX_SIG "ZLIBHEX_" +#define VNC_ENCODING_ZRLE_SIG "ZRLE____" +#define VNC_ENCODING_COMPRESSLEVEL0_SIG "COMPRLVL" +#define VNC_ENCODING_QUALITYLEVEL0_SIG "JPEGQLVL" + +/***************************************************************************** + * + * Other tight constants + * + *****************************************************************************/ + +/* + * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC. + */ + +#define VNC_VENDOR_STANDARD "STDV" +#define VNC_VENDOR_TRIDIA "TRDV" +#define VNC_VENDOR_TIGHT "TGHT" + +#define VNC_TIGHT_CCB_RESET_MASK (0x0f) +#define VNC_TIGHT_CCB_TYPE_MASK (0x0f << 4) +#define VNC_TIGHT_CCB_TYPE_FILL (0x08 << 4) +#define VNC_TIGHT_CCB_TYPE_JPEG (0x09 << 4) +#define VNC_TIGHT_CCB_BASIC_MAX (0x07 << 4) +#define VNC_TIGHT_CCB_BASIC_ZLIB (0x03 << 4) +#define VNC_TIGHT_CCB_BASIC_FILTER (0x04 << 4) + +/***************************************************************************** + * + * Features + * + *****************************************************************************/ + +#define VNC_FEATURE_RESIZE 0 +#define VNC_FEATURE_HEXTILE 1 +#define VNC_FEATURE_POINTER_TYPE_CHANGE 2 +#define VNC_FEATURE_WMVI 3 +#define VNC_FEATURE_TIGHT 4 +#define VNC_FEATURE_TIGHT_PROTOCOL 5 + +#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE) +#define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE) +#define VNC_FEATURE_POINTER_TYPE_CHANGE_MASK (1 << VNC_FEATURE_POINTER_TYPE_CHANGE) +#define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI) +#define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT) +#define VNC_FEATURE_TIGHT_PROTOCOL_MASK (1 << VNC_FEATURE_TIGHT_PROTOCOL) + +#endif /* __VNCTIGHT_H */ -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/7] Use VNC protocol defines 2009-01-29 11:24 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 0 siblings, 0 replies; 10+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel Now that we have nice defines for all sorts of constants, let's use them! This patch also takes the "feature variables", currently called has_* into a single feature int. This way adding new features is a lot easier and doesn't clutter the VncState struct. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 97 +++++++++++++++++++++++++++++++++------------------------------- 1 files changed, 50 insertions(+), 47 deletions(-) diff --git a/vnc.c b/vnc.c index e88f38f..6b885d3 100644 --- a/vnc.c +++ b/vnc.c @@ -98,10 +98,7 @@ struct VncState int need_update; uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS]; char *old_data; - int has_resize; - int has_hextile; - int has_pointer_type_change; - int has_WMVi; + uint32_t features; int absolute; int last_x; int last_y; @@ -164,6 +161,10 @@ void do_info_vnc(void) } } +static inline uint32_t vnc_has_feature(VncState *vs, int feature) { + return (vs->features & (1 << feature)); +} + /* TODO 1) Get the queue working for IO. 2) there is some weirdness when using the -S option (the screen is grey @@ -277,11 +278,12 @@ static void vnc_dpy_resize(DisplayState *ds) ds_get_height(ds) != vs->serverds.height; vs->serverds = *(ds->surface); if (size_changed) { - if (vs->csock != -1 && vs->has_resize) { + if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) { 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_get_width(ds), ds_get_height(ds), -223); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), + VNC_ENCODING_DESKTOPRESIZE); vnc_flush(vs); } } @@ -378,7 +380,7 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h int i; uint8_t *row; - vnc_framebuffer_update(vs, x, y, w, h, 0); + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); for (i = 0; i < h; i++) { @@ -429,7 +431,7 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i int has_fg, has_bg; uint8_t *last_fg, *last_bg; - vnc_framebuffer_update(vs, x, y, w, h, 5); + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel); @@ -448,7 +450,7 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - if (vs->has_hextile) + if (vnc_has_feature(vs, VNC_FEATURE_HEXTILE)) send_framebuffer_update_hextile(vs, x, y, w, h); else send_framebuffer_update_raw(vs, x, y, w, h); @@ -463,7 +465,7 @@ static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_ vnc_write_u8(vs, 0); /* msg id */ vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); /* number of rects */ - vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1); + vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT); vnc_write_u16(vs, src_x); vnc_write_u16(vs, src_y); vnc_flush(vs); @@ -919,12 +921,13 @@ static void client_cut_text(VncState *vs, size_t len, uint8_t *text) static void check_pointer_type_change(VncState *vs, int absolute) { - if (vs->has_pointer_type_change && vs->absolute != absolute) { + if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) { vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); vnc_framebuffer_update(vs, absolute, 0, - ds_get_width(vs->ds), ds_get_height(vs->ds), -257); + ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_POINTER_TYPE_CHANGE); vnc_flush(vs); } vs->absolute = absolute; @@ -950,7 +953,7 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y) kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1), y * 0x7FFF / (ds_get_height(vs->ds) - 1), dz, buttons); - } else if (vs->has_pointer_type_change) { + } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) { x -= 0x7FFF; y -= 0x7FFF; @@ -1140,7 +1143,8 @@ static void send_ext_key_event_ack(VncState *vs) vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); - vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -258); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_EXT_KEY_EVENT); vnc_flush(vs); } @@ -1149,50 +1153,50 @@ static void send_ext_audio_ack(VncState *vs) vnc_write_u8(vs, 0); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); - vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -259); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), + VNC_ENCODING_AUDIO); vnc_flush(vs); } static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) { int i; + unsigned int enc = 0; - vs->has_hextile = 0; - vs->has_resize = 0; - vs->has_pointer_type_change = 0; - vs->has_WMVi = 0; + vs->features = 0; vs->absolute = -1; dcl->dpy_copy = NULL; for (i = n_encodings - 1; i >= 0; i--) { - switch (encodings[i]) { - case 0: /* Raw */ - vs->has_hextile = 0; - break; - case 1: /* CopyRect */ - dcl->dpy_copy = vnc_copy; - break; - case 5: /* Hextile */ - vs->has_hextile = 1; - break; - case -223: /* DesktopResize */ - vs->has_resize = 1; - break; - case -257: - vs->has_pointer_type_change = 1; - break; - case -258: + enc = encodings[i]; + switch (enc) { + case VNC_ENCODING_RAW: + break; + case VNC_ENCODING_COPYRECT: + dcl->dpy_copy = vnc_copy; + break; + case VNC_ENCODING_HEXTILE: + vs->features |= VNC_FEATURE_HEXTILE_MASK; + break; + case VNC_ENCODING_DESKTOPRESIZE: + vs->features |= VNC_FEATURE_RESIZE_MASK; + break; + case VNC_ENCODING_POINTER_TYPE_CHANGE: + vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK; + break; + case VNC_ENCODING_EXT_KEY_EVENT: send_ext_key_event_ack(vs); break; - case -259: + case VNC_ENCODING_AUDIO: send_ext_audio_ack(vs); break; - case 0x574D5669: - vs->has_WMVi = 1; + case VNC_ENCODING_WMVi: + vs->features |= VNC_FEATURE_WMVI_MASK; break; - default: - break; - } + default: + printf("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); + break; + } } check_pointer_type_change(vs, kbd_mouse_is_absolute()); @@ -1306,12 +1310,13 @@ static void vnc_colordepth(DisplayState *ds) { struct VncState *vs = ds->opaque; - if (vs->csock != -1 && vs->has_WMVi) { + if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_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_get_width(ds), ds_get_height(ds), 0x574D5669); + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), + VNC_ENCODING_WMVi); pixel_format_message(vs); vnc_flush(vs); } else { @@ -2079,9 +2084,7 @@ static void vnc_connect(VncState *vs) vnc_read_when(vs, protocol_version, 12); memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds)); memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); - vs->has_resize = 0; - vs->has_hextile = 0; - vs->has_WMVi = 0; + vs->features = 0; dcl->dpy_copy = NULL; vnc_update_client(vs); reset_keys(vs); -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-02-02 15:59 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-01-30 14:38 [Qemu-devel] [PATCH 0/7] Add zlib support to VNC server Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 4/7] Add some tight awareness to vnc.c Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 5/7] Move buffer functions up Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 6/7] Move the framebuffer update package out Alexander Graf 2009-01-30 14:38 ` [Qemu-devel] [PATCH 7/7] Add zlib encoding support Alexander Graf 2009-02-02 15:58 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori -- strict thread matches above, loose matches on Subject: below -- 2009-01-29 11:24 [Qemu-devel] [PATCH 0/7] Add tight support to VNC Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 1/7] Split VNC defines to vnc.h Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).