* [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; 19+ 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] 19+ 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 2009-01-29 15:22 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori 0 siblings, 2 replies; 19+ 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] 19+ 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 2009-01-29 11:24 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf 2009-01-29 15:22 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori 1 sibling, 1 reply; 19+ 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] 19+ messages in thread
* [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled 2009-01-29 11:24 ` [Qemu-devel] [PATCH 2/7] Use VNC protocol defines Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 4/7] Make vnc buffer big-chunk aware Alexander Graf 0 siblings, 1 reply; 19+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 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] 19+ messages in thread
* [Qemu-devel] [PATCH 4/7] Make vnc buffer big-chunk aware 2009-01-29 11:24 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 5/7] Split vnc authentication code Alexander Graf 2009-01-29 15:11 ` [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware Anthony Liguori 0 siblings, 2 replies; 19+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel Currently writing to buffers is protected by buffer_reserve. Unfortunately, is reserves at most 1024 bytes more than we currently have, so if we want to write a 2048 bytes chunk, we overwrite random memory. This patch addresses this in a pretty dumb but easy way. 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 4b17f85..d0d9580 100644 --- a/vnc.c +++ b/vnc.c @@ -592,7 +592,7 @@ static int vnc_listen_poll(void *opaque) static void buffer_reserve(Buffer *buffer, size_t len) { - if ((buffer->capacity - buffer->offset) < len) { + while ((buffer->capacity - buffer->offset) < len) { buffer->capacity += (len + 1024); buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity); if (buffer->buffer == NULL) { -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 5/7] Split vnc authentication code 2009-01-29 11:24 ` [Qemu-devel] [PATCH 4/7] Make vnc buffer big-chunk aware Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 6/7] Add tight protocol awareness to vnc.c Alexander Graf 2009-01-29 15:11 ` [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware Anthony Liguori 1 sibling, 1 reply; 19+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel This patch splits the authentication code, mostly for readability reasons. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 67 ++++++++++++++++++++++++++++++++++------------------------------ 1 files changed, 36 insertions(+), 31 deletions(-) diff --git a/vnc.c b/vnc.c index d0d9580..b4b0843 100644 --- a/vnc.c +++ b/vnc.c @@ -180,6 +180,7 @@ static void vnc_write_u8(VncState *vs, uint8_t value); static void vnc_flush(VncState *vs); static void vnc_update_client(void *opaque); static void vnc_client_read(void *opaque); +static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len); static void vnc_colordepth(DisplayState *ds); @@ -1555,6 +1556,39 @@ static int start_auth_vnc(VncState *vs) return 0; } +static int vnc_start_auth(VncState *vs, int auth) +{ + switch (auth) { + case VNC_AUTH_NONE: + VNC_DEBUG("Accept auth none\n"); + if (vs->minor >= 8) { + vnc_write_u32(vs, 0); /* Accept auth completion */ + vnc_flush(vs); + } + vnc_read_when(vs, protocol_client_init, 1); + break; + case VNC_AUTH_VNC: + VNC_DEBUG("Start VNC auth\n"); + return start_auth_vnc(vs); +#ifdef CONFIG_VNC_TLS + case VNC_AUTH_VENCRYPT: + VNC_DEBUG("Accept VeNCrypt auth\n");; + return start_auth_vencrypt(vs); +#endif /* CONFIG_VNC_TLS */ + default: /* Should not be possible, but just in case */ + VNC_DEBUG("Reject auth %d unknown\n", auth); + vnc_write_u8(vs, 1); + if (vs->minor >= 8) { + static const char err[] = "Authentication failed"; + vnc_write_u32(vs, sizeof(err)); + vnc_write(vs, err, sizeof(err)); + } + vnc_client_error(vs); + } + + return 0; +} + #ifdef CONFIG_VNC_TLS #define DH_BITS 1024 @@ -1979,37 +2013,8 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) } vnc_client_error(vs); } else { /* Accept requested auth */ - VNC_DEBUG("Client requested auth %d\n", (int)data[0]); - switch (vs->auth) { - case VNC_AUTH_NONE: - VNC_DEBUG("Accept auth none\n"); - if (vs->minor >= 8) { - vnc_write_u32(vs, 0); /* Accept auth completion */ - vnc_flush(vs); - } - vnc_read_when(vs, protocol_client_init, 1); - break; - - case VNC_AUTH_VNC: - VNC_DEBUG("Start VNC auth\n"); - return start_auth_vnc(vs); - -#ifdef CONFIG_VNC_TLS - case VNC_AUTH_VENCRYPT: - VNC_DEBUG("Accept VeNCrypt auth\n");; - return start_auth_vencrypt(vs); -#endif /* CONFIG_VNC_TLS */ - - default: /* Should not be possible, but just in case */ - VNC_DEBUG("Reject auth %d\n", vs->auth); - vnc_write_u8(vs, 1); - if (vs->minor >= 8) { - static const char err[] = "Authentication failed"; - vnc_write_u32(vs, sizeof(err)); - vnc_write(vs, err, sizeof(err)); - } - vnc_client_error(vs); - } + VNC_DEBUG("Client requested auth %d\n", auth); + return vnc_start_auth(vs, data[0]); } return 0; } -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 6/7] Add tight protocol awareness to vnc.c 2009-01-29 11:24 ` [Qemu-devel] [PATCH 5/7] Split vnc authentication code Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 7/7] Add tight encoding (jpeg) " Alexander Graf 2009-01-29 15:13 ` [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness " Anthony Liguori 0 siblings, 2 replies; 19+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel This patch enables the vnc server to understand the tight protocol. Basically, negotiation if tight is existing happens through the authentication code. If a special authentication called VNC_AUTH_TIGHT is used, the real authentication is stacked afterwards and tight extensions exist. In order to make it easier to add different encodings later, this patch also adds "preferred encoding" awareness, only saves the last preferred encoding though. This way the client can choose which protocol it wants to use the most. Signed-off-by: Alexander Graf <agraf@suse.de> --- vnc.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 115 insertions(+), 7 deletions(-) diff --git a/vnc.c b/vnc.c index b4b0843..86e2a1b 100644 --- a/vnc.c +++ b/vnc.c @@ -103,6 +103,10 @@ struct VncState int last_x; int last_y; + int vnc_encoding; + unsigned int tight_quality; + unsigned int tight_compression; + int major; int minor; @@ -451,10 +455,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) @@ -1165,19 +1173,38 @@ 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=0; + vs->tight_quality=9; vs->absolute = -1; dcl->dpy_copy = NULL; for (i = n_encodings - 1; i >= 0; i--) { enc = encodings[i]; switch (enc) { + case VNC_ENCODING_RRE: + case VNC_ENCODING_CORRE: + case VNC_ENCODING_ZLIB: + case VNC_ENCODING_ZLIBHEX: + case VNC_ENCODING_ZRLE: + case VNC_ENCODING_LASTRECT: + case VNC_ENCODING_POINTER_POS: + case VNC_ENCODING_RICH_CURSOR: + case VNC_ENCODING_XCURSOR: + /* Ingore - at least for now... */ + break; 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_TIGHT: + vs->features |= VNC_FEATURE_TIGHT_MASK; break; case VNC_ENCODING_DESKTOPRESIZE: vs->features |= VNC_FEATURE_RESIZE_MASK; @@ -1194,6 +1221,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: printf("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); break; @@ -1461,6 +1494,36 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) return 0; } +static void write_tight_capability(VncState *vs, int encoding, + const char *signature, const char *vendor) +{ + vnc_write_u32(vs, encoding); + vnc_write(vs, vendor, 4); + vnc_write(vs, signature, 8); +} + +static void write_tight_interaction_capabilities(VncState *vs) +{ + VNC_DEBUG("Sending Tight capabilities...\n"); + vnc_write_u16(vs, 0); /* nServerMessageTypes */ + vnc_write_u16(vs, 0); /* nClientMessageTypes */ + vnc_write_u16(vs, 5); /* nEncodingTypes */ + vnc_write_u16(vs, 0); /* pad */ + write_tight_capability(vs, VNC_ENCODING_TIGHT, VNC_ENCODING_TIGHT_SIG, + VNC_VENDOR_TIGHT); + write_tight_capability(vs, VNC_ENCODING_RAW, VNC_ENCODING_RAW_SIG, + VNC_VENDOR_STANDARD); + write_tight_capability(vs, VNC_ENCODING_HEXTILE, VNC_ENCODING_HEXTILE_SIG, + VNC_VENDOR_STANDARD); + write_tight_capability(vs, VNC_ENCODING_COMPRESSLEVEL0, + VNC_ENCODING_COMPRESSLEVEL0_SIG, VNC_VENDOR_TIGHT); + write_tight_capability(vs, VNC_ENCODING_QUALITYLEVEL0, + VNC_ENCODING_QUALITYLEVEL0_SIG, VNC_VENDOR_TIGHT); + + vnc_flush(vs); +} + + static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) { char buf[1024]; @@ -1480,6 +1543,9 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) vnc_write(vs, buf, size); vnc_flush(vs); + if(vnc_has_feature(vs, VNC_FEATURE_TIGHT_PROTOCOL)) + write_tight_interaction_capabilities(vs); + vnc_read_when(vs, protocol_client_msg, 1); return 0; @@ -1556,6 +1622,32 @@ static int start_auth_vnc(VncState *vs) return 0; } +static int start_auth_tight(VncState *vs) +{ + vnc_write_u32(vs, 0); /* no tunnel types */ + vnc_write_u32(vs, 1); /* num auth types */ + + switch(vs->auth) { + case VNC_AUTH_NONE: + write_tight_capability(vs, VNC_AUTH_NONE, VNC_AUTH_NONE_SIG, + VNC_VENDOR_STANDARD); + break; + case VNC_AUTH_VNC: + write_tight_capability(vs, VNC_AUTH_VNC, VNC_AUTH_VNC_SIG, + VNC_VENDOR_STANDARD); + break; + default: + VNC_DEBUG("Unknown subset of tight auth: %d", vs->auth); + vnc_write_u32(vs, -1); + vnc_write(vs, "BAD_", 4); + vnc_write(vs, "UNKNOWN_", 8); + } + + vnc_flush(vs); + vnc_read_when(vs, protocol_client_auth, 4); + return 0; +} + static int vnc_start_auth(VncState *vs, int auth) { switch (auth) { @@ -1570,12 +1662,22 @@ static int vnc_start_auth(VncState *vs, int auth) case VNC_AUTH_VNC: VNC_DEBUG("Start VNC auth\n"); return start_auth_vnc(vs); + case VNC_AUTH_TIGHT: + /* If we know we're on tight here, we ran into recursion */ + if (vnc_has_feature(vs, VNC_FEATURE_TIGHT_PROTOCOL)) { + VNC_DEBUG("Danger! Server sent us tight auth request twice!\n"); + goto tight_recursion; + } + vs->features |= VNC_FEATURE_TIGHT_PROTOCOL_MASK; + VNC_DEBUG("Start VNC tight auth\n"); + return start_auth_tight(vs); #ifdef CONFIG_VNC_TLS case VNC_AUTH_VENCRYPT: VNC_DEBUG("Accept VeNCrypt auth\n");; return start_auth_vencrypt(vs); #endif /* CONFIG_VNC_TLS */ default: /* Should not be possible, but just in case */ + tight_recursion: VNC_DEBUG("Reject auth %d unknown\n", auth); vnc_write_u8(vs, 1); if (vs->minor >= 8) { @@ -2001,10 +2103,15 @@ static int start_auth_vencrypt(VncState *vs) static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) { + int auth = data[0]; + + if (len == 4) + auth = read_s32(data, 0); /* We only advertise 1 auth scheme at a time, so client * must pick the one we sent. Verify this */ - if (data[0] != vs->auth) { /* Reject auth */ - VNC_DEBUG("Reject auth %d\n", (int)data[0]); + if ((auth != vs->auth) && + (auth != VNC_AUTH_TIGHT)) { /* Reject auth */ + VNC_DEBUG("Reject auth %d != %d\n", auth, vs->auth); vnc_write_u32(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; @@ -2014,7 +2121,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) vnc_client_error(vs); } else { /* Accept requested auth */ VNC_DEBUG("Client requested auth %d\n", auth); - return vnc_start_auth(vs, data[0]); + return vnc_start_auth(vs, auth); } return 0; } @@ -2068,9 +2175,10 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) vnc_client_error(vs); } } else { - VNC_DEBUG("Telling client we support auth %d\n", vs->auth); - vnc_write_u8(vs, 1); /* num auth */ + VNC_DEBUG("Telling client we support auth %d and tight\n", vs->auth); + vnc_write_u8(vs, 2); /* num auth */ vnc_write_u8(vs, vs->auth); + vnc_write_u8(vs, VNC_AUTH_TIGHT); vnc_read_when(vs, protocol_client_auth, 1); vnc_flush(vs); } -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] [PATCH 7/7] Add tight encoding (jpeg) to vnc.c 2009-01-29 11:24 ` [Qemu-devel] [PATCH 6/7] Add tight protocol awareness to vnc.c Alexander Graf @ 2009-01-29 11:24 ` Alexander Graf 2009-01-29 15:17 ` [Qemu-devel] " Anthony Liguori 2009-01-29 15:13 ` [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness " Anthony Liguori 1 sibling, 1 reply; 19+ messages in thread From: Alexander Graf @ 2009-01-29 11:24 UTC (permalink / raw) To: qemu-devel Because we can now speak the tight protocol, let's use it to transmit jpeg data to the client! This patch adds a really easy implementation of the jpeg tight encoding. Tight in general can do a lot more, but let's take small steps here and see how things perform. Signed-off-by: Alexander Graf <agraf@suse.de> --- Makefile.target | 4 + configure | 25 ++++++++ vnc.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 0 deletions(-) diff --git a/Makefile.target b/Makefile.target index a091ce9..7b54748 100644 --- a/Makefile.target +++ b/Makefile.target @@ -554,6 +554,10 @@ CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS) LIBS += $(CONFIG_VNC_TLS_LIBS) endif +ifdef CONFIG_VNC_JPEG +LIBS += $(CONFIG_VNC_JPEG_LIBS) +endif + ifdef CONFIG_BLUEZ LIBS += $(CONFIG_BLUEZ_LIBS) endif diff --git a/configure b/configure index c3fbbbe..44e2e0b 100755 --- a/configure +++ b/configure @@ -164,6 +164,7 @@ fmod_lib="" fmod_inc="" oss_lib="" vnc_tls="yes" +vnc_jpeg="yes" bsd="no" linux="no" solaris="no" @@ -387,6 +388,8 @@ for opt do ;; --disable-vnc-tls) vnc_tls="no" ;; + --disable-jpeg) vnc_jpeg="no" + ;; --disable-slirp) slirp="no" ;; --disable-vde) vde="no" @@ -544,6 +547,7 @@ echo " Available cards: $audio_possible_cards" echo " --enable-mixemu enable mixer emulation" echo " --disable-brlapi disable BrlAPI" echo " --disable-vnc-tls disable TLS encryption for VNC server" +echo " --disable-jpeg disable JPEG compression for VNC server" echo " --disable-curses disable curses output" echo " --disable-bluez disable bluez stack connectivity" echo " --disable-kvm disable KVM acceleration support" @@ -823,6 +827,21 @@ EOF fi ########################################## +# VNC JPEG detection +if test "$vnc_jpeg" = "yes" ; then +cat > $TMPC <<EOF +#include <jpeglib.h> +int main(void) { jpeg_compress_struct s; jpeg_create_compress(&s); return 0; } +EOF + vnc_jpeg_libs="-ljpeg" + if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC $vnc_jpeg_libs > /dev/null 2> /dev/null ; then + : + else + vnc_tls="no" + fi +fi + +########################################## # vde libraries probe if test "$vde" = "yes" ; then cat > $TMPC << EOF @@ -1130,6 +1149,7 @@ if test "$vnc_tls" = "yes" ; then echo " TLS CFLAGS $vnc_tls_cflags" echo " TLS LIBS $vnc_tls_libs" fi +echo "VNC JPEG support $vnc_jpeg" if test -n "$sparc_cpu"; then echo "Target Sparc Arch $sparc_cpu" fi @@ -1371,6 +1391,11 @@ if test "$vnc_tls" = "yes" ; then echo "CONFIG_VNC_TLS_LIBS=$vnc_tls_libs" >> $config_mak echo "#define CONFIG_VNC_TLS 1" >> $config_h fi +if test "$vnc_jpeg" = "yes" ; then + echo "CONFIG_VNC_JPEG=yes" >> $config_mak + echo "CONFIG_VNC_JPEG_LIBS=$vnc_jpeg_libs" >> $config_mak + echo "#define CONFIG_VNC_JPEG 1" >> $config_h +fi qemu_version=`head $source_path/VERSION` echo "VERSION=$qemu_version" >>$config_mak echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h diff --git a/vnc.c b/vnc.c index 86e2a1b..7a7ec94 100644 --- a/vnc.c +++ b/vnc.c @@ -37,6 +37,10 @@ #include "keymaps.c" #include "d3des.h" +#ifdef CONFIG_VNC_JPEG +#include <jpeglib.h> +#endif /* CONFIG_VNC_JPEG */ + #ifdef CONFIG_VNC_TLS #include <gnutls/gnutls.h> #include <gnutls/x509.h> @@ -144,6 +148,11 @@ struct VncState size_t read_handler_expect; /* input */ uint8_t modifiers_state[256]; + +#ifdef CONFIG_VNC_JPEG + Buffer jpeg_buffer; + struct jpeg_destination_mgr jpeg_dst_manager; +#endif /* CONFIG_VNC_JPEG */ }; static VncState *vnc_state; /* needed for info vnc */ @@ -185,6 +194,8 @@ static void vnc_flush(VncState *vs); static void vnc_update_client(void *opaque); static void vnc_client_read(void *opaque); static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len); +static void buffer_reserve(Buffer *buffer, size_t len); +static void buffer_reset(Buffer *buffer); static void vnc_colordepth(DisplayState *ds); @@ -453,9 +464,172 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i } +#ifdef CONFIG_VNC_JPEG +/* This is called once per encoding */ +static void jpeg_init_destination(j_compress_ptr cinfo) +{ + VncState *vs = (VncState*)cinfo->client_data; + Buffer *buffer = &vs->jpeg_buffer; + + cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset; + cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset); +} + +/* This is called when we ran out of buffer (shouldn't happen!) */ +static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo) +{ + VncState *vs = (VncState*)cinfo->client_data; + Buffer *buffer = &vs->jpeg_buffer; + + buffer->offset = buffer->capacity; + buffer_reserve(buffer, 2048); + jpeg_init_destination(cinfo); + return TRUE; +} + +/* This is called when we are done processing data */ +static void jpeg_term_destination(j_compress_ptr cinfo) +{ + VncState *vs = (VncState*)cinfo->client_data; + Buffer *buffer = &vs->jpeg_buffer; + + buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer; +} + + +static void vnc_send_compact_size(VncState *vs, int len) +{ + char buf[3]; + int lpc = 0; + int bytes = 0; + + /* Adapted from SendCompressedData() in Xvnc/programs/Xserver/hw/vnc/tight.c */ + buf[bytes++] = len & 0x7F; + if (len > 0x7F) { + buf[bytes-1] |= 0x80; + buf[bytes++] = len >> 7 & 0x7F; + if (len > 0x3FFF) { + buf[bytes-1] |= 0x80; + buf[bytes++] = len >> 14 & 0xFF; + } + } + + for(lpc = 0; lpc < bytes; lpc++) { + vnc_write_u8(vs, buf[lpc]); + } +} + +static int32_t read_s32(uint8_t *data, size_t offset); +static void jpeg_row2pixel(VncState *vs, char *in, char *out, int len) +{ + char *pi = in; + char *po = out; + int depth = vs->serverds.pf.bytes_per_pixel; + int i; + + for (i = 0; i < len; i++) { + uint32_t v; + uint8_t r, g, b; + switch (depth) { + case 1: + po[0] = pi[0]; + po[1] = pi[0]; + po[2] = pi[0]; + continue; + break; + case 2: + v = *((uint16_t*)pi); + break; + case 4: + v = *((uint32_t*)pi); + break; + } + r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) + << vs->clientds.pf.rbits) >> vs->serverds.pf.rbits); + g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) + << vs->clientds.pf.gbits) >> vs->serverds.pf.gbits); + b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) + << vs->clientds.pf.bbits) >> vs->serverds.pf.bbits); + + po[0] = r; + po[1] = g; + po[2] = b; + + pi += depth; + po += 3; // RGB + } +} + +static void send_framebuffer_update_tight(VncState *vs, int x, int y, int w, int h) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + uint8_t *row = ds_get_data(vs->ds) + + y * ds_get_linesize(vs->ds) + + x * ds_get_bytes_per_pixel(vs->ds); + int dy; + JSAMPROW row_pointer[1]; + + if(vnc_has_feature(vs, VNC_FEATURE_HEXTILE) && (w * h) < 300) { + /* Below a certain size its actually more efficient to send hextiles + * Take a rough stab in the dark at 300 for text-based displays */ + send_framebuffer_update_hextile(vs, x, y, w, h); + return; + } + + vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_TIGHT); + + // XXX For now let's be stupid and always send JPEG data. Tight can do a lot more! + + // Indicate its a Jpeg data stream + vnc_write_u8(vs, VNC_TIGHT_CCB_TYPE_JPEG); + + // Compress data + cinfo.client_data = vs; + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, (vs->tight_quality+1) * 10, TRUE); + + buffer_reserve(&vs->jpeg_buffer, 1024); + vs->jpeg_dst_manager.init_destination = jpeg_init_destination; + vs->jpeg_dst_manager.empty_output_buffer = jpeg_empty_output_buffer; + vs->jpeg_dst_manager.term_destination = jpeg_term_destination; + cinfo.dest = &vs->jpeg_dst_manager; + + jpeg_start_compress(&cinfo, TRUE); + + row_pointer[0] = qemu_malloc(3 * w); + for (dy = 0; dy < h; dy++) { + jpeg_row2pixel(vs, (char*)row, (char*)row_pointer[0], w); + jpeg_write_scanlines(&cinfo, row_pointer, 1); + row += ds_get_linesize(vs->ds); + } + qemu_free(row_pointer[0]); + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + VNC_DEBUG("JPEG: Sending %d bytes of jpeg data\n", (int)vs->jpeg_buffer.offset); + vnc_send_compact_size(vs, vs->jpeg_buffer.offset); + vnc_write(vs, vs->jpeg_buffer.buffer, vs->jpeg_buffer.offset); + buffer_reset(&vs->jpeg_buffer); +} +#endif /* CONFIG_VNC_JPEG */ + static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { switch(vs->vnc_encoding) { +#ifdef CONFIG_VNC_JPEG + case VNC_ENCODING_TIGHT: + send_framebuffer_update_tight(vs, x, y, w, h); + break; +#endif /* CONFIG_VNC_JPEG */ case VNC_ENCODING_HEXTILE: send_framebuffer_update_hextile(vs, x, y, w, h); break; @@ -1204,7 +1378,11 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->vnc_encoding = enc; break; case VNC_ENCODING_TIGHT: +#ifdef CONFIG_VNC_JPEG + buffer_reset(&vs->jpeg_buffer); +#endif vs->features |= VNC_FEATURE_TIGHT_MASK; + vs->vnc_encoding = enc; break; case VNC_ENCODING_DESKTOPRESIZE: vs->features |= VNC_FEATURE_RESIZE_MASK; -- 1.6.0.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 7/7] Add tight encoding (jpeg) to vnc.c 2009-01-29 11:24 ` [Qemu-devel] [PATCH 7/7] Add tight encoding (jpeg) " Alexander Graf @ 2009-01-29 15:17 ` Anthony Liguori 2009-01-29 15:23 ` Stefano Stabellini 0 siblings, 1 reply; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:17 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > Because we can now speak the tight protocol, let's use it to > transmit jpeg data to the client! > > This patch adds a really easy implementation of the jpeg tight > encoding. Tight in general can do a lot more, but let's take small > steps here and see how things perform. > > Signed-off-by: Alexander Graf <agraf@suse.de> > I don't really like the idea of taking this. Tight is supported by a lot of clients and is usually very high on the preferred list. However, most servers do not enable jpeg compression by default because it's lossy. If we implement Tight and then use jpeg by default, for most clients, the default is going to be lossy encoding. While lossy isn't so bad for high detailed images (like pictures), it's pretty terrible for simple, high contrast images (like windows in a desktop). TightVNC has some sophisticated heuristics for determining whether to use jpeg or not (when it's enabled). I think that sort of heuristic is a prerequisite for enabling tight's jpeg support. FWIW, Tight essentially does hextile encoding but adds zlib compression. That's probably a better place to start as it should outperform hextile while remaining lossless. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 7/7] Add tight encoding (jpeg) to vnc.c 2009-01-29 15:17 ` [Qemu-devel] " Anthony Liguori @ 2009-01-29 15:23 ` Stefano Stabellini 2009-01-29 15:47 ` Anthony Liguori 0 siblings, 1 reply; 19+ messages in thread From: Stefano Stabellini @ 2009-01-29 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Alexander Graf Anthony Liguori wrote: > If we implement Tight and then use jpeg by default, for most clients, > the default is going to be lossy encoding. While lossy isn't so bad for > high detailed images (like pictures), it's pretty terrible for simple, > high contrast images (like windows in a desktop). > > TightVNC has some sophisticated heuristics for determining whether to > use jpeg or not (when it's enabled). I think that sort of heuristic is > a prerequisite for enabling tight's jpeg support. > > FWIW, Tight essentially does hextile encoding but adds zlib > compression. That's probably a better place to start as it should > outperform hextile while remaining lossless. > Another thing to consider is that using jpeg compression is going to worsen qemu performances, so I think it should be used only when necessary, e.g. the network connection between client and server is bad. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 7/7] Add tight encoding (jpeg) to vnc.c 2009-01-29 15:23 ` Stefano Stabellini @ 2009-01-29 15:47 ` Anthony Liguori 0 siblings, 0 replies; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:47 UTC (permalink / raw) To: qemu-devel; +Cc: Alexander Graf Stefano Stabellini wrote: > Anthony Liguori wrote: > > >> If we implement Tight and then use jpeg by default, for most clients, >> the default is going to be lossy encoding. While lossy isn't so bad for >> high detailed images (like pictures), it's pretty terrible for simple, >> high contrast images (like windows in a desktop). >> >> TightVNC has some sophisticated heuristics for determining whether to >> use jpeg or not (when it's enabled). I think that sort of heuristic is >> a prerequisite for enabling tight's jpeg support. >> >> FWIW, Tight essentially does hextile encoding but adds zlib >> compression. That's probably a better place to start as it should >> outperform hextile while remaining lossless. >> >> > > Another thing to consider is that using jpeg compression is going to > worsen qemu performances, so I think it should be used only when > necessary, e.g. the network connection between client and server is bad. > Most clients I know do not enable JPEG by default. It requires a user to explicitly do so. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness to vnc.c 2009-01-29 11:24 ` [Qemu-devel] [PATCH 6/7] Add tight protocol awareness to vnc.c Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 7/7] Add tight encoding (jpeg) " Alexander Graf @ 2009-01-29 15:13 ` Anthony Liguori 2009-01-29 15:24 ` Alexander Graf 1 sibling, 1 reply; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:13 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > This patch enables the vnc server to understand the tight protocol. > > Basically, negotiation if tight is existing happens through the > authentication code. If a special authentication called VNC_AUTH_TIGHT > is used, the real authentication is stacked afterwards and tight > extensions exist. > This is wrong. The way the standard works is that the client advertises the Tight encoding via SetEncodingTypes. That's all that should be needed. The VNC_AUTH_TIGHT thing is a Tight extension that shouldn't be needed for implementing tight encoding. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness to vnc.c 2009-01-29 15:13 ` [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness " Anthony Liguori @ 2009-01-29 15:24 ` Alexander Graf 2009-01-29 15:43 ` Anthony Liguori 0 siblings, 1 reply; 19+ messages in thread From: Alexander Graf @ 2009-01-29 15:24 UTC (permalink / raw) To: Anthony Liguori; +Cc: qemu-devel Anthony Liguori wrote: > Alexander Graf wrote: >> This patch enables the vnc server to understand the tight protocol. >> >> Basically, negotiation if tight is existing happens through the >> authentication code. If a special authentication called VNC_AUTH_TIGHT >> is used, the real authentication is stacked afterwards and tight >> extensions exist. >> > > This is wrong. The way the standard works is that the client > advertises the Tight encoding via SetEncodingTypes. That's all that > should be needed. The VNC_AUTH_TIGHT thing is a Tight extension that > shouldn't be needed for implementing tight encoding. So how am I supposed to do the write_tight_interaction_capabilities() thing? I don't see how we advertise to the guest that we do support tight encoding if we can't tell it that we do. Alex > > Regards, > > Anthony Liguori ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness to vnc.c 2009-01-29 15:24 ` Alexander Graf @ 2009-01-29 15:43 ` Anthony Liguori 0 siblings, 0 replies; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:43 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > Anthony Liguori wrote: > >> Alexander Graf wrote: >> >>> This patch enables the vnc server to understand the tight protocol. >>> >>> Basically, negotiation if tight is existing happens through the >>> authentication code. If a special authentication called VNC_AUTH_TIGHT >>> is used, the real authentication is stacked afterwards and tight >>> extensions exist. >>> >>> >> This is wrong. The way the standard works is that the client >> advertises the Tight encoding via SetEncodingTypes. That's all that >> should be needed. The VNC_AUTH_TIGHT thing is a Tight extension that >> shouldn't be needed for implementing tight encoding. >> > > So how am I supposed to do the write_tight_interaction_capabilities() > thing? I don't see how we advertise to the guest that we do support > tight encoding if we can't tell it that we do. > The server doesn't advertise encodings to the client. The client advertises supported encodings to the server and the server chooses to use whatever one it would like to (that is supports). A server is supposed to ignore encodings that it doesn't know about. Regards, Anthony Liguori > Alex > >> Regards, >> >> Anthony Liguori >> > > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware 2009-01-29 11:24 ` [Qemu-devel] [PATCH 4/7] Make vnc buffer big-chunk aware Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 5/7] Split vnc authentication code Alexander Graf @ 2009-01-29 15:11 ` Anthony Liguori 2009-01-29 15:16 ` Alexander Graf 1 sibling, 1 reply; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:11 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > Currently writing to buffers is protected by buffer_reserve. > Unfortunately, is reserves at most 1024 bytes more than we currently > have, so if we want to write a 2048 bytes chunk, we overwrite > random memory. > Yikes! > This patch addresses this in a pretty dumb but easy way. > > 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 4b17f85..d0d9580 100644 > --- a/vnc.c > +++ b/vnc.c > @@ -592,7 +592,7 @@ static int vnc_listen_poll(void *opaque) > > static void buffer_reserve(Buffer *buffer, size_t len) > { > - if ((buffer->capacity - buffer->offset) < len) { > + while ((buffer->capacity - buffer->offset) < len) { > buffer->capacity += (len + 1024); > Okay, I no longer believe you. If we want to write len bytes, and we increase capacity by (len + 1024) bytes, then we should be fine. The reason it's len + 1024 vs just len is to avoid many qemu_realloc()s on many small reservations (like for adding u32s). Regards, Anthony Liguori > buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity); > if (buffer->buffer == NULL) { > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware 2009-01-29 15:11 ` [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware Anthony Liguori @ 2009-01-29 15:16 ` Alexander Graf 0 siblings, 0 replies; 19+ messages in thread From: Alexander Graf @ 2009-01-29 15:16 UTC (permalink / raw) To: Anthony Liguori; +Cc: qemu-devel@nongnu.org On 29.01.2009, at 16:11, Anthony Liguori <anthony@codemonkey.ws> wrote: > Alexander Graf wrote: >> Currently writing to buffers is protected by buffer_reserve. >> Unfortunately, is reserves at most 1024 bytes more than we currently >> have, so if we want to write a 2048 bytes chunk, we overwrite >> random memory. >> > > Yikes! > >> This patch addresses this in a pretty dumb but easy way. >> >> 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 4b17f85..d0d9580 100644 >> --- a/vnc.c >> +++ b/vnc.c >> @@ -592,7 +592,7 @@ static int vnc_listen_poll(void *opaque) >> static void buffer_reserve(Buffer *buffer, size_t len) >> { >> - if ((buffer->capacity - buffer->offset) < len) { >> + while ((buffer->capacity - buffer->offset) < len) { >> buffer->capacity += (len + 1024); >> > > Okay, I no longer believe you. > > If we want to write len bytes, and we increase capacity by (len + > 1024) bytes, then we should be fine. The reason it's len + 1024 vs > just len is to avoid many qemu_realloc()s on many small reservations > (like for adding u32s). Ugh. I must've been really tired there :o. You're right, the code does look good. Alex > > > Regards, > > Anthony Liguori >> buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity); >> if (buffer->buffer == NULL) { >> > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h 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 @ 2009-01-29 15:22 ` Anthony Liguori 2009-01-29 15:29 ` Alexander Graf 1 sibling, 1 reply; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:22 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. > A much needed change. > 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_" > These AUTH sigs are not part of the standard as far as I'm aware of it. This is the VNC_AUTH_TIGHT stuff? I'd rather not do that. > + > +#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 > This was never standardized. > +#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 > Nor was this. > +#define VNC_ENCODING_LASTRECT 0xFFFFFF20 > Nor this. > +#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" > These are not part of the standard either. I'm not sure what they do. > +/***************************************************************************** > + * > + * 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" > This also is not part of the standard. Regards, Anthony Liguori > +#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 */ > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h 2009-01-29 15:22 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori @ 2009-01-29 15:29 ` Alexander Graf 2009-01-29 15:46 ` Anthony Liguori 0 siblings, 1 reply; 19+ messages in thread From: Alexander Graf @ 2009-01-29 15:29 UTC (permalink / raw) To: Anthony Liguori; +Cc: qemu-devel Anthony Liguori wrote: > 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. >> > > A much needed change. > >> 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_" >> > > These AUTH sigs are not part of the standard as far as I'm aware of > it. This is the VNC_AUTH_TIGHT stuff? I'd rather not do that. Right. That is the follow-up from AUTH_TIGHT. Tight uses signatures in general as addition to normal codes. The same thing applies to the encoding signatures. These are required for the "Hey client, I know these encodings" packet. > >> + >> +#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 >> > > This was never standardized. >From rfbproto.h of current tightvnc: #define rfbEncodingRaw 0 #define rfbEncodingCopyRect 1 #define rfbEncodingRRE 2 #define rfbEncodingCoRRE 4 #define rfbEncodingHextile 5 #define rfbEncodingZlib 6 #define rfbEncodingTight 7 #define rfbEncodingZlibHex 8 #define rfbEncodingZRLE 16 [...] #define rfbEncodingXCursor 0xFFFFFF10 #define rfbEncodingRichCursor 0xFFFFFF11 #define rfbEncodingPointerPos 0xFFFFFF18 #define rfbEncodingLastRect 0xFFFFFF20 #define rfbEncodingNewFBSize 0xFFFFFF21 Where else should I look for defines? I'd rather have them here and if anything collide than not in any header files. > >> +#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 >> > Nor was this. >> +#define VNC_ENCODING_LASTRECT 0xFFFFFF20 >> > Nor this. >> +#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" >> > > These are not part of the standard either. I'm not sure what they do. > >> +/***************************************************************************** >> >> + * >> + * 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" >> > > This also is not part of the standard. > > Regards, > > Anthony Liguori > >> +#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 */ >> > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h 2009-01-29 15:29 ` Alexander Graf @ 2009-01-29 15:46 ` Anthony Liguori 0 siblings, 0 replies; 19+ messages in thread From: Anthony Liguori @ 2009-01-29 15:46 UTC (permalink / raw) To: Alexander Graf; +Cc: qemu-devel Alexander Graf wrote: > Anthony Liguori wrote: > >> 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. >>> >>> >> A much needed change. >> >> >>> 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_" >>> >>> >> These AUTH sigs are not part of the standard as far as I'm aware of >> it. This is the VNC_AUTH_TIGHT stuff? I'd rather not do that. >> > > Right. That is the follow-up from AUTH_TIGHT. Tight uses signatures in > general as addition to normal codes. The same thing applies to the > encoding signatures. These are required for the "Hey client, I know > these encodings" packet. > > >>> + >>> +#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 >>> >>> >> This was never standardized. >> > > From rfbproto.h of current tightvnc: > > #define rfbEncodingRaw 0 > #define rfbEncodingCopyRect 1 > #define rfbEncodingRRE 2 > #define rfbEncodingCoRRE 4 > #define rfbEncodingHextile 5 > #define rfbEncodingZlib 6 > #define rfbEncodingTight 7 > #define rfbEncodingZlibHex 8 > #define rfbEncodingZRLE 16 > [...] > #define rfbEncodingXCursor 0xFFFFFF10 > #define rfbEncodingRichCursor 0xFFFFFF11 > #define rfbEncodingPointerPos 0xFFFFFF18 > > #define rfbEncodingLastRect 0xFFFFFF20 > #define rfbEncodingNewFBSize 0xFFFFFF21 > > Where else should I look for defines? I'd rather have them here and if > anything collide than not in any header files. > http://www.realvnc.com/docs/rfbproto.pdf is where the protocol is defined. Early in VNC's life, when TightVNC first fork()'d from RealVNC, there was no formal protocol definition. This led to some incompatible implementations so if you want to maintain compatibility with the largest number of clients, it's best to stick to what's defined by the standard. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2009-01-29 15:48 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 2009-01-29 11:24 ` [Qemu-devel] [PATCH 3/7] Fix invalid #if in vnc.c when debugging is enabled Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 4/7] Make vnc buffer big-chunk aware Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 5/7] Split vnc authentication code Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 6/7] Add tight protocol awareness to vnc.c Alexander Graf 2009-01-29 11:24 ` [Qemu-devel] [PATCH 7/7] Add tight encoding (jpeg) " Alexander Graf 2009-01-29 15:17 ` [Qemu-devel] " Anthony Liguori 2009-01-29 15:23 ` Stefano Stabellini 2009-01-29 15:47 ` Anthony Liguori 2009-01-29 15:13 ` [Qemu-devel] Re: [PATCH 6/7] Add tight protocol awareness " Anthony Liguori 2009-01-29 15:24 ` Alexander Graf 2009-01-29 15:43 ` Anthony Liguori 2009-01-29 15:11 ` [Qemu-devel] Re: [PATCH 4/7] Make vnc buffer big-chunk aware Anthony Liguori 2009-01-29 15:16 ` Alexander Graf 2009-01-29 15:22 ` [Qemu-devel] Re: [PATCH 1/7] Split VNC defines to vnc.h Anthony Liguori 2009-01-29 15:29 ` Alexander Graf 2009-01-29 15:46 ` Anthony Liguori
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).