Blame SOURCES/kvm-vnc-fix-memory-leak-when-vnc-disconnect.patch

4636b8
From 218e7ff50aceac54654f950fbf67ae5f9baf0a5a Mon Sep 17 00:00:00 2001
4636b8
From: jmaloy <jmaloy@redhat.com>
4636b8
Date: Thu, 28 May 2020 12:22:30 +0200
4636b8
Subject: [PATCH 2/2] vnc: fix memory leak when vnc disconnect
4636b8
4636b8
RH-Author: jmaloy <jmaloy@redhat.com>
4636b8
Message-id: <20200508213316.1251860-3-jmaloy@redhat.com>
4636b8
Patchwork-id: 96350
4636b8
O-Subject: [RHEL-7.9 qemu-kvm-rhev PATCH 2/2] vnc: fix memory leak when vnc disconnect
4636b8
Bugzilla: 1810409
4636b8
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
4636b8
RH-Acked-by: John Snow <jsnow@redhat.com>
4636b8
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
4636b8
4636b8
From: Li Qiang <liq3ea@163.com>
4636b8
4636b8
Currently when qemu receives a vnc connect, it creates a 'VncState' to
4636b8
represent this connection. In 'vnc_worker_thread_loop' it creates a
4636b8
local 'VncState'. The connection 'VcnState' and local 'VncState' exchange
4636b8
data in 'vnc_async_encoding_start' and 'vnc_async_encoding_end'.
4636b8
In 'zrle_compress_data' it calls 'deflateInit2' to allocate the libz library
4636b8
opaque data. The 'VncState' used in 'zrle_compress_data' is the local
4636b8
'VncState'. In 'vnc_zrle_clear' it calls 'deflateEnd' to free the libz
4636b8
library opaque data. The 'VncState' used in 'vnc_zrle_clear' is the connection
4636b8
'VncState'. In currently implementation there will be a memory leak when the
4636b8
vnc disconnect. Following is the asan output backtrack:
4636b8
4636b8
Direct leak of 29760 byte(s) in 5 object(s) allocated from:
4636b8
    0 0xffffa67ef3c3 in __interceptor_calloc (/lib64/libasan.so.4+0xd33c3)
4636b8
    1 0xffffa65071cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb)
4636b8
    2 0xffffa5e968f7 in deflateInit2_ (/lib64/libz.so.1+0x78f7)
4636b8
    3 0xaaaacec58613 in zrle_compress_data ui/vnc-enc-zrle.c:87
4636b8
    4 0xaaaacec58613 in zrle_send_framebuffer_update ui/vnc-enc-zrle.c:344
4636b8
    5 0xaaaacec34e77 in vnc_send_framebuffer_update ui/vnc.c:919
4636b8
    6 0xaaaacec5e023 in vnc_worker_thread_loop ui/vnc-jobs.c:271
4636b8
    7 0xaaaacec5e5e7 in vnc_worker_thread ui/vnc-jobs.c:340
4636b8
    8 0xaaaacee4d3c3 in qemu_thread_start util/qemu-thread-posix.c:502
4636b8
    9 0xffffa544e8bb in start_thread (/lib64/libpthread.so.0+0x78bb)
4636b8
    10 0xffffa53965cb in thread_start (/lib64/libc.so.6+0xd55cb)
4636b8
4636b8
This is because the opaque allocated in 'deflateInit2' is not freed in
4636b8
'deflateEnd'. The reason is that the 'deflateEnd' calls 'deflateStateCheck'
4636b8
and in the latter will check whether 's->strm != strm'(libz's data structure).
4636b8
This check will be true so in 'deflateEnd' it just return 'Z_STREAM_ERROR' and
4636b8
not free the data allocated in 'deflateInit2'.
4636b8
4636b8
The reason this happens is that the 'VncState' contains the whole 'VncZrle',
4636b8
so when calling 'deflateInit2', the 's->strm' will be the local address.
4636b8
So 's->strm != strm' will be true.
4636b8
4636b8
To fix this issue, we need to make 'zrle' of 'VncState' to be a pointer.
4636b8
Then the connection 'VncState' and local 'VncState' exchange mechanism will
4636b8
work as expection. The 'tight' of 'VncState' has the same issue, let's also turn
4636b8
it to a pointer.
4636b8
4636b8
Reported-by: Ying Fang <fangying1@huawei.com>
4636b8
Signed-off-by: Li Qiang <liq3ea@163.com>
4636b8
Message-id: 20190831153922.121308-1-liq3ea@163.com
4636b8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
4636b8
4636b8
(cherry picked from commit 6bf21f3d83e95bcc4ba35a7a07cc6655e8b010b0)
4636b8
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
4636b8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4636b8
---
4636b8
 ui/vnc-enc-tight.c         | 219 +++++++++++++++++++++++----------------------
4636b8
 ui/vnc-enc-zlib.c          |  11 +--
4636b8
 ui/vnc-enc-zrle-template.c |   2 +-
4636b8
 ui/vnc-enc-zrle.c          |  68 +++++++-------
4636b8
 ui/vnc.c                   |  28 +++---
4636b8
 ui/vnc.h                   |   4 +-
4636b8
 6 files changed, 170 insertions(+), 162 deletions(-)
4636b8
4636b8
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
4636b8
index f38aceb..9ce2b42 100644
4636b8
--- a/ui/vnc-enc-tight.c
4636b8
+++ b/ui/vnc-enc-tight.c
4636b8
@@ -117,7 +117,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
4636b8
 
4636b8
 static bool tight_can_send_png_rect(VncState *vs, int w, int h)
4636b8
 {
4636b8
-    if (vs->tight.type != VNC_ENCODING_TIGHT_PNG) {
4636b8
+    if (vs->tight->type != VNC_ENCODING_TIGHT_PNG) {
4636b8
         return false;
4636b8
     }
4636b8
 
4636b8
@@ -145,7 +145,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
4636b8
     int pixels = 0;
4636b8
     int pix, left[3];
4636b8
     unsigned int errors;
4636b8
-    unsigned char *buf = vs->tight.tight.buffer;
4636b8
+    unsigned char *buf = vs->tight->tight.buffer;
4636b8
 
4636b8
     /*
4636b8
      * If client is big-endian, color samples begin from the second
4636b8
@@ -216,7 +216,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
4636b8
         int pixels = 0;                                                 \
4636b8
         int sample, sum, left[3];                                       \
4636b8
         unsigned int errors;                                            \
4636b8
-        unsigned char *buf = vs->tight.tight.buffer;                    \
4636b8
+        unsigned char *buf = vs->tight->tight.buffer;                    \
4636b8
                                                                         \
4636b8
         endian = 0; /* FIXME */                                         \
4636b8
                                                                         \
4636b8
@@ -297,8 +297,8 @@ static int
4636b8
 tight_detect_smooth_image(VncState *vs, int w, int h)
4636b8
 {
4636b8
     unsigned int errors;
4636b8
-    int compression = vs->tight.compression;
4636b8
-    int quality = vs->tight.quality;
4636b8
+    int compression = vs->tight->compression;
4636b8
+    int quality = vs->tight->quality;
4636b8
 
4636b8
     if (!vs->vd->lossy) {
4636b8
         return 0;
4636b8
@@ -310,7 +310,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
4636b8
         return 0;
4636b8
     }
4636b8
 
4636b8
-    if (vs->tight.quality != (uint8_t)-1) {
4636b8
+    if (vs->tight->quality != (uint8_t)-1) {
4636b8
         if (w * h < VNC_TIGHT_JPEG_MIN_RECT_SIZE) {
4636b8
             return 0;
4636b8
         }
4636b8
@@ -321,9 +321,9 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
4636b8
     }
4636b8
 
4636b8
     if (vs->client_pf.bytes_per_pixel == 4) {
4636b8
-        if (vs->tight.pixel24) {
4636b8
+        if (vs->tight->pixel24) {
4636b8
             errors = tight_detect_smooth_image24(vs, w, h);
4636b8
-            if (vs->tight.quality != (uint8_t)-1) {
4636b8
+            if (vs->tight->quality != (uint8_t)-1) {
4636b8
                 return (errors < tight_conf[quality].jpeg_threshold24);
4636b8
             }
4636b8
             return (errors < tight_conf[compression].gradient_threshold24);
4636b8
@@ -353,7 +353,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
4636b8
         uint##bpp##_t c0, c1, ci;                                       \
4636b8
         int i, n0, n1;                                                  \
4636b8
                                                                         \
4636b8
-        data = (uint##bpp##_t *)vs->tight.tight.buffer;                 \
4636b8
+        data = (uint##bpp##_t *)vs->tight->tight.buffer;                \
4636b8
                                                                         \
4636b8
         c0 = data[0];                                                   \
4636b8
         i = 1;                                                          \
4636b8
@@ -424,9 +424,9 @@ static int tight_fill_palette(VncState *vs, int x, int y,
4636b8
 {
4636b8
     int max;
4636b8
 
4636b8
-    max = count / tight_conf[vs->tight.compression].idx_max_colors_divisor;
4636b8
+    max = count / tight_conf[vs->tight->compression].idx_max_colors_divisor;
4636b8
     if (max < 2 &&
4636b8
-        count >= tight_conf[vs->tight.compression].mono_min_rect_size) {
4636b8
+        count >= tight_conf[vs->tight->compression].mono_min_rect_size) {
4636b8
         max = 2;
4636b8
     }
4636b8
     if (max >= 256) {
4636b8
@@ -559,7 +559,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
4636b8
     int x, y, c;
4636b8
 
4636b8
     buf32 = (uint32_t *)buf;
4636b8
-    memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));
4636b8
+    memset(vs->tight->gradient.buffer, 0, w * 3 * sizeof(int));
4636b8
 
4636b8
     if (1 /* FIXME */) {
4636b8
         shift[0] = vs->client_pf.rshift;
4636b8
@@ -576,7 +576,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
4636b8
             upper[c] = 0;
4636b8
             here[c] = 0;
4636b8
         }
4636b8
-        prev = (int *)vs->tight.gradient.buffer;
4636b8
+        prev = (int *)vs->tight->gradient.buffer;
4636b8
         for (x = 0; x < w; x++) {
4636b8
             pix32 = *buf32++;
4636b8
             for (c = 0; c < 3; c++) {
4636b8
@@ -616,7 +616,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
4636b8
         int prediction;                                                 \
4636b8
         int x, y, c;                                                    \
4636b8
                                                                         \
4636b8
-        memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));     \
4636b8
+        memset(vs->tight->gradient.buffer, 0, w * 3 * sizeof(int));     \
4636b8
                                                                         \
4636b8
         endian = 0; /* FIXME */                                         \
4636b8
                                                                         \
4636b8
@@ -632,7 +632,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
4636b8
                 upper[c] = 0;                                           \
4636b8
                 here[c] = 0;                                            \
4636b8
             }                                                           \
4636b8
-            prev = (int *)vs->tight.gradient.buffer;                    \
4636b8
+            prev = (int *)vs->tight->gradient.buffer;                    \
4636b8
             for (x = 0; x < w; x++) {                                   \
4636b8
                 pix = *buf;                                             \
4636b8
                 if (endian) {                                           \
4636b8
@@ -786,7 +786,7 @@ static void extend_solid_area(VncState *vs, int x, int y, int w, int h,
4636b8
 static int tight_init_stream(VncState *vs, int stream_id,
4636b8
                              int level, int strategy)
4636b8
 {
4636b8
-    z_streamp zstream = &vs->tight.stream[stream_id];
4636b8
+    z_streamp zstream = &vs->tight->stream[stream_id];
4636b8
 
4636b8
     if (zstream->opaque == NULL) {
4636b8
         int err;
4636b8
@@ -804,15 +804,15 @@ static int tight_init_stream(VncState *vs, int stream_id,
4636b8
             return -1;
4636b8
         }
4636b8
 
4636b8
-        vs->tight.levels[stream_id] = level;
4636b8
+        vs->tight->levels[stream_id] = level;
4636b8
         zstream->opaque = vs;
4636b8
     }
4636b8
 
4636b8
-    if (vs->tight.levels[stream_id] != level) {
4636b8
+    if (vs->tight->levels[stream_id] != level) {
4636b8
         if (deflateParams(zstream, level, strategy) != Z_OK) {
4636b8
             return -1;
4636b8
         }
4636b8
-        vs->tight.levels[stream_id] = level;
4636b8
+        vs->tight->levels[stream_id] = level;
4636b8
     }
4636b8
     return 0;
4636b8
 }
4636b8
@@ -840,11 +840,11 @@ static void tight_send_compact_size(VncState *vs, size_t len)
4636b8
 static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
4636b8
                                int level, int strategy)
4636b8
 {
4636b8
-    z_streamp zstream = &vs->tight.stream[stream_id];
4636b8
+    z_streamp zstream = &vs->tight->stream[stream_id];
4636b8
     int previous_out;
4636b8
 
4636b8
     if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) {
4636b8
-        vnc_write(vs, vs->tight.tight.buffer, vs->tight.tight.offset);
4636b8
+        vnc_write(vs, vs->tight->tight.buffer, vs->tight->tight.offset);
4636b8
         return bytes;
4636b8
     }
4636b8
 
4636b8
@@ -853,13 +853,13 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
4636b8
     }
4636b8
 
4636b8
     /* reserve memory in output buffer */
4636b8
-    buffer_reserve(&vs->tight.zlib, bytes + 64);
4636b8
+    buffer_reserve(&vs->tight->zlib, bytes + 64);
4636b8
 
4636b8
     /* set pointers */
4636b8
-    zstream->next_in = vs->tight.tight.buffer;
4636b8
-    zstream->avail_in = vs->tight.tight.offset;
4636b8
-    zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
4636b8
-    zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
4636b8
+    zstream->next_in = vs->tight->tight.buffer;
4636b8
+    zstream->avail_in = vs->tight->tight.offset;
4636b8
+    zstream->next_out = vs->tight->zlib.buffer + vs->tight->zlib.offset;
4636b8
+    zstream->avail_out = vs->tight->zlib.capacity - vs->tight->zlib.offset;
4636b8
     previous_out = zstream->avail_out;
4636b8
     zstream->data_type = Z_BINARY;
4636b8
 
4636b8
@@ -869,14 +869,14 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
4636b8
         return -1;
4636b8
     }
4636b8
 
4636b8
-    vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
4636b8
+    vs->tight->zlib.offset = vs->tight->zlib.capacity - zstream->avail_out;
4636b8
     /* ...how much data has actually been produced by deflate() */
4636b8
     bytes = previous_out - zstream->avail_out;
4636b8
 
4636b8
     tight_send_compact_size(vs, bytes);
4636b8
-    vnc_write(vs, vs->tight.zlib.buffer, bytes);
4636b8
+    vnc_write(vs, vs->tight->zlib.buffer, bytes);
4636b8
 
4636b8
-    buffer_reset(&vs->tight.zlib);
4636b8
+    buffer_reset(&vs->tight->zlib);
4636b8
 
4636b8
     return bytes;
4636b8
 }
4636b8
@@ -927,16 +927,17 @@ static int send_full_color_rect(VncState *vs, int x, int y, int w, int h)
4636b8
 
4636b8
     vnc_write_u8(vs, stream << 4); /* no flushing, no filter */
4636b8
 
4636b8
-    if (vs->tight.pixel24) {
4636b8
-        tight_pack24(vs, vs->tight.tight.buffer, w * h, &vs->tight.tight.offset);
4636b8
+    if (vs->tight->pixel24) {
4636b8
+        tight_pack24(vs, vs->tight->tight.buffer, w * h,
4636b8
+                     &vs->tight->tight.offset);
4636b8
         bytes = 3;
4636b8
     } else {
4636b8
         bytes = vs->client_pf.bytes_per_pixel;
4636b8
     }
4636b8
 
4636b8
     bytes = tight_compress_data(vs, stream, w * h * bytes,
4636b8
-                                tight_conf[vs->tight.compression].raw_zlib_level,
4636b8
-                                Z_DEFAULT_STRATEGY);
4636b8
+                            tight_conf[vs->tight->compression].raw_zlib_level,
4636b8
+                            Z_DEFAULT_STRATEGY);
4636b8
 
4636b8
     return (bytes >= 0);
4636b8
 }
4636b8
@@ -947,14 +948,14 @@ static int send_solid_rect(VncState *vs)
4636b8
 
4636b8
     vnc_write_u8(vs, VNC_TIGHT_FILL << 4); /* no flushing, no filter */
4636b8
 
4636b8
-    if (vs->tight.pixel24) {
4636b8
-        tight_pack24(vs, vs->tight.tight.buffer, 1, &vs->tight.tight.offset);
4636b8
+    if (vs->tight->pixel24) {
4636b8
+        tight_pack24(vs, vs->tight->tight.buffer, 1, &vs->tight->tight.offset);
4636b8
         bytes = 3;
4636b8
     } else {
4636b8
         bytes = vs->client_pf.bytes_per_pixel;
4636b8
     }
4636b8
 
4636b8
-    vnc_write(vs, vs->tight.tight.buffer, bytes);
4636b8
+    vnc_write(vs, vs->tight->tight.buffer, bytes);
4636b8
     return 1;
4636b8
 }
4636b8
 
4636b8
@@ -963,7 +964,7 @@ static int send_mono_rect(VncState *vs, int x, int y,
4636b8
 {
4636b8
     ssize_t bytes;
4636b8
     int stream = 1;
4636b8
-    int level = tight_conf[vs->tight.compression].mono_zlib_level;
4636b8
+    int level = tight_conf[vs->tight->compression].mono_zlib_level;
4636b8
 
4636b8
 #ifdef CONFIG_VNC_PNG
4636b8
     if (tight_can_send_png_rect(vs, w, h)) {
4636b8
@@ -991,26 +992,26 @@ static int send_mono_rect(VncState *vs, int x, int y,
4636b8
         uint32_t buf[2] = {bg, fg};
4636b8
         size_t ret = sizeof (buf);
4636b8
 
4636b8
-        if (vs->tight.pixel24) {
4636b8
+        if (vs->tight->pixel24) {
4636b8
             tight_pack24(vs, (unsigned char*)buf, 2, &ret;;
4636b8
         }
4636b8
         vnc_write(vs, buf, ret);
4636b8
 
4636b8
-        tight_encode_mono_rect32(vs->tight.tight.buffer, w, h, bg, fg);
4636b8
+        tight_encode_mono_rect32(vs->tight->tight.buffer, w, h, bg, fg);
4636b8
         break;
4636b8
     }
4636b8
     case 2:
4636b8
         vnc_write(vs, &bg, 2);
4636b8
         vnc_write(vs, &fg, 2);
4636b8
-        tight_encode_mono_rect16(vs->tight.tight.buffer, w, h, bg, fg);
4636b8
+        tight_encode_mono_rect16(vs->tight->tight.buffer, w, h, bg, fg);
4636b8
         break;
4636b8
     default:
4636b8
         vnc_write_u8(vs, bg);
4636b8
         vnc_write_u8(vs, fg);
4636b8
-        tight_encode_mono_rect8(vs->tight.tight.buffer, w, h, bg, fg);
4636b8
+        tight_encode_mono_rect8(vs->tight->tight.buffer, w, h, bg, fg);
4636b8
         break;
4636b8
     }
4636b8
-    vs->tight.tight.offset = bytes;
4636b8
+    vs->tight->tight.offset = bytes;
4636b8
 
4636b8
     bytes = tight_compress_data(vs, stream, bytes, level, Z_DEFAULT_STRATEGY);
4636b8
     return (bytes >= 0);
4636b8
@@ -1040,7 +1041,7 @@ static void write_palette(int idx, uint32_t color, void *opaque)
4636b8
 static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
4636b8
 {
4636b8
     int stream = 3;
4636b8
-    int level = tight_conf[vs->tight.compression].gradient_zlib_level;
4636b8
+    int level = tight_conf[vs->tight->compression].gradient_zlib_level;
4636b8
     ssize_t bytes;
4636b8
 
4636b8
     if (vs->client_pf.bytes_per_pixel == 1) {
4636b8
@@ -1050,23 +1051,23 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
4636b8
     vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
4636b8
     vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT);
4636b8
 
4636b8
-    buffer_reserve(&vs->tight.gradient, w * 3 * sizeof (int));
4636b8
+    buffer_reserve(&vs->tight->gradient, w * 3 * sizeof(int));
4636b8
 
4636b8
-    if (vs->tight.pixel24) {
4636b8
-        tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
4636b8
+    if (vs->tight->pixel24) {
4636b8
+        tight_filter_gradient24(vs, vs->tight->tight.buffer, w, h);
4636b8
         bytes = 3;
4636b8
     } else if (vs->client_pf.bytes_per_pixel == 4) {
4636b8
-        tight_filter_gradient32(vs, (uint32_t *)vs->tight.tight.buffer, w, h);
4636b8
+        tight_filter_gradient32(vs, (uint32_t *)vs->tight->tight.buffer, w, h);
4636b8
         bytes = 4;
4636b8
     } else {
4636b8
-        tight_filter_gradient16(vs, (uint16_t *)vs->tight.tight.buffer, w, h);
4636b8
+        tight_filter_gradient16(vs, (uint16_t *)vs->tight->tight.buffer, w, h);
4636b8
         bytes = 2;
4636b8
     }
4636b8
 
4636b8
-    buffer_reset(&vs->tight.gradient);
4636b8
+    buffer_reset(&vs->tight->gradient);
4636b8
 
4636b8
     bytes = w * h * bytes;
4636b8
-    vs->tight.tight.offset = bytes;
4636b8
+    vs->tight->tight.offset = bytes;
4636b8
 
4636b8
     bytes = tight_compress_data(vs, stream, bytes,
4636b8
                                 level, Z_FILTERED);
4636b8
@@ -1077,7 +1078,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
4636b8
                              int w, int h, VncPalette *palette)
4636b8
 {
4636b8
     int stream = 2;
4636b8
-    int level = tight_conf[vs->tight.compression].idx_zlib_level;
4636b8
+    int level = tight_conf[vs->tight->compression].idx_zlib_level;
4636b8
     int colors;
4636b8
     ssize_t bytes;
4636b8
 
4636b8
@@ -1104,12 +1105,12 @@ static int send_palette_rect(VncState *vs, int x, int y,
4636b8
         palette_iter(palette, write_palette, &priv;;
4636b8
         vnc_write(vs, header, sizeof(header));
4636b8
 
4636b8
-        if (vs->tight.pixel24) {
4636b8
+        if (vs->tight->pixel24) {
4636b8
             tight_pack24(vs, vs->output.buffer + old_offset, colors, &offset);
4636b8
             vs->output.offset = old_offset + offset;
4636b8
         }
4636b8
 
4636b8
-        tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
4636b8
+        tight_encode_indexed_rect32(vs->tight->tight.buffer, w * h, palette);
4636b8
         break;
4636b8
     }
4636b8
     case 2:
4636b8
@@ -1119,7 +1120,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
4636b8
 
4636b8
         palette_iter(palette, write_palette, &priv;;
4636b8
         vnc_write(vs, header, sizeof(header));
4636b8
-        tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
4636b8
+        tight_encode_indexed_rect16(vs->tight->tight.buffer, w * h, palette);
4636b8
         break;
4636b8
     }
4636b8
     default:
4636b8
@@ -1127,7 +1128,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
4636b8
         break;
4636b8
     }
4636b8
     bytes = w * h;
4636b8
-    vs->tight.tight.offset = bytes;
4636b8
+    vs->tight->tight.offset = bytes;
4636b8
 
4636b8
     bytes = tight_compress_data(vs, stream, bytes,
4636b8
                                 level, Z_DEFAULT_STRATEGY);
4636b8
@@ -1146,7 +1147,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
4636b8
 static void jpeg_init_destination(j_compress_ptr cinfo)
4636b8
 {
4636b8
     VncState *vs = cinfo->client_data;
4636b8
-    Buffer *buffer = &vs->tight.jpeg;
4636b8
+    Buffer *buffer = &vs->tight->jpeg;
4636b8
 
4636b8
     cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset;
4636b8
     cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset);
4636b8
@@ -1156,7 +1157,7 @@ static void jpeg_init_destination(j_compress_ptr cinfo)
4636b8
 static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
4636b8
 {
4636b8
     VncState *vs = cinfo->client_data;
4636b8
-    Buffer *buffer = &vs->tight.jpeg;
4636b8
+    Buffer *buffer = &vs->tight->jpeg;
4636b8
 
4636b8
     buffer->offset = buffer->capacity;
4636b8
     buffer_reserve(buffer, 2048);
4636b8
@@ -1168,7 +1169,7 @@ static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
4636b8
 static void jpeg_term_destination(j_compress_ptr cinfo)
4636b8
 {
4636b8
     VncState *vs = cinfo->client_data;
4636b8
-    Buffer *buffer = &vs->tight.jpeg;
4636b8
+    Buffer *buffer = &vs->tight->jpeg;
4636b8
 
4636b8
     buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer;
4636b8
 }
4636b8
@@ -1187,7 +1188,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
4636b8
         return send_full_color_rect(vs, x, y, w, h);
4636b8
     }
4636b8
 
4636b8
-    buffer_reserve(&vs->tight.jpeg, 2048);
4636b8
+    buffer_reserve(&vs->tight->jpeg, 2048);
4636b8
 
4636b8
     cinfo.err = jpeg_std_error(&jerr);
4636b8
     jpeg_create_compress(&cinfo);
4636b8
@@ -1222,9 +1223,9 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
4636b8
 
4636b8
     vnc_write_u8(vs, VNC_TIGHT_JPEG << 4);
4636b8
 
4636b8
-    tight_send_compact_size(vs, vs->tight.jpeg.offset);
4636b8
-    vnc_write(vs, vs->tight.jpeg.buffer, vs->tight.jpeg.offset);
4636b8
-    buffer_reset(&vs->tight.jpeg);
4636b8
+    tight_send_compact_size(vs, vs->tight->jpeg.offset);
4636b8
+    vnc_write(vs, vs->tight->jpeg.buffer, vs->tight->jpeg.offset);
4636b8
+    buffer_reset(&vs->tight->jpeg);
4636b8
 
4636b8
     return 1;
4636b8
 }
4636b8
@@ -1240,7 +1241,7 @@ static void write_png_palette(int idx, uint32_t pix, void *opaque)
4636b8
     VncState *vs = priv->vs;
4636b8
     png_colorp color = &priv->png_palette[idx];
4636b8
 
4636b8
-    if (vs->tight.pixel24)
4636b8
+    if (vs->tight->pixel24)
4636b8
     {
4636b8
         color->red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax;
4636b8
         color->green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax;
4636b8
@@ -1267,10 +1268,10 @@ static void png_write_data(png_structp png_ptr, png_bytep data,
4636b8
 {
4636b8
     VncState *vs = png_get_io_ptr(png_ptr);
4636b8
 
4636b8
-    buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
4636b8
-    memcpy(vs->tight.png.buffer + vs->tight.png.offset, data, length);
4636b8
+    buffer_reserve(&vs->tight->png, vs->tight->png.offset + length);
4636b8
+    memcpy(vs->tight->png.buffer + vs->tight->png.offset, data, length);
4636b8
 
4636b8
-    vs->tight.png.offset += length;
4636b8
+    vs->tight->png.offset += length;
4636b8
 }
4636b8
 
4636b8
 static void png_flush_data(png_structp png_ptr)
4636b8
@@ -1295,8 +1296,8 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
4636b8
     png_infop info_ptr;
4636b8
     png_colorp png_palette = NULL;
4636b8
     pixman_image_t *linebuf;
4636b8
-    int level = tight_png_conf[vs->tight.compression].png_zlib_level;
4636b8
-    int filters = tight_png_conf[vs->tight.compression].png_filters;
4636b8
+    int level = tight_png_conf[vs->tight->compression].png_zlib_level;
4636b8
+    int filters = tight_png_conf[vs->tight->compression].png_filters;
4636b8
     uint8_t *buf;
4636b8
     int dy;
4636b8
 
4636b8
@@ -1340,21 +1341,23 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
4636b8
         png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette));
4636b8
 
4636b8
         if (vs->client_pf.bytes_per_pixel == 4) {
4636b8
-            tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
4636b8
+            tight_encode_indexed_rect32(vs->tight->tight.buffer, w * h,
4636b8
+                                        palette);
4636b8
         } else {
4636b8
-            tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
4636b8
+            tight_encode_indexed_rect16(vs->tight->tight.buffer, w * h,
4636b8
+                                        palette);
4636b8
         }
4636b8
     }
4636b8
 
4636b8
     png_write_info(png_ptr, info_ptr);
4636b8
 
4636b8
-    buffer_reserve(&vs->tight.png, 2048);
4636b8
+    buffer_reserve(&vs->tight->png, 2048);
4636b8
     linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
4636b8
     buf = (uint8_t *)pixman_image_get_data(linebuf);
4636b8
     for (dy = 0; dy < h; dy++)
4636b8
     {
4636b8
         if (color_type == PNG_COLOR_TYPE_PALETTE) {
4636b8
-            memcpy(buf, vs->tight.tight.buffer + (dy * w), w);
4636b8
+            memcpy(buf, vs->tight->tight.buffer + (dy * w), w);
4636b8
         } else {
4636b8
             qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy);
4636b8
         }
4636b8
@@ -1372,27 +1375,27 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
4636b8
 
4636b8
     vnc_write_u8(vs, VNC_TIGHT_PNG << 4);
4636b8
 
4636b8
-    tight_send_compact_size(vs, vs->tight.png.offset);
4636b8
-    vnc_write(vs, vs->tight.png.buffer, vs->tight.png.offset);
4636b8
-    buffer_reset(&vs->tight.png);
4636b8
+    tight_send_compact_size(vs, vs->tight->png.offset);
4636b8
+    vnc_write(vs, vs->tight->png.buffer, vs->tight->png.offset);
4636b8
+    buffer_reset(&vs->tight->png);
4636b8
     return 1;
4636b8
 }
4636b8
 #endif /* CONFIG_VNC_PNG */
4636b8
 
4636b8
 static void vnc_tight_start(VncState *vs)
4636b8
 {
4636b8
-    buffer_reset(&vs->tight.tight);
4636b8
+    buffer_reset(&vs->tight->tight);
4636b8
 
4636b8
     // make the output buffer be the zlib buffer, so we can compress it later
4636b8
-    vs->tight.tmp = vs->output;
4636b8
-    vs->output = vs->tight.tight;
4636b8
+    vs->tight->tmp = vs->output;
4636b8
+    vs->output = vs->tight->tight;
4636b8
 }
4636b8
 
4636b8
 static void vnc_tight_stop(VncState *vs)
4636b8
 {
4636b8
     // switch back to normal output/zlib buffers
4636b8
-    vs->tight.tight = vs->output;
4636b8
-    vs->output = vs->tight.tmp;
4636b8
+    vs->tight->tight = vs->output;
4636b8
+    vs->output = vs->tight->tmp;
4636b8
 }
4636b8
 
4636b8
 static int send_sub_rect_nojpeg(VncState *vs, int x, int y, int w, int h,
4636b8
@@ -1426,9 +1429,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
4636b8
     int ret;
4636b8
 
4636b8
     if (colors == 0) {
4636b8
-        if (force || (tight_jpeg_conf[vs->tight.quality].jpeg_full &&
4636b8
+        if (force || (tight_jpeg_conf[vs->tight->quality].jpeg_full &&
4636b8
                       tight_detect_smooth_image(vs, w, h))) {
4636b8
-            int quality = tight_conf[vs->tight.quality].jpeg_quality;
4636b8
+            int quality = tight_conf[vs->tight->quality].jpeg_quality;
4636b8
 
4636b8
             ret = send_jpeg_rect(vs, x, y, w, h, quality);
4636b8
         } else {
4636b8
@@ -1440,9 +1443,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
4636b8
         ret = send_mono_rect(vs, x, y, w, h, bg, fg);
4636b8
     } else if (colors <= 256) {
4636b8
         if (force || (colors > 96 &&
4636b8
-                      tight_jpeg_conf[vs->tight.quality].jpeg_idx &&
4636b8
+                      tight_jpeg_conf[vs->tight->quality].jpeg_idx &&
4636b8
                       tight_detect_smooth_image(vs, w, h))) {
4636b8
-            int quality = tight_conf[vs->tight.quality].jpeg_quality;
4636b8
+            int quality = tight_conf[vs->tight->quality].jpeg_quality;
4636b8
 
4636b8
             ret = send_jpeg_rect(vs, x, y, w, h, quality);
4636b8
         } else {
4636b8
@@ -1480,20 +1483,20 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
4636b8
         qemu_thread_atexit_add(&vnc_tight_cleanup_notifier);
4636b8
     }
4636b8
 
4636b8
-    vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
4636b8
+    vnc_framebuffer_update(vs, x, y, w, h, vs->tight->type);
4636b8
 
4636b8
     vnc_tight_start(vs);
4636b8
     vnc_raw_send_framebuffer_update(vs, x, y, w, h);
4636b8
     vnc_tight_stop(vs);
4636b8
 
4636b8
 #ifdef CONFIG_VNC_JPEG
4636b8
-    if (!vs->vd->non_adaptive && vs->tight.quality != (uint8_t)-1) {
4636b8
+    if (!vs->vd->non_adaptive && vs->tight->quality != (uint8_t)-1) {
4636b8
         double freq = vnc_update_freq(vs, x, y, w, h);
4636b8
 
4636b8
-        if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) {
4636b8
+        if (freq < tight_jpeg_conf[vs->tight->quality].jpeg_freq_min) {
4636b8
             allow_jpeg = false;
4636b8
         }
4636b8
-        if (freq >= tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
4636b8
+        if (freq >= tight_jpeg_conf[vs->tight->quality].jpeg_freq_threshold) {
4636b8
             force_jpeg = true;
4636b8
             vnc_sent_lossy_rect(vs, x, y, w, h);
4636b8
         }
4636b8
@@ -1503,7 +1506,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
4636b8
     colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, color_count_palette);
4636b8
 
4636b8
 #ifdef CONFIG_VNC_JPEG
4636b8
-    if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
4636b8
+    if (allow_jpeg && vs->tight->quality != (uint8_t)-1) {
4636b8
         ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors,
4636b8
                                  color_count_palette, force_jpeg);
4636b8
     } else {
4636b8
@@ -1520,7 +1523,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
4636b8
 
4636b8
 static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h)
4636b8
 {
4636b8
-    vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
4636b8
+    vnc_framebuffer_update(vs, x, y, w, h, vs->tight->type);
4636b8
 
4636b8
     vnc_tight_start(vs);
4636b8
     vnc_raw_send_framebuffer_update(vs, x, y, w, h);
4636b8
@@ -1538,8 +1541,8 @@ static int send_rect_simple(VncState *vs, int x, int y, int w, int h,
4636b8
     int rw, rh;
4636b8
     int n = 0;
4636b8
 
4636b8
-    max_size = tight_conf[vs->tight.compression].max_rect_size;
4636b8
-    max_width = tight_conf[vs->tight.compression].max_rect_width;
4636b8
+    max_size = tight_conf[vs->tight->compression].max_rect_size;
4636b8
+    max_width = tight_conf[vs->tight->compression].max_rect_width;
4636b8
 
4636b8
     if (split && (w > max_width || w * h > max_size)) {
4636b8
         max_sub_width = (w > max_width) ? max_width : w;
4636b8
@@ -1648,16 +1651,16 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
 
4636b8
     if (vs->client_pf.bytes_per_pixel == 4 && vs->client_pf.rmax == 0xFF &&
4636b8
         vs->client_pf.bmax == 0xFF && vs->client_pf.gmax == 0xFF) {
4636b8
-        vs->tight.pixel24 = true;
4636b8
+        vs->tight->pixel24 = true;
4636b8
     } else {
4636b8
-        vs->tight.pixel24 = false;
4636b8
+        vs->tight->pixel24 = false;
4636b8
     }
4636b8
 
4636b8
 #ifdef CONFIG_VNC_JPEG
4636b8
-    if (vs->tight.quality != (uint8_t)-1) {
4636b8
+    if (vs->tight->quality != (uint8_t)-1) {
4636b8
         double freq = vnc_update_freq(vs, x, y, w, h);
4636b8
 
4636b8
-        if (freq > tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
4636b8
+        if (freq > tight_jpeg_conf[vs->tight->quality].jpeg_freq_threshold) {
4636b8
             return send_rect_simple(vs, x, y, w, h, false);
4636b8
         }
4636b8
     }
4636b8
@@ -1669,8 +1672,8 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
 
4636b8
     /* Calculate maximum number of rows in one non-solid rectangle. */
4636b8
 
4636b8
-    max_rows = tight_conf[vs->tight.compression].max_rect_size;
4636b8
-    max_rows /= MIN(tight_conf[vs->tight.compression].max_rect_width, w);
4636b8
+    max_rows = tight_conf[vs->tight->compression].max_rect_size;
4636b8
+    max_rows /= MIN(tight_conf[vs->tight->compression].max_rect_width, w);
4636b8
 
4636b8
     return find_large_solid_color_rect(vs, x, y, w, h, max_rows);
4636b8
 }
4636b8
@@ -1678,33 +1681,33 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
 int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
                                       int w, int h)
4636b8
 {
4636b8
-    vs->tight.type = VNC_ENCODING_TIGHT;
4636b8
+    vs->tight->type = VNC_ENCODING_TIGHT;
4636b8
     return tight_send_framebuffer_update(vs, x, y, w, h);
4636b8
 }
4636b8
 
4636b8
 int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
                                           int w, int h)
4636b8
 {
4636b8
-    vs->tight.type = VNC_ENCODING_TIGHT_PNG;
4636b8
+    vs->tight->type = VNC_ENCODING_TIGHT_PNG;
4636b8
     return tight_send_framebuffer_update(vs, x, y, w, h);
4636b8
 }
4636b8
 
4636b8
 void vnc_tight_clear(VncState *vs)
4636b8
 {
4636b8
     int i;
4636b8
-    for (i=0; i<ARRAY_SIZE(vs->tight.stream); i++) {
4636b8
-        if (vs->tight.stream[i].opaque) {
4636b8
-            deflateEnd(&vs->tight.stream[i]);
4636b8
+    for (i = 0; i < ARRAY_SIZE(vs->tight->stream); i++) {
4636b8
+        if (vs->tight->stream[i].opaque) {
4636b8
+            deflateEnd(&vs->tight->stream[i]);
4636b8
         }
4636b8
     }
4636b8
 
4636b8
-    buffer_free(&vs->tight.tight);
4636b8
-    buffer_free(&vs->tight.zlib);
4636b8
-    buffer_free(&vs->tight.gradient);
4636b8
+    buffer_free(&vs->tight->tight);
4636b8
+    buffer_free(&vs->tight->zlib);
4636b8
+    buffer_free(&vs->tight->gradient);
4636b8
 #ifdef CONFIG_VNC_JPEG
4636b8
-    buffer_free(&vs->tight.jpeg);
4636b8
+    buffer_free(&vs->tight->jpeg);
4636b8
 #endif
4636b8
 #ifdef CONFIG_VNC_PNG
4636b8
-    buffer_free(&vs->tight.png);
4636b8
+    buffer_free(&vs->tight->png);
4636b8
 #endif
4636b8
 }
4636b8
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
4636b8
index 33e9df2..900ae5b 100644
4636b8
--- a/ui/vnc-enc-zlib.c
4636b8
+++ b/ui/vnc-enc-zlib.c
4636b8
@@ -76,7 +76,8 @@ static int vnc_zlib_stop(VncState *vs)
4636b8
         zstream->zalloc = vnc_zlib_zalloc;
4636b8
         zstream->zfree = vnc_zlib_zfree;
4636b8
 
4636b8
-        err = deflateInit2(zstream, vs->tight.compression, Z_DEFLATED, MAX_WBITS,
4636b8
+        err = deflateInit2(zstream, vs->tight->compression, Z_DEFLATED,
4636b8
+                           MAX_WBITS,
4636b8
                            MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
4636b8
 
4636b8
         if (err != Z_OK) {
4636b8
@@ -84,16 +85,16 @@ static int vnc_zlib_stop(VncState *vs)
4636b8
             return -1;
4636b8
         }
4636b8
 
4636b8
-        vs->zlib.level = vs->tight.compression;
4636b8
+        vs->zlib.level = vs->tight->compression;
4636b8
         zstream->opaque = vs;
4636b8
     }
4636b8
 
4636b8
-    if (vs->tight.compression != vs->zlib.level) {
4636b8
-        if (deflateParams(zstream, vs->tight.compression,
4636b8
+    if (vs->tight->compression != vs->zlib.level) {
4636b8
+        if (deflateParams(zstream, vs->tight->compression,
4636b8
                           Z_DEFAULT_STRATEGY) != Z_OK) {
4636b8
             return -1;
4636b8
         }
4636b8
-        vs->zlib.level = vs->tight.compression;
4636b8
+        vs->zlib.level = vs->tight->compression;
4636b8
     }
4636b8
 
4636b8
     // reserve memory in output buffer
4636b8
diff --git a/ui/vnc-enc-zrle-template.c b/ui/vnc-enc-zrle-template.c
4636b8
index abf6b86..c107d8a 100644
4636b8
--- a/ui/vnc-enc-zrle-template.c
4636b8
+++ b/ui/vnc-enc-zrle-template.c
4636b8
@@ -96,7 +96,7 @@ static void ZRLE_ENCODE(VncState *vs, int x, int y, int w, int h,
4636b8
 static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
4636b8
                              int zywrle_level)
4636b8
 {
4636b8
-    VncPalette *palette = &vs->zrle.palette;
4636b8
+    VncPalette *palette = &vs->zrle->palette;
4636b8
 
4636b8
     int runs = 0;
4636b8
     int single_pixels = 0;
4636b8
diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
4636b8
index fd63d4f..3d259ed 100644
4636b8
--- a/ui/vnc-enc-zrle.c
4636b8
+++ b/ui/vnc-enc-zrle.c
4636b8
@@ -37,18 +37,18 @@ static const int bits_per_packed_pixel[] = {
4636b8
 
4636b8
 static void vnc_zrle_start(VncState *vs)
4636b8
 {
4636b8
-    buffer_reset(&vs->zrle.zrle);
4636b8
+    buffer_reset(&vs->zrle->zrle);
4636b8
 
4636b8
     /* make the output buffer be the zlib buffer, so we can compress it later */
4636b8
-    vs->zrle.tmp = vs->output;
4636b8
-    vs->output = vs->zrle.zrle;
4636b8
+    vs->zrle->tmp = vs->output;
4636b8
+    vs->output = vs->zrle->zrle;
4636b8
 }
4636b8
 
4636b8
 static void vnc_zrle_stop(VncState *vs)
4636b8
 {
4636b8
     /* switch back to normal output/zlib buffers */
4636b8
-    vs->zrle.zrle = vs->output;
4636b8
-    vs->output = vs->zrle.tmp;
4636b8
+    vs->zrle->zrle = vs->output;
4636b8
+    vs->output = vs->zrle->tmp;
4636b8
 }
4636b8
 
4636b8
 static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
4636b8
@@ -56,24 +56,24 @@ static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
4636b8
 {
4636b8
     Buffer tmp;
4636b8
 
4636b8
-    buffer_reset(&vs->zrle.fb);
4636b8
-    buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
4636b8
+    buffer_reset(&vs->zrle->fb);
4636b8
+    buffer_reserve(&vs->zrle->fb, w * h * bpp + bpp);
4636b8
 
4636b8
     tmp = vs->output;
4636b8
-    vs->output = vs->zrle.fb;
4636b8
+    vs->output = vs->zrle->fb;
4636b8
 
4636b8
     vnc_raw_send_framebuffer_update(vs, x, y, w, h);
4636b8
 
4636b8
-    vs->zrle.fb = vs->output;
4636b8
+    vs->zrle->fb = vs->output;
4636b8
     vs->output = tmp;
4636b8
-    return vs->zrle.fb.buffer;
4636b8
+    return vs->zrle->fb.buffer;
4636b8
 }
4636b8
 
4636b8
 static int zrle_compress_data(VncState *vs, int level)
4636b8
 {
4636b8
-    z_streamp zstream = &vs->zrle.stream;
4636b8
+    z_streamp zstream = &vs->zrle->stream;
4636b8
 
4636b8
-    buffer_reset(&vs->zrle.zlib);
4636b8
+    buffer_reset(&vs->zrle->zlib);
4636b8
 
4636b8
     if (zstream->opaque != vs) {
4636b8
         int err;
4636b8
@@ -93,13 +93,13 @@ static int zrle_compress_data(VncState *vs, int level)
4636b8
     }
4636b8
 
4636b8
     /* reserve memory in output buffer */
4636b8
-    buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
4636b8
+    buffer_reserve(&vs->zrle->zlib, vs->zrle->zrle.offset + 64);
4636b8
 
4636b8
     /* set pointers */
4636b8
-    zstream->next_in = vs->zrle.zrle.buffer;
4636b8
-    zstream->avail_in = vs->zrle.zrle.offset;
4636b8
-    zstream->next_out = vs->zrle.zlib.buffer + vs->zrle.zlib.offset;
4636b8
-    zstream->avail_out = vs->zrle.zlib.capacity - vs->zrle.zlib.offset;
4636b8
+    zstream->next_in = vs->zrle->zrle.buffer;
4636b8
+    zstream->avail_in = vs->zrle->zrle.offset;
4636b8
+    zstream->next_out = vs->zrle->zlib.buffer + vs->zrle->zlib.offset;
4636b8
+    zstream->avail_out = vs->zrle->zlib.capacity - vs->zrle->zlib.offset;
4636b8
     zstream->data_type = Z_BINARY;
4636b8
 
4636b8
     /* start encoding */
4636b8
@@ -108,8 +108,8 @@ static int zrle_compress_data(VncState *vs, int level)
4636b8
         return -1;
4636b8
     }
4636b8
 
4636b8
-    vs->zrle.zlib.offset = vs->zrle.zlib.capacity - zstream->avail_out;
4636b8
-    return vs->zrle.zlib.offset;
4636b8
+    vs->zrle->zlib.offset = vs->zrle->zlib.capacity - zstream->avail_out;
4636b8
+    return vs->zrle->zlib.offset;
4636b8
 }
4636b8
 
4636b8
 /* Try to work out whether to use RLE and/or a palette.  We do this by
4636b8
@@ -259,14 +259,14 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
     size_t bytes;
4636b8
     int zywrle_level;
4636b8
 
4636b8
-    if (vs->zrle.type == VNC_ENCODING_ZYWRLE) {
4636b8
-        if (!vs->vd->lossy || vs->tight.quality == (uint8_t)-1
4636b8
-            || vs->tight.quality == 9) {
4636b8
+    if (vs->zrle->type == VNC_ENCODING_ZYWRLE) {
4636b8
+        if (!vs->vd->lossy || vs->tight->quality == (uint8_t)-1
4636b8
+            || vs->tight->quality == 9) {
4636b8
             zywrle_level = 0;
4636b8
-            vs->zrle.type = VNC_ENCODING_ZRLE;
4636b8
-        } else if (vs->tight.quality < 3) {
4636b8
+            vs->zrle->type = VNC_ENCODING_ZRLE;
4636b8
+        } else if (vs->tight->quality < 3) {
4636b8
             zywrle_level = 3;
4636b8
-        } else if (vs->tight.quality < 6) {
4636b8
+        } else if (vs->tight->quality < 6) {
4636b8
             zywrle_level = 2;
4636b8
         } else {
4636b8
             zywrle_level = 1;
4636b8
@@ -337,30 +337,30 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
4636b8
 
4636b8
     vnc_zrle_stop(vs);
4636b8
     bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION);
4636b8
-    vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type);
4636b8
+    vnc_framebuffer_update(vs, x, y, w, h, vs->zrle->type);
4636b8
     vnc_write_u32(vs, bytes);
4636b8
-    vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset);
4636b8
+    vnc_write(vs, vs->zrle->zlib.buffer, vs->zrle->zlib.offset);
4636b8
     return 1;
4636b8
 }
4636b8
 
4636b8
 int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
4636b8
 {
4636b8
-    vs->zrle.type = VNC_ENCODING_ZRLE;
4636b8
+    vs->zrle->type = VNC_ENCODING_ZRLE;
4636b8
     return zrle_send_framebuffer_update(vs, x, y, w, h);
4636b8
 }
4636b8
 
4636b8
 int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
4636b8
 {
4636b8
-    vs->zrle.type = VNC_ENCODING_ZYWRLE;
4636b8
+    vs->zrle->type = VNC_ENCODING_ZYWRLE;
4636b8
     return zrle_send_framebuffer_update(vs, x, y, w, h);
4636b8
 }
4636b8
 
4636b8
 void vnc_zrle_clear(VncState *vs)
4636b8
 {
4636b8
-    if (vs->zrle.stream.opaque) {
4636b8
-        deflateEnd(&vs->zrle.stream);
4636b8
+    if (vs->zrle->stream.opaque) {
4636b8
+        deflateEnd(&vs->zrle->stream);
4636b8
     }
4636b8
-    buffer_free(&vs->zrle.zrle);
4636b8
-    buffer_free(&vs->zrle.fb);
4636b8
-    buffer_free(&vs->zrle.zlib);
4636b8
+    buffer_free(&vs->zrle->zrle);
4636b8
+    buffer_free(&vs->zrle->fb);
4636b8
+    buffer_free(&vs->zrle->zlib);
4636b8
 }
4636b8
diff --git a/ui/vnc.c b/ui/vnc.c
4636b8
index fbd0da1..821e664 100644
4636b8
--- a/ui/vnc.c
4636b8
+++ b/ui/vnc.c
4636b8
@@ -1278,6 +1278,8 @@ void vnc_disconnect_finish(VncState *vs)
4636b8
     object_unref(OBJECT(vs->sioc));
4636b8
     vs->sioc = NULL;
4636b8
     vs->magic = 0;
4636b8
+    g_free(vs->zrle);
4636b8
+    g_free(vs->tight);
4636b8
     g_free(vs);
4636b8
 }
4636b8
 
4636b8
@@ -2087,8 +2089,8 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
4636b8
 
4636b8
     vs->features = 0;
4636b8
     vs->vnc_encoding = 0;
4636b8
-    vs->tight.compression = 9;
4636b8
-    vs->tight.quality = -1; /* Lossless by default */
4636b8
+    vs->tight->compression = 9;
4636b8
+    vs->tight->quality = -1; /* Lossless by default */
4636b8
     vs->absolute = -1;
4636b8
 
4636b8
     /*
4636b8
@@ -2156,11 +2158,11 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
4636b8
             vs->features |= VNC_FEATURE_LED_STATE_MASK;
4636b8
             break;
4636b8
         case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
4636b8
-            vs->tight.compression = (enc & 0x0F);
4636b8
+            vs->tight->compression = (enc & 0x0F);
4636b8
             break;
4636b8
         case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
4636b8
             if (vs->vd->lossy) {
4636b8
-                vs->tight.quality = (enc & 0x0F);
4636b8
+                vs->tight->quality = (enc & 0x0F);
4636b8
             }
4636b8
             break;
4636b8
         default:
4636b8
@@ -3070,6 +3072,8 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
4636b8
     int i;
4636b8
 
4636b8
     trace_vnc_client_connect(vs, sioc);
4636b8
+    vs->zrle = g_new0(VncZrle, 1);
4636b8
+    vs->tight = g_new0(VncTight, 1);
4636b8
     vs->magic = VNC_MAGIC;
4636b8
     vs->sioc = sioc;
4636b8
     object_ref(OBJECT(vs->sioc));
4636b8
@@ -3081,19 +3085,19 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
4636b8
     buffer_init(&vs->output,         "vnc-output/%p", sioc);
4636b8
     buffer_init(&vs->jobs_buffer,    "vnc-jobs_buffer/%p", sioc);
4636b8
 
4636b8
-    buffer_init(&vs->tight.tight,    "vnc-tight/%p", sioc);
4636b8
-    buffer_init(&vs->tight.zlib,     "vnc-tight-zlib/%p", sioc);
4636b8
-    buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
4636b8
+    buffer_init(&vs->tight->tight,    "vnc-tight/%p", sioc);
4636b8
+    buffer_init(&vs->tight->zlib,     "vnc-tight-zlib/%p", sioc);
4636b8
+    buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
4636b8
 #ifdef CONFIG_VNC_JPEG
4636b8
-    buffer_init(&vs->tight.jpeg,     "vnc-tight-jpeg/%p", sioc);
4636b8
+    buffer_init(&vs->tight->jpeg,     "vnc-tight-jpeg/%p", sioc);
4636b8
 #endif
4636b8
 #ifdef CONFIG_VNC_PNG
4636b8
-    buffer_init(&vs->tight.png,      "vnc-tight-png/%p", sioc);
4636b8
+    buffer_init(&vs->tight->png,      "vnc-tight-png/%p", sioc);
4636b8
 #endif
4636b8
     buffer_init(&vs->zlib.zlib,      "vnc-zlib/%p", sioc);
4636b8
-    buffer_init(&vs->zrle.zrle,      "vnc-zrle/%p", sioc);
4636b8
-    buffer_init(&vs->zrle.fb,        "vnc-zrle-fb/%p", sioc);
4636b8
-    buffer_init(&vs->zrle.zlib,      "vnc-zrle-zlib/%p", sioc);
4636b8
+    buffer_init(&vs->zrle->zrle,      "vnc-zrle/%p", sioc);
4636b8
+    buffer_init(&vs->zrle->fb,        "vnc-zrle-fb/%p", sioc);
4636b8
+    buffer_init(&vs->zrle->zlib,      "vnc-zrle-zlib/%p", sioc);
4636b8
 
4636b8
     if (skipauth) {
4636b8
 	vs->auth = VNC_AUTH_NONE;
4636b8
diff --git a/ui/vnc.h b/ui/vnc.h
4636b8
index 7626329..8d9687c 100644
4636b8
--- a/ui/vnc.h
4636b8
+++ b/ui/vnc.h
4636b8
@@ -335,10 +335,10 @@ struct VncState
4636b8
     /* Encoding specific, if you add something here, don't forget to
4636b8
      *  update vnc_async_encoding_start()
4636b8
      */
4636b8
-    VncTight tight;
4636b8
+    VncTight *tight;
4636b8
     VncZlib zlib;
4636b8
     VncHextile hextile;
4636b8
-    VncZrle zrle;
4636b8
+    VncZrle *zrle;
4636b8
     VncZywrle zywrle;
4636b8
 
4636b8
     Notifier mouse_mode_notifier;
4636b8
-- 
4636b8
1.8.3.1
4636b8