[Spice-devel] [PATCH spice-gtk] use common submodule

Marc-André Lureau marcandre.lureau at gmail.com
Wed Mar 14 18:20:00 PDT 2012


---
 .gitmodules                 |    3 +
 common                      |    1 +
 common/.gitignore           |    8 -
 common/Makefile.am          |   55 -
 common/canvas_base.c        | 3426 ----------------------------------------
 common/canvas_base.h        |  316 ----
 common/canvas_utils.c       |  307 ----
 common/canvas_utils.h       |   72 -
 common/demarshallers.h      |   28 -
 common/draw.h               |  274 ----
 common/gdi_canvas.c         | 1870 ----------------------
 common/gdi_canvas.h         |   39 -
 common/gl_canvas.c          |  909 -----------
 common/gl_canvas.h          |   37 -
 common/gl_utils.h           |  105 --
 common/glc.c                | 1521 ------------------
 common/glc.c.save           | 1413 -----------------
 common/glc.h                |  159 --
 common/lines.c              | 3618 -------------------------------------------
 common/lines.h              |  130 --
 common/lz.c                 |  738 ---------
 common/lz.h                 |   76 -
 common/lz_common.h          |   62 -
 common/lz_compress_tmpl.c   |  526 -------
 common/lz_config.h          |   48 -
 common/lz_decompress_tmpl.c |  323 ----
 common/macros.h             |   30 -
 common/marshaller.c         |  614 --------
 common/marshaller.h         |   66 -
 common/marshallers.h        |   74 -
 common/mem.c                |  243 ---
 common/mem.h                |  129 --
 common/messages.h           |  550 -------
 common/mutex.h              |   35 -
 common/ogl_ctx.c            |  254 ---
 common/ogl_ctx.h            |   31 -
 common/pixman_utils.c       | 1614 -------------------
 common/pixman_utils.h       |  128 --
 common/quic.c               | 1706 --------------------
 common/quic.h               |   66 -
 common/quic_config.h        |   51 -
 common/quic_family_tmpl.c   |  115 --
 common/quic_rgb_tmpl.c      |  763 ---------
 common/quic_tmpl.c          |  633 --------
 common/rect.h               |  115 --
 common/region.c             |  893 -----------
 common/region.h             |   63 -
 common/ring.h               |  153 --
 common/rop3.c               |  657 --------
 common/rop3.h               |   34 -
 common/ssl_verify.c         |  477 ------
 common/ssl_verify.h         |   59 -
 common/sw_canvas.c          | 1321 ----------------
 common/sw_canvas.h          |   58 -
 configure.ac                |    2 +
 gtk/Makefile.am             |    8 +-
 gtk/decode.h                |    1 +
 gtk/spice-channel-priv.h    |    5 +-
 58 files changed, 15 insertions(+), 26997 deletions(-)
 create mode 160000 common
 delete mode 100644 common/.gitignore
 delete mode 100644 common/Makefile.am
 delete mode 100644 common/canvas_base.c
 delete mode 100644 common/canvas_base.h
 delete mode 100644 common/canvas_utils.c
 delete mode 100644 common/canvas_utils.h
 delete mode 100644 common/demarshallers.h
 delete mode 100644 common/draw.h
 delete mode 100644 common/gdi_canvas.c
 delete mode 100644 common/gdi_canvas.h
 delete mode 100644 common/gl_canvas.c
 delete mode 100644 common/gl_canvas.h
 delete mode 100644 common/gl_utils.h
 delete mode 100644 common/glc.c
 delete mode 100644 common/glc.c.save
 delete mode 100644 common/glc.h
 delete mode 100644 common/lines.c
 delete mode 100644 common/lines.h
 delete mode 100644 common/lz.c
 delete mode 100644 common/lz.h
 delete mode 100644 common/lz_common.h
 delete mode 100644 common/lz_compress_tmpl.c
 delete mode 100644 common/lz_config.h
 delete mode 100644 common/lz_decompress_tmpl.c
 delete mode 100644 common/macros.h
 delete mode 100644 common/marshaller.c
 delete mode 100644 common/marshaller.h
 delete mode 100644 common/marshallers.h
 delete mode 100644 common/mem.c
 delete mode 100644 common/mem.h
 delete mode 100644 common/messages.h
 delete mode 100644 common/mutex.h
 delete mode 100644 common/ogl_ctx.c
 delete mode 100644 common/ogl_ctx.h
 delete mode 100644 common/pixman_utils.c
 delete mode 100644 common/pixman_utils.h
 delete mode 100644 common/quic.c
 delete mode 100644 common/quic.h
 delete mode 100644 common/quic_config.h
 delete mode 100644 common/quic_family_tmpl.c
 delete mode 100644 common/quic_rgb_tmpl.c
 delete mode 100644 common/quic_tmpl.c
 delete mode 100644 common/rect.h
 delete mode 100644 common/region.c
 delete mode 100644 common/region.h
 delete mode 100644 common/ring.h
 delete mode 100644 common/rop3.c
 delete mode 100644 common/rop3.h
 delete mode 100644 common/ssl_verify.c
 delete mode 100644 common/ssl_verify.h
 delete mode 100644 common/sw_canvas.c
 delete mode 100644 common/sw_canvas.h

diff --git a/.gitmodules b/.gitmodules
index f7de75d..6981ae4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "spice-protocol"]
 	path = spice-protocol
 	url = ../spice-protocol
+[submodule "common"]
+	path = common
+	url = ../spice-common
diff --git a/common b/common
new file mode 160000
index 0000000..0da9c0d
--- /dev/null
+++ b/common
@@ -0,0 +1 @@
+Subproject commit 0da9c0d6ac4d709e00dd92b744cdd9f1bd1ca7de
diff --git a/common/.gitignore b/common/.gitignore
deleted file mode 100644
index 07491dd..0000000
--- a/common/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.la
-*.lo
-*.loT
-*.o
-.deps
-.libs
-Makefile
-Makefile.in
diff --git a/common/Makefile.am b/common/Makefile.am
deleted file mode 100644
index 17e36a3..0000000
--- a/common/Makefile.am
+++ /dev/null
@@ -1,55 +0,0 @@
-NULL =
-
-COMMON_SRCS =				\
-	sw_canvas.h			\
-	sw_canvas.c			\
-	pixman_utils.h			\
-	pixman_utils.c			\
-	canvas_base.h			\
-	canvas_base.c			\
-	canvas_utils.h			\
-	canvas_utils.c			\
-	demarshallers.h			\
-	draw.h				\
-	gdi_canvas.h			\
-	gdi_canvas.c			\
-	gl_canvas.h			\
-	gl_canvas.c			\
-	glc.h				\
-	glc.c				\
-	gl_utils.h			\
-	lz_common.h			\
-	mutex.h				\
-	ogl_ctx.h			\
-	ogl_ctx.c			\
-	quic.h				\
-	quic.c				\
-	quic_config.h			\
-	rect.h				\
-	region.h			\
-	region.c			\
-	ring.h				\
-	rop3.h				\
-	rop3.c				\
-	lines.h				\
-	lines.c				\
-	lz.c				\
-	lz_compress_tmpl.c		\
-	lz_config.h			\
-	lz_decompress_tmpl.c		\
-	lz.h				\
-	marshaller.h			\
-	marshaller.c			\
-	marshallers.h			\
-	messages.h			\
-	mem.h				\
-	mem.c				\
-	quic_family_tmpl.c		\
-	quic_rgb_tmpl.c			\
-	quic_tmpl.c			\
-	ssl_verify.h			\
-	ssl_verify.c			\
-	$(NULL)
-
-EXTRA_DIST = $(COMMON_SRCS)
-
diff --git a/common/canvas_base.c b/common/canvas_base.c
deleted file mode 100644
index 46a0cdd..0000000
--- a/common/canvas_base.c
+++ /dev/null
@@ -1,3426 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <stdio.h>
-#include <math.h>
-
-#include <spice/macros.h>
-#include "quic.h"
-#include "lz.h"
-#include "canvas_base.h"
-#include "pixman_utils.h"
-#include "canvas_utils.h"
-#include "rect.h"
-#include "lines.h"
-#include "rop3.h"
-#include "mem.h"
-
-#include "mutex.h"
-
-#ifndef spice_return_if_fail
-#define spice_return_if_fail(x) if (!(x)) {                             \
-        fprintf(stderr, "(%s:%d) %s: condition %s failed\n", __FILE__, __LINE__, __FUNCTION__, #x); \
-        return;                                                         \
-}
-#endif
-
-#ifndef spice_return_val_if_fail
-#define spice_return_val_if_fail(x, val) if (!(x)) {                        \
-        fprintf(stderr, "(%s:%d) %s: condition %s failed\n", __FILE__, __LINE__, __FUNCTION__, #x); \
-        return (val);                                                   \
-}
-#endif
-
-#ifndef spice_warn_if_reached
-#define spice_warn_if_reached() do {                                    \
-        fprintf(stderr, "(%s:%d) %s: should not be reached", __FILE__, __LINE__, __FUNCTION__); \
-}while(0)
-#endif
-
-#ifndef spice_warning
-#define spice_warning(x) do {                                           \
-        fprintf(stderr, "(%s:%d) %s: warning %s", __FILE__, __LINE__, __FUNCTION__, (x)); \
-} while(0)
-#endif
-
-#ifndef spice_critical
-#define spice_critical(x) do {                                          \
-        fprintf(stderr, "(%s:%d) %s: CRITICAL %s", __FILE__, __LINE__, __FUNCTION__, (x)); \
-} while(0)
-#endif
-
-#define ROUND(_x) ((int)floor((_x) + 0.5))
-
-#define IS_IMAGE_LOSSY(descriptor)                         \
-    (((descriptor)->type == SPICE_IMAGE_TYPE_JPEG) ||      \
-    ((descriptor)->type == SPICE_IMAGE_TYPE_JPEG_ALPHA))
-
- static inline int fix_to_int(SPICE_FIXED28_4 fixed)
-{
-    int val, rem;
-
-    rem = fixed & 0x0f;
-    val = fixed >> 4;
-    if (rem > 8) {
-        val++;
-    }
-    return val;
-}
-
- static inline SPICE_FIXED28_4  int_to_fix(int v)
-{
-    return v << 4;
-}
-
-static inline double fix_to_double(SPICE_FIXED28_4 fixed)
-{
-    return (double)(fixed & 0x0f) / 0x0f + (fixed >> 4);
-}
-
-static inline uint16_t rgb_32_to_16_555(uint32_t color)
-{
-    return
-        (((color) >> 3) & 0x001f) |
-        (((color) >> 6) & 0x03e0) |
-        (((color) >> 9) & 0x7c00);
-}
-static inline uint16_t rgb_32_to_16_565(uint32_t color)
-{
-    return
-        (((color) >> 3) & 0x001f) |
-        (((color) >> 5) & 0x07e0) |
-        (((color) >> 8) & 0xf800);
-}
-
-static inline uint32_t canvas_16bpp_to_32bpp(uint32_t color)
-{
-    uint32_t ret;
-
-    ret = ((color & 0x001f) << 3) | ((color & 0x001c) >> 2);
-    ret |= ((color & 0x03e0) << 6) | ((color & 0x0380) << 1);
-    ret |= ((color & 0x7c00) << 9) | ((color & 0x7000) << 4);
-
-    return ret;
-}
-#if defined(WIN32) && defined(GDI_CANVAS)
-static HDC create_compatible_dc()
-{
-    HDC dc = CreateCompatibleDC(NULL);
-
-    spice_return_val_if_fail(dc != NULL, NULL);
-
-    return dc;
-}
-
-#endif
-
-typedef struct LzData {
-    LzUsrContext usr;
-    LzContext *lz;
-    LzDecodeUsrData decode_data;
-    jmp_buf jmp_env;
-    char message_buf[512];
-} LzData;
-
-typedef struct GlzData {
-    SpiceGlzDecoder *decoder;
-    LzDecodeUsrData decode_data;
-} GlzData;
-
-typedef struct QuicData {
-    QuicUsrContext usr;
-    QuicContext *quic;
-    jmp_buf jmp_env;
-    char message_buf[512];
-    SpiceChunks *chunks;
-    uint32_t current_chunk;
-} QuicData;
-
-typedef struct CanvasBase {
-    SpiceCanvas parent;
-    uint32_t color_shift;
-    uint32_t color_mask;
-    QuicData quic_data;
-
-    uint32_t format;
-    int width;
-    int height;
-    pixman_region32_t canvas_region;
-
-#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
-    SpiceImageCache *bits_cache;
-#endif
-#ifdef SW_CANVAS_CACHE
-    SpicePaletteCache *palette_cache;
-#endif
-#ifdef WIN32
-    HDC dc;
-#endif
-
-    SpiceImageSurfaces *surfaces;
-
-    LzData lz_data;
-    GlzData glz_data;
-    SpiceJpegDecoder* jpeg;
-    SpiceZlibDecoder* zlib;
-
-    void *usr_data;
-    spice_destroy_fn_t usr_data_destroy;
-} CanvasBase;
-
-typedef enum {
-    ROP_INPUT_SRC,
-    ROP_INPUT_BRUSH,
-    ROP_INPUT_DEST
-} ROPInput;
-
-static SpiceROP ropd_descriptor_to_rop(int desc,
-                                       ROPInput src_input,
-                                       ROPInput dest_input)
-{
-    int old;
-    int invert_masks[] = {
-        SPICE_ROPD_INVERS_SRC,
-        SPICE_ROPD_INVERS_BRUSH,
-        SPICE_ROPD_INVERS_DEST
-    };
-
-    old = desc;
-
-    desc &= ~(SPICE_ROPD_INVERS_SRC | SPICE_ROPD_INVERS_DEST);
-    if (old & invert_masks[src_input]) {
-        desc |= SPICE_ROPD_INVERS_SRC;
-    }
-
-    if (old & invert_masks[dest_input]) {
-        desc |= SPICE_ROPD_INVERS_DEST;
-    }
-
-    if (desc & SPICE_ROPD_OP_PUT) {
-        if (desc & SPICE_ROPD_INVERS_SRC) {
-            if (desc & SPICE_ROPD_INVERS_RES) {
-                return SPICE_ROP_COPY;
-            }
-            return SPICE_ROP_COPY_INVERTED;
-        } else {
-            if (desc & SPICE_ROPD_INVERS_RES) {
-                return SPICE_ROP_COPY_INVERTED;
-            }
-            return SPICE_ROP_COPY;
-        }
-    } else if (desc & SPICE_ROPD_OP_OR) {
-
-        if (desc & SPICE_ROPD_INVERS_RES) {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(!src or !dest) == src and dest*/
-                    return SPICE_ROP_AND;
-                } else {
-                    /* ! (!src or dest) = src and !dest*/
-                    return SPICE_ROP_AND_REVERSE;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(src or !dest) == !src and dest */
-                    return SPICE_ROP_AND_INVERTED;
-                } else {
-                    /* !(src or dest) */
-                    return SPICE_ROP_NOR;
-                }
-            }
-        } else {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !src or !dest == !(src and dest)*/
-                    return SPICE_ROP_NAND;
-                } else {
-                    /* !src or dest */
-                    return SPICE_ROP_OR_INVERTED;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* src or !dest */
-                    return SPICE_ROP_OR_REVERSE;
-                } else {
-                    /* src or dest */
-                    return SPICE_ROP_OR;
-                }
-            }
-        }
-
-    } else if (desc & SPICE_ROPD_OP_AND) {
-
-        if (desc & SPICE_ROPD_INVERS_RES) {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(!src and !dest) == src or dest*/
-                    return SPICE_ROP_OR;
-                } else {
-                    /* ! (!src and dest) = src or !dest*/
-                    return SPICE_ROP_OR_REVERSE;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(src and !dest) == !src or dest */
-                    return SPICE_ROP_OR_INVERTED;
-                } else {
-                    /* !(src and dest) */
-                    return SPICE_ROP_NAND;
-                }
-            }
-        } else {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !src and !dest == !(src or dest)*/
-                    return SPICE_ROP_NOR;
-                } else {
-                    /* !src and dest */
-                    return SPICE_ROP_AND_INVERTED;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* src and !dest */
-                    return SPICE_ROP_AND_REVERSE;
-                } else {
-                    /* src and dest */
-                    return SPICE_ROP_AND;
-                }
-            }
-        }
-
-    } else if (desc & SPICE_ROPD_OP_XOR) {
-
-        if (desc & SPICE_ROPD_INVERS_RES) {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(!src xor !dest) == !src xor dest */
-                    return SPICE_ROP_EQUIV;
-                } else {
-                    /* ! (!src xor dest) = src xor dest*/
-                    return SPICE_ROP_XOR;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !(src xor !dest) == src xor dest */
-                    return SPICE_ROP_XOR;
-                } else {
-                    /* !(src xor dest) */
-                    return SPICE_ROP_EQUIV;
-                }
-            }
-        } else {
-            if (desc & SPICE_ROPD_INVERS_SRC) {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* !src xor !dest == src xor dest */
-                    return SPICE_ROP_XOR;
-                } else {
-                    /* !src xor dest */
-                    return SPICE_ROP_EQUIV;
-                }
-            } else {
-                if (desc & SPICE_ROPD_INVERS_DEST) {
-                    /* src xor !dest */
-                    return SPICE_ROP_EQUIV;
-                } else {
-                    /* src xor dest */
-                    return SPICE_ROP_XOR;
-                }
-            }
-        }
-
-    } else if (desc & SPICE_ROPD_OP_BLACKNESS) {
-        return SPICE_ROP_CLEAR;
-    } else if (desc & SPICE_ROPD_OP_WHITENESS) {
-        return SPICE_ROP_SET;
-    } else if (desc & SPICE_ROPD_OP_INVERS) {
-        return SPICE_ROP_INVERT;
-    }
-    return SPICE_ROP_COPY;
-}
-
-//#define DEBUG_DUMP_COMPRESS
-#ifdef DEBUG_DUMP_COMPRESS
-static void dump_surface(pixman_image_t *surface, int cache);
-#endif
-
-
-static pixman_format_code_t canvas_get_target_format(CanvasBase *canvas,
-                                                     int source_has_alpha)
-{
-    pixman_format_code_t format;
-
-    /* Convert to target surface format */
-    format = spice_surface_format_to_pixman (canvas->format);
-
-    if (source_has_alpha) {
-        /* Even though the destination has no alpha, we make the source
-         * remember there are alpha bits instead of throwing away this
-         * information. The results are the same if alpha is not
-         * interpreted, and if need to interpret alpha, don't use
-         * conversion to target format.
-         * This is needed for instance when doing the final
-         * canvas_get_target_format() in canvas_get_image_internal
-         * as otherwise we wouldn't know if the bitmap source
-         * really had alpha.
-         */
-        if (format == PIXMAN_x8r8g8b8) {
-            format = PIXMAN_a8r8g8b8;
-        }
-    } else { /* !source_has_alpha */
-        /* If the source doesn't have alpha, but the destination has,
-           don't convert to alpha, since that would just do an unnecessary
-           copy to fill the alpha bytes with 0xff which is not expected if
-           we just use the raw bits, (and handled implicitly by pixman if
-           we're interpreting data) */
-        if (format == PIXMAN_a8r8g8b8) {
-            format = PIXMAN_x8r8g8b8;
-        }
-    }
-
-    return format;
-}
-
-static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceImage *image,
-                                       int invers, int want_original)
-{
-    pixman_image_t *surface = NULL;
-    QuicData *quic_data = &canvas->quic_data;
-    QuicImageType type, as_type;
-    pixman_format_code_t pixman_format;
-    uint8_t *dest;
-    int stride;
-    int width;
-    int height;
-
-    if (setjmp(quic_data->jmp_env)) {
-        pixman_image_unref(surface);
-        spice_warning(quic_data->message_buf);
-        return NULL;
-    }
-
-    quic_data->chunks = image->u.quic.data;
-    quic_data->current_chunk = 0;
-
-    if (quic_decode_begin(quic_data->quic,
-                          (uint32_t *)image->u.quic.data->chunk[0].data,
-                          image->u.quic.data->chunk[0].len >> 2,
-                          &type, &width, &height) == QUIC_ERROR) {
-        spice_warning("quic decode begin failed");
-        return NULL;
-    }
-
-    switch (type) {
-    case QUIC_IMAGE_TYPE_RGBA:
-        as_type = QUIC_IMAGE_TYPE_RGBA;
-        pixman_format = PIXMAN_a8r8g8b8;
-        break;
-    case QUIC_IMAGE_TYPE_RGB32:
-    case QUIC_IMAGE_TYPE_RGB24:
-        as_type = QUIC_IMAGE_TYPE_RGB32;
-        pixman_format = PIXMAN_x8r8g8b8;
-        break;
-    case QUIC_IMAGE_TYPE_RGB16:
-        if (!want_original &&
-            (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
-             canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
-            as_type = QUIC_IMAGE_TYPE_RGB32;
-            pixman_format = PIXMAN_x8r8g8b8;
-        } else {
-            as_type = QUIC_IMAGE_TYPE_RGB16;
-            pixman_format = PIXMAN_x1r5g5b5;
-        }
-        break;
-    case QUIC_IMAGE_TYPE_INVALID:
-    case QUIC_IMAGE_TYPE_GRAY:
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-    spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
-    spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
-
-    surface = surface_create(
-#ifdef WIN32
-                             canvas->dc,
-#endif
-                             pixman_format,
-                             width, height, FALSE);
-
-    spice_return_val_if_fail(surface != NULL, NULL);
-
-    dest = (uint8_t *)pixman_image_get_data(surface);
-    stride = pixman_image_get_stride(surface);
-    if (quic_decode(quic_data->quic, as_type,
-                    dest, stride) == QUIC_ERROR) {
-        pixman_image_unref(surface);
-        spice_warning("quic decode failed");
-        return NULL;
-    }
-
-    if (invers) {
-        uint8_t *end = dest + height * stride;
-        for (; dest != end; dest += stride) {
-            uint32_t *pix;
-            uint32_t *end_pix;
-
-            pix = (uint32_t *)dest;
-            end_pix = pix + width;
-            for (; pix < end_pix; pix++) {
-                *pix ^= 0xffffffff;
-            }
-        }
-    }
-
-#ifdef DEBUG_DUMP_COMPRESS
-    dump_surface(surface, 0);
-#endif
-    return surface;
-}
-
-
-//#define DUMP_JPEG
-#ifdef DUMP_JPEG
-static int jpeg_id = 0;
-static void dump_jpeg(uint8_t* data, int data_size)
-{
-    char file_str[200];
-    uint32_t id = ++jpeg_id;
-
-#ifdef WIN32
-    sprintf(file_str, "c:\\tmp\\spice_dump\\%u.jpg", id);
-#else
-    sprintf(file_str, "/tmp/spice_dump/%u.jpg", id);
-#endif
-
-    FILE *f = fopen(file_str, "wb");
-    if (!f) {
-        return;
-    }
-
-    fwrite(data, 1, data_size, f);
-    fclose(f);
-}
-#endif
-
-static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image, int invers)
-{
-    pixman_image_t *surface = NULL;
-    int stride;
-    int width;
-    int height;
-    uint8_t *dest;
-
-    spice_return_val_if_fail(image->u.jpeg.data->num_chunks == 1, NULL);
-    canvas->jpeg->ops->begin_decode(canvas->jpeg, image->u.jpeg.data->chunk[0].data, image->u.jpeg.data->chunk[0].len,
-                                    &width, &height);
-    spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
-    spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
-
-    surface = surface_create(
-#ifdef WIN32
-                             canvas->dc,
-#endif
-                             PIXMAN_x8r8g8b8,
-                             width, height, FALSE);
-    if (surface == NULL) {
-        spice_warning("create surface failed");
-        return NULL;
-    }
-
-    dest = (uint8_t *)pixman_image_get_data(surface);
-    stride = pixman_image_get_stride(surface);
-
-    canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
-
-    if (invers) {
-        uint8_t *end = dest + height * stride;
-        for (; dest != end; dest += stride) {
-            uint32_t *pix;
-            uint32_t *end_pix;
-
-            pix = (uint32_t *)dest;
-            end_pix = pix + width;
-            for (; pix < end_pix; pix++) {
-                *pix ^= 0x00ffffff;
-            }
-        }
-    }
-#ifdef DUMP_JPEG
-    dump_jpeg(image->u.jpeg.data, image->u.jpeg.data_size);
-#endif
-    return surface;
-}
-
-static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
-                                             SpiceImage *image, int invers)
-{
-    pixman_image_t *surface = NULL;
-    int stride;
-    int width;
-    int height;
-    uint8_t *dest;
-    int alpha_top_down = FALSE;
-    LzData *lz_data = &canvas->lz_data;
-    LzImageType lz_alpha_type;
-    uint8_t *comp_alpha_buf = NULL;
-    uint8_t *decomp_alpha_buf = NULL;
-    int alpha_size;
-    int lz_alpha_width, lz_alpha_height, n_comp_pixels, lz_alpha_top_down;
-
-    spice_return_val_if_fail(image->u.jpeg_alpha.data->num_chunks == 1, NULL);
-    canvas->jpeg->ops->begin_decode(canvas->jpeg,
-                                    image->u.jpeg_alpha.data->chunk[0].data,
-                                    image->u.jpeg_alpha.jpeg_size,
-                                    &width, &height);
-    spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
-    spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
-
-    if (image->u.jpeg_alpha.flags & SPICE_JPEG_ALPHA_FLAGS_TOP_DOWN) {
-        alpha_top_down = TRUE;
-    }
-
-#ifdef WIN32
-    lz_data->decode_data.dc = canvas->dc;
-#endif
-    surface = alloc_lz_image_surface(&lz_data->decode_data, PIXMAN_a8r8g8b8,
-                                     width, height, width*height, alpha_top_down);
-
-    if (surface == NULL) {
-        spice_warning("create surface failed");
-        return NULL;
-    }
-
-    dest = (uint8_t *)pixman_image_get_data(surface);
-    stride = pixman_image_get_stride(surface);
-
-    canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
-
-    comp_alpha_buf = image->u.jpeg_alpha.data->chunk[0].data + image->u.jpeg_alpha.jpeg_size;
-    alpha_size = image->u.jpeg_alpha.data_size - image->u.jpeg_alpha.jpeg_size;
-
-    lz_decode_begin(lz_data->lz, comp_alpha_buf, alpha_size, &lz_alpha_type,
-                    &lz_alpha_width, &lz_alpha_height, &n_comp_pixels,
-                    &lz_alpha_top_down, NULL);
-    spice_return_val_if_fail(lz_alpha_type == LZ_IMAGE_TYPE_XXXA, NULL);
-    spice_return_val_if_fail(!!lz_alpha_top_down == !!alpha_top_down, NULL);
-    spice_return_val_if_fail(lz_alpha_width == width, NULL);
-    spice_return_val_if_fail(lz_alpha_height == height, NULL);
-    spice_return_val_if_fail(n_comp_pixels == width * height, NULL);
-
-    if (!alpha_top_down) {
-        decomp_alpha_buf = dest + stride * (height - 1);
-    } else {
-        decomp_alpha_buf = dest;
-    }
-    lz_decode(lz_data->lz, LZ_IMAGE_TYPE_XXXA, decomp_alpha_buf);
-    
-    if (invers) {
-        uint8_t *end = dest + height * stride;
-        for (; dest != end; dest += stride) {
-            uint32_t *pix;
-            uint32_t *end_pix;
-
-            pix = (uint32_t *)dest;
-            end_pix = pix + width;
-            for (; pix < end_pix; pix++) {
-                *pix ^= 0x00ffffff;
-            }
-        }
-    }
-#ifdef DUMP_JPEG
-    dump_jpeg(image->u.jpeg_alpha.data, image->u.jpeg_alpha.jpeg_size);
-#endif
-    return surface;
-}
-
-static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
-                                                SpicePalette *palette, int want_original)
-{
-    uint8_t* src;
-    pixman_image_t *image;
-    pixman_format_code_t format;
-
-    spice_chunks_linearize(bitmap->data);
-
-    src = bitmap->data->chunk[0].data;
-
-    if (want_original) {
-        format = spice_bitmap_format_to_pixman(bitmap->format, canvas->format);
-    } else {
-        format = canvas_get_target_format(canvas,
-                                          bitmap->format == SPICE_BITMAP_FMT_RGBA);
-    }
-
-    image = surface_create(
-#ifdef WIN32
-                           canvas->dc,
-#endif
-                           format,
-                           bitmap->x, bitmap->y, FALSE);
-    if (image == NULL) {
-        spice_warning("create surface failed");
-        return NULL;
-    }
-
-    spice_bitmap_convert_to_pixman(format, image,
-                                   bitmap->format,
-                                   bitmap->flags,
-                                   bitmap->x, bitmap->y,
-                                   src, bitmap->stride,
-                                   canvas->format, palette);
-    return image;
-}
-
-
-#ifdef SW_CANVAS_CACHE
-
-static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags)
-{
-    SpicePalette *palette;
-
-    if (flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE) {
-        palette = canvas->palette_cache->ops->get(canvas->palette_cache, palette_id);
-    } else {
-        palette = base_palette;
-        if (palette != NULL && flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
-            canvas->palette_cache->ops->put(canvas->palette_cache, palette);
-        }
-    }
-    return palette;
-}
-
-static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags, int *free_palette)
-{
-    SpicePalette *palette = canvas_get_palette(canvas, base_palette, palette_id, flags);
-    SpicePalette *copy;
-    uint32_t *now, *end;
-    size_t size;
-
-    if (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
-        canvas->format == SPICE_SURFACE_FMT_32_ARGB) {
-        return palette;
-    }
-
-    size = sizeof(SpicePalette) + palette->num_ents * 4;
-    copy = (SpicePalette *)spice_malloc(size);
-    memcpy(copy, palette, size);
-
-    switch (canvas->format) {
-    case SPICE_SURFACE_FMT_32_xRGB:
-    case SPICE_SURFACE_FMT_32_ARGB:
-        /* Won't happen */
-        break;
-    case SPICE_SURFACE_FMT_16_555:
-        now = copy->ents;
-        end = now + copy->num_ents;
-        for (; now < end; now++) {
-            *now = canvas_16bpp_to_32bpp(*now);
-        }
-        break;
-    case SPICE_SURFACE_FMT_16_565:
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-    *free_palette = TRUE;
-    return copy;
-}
-
-static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, int invers,
-                                     int want_original)
-{
-    LzData *lz_data = &canvas->lz_data;
-    uint8_t *comp_buf = NULL;
-    int comp_size;
-    uint8_t    *decomp_buf = NULL;
-    uint8_t    *src;
-    pixman_format_code_t pixman_format;
-    LzImageType type, as_type;
-    SpicePalette *palette;
-    int n_comp_pixels;
-    int width;
-    int height;
-    int top_down;
-    int stride;
-    int free_palette;
-
-    if (setjmp(lz_data->jmp_env)) {
-        if (decomp_buf) {
-            free(decomp_buf);
-        }
-        spice_warning(lz_data->message_buf);
-        return NULL;
-    }
-
-    free_palette = FALSE;
-    if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB) {
-        spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
-        comp_buf = image->u.lz_rgb.data->chunk[0].data;
-        comp_size = image->u.lz_rgb.data->chunk[0].len;
-        palette = NULL;
-    } else if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
-        spice_return_val_if_fail(image->u.lz_plt.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
-        comp_buf = image->u.lz_plt.data->chunk[0].data;
-        comp_size = image->u.lz_plt.data->chunk[0].len;
-        palette = canvas_get_localized_palette(canvas, image->u.lz_plt.palette, image->u.lz_plt.palette_id, image->u.lz_plt.flags, &free_palette);
-    } else {
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-    lz_decode_begin(lz_data->lz, comp_buf, comp_size, &type,
-                    &width, &height, &n_comp_pixels, &top_down, palette);
-
-    switch (type) {
-    case LZ_IMAGE_TYPE_RGBA:
-        as_type = LZ_IMAGE_TYPE_RGBA;
-        pixman_format = PIXMAN_a8r8g8b8;
-        break;
-    case LZ_IMAGE_TYPE_RGB32:
-    case LZ_IMAGE_TYPE_RGB24:
-    case LZ_IMAGE_TYPE_PLT1_LE:
-    case LZ_IMAGE_TYPE_PLT1_BE:
-    case LZ_IMAGE_TYPE_PLT4_LE:
-    case LZ_IMAGE_TYPE_PLT4_BE:
-    case LZ_IMAGE_TYPE_PLT8:
-        as_type = LZ_IMAGE_TYPE_RGB32;
-        pixman_format = PIXMAN_x8r8g8b8;
-        break;
-    case LZ_IMAGE_TYPE_RGB16:
-        if (!want_original &&
-            (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
-             canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
-            as_type = LZ_IMAGE_TYPE_RGB32;
-            pixman_format = PIXMAN_x8r8g8b8;
-        } else {
-            as_type = LZ_IMAGE_TYPE_RGB16;
-            pixman_format = PIXMAN_x1r5g5b5;
-        }
-        break;
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-    spice_return_val_if_fail((unsigned)width == image->descriptor.width, NULL);
-    spice_return_val_if_fail((unsigned)height == image->descriptor.height, NULL);
-
-    spice_return_val_if_fail((image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) || (n_comp_pixels == width * height), NULL);
-#ifdef WIN32
-    lz_data->decode_data.dc = canvas->dc;
-#endif
-
-
-    alloc_lz_image_surface(&lz_data->decode_data, pixman_format,
-                           width, height, n_comp_pixels, top_down);
-
-    src = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface);
-
-    stride = (n_comp_pixels / height) * 4;
-    if (!top_down) {
-        stride = -stride;
-        decomp_buf = src + stride * (height - 1);
-    } else {
-        decomp_buf = src;
-    }
-
-    lz_decode(lz_data->lz, as_type, decomp_buf);
-
-    if (invers) {
-        uint8_t *line = src;
-        uint8_t *end = src + height * stride;
-        for (; line != end; line += stride) {
-            uint32_t *pix;
-            uint32_t *end_pix;
-
-            pix = (uint32_t *)line;
-            end_pix = pix + width;
-            for (; pix < end_pix; pix++) {
-                *pix ^= 0xffffffff;
-            }
-        }
-    }
-
-    if (free_palette)  {
-        free(palette);
-    }
-
-    return lz_data->decode_data.out_surface;
-}
-
-static pixman_image_t *canvas_get_glz_rgb_common(CanvasBase *canvas, uint8_t *data,
-                                                 int want_original)
-{
-    spice_return_val_if_fail(canvas->glz_data.decoder != NULL, NULL);
-
-    canvas->glz_data.decoder->ops->decode(canvas->glz_data.decoder,
-                                          data, NULL,
-                                          &canvas->glz_data.decode_data);
-
-    /* global_decode calls alloc_lz_image, which sets canvas->glz_data.surface */
-    return (canvas->glz_data.decode_data.out_surface);
-}
-
-// don't handle plts since bitmaps with plt can be decoded globally to RGB32 (because
-// same byte sequence can be transformed to different RGB pixels by different plts)
-static pixman_image_t *canvas_get_glz(CanvasBase *canvas, SpiceImage *image,
-                                      int want_original)
-{
-    spice_return_val_if_fail(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB, NULL);
-#ifdef WIN32
-    canvas->glz_data.decode_data.dc = canvas->dc;
-#endif
-
-    spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
-    return canvas_get_glz_rgb_common(canvas, image->u.lz_rgb.data->chunk[0].data, want_original);
-}
-
-static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceImage *image,
-                                               int want_original)
-{
-    uint8_t *glz_data;
-    pixman_image_t *surface;
-
-    spice_return_val_if_fail(canvas->zlib != NULL, NULL);
-
-    spice_return_val_if_fail(image->u.zlib_glz.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
-    glz_data = (uint8_t*)spice_malloc(image->u.zlib_glz.glz_data_size);
-    canvas->zlib->ops->decode(canvas->zlib, image->u.zlib_glz.data->chunk[0].data,
-                              image->u.zlib_glz.data->chunk[0].len,
-                              glz_data, image->u.zlib_glz.glz_data_size);
-    surface = canvas_get_glz_rgb_common(canvas, glz_data, want_original);
-    free(glz_data);
-    return surface;
-}
-
-//#define DEBUG_DUMP_BITMAP
-
-#ifdef DEBUG_DUMP_BITMAP
-static void dump_bitmap(SpiceBitmap *bitmap, SpicePalette *palette)
-{
-    uint8_t* data = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
-    static uint32_t file_id = 0;
-    uint32_t i, j;
-    char file_str[200];
-    uint32_t id = ++file_id;
-
-#ifdef WIN32
-    sprintf(file_str, "c:\\tmp\\spice_dump\\%u.%ubpp", id, bitmap->format);
-#else
-    sprintf(file_str, "/tmp/spice_dump/%u.%ubpp", id, bitmap->format);
-#endif
-    FILE *f = fopen(file_str, "wb");
-    if (!f) {
-        return;
-    }
-
-    fprintf(f, "%d\n", bitmap->format);                          // 1_LE,1_BE,....
-    fprintf(f, "%d %d\n", bitmap->x, bitmap->y);     // width and height
-    fprintf(f, "%d\n", palette->num_ents);               // #plt entries
-    for (i = 0; i < palette->num_ents; i++) {
-        fwrite(&(palette->ents[i]), 4, 1, f);
-    }
-    fprintf(f, "\n");
-
-    for (i = 0; i < bitmap->y; i++, data += bitmap->stride) {
-        uint8_t *now = data;
-        for (j = 0; j < bitmap->x; j++) {
-            fwrite(now, 1, 1, f);
-            now++;
-        }
-    }
-}
-
-#endif
-
-static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
-                                       int want_original)
-{
-    pixman_image_t* surface;
-    SpicePalette *palette;
-
-    palette = canvas_get_palette(canvas, bitmap->palette, bitmap->palette_id, bitmap->flags);
-#ifdef DEBUG_DUMP_BITMAP
-    if (palette) {
-        dump_bitmap(bitmap, palette);
-    }
-#endif
-
-    surface = canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
-
-    if (palette && (bitmap->flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
-        canvas->palette_cache->ops->release(canvas->palette_cache, palette);
-    }
-
-    return surface;
-}
-
-#else
-
-
-static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
-                                       int want_original)
-{
-    SpicePalette *palette;
-
-    if (!bitmap->palette) {
-        return canvas_bitmap_to_surface(canvas, bitmap, NULL, want_original);
-    }
-    palette = (SpicePalette *)SPICE_GET_ADDRESS(bitmap->palette);
-    return canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
-}
-
-#endif
-
-
-
-// caution: defining DEBUG_DUMP_SURFACE will dump both cached & non-cached
-//          images to disk. it will reduce performance dramatically & eat
-//          disk space rapidly. use it only for debugging.
-//#define DEBUG_DUMP_SURFACE
-
-#if defined(DEBUG_DUMP_SURFACE) || defined(DEBUG_DUMP_COMPRESS)
-
-static void dump_surface(pixman_image_t *surface, int cache)
-{
-    static uint32_t file_id = 0;
-    int i, j;
-    char file_str[200];
-    int depth = pixman_image_get_depth(surface);
-
-    if (depth != 24 && depth != 32) {
-        return;
-    }
-
-    uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
-    int width = pixman_image_get_width(surface);
-    int height = pixman_image_get_height(surface);
-    int stride = pixman_image_surface_get_stride(surface);
-
-    uint32_t id = ++file_id;
-#ifdef WIN32
-    sprintf(file_str, "c:\\tmp\\spice_dump\\%d\\%u.ppm", cache, id);
-#else
-    sprintf(file_str, "/tmp/spice_dump/%u.ppm", id);
-#endif
-    FILE *f = fopen(file_str, "wb");
-    if (!f) {
-        return;
-    }
-    fprintf(f, "P6\n");
-    fprintf(f, "%d %d\n", width, height);
-    fprintf(f, "#spicec dump\n");
-    fprintf(f, "255\n");
-    for (i = 0; i < height; i++, data += stride) {
-        uint8_t *now = data;
-        for (j = 0; j < width; j++) {
-            fwrite(&now[2], 1, 1, f);
-            fwrite(&now[1], 1, 1, f);
-            fwrite(&now[0], 1, 1, f);
-            now += 4;
-        }
-    }
-    fclose(f);
-}
-
-#endif
-
-static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SpiceImage *image)
-{
-    if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
-        SpiceSurface *surface = &image->u.surface;
-        return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
-    }
-    return NULL;
-}
-
-static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SpiceImage *image)
-{
-    if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
-        SpiceSurface *surface = &image->u.surface;
-        return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
-    }
-    return NULL;
-}
-
-#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
-
-//#define DEBUG_LZ
-
-/* If real get is FALSE, then only do whatever is needed but don't return an image. For instance,
- *  if we need to read it to cache it we do.
- *
- * This generally converts the image to the right type for the canvas.
- * However, if want_original is set the real source format is returned, and
- * you have to be able to handle any image format. This is useful to avoid
- * e.g. losing alpha when blending a argb32 image on a rgb16 surface.
- */
-static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
-                                                 int want_original, int real_get)
-{
-    SpiceImageDescriptor *descriptor = &image->descriptor;
-    pixman_image_t *surface, *converted;
-    pixman_format_code_t wanted_format, surface_format;
-    int saved_want_original;
-
-    /* When touching, only really allocate if we need to cache, or
-     * if we're loading a GLZ stream (since those need inter-thread communication
-     * to happen which breaks if we don't. */
-    if (!real_get &&
-        !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME) &&
-#ifdef SW_CANVAS_CACHE
-        !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) &&
-#endif
-        (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB) &&
-        (descriptor->type != SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB)) {
-        return NULL;
-    }
-
-    saved_want_original = want_original;
-    if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME
-#ifdef SW_CANVAS_CACHE
-        || descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME
-#endif
-       ) {
-        want_original = TRUE;
-    }
-
-    switch (descriptor->type) {
-    case SPICE_IMAGE_TYPE_QUIC: {
-        surface = canvas_get_quic(canvas, image, 0, want_original);
-        break;
-    }
-#if defined(SW_CANVAS_CACHE)
-    case SPICE_IMAGE_TYPE_LZ_PLT: {
-        surface = canvas_get_lz(canvas, image, 0, want_original);
-        break;
-    }
-    case SPICE_IMAGE_TYPE_LZ_RGB: {
-        surface = canvas_get_lz(canvas, image, 0, want_original);
-        break;
-    }
-#endif
-    case SPICE_IMAGE_TYPE_JPEG: {
-        surface = canvas_get_jpeg(canvas, image, 0);
-        break;
-    }
-    case SPICE_IMAGE_TYPE_JPEG_ALPHA: {
-        surface = canvas_get_jpeg_alpha(canvas, image, 0);
-        break;
-    }
-#if defined(SW_CANVAS_CACHE)
-    case SPICE_IMAGE_TYPE_GLZ_RGB: {
-        surface = canvas_get_glz(canvas, image, want_original);
-        break;
-    }
-    case SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB: {
-        surface = canvas_get_zlib_glz_rgb(canvas, image, want_original);
-        break;
-    }
-#endif
-    case SPICE_IMAGE_TYPE_FROM_CACHE:
-        surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id);
-        break;
-#ifdef SW_CANVAS_CACHE
-    case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
-        surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id);
-        break;
-#endif
-    case SPICE_IMAGE_TYPE_BITMAP: {
-        surface = canvas_get_bits(canvas, &image->u.bitmap, want_original);
-        break;
-    }
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-    spice_return_val_if_fail(surface != NULL, NULL);
-    surface_format = spice_pixman_image_get_format(surface);
-
-    if (descriptor->flags & SPICE_IMAGE_FLAGS_HIGH_BITS_SET &&
-        descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE &&
-#ifdef SW_CANVAS_CACHE
-        descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS &&
-#endif
-        surface_format == PIXMAN_x8r8g8b8) {
-        spice_pixman_fill_rect_rop(surface,
-                                   0, 0,
-                                   pixman_image_get_width(surface),
-                                   pixman_image_get_height(surface),
-                                   0xff000000U, SPICE_ROP_OR);
-    }
-
-    if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME &&
-#ifdef SW_CANVAS_CACHE
-        descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS &&
-#endif
-        descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE ) {
-#ifdef SW_CANVAS_CACHE
-        if (!IS_IMAGE_LOSSY(descriptor)) {
-            canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
-        } else {
-            canvas->bits_cache->ops->put_lossy(canvas->bits_cache, descriptor->id, surface);
-        }
-#else
-        canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
-#endif
-#ifdef DEBUG_DUMP_SURFACE
-        dump_surface(surface, 1);
-#endif
-#ifdef SW_CANVAS_CACHE
-    } else if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) {
-        if (IS_IMAGE_LOSSY(descriptor)) {
-            spice_warning("invalid cache replace request: the image is lossy");
-            return NULL;
-        }
-        canvas->bits_cache->ops->replace_lossy(canvas->bits_cache, descriptor->id, surface);
-#ifdef DEBUG_DUMP_SURFACE
-        dump_surface(surface, 1);
-#endif
-#endif
-#ifdef DEBUG_DUMP_SURFACE
-    } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE
-#ifdef SW_CANVAS_CACHE
-               && descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS
-#endif
-    ) {
-
-        dump_surface(surface, 0);
-#endif
-    }
-
-    if (!real_get) {
-        pixman_image_unref(surface);
-        return NULL;
-    }
-
-    if (!saved_want_original) {
-        /* Conversion to canvas format was requested, but maybe it didn't
-           happen above (due to save/load to cache for instance, or
-           maybe the reader didn't support conversion).
-           If so we convert here. */
-
-        wanted_format = canvas_get_target_format(canvas,
-                                                 surface_format == PIXMAN_a8r8g8b8);
-
-        if (surface_format != wanted_format) {
-            converted = surface_create(
-#ifdef WIN32
-                                       canvas->dc,
-#endif
-                                       wanted_format,
-                                       pixman_image_get_width(surface),
-                                       pixman_image_get_height(surface),
-                                       TRUE);
-            pixman_image_composite32 (PIXMAN_OP_SRC,
-                                      surface, NULL, converted,
-                                      0, 0,
-                                      0, 0,
-                                      0, 0,
-                                      pixman_image_get_width(surface),
-                                      pixman_image_get_height(surface));
-            pixman_image_unref (surface);
-            surface = converted;
-        }
-    }
-
-    return surface;
-}
-
-#else
-
-static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
-                                                 int want_original, int real_get)
-{
-    SpiceImageDescriptor *descriptor = &image->descriptor;
-    pixman_format_code_t format;
-
-    /* When touching, never load image. */
-    if (!real_get) {
-        return NULL;
-    }
-
-    switch (descriptor->type) {
-    case SPICE_IMAGE_TYPE_QUIC: {
-        return canvas_get_quic(canvas, image, 0);
-    }
-    case SPICE_IMAGE_TYPE_BITMAP: {
-        return canvas_get_bits(canvas, &image->u.bitmap, want_original, &format);
-    }
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-    return NULL;
-}
-
-#endif
-
-static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SpiceImage *image)
-{
-    return canvas_get_surface_mask_internal(canvas, image);
-}
-
-static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SpiceImage *image)
-{
-    return canvas_get_surface_internal(canvas, image);
-}
-
-static pixman_image_t *canvas_get_image(CanvasBase *canvas, SpiceImage *image,
-                                        int want_original)
-{
-    return canvas_get_image_internal(canvas, image, want_original, TRUE);
-}
-
-static void canvas_touch_image(CanvasBase *canvas, SpiceImage *image)
-{
-    canvas_get_image_internal(canvas, image, TRUE, FALSE);
-}
-
-static pixman_image_t* canvas_get_image_from_self(SpiceCanvas *canvas,
-                                                  int x, int y,
-                                                  int32_t width, int32_t height)
-{
-    CanvasBase *canvas_base = (CanvasBase *)canvas;
-    pixman_image_t *surface;
-    uint8_t *dest;
-    int dest_stride;
-    SpiceRect area;
-
-    surface = pixman_image_create_bits(spice_surface_format_to_pixman (canvas_base->format),
-                                       width, height, NULL, 0);
-    spice_return_val_if_fail(surface != NULL, NULL);
-
-    dest = (uint8_t *)pixman_image_get_data(surface);
-    dest_stride = pixman_image_get_stride(surface);
-
-    area.left = x;
-    area.top = y;
-    area.right = x + width;
-    area.bottom = y + height;
-
-    canvas->ops->read_bits(canvas, dest, dest_stride, &area);
-
-    return surface;
-}
-
-static inline uint8_t revers_bits(uint8_t byte)
-{
-    uint8_t ret = 0;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        int shift = 7 - i * 2;
-        ret |= (byte & (1 << i)) << shift;
-        ret |= (byte & (0x80 >> i)) >> shift;
-    }
-    return ret;
-}
-
-static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
-{
-    pixman_image_t *surface;
-    uint8_t *src_line;
-    uint8_t *end_line;
-    uint8_t *dest_line;
-    int src_stride;
-    int line_size;
-    int dest_stride;
-
-    surface = surface_create(
-#ifdef WIN32
-            canvas->dc,
-#endif
-            PIXMAN_a1, bitmap->x, bitmap->y, TRUE);
-    spice_return_val_if_fail(surface != NULL, NULL);
-
-    spice_chunks_linearize(bitmap->data);
-    src_line = bitmap->data->chunk[0].data;
-    src_stride = bitmap->stride;
-    end_line = src_line + (bitmap->y * src_stride);
-    line_size = SPICE_ALIGN(bitmap->x, 8) >> 3;
-
-    dest_stride = pixman_image_get_stride(surface);
-    dest_line = (uint8_t *)pixman_image_get_data(surface);
-#if defined(GL_CANVAS)
-    if ((bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
-#else
-    if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
-#endif
-        spice_return_val_if_fail(bitmap->y > 0, NULL);
-        dest_line += dest_stride * ((int)bitmap->y - 1);
-        dest_stride = -dest_stride;
-    }
-
-    if (invers) {
-        switch (bitmap->format) {
-#if defined(GL_CANVAS) || defined(GDI_CANVAS)
-        case SPICE_BITMAP_FMT_1BIT_BE:
-#else
-        case SPICE_BITMAP_FMT_1BIT_LE:
-#endif
-            for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
-                uint8_t *dest = dest_line;
-                uint8_t *now = src_line;
-                uint8_t *end = now + line_size;
-                while (now < end) {
-                    *(dest++) = ~*(now++);
-                }
-            }
-            break;
-#if defined(GL_CANVAS) || defined(GDI_CANVAS)
-        case SPICE_BITMAP_FMT_1BIT_LE:
-#else
-        case SPICE_BITMAP_FMT_1BIT_BE:
-#endif
-            for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
-                uint8_t *dest = dest_line;
-                uint8_t *now = src_line;
-                uint8_t *end = now + line_size;
-
-                while (now < end) {
-                    *(dest++) = ~revers_bits(*(now++));
-                }
-            }
-            break;
-        default:
-            pixman_image_unref(surface);
-            surface = NULL;
-            spice_warn_if_reached();
-            return NULL;
-        }
-    } else {
-        switch (bitmap->format) {
-#if defined(GL_CANVAS) || defined(GDI_CANVAS)
-        case SPICE_BITMAP_FMT_1BIT_BE:
-#else
-        case SPICE_BITMAP_FMT_1BIT_LE:
-#endif
-            for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
-                memcpy(dest_line, src_line, line_size);
-            }
-            break;
-#if defined(GL_CANVAS) || defined(GDI_CANVAS)
-        case SPICE_BITMAP_FMT_1BIT_LE:
-#else
-        case SPICE_BITMAP_FMT_1BIT_BE:
-#endif
-            for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
-                uint8_t *dest = dest_line;
-                uint8_t *now = src_line;
-                uint8_t *end = now + line_size;
-
-                while (now < end) {
-                    *(dest++) = revers_bits(*(now++));
-                }
-            }
-            break;
-        default:
-            pixman_image_unref(surface);
-            surface = NULL;
-            spice_warn_if_reached();
-            return NULL;
-        }
-    }
-    return surface;
-}
-
-static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
-{
-    int width = pixman_image_get_width(src_surf);
-    int height = pixman_image_get_height(src_surf);
-    pixman_image_t * invers;
-    uint8_t *src_line, *end_line,  *dest_line;
-    int src_stride, line_size, dest_stride;
-
-    spice_return_val_if_fail(pixman_image_get_depth(src_surf) == 1, NULL);
-
-    invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
-    spice_return_val_if_fail(invers != NULL, NULL);
-
-    src_line = (uint8_t *)pixman_image_get_data(src_surf);
-    src_stride = pixman_image_get_stride(src_surf);
-    end_line = src_line + (height * src_stride);
-    line_size = SPICE_ALIGN(width, 8) >> 3;
-    dest_line = (uint8_t *)pixman_image_get_data(invers);
-    dest_stride = pixman_image_get_stride(invers);
-
-    for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
-        uint8_t *dest = dest_line;
-        uint8_t *now = src_line;
-        uint8_t *end = now + line_size;
-        while (now < end) {
-            *(dest++) = ~*(now++);
-        }
-    }
-    return invers;
-}
-
-static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int *needs_invert_out)
-{
-    SpiceImage *image;
-    pixman_image_t *surface;
-    int need_invers;
-    int is_invers;
-    int cache_me;
-
-    if (needs_invert_out) {
-        *needs_invert_out = 0;
-    }
-
-    image = mask->bitmap;
-    need_invers = mask->flags & SPICE_MASK_FLAGS_INVERS;
-
-#ifdef SW_CANVAS_CACHE
-    cache_me = image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME;
-#else
-    cache_me = 0;
-#endif
-
-    switch (image->descriptor.type) {
-    case SPICE_IMAGE_TYPE_BITMAP: {
-        is_invers = need_invers && !cache_me;
-        surface = canvas_get_bitmap_mask(canvas, &image->u.bitmap, is_invers);
-        break;
-    }
-#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
-    case SPICE_IMAGE_TYPE_FROM_CACHE:
-        surface = canvas->bits_cache->ops->get(canvas->bits_cache, image->descriptor.id);
-        is_invers = 0;
-        break;
-#endif
-#ifdef SW_CANVAS_CACHE
-    case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
-        surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, image->descriptor.id);
-        is_invers = 0;
-        break;
-#endif
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-
-#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
-    if (cache_me) {
-        canvas->bits_cache->ops->put(canvas->bits_cache, image->descriptor.id, surface);
-    }
-
-    if (need_invers && !is_invers) { // surface is in cache
-        if (needs_invert_out != NULL) {
-            *needs_invert_out = TRUE;
-        } else {
-            pixman_image_t *inv_surf;
-            inv_surf = canvas_A1_invers(surface);
-            pixman_image_unref(surface);
-            surface = inv_surf;
-        }
-    }
-#endif
-    return surface;
-}
-
-static inline void canvas_raster_glyph_box(const SpiceRasterGlyph *glyph, SpiceRect *r)
-{
-    spice_return_if_fail(r != NULL);
-
-    r->top = glyph->render_pos.y + glyph->glyph_origin.y;
-    r->bottom = r->top + glyph->height;
-    r->left = glyph->render_pos.x + glyph->glyph_origin.x;
-    r->right = r->left + glyph->width;
-}
-
-#ifdef GL_CANVAS
-static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
-{
-    uint8_t mask;
-    int now;
-
-    dest = dest + (offset >> 3);
-    offset &= 0x07;
-    now = MIN(8 - offset, n);
-
-    mask = ~((1 << (8 - now)) - 1);
-    mask >>= offset;
-    *dest = ((val >> offset) & mask) | *dest;
-
-    if ((n = n - now)) {
-        mask = ~((1 << (8 - n)) - 1);
-        dest++;
-        *dest = ((val << now) & mask) | *dest;
-    }
-}
-
-#else
-static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
-{
-    uint8_t mask;
-    int now;
-
-    dest = dest + (offset >> 3);
-    offset &= 0x07;
-
-    now = MIN(8 - offset, n);
-
-    mask = (1 << now) - 1;
-    mask <<= offset;
-    val = revers_bits(val);
-    *dest = ((val << offset) & mask) | *dest;
-
-    if ((n = n - now)) {
-        mask = (1 << n) - 1;
-        dest++;
-        *dest = ((val >> now) & mask) | *dest;
-    }
-}
-
-#endif
-
-static inline void canvas_put_bits(uint8_t *dest, int dest_offset, uint8_t *src, int n)
-{
-    while (n) {
-        int now = MIN(n, 8);
-
-        n -= now;
-        __canvas_put_bits(dest, dest_offset, *src, now);
-        dest_offset += now;
-        src++;
-    }
-}
-
-static void canvas_put_glyph_bits(SpiceRasterGlyph *glyph, int bpp, uint8_t *dest, int dest_stride,
-                                  SpiceRect *bounds)
-{
-    SpiceRect glyph_box;
-    uint8_t *src;
-    int lines;
-    int width;
-
-    //todo: support SPICE_STRING_FLAGS_RASTER_TOP_DOWN
-    canvas_raster_glyph_box(glyph, &glyph_box);
-    spice_return_if_fail(glyph_box.top >= bounds->top && glyph_box.bottom <= bounds->bottom);
-    spice_return_if_fail(glyph_box.left >= bounds->left && glyph_box.right <= bounds->right);
-    rect_offset(&glyph_box, -bounds->left, -bounds->top);
-
-    dest += glyph_box.top * dest_stride;
-    src = glyph->data;
-    lines = glyph_box.bottom - glyph_box.top;
-    width = glyph_box.right - glyph_box.left;
-    switch (bpp) {
-    case 1: {
-        int src_stride = SPICE_ALIGN(width, 8) >> 3;
-        int i;
-
-        src += src_stride * (lines);
-        for (i = 0; i < lines; i++) {
-            src -= src_stride;
-            canvas_put_bits(dest, glyph_box.left, src, width);
-            dest += dest_stride;
-        }
-        break;
-    }
-    case 4: {
-        uint8_t *end;
-        int src_stride = SPICE_ALIGN(width * 4, 8) >> 3;
-
-        src += src_stride * lines;
-        dest += glyph_box.left;
-        end = dest + dest_stride * lines;
-        for (; dest != end; dest += dest_stride) {
-            int i = 0;
-            uint8_t *now;
-
-            src -= src_stride;
-            now = src;
-            while (i < (width & ~1)) {
-                dest[i] = MAX(dest[i], *now & 0xf0);
-                dest[i + 1] = MAX(dest[i + 1], *now << 4);
-                i += 2;
-                now++;
-            }
-            if (i < width) {
-                dest[i] = MAX(dest[i], *now & 0xf0);
-                now++;
-            }
-        }
-        break;
-    }
-    case 8: {
-        uint8_t *end;
-        src += width * lines;
-        dest += glyph_box.left;
-        end = dest + dest_stride * lines;
-        for (; dest != end; dest += dest_stride, src -= width) {
-            int i;
-
-            for (i = 0; i < width; i++) {
-                dest[i] = MAX(dest[i], src[i]);
-            }
-        }
-        break;
-    }
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
-{
-    SpiceRasterGlyph *glyph;
-    SpiceRect bounds;
-    pixman_image_t *str_mask;
-    uint8_t *dest;
-    int dest_stride;
-    int i;
-
-    spice_return_val_if_fail(str->length > 0, NULL);
-
-    glyph = str->glyphs[0];
-    canvas_raster_glyph_box(glyph, &bounds);
-
-    for (i = 1; i < str->length; i++) {
-        SpiceRect glyph_box;
-
-        canvas_raster_glyph_box(str->glyphs[i], &glyph_box);
-        rect_union(&bounds, &glyph_box);
-    }
-
-    str_mask = pixman_image_create_bits((bpp == 1) ? PIXMAN_a1 : PIXMAN_a8,
-                                        bounds.right - bounds.left,
-                                        bounds.bottom - bounds.top, NULL, 0);
-    spice_return_val_if_fail(str_mask != NULL, NULL);
-
-    dest = (uint8_t *)pixman_image_get_data(str_mask);
-    dest_stride = pixman_image_get_stride(str_mask);
-    for (i = 0; i < str->length; i++) {
-        glyph = str->glyphs[i];
-#if defined(GL_CANVAS)
-        canvas_put_glyph_bits(glyph, bpp, dest + (bounds.bottom - bounds.top - 1) * dest_stride,
-                              -dest_stride, &bounds);
-#else
-        canvas_put_glyph_bits(glyph, bpp, dest, dest_stride, &bounds);
-#endif
-    }
-
-    pos->x = bounds.left;
-    pos->y = bounds.top;
-    return str_mask;
-}
-
-static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect *src_area, int width,
-                                            int height, int scale_mode)
-{
-    pixman_image_t *surface;
-    pixman_transform_t transform;
-    double sx, sy;
-
-    surface = pixman_image_create_bits(spice_pixman_image_get_format (src),
-                                       width, height, NULL, 0);
-    spice_return_val_if_fail(surface != NULL, NULL);
-
-    sx = (double)(src_area->right - src_area->left) / width;
-    sy = (double)(src_area->bottom - src_area->top) / height;
-
-    pixman_transform_init_scale(&transform, pixman_double_to_fixed(sx), pixman_double_to_fixed(sy));
-
-    pixman_image_set_transform (src, &transform);
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-    spice_return_val_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE || scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST, NULL);
-    pixman_image_set_filter(src,
-                            (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
-                            NULL, 0);
-
-    pixman_image_composite32(PIXMAN_OP_SRC,
-                             src, NULL, surface,
-                             ROUND(src_area->left / sx), ROUND (src_area->top / sy),
-                             0, 0, /* mask */
-                             0, 0, /* dst */
-                             width, height);
-
-    pixman_transform_init_identity(&transform);
-    pixman_image_set_transform(src, &transform);
-
-    return surface;
-}
-
-ATTR_PRINTF(2, 3) static void quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
-{
-    QuicData *usr_data = (QuicData *)usr;
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
-    va_end(ap);
-
-    longjmp(usr_data->jmp_env, 1);
-}
-
-ATTR_PRINTF(2, 3) static void quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...)
-{
-    QuicData *usr_data = (QuicData *)usr;
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
-    va_end(ap);
-}
-
-static void *quic_usr_malloc(QuicUsrContext *usr, int size)
-{
-    return spice_malloc(size);
-}
-
-static void quic_usr_free(QuicUsrContext *usr, void *ptr)
-{
-    free(ptr);
-}
-
-ATTR_PRINTF(2, 3) static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
-{
-    LzData *usr_data = (LzData *)usr;
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
-    va_end(ap);
-}
-
-ATTR_PRINTF(2, 3) static void lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
-{
-    LzData *usr_data = (LzData *)usr;
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
-    va_end(ap);
-
-    longjmp(usr_data->jmp_env, 1);
-}
-
-static void *lz_usr_malloc(LzUsrContext *usr, int size)
-{
-    return spice_malloc(size);
-}
-
-static void lz_usr_free(LzUsrContext *usr, void *ptr)
-{
-    free(ptr);
-}
-
-static int lz_usr_more_space(LzUsrContext *usr, uint8_t **io_ptr)
-{
-    return 0;
-}
-
-static int lz_usr_more_lines(LzUsrContext *usr, uint8_t **lines)
-{
-    return 0;
-}
-
-static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed)
-{
-    QuicData *quic_data = (QuicData *)usr;
-
-    if (quic_data->current_chunk == quic_data->chunks->num_chunks -1) {
-        return 0;
-    }
-    quic_data->current_chunk++;
-
-    *io_ptr = (uint32_t *)quic_data->chunks->chunk[quic_data->current_chunk].data;
-    return quic_data->chunks->chunk[quic_data->current_chunk].len >> 2;
-}
-
-
-static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
-{
-    return 0;
-}
-
-static void canvas_base_destroy(CanvasBase *canvas)
-{
-    quic_destroy(canvas->quic_data.quic);
-    lz_destroy(canvas->lz_data.lz);
-#ifdef GDI_CANVAS
-    DeleteDC(canvas->dc);
-#endif
-
-    if (canvas->usr_data && canvas->usr_data_destroy) {
-        canvas->usr_data_destroy (canvas->usr_data);
-        canvas->usr_data = NULL;
-    }
-}
-
-/* This is kind of lame, but it protects against multiple
-   instances of these functions. We really should stop including
-   canvas_base.c and build it separately instead */
-#ifdef  CANVAS_SINGLE_INSTANCE
-
-void spice_canvas_set_usr_data(SpiceCanvas *spice_canvas,
-                               void *data,
-                               spice_destroy_fn_t destroy_fn)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    if (canvas->usr_data && canvas->usr_data_destroy) {
-        canvas->usr_data_destroy (canvas->usr_data);
-    }
-    canvas->usr_data = data;
-    canvas->usr_data_destroy = destroy_fn;
-}
-
-void *spice_canvas_get_usr_data(SpiceCanvas *spice_canvas)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    return  canvas->usr_data;
-}
-#endif
-
-
-static void canvas_clip_pixman(CanvasBase *canvas,
-                               pixman_region32_t *dest_region,
-                               SpiceClip *clip)
-{
-    pixman_region32_intersect(dest_region, dest_region, &canvas->canvas_region);
-
-    switch (clip->type) {
-    case SPICE_CLIP_TYPE_NONE:
-        break;
-    case SPICE_CLIP_TYPE_RECTS: {
-        uint32_t n = clip->rects->num_rects;
-        SpiceRect *now = clip->rects->rects;
-
-        pixman_region32_t clip;
-
-        if (spice_pixman_region32_init_rects(&clip, now, n)) {
-            pixman_region32_intersect(dest_region, dest_region, &clip);
-            pixman_region32_fini(&clip);
-        }
-
-        break;
-    }
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-static void canvas_mask_pixman(CanvasBase *canvas,
-                               pixman_region32_t *dest_region,
-                               SpiceQMask *mask, int x, int y)
-{
-    SpiceCanvas *surface_canvas;
-    pixman_image_t *image, *subimage;
-    int needs_invert;
-    pixman_region32_t mask_region;
-    uint32_t *mask_data;
-    int mask_x, mask_y;
-    int mask_width, mask_height, mask_stride;
-    pixman_box32_t extents;
-
-    if (!mask->bitmap) {
-        return;
-    }
-
-    surface_canvas = canvas_get_surface_mask(canvas, mask->bitmap);
-    if (surface_canvas) {
-        needs_invert = mask->flags & SPICE_MASK_FLAGS_INVERS;
-        image = surface_canvas->ops->get_image(surface_canvas);
-    } else {
-        needs_invert = FALSE;
-        image = canvas_get_mask(canvas,
-                                mask,
-                                &needs_invert);
-    }
-
-    mask_data = pixman_image_get_data(image);
-    mask_width = pixman_image_get_width(image);
-    mask_height = pixman_image_get_height(image);
-    mask_stride = pixman_image_get_stride(image);
-
-    mask_x = mask->pos.x;
-    mask_y = mask->pos.y;
-
-    /* We need to subset the area of the mask that we turn into a region,
-       because a cached mask may be much larger than what is used for
-       the clip operation. */
-    extents = *pixman_region32_extents(dest_region);
-
-    /* convert from destination pixels to mask pixels */
-    extents.x1 -= x - mask_x;
-    extents.y1 -= y - mask_y;
-    extents.x2 -= x - mask_x;
-    extents.y2 -= y - mask_y;
-
-    /* clip to mask size */
-    if (extents.x1 < 0) {
-        extents.x1 = 0;
-    }
-    if (extents.x2 >= mask_width) {
-        extents.x2 = mask_width;
-    }
-    if (extents.x2 < extents.x1) {
-        extents.x2 = extents.x1;
-    }
-    if (extents.y1 < 0) {
-        extents.y1 = 0;
-    }
-    if (extents.y2 >= mask_height) {
-        extents.y2 = mask_height;
-    }
-    if (extents.y2 < extents.y1) {
-        extents.y2 = extents.y1;
-    }
-
-    /* round down X to even 32 pixels (i.e. uint32_t) */
-    extents.x1 = extents.x1 & ~(0x1f);
-
-    mask_data = (uint32_t *)((uint8_t *)mask_data + mask_stride * extents.y1 + extents.x1 / 32);
-    mask_x -= extents.x1;
-    mask_y -= extents.y1;
-    mask_width = extents.x2 - extents.x1;
-    mask_height = extents.y2 - extents.y1;
-
-    subimage = pixman_image_create_bits(PIXMAN_a1, mask_width, mask_height,
-                                        mask_data, mask_stride);
-    pixman_region32_init_from_image(&mask_region,
-                                    subimage);
-    pixman_image_unref(subimage);
-
-    if (needs_invert) {
-        pixman_box32_t rect;
-
-        rect.x1 = rect.y1 = 0;
-        rect.x2 = mask_width;
-        rect.y2 = mask_height;
-
-        pixman_region32_inverse(&mask_region, &mask_region, &rect);
-    }
-
-    pixman_region32_translate(&mask_region,
-                              -mask_x + x, -mask_y + y);
-
-    pixman_region32_intersect(dest_region, dest_region, &mask_region);
-    pixman_region32_fini(&mask_region);
-
-    pixman_image_unref(image);
-}
-
-static void draw_brush(SpiceCanvas *canvas,
-                       pixman_region32_t *region,
-                       SpiceBrush *brush,
-                       SpiceROP rop)
-{
-    CanvasBase *canvas_base = (CanvasBase *)canvas;
-    uint32_t color;
-    SpicePattern *pattern;
-    pixman_image_t *tile;
-    int offset_x, offset_y;
-    pixman_box32_t *rects;
-    int n_rects;
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-   switch (brush->type) {
-    case SPICE_BRUSH_TYPE_SOLID:
-        color = brush->u.color;
-        if (rop == SPICE_ROP_COPY) {
-            canvas->ops->fill_solid_rects(canvas, rects, n_rects, color);
-        } else {
-            canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, color, rop);
-        }
-        break;
-        case SPICE_BRUSH_TYPE_PATTERN: {
-        SpiceCanvas *surface_canvas;
-
-        pattern = &brush->u.pattern;
-        offset_x = pattern->pos.x;
-        offset_y = pattern->pos.y;
-
-        surface_canvas = canvas_get_surface(canvas_base, pattern->pat);
-        if (surface_canvas) {
-            if (rop == SPICE_ROP_COPY) {
-                canvas->ops->fill_tiled_rects_from_surface(canvas, rects, n_rects, surface_canvas,
-                                                           offset_x, offset_y);
-            } else {
-                canvas->ops->fill_tiled_rects_rop_from_surface(canvas, rects, n_rects,
-                                                               surface_canvas, offset_x, offset_y,
-                                                               rop);
-            }
-        } else {
-            tile = canvas_get_image(canvas_base, pattern->pat, FALSE);
-            spice_return_if_fail(tile != NULL);
-
-            if (rop == SPICE_ROP_COPY) {
-                canvas->ops->fill_tiled_rects(canvas, rects, n_rects, tile, offset_x, offset_y);
-            } else {
-                canvas->ops->fill_tiled_rects_rop(canvas, rects, n_rects,
-                                                  tile, offset_x, offset_y, rop);
-            }
-            pixman_image_unref(tile);
-        }
-        break;
-    }
-    case SPICE_BRUSH_TYPE_NONE:
-        /* Still need to do *something* here, because rop could be e.g invert dest */
-        canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, 0, rop);
-        break;
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-/* If we're exiting early we may still have to load an image in case
-   it has to be cached or something */
-static void touch_brush(CanvasBase *canvas, SpiceBrush *brush)
-{
-    SpicePattern *pattern;
-
-    if (brush->type == SPICE_BRUSH_TYPE_PATTERN) {
-        pattern = &brush->u.pattern;
-        canvas_touch_image(canvas, pattern->pat);
-    }
-}
-
-static void canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    SpiceROP rop;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &fill->mask,
-                       bbox->left, bbox->top);
-
-    rop = ropd_descriptor_to_rop(fill->rop_descriptor,
-                                 ROP_INPUT_BRUSH,
-                                 ROP_INPUT_DEST);
-
-    if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
-        touch_brush(canvas, &fill->brush);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    draw_brush(spice_canvas, &dest_region, &fill->brush, rop);
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    SpiceCanvas *surface_canvas;
-    pixman_image_t *src_image;
-    SpiceROP rop;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &copy->mask,
-                       bbox->left, bbox->top);
-
-    rop = ropd_descriptor_to_rop(copy->rop_descriptor,
-                                 ROP_INPUT_SRC,
-                                 ROP_INPUT_DEST);
-
-    if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
-        canvas_touch_image(canvas, copy->src_bitmap);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    surface_canvas = canvas_get_surface(canvas, copy->src_bitmap);
-    if (surface_canvas) {
-        if (rect_is_same_size(bbox, &copy->src_area)) {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
-                                                           surface_canvas,
-                                                           bbox->left - copy->src_area.left,
-                                                           bbox->top - copy->src_area.top);
-            } else {
-                spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
-                                                               surface_canvas,
-                                                               bbox->left - copy->src_area.left,
-                                                               bbox->top - copy->src_area.top,
-                                                               rop);
-            }
-        } else {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
-                                                            surface_canvas,
-                                                            copy->src_area.left,
-                                                            copy->src_area.top,
-                                                            copy->src_area.right - copy->src_area.left,
-                                                            copy->src_area.bottom - copy->src_area.top,
-                                                            bbox->left,
-                                                            bbox->top,
-                                                            bbox->right - bbox->left,
-                                                            bbox->bottom - bbox->top,
-                                                            copy->scale_mode);
-            } else {
-                spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
-                                                                surface_canvas,
-                                                                copy->src_area.left,
-                                                                copy->src_area.top,
-                                                                copy->src_area.right - copy->src_area.left,
-                                                                copy->src_area.bottom - copy->src_area.top,
-                                                                bbox->left,
-                                                                bbox->top,
-                                                                bbox->right - bbox->left,
-                                                                bbox->bottom - bbox->top,
-                                                                copy->scale_mode,
-                                                                rop);
-            }
-        }
-    } else {
-        src_image = canvas_get_image(canvas, copy->src_bitmap, FALSE);
-        spice_return_if_fail(src_image != NULL);
-
-        if (rect_is_same_size(bbox, &copy->src_area)) {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->blit_image(spice_canvas, &dest_region,
-                                              src_image,
-                                              bbox->left - copy->src_area.left,
-                                              bbox->top - copy->src_area.top);
-            } else {
-                spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
-                                                  src_image,
-                                                  bbox->left - copy->src_area.left,
-                                                  bbox->top - copy->src_area.top,
-                                                  rop);
-            }
-        } else {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->scale_image(spice_canvas, &dest_region,
-                                               src_image,
-                                               copy->src_area.left,
-                                               copy->src_area.top,
-                                               copy->src_area.right - copy->src_area.left,
-                                               copy->src_area.bottom - copy->src_area.top,
-                                               bbox->left,
-                                               bbox->top,
-                                               bbox->right - bbox->left,
-                                               bbox->bottom - bbox->top,
-                                               copy->scale_mode);
-            } else {
-                spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
-                                                   src_image,
-                                                   copy->src_area.left,
-                                                   copy->src_area.top,
-                                                   copy->src_area.right - copy->src_area.left,
-                                                   copy->src_area.bottom - copy->src_area.top,
-                                                   bbox->left,
-                                                   bbox->top,
-                                                   bbox->right - bbox->left,
-                                                   bbox->bottom - bbox->top,
-                                                   copy->scale_mode,
-                                                   rop);
-            }
-        }
-        pixman_image_unref(src_image);
-    }
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    SpiceCanvas *surface_canvas;
-    pixman_image_t *src_image;
-    pixman_region32_t dest_region;
-    uint32_t transparent_color;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-
-    if (pixman_region32_n_rects (&dest_region) == 0) {
-        canvas_touch_image(canvas, transparent->src_bitmap);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    switch (canvas->format) {
-    case SPICE_SURFACE_FMT_32_xRGB:
-    case SPICE_SURFACE_FMT_32_ARGB:
-        transparent_color = transparent->true_color;
-        break;
-    case SPICE_SURFACE_FMT_16_555:
-        transparent_color = rgb_32_to_16_555(transparent->true_color);
-        break;
-    case SPICE_SURFACE_FMT_16_565:
-        transparent_color = rgb_32_to_16_565(transparent->true_color);
-        break;
-    default:
-        transparent_color = 0;
-    }
-
-    surface_canvas = canvas_get_surface(canvas, transparent->src_bitmap);
-    if (surface_canvas) {
-        if (rect_is_same_size(bbox, &transparent->src_area)) {
-            spice_canvas->ops->colorkey_image_from_surface(spice_canvas, &dest_region,
-                                                           surface_canvas,
-                                                           bbox->left - transparent->src_area.left,
-                                                           bbox->top - transparent->src_area.top,
-                                                           transparent_color);
-        } else {
-            spice_canvas->ops->colorkey_scale_image_from_surface(spice_canvas, &dest_region,
-                                                                 surface_canvas,
-                                                                 transparent->src_area.left,
-                                                                 transparent->src_area.top,
-                                                                 transparent->src_area.right - transparent->src_area.left,
-                                                                 transparent->src_area.bottom - transparent->src_area.top,
-                                                                 bbox->left,
-                                                                 bbox->top,
-                                                                 bbox->right - bbox->left,
-                                                                 bbox->bottom - bbox->top,
-                                                                 transparent_color);
-        }
-    } else {
-        src_image = canvas_get_image(canvas, transparent->src_bitmap, FALSE);
-        spice_return_if_fail(src_image != NULL);
-
-        if (rect_is_same_size(bbox, &transparent->src_area)) {
-            spice_canvas->ops->colorkey_image(spice_canvas, &dest_region,
-                                              src_image,
-                                              bbox->left - transparent->src_area.left,
-                                              bbox->top - transparent->src_area.top,
-                                              transparent_color);
-        } else {
-            spice_canvas->ops->colorkey_scale_image(spice_canvas, &dest_region,
-                                                    src_image,
-                                                    transparent->src_area.left,
-                                                    transparent->src_area.top,
-                                                    transparent->src_area.right - transparent->src_area.left,
-                                                    transparent->src_area.bottom - transparent->src_area.top,
-                                                    bbox->left,
-                                                    bbox->top,
-                                                    bbox->right - bbox->left,
-                                                    bbox->bottom - bbox->top,
-                                                    transparent_color);
-        }
-        pixman_image_unref(src_image);
-    }
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    SpiceCanvas *surface_canvas;
-    pixman_image_t *src_image;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-
-    if (alpha_blend->alpha == 0 ||
-        !pixman_region32_not_empty(&dest_region)) {
-        canvas_touch_image(canvas, alpha_blend->src_bitmap);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    surface_canvas = canvas_get_surface(canvas, alpha_blend->src_bitmap);
-    if (surface_canvas) {
-        if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
-            spice_canvas->ops->blend_image_from_surface(spice_canvas, &dest_region,
-                                                        alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
-                                                        surface_canvas,
-                                                        alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
-                                                        alpha_blend->src_area.left,
-                                                        alpha_blend->src_area.top,
-                                                        bbox->left,
-                                                        bbox->top,
-                                                        bbox->right - bbox->left,
-                                                        bbox->bottom - bbox->top,
-                                                        alpha_blend->alpha);
-        } else {
-            spice_canvas->ops->blend_scale_image_from_surface(spice_canvas, &dest_region,
-                                                              alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
-                                                              surface_canvas,
-                                                              alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
-                                                              alpha_blend->src_area.left,
-                                                              alpha_blend->src_area.top,
-                                                              alpha_blend->src_area.right - alpha_blend->src_area.left,
-                                                              alpha_blend->src_area.bottom - alpha_blend->src_area.top,
-                                                              bbox->left,
-                                                              bbox->top,
-                                                              bbox->right - bbox->left,
-                                                              bbox->bottom - bbox->top,
-                                                              SPICE_IMAGE_SCALE_MODE_NEAREST,
-                                                              alpha_blend->alpha);
-        }
-     } else {
-        src_image = canvas_get_image(canvas, alpha_blend->src_bitmap, TRUE);
-        spice_return_if_fail(src_image != NULL);
-
-        if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
-            spice_canvas->ops->blend_image(spice_canvas, &dest_region,
-                                           alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
-                                           src_image,
-                                           alpha_blend->src_area.left,
-                                           alpha_blend->src_area.top,
-                                           bbox->left,
-                                           bbox->top,
-                                           bbox->right - bbox->left,
-                                           bbox->bottom - bbox->top,
-                                           alpha_blend->alpha);
-        } else {
-            spice_canvas->ops->blend_scale_image(spice_canvas, &dest_region,
-                                                 alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
-                                                 src_image,
-                                                 alpha_blend->src_area.left,
-                                                 alpha_blend->src_area.top,
-                                                 alpha_blend->src_area.right - alpha_blend->src_area.left,
-                                                 alpha_blend->src_area.bottom - alpha_blend->src_area.top,
-                                                 bbox->left,
-                                                 bbox->top,
-                                                 bbox->right - bbox->left,
-                                                 bbox->bottom - bbox->top,
-                                                 SPICE_IMAGE_SCALE_MODE_NEAREST,
-                                                 alpha_blend->alpha);
-        }
-
-        pixman_image_unref(src_image);
-    }
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_image_t *src_image;
-    pixman_region32_t dest_region;
-    SpiceCanvas *surface_canvas;
-    SpiceROP rop;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &opaque->mask,
-                       bbox->left, bbox->top);
-
-    rop = ropd_descriptor_to_rop(opaque->rop_descriptor,
-                                 ROP_INPUT_BRUSH,
-                                 ROP_INPUT_SRC);
-
-    if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
-        canvas_touch_image(canvas, opaque->src_bitmap);
-        touch_brush(canvas, &opaque->brush);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    surface_canvas = canvas_get_surface(canvas, opaque->src_bitmap);
-    if (surface_canvas) {
-        if (rect_is_same_size(bbox, &opaque->src_area)) {
-            spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
-                                                       surface_canvas,
-                                                       bbox->left - opaque->src_area.left,
-                                                       bbox->top - opaque->src_area.top);
-        } else {
-            spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
-                                                        surface_canvas,
-                                                        opaque->src_area.left,
-                                                        opaque->src_area.top,
-                                                        opaque->src_area.right - opaque->src_area.left,
-                                                        opaque->src_area.bottom - opaque->src_area.top,
-                                                        bbox->left,
-                                                        bbox->top,
-                                                        bbox->right - bbox->left,
-                                                        bbox->bottom - bbox->top,
-                                                        opaque->scale_mode);
-        }
-    } else {
-        src_image = canvas_get_image(canvas, opaque->src_bitmap, FALSE);
-        spice_return_if_fail(src_image != NULL);
-
-        if (rect_is_same_size(bbox, &opaque->src_area)) {
-            spice_canvas->ops->blit_image(spice_canvas, &dest_region,
-                                          src_image,
-                                          bbox->left - opaque->src_area.left,
-                                          bbox->top - opaque->src_area.top);
-        } else {
-            spice_canvas->ops->scale_image(spice_canvas, &dest_region,
-                                           src_image,
-                                           opaque->src_area.left,
-                                           opaque->src_area.top,
-                                           opaque->src_area.right - opaque->src_area.left,
-                                           opaque->src_area.bottom - opaque->src_area.top,
-                                           bbox->left,
-                                           bbox->top,
-                                           bbox->right - bbox->left,
-                                           bbox->bottom - bbox->top,
-                                           opaque->scale_mode);
-        }
-        pixman_image_unref(src_image);
-    }
-
-    draw_brush(spice_canvas, &dest_region, &opaque->brush, rop);
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    SpiceCanvas *surface_canvas;
-    pixman_image_t *src_image;
-    pixman_region32_t dest_region;
-    SpiceROP rop;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &blend->mask,
-                       bbox->left, bbox->top);
-
-    rop = ropd_descriptor_to_rop(blend->rop_descriptor,
-                                 ROP_INPUT_SRC,
-                                 ROP_INPUT_DEST);
-
-    if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
-        canvas_touch_image(canvas, blend->src_bitmap);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    surface_canvas = canvas_get_surface(canvas, blend->src_bitmap);
-    if (surface_canvas) {
-        if (rect_is_same_size(bbox, &blend->src_area)) {
-            if (rop == SPICE_ROP_COPY)
-                spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
-                                                           surface_canvas,
-                                                           bbox->left - blend->src_area.left,
-                                                           bbox->top - blend->src_area.top);
-            else
-                spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
-                                                               surface_canvas,
-                                                               bbox->left - blend->src_area.left,
-                                                               bbox->top - blend->src_area.top,
-                                                               rop);
-        } else {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
-                                                            surface_canvas,
-                                                            blend->src_area.left,
-                                                            blend->src_area.top,
-                                                            blend->src_area.right - blend->src_area.left,
-                                                            blend->src_area.bottom - blend->src_area.top,
-                                                            bbox->left,
-                                                            bbox->top,
-                                                            bbox->right - bbox->left,
-                                                            bbox->bottom - bbox->top,
-                                                            blend->scale_mode);
-            } else {
-                spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
-                                                                surface_canvas,
-                                                                blend->src_area.left,
-                                                                blend->src_area.top,
-                                                                blend->src_area.right - blend->src_area.left,
-                                                                blend->src_area.bottom - blend->src_area.top,
-                                                                bbox->left,
-                                                                bbox->top,
-                                                                bbox->right - bbox->left,
-                                                                bbox->bottom - bbox->top,
-                                                                blend->scale_mode, rop);
-            }
-        }
-    } else {
-        src_image = canvas_get_image(canvas, blend->src_bitmap, FALSE);
-        spice_return_if_fail(src_image != NULL);
-
-        if (rect_is_same_size(bbox, &blend->src_area)) {
-            if (rop == SPICE_ROP_COPY)
-                spice_canvas->ops->blit_image(spice_canvas, &dest_region,
-                                              src_image,
-                                              bbox->left - blend->src_area.left,
-                                              bbox->top - blend->src_area.top);
-            else
-                spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
-                                                  src_image,
-                                                  bbox->left - blend->src_area.left,
-                                                  bbox->top - blend->src_area.top,
-                                                  rop);
-        } else {
-            if (rop == SPICE_ROP_COPY) {
-                spice_canvas->ops->scale_image(spice_canvas, &dest_region,
-                                               src_image,
-                                               blend->src_area.left,
-                                               blend->src_area.top,
-                                               blend->src_area.right - blend->src_area.left,
-                                               blend->src_area.bottom - blend->src_area.top,
-                                               bbox->left,
-                                               bbox->top,
-                                               bbox->right - bbox->left,
-                                               bbox->bottom - bbox->top,
-                                               blend->scale_mode);
-            } else {
-                spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
-                                                   src_image,
-                                                   blend->src_area.left,
-                                                   blend->src_area.top,
-                                                   blend->src_area.right - blend->src_area.left,
-                                                   blend->src_area.bottom - blend->src_area.top,
-                                                   bbox->left,
-                                                   bbox->top,
-                                                   bbox->right - bbox->left,
-                                                   bbox->bottom - bbox->top,
-                                                   blend->scale_mode, rop);
-            }
-        }
-        pixman_image_unref(src_image);
-    }
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    pixman_box32_t *rects;
-    int n_rects;
-
-   pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &blackness->mask,
-                       bbox->left, bbox->top);
-
-    if (!pixman_region32_not_empty(&dest_region)) {
-        pixman_region32_fini (&dest_region);
-        return;
-    }
-
-    rects = pixman_region32_rectangles(&dest_region, &n_rects);
-
-    spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0x000000);
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    pixman_box32_t *rects;
-    int n_rects;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &whiteness->mask,
-                       bbox->left, bbox->top);
-
-    if (!pixman_region32_not_empty(&dest_region)) {
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    rects = pixman_region32_rectangles(&dest_region, &n_rects);
-    spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0xffffffff);
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    pixman_box32_t *rects;
-    int n_rects;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &invers->mask,
-                       bbox->left, bbox->top);
-
-    if (!pixman_region32_not_empty(&dest_region)) {
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    rects = pixman_region32_rectangles(&dest_region, &n_rects);
-    spice_canvas->ops->fill_solid_rects_rop(spice_canvas, rects, n_rects, 0x00000000,
-                                            SPICE_ROP_INVERT);
-
-    pixman_region32_fini(&dest_region);
-}
-
-typedef struct {
-    lineGC base;
-    SpiceCanvas *canvas;
-    pixman_region32_t dest_region;
-    SpiceROP fore_rop;
-    SpiceROP back_rop;
-    int solid;
-    uint32_t color;
-    int use_surface_canvas;
-    union {
-        SpiceCanvas *surface_canvas;
-        pixman_image_t *tile;
-    };
-    int tile_offset_x;
-    int tile_offset_y;
-} StrokeGC;
-
-static void stroke_fill_spans(lineGC * pGC,
-                              int num_spans,
-                              SpicePoint *points,
-                              int *widths,
-                              int sorted,
-                              int foreground)
-{
-    SpiceCanvas *canvas;
-    StrokeGC *strokeGC;
-    int i;
-    SpiceROP rop;
-
-    strokeGC = (StrokeGC *)pGC;
-    canvas = strokeGC->canvas;
-
-    num_spans = spice_canvas_clip_spans(&strokeGC->dest_region,
-                                        points, widths, num_spans,
-                                        points, widths, sorted);
-
-    if (foreground) {
-        rop = strokeGC->fore_rop;
-    } else {
-        rop = strokeGC->back_rop;
-    }
-
-    if (strokeGC->solid) {
-        if (rop == SPICE_ROP_COPY) {
-            canvas->ops->fill_solid_spans(canvas, points, widths, num_spans,
-                                          strokeGC->color);
-        } else {
-            for (i = 0; i < num_spans; i++) {
-                pixman_box32_t r;
-                r.x1 = points[i].x;
-                r.y1 = points[i].y;
-                r.x2 = points[i].x + widths[i];
-                r.y2 = r.y1 + 1;
-                canvas->ops->fill_solid_rects_rop(canvas, &r, 1,
-                                                  strokeGC->color, rop);
-            }
-        }
-    } else {
-        if (rop == SPICE_ROP_COPY) {
-            for (i = 0; i < num_spans; i++) {
-                pixman_box32_t r;
-                r.x1 = points[i].x;
-                r.y1 = points[i].y;
-                r.x2 = points[i].x + widths[i];
-                r.y2 = r.y1 + 1;
-                canvas->ops->fill_tiled_rects(canvas, &r, 1,
-                                              strokeGC->tile,
-                                              strokeGC->tile_offset_x,
-                                              strokeGC->tile_offset_y);
-            }
-        } else {
-            for (i = 0; i < num_spans; i++) {
-                pixman_box32_t r;
-                r.x1 = points[i].x;
-                r.y1 = points[i].y;
-                r.x2 = points[i].x + widths[i];
-                r.y2 = r.y1 + 1;
-                canvas->ops->fill_tiled_rects_rop(canvas, &r, 1,
-                                                  strokeGC->tile,
-                                                  strokeGC->tile_offset_x,
-                                                  strokeGC->tile_offset_y, rop);
-            }
-        }
-    }
-}
-
-static void stroke_fill_rects(lineGC * pGC,
-                              int num_rects,
-                              pixman_rectangle32_t *rects,
-                              int foreground)
-{
-    SpiceCanvas *canvas;
-    pixman_region32_t area;
-    pixman_box32_t *boxes;
-    StrokeGC *strokeGC;
-    SpiceROP rop;
-    int i;
-    pixman_box32_t *area_rects;
-    int n_area_rects;
-
-    strokeGC = (StrokeGC *)pGC;
-    canvas = strokeGC->canvas;
-
-    if (foreground) {
-        rop = strokeGC->fore_rop;
-    } else {
-        rop = strokeGC->back_rop;
-    }
-
-    /* TODO: We can optimize this for more common cases where
-       dest is one rect */
-
-    boxes = spice_new(pixman_box32_t, num_rects);
-    for (i = 0; i < num_rects; i++) {
-        boxes[i].x1 = rects[i].x;
-        boxes[i].y1 = rects[i].y;
-        boxes[i].x2 = rects[i].x + rects[i].width;
-        boxes[i].y2 = rects[i].y + rects[i].height;
-    }
-    pixman_region32_init_rects(&area, boxes, num_rects);
-    pixman_region32_intersect(&area, &area, &strokeGC->dest_region);
-    free(boxes);
-
-    area_rects = pixman_region32_rectangles(&area, &n_area_rects);
-
-    if (strokeGC->solid) {
-        if (rop == SPICE_ROP_COPY) {
-            canvas->ops->fill_solid_rects(canvas, area_rects, n_area_rects,
-                                          strokeGC->color);
-        } else {
-            canvas->ops->fill_solid_rects_rop(canvas, area_rects, n_area_rects,
-                                              strokeGC->color, rop);
-        }
-    } else {
-        if (rop == SPICE_ROP_COPY) {
-            if (strokeGC->use_surface_canvas) {
-                canvas->ops->fill_tiled_rects_from_surface(canvas, area_rects, n_area_rects,
-                                                           strokeGC->surface_canvas,
-                                                           strokeGC->tile_offset_x,
-                                                           strokeGC->tile_offset_y);
-            } else {
-                canvas->ops->fill_tiled_rects(canvas, area_rects, n_area_rects,
-                                              strokeGC->tile,
-                                              strokeGC->tile_offset_x,
-                                              strokeGC->tile_offset_y);
-            }
-        } else {
-            if (strokeGC->use_surface_canvas) {
-                canvas->ops->fill_tiled_rects_rop_from_surface(canvas, area_rects, n_area_rects,
-                                                               strokeGC->surface_canvas,
-                                                               strokeGC->tile_offset_x,
-                                                               strokeGC->tile_offset_y,
-                                                               rop);
-            } else {
-                canvas->ops->fill_tiled_rects_rop(canvas, area_rects, n_area_rects,
-                                                  strokeGC->tile,
-                                                  strokeGC->tile_offset_x,
-                                                  strokeGC->tile_offset_y,
-                                                  rop);
-            }
-        }
-    }
-
-   pixman_region32_fini(&area);
-}
-
-typedef struct {
-    SpicePoint *points;
-    int num_points;
-    int size;
-} StrokeLines;
-
-static void stroke_lines_init(StrokeLines *lines)
-{
-    lines->points = spice_new(SpicePoint, 10);
-    lines->size = 10;
-    lines->num_points = 0;
-}
-
-static void stroke_lines_free(StrokeLines *lines)
-{
-    free(lines->points);
-}
-
-static void stroke_lines_append(StrokeLines *lines,
-                                int x, int y)
-{
-    if (lines->num_points == lines->size) {
-        lines->size *= 2;
-        lines->points = spice_renew(SpicePoint, lines->points, lines->size);
-    }
-    lines->points[lines->num_points].x = x;
-    lines->points[lines->num_points].y = y;
-    lines->num_points++;
-}
-
-static void stroke_lines_append_fix(StrokeLines *lines,
-                                    SpicePointFix *point)
-{
-    stroke_lines_append(lines,
-                        fix_to_int(point->x),
-                        fix_to_int(point->y));
-}
-
-static inline int64_t dot(SPICE_FIXED28_4 x1,
-                          SPICE_FIXED28_4 y1,
-                          SPICE_FIXED28_4 x2,
-                          SPICE_FIXED28_4 y2)
-{
-    return (((int64_t)x1) *((int64_t)x2) +
-            ((int64_t)y1) *((int64_t)y2)) >> 4;
-}
-
-static inline int64_t dot2(SPICE_FIXED28_4 x,
-                           SPICE_FIXED28_4 y)
-{
-    return (((int64_t)x) *((int64_t)x) +
-            ((int64_t)y) *((int64_t)y)) >> 4;
-}
-
-static void subdivide_bezier(StrokeLines *lines,
-                             SpicePointFix point0,
-                             SpicePointFix point1,
-                             SpicePointFix point2,
-                             SpicePointFix point3)
-{
-    int64_t A2, B2, C2, AB, CB, h1, h2;
-
-    A2 = dot2(point1.x - point0.x,
-              point1.y - point0.y);
-    B2 = dot2(point3.x - point0.x,
-              point3.y - point0.y);
-    C2 = dot2(point2.x - point3.x,
-              point2.y - point3.y);
-
-    AB = dot(point1.x - point0.x,
-             point1.y - point0.y,
-             point3.x - point0.x,
-             point3.y - point0.y);
-
-    CB = dot(point2.x - point3.x,
-             point2.y - point3.y,
-             point0.x - point3.x,
-             point0.y - point3.y);
-
-    h1 = (A2*B2 - AB*AB) >> 3;
-    h2 = (C2*B2 - CB*CB) >> 3;
-
-    if (h1 < B2 && h2 < B2) {
-        /* deviation squared less than half a pixel, use straight line */
-        stroke_lines_append_fix(lines, &point3);
-    } else {
-        SpicePointFix point01, point23, point12, point012, point123, point0123;
-
-        point01.x = (point0.x + point1.x) / 2;
-        point01.y = (point0.y + point1.y) / 2;
-        point12.x = (point1.x + point2.x) / 2;
-        point12.y = (point1.y + point2.y) / 2;
-        point23.x = (point2.x + point3.x) / 2;
-        point23.y = (point2.y + point3.y) / 2;
-        point012.x = (point01.x + point12.x) / 2;
-        point012.y = (point01.y + point12.y) / 2;
-        point123.x = (point12.x + point23.x) / 2;
-        point123.y = (point12.y + point23.y) / 2;
-        point0123.x = (point012.x + point123.x) / 2;
-        point0123.y = (point012.y + point123.y) / 2;
-
-        subdivide_bezier(lines, point0, point01, point012, point0123);
-        subdivide_bezier(lines, point0123, point123, point23, point3);
-    }
-}
-
-static void stroke_lines_append_bezier(StrokeLines *lines,
-                                       SpicePointFix *point1,
-                                       SpicePointFix *point2,
-                                       SpicePointFix *point3)
-{
-    SpicePointFix point0;
-
-    point0.x = int_to_fix(lines->points[lines->num_points-1].x);
-    point0.y = int_to_fix(lines->points[lines->num_points-1].y);
-
-    subdivide_bezier(lines, point0, *point1, *point2, *point3);
-}
-
-static void stroke_lines_draw(StrokeLines *lines,
-                              lineGC *gc,
-                              int dashed)
-{
-    if (lines->num_points != 0) {
-        if (dashed) {
-            spice_canvas_zero_dash_line(gc, CoordModeOrigin,
-                                        lines->num_points, lines->points);
-        } else {
-            spice_canvas_zero_line(gc, CoordModeOrigin,
-                                   lines->num_points, lines->points);
-        }
-        lines->num_points = 0;
-    }
-}
-
-
-static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
-                               SpiceClip *clip, SpiceStroke *stroke)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    SpiceCanvas *surface_canvas = NULL;
-    StrokeGC gc = { { 0 } };
-    lineGCOps ops = {
-        stroke_fill_spans,
-        stroke_fill_rects
-    };
-    StrokeLines lines;
-    unsigned int i;
-    int dashed;
-
-    pixman_region32_init_rect(&gc.dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &gc.dest_region, clip);
-
-    if (!pixman_region32_not_empty(&gc.dest_region)) {
-        touch_brush(canvas, &stroke->brush);
-        pixman_region32_fini(&gc.dest_region);
-        return;
-    }
-
-    gc.canvas = spice_canvas;
-    gc.fore_rop = ropd_descriptor_to_rop(stroke->fore_mode,
-                                         ROP_INPUT_BRUSH,
-                                         ROP_INPUT_DEST);
-    gc.back_rop = ropd_descriptor_to_rop(stroke->back_mode,
-                                         ROP_INPUT_BRUSH,
-                                         ROP_INPUT_DEST);
-
-    gc.base.width = canvas->width;
-    gc.base.height = canvas->height;
-    gc.base.alu = gc.fore_rop;
-    gc.base.lineWidth = 0;
-
-    /* dash */
-    gc.base.dashOffset = 0;
-    gc.base.dash = NULL;
-    gc.base.numInDashList = 0;
-    gc.base.lineStyle = LineSolid;
-    /* win32 cosmetic lines are endpoint-exclusive, so use CapNotLast */
-    gc.base.capStyle = CapNotLast;
-    gc.base.joinStyle = JoinMiter;
-    gc.base.ops = &ops;
-
-    dashed = 0;
-    if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
-        SPICE_FIXED28_4 *style = stroke->attr.style;
-        int nseg;
-
-        dashed = 1;
-
-        nseg = stroke->attr.style_nseg;
-
-        /* To truly handle back_mode we should use LineDoubleDash here
-           and treat !foreground as back_rop using the same brush.
-           However, using the same brush for that seems wrong.
-           The old cairo backend was stroking the non-dashed line with
-           rop_mode before enabling dashes for the foreground which is
-           not right either. The gl an gdi backend don't use back_mode
-           at all */
-        gc.base.lineStyle = LineOnOffDash;
-        gc.base.dash = (unsigned char *)spice_malloc(nseg);
-        gc.base.numInDashList = nseg;
-
-        if (stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP) {
-            gc.base.dash[stroke->attr.style_nseg - 1] = fix_to_int(style[0]);
-            for (i = 0; i < (unsigned int)(stroke->attr.style_nseg - 1); i++) {
-                gc.base.dash[i] = fix_to_int(style[i+1]);
-            }
-            gc.base.dashOffset = gc.base.dash[0];
-        } else {
-            for (i = 0; i < stroke->attr.style_nseg; i++) {
-                gc.base.dash[i] = fix_to_int(style[i]);
-            }
-        }
-    }
-
-    switch (stroke->brush.type) {
-    case SPICE_BRUSH_TYPE_NONE:
-        gc.solid = TRUE;
-        gc.color = 0;
-        break;
-    case SPICE_BRUSH_TYPE_SOLID:
-        gc.solid = TRUE;
-        gc.color = stroke->brush.u.color;
-        break;
-    case SPICE_BRUSH_TYPE_PATTERN:
-        gc.solid = FALSE;
-        surface_canvas = canvas_get_surface(canvas,
-                                            stroke->brush.u.pattern.pat);
-        if (surface_canvas) {
-            gc.use_surface_canvas = TRUE;
-            gc.surface_canvas = surface_canvas;
-        } else {
-            gc.use_surface_canvas = FALSE;
-            gc.tile = canvas_get_image(canvas,
-                                       stroke->brush.u.pattern.pat,
-                                       FALSE);
-        }
-        gc.tile_offset_x = stroke->brush.u.pattern.pos.x;
-        gc.tile_offset_y = stroke->brush.u.pattern.pos.y;
-        break;
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-
-    stroke_lines_init(&lines);
-
-    for (i = 0; i < stroke->path->num_segments; i++) {
-        SpicePathSeg *seg = stroke->path->segments[i];
-        SpicePointFix* point, *end_point;
-
-        point = seg->points;
-        end_point = point + seg->count;
-
-        if (seg->flags & SPICE_PATH_BEGIN) {
-            stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
-            stroke_lines_append_fix(&lines, point);
-            point++;
-        }
-
-        if (seg->flags & SPICE_PATH_BEZIER) {
-            spice_return_if_fail((point - end_point) % 3 == 0);
-            for (; point + 2 < end_point; point += 3) {
-                stroke_lines_append_bezier(&lines,
-                                           &point[0],
-                                           &point[1],
-                                           &point[2]);
-            }
-        } else
-            {
-            for (; point < end_point; point++) {
-                stroke_lines_append_fix(&lines, point);
-            }
-        }
-        if (seg->flags & SPICE_PATH_END) {
-            if (seg->flags & SPICE_PATH_CLOSE) {
-                stroke_lines_append(&lines,
-                                    lines.points[0].x, lines.points[0].y);
-            }
-            stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
-        }
-    }
-
-    stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
-
-    if (gc.base.dash) {
-        free(gc.base.dash);
-    }
-    stroke_lines_free(&lines);
-
-    if (!gc.solid && gc.tile && !surface_canvas) {
-        pixman_image_unref(gc.tile);
-    }
-
-    pixman_region32_fini(&gc.dest_region);
-}
-
-
-//need surfaces handling here !!!
-static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
-                             SpiceClip *clip, SpiceRop3 *rop3)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    SpiceCanvas *surface_canvas;
-    pixman_region32_t dest_region;
-    pixman_image_t *d;
-    pixman_image_t *s;
-    SpicePoint src_pos;
-    int width;
-    int heigth;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-    canvas_mask_pixman(canvas, &dest_region, &rop3->mask,
-                       bbox->left, bbox->top);
-
-    width = bbox->right - bbox->left;
-    heigth = bbox->bottom - bbox->top;
-
-    d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth);
-    surface_canvas = canvas_get_surface(canvas, rop3->src_bitmap);
-    if (surface_canvas) {
-        s = surface_canvas->ops->get_image(surface_canvas);
-    } else {
-        s = canvas_get_image(canvas, rop3->src_bitmap, FALSE);
-    }
-
-    if (!rect_is_same_size(bbox, &rop3->src_area)) {
-        pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
-                                                        rop3->scale_mode);
-        pixman_image_unref(s);
-        s = scaled_s;
-        src_pos.x = 0;
-        src_pos.y = 0;
-    } else {
-        src_pos.x = rop3->src_area.left;
-        src_pos.y = rop3->src_area.top;
-    }
-    if (pixman_image_get_width(s) - src_pos.x < width ||
-        pixman_image_get_height(s) - src_pos.y < heigth) {
-        spice_critical("bad src bitmap size");
-        return;
-    }
-    if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
-        SpiceCanvas *_surface_canvas;
-        pixman_image_t *p;
-
-        _surface_canvas = canvas_get_surface(canvas, rop3->brush.u.pattern.pat);
-        if (_surface_canvas) {
-            p = _surface_canvas->ops->get_image(_surface_canvas);
-        } else {
-            p = canvas_get_image(canvas, rop3->brush.u.pattern.pat, FALSE);
-        }
-        SpicePoint pat_pos;
-
-        pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
-        pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
-        do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
-        pixman_image_unref(p);
-    } else {
-        do_rop3_with_color(rop3->rop3, d, s, &src_pos, rop3->brush.u.color);
-    }
-    pixman_image_unref(s);
-
-    spice_canvas->ops->blit_image(spice_canvas, &dest_region, d,
-                                  bbox->left,
-                                  bbox->top);
-
-    pixman_image_unref(d);
-
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_t dest_region;
-    int dx, dy;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(canvas, &dest_region, clip);
-
-    dx = bbox->left - src_pos->x;
-    dy = bbox->top - src_pos->y;
-
-    if (dx != 0 || dy != 0) {
-        pixman_region32_t src_region;
-
-        /* Clip so we don't read outside canvas */
-        pixman_region32_init_rect(&src_region,
-                                  dx, dy,
-                                  canvas->width,
-                                  canvas->height);
-        pixman_region32_intersect(&dest_region, &dest_region, &src_region);
-        pixman_region32_fini(&src_region);
-
-        spice_canvas->ops->copy_region(spice_canvas, &dest_region, dx, dy);
-    }
-
-    pixman_region32_fini(&dest_region);
-}
-
-
-
-static void canvas_base_group_start(SpiceCanvas *spice_canvas, QRegion *region)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_fini(&canvas->canvas_region);
-
-    /* Make sure we always clip to canvas size */
-    pixman_region32_init_rect(&canvas->canvas_region,
-                              0, 0,
-                              canvas->width,
-                              canvas->height);
-
-    pixman_region32_intersect(&canvas->canvas_region, &canvas->canvas_region, region);
-}
-
-static void canvas_base_group_end(SpiceCanvas *spice_canvas)
-{
-    CanvasBase *canvas = (CanvasBase *)spice_canvas;
-    pixman_region32_fini(&canvas->canvas_region);
-    pixman_region32_init_rect(&canvas->canvas_region,
-                              0, 0,
-                              canvas->width,
-                              canvas->height);
-}
-
-
-static void unimplemented_op(SpiceCanvas *canvas)
-{
-    spice_critical("unimplemented canvas operation");
-}
-
-inline static void canvas_base_init_ops(SpiceCanvasOps *ops)
-{
-    void **ops_cast;
-    unsigned i;
-
-    ops_cast = (void **)ops;
-    for (i = 0; i < sizeof(SpiceCanvasOps) / sizeof(void *); i++) {
-        ops_cast[i] = (void *) unimplemented_op;
-    }
-
-    ops->draw_fill = canvas_draw_fill;
-    ops->draw_copy = canvas_draw_copy;
-    ops->draw_opaque = canvas_draw_opaque;
-    ops->copy_bits = canvas_copy_bits;
-    ops->draw_blend = canvas_draw_blend;
-    ops->draw_blackness = canvas_draw_blackness;
-    ops->draw_whiteness = canvas_draw_whiteness;
-    ops->draw_invers = canvas_draw_invers;
-    ops->draw_transparent = canvas_draw_transparent;
-    ops->draw_alpha_blend = canvas_draw_alpha_blend;
-    ops->draw_stroke = canvas_draw_stroke;
-    ops->draw_rop3 = canvas_draw_rop3;
-    ops->group_start = canvas_base_group_start;
-    ops->group_end = canvas_base_group_end;
-}
-
-static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
-                            int width, int height, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                            , SpiceImageCache *bits_cache
-                            , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                            , SpiceImageCache *bits_cache
-#endif
-                            , SpiceImageSurfaces *surfaces
-                            , SpiceGlzDecoder *glz_decoder
-                            , SpiceJpegDecoder *jpeg_decoder
-                            , SpiceZlibDecoder *zlib_decoder
-                            )
-{
-    canvas->parent.ops = ops;
-    canvas->quic_data.usr.error = quic_usr_error;
-    canvas->quic_data.usr.warn = quic_usr_warn;
-    canvas->quic_data.usr.info = quic_usr_warn;
-    canvas->quic_data.usr.malloc = quic_usr_malloc;
-    canvas->quic_data.usr.free = quic_usr_free;
-    canvas->quic_data.usr.more_space = quic_usr_more_space;
-    canvas->quic_data.usr.more_lines = quic_usr_more_lines;
-    if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
-            return 0;
-    }
-
-    canvas->lz_data.usr.error = lz_usr_error;
-    canvas->lz_data.usr.warn = lz_usr_warn;
-    canvas->lz_data.usr.info = lz_usr_warn;
-    canvas->lz_data.usr.malloc = lz_usr_malloc;
-    canvas->lz_data.usr.free = lz_usr_free;
-    canvas->lz_data.usr.more_space = lz_usr_more_space;
-    canvas->lz_data.usr.more_lines = lz_usr_more_lines;
-    if (!(canvas->lz_data.lz = lz_create(&canvas->lz_data.usr))) {
-            return 0;
-    }
-
-    canvas->surfaces = surfaces;
-    canvas->glz_data.decoder = glz_decoder;
-    canvas->jpeg = jpeg_decoder;
-    canvas->zlib = zlib_decoder;
-
-    canvas->format = format;
-
-    /* TODO: This is all wrong now */
-    if (SPICE_SURFACE_FMT_DEPTH(format) == 16) {
-        canvas->color_shift = 5;
-        canvas->color_mask = 0x1f;
-    } else {
-        canvas->color_shift = 8;
-        canvas->color_mask = 0xff;
-    }
-
-    canvas->width = width;
-    canvas->height = height;
-    pixman_region32_init_rect(&canvas->canvas_region,
-                              0, 0,
-                              canvas->width,
-                              canvas->height);
-
-#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
-    canvas->bits_cache = bits_cache;
-#endif
-#ifdef SW_CANVAS_CACHE
-    canvas->palette_cache = palette_cache;
-#endif
-
-#ifdef WIN32
-    canvas->dc = NULL;
-#endif
-
-#ifdef GDI_CANVAS
-    canvas->dc = create_compatible_dc();
-    if (!canvas->dc) {
-        lz_destroy(canvas->lz_data.lz);
-        return 0;
-    }
-#endif
-    return 1;
-}
diff --git a/common/canvas_base.h b/common/canvas_base.h
deleted file mode 100644
index bea041f..0000000
--- a/common/canvas_base.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_CANVAS_BASE
-#define _H_CANVAS_BASE
-
-
-#include "pixman_utils.h"
-#include "lz.h"
-#include "region.h"
-#include "draw.h"
-#ifdef WIN32
-#include <windows.h>
-#endif
-
-typedef void (*spice_destroy_fn_t)(void *data);
-
-typedef struct _SpiceImageCache SpiceImageCache;
-typedef struct _SpiceImageSurfaces SpiceImageSurfaces;
-typedef struct _SpicePaletteCache SpicePaletteCache;
-typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
-typedef struct _SpiceJpegDecoder SpiceJpegDecoder;
-typedef struct _SpiceZlibDecoder SpiceZlibDecoder;
-typedef struct _SpiceCanvas SpiceCanvas;
-
-typedef struct {
-    void (*put)(SpiceImageCache *cache,
-                uint64_t id,
-                pixman_image_t *surface);
-    pixman_image_t *(*get)(SpiceImageCache *cache,
-                           uint64_t id);
-#ifdef SW_CANVAS_CACHE
-    void (*put_lossy)(SpiceImageCache *cache,
-                      uint64_t id,
-                      pixman_image_t *surface);
-    void (*replace_lossy)(SpiceImageCache *cache,
-                          uint64_t id,
-                          pixman_image_t *surface);
-    pixman_image_t *(*get_lossless)(SpiceImageCache *cache,
-                                    uint64_t id);
-#endif
-} SpiceImageCacheOps;
-
-struct _SpiceImageCache {
-  SpiceImageCacheOps *ops;
-};
-
-typedef struct {
- SpiceCanvas *(*get)(SpiceImageSurfaces *surfaces,
-	             uint32_t surface_id);
-} SpiceImageSurfacesOps;
-
-struct _SpiceImageSurfaces {
- SpiceImageSurfacesOps *ops;
-};
-
-typedef struct {
-    void (*put)(SpicePaletteCache *cache,
-                SpicePalette *palette);
-    SpicePalette *(*get)(SpicePaletteCache *cache,
-                         uint64_t id);
-    void (*release)(SpicePaletteCache *cache,
-                    SpicePalette *palette);
-} SpicePaletteCacheOps;
-
-struct _SpicePaletteCache {
-  SpicePaletteCacheOps *ops;
-};
-
-typedef struct {
-    void (*decode)(SpiceGlzDecoder *decoder,
-                   uint8_t *data,
-                   SpicePalette *plt,
-                   void *usr_data);
-} SpiceGlzDecoderOps;
-
-struct _SpiceGlzDecoder {
-  SpiceGlzDecoderOps *ops;
-};
-
-
-typedef struct SpiceJpegDecoderOps {
-    void (*begin_decode)(SpiceJpegDecoder *decoder,
-                         uint8_t* data,
-                         int data_size,
-                         int* out_width,
-                         int* out_height);
-    void (*decode)(SpiceJpegDecoder *decoder,
-                   uint8_t* dest,
-                   int stride,
-                   int format);
-} SpiceJpegDecoderOps;
-
-struct _SpiceJpegDecoder {
-    SpiceJpegDecoderOps *ops;
-};
-
-typedef struct {
-    void (*decode)(SpiceZlibDecoder *decoder,
-                   uint8_t *data,
-                   int data_size,
-                   uint8_t *dest,
-                   int dest_size);
-} SpiceZlibDecoderOps;
-
-struct _SpiceZlibDecoder {
-  SpiceZlibDecoderOps *ops;
-};
-
-typedef struct {
-    void (*draw_fill)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
-    void (*draw_copy)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
-    void (*draw_opaque)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
-    void (*copy_bits)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
-    void (*draw_text)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
-    void (*draw_stroke)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
-    void (*draw_rop3)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
-    void (*draw_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
-    void (*draw_blackness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
-    void (*draw_whiteness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
-    void (*draw_invers)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
-    void (*draw_transparent)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
-    void (*draw_alpha_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend);
-    void (*put_image)(SpiceCanvas *canvas,
-#ifdef WIN32
-                      HDC dc,
-#endif
-                      const SpiceRect *dest, const uint8_t *src_data,
-                      uint32_t src_width, uint32_t src_height, int src_stride,
-                      const QRegion *clip);
-    void (*clear)(SpiceCanvas *canvas);
-    void (*read_bits)(SpiceCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
-    void (*group_start)(SpiceCanvas *canvas, QRegion *region);
-    void (*group_end)(SpiceCanvas *canvas);
-    void (*destroy)(SpiceCanvas *canvas);
-
-    /* Implementation vfuncs */
-    void (*fill_solid_spans)(SpiceCanvas *canvas,
-                             SpicePoint *points,
-                             int *widths,
-                             int n_spans,
-                             uint32_t color);
-    void (*fill_solid_rects)(SpiceCanvas *canvas,
-                             pixman_box32_t *rects,
-                             int n_rects,
-                             uint32_t color);
-    void (*fill_solid_rects_rop)(SpiceCanvas *canvas,
-                                 pixman_box32_t *rects,
-                                 int n_rects,
-                                 uint32_t color,
-                                 SpiceROP rop);
-    void (*fill_tiled_rects)(SpiceCanvas *canvas,
-                             pixman_box32_t *rects,
-                             int n_rects,
-                             pixman_image_t *tile,
-                             int offset_x, int offset_y);
-    void (*fill_tiled_rects_from_surface)(SpiceCanvas *canvas,
-					  pixman_box32_t *rects,
-					  int n_rects,
-					  SpiceCanvas *tile,
-					  int offset_x, int offset_y);
-    void (*fill_tiled_rects_rop)(SpiceCanvas *canvas,
-                                 pixman_box32_t *rects,
-                                 int n_rects,
-                                 pixman_image_t *tile,
-                                 int offset_x, int offset_y,
-                                 SpiceROP rop);
-    void (*fill_tiled_rects_rop_from_surface)(SpiceCanvas *canvas,
-					      pixman_box32_t *rects,
-					      int n_rects,
-					      SpiceCanvas *tile,
-					      int offset_x, int offset_y,
-					      SpiceROP rop);
-    void (*blit_image)(SpiceCanvas *canvas,
-                       pixman_region32_t *region,
-                       pixman_image_t *src_image,
-                       int offset_x, int offset_y);
-    void (*blit_image_from_surface)(SpiceCanvas *canvas,
-				    pixman_region32_t *region,
-				    SpiceCanvas *src_image,
-				    int offset_x, int offset_y);
-    void (*blit_image_rop)(SpiceCanvas *canvas,
-                           pixman_region32_t *region,
-                           pixman_image_t *src_image,
-                           int offset_x, int offset_y,
-                           SpiceROP rop);
-    void (*blit_image_rop_from_surface)(SpiceCanvas *canvas,
-					pixman_region32_t *region,
-					SpiceCanvas *src_image,
-					int offset_x, int offset_y,
-					SpiceROP rop);
-    void (*scale_image)(SpiceCanvas *canvas,
-                        pixman_region32_t *region,
-                        pixman_image_t *src_image,
-                        int src_x, int src_y,
-                        int src_width, int src_height,
-                        int dest_x, int dest_y,
-                        int dest_width, int dest_height,
-                        int scale_mode);
-    void (*scale_image_from_surface)(SpiceCanvas *canvas,
-				     pixman_region32_t *region,
-				     SpiceCanvas *src_image,
-				     int src_x, int src_y,
-				     int src_width, int src_height,
-				     int dest_x, int dest_y,
-				     int dest_width, int dest_height,
-				     int scale_mode);
-    void (*scale_image_rop)(SpiceCanvas *canvas,
-                            pixman_region32_t *region,
-                            pixman_image_t *src_image,
-                            int src_x, int src_y,
-                            int src_width, int src_height,
-                            int dest_x, int dest_y,
-                            int dest_width, int dest_height,
-                            int scale_mode, SpiceROP rop);
-    void (*scale_image_rop_from_surface)(SpiceCanvas *canvas,
-					 pixman_region32_t *region,
-					 SpiceCanvas *src_image,
-					 int src_x, int src_y,
-					 int src_width, int src_height,
-					 int dest_x, int dest_y,
-					 int dest_width, int dest_height,
-					 int scale_mode, SpiceROP rop);
-    void (*blend_image)(SpiceCanvas *canvas,
-                        pixman_region32_t *region,
-                        int dest_has_alpha,
-                        pixman_image_t *src_image,
-                        int src_x, int src_y,
-                        int dest_x, int dest_y,
-                        int width, int height,
-                        int overall_alpha);
-    void (*blend_image_from_surface)(SpiceCanvas *canvas,
-				     pixman_region32_t *region,
-                                     int dest_has_alpha,
-				     SpiceCanvas *src_image,
-                                     int src_has_alpha,
-				     int src_x, int src_y,
-				     int dest_x, int dest_y,
-				     int width, int height,
-				     int overall_alpha);
-    void (*blend_scale_image)(SpiceCanvas *canvas,
-                              pixman_region32_t *region,
-                              int dest_has_alpha,
-                              pixman_image_t *src_image,
-                              int src_x, int src_y,
-                              int src_width, int src_height,
-                              int dest_x, int dest_y,
-                              int dest_width, int dest_height,
-                              int scale_mode,
-                              int overall_alpha);
-    void (*blend_scale_image_from_surface)(SpiceCanvas *canvas,
-					   pixman_region32_t *region,
-                                           int dest_has_alpha,
-					   SpiceCanvas *src_image,
-                                           int src_has_alpha,
-					   int src_x, int src_y,
-					   int src_width, int src_height,
-					   int dest_x, int dest_y,
-					   int dest_width, int dest_height,
-					   int scale_mode,
-					   int overall_alpha);
-    void (*colorkey_image)(SpiceCanvas *canvas,
-                           pixman_region32_t *region,
-                           pixman_image_t *src_image,
-                           int offset_x, int offset_y,
-                           uint32_t transparent_color);
-    void (*colorkey_image_from_surface)(SpiceCanvas *canvas,
-					pixman_region32_t *region,
-					SpiceCanvas *src_image,
-					int offset_x, int offset_y,
-					uint32_t transparent_color);
-    void (*colorkey_scale_image)(SpiceCanvas *canvas,
-                                 pixman_region32_t *region,
-                                 pixman_image_t *src_image,
-                                 int src_x, int src_y,
-                                 int src_width, int src_height,
-                                 int dest_x, int dest_y,
-                                 int dest_width, int dest_height,
-                                 uint32_t transparent_color);
-    void (*colorkey_scale_image_from_surface)(SpiceCanvas *canvas,
-					      pixman_region32_t *region,
-					      SpiceCanvas *src_image,
-					      int src_x, int src_y,
-					      int src_width, int src_height,
-					      int dest_x, int dest_y,
-					      int dest_width, int dest_height,
-					      uint32_t transparent_color);
-    void (*copy_region)(SpiceCanvas *canvas,
-                        pixman_region32_t *dest_region,
-                        int dx, int dy);
-    pixman_image_t *(*get_image)(SpiceCanvas *canvas);
-} SpiceCanvasOps;
-
-void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn);
-void *spice_canvas_get_usr_data(SpiceCanvas *canvas);
-
-struct _SpiceCanvas {
-  SpiceCanvasOps *ops;
-};
-
-#endif
diff --git a/common/canvas_utils.c b/common/canvas_utils.c
deleted file mode 100644
index 743c86c..0000000
--- a/common/canvas_utils.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "canvas_utils.h"
-
-#include <spice/macros.h>
-
-#ifdef __GNUC__
-#include <stdlib.h>
-#include <stdio.h>
-#endif
-#include "mem.h"
-
-#ifdef WIN32
-static int gdi_handlers = 0;
-#endif
-
-#ifndef ASSERT
-#define ASSERT(x) if (!(x)) {                               \
-    printf("%s: ASSERT %s failed\n", __FUNCTION__, #x);     \
-    abort();                                                \
-}
-#endif
-
-
-#ifndef CANVAS_ERROR
-#define CANVAS_ERROR(format, ...) {                             \
-    printf("%s: " format "\n", __FUNCTION__, ## __VA_ARGS__);   \
-    abort();                                                    \
-}
-#endif
-
-static void release_data(pixman_image_t *image, void *release_data)
-{
-    PixmanData *data = (PixmanData *)release_data;
-
-#ifdef WIN32
-    if (data->bitmap) {
-        DeleteObject((HBITMAP)data->bitmap);
-        CloseHandle(data->mutex);
-        gdi_handlers--;
-    }
-#endif
-    if (data->data) {
-        free(data->data);
-    }
-
-    free(data);
-}
-
-static PixmanData *
-pixman_image_add_data(pixman_image_t *image)
-{
-    PixmanData *data;
-
-    data = (PixmanData *)pixman_image_get_destroy_data(image);
-    if (data == NULL) {
-        data = (PixmanData *)calloc(1, sizeof(PixmanData));
-        if (data == NULL) {
-            CANVAS_ERROR("out of memory");
-        }
-        pixman_image_set_destroy_function(image,
-                                          release_data,
-                                          data);
-    }
-
-    return data;
-}
-
-void
-spice_pixman_image_set_format(pixman_image_t *image,
-                              pixman_format_code_t format)
-{
-    PixmanData *data;
-
-    data = pixman_image_add_data(image);
-    data->format = format;
-}
-
-pixman_format_code_t
-spice_pixman_image_get_format(pixman_image_t *image)
-{
-    PixmanData *data;
-
-    data = (PixmanData *)pixman_image_get_destroy_data(image);
-    if (data != NULL &&
-        data->format != 0)
-        return data->format;
-
-    CANVAS_ERROR("Unknown pixman image type");
-}
-
-static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height,
-                                                      int stride)
-{
-    uint8_t *data;
-    uint8_t *stride_data;
-    pixman_image_t *surface;
-    PixmanData *pixman_data;
-
-    data = (uint8_t *)spice_malloc_n(abs(stride), height);
-    if (stride < 0) {
-        stride_data = data + (-stride) * (height - 1);
-    } else {
-        stride_data = data;
-    }
-
-    surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride);
-
-    if (surface == NULL) {
-        free(data);
-        CANVAS_ERROR("create surface failed, out of memory");
-    }
-
-    pixman_data = pixman_image_add_data(surface);
-    pixman_data->data = data;
-    pixman_data->format = format;
-
-    return surface;
-}
-
-#ifdef WIN32
-pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
-                                int width, int height, int top_down)
-#else
-pixman_image_t * surface_create(pixman_format_code_t format, int width, int height, int top_down)
-#endif
-{
-#ifdef WIN32
-    /*
-     * Windows xp allow only 10,000 of gdi handlers, considering the fact that
-     * we limit here the number to 5000, we dont use atomic operations to sync
-     * this calculation against the other canvases (in case of multiple
-     * monitors), in worst case there will be little more than 5000 gdi
-     * handlers.
-     */
-    if (dc && gdi_handlers < 5000) {
-        uint8_t *data;
-        uint8_t *src;
-        struct {
-            BITMAPINFO inf;
-            RGBQUAD palette[255];
-        } bitmap_info;
-        int nstride;
-        pixman_image_t *surface;
-        PixmanData *pixman_data;
-        HBITMAP bitmap;
-        HANDLE mutex;
-
-        memset(&bitmap_info, 0, sizeof(bitmap_info));
-        bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
-        bitmap_info.inf.bmiHeader.biWidth = width;
-
-        bitmap_info.inf.bmiHeader.biHeight = (!top_down) ? height : -height;
-
-        bitmap_info.inf.bmiHeader.biPlanes = 1;
-        switch (format) {
-        case PIXMAN_a8r8g8b8:
-        case PIXMAN_x8r8g8b8:
-            bitmap_info.inf.bmiHeader.biBitCount = 32;
-            nstride = width * 4;
-            break;
-        case PIXMAN_x1r5g5b5:
-        case PIXMAN_r5g6b5:
-            bitmap_info.inf.bmiHeader.biBitCount = 16;
-            nstride = SPICE_ALIGN(width * 2, 4);
-            break;
-        case PIXMAN_a8:
-            bitmap_info.inf.bmiHeader.biBitCount = 8;
-            nstride = SPICE_ALIGN(width, 4);
-            break;
-        case PIXMAN_a1:
-            bitmap_info.inf.bmiHeader.biBitCount = 1;
-            nstride = SPICE_ALIGN(width, 32) / 8;
-            break;
-        default:
-            CANVAS_ERROR("invalid format");
-        }
-
-        bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
-
-        mutex = CreateMutex(NULL, 0, NULL);
-        if (!mutex) {
-            CANVAS_ERROR("Unable to CreateMutex");
-        }
-
-        bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
-        if (!bitmap) {
-            CloseHandle(mutex);
-            CANVAS_ERROR("Unable to CreateDIBSection");
-        }
-
-        if (top_down) {
-            src = data;
-        } else {
-            src = data + nstride * (height - 1);
-            nstride = -nstride;
-        }
-
-        surface = pixman_image_create_bits(format, width, height, (uint32_t *)src, nstride);
-        if (surface == NULL) {
-            CloseHandle(mutex);
-            DeleteObject(bitmap);
-            CANVAS_ERROR("create surface failed, out of memory");
-        }
-        pixman_data = pixman_image_add_data(surface);
-        pixman_data->format = format;
-        pixman_data->bitmap = bitmap;
-        pixman_data->mutex = mutex;
-        gdi_handlers++;
-        return surface;
-    } else {
-#endif
-    if (top_down) {
-        pixman_image_t *surface;
-        PixmanData *data;
-
-        surface = pixman_image_create_bits(format, width, height, NULL, 0);
-        data = pixman_image_add_data(surface);
-        data->format = format;
-        return surface;
-    } else {
-        // NOTE: we assume here that the lz decoders always decode to RGB32.
-        int stride = 0;
-        switch (format) {
-        case PIXMAN_a8r8g8b8:
-        case PIXMAN_x8r8g8b8:
-            stride = width * 4;
-            break;
-        case PIXMAN_x1r5g5b5:
-        case PIXMAN_r5g6b5:
-            stride = SPICE_ALIGN(width * 2, 4);
-            break;
-        case PIXMAN_a8:
-            stride = SPICE_ALIGN(width, 4);
-            break;
-        case PIXMAN_a1:
-            stride = SPICE_ALIGN(width, 32) / 8;
-            break;
-        default:
-            CANVAS_ERROR("invalid format");
-        }
-        stride = -stride;
-        return __surface_create_stride(format, width, height, stride);
-    }
-#ifdef WIN32
-}
-
-#endif
-}
-
-#ifdef WIN32
-pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
-                                      int stride)
-#else
-pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
-                                      int stride)
-#endif
-{
-#ifdef WIN32
-    if (dc) {
-        if (abs(stride) == (width * 4)) {
-            return surface_create(dc, format, width, height, (stride > 0));
-        }
-    }
-#endif
-
-    return __surface_create_stride(format, width, height, stride);
-}
-
-pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
-                                       pixman_format_code_t pixman_format, int width,
-                                       int height, int gross_pixels, int top_down)
-{
-    int stride;
-    pixman_image_t *surface = NULL;
-
-    stride = (gross_pixels / height) * (PIXMAN_FORMAT_BPP (pixman_format) / 8);
-
-    if (!top_down) {
-        stride = -stride;
-    }
-
-   surface = surface_create_stride(
-#ifdef WIN32
-            canvas_data->dc,
-#endif
-            pixman_format, width, height, stride);
-    canvas_data->out_surface = surface;
-    return surface;
-}
-
diff --git a/common/canvas_utils.h b/common/canvas_utils.h
deleted file mode 100644
index fe66f85..0000000
--- a/common/canvas_utils.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_CANVAS_UTILS
-#define _H_CANVAS_UTILS
-
-#ifdef WIN32
-#include <windows.h>
-#endif
-
-#include <spice/types.h>
-
-#include "pixman_utils.h"
-#include "lz.h"
-
-typedef struct PixmanData {
-#ifdef WIN32
-    HBITMAP bitmap;
-    HANDLE mutex;
-#endif
-    uint8_t *data;
-    pixman_format_code_t format;
-} PixmanData;
-
-void spice_pixman_image_set_format(pixman_image_t *image,
-                                   pixman_format_code_t format);
-pixman_format_code_t spice_pixman_image_get_format(pixman_image_t *image);
-
-
-#ifdef WIN32
-pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
-                               int width, int height, int top_down);
-#else
-pixman_image_t *surface_create(pixman_format_code_t format, int width, int height, int top_down);
-#endif
-
-#ifdef WIN32
-pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
-                                      int stride);
-#else
-pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
-                                      int stride);
-#endif
-
-
-typedef struct LzDecodeUsrData {
-#ifdef WIN32
-    HDC dc;
-#endif
-    pixman_image_t       *out_surface;
-} LzDecodeUsrData;
-
-
-pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
-                                       pixman_format_code_t pixman_format, int width,
-                                       int height, int gross_pixels, int top_down);
-#endif
diff --git a/common/demarshallers.h b/common/demarshallers.h
deleted file mode 100644
index fc2f75a..0000000
--- a/common/demarshallers.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef _H_DEMARSHAL
-#define _H_DEMARSHAL
-
-typedef void (*message_destructor_t)(uint8_t *message);
-typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor,
-						size_t *size_out, message_destructor_t *free_message);
-
-spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type);
-spice_parse_channel_func_t spice_get_server_channel_parser1(uint32_t channel, unsigned int *max_message_type);
-
-#endif
-
diff --git a/common/draw.h b/common/draw.h
deleted file mode 100644
index 994aebb..0000000
--- a/common/draw.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are
-   met:
-
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in
-         the documentation and/or other materials provided with the
-         distribution.
-       * Neither the name of the copyright holder nor the names of its
-         contributors may be used to endorse or promote products derived
-         from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
-   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-   TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-   PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef _H_SPICE_DRAW
-#define _H_SPICE_DRAW
-
-#include <spice/types.h>
-#include <spice/enums.h>
-#include "mem.h"
-
-#define SPICE_GET_ADDRESS(addr) ((void *)(uintptr_t)(addr))
-#define SPICE_SET_ADDRESS(addr, val) ((addr) = (unsigned long)(val))
-
-typedef int32_t SPICE_FIXED28_4;
-typedef uint64_t SPICE_ADDRESS;
-
-typedef struct SpicePointFix {
-    SPICE_FIXED28_4 x;
-    SPICE_FIXED28_4 y;
-} SpicePointFix;
-
-typedef struct SpicePoint {
-    int32_t x;
-    int32_t y;
-} SpicePoint;
-
-typedef struct SpicePoint16 {
-    int16_t x;
-    int16_t y;
-} SpicePoint16;
-
-typedef struct SpiceRect {
-    int32_t left;
-    int32_t top;
-    int32_t right;
-    int32_t bottom;
-} SpiceRect;
-
-typedef struct SpicePathSeg {
-    uint32_t flags;
-    uint32_t count;
-    SpicePointFix points[0];
-} SpicePathSeg;
-
-typedef struct SpicePath {
-  uint32_t num_segments;
-  SpicePathSeg *segments[0];
-} SpicePath;
-
-typedef struct SpiceClipRects {
-  uint32_t num_rects;
-  SpiceRect rects[0];
-} SpiceClipRects;
-
-typedef struct SpiceClip {
-    uint32_t type;
-    SpiceClipRects *rects;
-} SpiceClip;
-
-typedef struct SpicePalette {
-    uint64_t unique;
-    uint16_t num_ents;
-    uint32_t ents[0];
-} SpicePalette;
-
-#define SPICE_SURFACE_FMT_DEPTH(_d) ((_d) & 0x3f)
-
-typedef struct SpiceImageDescriptor {
-    uint64_t id;
-    uint8_t type;
-    uint8_t flags;
-    uint32_t width;
-    uint32_t height;
-} SpiceImageDescriptor;
-
-typedef struct SpiceBitmap {
-    uint8_t format;
-    uint8_t flags;
-    uint32_t x;
-    uint32_t y;
-    uint32_t stride;
-    SpicePalette *palette;
-    uint64_t palette_id;
-    SpiceChunks *data;
-} SpiceBitmap;
-
-typedef struct SpiceSurface {
-    uint32_t surface_id;
-} SpiceSurface;
-
-typedef struct SpiceQUICData {
-    uint32_t data_size;
-    SpiceChunks *data;
-} SpiceQUICData, SpiceLZRGBData, SpiceJPEGData;
-
-typedef struct SpiceLZPLTData {
-    uint8_t flags;
-    uint32_t data_size;
-    SpicePalette *palette;
-    uint64_t palette_id;
-    SpiceChunks *data;
-} SpiceLZPLTData;
-
-typedef struct SpiceZlibGlzRGBData {
-    uint32_t glz_data_size;
-    uint32_t data_size;
-    SpiceChunks *data;
-} SpiceZlibGlzRGBData;
-
-typedef struct SpiceJPEGAlphaData {
-    uint8_t flags;
-    uint32_t jpeg_size;
-    uint32_t data_size;
-    SpiceChunks *data;
-} SpiceJPEGAlphaData;
-
-
-typedef struct SpiceImage {
-    SpiceImageDescriptor descriptor;
-    union {
-        SpiceBitmap         bitmap;
-        SpiceQUICData       quic;
-        SpiceSurface        surface;
-        SpiceLZRGBData      lz_rgb;
-        SpiceLZPLTData      lz_plt;
-        SpiceJPEGData       jpeg;
-        SpiceZlibGlzRGBData zlib_glz;
-        SpiceJPEGAlphaData  jpeg_alpha;
-    } u;
-} SpiceImage;
-
-typedef struct SpicePattern {
-    SpiceImage *pat;
-    SpicePoint pos;
-} SpicePattern;
-
-typedef struct SpiceBrush {
-    uint32_t type;
-    union {
-        uint32_t color;
-        SpicePattern pattern;
-    } u;
-} SpiceBrush;
-
-typedef struct SpiceQMask {
-    uint8_t flags;
-    SpicePoint pos;
-    SpiceImage *bitmap;
-} SpiceQMask;
-
-typedef struct SpiceFill {
-    SpiceBrush brush;
-    uint16_t rop_descriptor;
-    SpiceQMask mask;
-} SpiceFill;
-
-typedef struct SpiceOpaque {
-    SpiceImage *src_bitmap;
-    SpiceRect src_area;
-    SpiceBrush brush;
-    uint16_t rop_descriptor;
-    uint8_t scale_mode;
-    SpiceQMask mask;
-} SpiceOpaque;
-
-typedef struct SpiceCopy {
-    SpiceImage *src_bitmap;
-    SpiceRect src_area;
-    uint16_t rop_descriptor;
-    uint8_t scale_mode;
-    SpiceQMask mask;
-} SpiceCopy, SpiceBlend;
-
-typedef struct SpiceTransparent {
-    SpiceImage *src_bitmap;
-    SpiceRect src_area;
-    uint32_t src_color;
-    uint32_t true_color;
-} SpiceTransparent;
-
-typedef struct SpiceAlphaBlend {
-    uint16_t alpha_flags;
-    uint8_t alpha;
-    SpiceImage *src_bitmap;
-    SpiceRect src_area;
-} SpiceAlphaBlend;
-
-typedef struct SpiceRop3 {
-    SpiceImage *src_bitmap;
-    SpiceRect src_area;
-    SpiceBrush brush;
-    uint8_t rop3;
-    uint8_t scale_mode;
-    SpiceQMask mask;
-} SpiceRop3;
-
-typedef struct SpiceBlackness {
-    SpiceQMask mask;
-} SpiceBlackness, SpiceInvers, SpiceWhiteness;
-
-typedef struct SpiceLineAttr {
-    uint8_t flags;
-    uint8_t style_nseg;
-    SPICE_FIXED28_4 *style;
-} SpiceLineAttr;
-
-typedef struct SpiceStroke {
-    SpicePath *path;
-    SpiceLineAttr attr;
-    SpiceBrush brush;
-    uint16_t fore_mode;
-    uint16_t back_mode;
-} SpiceStroke;
-
-typedef struct SpiceRasterGlyph {
-    SpicePoint render_pos;
-    SpicePoint glyph_origin;
-    uint16_t width;
-    uint16_t height;
-    uint8_t data[0];
-} SpiceRasterGlyph;
-
-typedef struct SpiceString {
-    uint16_t length;
-    uint16_t flags;
-    SpiceRasterGlyph *glyphs[0];
-} SpiceString;
-
-typedef struct SpiceText {
-    SpiceString *str;
-    SpiceRect back_area;
-    SpiceBrush fore_brush;
-    SpiceBrush back_brush;
-    uint16_t fore_mode;
-    uint16_t back_mode;
-} SpiceText;
-
-typedef struct SpiceCursorHeader {
-    uint64_t unique;
-    uint16_t type;
-    uint16_t width;
-    uint16_t height;
-    uint16_t hot_spot_x;
-    uint16_t hot_spot_y;
-} SpiceCursorHeader;
-
-#endif /* _H_SPICE_DRAW */
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
deleted file mode 100644
index a11ba90..0000000
--- a/common/gdi_canvas.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <windows.h>
-#include <wingdi.h>
-#include "gdi_canvas.h"
-#define GDI_CANVAS
-#include "canvas_base.c"
-#include "rop3.h"
-#include "rect.h"
-#include "region.h"
-#include "threads.h"
-
-typedef struct GdiCanvas GdiCanvas;
-
-struct GdiCanvas {
-    CanvasBase base;
-    HDC dc;
-    RecurciveMutex* lock;
-};
-
-
-struct BitmapData {
-    HBITMAP hbitmap;
-    HBITMAP prev_hbitmap;
-    SpicePoint pos;
-    uint8_t flags;
-    HDC dc;
-    int cache;
-    int from_surface;
-};
-
-#define _rop3_brush 0xf0
-#define _rop3_src 0xcc
-#define _rop3_dest 0xaa
-
-uint32_t raster_ops[] = {
-    0x00000042,
-    0x00010289,
-    0x00020C89,
-    0x000300AA,
-    0x00040C88,
-    0x000500A9,
-    0x00060865,
-    0x000702C5,
-    0x00080F08,
-    0x00090245,
-    0x000A0329,
-    0x000B0B2A,
-    0x000C0324,
-    0x000D0B25,
-    0x000E08A5,
-    0x000F0001,
-    0x00100C85,
-    0x001100A6,
-    0x00120868,
-    0x001302C8,
-    0x00140869,
-    0x001502C9,
-    0x00165CCA,
-    0x00171D54,
-    0x00180D59,
-    0x00191CC8,
-    0x001A06C5,
-    0x001B0768,
-    0x001C06CA,
-    0x001D0766,
-    0x001E01A5,
-    0x001F0385,
-    0x00200F09,
-    0x00210248,
-    0x00220326,
-    0x00230B24,
-    0x00240D55,
-    0x00251CC5,
-    0x002606C8,
-    0x00271868,
-    0x00280369,
-    0x002916CA,
-    0x002A0CC9,
-    0x002B1D58,
-    0x002C0784,
-    0x002D060A,
-    0x002E064A,
-    0x002F0E2A,
-    0x0030032A,
-    0x00310B28,
-    0x00320688,
-    0x00330008,
-    0x003406C4,
-    0x00351864,
-    0x003601A8,
-    0x00370388,
-    0x0038078A, // PSDPoax
-    0x00390604, // SPDnox
-    0x003A0644, // SPDSxox
-    0x003B0E24, // SPDnoan
-    0x003C004A, // PSx
-    0x003D18A4, // SPDSonox
-    0x003E1B24, // SPDSnaox
-    0x003F00EA, // PSan
-    0x00400F0A, // PSDnaa
-    0x00410249, // DPSxon
-    0x00420D5D, // SDxPDxa
-    0x00431CC4, // SPDSanaxn
-    0x00440328, // SDna SRCERASE
-    0x00450B29, // DPSnaon
-    0x004606C6, // DSPDaox
-    0x0047076A, // PSDPxaxn
-    0x00480368, // SDPxa
-    0x004916C5, // PDSPDaoxxn
-    0x004A0789, // DPSDoax
-    0x004B0605, // PDSnox
-    0x004C0CC8, // SDPana
-    0x004D1954, // SSPxDSxoxn
-    0x004E0645, // PDSPxox
-    0x004F0E25, // PDSnoan
-    0x00500325, // PDna
-    0x00510B26, // DSPnaon
-    0x005206C9, // DPSDaox
-    0x00530764, // SPDSxaxn
-    0x005408A9, // DPSonon
-    0x00550009, // Dn DSTINVERT
-    0x005601A9, // DPSox
-    0x00570389, // DPSoan
-    0x00580785, // PDSPoax
-    0x00590609, // DPSnox
-    0x005A0049, // DPx PATINVERT
-    0x005B18A9, // DPSDonox
-    0x005C0649, // DPSDxox
-    0x005D0E29, // DPSnoan
-    0x005E1B29, // DPSDnaox
-    0x005F00E9, // DPan
-    0x00600365, // PDSxa
-    0x006116C6, // DSPDSaoxxn
-    0x00620786, // DSPDoax
-    0x00630608, // SDPnox
-    0x00640788, // SDPSoax
-    0x00650606, // DSPnox
-    0x00660046, // DSx SRCINVERT
-    0x006718A8, // SDPSonox
-    0x006858A6, // DSPDSonoxxn
-    0x00690145, // PDSxxn
-    0x006A01E9, // DPSax
-    0x006B178A, // PSDPSoaxxn
-    0x006C01E8, // SDPax
-    0x006D1785, // PDSPDoaxxn
-    0x006E1E28, // SDPSnoax
-    0x006F0C65, // PDSxnan
-    0x00700CC5, // PDSana
-    0x00711D5C, // SSDxPDxaxn
-    0x00720648, // SDPSxox
-    0x00730E28, // SDPnoan
-    0x00740646, // DSPDxox
-    0x00750E26, // DSPnoan
-    0x00761B28, // SDPSnaox
-    0x007700E6, // DSan
-    0x007801E5, // PDSax
-    0x00791786, // DSPDSoaxxn
-    0x007A1E29, // DPSDnoax
-    0x007B0C68, // SDPxnan
-    0x007C1E24, // SPDSnoax
-    0x007D0C69, // DPSxnan
-    0x007E0955, // SPxDSxo
-    0x007F03C9, // DPSaan
-    0x008003E9, // DPSaa
-    0x00810975, // SPxDSxon
-    0x00820C49, // DPSxna
-    0x00831E04, // SPDSnoaxn
-    0x00840C48, // SDPxna
-    0x00851E05, // PDSPnoaxn
-    0x008617A6, // DSPDSoaxx
-    0x008701C5, // PDSaxn
-    0x008800C6, // DSa SRCAND
-    0x00891B08, // SDPSnaoxn
-    0x008A0E06, // DSPnoa
-    0x008B0666, // DSPDxoxn
-    0x008C0E08, // SDPnoa
-    0x008D0668, // SDPSxoxn
-    0x008E1D7C, // SSDxPDxax
-    0x008F0CE5, // PDSanan
-    0x00900C45, // PDSxna
-    0x00911E08, // SDPSnoaxn
-    0x009217A9, // DPSDPoaxx
-    0x009301C4, // SPDaxn
-    0x009417AA, // PSDPSoaxx
-    0x009501C9, // DPSaxn
-    0x00960169, // DPSxx
-    0x0097588A, // PSDPSonoxx
-    0x00981888, // SDPSonoxn
-    0x00990066, // DSxn
-    0x009A0709, // DPSnax
-    0x009B07A8, // SDPSoaxn
-    0x009C0704, // SPDnax
-    0x009D07A6, // DSPDoaxn
-    0x009E16E6, // DSPDSaoxx
-    0x009F0345, // PDSxan
-    0x00A000C9, // DPa
-    0x00A11B05, // PDSPnaoxn
-    0x00A20E09, // DPSnoa
-    0x00A30669, // DPSDxoxn
-    0x00A41885, // PDSPonoxn
-    0x00A50065, // PDxn
-    0x00A60706, // DSPnax
-    0x00A707A5, // PDSPoaxn
-    0x00A803A9, // DPSoa
-    0x00A90189, // DPSoxn
-    0x00AA0029, // D
-    0x00AB0889, // DPSono
-    0x00AC0744, // SPDSxax
-    0x00AD06E9, // DPSDaoxn
-    0x00AE0B06, // DSPnao
-    0x00AF0229, // DPno
-    0x00B00E05, // PDSnoa
-    0x00B10665, // PDSPxoxn
-    0x00B21974, // SSPxDSxox
-    0x00B30CE8, // SDPanan
-    0x00B4070A, // PSDnax
-    0x00B507A9, // DPSDoaxn
-    0x00B616E9, // DPSDPaoxx
-    0x00B70348, // SDPxan
-    0x00B8074A, // PSDPxax
-    0x00B906E6, // DSPDaoxn
-    0x00BA0B09, // DPSnao
-    0x00BB0226, // DSno MERGEPAINT
-    0x00BC1CE4, // SPDSanax
-    0x00BD0D7D, // SDxPDxan
-    0x00BE0269, // DPSxo
-    0x00BF08C9, // DPSano
-    0x00C000CA, // PSa MERGECOPY
-    0x00C11B04, // SPDSnaoxn
-    0x00C21884, // SPDSonoxn
-    0x00C3006A, // PSxn
-    0x00C40E04, // SPDnoa
-    0x00C50664, // SPDSxoxn
-    0x00C60708, // SDPnax
-    0x00C707AA, // PSDPoaxn
-    0x00C803A8, // SDPoa
-    0x00C90184, // SPDoxn
-    0x00CA0749, // DPSDxax
-    0x00CB06E4, // SPDSaoxn
-    0x00CC0020, // S SRCCOPY
-    0x00CD0888, // SDPono
-    0x00CE0B08, // SDPnao
-    0x00CF0224, // SPno
-    0x00D00E0A, // PSDnoa
-    0x00D1066A, // PSDPxoxn
-    0x00D20705, // PDSnax
-    0x00D307A4, // SPDSoaxn
-    0x00D41D78, // SSPxPDxax
-    0x00D50CE9, // DPSanan
-    0x00D616EA, // PSDPSaoxx
-    0x00D70349, // DPSxan
-    0x00D80745, // PDSPxax
-    0x00D906E8, // SDPSaoxn
-    0x00DA1CE9, // DPSDanax
-    0x00DB0D75, // SPxDSxan
-    0x00DC0B04, // SPDnao
-    0x00DD0228, // SDno
-    0x00DE0268, // SDPxo
-    0x00DF08C8, // SDPano
-    0x00E003A5, // PDSoa
-    0x00E10185, // PDSoxn
-    0x00E20746, // DSPDxax
-    0x00E306EA, // PSDPaoxn
-    0x00E40748, // SDPSxax
-    0x00E506E5, // PDSPaoxn
-    0x00E61CE8, // SDPSanax
-    0x00E70D79, // SPxPDxan
-    0x00E81D74, // SSPxDSxax
-    0x00E95CE6, // DSPDSanaxxn
-    0x00EA02E9, // DPSao
-    0x00EB0849, // DPSxno
-    0x00EC02E8, // SDPao
-    0x00ED0848, // SDPxno
-    0x00EE0086, // DSo SRCPAINT
-    0x00EF0A08, // SDPnoo
-    0x00F00021, // P PATCOPY
-    0x00F10885, // PDSono
-    0x00F20B05, // PDSnao
-    0x00F3022A, // PSno
-    0x00F40B0A, // PSDnao
-    0x00F50225, // PDno
-    0x00F60265, // PDSxo
-    0x00F708C5, // PDSano
-    0x00F802E5, // PDSao
-    0x00F90845, // PDSxno
-    0x00FA0089, // DPo
-    0x00FB0A09, // DPSnoo PATPAINT
-    0x00FC008A, // PSo
-    0x00FD0A0A, // PSDnoo
-    0x00FE02A9, // DPSoo
-    0x00FF0062 // 1 WHITENESS
-};
-
-static void set_path(GdiCanvas *canvas, SpicePath *s)
-{
-    unsigned int i;
-
-    for (i = 0; i < s->num_segments; i++) {
-        SpicePathSeg* seg = s->segments[0];
-        SpicePointFix* point = seg->points;
-        SpicePointFix* end_point = point + seg->count;
-
-        if (seg->flags & SPICE_PATH_BEGIN) {
-            BeginPath(canvas->dc);
-            if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y),
-                          NULL)) {
-                spice_critical("MoveToEx failed");
-                return;
-            }
-            point++;
-        }
-
-        if (seg->flags & SPICE_PATH_BEZIER) {
-            spice_return_if_fail((point - end_point) % 3 == 0);
-            for (; point + 2 < end_point; point += 3) {
-                POINT points[3];
-
-                points[0].x = (int)fix_to_double(point[0].x);
-                points[0].y = (int)fix_to_double(point[0].y);
-                points[1].x = (int)fix_to_double(point[1].x);
-                points[1].y = (int)fix_to_double(point[1].y);
-                points[2].x = (int)fix_to_double(point[2].x);
-                points[2].y = (int)fix_to_double(point[2].y);
-                if (!PolyBezierTo(canvas->dc, points, 3)) {
-                    spice_critical("PolyBezierTo failed");
-                    return;
-                }
-            }
-        } else {
-            for (; point < end_point; point++) {
-                if (!LineTo(canvas->dc, (int)fix_to_double(point->x),
-                            (int)fix_to_double(point->y))) {
-                    spice_critical("LineTo failed");
-                }
-            }
-        }
-
-        if (seg->flags & SPICE_PATH_END) {
-
-            if (seg->flags & SPICE_PATH_CLOSE) {
-                if (!CloseFigure(canvas->dc)) {
-                    spice_critical("CloseFigure failed");
-                }
-            }
-
-            if (!EndPath(canvas->dc)) {
-                spice_critical("EndPath failed");
-            }
-        }
-
-    }
-}
-
-static void set_scale_mode(GdiCanvas *canvas, uint8_t scale_mode)
-{
-    if (scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE) {
-        SetStretchBltMode(canvas->dc, HALFTONE);
-    } else if (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) {
-        SetStretchBltMode(canvas->dc, COLORONCOLOR);
-    } else {
-        spice_critical("Unknown ScaleMode");
-    }
-}
-
-static void set_clip(GdiCanvas *canvas, SpiceClip *clip)
-{
-    switch (clip->type) {
-    case SPICE_CLIP_TYPE_NONE:
-        if (SelectClipRgn(canvas->dc, NULL) == ERROR) {
-            spice_critical("SelectClipRgn failed");
-        }
-        break;
-    case SPICE_CLIP_TYPE_RECTS: {
-        uint32_t n = clip->rects->num_rects;
-
-        SpiceRect *now = clip->rects->rects;
-        SpiceRect *end = now + n;
-
-        if (now < end) {
-            HRGN main_hrgn;
-
-            main_hrgn = CreateRectRgn(now->left, now->top, now->right, now->bottom);
-            if (!main_hrgn) {
-                return;
-            }
-            now++;
-            for (; now < end; now++) {
-                HRGN combaine_hrgn;
-                combaine_hrgn = CreateRectRgn(now->left, now->top, now->right,
-                                              now->bottom);
-                if (!combaine_hrgn) {
-                    spice_critical("Unable to CreateRectRgn");
-                    DeleteObject(main_hrgn);
-                    return;
-                }
-                if (CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR) == ERROR) {
-                    spice_critical("Unable to CombineRgn");
-                    DeleteObject(combaine_hrgn);
-                    return;
-                }
-                DeleteObject(combaine_hrgn);
-            }
-            if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
-                spice_critical("Unable to SelectClipRgn");
-            }
-            DeleteObject(main_hrgn);
-        }
-        break;
-    }
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-static void copy_bitmap(const uint8_t *src_image, int height, int src_stride,
-                        uint8_t *dest_bitmap, int dest_stride)
-{
-    int copy_width = MIN(dest_stride, src_stride);
-    int y = 0;
-
-    spice_return_if_fail(dest_stride >= 0 && src_stride >= 0);
-
-    while (y < height) {
-        memcpy(dest_bitmap, src_image, copy_width);
-        src_image += src_stride;
-        dest_bitmap += dest_stride;
-        y++;
-    }
-}
-
-static void copy_bitmap_alpha(const uint8_t *src_alpha, int height, int width, int src_stride,
-                              uint8_t *dest_bitmap, int dest_stride, int alpha_bits_size)
-{
-    int y = 0;
-    uint8_t i_offset;
-    int i_count = 0;
-    int i = 0;
-    int width_div_stride;
-
-    width_div_stride = width / src_stride;
-
-    if (alpha_bits_size == 1) {
-        i_offset = 1;
-    } else {
-        i_offset = 8;
-    }
-
-
-    while (y < height) {
-        int x;
-
-        for (x = 0; x < width; ++x) {
-            uint8_t alphaval;
-            double alpha;
-
-            alphaval = src_alpha[i];
-            alphaval = alphaval >> (i_count * i_offset);
-            alphaval &= ((uint8_t)0xff >> (8 - i_offset));
-            alphaval = ((255 * alphaval) / ((uint8_t)0xff >> (8 - i_offset)));
-
-            dest_bitmap[x * 4 + 3] = alphaval;
-            alpha = (double)alphaval / 0xff;
-            dest_bitmap[x * 4 + 2] = (uint8_t)(alpha * dest_bitmap[x * 4 + 2]);
-            dest_bitmap[x * 4 + 1] = (uint8_t)(alpha * dest_bitmap[x * 4 + 1]);
-            dest_bitmap[x * 4] = (uint8_t)(alpha * dest_bitmap[x * 4]);
-
-            i_count++;
-            if (i_count == (8 / i_offset)) {
-                i++;
-                i_count = 0;
-            }
-        }
-
-        dest_bitmap += width * 4;
-        i = 0;
-        src_alpha += src_stride;
-        i_count = 0;
-        y++;
-    }
-}
-
-static uint8_t *create_bitmap(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
-                              const uint8_t *bitmap_data, int width, int height,
-                              int stride, int bits, int rotate)
-{
-    uint8_t *data;
-    const uint8_t *src_data;
-    uint32_t nstride;
-    struct {
-        BITMAPINFO inf;
-        RGBQUAD palette[255];
-    } bitmap_info;
-
-    memset(&bitmap_info, 0, sizeof(bitmap_info));
-    bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
-    bitmap_info.inf.bmiHeader.biWidth = width;
-    if (stride < 0) {
-        bitmap_info.inf.bmiHeader.biHeight = height;
-    } else {
-        bitmap_info.inf.bmiHeader.biHeight = -height;
-    }
-
-    if (rotate) {
-        bitmap_info.inf.bmiHeader.biHeight = -bitmap_info.inf.bmiHeader.biHeight;
-    }
-
-    bitmap_info.inf.bmiHeader.biPlanes = 1;
-    bitmap_info.inf.bmiHeader.biBitCount = bits;
-    bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
-
-    *dc = create_compatible_dc();
-    if (!*dc) {
-        spice_critical("create_compatible_dc() failed");
-        return NULL;
-    }
-
-    *bitmap = CreateDIBSection(*dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
-    if (!*bitmap) {
-        spice_critical("Unable to CreateDIBSection");
-        DeleteDC(*dc);
-        return NULL;
-    }
-    *prev_bitmap = (HBITMAP)SelectObject(*dc, *bitmap);
-
-    if (stride < 0) {
-        src_data = bitmap_data - (height - 1) * -stride;
-    } else {
-        src_data = bitmap_data;
-    }
-
-    switch (bits) {
-    case 1:
-        nstride = SPICE_ALIGN(width, 32) / 8;
-        break;
-    case 8:
-        nstride = SPICE_ALIGN(width, 4);
-        break;
-    case 16:
-        nstride = SPICE_ALIGN(width * 2, 4);
-        break;
-    case 32:
-        nstride = width * 4;
-        break;
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-
-    if (bitmap_data) {
-        if (stride < 0) {
-            copy_bitmap(src_data, height, -stride, data, nstride);
-        } else {
-            copy_bitmap(src_data, height, stride, data, nstride);
-        }
-    }
-
-    return data;
-}
-
-static uint8_t *create_bitmap_from_pixman(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
-										   pixman_image_t *surface, int rotate)
-{
-    return create_bitmap(bitmap, prev_bitmap, dc,
-                         (uint8_t*)pixman_image_get_data(surface),
-						 pixman_image_get_width(surface),
-						 pixman_image_get_height(surface),
-						 pixman_image_get_stride(surface),
-						 spice_pixman_image_get_bpp(surface),
-						 rotate);
-}
-
-
-static void release_bitmap(HDC dc, HBITMAP bitmap, HBITMAP prev_bitmap, int cache)
-{
-    bitmap = (HBITMAP)SelectObject(dc, prev_bitmap);
-    if (!cache) {
-        DeleteObject(bitmap);
-    }
-    DeleteDC(dc);
-}
-
-static inline uint8_t get_converted_color(uint8_t color)
-{
-    uint8_t msb;
-
-    msb = color & 0xE0;
-    msb = msb >> 5;
-    color |= msb;
-    return color;
-}
-
-static inline COLORREF get_color_ref(GdiCanvas *canvas, uint32_t color)
-{
-    int shift = canvas->base.color_shift == 8 ? 0 : 3;
-    uint8_t r, g, b;
-
-    b = (color & canvas->base.color_mask);
-    color >>= canvas->base.color_shift;
-    g = (color & canvas->base.color_mask);
-    color >>= canvas->base.color_shift;
-    r = (color & canvas->base.color_mask);
-    if (shift) {
-        r = get_converted_color(r << shift);
-        g = get_converted_color(g << shift);
-        b = get_converted_color(b << shift);
-    }
-    return RGB(r, g, b);
-}
-
-static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush, RecurciveMutex **brush_lock)
-{
-    HBRUSH hbrush;
-
-    *brush_lock = NULL;
-
-    switch (brush->type) {
-    case SPICE_BRUSH_TYPE_SOLID:
-        if (!(hbrush = CreateSolidBrush(get_color_ref(canvas, brush->u.color)))) {
-            spice_critical("CreateSolidBrush failed");
-            return NULL;
-        }
-        return hbrush;
-    case SPICE_BRUSH_TYPE_PATTERN: { 
-        GdiCanvas *gdi_surface = NULL;
-        HBRUSH hbrush;
-        pixman_image_t *surface = NULL;
-        HDC dc;
-        HBITMAP bitmap;
-        HBITMAP prev_bitmap;
-
-        gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
-        if (gdi_surface) {
-            bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
-            if (!bitmap) {
-                spice_critical("GetCurrentObject failed");
-                return NULL;
-            }
-            *brush_lock = gdi_surface->lock;
-        } else {
-            surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
-            if (!create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, surface, 0)) {
-                spice_critical("create_bitmap failed");
-                return NULL;
-            }
-        }
-
-        if (!(hbrush = CreatePatternBrush(bitmap))) {
-            spice_critical("CreatePatternBrush failed");
-            return NULL;
-        }
-
-        if (!gdi_surface) {
-            release_bitmap(dc, bitmap, prev_bitmap, 0);
-            pixman_image_unref(surface);
-        }
-        return hbrush;
-    }
-    case SPICE_BRUSH_TYPE_NONE:
-        return NULL;
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-}
-
-static HBRUSH set_brush(HDC dc, HBRUSH hbrush, SpiceBrush *brush)
-{
-    switch (brush->type) {
-    case SPICE_BRUSH_TYPE_SOLID: {
-        return (HBRUSH)SelectObject(dc, hbrush);
-    }
-    case SPICE_BRUSH_TYPE_PATTERN: {
-        HBRUSH prev_hbrush;
-        prev_hbrush = (HBRUSH)SelectObject(dc, hbrush);
-        if (!SetBrushOrgEx(dc, brush->u.pattern.pos.x, brush->u.pattern.pos.y, NULL)) {
-            spice_critical("SetBrushOrgEx failed");
-            return NULL;
-        }
-        return prev_hbrush;
-    }
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-}
-
-static void unset_brush(HDC dc, HBRUSH prev_hbrush)
-{
-    if (!prev_hbrush) {
-        return;
-    }
-    prev_hbrush = (HBRUSH)SelectObject(dc, prev_hbrush);
-    DeleteObject(prev_hbrush);
-}
-
-uint8_t calc_rop3(uint16_t rop3_bits, int brush)
-{
-    uint8_t rop3 = 0;
-    uint8_t rop3_src = _rop3_src;
-    uint8_t rop3_dest = _rop3_dest;
-    uint8_t rop3_brush = _rop3_brush;
-    uint8_t rop3_src_brush;
-
-    if (rop3_bits & SPICE_ROPD_INVERS_SRC) {
-        rop3_src = ~rop3_src;
-    }
-    if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) {
-        rop3_brush = ~rop3_brush;
-    }
-    if (rop3_bits & SPICE_ROPD_INVERS_DEST) {
-        rop3_dest = ~rop3_dest;
-    }
-
-    if (brush) {
-        rop3_src_brush = rop3_brush;
-    } else {
-        rop3_src_brush = rop3_src;
-    }
-
-    if (rop3_bits & SPICE_ROPD_OP_PUT) {
-        rop3 = rop3_src_brush;
-    }
-    if (rop3_bits & SPICE_ROPD_OP_OR) {
-        rop3 = rop3_src_brush | rop3_dest;
-    }
-    if (rop3_bits & SPICE_ROPD_OP_AND) {
-        rop3 = rop3_src_brush & rop3_dest;
-    }
-    if (rop3_bits & SPICE_ROPD_OP_XOR) {
-        rop3 = rop3_src_brush ^ rop3_dest;
-    }
-    if (rop3_bits & SPICE_ROPD_INVERS_RES) {
-        rop3 = ~rop3_dest;
-    }
-
-    if (rop3_bits & SPICE_ROPD_OP_BLACKNESS || rop3_bits & SPICE_ROPD_OP_WHITENESS ||
-        rop3_bits & SPICE_ROPD_OP_INVERS) {
-        spice_warn_if_reached("invalid rop3 type");
-        return 0;
-    }
-    return rop3;
-}
-
-uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
-{
-    uint8_t rop3 = 0;
-    uint8_t rop3_src = _rop3_src;
-    uint8_t rop3_brush = _rop3_brush;
-
-    if (rop3_bits & SPICE_ROPD_INVERS_SRC) {
-        rop3_src = ~rop3_src;
-    }
-    if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) {
-        rop3_brush = ~rop3_brush;
-    }
-
-    if (rop3_bits & SPICE_ROPD_OP_OR) {
-        rop3 = rop3_src | rop3_brush;
-    }
-    if (rop3_bits & SPICE_ROPD_OP_AND) {
-        rop3 = rop3_src & rop3_brush;
-    }
-    if (rop3_bits & SPICE_ROPD_OP_XOR) {
-        rop3 = rop3_src ^ rop3_brush;
-    }
-
-    return rop3;
-}
-
-static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
-{
-    GdiCanvas *gdi_surface;
-    pixman_image_t *surface;
-    struct BitmapData bitmap;
-    PixmanData *pixman_data;
-
-    bitmap.hbitmap = NULL;
-    if (!mask->bitmap) {
-        return bitmap;
-    }
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface_mask(&canvas->base, mask->bitmap);
-    if (gdi_surface) {
-        	HBITMAP _bitmap;
-
-            _bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
-            if (!_bitmap) {
-                spice_critical("GetCurrentObject failed");
-                return bitmap;
-            }
-            bitmap.dc = gdi_surface->dc;
-            bitmap.hbitmap = _bitmap;
-            bitmap.prev_hbitmap = (HBITMAP)0;
-            bitmap.cache = 0;
-            bitmap.from_surface = 1;
-    } else {
-    
-        if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) {
-            return bitmap;
-        }
-    
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface);
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            bitmap.dc = create_compatible_dc();
-            bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
-            bitmap.hbitmap = pixman_data->bitmap;
-            ReleaseMutex(pixman_data->mutex);
-            bitmap.cache = 1;
-        } else if (!create_bitmap_from_pixman(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
-                                               surface, 0)) {
-            bitmap.hbitmap = NULL;
-        } else {
-            bitmap.cache = 0;
-        }
-
-        bitmap.from_surface = 0;
-    }
-
-    bitmap.flags = mask->flags;
-    bitmap.pos = mask->pos;
-
-    return bitmap;
-}
-
-static void gdi_draw_bitmap(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-                            HDC src_dc, struct BitmapData *bitmapmask, uint32_t rop3_val)
-{
-    uint32_t rast_oper;
-
-    rast_oper = raster_ops[rop3_val];
-
-    if (!bitmapmask || !bitmapmask->hbitmap) {
-        if ((dest->right - dest->left) == (src->right - src->left) &&
-                                           (dest->bottom - dest->top) == (src->bottom - src->top)) {
-            if (!BitBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
-                        dest->bottom - dest->top, src_dc, src->left, src->top, rast_oper)) {
-                spice_critical("BitBlt failed");
-                return;
-            }
-        } else {
-            if (!StretchBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
-                            dest->bottom - dest->top, src_dc, src->left, src->top,
-                            src->right - src->left, src->bottom - src->top, rast_oper)) {
-                spice_critical("StretchBlt failed");
-                return;
-            }
-        }
-    } else {
-        rast_oper = MAKEROP4(rast_oper, raster_ops[_rop3_dest]);
-
-        if (!MaskBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
-                     dest->bottom - dest->top, src_dc, src->left, src->top,
-                     bitmapmask->hbitmap, bitmapmask->pos.x, bitmapmask->pos.y,
-                     rast_oper)) {
-            spice_critical("MaskBlt failed");
-            return;
-        }
-    }
-}
-
-static void gdi_draw_bitmap_redrop(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-                                   HDC src_dc, struct BitmapData *bitmapmask,
-                                   uint16_t rop, int brush)
-{
-    uint32_t rop3_val;
-
-    rop3_val = calc_rop3(rop, brush);
-    gdi_draw_bitmap(dest_dc, src, dest, src_dc, bitmapmask, rop3_val);
-}
-
-static void free_mask(struct BitmapData *bitmap)
-{
-    if (bitmap->hbitmap) {
-        if (!bitmap->from_surface) {
-            release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache);
-        }
-    }
-}
-
-static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
-                                 SpiceString *str, int n, SpiceRect *dest,
-                                 SpiceRect *src, SpiceBrush *brush)
-{
-    pixman_image_t *surface;
-    struct BitmapData bitmap;
-    SpicePoint pos;
-    int dest_stride;
-    uint8_t *bitmap_data;
-    HBRUSH prev_hbrush;
-    HBRUSH hbrush;
-    RecurciveMutex *brush_lock;
-
-    bitmap.hbitmap = (HBITMAP)1;
-    if (!(surface = canvas_get_str_mask(&canvas->base, str, n, &pos))) {
-        spice_critical("unable to canvas_get_str_mask");
-        return;
-    }
-
-    bitmap.from_surface = 0;
-    bitmap.cache = 0;
-    bitmap_data = create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap,
-                                &bitmap.dc, NULL,
-                                pixman_image_get_width(surface),
-                                pixman_image_get_height(surface),
-                                pixman_image_get_stride(surface), 32, 0);
-
-    if (!bitmap_data) {
-        return;
-    }
-
-    bitmap.flags = 0;
-    bitmap.pos.x = 0;
-    bitmap.pos.y = 0;
-
-    dest->left = pos.x;
-    dest->top = pos.y;
-    dest->right = pos.x + pixman_image_get_width(surface);
-    dest->bottom = pos.y + pixman_image_get_height(surface);
-    src->left = 0;
-    src->top = 0;
-    src->right = pixman_image_get_width(surface);
-    src->bottom = pixman_image_get_height(surface);
-
-    dest_stride = pixman_image_get_width(surface);
-    switch (n) {
-    case 1:
-        dest_stride = dest_stride / 8;
-        break;
-    case 4:
-        dest_stride = dest_stride / 2;
-        break;
-    case 32:
-        dest_stride = dest_stride * 4;
-        break;
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-    dest_stride = dest_stride + 3;
-    dest_stride = dest_stride & ~3;
-
-    hbrush = get_brush(canvas, brush, &brush_lock);
-    prev_hbrush = set_brush(bitmap.dc, hbrush, brush);
-    if (brush_lock) {
-        RecurciveLock b_lock(*brush_lock);
-        gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
-    } else {
-        gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
-    }
-
-    unset_brush(bitmap.dc, prev_hbrush);
-
-    copy_bitmap_alpha((uint8_t *)pixman_image_get_data(surface),
-                      pixman_image_get_height(surface),
-                      pixman_image_get_width(surface),
-                      pixman_image_get_stride(surface),
-                      bitmap_data, dest_stride, n);
-
-    BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
-
-    RecurciveLock lock(*canvas->lock);
-    AlphaBlend(canvas->dc, dest->left, dest->top, dest->right - dest->left,
-               dest->bottom - dest->top, bitmap.dc, src->left, src->top,
-               src->right - src->left, src->bottom - src->top, bf);
-
-    free_mask(&bitmap);
-}
-
-static void gdi_draw_image(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-                           pixman_image_t *image, struct BitmapData *bitmapmask, uint16_t rop,
-                           int rotate)
-{
-    HDC dc;
-    HBITMAP bitmap;
-    HBITMAP prev_bitmap;
-
-    create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
-
-    gdi_draw_bitmap_redrop(dest_dc, src, dest, dc, bitmapmask, rop, 0);
-
-    release_bitmap(dc, bitmap, prev_bitmap, 0);
-}
-
-static void gdi_draw_image_rop3(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-                                pixman_image_t *image, struct BitmapData *bitmapmask, uint8_t rop3,
-                                int rotate)
-{
-    HDC dc;
-    HBITMAP bitmap;
-    HBITMAP prev_bitmap;
-
-    create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
-
-    gdi_draw_bitmap(dest_dc, src, dest, dc, bitmapmask, rop3);
-
-    release_bitmap(dc, bitmap, prev_bitmap, 0);
-}
-
-static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    HBRUSH prev_hbrush;
-    HBRUSH brush;
-    struct BitmapData bitmapmask;
-    RecurciveMutex *brush_lock;
-
-    RecurciveLock lock(*canvas->lock);
-
-    brush = get_brush(canvas, &fill->brush, &brush_lock);
-    spice_return_if_fail(brush != NULL);
-
-    bitmapmask = get_mask_bitmap(canvas, &fill->mask);
-
-    set_clip(canvas, clip);
-    prev_hbrush = set_brush(canvas->dc, brush, &fill->brush);
-    if (brush_lock) {
-        RecurciveLock b_lock(*brush_lock);
-        gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask,
-                               fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
-    } else {
-        gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask,
-                               fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
-    }
-
-    free_mask(&bitmapmask);
-    unset_brush(canvas->dc, prev_hbrush);
-}
-
-static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    GdiCanvas *gdi_surface;
-    pixman_image_t *surface;
-    struct BitmapData bitmapmask;
-    PixmanData *pixman_data;
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, copy->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        bitmapmask = get_mask_bitmap(canvas, &copy->mask);
-        set_scale_mode(canvas, copy->scale_mode);
-        set_clip(canvas, clip);
-        gdi_draw_bitmap_redrop(canvas->dc, &copy->src_area, bbox, gdi_surface->dc,
-                               &bitmapmask, copy->rop_descriptor, 0);
-    } else {
-        surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-    
-        RecurciveLock lock(*canvas->lock);
-        bitmapmask = get_mask_bitmap(canvas, &copy->mask);
-        set_scale_mode(canvas, copy->scale_mode);
-        set_clip(canvas, clip);
-    
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            gdi_draw_bitmap_redrop(canvas->dc, &copy->src_area, bbox, dc,
-                                   &bitmapmask, copy->rop_descriptor, 0);
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            gdi_draw_image(canvas->dc, &copy->src_area, bbox, surface, &bitmapmask,
-                           copy->rop_descriptor, 0);
-        }
-
-        pixman_image_unref(surface);
-    
-    }
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
-                                 uint32_t src_width, uint32_t src_height, int src_stride,
-                                 const QRegion *clip)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    SpiceRect src;
-    src.top = 0;
-    src.bottom = src_height;
-    src.left = 0;
-    src.right = src_width;
-    int num_rects;
-    pixman_box32_t *rects;
-
-    RecurciveLock lock(*canvas->lock);
-    set_scale_mode(canvas, SPICE_IMAGE_SCALE_MODE_NEAREST);
-    if (clip) {
-        rects = pixman_region32_rectangles((pixman_region32_t*)clip, &num_rects);
-        if (num_rects == 0) {
-            return;
-        } else {
-            HRGN main_hrgn;
-            int i;
-
-            main_hrgn = CreateRectRgn(rects[0].x1, rects[0].y1, rects[0].x2,
-                                      rects[0].y2);
-            if (!main_hrgn) {
-                return;
-            }
-
-            for (i = 1; i < num_rects; i++) {
-                HRGN combaine_hrgn;
-
-                combaine_hrgn = CreateRectRgn(rects[i].x1, rects[i].y1,
-                                              rects[i].x2,
-                                              rects[i].y2);
-                if (!combaine_hrgn) {
-                    spice_critical("CreateRectRgn failed");
-                    DeleteObject(main_hrgn);
-                    return;
-                }
-                if (!CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR)) {
-                    spice_critical("CombineRgn failed in put_image");
-                    return;
-                }
-                DeleteObject(combaine_hrgn);
-            }
-            if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
-                spice_critical("SelectClipRgn failed in put_image");
-                DeleteObject(main_hrgn);
-                return;
-            }
-            DeleteObject(main_hrgn);
-        }
-    } else {
-        SelectClipRgn(canvas->dc, NULL);
-    }
-
-    if (dc) {
-        gdi_draw_bitmap_redrop(canvas->dc, &src, dest, dc,
-                               NULL, SPICE_ROPD_OP_PUT, 0);
-    } else {
-		pixman_image_t *image = pixman_image_create_bits(PIXMAN_a8r8g8b8, src_width, src_height, 
-			                                             (uint32_t *)src_data, src_stride);
-        gdi_draw_image(canvas->dc, &src, dest, image, NULL, SPICE_ROPD_OP_PUT, 0);
-		pixman_image_unref(image);
-    }
-}
-
-static void gdi_draw_bitmap_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
-                                        const SpiceRect *dest, HDC src_dc, uint32_t color)
-{
-    TransparentBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
-                   dest->bottom - dest->top, src_dc, src->left, src->top,
-                   src->right - src->left, src->bottom - src->top,
-                   RGB(((uint8_t*)&color)[2], ((uint8_t*)&color)[1], ((uint8_t*)&color)[0]));
-}
-
-static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
-                                       const SpiceRect *dest, pixman_image_t *image, 
-                                       uint32_t color, int rotate)
-{
-    HDC dc;
-    HBITMAP bitmap;
-    HBITMAP prev_bitmap;
-
-    create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
-
-    gdi_draw_bitmap_transparent(canvas, dest_dc, src, dest, dc, color);
-
-    release_bitmap(dc, bitmap, prev_bitmap, 0);
-}
-
-static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip,
-                                        SpiceTransparent* transparent)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    GdiCanvas *gdi_surface;
-    pixman_image_t *surface;
-    PixmanData *pixman_data;
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, transparent->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        set_clip(canvas, clip);
-        gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox,
-                                    gdi_surface->dc, transparent->true_color);
-    } else {
-        surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-        RecurciveLock lock(*canvas->lock);
-        set_clip(canvas, clip);
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
-                                        transparent->true_color);
-    
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, surface,
-                                       transparent->true_color, 0);
-        }
-    
-        pixman_image_unref(surface);
-    }
-}
-
-static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-                                  HDC src_dc, uint8_t alpha, int use_bitmap_alpha)
-{
-    BLENDFUNCTION bf;
-
-    bf.BlendOp = AC_SRC_OVER;
-    bf.BlendFlags = 0;
-    bf.SourceConstantAlpha = alpha;
-
-    if (use_bitmap_alpha) {
-        bf.AlphaFormat = AC_SRC_ALPHA;
-    } else {
-        bf.AlphaFormat = 0;
-    }
-
-    if (!AlphaBlend(dest_dc, dest->left, dest->top, dest->right - dest->left,
-                    dest->bottom - dest->top, src_dc, src->left, src->top,
-                    src->right - src->left, src->bottom - src->top, bf)) {
-        spice_critical("AlphaBlend failed");
-        return;
-    }
-}
-
-static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
-								 pixman_image_t *image, uint8_t alpha,
-                                 int rotate, int use_bitmap_alpha)
-{
-    HDC dc;
-    HBITMAP bitmap;
-    HBITMAP prev_bitmap;
-
-    create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
-
-    gdi_draw_bitmap_alpha(dest_dc, src, dest, dc, alpha, use_bitmap_alpha);
-
-    release_bitmap(dc, bitmap, prev_bitmap, 0);
-}
-
-static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    GdiCanvas *gdi_surface;
-    pixman_image_t *surface;
-    PixmanData *pixman_data;
-    int use_bitmap_alpha;
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, alpha_blend->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        set_clip(canvas, clip);
-        use_bitmap_alpha = alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA;
-        gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, gdi_surface->dc,
-                              alpha_blend->alpha, use_bitmap_alpha);
-    } else {
-        surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, TRUE);
-        use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-    
-        RecurciveLock lock(*canvas->lock);
-        set_clip(canvas, clip);
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
-                                  use_bitmap_alpha);
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, surface,
-                                 alpha_blend->alpha, 0, use_bitmap_alpha);
-        }
-    
-        pixman_image_unref(surface);
-    }
-}
-
-static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
-    GdiCanvas *gdi_surface;
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    struct BitmapData bitmapmask;
-    PixmanData *pixman_data;
-    HBRUSH prev_hbrush;
-    HBRUSH hbrush;
-    uint8_t rop3;
-    RecurciveMutex *brush_lock;
-
-    rop3 = calc_rop3_src_brush(opaque->rop_descriptor);
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, opaque->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
-        hbrush = get_brush(canvas, &opaque->brush, &brush_lock);
-        set_scale_mode(canvas, opaque->scale_mode);
-        set_clip(canvas, clip);
-        prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
-        if (brush_lock) {
-            RecurciveLock b_lock(*brush_lock);
-            gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3);
-        } else {
-            gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3);
-        }
-        unset_brush(canvas->dc, prev_hbrush);
-    } else {
-        surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-    
-        RecurciveLock lock(*canvas->lock);
-        bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
-        hbrush = get_brush(canvas, &opaque->brush, &brush_lock);
-        set_scale_mode(canvas, opaque->scale_mode);
-        set_clip(canvas, clip);
-        prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
-    
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            if (brush_lock) {
-                RecurciveLock b_lock(*brush_lock);
-                gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
-            } else {
-                gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
-            }
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            if (brush_lock) {
-                RecurciveLock b_lock(*brush_lock);
-                gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0);
-            } else {
-                gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0);
-            }
-        }
-        unset_brush(canvas->dc, prev_hbrush);
-        pixman_image_unref(surface);
-    }
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
-    GdiCanvas *gdi_surface;
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    struct BitmapData bitmapmask;
-    PixmanData *pixman_data;
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, blend->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        bitmapmask = get_mask_bitmap(canvas, &blend->mask);
-        set_scale_mode(canvas, blend->scale_mode);
-        set_clip(canvas, clip);
-        gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, gdi_surface->dc,
-                               &bitmapmask, blend->rop_descriptor, 0);
-    }  else {
-        surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-    
-        RecurciveLock lock(*canvas->lock);
-        bitmapmask = get_mask_bitmap(canvas, &blend->mask);
-        set_scale_mode(canvas, blend->scale_mode);
-        set_clip(canvas, clip);
-    
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
-                                   &bitmapmask, blend->rop_descriptor, 0);
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            gdi_draw_image(canvas->dc, &blend->src_area, bbox, surface,
-				           &bitmapmask, blend->rop_descriptor, 0);
-        }
-
-        pixman_image_unref(surface);
-    }
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    struct BitmapData bitmapmask;
-
-    RecurciveLock lock(*canvas->lock);
-    bitmapmask = get_mask_bitmap(canvas, &blackness->mask);
-    set_clip(canvas, clip);
-    gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x0);
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    struct BitmapData bitmapmask;
-
-    RecurciveLock lock(*canvas->lock);
-    bitmapmask = get_mask_bitmap(canvas, &invers->mask);
-    set_clip(canvas, clip);
-    gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x55);
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    struct BitmapData bitmapmask;
-
-    RecurciveLock lock(*canvas->lock);
-    bitmapmask = get_mask_bitmap(canvas, &whiteness->mask);
-    set_clip(canvas, clip);
-    gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0xff);
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
-{
-    GdiCanvas *gdi_surface;
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    struct BitmapData bitmapmask;
-    HBRUSH prev_hbrush;
-    HBRUSH hbrush;
-    PixmanData *pixman_data;
-    RecurciveMutex *brush_lock;
-
-    gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, rop3->src_bitmap);
-    if (gdi_surface) {
-        RecurciveLock lock(*canvas->lock);
-        RecurciveLock s_lock(*gdi_surface->lock);
-        hbrush = get_brush(canvas, &rop3->brush, &brush_lock);
-        bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
-        set_scale_mode(canvas, rop3->scale_mode);
-        set_clip(canvas, clip);
-        prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
-        if (brush_lock) {
-            RecurciveLock b_lock(*brush_lock);
-            gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc,
-                            &bitmapmask, rop3->rop3);
-        } else {
-            gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc,
-                            &bitmapmask, rop3->rop3);
-        }
-        unset_brush(canvas->dc, prev_hbrush);
-    } else {
-        surface = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
-        pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
-        RecurciveLock lock(*canvas->lock);
-        hbrush = get_brush(canvas, &rop3->brush, &brush_lock);
-        bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
-        set_scale_mode(canvas, rop3->scale_mode);
-        set_clip(canvas, clip);
-        prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
-    
-        if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
-            HDC dc;
-            HBITMAP prev_bitmap;
-    
-            dc = create_compatible_dc();
-            prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
-            if (brush_lock) {
-                RecurciveLock b_lock(*brush_lock);
-                gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
-                                &bitmapmask, rop3->rop3);
-            } else {
-                gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
-                                &bitmapmask, rop3->rop3);
-            }
-            SelectObject(dc, prev_bitmap);
-            DeleteObject(dc);
-            ReleaseMutex(pixman_data->mutex);
-        } else {
-            if (brush_lock) {
-                RecurciveLock b_lock(*brush_lock);
-                gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0);
-            } else {
-                gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0);
-            }
-        }
-
-        unset_brush(canvas->dc, prev_hbrush);
-        pixman_image_unref(surface);
-    }
-
-    free_mask(&bitmapmask);
-}
-
-static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    RecurciveLock lock(*canvas->lock);
-
-    set_clip(canvas, clip);
-
-    BitBlt(canvas->dc, bbox->left, bbox->top, bbox->right - bbox->left,
-           bbox->bottom - bbox->top, canvas->dc, src_pos->x, src_pos->y, SRCCOPY);
-}
-
-static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    SpiceString *str;
-    RecurciveMutex *brush_lock;
-
-    RecurciveLock lock(*canvas->lock);
-    set_clip(canvas, clip);
-    lock.unlock();
-
-    if (!rect_is_empty(&text->back_area)) {
-        HBRUSH prev_hbrush;
-        HBRUSH hbrush;
-
-        RecurciveLock lock(*canvas->lock);
-        hbrush = get_brush(canvas, &text->back_brush, &brush_lock);
-        prev_hbrush = set_brush(canvas->dc, hbrush, &text->back_brush);
-        if (brush_lock) {
-            RecurciveLock b_lock(*brush_lock);
-            gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
-                                   text->back_mode, 1);
-        } else {
-            gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
-                                   text->back_mode, 1);
-        }
-        unset_brush(canvas->dc, prev_hbrush);
-    }
-
-    str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
-
-    if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
-        SpiceRect dest;
-        SpiceRect src;
-
-        draw_str_mask_bitmap(canvas, str, 1, &dest, &src, &text->fore_brush);
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
-        SpiceRect dest;
-        SpiceRect src;
-
-        draw_str_mask_bitmap(canvas, str, 4, &dest, &src, &text->fore_brush);
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
-        spice_warning("untested path A8 glyphs, doing nothing");
-        if (0) {
-            SpiceRect dest;
-            SpiceRect src;
-
-            draw_str_mask_bitmap(canvas, str, 8, &dest, &src, &text->fore_brush);
-        }
-    } else {
-        spice_warning("untested path vector glyphs, doing nothing");
-        if (0) {
-        }
-    }
-}
-
-static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_FIXED28_4* style, int start_is_gap)
-{
-    double offset = 0;
-    uint32_t *local_style;
-    int i;
-
-    spice_return_val_if_fail(nseg != 0, NULL);
-
-    local_style = spice_new(uint32_t , nseg);
-
-    if (start_is_gap) {
-        offset = (uint32_t)fix_to_double(*style);
-        local_style[nseg - 1] = (uint32_t)fix_to_double(*style);
-        style++;
-
-        for (i = 0; i < nseg - 1; i++, style++) {
-            local_style[i] = (uint32_t)fix_to_double(*style);
-        }
-    } else {
-        for (i = 0; i < nseg; i++, style++) {
-            local_style[i] = (uint32_t)fix_to_double(*style);
-        }
-    }
-
-    return local_style;
-}
-
-static void gdi_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    HPEN hpen;
-    HPEN prev_hpen;
-    LOGBRUSH logbrush;
-    uint32_t *user_style = NULL;
-    pixman_image_t *surface = NULL;
-
-    if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
-        surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat, FALSE);
-    }
-
-    RecurciveLock lock(*canvas->lock);
-    set_clip(canvas, clip);
-
-    switch (stroke->fore_mode) {
-    case SPICE_ROPD_OP_WHITENESS:
-        SetROP2(canvas->dc, R2_WHITE);    //0
-        break;
-    case SPICE_ROPD_OP_BLACKNESS:
-        SetROP2(canvas->dc, R2_BLACK);    //1
-        break;
-    case SPICE_ROPD_OP_INVERS:
-        SetROP2(canvas->dc, R2_NOT);    //Dn
-        break;
-    case SPICE_ROPD_OP_PUT:
-        SetROP2(canvas->dc, R2_COPYPEN);    //P
-        break;
-    case SPICE_ROPD_OP_OR:
-        SetROP2(canvas->dc, R2_MERGEPEN);    //DPo
-        break;
-    case SPICE_ROPD_OP_XOR:
-        SetROP2(canvas->dc, R2_XORPEN);    //DPx
-        break;
-    case SPICE_ROPD_OP_AND:
-        SetROP2(canvas->dc, R2_MASKPEN);    //DPa
-        break;
-    case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_PUT:    //Pn
-        SetROP2(canvas->dc, R2_NOTCOPYPEN);
-        break;
-    case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
-        SetROP2(canvas->dc, R2_NOTXORPEN);    //DPxn
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
-        SetROP2(canvas->dc, R2_NOTMERGEPEN);    //DPon
-        break;
-    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
-        SetROP2(canvas->dc, R2_NOTMASKPEN);    //DPan
-        break;
-    case SPICE_ROPD_INVERS_DEST | SPICE_ROPD_OP_AND:
-        SetROP2(canvas->dc, R2_MASKPENNOT);    //PDna
-        break;
-    case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_AND:
-        SetROP2(canvas->dc, R2_MASKNOTPEN);    //DPna
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
-        SetROP2(canvas->dc, R2_MERGENOTPEN);    //DPno
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
-        SetROP2(canvas->dc, R2_MERGEPENNOT);    //PDno
-        break;
-    default:
-        SetROP2(canvas->dc, R2_NOP);    //D
-    }
-
-
-    if (stroke->brush.type == SPICE_BRUSH_TYPE_SOLID) {
-        logbrush.lbStyle = BS_SOLID | DIB_RGB_COLORS;
-        logbrush.lbHatch = 0;
-        logbrush.lbColor = get_color_ref(canvas, stroke->brush.u.color);
-    } else if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
-#if 0
-        struct {
-            BITMAPINFO inf;
-            RGBQUAD palette[255];
-        } bitmap_info;
-        GdiImage image;
-#endif
-#if 0
-        spice_return_if_fail(surface != NULL)
-        surface_to_image(surface, &image);
-
-        memset(&bitmap_info, 0, sizeof(bitmap_info));
-        bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
-        bitmap_info.inf.bmiHeader.biWidth = image.width;
-        if (image.stride < 0) {
-            bitmap_info.inf.bmiHeader.biHeight = image.height;
-        } else {
-            bitmap_info.inf.bmiHeader.biHeight = -image.height;
-        }
-        bitmap_info.inf.bmiHeader.biPlanes = 1;
-        bitmap_info.inf.bmiHeader.biBitCount = 32;
-        bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
-
-        if (image.stride < 0) {
-            logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
-                                                 image.height * -image.stride + sizeof(BITMAPINFO));
-            if (!logbrush.lbHatch) {
-                spice_critical("GlobalAlloc failed");
-                return;
-            }
-            copy_bitmap(image.pixels - (image.height - 1) * -image.stride,
-                        image.height, -image.stride,
-                        (uint8_t *)logbrush.lbHatch, image.width);
-        } else {
-            logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
-                                                 image.height * image.stride + sizeof(BITMAPINFO));
-            if (!logbrush.lbHatch) {
-                spice_critical("GlobalAlloc failed");
-                return;
-            }
-            copy_bitmap(image.pixels, image.height, image.stride,
-                        (uint8_t *)logbrush.lbHatch, image.width);
-        }
-
-        memcpy((void *)logbrush.lbHatch, &bitmap_info.inf, sizeof(BITMAPINFO));
-
-        logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS;
-        logbrush.lbColor = 0;
-#endif
-        pixman_image_unref(surface);
-    }
-
-    if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
-        user_style = gdi_get_userstyle(canvas, stroke->attr.style_nseg,
-                                       stroke->attr.style,
-                                       !!(stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP));
-        hpen = ExtCreatePen(PS_COSMETIC | PS_USERSTYLE,
-                            1,
-                            &logbrush, stroke->attr.style_nseg, (DWORD *)user_style);
-    } else {
-        hpen = ExtCreatePen(PS_COSMETIC,
-                            1,
-                            &logbrush, 0, NULL);
-    }
-    prev_hpen = (HPEN)SelectObject(canvas->dc, hpen);
-
-    set_path(canvas, stroke->path);
-
-    StrokePath(canvas->dc);
-
-    SelectObject(canvas->dc, prev_hpen);
-    DeleteObject(hpen);
-
-#if 0
-    if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
-        GlobalFree((HGLOBAL)logbrush.lbHatch);
-    }
-#endif
-
-    if (user_style) {
-        free(user_style);
-    }
-}
-
-static void gdi_canvas_clear(SpiceCanvas *spice_canvas)
-{
-}
-
-static void gdi_canvas_destroy(SpiceCanvas *spice_canvas)
-{
-    GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
-    if (!canvas) {
-        return;
-    }
-    canvas_base_destroy(&canvas->base);
-    free(canvas);
-}
-
-static int need_init = 1;
-static SpiceCanvasOps gdi_canvas_ops;
-
-SpiceCanvas *gdi_canvas_create(int width, int height,
-                               HDC dc, RecurciveMutex* lock, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                             , SpiceImageCache *bits_cache
-                             , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                             , SpiceImageCache *bits_cache
-#endif
-                            , SpiceImageSurfaces *surfaces
-                            , SpiceGlzDecoder *glz_decoder
-                            , SpiceJpegDecoder *jpeg_decoder
-                            , SpiceZlibDecoder *zlib_decoder
-                            )
-{
-    GdiCanvas *canvas;
-    int init_ok;
-
-    if (need_init) {
-        return NULL;
-    }
-    canvas = spice_new0(GdiCanvas, 1);
-    init_ok = canvas_base_init(&canvas->base, &gdi_canvas_ops,
-                               width, height, format
-#ifdef SW_CANVAS_CACHE
-                               ,bits_cache
-                               ,palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                               , bits_cache
-#endif
-                               , surfaces
-                               , glz_decoder
-                               , jpeg_decoder
-                               , zlib_decoder);
-    canvas->dc = dc;
-    canvas->lock = lock;
-    return (SpiceCanvas *)canvas;
-}
-
-void gdi_canvas_init() //unsafe global function
-{
-    if (!need_init) {
-        return;
-    }
-    need_init = 0;
-
-    canvas_base_init_ops(&gdi_canvas_ops);
-    gdi_canvas_ops.draw_fill = gdi_canvas_draw_fill;
-    gdi_canvas_ops.draw_copy = gdi_canvas_draw_copy;
-    gdi_canvas_ops.draw_opaque = gdi_canvas_draw_opaque;
-    gdi_canvas_ops.copy_bits = gdi_canvas_copy_bits;
-    gdi_canvas_ops.draw_text = gdi_canvas_draw_text;
-    gdi_canvas_ops.draw_stroke = gdi_canvas_draw_stroke;
-    gdi_canvas_ops.draw_rop3 = gdi_canvas_draw_rop3;
-    gdi_canvas_ops.draw_blend = gdi_canvas_draw_blend;
-    gdi_canvas_ops.draw_blackness = gdi_canvas_draw_blackness;
-    gdi_canvas_ops.draw_whiteness = gdi_canvas_draw_whiteness;
-    gdi_canvas_ops.draw_invers = gdi_canvas_draw_invers;
-    gdi_canvas_ops.draw_transparent = gdi_canvas_draw_transparent;
-    gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend;
-    gdi_canvas_ops.put_image = gdi_canvas_put_image;
-    gdi_canvas_ops.clear = gdi_canvas_clear;
-    gdi_canvas_ops.destroy = gdi_canvas_destroy;
-
-    rop3_init();
-}
-
diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
deleted file mode 100644
index b3d4b15..0000000
--- a/common/gdi_canvas.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H__GDI_CANVAS
-#define _H__GDI_CANVAS
-
-#include <stdint.h>
-
-#include "pixman_utils.h"
-#include "canvas_base.h"
-#include "region.h"
-
-SpiceCanvas *gdi_canvas_create(int width, int height,
-                               HDC dc, class RecurciveMutex *lock, uint32_t format,
-                               SpiceImageCache *bits_cache,
-                               SpicePaletteCache *palette_cache,
-			       SpiceImageSurfaces *surfaces,
-                               SpiceGlzDecoder *glz_decoder,
-                               SpiceJpegDecoder *jpeg_decoder,
-                               SpiceZlibDecoder *zlib_decoder);
-
-void gdi_canvas_init();
-
-#endif
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
deleted file mode 100644
index 9baf7e8..0000000
--- a/common/gl_canvas.c
+++ /dev/null
@@ -1,909 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gl_canvas.h"
-#include "quic.h"
-#include "rop3.h"
-#include "region.h"
-
-#define GL_CANVAS
-#include "canvas_base.c"
-
-typedef struct GLCanvas GLCanvas;
-
-struct GLCanvas {
-    CanvasBase base;
-    GLCCtx glc;
-    void *private_data;
-    int private_data_size;
-    int textures_lost;
-};
-
-static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int stride, int height)
-{
-    uint8_t *ret_data = (uint8_t *)data;
-    uint8_t *dest;
-    uint8_t *src;
-    int i;
-
-    if (!canvas->private_data) {
-        canvas->private_data = spice_malloc_n(height, stride);
-        if (!canvas->private_data) {
-            return ret_data;
-        }
-        canvas->private_data_size = stride * height;
-    }
-
-    if (canvas->private_data_size < (stride * height)) {
-        free(canvas->private_data);
-        canvas->private_data = spice_malloc_n(height, stride);
-        if (!canvas->private_data) {
-            return ret_data;
-        }
-        canvas->private_data_size = stride * height;
-    }
-
-    dest = (uint8_t *)canvas->private_data;
-    src = (uint8_t *)data + (height - 1) * stride;
-
-    for (i = 0; i < height; ++i) {
-        memcpy(dest, src, stride);
-        dest += stride;
-        src -= stride;
-    }
-    return (uint8_t *)canvas->private_data;
-}
-
-static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image,
-                                                 uint32_t trans_color)
-{
-    int width = image->width;
-    int height = image->height;
-    uint8_t *src_line;
-    uint8_t *end_src_line;
-    int src_stride;
-    uint8_t *dest_line;
-    int dest_stride;
-    pixman_image_t *ret;
-    int i;
-
-    ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
-    if (ret == NULL) {
-        spice_critical("create surface failed");
-        return NULL;
-    }
-
-    src_line = image->pixels;
-    src_stride = image->stride;
-    end_src_line = src_line + src_stride * height;
-
-    dest_line = (uint8_t *)pixman_image_get_data(ret);
-    dest_stride = pixman_image_get_stride(ret);
-
-    for (; src_line < end_src_line; src_line += src_stride, dest_line += dest_stride) {
-        for (i = 0; i < width; i++) {
-            if ((((uint32_t*)src_line)[i] & 0x00ffffff) == trans_color) {
-                ((uint32_t*)dest_line)[i] = 0;
-            } else {
-                ((uint32_t*)dest_line)[i] = (((uint32_t*)src_line)[i]) | 0xff000000;
-            }
-        }
-    }
-
-    return ret;
-}
-
-static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
-{
-    GLCPath path = glc_path_create(canvas->glc);
-    int i;
-
-    for (i = 0; i < s->num_segments; i++) {
-        SpicePathSeg* seg = s->segments[i];
-        SpicePointFix* point = seg->points;
-        SpicePointFix* end_point = point + seg->count;
-
-        if (seg->flags & SPICE_PATH_BEGIN) {
-            glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y));
-            point++;
-        }
-
-        if (seg->flags & SPICE_PATH_BEZIER) {
-            spice_return_val_if_fail((point - end_point) % 3 == 0, path);
-            for (; point + 2 < end_point; point += 3) {
-                glc_path_curve_to(path,
-                                  fix_to_double(point[0].x), fix_to_double(point[0].y),
-                                  fix_to_double(point[1].x), fix_to_double(point[1].y),
-                                  fix_to_double(point[2].x), fix_to_double(point[2].y));
-            }
-        } else {
-            for (; point < end_point; point++) {
-                glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y));
-            }
-        }
-        if (seg->flags & SPICE_PATH_END) {
-            if (seg->flags & SPICE_PATH_CLOSE) {
-                glc_path_close(path);
-            }
-        }
-    }
-
-    return path;
-}
-
-#define SET_GLC_RECT(dest, src) {                   \
-    (dest)->x = (src)->left;                        \
-    (dest)->y = (src)->top;                         \
-    (dest)->width = (src)->right - (src)->left;     \
-    (dest)->height = (src)->bottom - (src)->top;    \
-}
-
-#define SET_GLC_BOX(dest, src) {                    \
-    (dest)->x = (src)->x1;                          \
-    (dest)->y = (src)->y1;                          \
-    (dest)->width = (src)->x2 - (src)->x1;          \
-    (dest)->height = (src)->y2 - (src)->y1;         \
-}
-
-static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
-{
-    GLCRect rect;
-    glc_clip_reset(canvas->glc);
-
-    switch (clip->type) {
-    case SPICE_CLIP_TYPE_NONE:
-        break;
-    case SPICE_CLIP_TYPE_RECTS: {
-        uint32_t n = clip->rects->num_rects;
-        SpiceRect *now = clip->rects->rects;
-        SpiceRect *end = now + n;
-
-        if (n == 0) {
-            rect.x = rect.y = 0;
-            rect.width = rect.height = 0;
-            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
-            break;
-        } else {
-            SET_GLC_RECT(&rect, now);
-            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
-        }
-
-        for (now++; now < end; now++) {
-            SET_GLC_RECT(&rect, now);
-            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR);
-        }
-        break;
-    }
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y)
-{
-    pixman_image_t *image;
-
-    if (!(image = canvas_get_mask(&canvas->base, mask, NULL))) {
-        glc_clear_mask(canvas->glc, GLC_MASK_A);
-        return;
-    }
-
-
-    glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y,
-                 pixman_image_get_width(image),
-                 pixman_image_get_height(image),
-                 pixman_image_get_stride(image),
-                 (uint8_t *)pixman_image_get_data(image), GLC_MASK_A);
-}
-
-static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image,
-                                    int ignore_stride)
-{
-    int depth = pixman_image_get_depth(surface);
-
-    spice_return_if_fail(depth == 32 || depth == 24);
-    image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
-    image->width = pixman_image_get_width(surface);
-    image->height = pixman_image_get_height(surface);
-    image->stride = pixman_image_get_stride(surface);
-    image->pixels = (uint8_t *)pixman_image_get_data(surface);
-    image->pallet = NULL;
-    if (ignore_stride) {
-        return;
-    }
-    if (image->stride < 0) {
-        image->stride = -image->stride;
-        image->pixels = image->pixels - (image->height - 1) * image->stride;
-    } else {
-        image->pixels = copy_opposite_image(canvas, image->pixels, image->stride, image->height);
-    }
-}
-
-static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
-{
-    switch (brush->type) {
-    case SPICE_BRUSH_TYPE_SOLID: {
-        uint32_t color = brush->u.color;
-        double r, g, b;
-
-        b = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
-        color >>= canvas->base.color_shift;
-        g = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
-        color >>= canvas->base.color_shift;
-        r = (double)(color & canvas->base.color_mask) / canvas->base.color_mask;
-        glc_set_rgb(canvas->glc, r, g, b);
-        break;
-    }
-    case SPICE_BRUSH_TYPE_PATTERN: {
-        GLCImage image;
-        GLCPattern pattern;
-        pixman_image_t *surface;
-
-        surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
-        surface_to_image(canvas, surface, &image, 0);
-
-        pattern = glc_pattern_create(canvas->glc, -brush->u.pattern.pos.x,
-                                     -brush->u.pattern.pos.y, &image);
-
-        glc_set_pattern(canvas->glc, pattern);
-        glc_pattern_destroy(pattern);
-        pixman_image_unref (surface);
-    }
-    case SPICE_BRUSH_TYPE_NONE:
-        return;
-    default:
-        spice_warn_if_reached();
-        return;
-    }
-}
-
-static void set_op(GLCanvas *canvas, uint16_t rop_decriptor)
-{
-    GLCOp op;
-
-    switch (rop_decriptor) {
-    case SPICE_ROPD_OP_PUT:
-        op = GLC_OP_COPY;
-        break;
-    case SPICE_ROPD_OP_XOR:
-        op = GLC_OP_XOR;
-        break;
-    case SPICE_ROPD_OP_BLACKNESS:
-        op = GLC_OP_CLEAR;
-        break;
-    case SPICE_ROPD_OP_WHITENESS:
-        op = GLC_OP_SET;
-        break;
-    case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_BRUSH:
-    case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_SRC:
-        op = GLC_OP_COPY_INVERTED;
-        break;
-    case SPICE_ROPD_OP_INVERS:
-        op = GLC_OP_INVERT;
-        break;
-    case SPICE_ROPD_OP_AND:
-        op = GLC_OP_AND;
-        break;
-    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
-        op = GLC_OP_NAND;
-        break;
-    case SPICE_ROPD_OP_OR:
-        op = GLC_OP_OR;
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
-        op = GLC_OP_NOR;
-        break;
-    case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
-        op = GLC_OP_EQUIV;
-        break;
-    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_DEST:
-        op = GLC_OP_AND_REVERSE;
-        break;
-    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_BRUSH:
-    case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_SRC:
-        op = GLC_OP_AND_INVERTED;
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
-        op = GLC_OP_OR_REVERSE;
-        break;
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
-    case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_SRC:
-        op = GLC_OP_OR_INVERTED;
-        break;
-    default:
-        spice_warning("GLC_OP_NOOP");
-        op = GLC_OP_NOOP;
-    }
-    glc_set_op(canvas->glc, op);
-}
-
-static void gl_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCRect rect;
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, &fill->mask, bbox->left, bbox->top);
-    set_brush(canvas, &fill->brush);
-    set_op(canvas, fill->rop_descriptor);
-    SET_GLC_RECT(&rect, bbox);
-
-    glc_fill_rect(canvas->glc, &rect);
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    GLCRecti src;
-    GLCRecti dest;
-    GLCImage image;
-
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, &copy->mask, bbox->left, bbox->top);
-    set_op(canvas, copy->rop_descriptor);
-
-    //todo: optimize get_image (use ogl conversion + remove unnecessary copy of 32bpp)
-    surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
-    surface_to_image(canvas, surface, &image, 0);
-    SET_GLC_RECT(&dest, bbox);
-    SET_GLC_RECT(&src, &copy->src_area);
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
-
-    pixman_image_unref(surface);
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    GLCRecti src;
-    GLCRecti dest;
-    GLCRect fill_rect;
-    GLCImage image;
-
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, &opaque->mask, bbox->left, bbox->top);
-
-    glc_set_op(canvas->glc, (opaque->rop_descriptor & SPICE_ROPD_INVERS_SRC) ? GLC_OP_COPY_INVERTED :
-               GLC_OP_COPY);
-    surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
-    surface_to_image(canvas, surface, &image, 0);
-    SET_GLC_RECT(&dest, bbox);
-    SET_GLC_RECT(&src, &opaque->src_area);
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
-    pixman_image_unref(surface);
-
-    set_brush(canvas, &opaque->brush);
-    set_op(canvas, opaque->rop_descriptor & ~SPICE_ROPD_INVERS_SRC);
-    SET_GLC_RECT(&fill_rect, bbox);
-    glc_fill_rect(canvas->glc, &fill_rect);
-
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend *alpha_blend)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    GLCRecti src;
-    GLCRecti dest;
-    GLCImage image;
-
-    set_clip(canvas, bbox, clip);
-    glc_clear_mask(canvas->glc, GLC_MASK_A);
-    glc_set_op(canvas->glc, GLC_OP_COPY);
-
-    surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, FALSE);
-    surface_to_image(canvas, surface, &image, 0);
-    SET_GLC_RECT(&dest, bbox);
-    SET_GLC_RECT(&src, &alpha_blend->src_area);
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, (double)alpha_blend->alpha / 0xff);
-
-    pixman_image_unref(surface);
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    GLCRecti src;
-    GLCRecti dest;
-    GLCImage image;
-
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, &blend->mask, bbox->left, bbox->top);
-    set_op(canvas, blend->rop_descriptor);
-
-    surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
-    SET_GLC_RECT(&dest, bbox);
-    SET_GLC_RECT(&src, &blend->src_area);
-    surface_to_image(canvas, surface, &image, 0);
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
-
-    pixman_image_unref(surface);
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *surface;
-    pixman_image_t *trans_surf;
-    GLCImage image;
-    GLCRecti src;
-    GLCRecti dest;
-
-    set_clip(canvas, bbox, clip);
-    glc_clear_mask(canvas->glc, GLC_MASK_A);
-    glc_set_op(canvas->glc, GLC_OP_COPY);
-
-    surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
-    surface_to_image(canvas, surface, &image, 0);
-
-    trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color);
-    pixman_image_unref(surface);
-
-    surface_to_image(canvas, trans_surf, &image, 1);
-    SET_GLC_RECT(&dest, bbox);
-    SET_GLC_RECT(&src, &transparent->src_area);
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
-
-    pixman_image_unref(trans_surf);
-    glc_flush(canvas->glc);
-}
-
-static inline void fill_common(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceQMask * mask, GLCOp op)
-{
-    GLCRect rect;
-
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, mask, bbox->left, bbox->top);
-    glc_set_op(canvas->glc, op);
-    SET_GLC_RECT(&rect, bbox);
-    glc_fill_rect(canvas->glc, &rect);
-}
-
-static void gl_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    fill_common(canvas, bbox, clip, &whiteness->mask, GLC_OP_SET);
-}
-
-static void gl_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    fill_common(canvas, bbox, clip, &blackness->mask, GLC_OP_CLEAR);
-}
-
-static void gl_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    fill_common(canvas, bbox, clip, &invers->mask, GLC_OP_INVERT);
-}
-
-static void gl_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    pixman_image_t *d;
-    pixman_image_t *s;
-    GLCImage image;
-    SpicePoint src_pos;
-    uint8_t *data_opp;
-    int src_stride;
-
-    set_clip(canvas, bbox, clip);
-    set_mask(canvas, &rop3->mask, bbox->left, bbox->top);
-
-    glc_set_op(canvas->glc, GLC_OP_COPY);
-
-    image.format = GLC_IMAGE_RGB32;
-    image.width = bbox->right - bbox->left;
-    image.height = bbox->bottom - bbox->top;
-
-    image.pallet = NULL;
-
-    d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0);
-    if (d == NULL) {
-        spice_critical("create surface failed");
-        return;
-    }
-    image.pixels = (uint8_t *)pixman_image_get_data(d);
-    image.stride = pixman_image_get_stride(d);
-
-    glc_read_pixels(canvas->glc, bbox->left, bbox->top, &image);
-    data_opp = copy_opposite_image(canvas, image.pixels,
-                                   image.stride,
-                                   pixman_image_get_height(d));
-    memcpy(image.pixels, data_opp,
-           image.stride * pixman_image_get_height(d));
-
-    s = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
-    src_stride = pixman_image_get_stride(s);
-    if (src_stride > 0) {
-        data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s),
-                                       src_stride, pixman_image_get_height(s));
-        memcpy((uint8_t *)pixman_image_get_data(s), data_opp,
-               src_stride * pixman_image_get_height(s));
-    }
-
-    if (!rect_is_same_size(bbox, &rop3->src_area)) {
-        pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
-                                                        image.height, rop3->scale_mode);
-        pixman_image_unref(s);
-        s = scaled_s;
-        src_pos.x = 0;
-        src_pos.y = 0;
-    } else {
-        src_pos.x = rop3->src_area.left;
-        src_pos.y = rop3->src_area.top;
-    }
-
-    if (pixman_image_get_width(s) - src_pos.x < image.width ||
-        pixman_image_get_height(s) - src_pos.y < image.height) {
-        spice_critical("bad src bitmap size");
-        return;
-    }
-
-    if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
-        pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat, FALSE);
-        SpicePoint pat_pos;
-
-        pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
-
-        pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
-
-        //for now (bottom-top)
-        if (pat_pos.y < 0) {
-            pat_pos.y = pixman_image_get_height(p) + pat_pos.y;
-        }
-        pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p);
-        pat_pos.y = pixman_image_get_height(p) - pat_pos.y;
-
-        do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
-        pixman_image_unref(p);
-    } else {
-        uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
-                                                         canvas_16bpp_to_32bpp(rop3->brush.u.color);
-        do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
-    }
-
-    pixman_image_unref(s);
-
-    GLCRecti dest;
-    GLCRecti src;
-    dest.x = bbox->left;
-    dest.y = bbox->top;
-
-    image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d),
-                                       pixman_image_get_height(d));
-
-    src.x = src.y = 0;
-    dest.width = src.width = image.width;
-    dest.height = src.height = image.height;
-    glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
-    pixman_image_unref(d);
-}
-
-static void gl_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCPath path;
-
-    set_clip(canvas, bbox, clip);
-    glc_clear_mask(canvas->glc, GLC_MASK_A);
-    set_op(canvas, stroke->fore_mode);
-    set_brush(canvas, &stroke->brush);
-
-    if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
-        spice_warning("SPICE_LINE_FLAGS_STYLED");
-    }
-    glc_set_line_width(canvas->glc, 1.0);
-
-    path = get_path(canvas, stroke->path);
-    glc_stroke_path(canvas->glc, path);
-    glc_path_destroy(path);
-}
-
-static void gl_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCRect rect;
-    SpiceString *str;
-
-    set_clip(canvas, bbox, clip);
-    glc_clear_mask(canvas->glc, GLC_MASK_A);
-
-    if (!rect_is_empty(&text->back_area)) {
-        set_brush(canvas, &text->back_brush);
-        set_op(canvas, text->back_mode);
-        SET_GLC_RECT(&rect, bbox);
-        glc_fill_rect(canvas->glc, &rect);
-    }
-
-    str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
-    set_brush(canvas, &text->fore_brush);
-    set_op(canvas, text->fore_mode);
-    if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
-        SpicePoint pos;
-        pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
-        _glc_fill_mask(canvas->glc, pos.x, pos.y,
-                       pixman_image_get_width(mask),
-                       pixman_image_get_height(mask),
-                       pixman_image_get_stride(mask),
-                       (uint8_t *)pixman_image_get_data(mask));
-        pixman_image_unref(mask);
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
-        SpicePoint pos;
-        pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
-        glc_fill_alpha(canvas->glc, pos.x, pos.y,
-                       pixman_image_get_width(mask),
-                       pixman_image_get_height(mask),
-                       pixman_image_get_stride(mask),
-                       (uint8_t *)pixman_image_get_data(mask));
-
-        pixman_image_unref(mask);
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
-        spice_warning("untested path A8 glyphs, doing nothing");
-        if (0) {
-            SpicePoint pos;
-            pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
-            glc_fill_alpha(canvas->glc, pos.x, pos.y,
-                           pixman_image_get_width(mask),
-                           pixman_image_get_height(mask),
-                           pixman_image_get_stride(mask),
-                           (uint8_t *)pixman_image_get_data(mask));
-            pixman_image_unref(mask);
-        }
-    } else {
-        spice_warning("untested path vector glyphs, doing nothing");
-        if (0) {
-            //draw_vector_str(canvas, str, &text->fore_brush, text->fore_mode);
-        }
-    }
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_clear(SpiceCanvas *spice_canvas)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    glc_clear(canvas->glc);
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    set_clip(canvas, bbox, clip);
-    glc_clear_mask(canvas->glc, GLC_MASK_A);
-    glc_set_op(canvas->glc, GLC_OP_COPY);
-    glc_copy_pixels(canvas->glc, bbox->left, bbox->top, src_pos->x, src_pos->y,
-                    bbox->right - bbox->left, bbox->bottom - bbox->top);
-}
-
-static void gl_canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCImage image;
-
-    spice_return_if_fail(dest_stride > 0);
-
-    image.format = GLC_IMAGE_RGB32;
-    image.height = area->bottom - area->top;
-    image.width = area->right - area->left;
-    image.pixels = dest;
-    image.stride = dest_stride;
-    glc_read_pixels(canvas->glc, area->left, area->top, &image);
-}
-
-static void gl_canvas_group_start(SpiceCanvas *spice_canvas, QRegion *region)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCRect *glc_rects;
-    GLCRect *now, *end;
-    int num_rect;
-    pixman_box32_t *rects;
-
-    canvas_base_group_start(spice_canvas, region);
-
-    rects = pixman_region32_rectangles(region, &num_rect);
-
-    glc_rects = spice_new(GLCRect, num_rect);
-    now = glc_rects;
-    end = glc_rects + num_rect;
-
-    for (; now < end; now++, rects++) {
-        SET_GLC_BOX(now, rects);
-    }
-    glc_mask_rects(canvas->glc, num_rect, glc_rects, GLC_MASK_B);
-
-    free(glc_rects);
-}
-
-static void gl_canvas_put_image(SpiceCanvas *spice_canvas, const SpiceRect *dest, const uint8_t *src_data,
-                         uint32_t src_width, uint32_t src_height, int src_stride,
-                         const QRegion *clip)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-    GLCRecti src;
-    GLCRecti gldest;
-    GLCImage image;
-    uint32_t i;
-
-    spice_return_if_fail(src_stride <= 0)
-
-    glc_clip_reset(canvas->glc);
-
-    if (clip) {
-        int num_rects;
-        pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip,
-                                                           &num_rects);
-        GLCRect rect;
-        if (num_rects == 0) {
-            rect.x = rect.y = rect.width = rect.height = 0;
-            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
-        } else {
-            SET_GLC_BOX(&rect, rects);
-            glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
-            for (i = 1; i < num_rects; i++) {
-                SET_GLC_BOX(&rect, rects + i);
-                glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR);
-            }
-        }
-    }
-
-    SET_GLC_RECT(&gldest, dest);
-    src.x = src.y = 0;
-    src.width = src_width;
-    src.height = src_height;
-
-    image.format = GLC_IMAGE_RGB32;
-    image.width = src_width;
-    image.height = src_height;
-    src_stride = -src_stride;
-    image.stride = src_stride;
-    image.pixels = (uint8_t *)src_data - (src_height - 1) * src_stride;
-    image.pallet = NULL;
-    glc_draw_image(canvas->glc, &gldest, &src, &image, 0, 1);
-
-    glc_flush(canvas->glc);
-}
-
-static void gl_canvas_group_end(SpiceCanvas *spice_canvas)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-
-    canvas_base_group_end(spice_canvas);
-    glc_clear_mask(canvas->glc, GLC_MASK_B);
-}
-
-static int need_init = 1;
-static SpiceCanvasOps gl_canvas_ops;
-
-SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                              , SpiceImageCache *bits_cache
-                              , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                              , SpiceImageCache *bits_cache
-#endif
-                              , SpiceImageSurfaces *surfaces
-                              , SpiceGlzDecoder *glz_decoder
-                              , SpiceJpegDecoder *jpeg_decoder
-                              , SpiceZlibDecoder *zlib_decoder
-                           )
-{
-    GLCanvas *canvas;
-    int init_ok;
-
-    if (need_init) {
-        return NULL;
-    }
-    canvas = spice_new0(GLCanvas, 1);
-
-    if (!(canvas->glc = glc_create(width, height))) {
-        goto error_1;
-    }
-    canvas->private_data = NULL;
-    init_ok = canvas_base_init(&canvas->base, &gl_canvas_ops,
-                               width, height, format
-#ifdef SW_CANVAS_CACHE
-                               , bits_cache
-                               , palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                               , bits_cache
-#endif
-                               , surfaces
-                               , glz_decoder
-                               , jpeg_decoder
-                               , zlib_decoder
-                               );
-    if (!init_ok) {
-        goto error_2;
-    }
-
-    return (SpiceCanvas *)canvas;
-
-error_2:
-    glc_destroy(canvas->glc, 0);
-error_1:
-    free(canvas);
-
-    return NULL;
-}
-
-void gl_canvas_set_textures_lost(SpiceCanvas *spice_canvas,
-                                 int textures_lost)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-
-    canvas->textures_lost = textures_lost;
-}
-
-static void gl_canvas_destroy(SpiceCanvas *spice_canvas)
-{
-    GLCanvas *canvas = (GLCanvas *)spice_canvas;
-
-    if (!canvas) {
-        return;
-    }
-    canvas_base_destroy(&canvas->base);
-    glc_destroy(canvas->glc, canvas->textures_lost);
-    if (canvas->private_data) {
-        free(canvas->private_data);
-    }
-    free(canvas);
-}
-
-void gl_canvas_init() //unsafe global function
-{
-    if (!need_init) {
-        return;
-    }
-    need_init = 0;
-
-    canvas_base_init_ops(&gl_canvas_ops);
-    gl_canvas_ops.draw_fill = gl_canvas_draw_fill;
-    gl_canvas_ops.draw_copy = gl_canvas_draw_copy;
-    gl_canvas_ops.draw_opaque = gl_canvas_draw_opaque;
-    gl_canvas_ops.copy_bits = gl_canvas_copy_bits;
-    gl_canvas_ops.draw_text = gl_canvas_draw_text;
-    gl_canvas_ops.draw_stroke = gl_canvas_draw_stroke;
-    gl_canvas_ops.draw_rop3 = gl_canvas_draw_rop3;
-    gl_canvas_ops.draw_blend = gl_canvas_draw_blend;
-    gl_canvas_ops.draw_blackness = gl_canvas_draw_blackness;
-    gl_canvas_ops.draw_whiteness = gl_canvas_draw_whiteness;
-    gl_canvas_ops.draw_invers = gl_canvas_draw_invers;
-    gl_canvas_ops.draw_transparent = gl_canvas_draw_transparent;
-    gl_canvas_ops.draw_alpha_blend = gl_canvas_draw_alpha_blend;
-    gl_canvas_ops.put_image = gl_canvas_put_image;
-    gl_canvas_ops.clear = gl_canvas_clear;
-    gl_canvas_ops.read_bits = gl_canvas_read_bits;
-    gl_canvas_ops.group_start = gl_canvas_group_start;
-    gl_canvas_ops.group_end = gl_canvas_group_end;
-    gl_canvas_ops.destroy = gl_canvas_destroy;
-
-    rop3_init();
-}
diff --git a/common/gl_canvas.h b/common/gl_canvas.h
deleted file mode 100644
index d7125e6..0000000
--- a/common/gl_canvas.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "glc.h"
-#include "canvas_base.h"
-#include "region.h"
-
-SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-			   , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           );
-void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost);
-void gl_canvas_init();
-
diff --git a/common/gl_utils.h b/common/gl_utils.h
deleted file mode 100644
index eecff26..0000000
--- a/common/gl_utils.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef GL_UTILS_H
-#define GL_UTILS_H
-
-#ifdef RED_DEBUG
-#define GLC_ERROR_TEST_FLUSH {                                        \
-    GLenum gl_err;  glFlush();                                        \
-    if ((gl_err = glGetError()) != GL_NO_ERROR) {                     \
-        printf("%s[%d]: opengl error: %s\n",  __FUNCTION__, __LINE__, \
-        gluErrorString(gl_err));                                      \
-        abort();                                                      \
-    }                                                                 \
-}
-
-#define GLC_ERROR_TEST_FINISH {                                       \
-    GLenum gl_err;  glFinish();                                       \
-    if ((gl_err = glGetError()) != GL_NO_ERROR) {                     \
-        printf("%s[%d]: opengl error: %s\n",  __FUNCTION__, __LINE__, \
-        gluErrorString(gl_err));                                      \
-        abort();                                                      \
-    }                                                                 \
-}
-#else
-#define GLC_ERROR_TEST_FLUSH ;
-
-#define GLC_ERROR_TEST_FINISH ;
-#endif
-
-#ifdef WIN32
-static inline int find_msb(uint32_t val)
-{
-    uint32_t r;
-    __asm {
-        bsr eax, val
-        jnz found
-        mov eax, -1
-
-found:
-        mov r, eax
-    }
-    return r + 1;
-}
-
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-static inline int find_msb(unsigned int val)
-{
-    int ret;
-
-    asm ("bsrl %1,%0\n\t"
-         "jnz 1f\n\t"
-         "movl $-1,%0\n"
-         "1:"
-         : "=r"(ret) : "r"(val));
-    return ret + 1;
-}
-
-#else
-static inline int find_msb(unsigned int val)
-{
-    signed char index = 31;
-
-    if(val == 0) {
-        return 0;
-    }
-
-    do {
-        if(val & 0x80000000) {
-            break;
-        }
-        val <<= 1;
-    } while(--index >= 0);
-
-    return index+1;
-}
-
-#endif
-
-static inline int gl_get_to_power_two(unsigned int val)
-{
-    if ((val & (val - 1)) == 0) {
-        return val;
-    }
-    return 1 << find_msb(val);
-}
-
-#endif
diff --git a/common/glc.c b/common/glc.c
deleted file mode 100644
index e4263cd..0000000
--- a/common/glc.c
+++ /dev/null
@@ -1,1521 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <spice/macros.h>
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
-
-#ifdef WIN32
-#include "glext.h"
-#include "wglext.h"
-#endif
-
-#include "mem.h"
-#include "glc.h"
-#include "gl_utils.h"
-
-#define ASSERT(x) if (!(x)) {printf("%s: assert failed %s\n", __FUNCTION__, #x); abort();}
-
-#define WARN_ONCE(x) {      \
-    static int warn = TRUE; \
-    if (warn) {             \
-        printf x;           \
-        warn = FALSE;       \
-    }                       \
-}
-
-#define TESS_VERTEX_ALLOC_BUNCH 20
-
-typedef struct InternaCtx InternaCtx;
-typedef struct InternalPat {
-    InternaCtx *owner;
-    int refs;
-    GLuint texture;
-    int x_orign;
-    int y_orign;
-    int width;
-    int height;
-} InternalPat;
-
-typedef struct Pathpath {
-    int start_point;
-    int num_segments;
-} Path;
-
-enum  {
-    GLC_PATH_SEG_LINES,
-    GLC_PATH_SEG_BEIZER,
-};
-
-//todo: flatten cache
-typedef struct PathSegment {
-    int type;
-    int count;
-} PathSegment;
-
-typedef struct PathPoint {
-    double x;
-    double y;
-    double z;
-} PathPoint;
-
-typedef GLdouble Vertex[3];
-
-typedef struct InternalPath {
-    InternaCtx *owner;
-
-    Path *paths;
-    int paths_size;
-    int paths_pos;
-
-    PathSegment *segments;
-    int segments_size;
-    int segments_pos;
-
-    PathPoint *points;
-    int points_size;
-    int points_pos;
-
-    Path *current_path;
-    PathSegment *current_segment;
-} InternalPath;
-
-typedef struct TassVertex TassVertex;
-struct TassVertex {
-    PathPoint point;
-    TassVertex *list_link;
-    TassVertex *next;
-};
-
-typedef struct TassVertexBuf TassVertexBuf;
-struct TassVertexBuf {
-    TassVertexBuf *next;
-    TassVertex vertexs[0];
-};
-
-#define USE_LINE_ANTIALIAS 0
-
-typedef struct LineDash {
-    double *dashes;
-    int num_dashes;
-    double offset;
-    int cur_dash;
-    double dash_pos;
-} LineDash;
-
-enum  {
-    GLC_STROKE_NONACTIVE,
-    GLC_STROKE_FIRST,
-    GLC_STROKE_ACTIVE,
-};
-
-typedef struct PathStroke {
-    double x;
-    double y;
-    int state;
-} PathStroke;
-
-struct InternaCtx {
-    int draw_mode;
-    int stencil_refs;
-    int stencil_mask;
-    int width;
-    int height;
-    GLfloat line_width;
-    LineDash line_dash;
-    PathStroke path_stroke;
-    InternalPat *pat;
-    int max_texture_size;
-    GLUtesselator* tesselator;
-    TassVertex *free_tess_vertex;
-    TassVertex *used_tess_vertex;
-    TassVertexBuf *vertex_bufs;
-    int private_tex_width;
-    int private_tex_height;
-    GLuint private_tex;
-#ifdef WIN32
-    PFNGLBLENDEQUATIONPROC glBlendEquation;
-#endif
-};
-
-#define Y(y) -(y)
-#define VERTEX2(x, y) glVertex2d(x, Y(y))
-
-static void fill_rect(InternaCtx *ctx, void *rect);
-static void fill_path(InternaCtx *ctx, void *path);
-static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride,
-                      const uint8_t *bitmap);
-static void set_pat(InternaCtx *ctx, InternalPat *pat);
-
-static inline void set_raster_pos(InternaCtx *ctx, int x, int y)
-{
-    if (x >= 0 && y >= 0 && x < ctx->width && y < ctx->height) {
-        glRasterPos2i(x, Y(y));
-        return;
-    }
-    glRasterPos2i(0, 0);
-    glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL);
-}
-
-static TassVertex *alloc_tess_vertex(InternaCtx *ctx)
-{
-    TassVertex *vertex;
-
-    if (!ctx->free_tess_vertex) {
-        TassVertexBuf *buf;
-        int i;
-
-        buf = (TassVertexBuf *)spice_malloc(sizeof(TassVertexBuf) +
-                                            sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH);
-        buf->next = ctx->vertex_bufs;
-        ctx->vertex_bufs = buf;
-        for (i = 0; i < TESS_VERTEX_ALLOC_BUNCH; i++) {
-            buf->vertexs[i].point.z = 0;
-            buf->vertexs[i].next = ctx->free_tess_vertex;
-            ctx->free_tess_vertex = &buf->vertexs[i];
-        }
-    }
-
-    vertex = ctx->free_tess_vertex;
-    ctx->free_tess_vertex = vertex->next;
-    vertex->next = ctx->used_tess_vertex;
-    ctx->used_tess_vertex = vertex;
-    return vertex;
-}
-
-static void reset_tass_vertex(InternaCtx *ctx)
-{
-    TassVertex *vertex;
-    while ((vertex = ctx->used_tess_vertex)) {
-        ctx->used_tess_vertex = vertex->next;
-        vertex->next = ctx->free_tess_vertex;
-        ctx->free_tess_vertex = vertex;
-    }
-}
-
-static void free_tass_vertex_bufs(InternaCtx *ctx)
-{
-    TassVertexBuf *buf;
-
-    ctx->used_tess_vertex = NULL;
-    ctx->free_tess_vertex = NULL;
-    while ((buf = ctx->vertex_bufs)) {
-        ctx->vertex_bufs = buf->next;
-        free(buf);
-    }
-}
-
-//naive bezier flattener
-static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points)
-{
-    double ax, bx, cx;
-    double ay, by, cy;
-    const int num_points = 30;
-    double dt;
-    int i;
-
-    TassVertex *vertex_list = NULL;
-    TassVertex *curr_vertex;
-
-    for (i = 0; i < num_points - 2; i++) {
-        TassVertex *vertex;
-
-        vertex = alloc_tess_vertex(ctx);
-        vertex->list_link = vertex_list;
-        vertex_list = vertex;
-    }
-
-    curr_vertex = vertex_list;
-
-    cx = 3.0 * (points[1].x - points[0].x);
-    bx = 3.0 * (points[2].x - points[1].x) - cx;
-    ax = points[3].x - points[0].x - cx - bx;
-
-    cy = 3.0 * (points[1].y - points[0].y);
-    by = 3.0 * (points[2].y - points[1].y) - cy;
-    ay = points[3].y - points[0].y - cy - by;
-
-    dt = 1.0 / (num_points - 1);
-
-    for (i = 1; i < num_points - 1; i++, curr_vertex = curr_vertex->list_link) {
-        double tSquared, tCubed;
-        double t;
-        t = i * dt;
-
-        tSquared = t * t;
-        tCubed = tSquared * t;
-
-        curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x;
-        curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y;
-    }
-
-    return vertex_list;
-}
-
-#define MORE_X(path, Type, name) {                                              \
-    Type *name;                                                                 \
-                                                                                \
-    name = spice_new0(Type, path->name##_size * 2);                             \
-    memcpy(name, path->name, sizeof(*name) * path->name##_size);                \
-    free(path->name);                                                           \
-    path->name = name;                                                          \
-    path->name##_size *= 2;                                                     \
-}
-
-static void more_points(InternalPath *path)
-{
-    MORE_X(path, PathPoint, points);
-}
-
-static void more_segments(InternalPath *path)
-{
-    MORE_X(path, PathSegment, segments);
-}
-
-static void more_paths(InternalPath *path)
-{
-    MORE_X(path, Path, paths);
-}
-
-static inline void put_point(InternalPath *path, double x, double y)
-{
-    path->points[path->points_pos].x = x;
-    path->points[path->points_pos].y = Y(y + 0.5);
-    path->points[path->points_pos++].z = 0;
-}
-
-void glc_path_move_to(GLCPath path, double x, double y)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    ASSERT(internal);
-
-    if (internal->current_segment) {
-        internal->current_segment = NULL;
-        internal->current_path = NULL;
-        if (internal->points_pos == internal->points_size) {
-            more_points(internal);
-        }
-        internal->points_pos++;
-    }
-    internal->points[internal->points_pos - 1].x = x;
-    internal->points[internal->points_pos - 1].y = Y(y + 0.5);
-    internal->points[internal->points_pos - 1].z = 0;
-}
-
-static void add_segment_common(InternalPath *internal, int type, int num_points)
-{
-    if (internal->points_size - internal->points_pos < num_points) {
-        more_points(internal);
-    }
-
-    if (internal->current_segment) {
-        if (internal->current_segment->type == type) {
-            internal->current_segment->count++;
-            return;
-        }
-        if (internal->segments_pos == internal->segments_size) {
-            more_segments(internal);
-        }
-        internal->current_segment = &internal->segments[internal->segments_pos++];
-        internal->current_segment->type = type;
-        internal->current_segment->count = 1;
-        internal->current_path->num_segments++;
-        return;
-    }
-
-    if (internal->paths_pos == internal->paths_size) {
-        more_paths(internal);
-    }
-
-    if (internal->segments_pos == internal->segments_size) {
-        more_segments(internal);
-    }
-
-    internal->current_path = &internal->paths[internal->paths_pos++];
-    internal->current_path->start_point = internal->points_pos - 1;
-    internal->current_path->num_segments = 1;
-    internal->current_segment = &internal->segments[internal->segments_pos++];
-    internal->current_segment->type = type;
-    internal->current_segment->count = 1;
-}
-
-void glc_path_line_to(GLCPath path, double x, double y)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    ASSERT(internal);
-
-    add_segment_common(internal, GLC_PATH_SEG_LINES, 1);
-    put_point(internal, x, y);
-}
-
-void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
-                       double p3_x, double p3_y)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    ASSERT(internal);
-
-    add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3);
-    put_point(internal, p1_x, p1_y);
-    put_point(internal, p2_x, p2_y);
-    put_point(internal, p3_x, p3_y);
-}
-
-void glc_path_close(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    ASSERT(internal);
-    if (!internal->current_path) {
-        return;
-    }
-    PathPoint *end_point = &internal->points[internal->current_path->start_point];
-    glc_path_line_to(path, end_point->x, Y(end_point->y));
-    glc_path_move_to(path, end_point->x, Y(end_point->y));
-}
-
-void glc_path_cleare(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    ASSERT(internal);
-    internal->paths_pos = internal->segments_pos = 0;
-    internal->current_segment = NULL;
-    internal->current_path = NULL;
-
-    internal->points[0].x = 0;
-    internal->points[0].y = 0;
-    internal->points_pos = 1;
-}
-
-GLCPath glc_path_create(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPath *path;
-
-    ASSERT(ctx);
-    path = spice_new0(InternalPath, 1);
-    path->paths_size = 2;
-    path->paths = spice_new(Path, path->paths_size);
-
-    path->segments_size = 4;
-    path->segments = spice_new(PathSegment, path->segments_size);
-
-    path->points_size = 20;
-    path->points = spice_new(PathPoint, path->points_size);
-
-    path->owner = ctx;
-    path->points_pos = 1;
-    return path;
-}
-
-void glc_path_destroy(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-
-    if (!path) {
-        return;
-    }
-
-    free(internal->points);
-    free(internal->segments);
-    free(internal->paths);
-    free(internal);
-}
-
-static inline void unref_pat(InternalPat *pat)
-{
-    if (!pat) {
-        return;
-    }
-    ASSERT(pat->refs > 0);
-    if (--pat->refs == 0) {
-        glFinish();
-        glDeleteTextures(1, &pat->texture);
-        free(pat);
-    }
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static inline InternalPat *ref_pat(InternalPat *pat)
-{
-    pat->refs++;
-    return pat;
-}
-
-static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height,
-                  uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride)
-{
-    double x_scale = (double)src_width / dest_width;
-    double y_scale = (double)src_height / dest_height;
-    uint32_t i;
-    uint32_t j;
-    int prev_row = -1;
-
-    for (i = 0; i < dest_height; i++) {
-        int row = (int)(y_scale * i);
-        if (row == prev_row) {
-            memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t));
-            dest += dest_width;
-            continue;
-        }
-        for (j = 0; j < dest_width; j++) {
-            int col = (int)(x_scale * j);
-            *(dest++) = *(src + col);
-        }
-        prev_row = row;
-        src = (uint32_t *)((uint8_t *)src + src_stride);
-    }
-}
-
-static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternaCtx *ctx = pat->owner;
-    uint32_t *tmp_pixmap = NULL;
-    int width;
-    int height;
-    int width2;
-    int height2;
-
-    const int pix_bytes = 4;
-
-    ASSERT(image->format == GLC_IMAGE_RGB32); //for now
-
-    width = image->width;
-    height = image->height;
-    width2 = gl_get_to_power_two(width);
-    height2 = gl_get_to_power_two(height);
-
-    ASSERT(width > 0 && height > 0);
-    ASSERT(width > 0 && width <= pat->owner->max_texture_size);
-    ASSERT(height > 0 && height <= pat->owner->max_texture_size);
-
-    if (width2 != width || height2 != height) {
-        tmp_pixmap = (uint32_t *)spice_malloc(width2 * height2 * sizeof(uint32_t));
-        scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride);
-    }
-
-    glBindTexture(GL_TEXTURE_2D, pat->texture);
-
-    //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    if (tmp_pixmap) {
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, width2);
-        glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE,
-                     tmp_pixmap);
-        free(tmp_pixmap);
-    } else {
-        ASSERT(image->stride % pix_bytes == 0);
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
-        glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
-                     image->pixels);
-    }
-
-    GLC_ERROR_TEST_FLUSH;
-    pat->x_orign = x_orign % width;
-    pat->y_orign = y_orign % height;
-    pat->width = width;
-    pat->height = height;
-
-    if (ctx->pat == pat) {
-        set_pat(pat->owner, pat);
-    } else if (ctx->pat) {
-        glBindTexture(GL_TEXTURE_2D, ctx->pat->texture);
-    }
-}
-
-GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPat *pat;
-
-    ASSERT(ctx && image);
-
-    pat = spice_new0(InternalPat, 1);
-    pat->refs = 1;
-    pat->owner = ctx;
-    glGenTextures(1, &pat->texture);
-    init_pattern(pat, x_orign, y_orign, image);
-    return pat;
-}
-
-void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternalPat *pat = (InternalPat *)pattern;
-    ASSERT(pat && pat->owner);
-
-    glFinish();
-    init_pattern(pat, x_orign, y_orign, image);
-}
-
-void glc_pattern_destroy(GLCPattern pat)
-{
-    unref_pat((InternalPat *)pat);
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void set_pat(InternaCtx *ctx, InternalPat *pat)
-{
-    pat = ref_pat(pat);
-    unref_pat(ctx->pat);
-    ctx->pat = pat;
-
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, pat->texture);
-
-    GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 };
-    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 };
-    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
-    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
-
-    glMatrixMode(GL_TEXTURE);
-    glLoadIdentity();
-    glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0);
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_set_pattern(GLCCtx glc, GLCPattern pattern)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPat *pat = (InternalPat *)pattern;
-
-    ASSERT(ctx && pat && pat->owner == ctx);
-    set_pat(ctx, pat);
-}
-
-void glc_set_rgb(GLCCtx glc, double red, double green, double blue)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-
-    glDisable(GL_TEXTURE_2D);
-    unref_pat(ctx->pat);
-    ctx->pat = NULL;
-    glColor4d(red, green, blue, 1);
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_set_op(GLCCtx glc, GLCOp op)
-{
-    if (op == GL_COPY) {
-        glDisable(GL_COLOR_LOGIC_OP);
-        return;
-    }
-    glLogicOp(op);
-    glEnable(GL_COLOR_LOGIC_OP);
-}
-
-void glc_set_line_width(GLCCtx glc, double width)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-    ctx->line_width = (GLfloat)width;
-    if (ctx->line_width > 0) {
-        glLineWidth(ctx->line_width);
-    } else {
-        ctx->line_width = 0;
-    }
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-    if (dashes && num_dashes >= 0 && offset >= 0) {
-        ctx->line_dash.dashes = spice_new(double, num_dashes);
-        memcpy(ctx->line_dash.dashes, dashes, sizeof(double) * num_dashes);
-        ctx->line_dash.num_dashes = num_dashes;
-        ctx->line_dash.offset = offset;
-        ctx->line_dash.cur_dash = offset ? -1 : 0;
-        ctx->line_dash.dash_pos = 0;
-    } else {
-        free(ctx->line_dash.dashes);
-        memset(&ctx->line_dash, 0, sizeof(ctx->line_dash));
-    }
-}
-
-void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-    int mode;
-    switch (fill_mode) {
-    case GLC_FILL_MODE_WINDING_ODD:
-        mode = GLU_TESS_WINDING_ODD;
-        break;
-    case GLC_FILL_MODE_WINDING_NONZERO:
-        mode = GLU_TESS_WINDING_NONZERO;
-        break;
-    default:
-        //warn
-        return;
-    }
-    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode);
-}
-
-static inline void add_stencil_client(InternaCtx *ctx)
-{
-    if (!ctx->stencil_refs) {
-        glEnable(GL_STENCIL_TEST);
-    }
-    ctx->stencil_refs++;
-}
-
-static inline void remove_stencil_client(InternaCtx *ctx)
-{
-    ctx->stencil_refs--;
-    if (!ctx->stencil_refs) {
-        glDisable(GL_STENCIL_TEST);
-    }
-}
-
-void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
-                  int stride, const uint8_t *bitmap, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    ASSERT(ctx && bitmap);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-
-    glDisable(GL_BLEND);
-
-    if (!(ctx->stencil_mask & mask)) {
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= mask;
-    }
-
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-    glStencilMask(mask);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    glStencilFunc(GL_ALWAYS, mask, mask);
-    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
-}
-
-void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    GLCRect *end;
-    ASSERT(ctx && rects);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-
-    glDisable(GL_BLEND);
-
-    if (!(ctx->stencil_mask & mask)) {
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= mask;
-    }
-
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-    glStencilMask(mask);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    glStencilFunc(GL_ALWAYS, mask, mask);
-    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-    end = rects + num_rect;
-    for (; rects < end; rects++) {
-        fill_rect(ctx, rects);
-    }
-}
-
-void glc_clear_mask(GLCCtx glc, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    ASSERT(ctx);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-
-    if ((ctx->stencil_mask & mask)) {
-        ctx->stencil_mask &= ~mask;
-        remove_stencil_client(ctx);
-    }
-}
-
-void glc_clip_reset(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    if (!(ctx->stencil_mask & 0x03)) {
-        return;
-    }
-    remove_stencil_client(ctx);
-    ctx->stencil_mask &= ~0x03;
-    glStencilMask(0x03);
-    glClear(GL_STENCIL_BUFFER_BIT);
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *),
-                        void *data)
-{
-    int stencil_val;
-
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    glDisable(GL_BLEND);
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-
-    if (op == GLC_CLIP_OP_SET) {
-        glc_clip_reset(ctx);
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= 0x01;
-    } else if (!(ctx->stencil_mask & 0x03)) {
-        GLCRect area;
-        if (op == GLC_CLIP_OP_OR) {
-            return;
-        }
-        area.x = area.y = 0;
-        area.width = ctx->width;
-        area.height = ctx->height;
-        clip_common(ctx, GLC_CLIP_OP_SET, fill_rect, &area);
-    }
-    glStencilMask(0x03);
-    switch (op) {
-    case GLC_CLIP_OP_SET:
-    case GLC_CLIP_OP_OR:
-        stencil_val = ctx->stencil_mask & 0x03;
-        glStencilFunc(GL_ALWAYS, stencil_val, stencil_val);
-        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-        fill_func(ctx, data);
-        break;
-    case GLC_CLIP_OP_AND: {
-        int clear_mask;
-        stencil_val = ctx->stencil_mask & 0x03;
-        glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
-        if (stencil_val == 0x01) {
-            glStencilOp(GL_ZERO, GL_INCR, GL_INCR);
-            stencil_val = 0x02;
-            clear_mask = 0x01;
-        } else {
-            glStencilOp(GL_ZERO, GL_DECR, GL_DECR);
-            stencil_val = 0x01;
-            clear_mask = 0x02;
-        }
-        fill_func(ctx, data);
-
-        glStencilMask(clear_mask);
-        glClear(GL_STENCIL_BUFFER_BIT);
-        ctx->stencil_mask = (ctx->stencil_mask & ~clear_mask) | stencil_val;
-        break;
-    }
-    case GLC_CLIP_OP_EXCLUDE:
-        stencil_val = ctx->stencil_mask & 0x03;
-        glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
-        glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
-        fill_func(ctx, data);
-        break;
-    }
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx && rect);
-    clip_common(ctx, op, fill_rect, (void *)rect);
-}
-
-void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx && path);
-    clip_common(ctx, op, fill_path, path);
-}
-
-typedef struct FillMaskInfo {
-    int x_dest;
-    int y_dest;
-    int width;
-    int height;
-    int stride;
-    const uint8_t *bitmap;
-} FillMaskInfo;
-
-static void __fill_mask(InternaCtx *ctx, void *data)
-{
-    FillMaskInfo *info = (FillMaskInfo *)data;
-    fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride,
-              info->bitmap);
-}
-
-void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
-                   int stride, const uint8_t *bitmap, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    FillMaskInfo mask_info;
-
-    ASSERT(ctx && bitmap);
-    mask_info.x_dest = x_dest;
-    mask_info.y_dest = y_dest;
-    mask_info.width = width;
-    mask_info.height = height;
-    mask_info.stride = stride;
-    mask_info.bitmap = bitmap;
-    clip_common(ctx, op, __fill_mask, &mask_info);
-}
-
-static inline void start_draw(InternaCtx *ctx)
-{
-    if (ctx->draw_mode) {
-        return;
-    }
-    ctx->draw_mode = TRUE;
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask);
-    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    } else {
-        glDisable(GL_TEXTURE_2D);
-    }
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void fill_rect(InternaCtx *ctx, void *r)
-{
-    GLCRect *rect = (GLCRect *)r;
-    glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height));
-    /*glBegin(GL_POLYGON);
-        VERTEX2(rect->x, rect->y);
-        VERTEX2 (rect->x + rect->width, rect->y);
-        VERTEX2 (rect->x + rect->width, rect->y + rect->height);
-        VERTEX2 (rect->x , rect->y + rect->height);
-    glEnd();*/
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_fill_rect(GLCCtx glc, const GLCRect *rect)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    GLCRect *r = (GLCRect *)rect; // to avoid bugs in gcc older than 4.3
-
-    ASSERT(ctx);
-    start_draw(ctx);
-    fill_rect(ctx, (void *)r);
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void fill_path(InternaCtx *ctx, void *p)
-{
-    InternalPath *path = (InternalPath *)p;
-
-    PathPoint *current_point = path->points;
-    PathSegment *current_segment = path->segments;
-    Path *current_path = path->paths;
-    Path *end_path = current_path + path->paths_pos;
-    reset_tass_vertex(ctx);
-    gluTessBeginPolygon(ctx->tesselator, ctx);
-    for (; current_path < end_path; current_path++) {
-        gluTessBeginContour(ctx->tesselator);
-        PathSegment *end_segment = current_segment + current_path->num_segments;
-        gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point);
-        current_point++;
-        for (; current_segment < end_segment; current_segment++) {
-            PathPoint *end_point;
-            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
-                end_point = current_point + current_segment->count * 3;
-                for (; current_point < end_point; current_point += 3) {
-                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
-                    while (vertex) {
-                        gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point,
-                                      (GLdouble *)&vertex->point);
-                        vertex = vertex->list_link;
-                    }
-                    gluTessVertex(ctx->tesselator, (GLdouble *)&current_point[2],
-                                  (GLdouble *)&current_point[2]);
-                }
-            } else {
-                ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
-                end_point = current_point + current_segment->count;
-                for (; current_point < end_point; current_point++) {
-                    gluTessVertex(ctx->tesselator, (GLdouble *)current_point,
-                                  (GLdouble *)current_point);
-                }
-            }
-        }
-        gluTessEndContour(ctx->tesselator);
-    }
-    gluTessEndPolygon(ctx->tesselator);
-}
-
-void glc_fill_path(GLCCtx glc, GLCPath path_ref)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx && path_ref);
-    start_draw(ctx);
-    fill_path(ctx, path_ref);
-}
-
-static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height,
-                      int stride, const uint8_t *bitmap)
-{
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-    glBitmap(width, height, 0, 0, 0, 0, bitmap);
-}
-
-void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                    const uint8_t *bitmap)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx && bitmap);
-    start_draw(ctx);
-    if (ctx->pat) {
-        WARN_ONCE(("%s: unimplemented fill mask with pattern\n", __FUNCTION__));
-    }
-    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
-}
-
-void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                    const uint8_t *alpha_mask)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    GLCRect r;
-
-    ASSERT(ctx);
-    start_draw(ctx);
-
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
-    glPixelZoom(1, 1);
-    glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask);
-
-    r.x = x_dest;
-    r.y = y_dest;
-    r.width = width;
-    r.height = height;
-
-    //todo: support color/texture alpah vals (GL_MODULATE)
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    fill_rect(ctx, &r);
-    glDisable(GL_BLEND);
-}
-
-void glc_stroke_rect(GLCCtx glc, const GLCRect *rect)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-    if (ctx->line_width == 0) {
-        return;
-    }
-
-    start_draw(ctx);
-
-    glBegin(GL_LINES);
-    VERTEX2(rect->x, rect->y + 0.5);
-    VERTEX2(rect->x + rect->width, rect->y + 0.5);
-    VERTEX2(rect->x + rect->width - 0.5, rect->y);
-    VERTEX2(rect->x + rect->width - 0.5, rect->y + rect->height);
-    VERTEX2(rect->x + rect->width, rect->y + rect->height - 0.5);
-    VERTEX2(rect->x, rect->y + rect->height - 0.5);
-    VERTEX2(rect->x + 0.5, rect->y + rect->height);
-    VERTEX2(rect->x + 0.5, rect->y);
-    glEnd();
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void glc_stroke_line(double x1, double y1, double x2, double y2, double width)
-{
-    double ax, ay, bx, by, cx, cy, dx, dy;
-    double norm, tx;
-
-    if (width == 1 || y1 == y2 || x1 == x2) {
-        glBegin(GL_LINES);
-        glVertex2d(x1, y1);
-        glVertex2d(x2, y2);
-        glEnd();
-        return;
-    }
-    norm = (x1 - x2) / (y2 - y1);
-    tx = width / (2 * sqrt(1 + norm * norm));
-    ax = x1 + tx;
-    ay = y1 + norm * (ax - x1);
-    bx = x2 + tx;
-    by = y2 + norm * (bx - x2);
-    cx = x2 - tx;
-    cy = y2 + norm * (cx - x2);
-    dx = x1 - tx;
-    dy = y1 + norm * (dx - x1);
-    glBegin(GL_POLYGON);
-    glVertex2d(ax, ay);
-    glVertex2d(bx, by);
-    glVertex2d(cx, cy);
-    glVertex2d(dx, dy);
-    glEnd();
-}
-
-static double glc_stroke_line_dash(double x1, double y1, double x2, double y2,
-                                   double width, LineDash *dash)
-{
-    double ax, ay, bx, by;
-    double mx, my, len;
-    double dash_len, total = 0;
-
-    len = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
-    if (!dash->dashes || !dash->num_dashes) {
-        glc_stroke_line(x1, y1, x2, y2, width);
-        return len;
-    }
-    mx = (x2 - x1) / len;
-    my = (y2 - y1) / len;
-    ax = x1;
-    ay = y1;
-    while (total < len) {
-        if (dash->cur_dash >= 0) {
-            dash_len = dash->dashes[dash->cur_dash % dash->num_dashes] - dash->dash_pos;
-        } else {
-            dash_len = dash->offset - dash->dash_pos;
-        }
-        total += dash_len;
-        if (total < len) {
-            bx = x1 + mx * total;
-            by = y1 + my * total;
-            dash->dash_pos = 0;
-        } else {
-            bx = x2;
-            by = y2;
-            dash->dash_pos = dash->dashes[dash->cur_dash % dash->num_dashes] - (total - len);
-        }
-        if (dash->cur_dash % 2 == 0) {
-            glc_stroke_line(ax, ay, bx, by, width);
-        }
-        if (dash->dash_pos == 0) {
-            dash->cur_dash = (dash->cur_dash + 1) % (2 * dash->num_dashes);
-        }
-        ax = bx;
-        ay = by;
-    }
-    return len;
-}
-
-static void glc_vertex2d(InternaCtx *ctx, double x, double y)
-{
-    double len;
-    if (ctx->path_stroke.state == GLC_STROKE_ACTIVE) {
-        len = glc_stroke_line_dash(ctx->path_stroke.x, ctx->path_stroke.y, x, y,
-                                   ctx->line_width, &ctx->line_dash);
-        ctx->path_stroke.x = x;
-        ctx->path_stroke.y = y;
-    } else if (ctx->path_stroke.state == GLC_STROKE_FIRST) {
-        ctx->path_stroke.x = x;
-        ctx->path_stroke.y = y;
-        ctx->path_stroke.state = GLC_STROKE_ACTIVE;
-    } else {
-        ASSERT(ctx->path_stroke.state == GLC_STROKE_NONACTIVE);
-        //error
-    }
-}
-
-static void glc_begin_path(InternaCtx *ctx)
-{
-    ctx->path_stroke.state = GLC_STROKE_FIRST;
-    ctx->line_dash.cur_dash = ctx->line_dash.offset ? -1 : 0;
-    ctx->line_dash.dash_pos = 0;
-}
-
-static void glc_end_path(InternaCtx *ctx)
-{
-    ctx->path_stroke.state = GLC_STROKE_NONACTIVE;
-}
-
-void glc_stroke_path(GLCCtx glc, GLCPath path_ref)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPath *path = (InternalPath *)path_ref;
-
-    ASSERT(ctx && path);
-    if (ctx->line_width == 0) {
-        return;
-    }
-    start_draw(ctx);
-
-    reset_tass_vertex(ctx);
-    PathPoint *current_point = path->points;
-    PathSegment *current_segment = path->segments;
-    Path *current_path = path->paths;
-    Path *end_path = current_path + path->paths_pos;
-    for (; current_path < end_path; current_path++) {
-        glc_begin_path(ctx);
-        PathSegment *end_segment = current_segment + current_path->num_segments;
-        glc_vertex2d(ctx, current_point->x, current_point->y);
-        current_point++;
-        for (; current_segment < end_segment; current_segment++) {
-            PathPoint *end_point;
-            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
-                end_point = current_point + current_segment->count * 3;
-                for (; current_point < end_point; current_point += 3) {
-                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
-                    while (vertex) {
-                        glc_vertex2d(ctx, vertex->point.x, vertex->point.y);
-                        vertex = vertex->list_link;
-                    }
-                    glc_vertex2d(ctx, current_point[2].x, current_point[2].y);
-                }
-            } else {
-                ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
-                end_point = current_point + current_segment->count;
-                for (; current_point < end_point; current_point++) {
-                    glc_vertex2d(ctx, current_point->x, current_point->y);
-                }
-            }
-        }
-        glc_end_path(ctx);
-    }
-}
-
-void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
-                    int scale_mode, double alpha)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint8_t *pixels;
-    const int pix_bytes = 4;
-
-    ASSERT(ctx && image);
-    ASSERT(src->width > 0 && src->height > 0);
-
-    ASSERT(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now
-    start_draw(ctx);
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    set_raster_pos(ctx, dest->x, dest->y + dest->height);
-
-    if (dest->width == src->width && src->height == dest->height) {
-        glPixelZoom(1, 1);
-    } else {
-        glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height);
-    }
-
-    pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride;
-    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
-        glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha);
-        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-        glEnable(GL_BLEND);
-    }
-    ASSERT(image->stride % pix_bytes == 0);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
-    glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
-
-    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
-        glDisable(GL_BLEND);
-    }
-
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    }
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
-                     int height)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    int recreate = 0;
-
-    ASSERT(ctx);
-#ifdef USE_COPY_PIXELS
-    start_draw(ctx);
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelZoom(1, 1);
-    glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR);
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    }
-#else
-    int width2 = gl_get_to_power_two(width);
-    int height2 = gl_get_to_power_two(height);
-
-    start_draw(ctx);
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, 0);
-
-    if (width2 > ctx->private_tex_width) {
-        ctx->private_tex_width = width2;
-        recreate = 1;
-    }
-    if (height2 > ctx->private_tex_height) {
-        ctx->private_tex_height = height2;
-        recreate = 1;
-    }
-    if (recreate) {
-        glDeleteTextures(1, &ctx->private_tex);
-        glGenTextures(1, &ctx->private_tex);
-        glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-        ctx->private_tex_width = gl_get_to_power_two(width);
-        ctx->private_tex_height = gl_get_to_power_two(height);
-        glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->private_tex_width,
-                     ctx->private_tex_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-    }
-    ASSERT(ctx->private_tex);
-    glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
-    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height),
-                     width2, height2, 0);
-
-    GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 };
-    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 };
-    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
-    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
-
-    glMatrixMode(GL_TEXTURE);
-    glLoadIdentity();
-    glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0);
-
-    glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height));
-    glFlush();
-    if (!ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    } else {
-        set_pat(ctx, ctx->pat);
-    }
-#endif
-    GLC_ERROR_TEST_FLUSH;
-}
-
-void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx && image);
-    ASSERT(image->format == GLC_IMAGE_RGB32); //for now
-    ASSERT((image->stride % 4) == 0); //for now
-    glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4);
-    glReadPixels(x, ctx->height - (y + image->height), image->width, image->height,
-                 GL_BGRA, GL_UNSIGNED_BYTE, image->pixels);
-}
-
-void glc_clear(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-
-    ASSERT(ctx);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    glClear(GL_COLOR_BUFFER_BIT);
-}
-
-void glc_flush(GLCCtx glc)
-{
-    glFlush();
-
-    GLC_ERROR_TEST_FLUSH;
-}
-
-static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4],
-                                 GLdouble **data_out, void *usr_data)
-{
-    TassVertex *vertex;
-
-    vertex = alloc_tess_vertex((InternaCtx *)usr_data);
-    vertex->point.x = coords[0];
-    vertex->point.y = coords[1];
-    //vertex->point.z = coords[2];
-    *data_out = (GLdouble *)&vertex->point;
-}
-
-static void tessellation_error(GLenum errorCode)
-{
-    printf("%s: %s\n", __FUNCTION__, gluErrorString(errorCode));
-}
-
-#ifdef WIN32
-#define TESS_CALL_BACK_TYPE void(CALLBACK *)()
-#else
-#define TESS_CALL_BACK_TYPE void(*)()
-#endif
-
-static int init(InternaCtx *ctx, int width, int height)
-{
-#ifdef WIN32
-    if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) {
-        return FALSE;
-    }
-#endif
-    ctx->width = width;
-    ctx->height = height;
-    ctx->line_width = 1;
-
-    glClearColor(0, 0, 0, 0);
-    glClearStencil(0);
-
-    if (!(ctx->tesselator = gluNewTess())) {
-        return FALSE;
-    }
-
-    glGenTextures(1, &ctx->private_tex);
-    glBindTexture(GL_TEXTURE_2D, ctx->private_tex);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-    glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_get_to_power_two(width),
-                 gl_get_to_power_two(height), 0,
-                 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-    ctx->private_tex_width = gl_get_to_power_two(width);
-    ctx->private_tex_height = gl_get_to_power_two(height);
-    glBindTexture(GL_TEXTURE_2D, 0);
-
-    glViewport(0, 0, width, height);
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(0, width, 0, height, -1, 1);
-
-    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
-    gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin);
-    gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv);
-    gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd);
-    gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA,
-                    (TESS_CALL_BACK_TYPE)tessellation_combine);
-    gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error);
-
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-    glEnable(GL_TEXTURE_GEN_S);
-    glEnable(GL_TEXTURE_GEN_T);
-
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    glTranslatef(0, (GLfloat)height, 0);
-
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size);
-
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
-    glPixelTransferf(GL_ALPHA_BIAS, 0);
-#ifdef WIN32
-    ctx->glBlendEquation(GL_FUNC_ADD);
-#else
-    glBlendEquation(GL_FUNC_ADD);
-#endif
-
-    glStencilMask(0xff);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    return TRUE;
-}
-
-GLCCtx glc_create(int width, int height)
-{
-    InternaCtx *ctx;
-
-    ASSERT(sizeof(PathPoint) == sizeof(Vertex));
-
-    ctx = spice_new0(InternaCtx, 1);
-    if (!init(ctx, width, height)) {
-        free(ctx);
-        return NULL;
-    }
-    return ctx;
-}
-
-/*
- * In glx video mode change the textures will be destroyed, therefore
- * if we will try to glDeleteTextures() them we might get seagfault.
- * (this why we use the textures_lost parameter)
- */
-void glc_destroy(GLCCtx glc, int textures_lost)
-{
-    InternaCtx *ctx;
-
-    if (!(ctx = (InternaCtx *)glc)) {
-        return;
-    }
-
-    if (!textures_lost) {
-        unref_pat(ctx->pat);
-        ctx->pat = NULL;
-        if (ctx->private_tex) {
-            glDeleteTextures(1, &ctx->private_tex);
-        }
-    }
-
-    free_tass_vertex_bufs(ctx);
-    free(ctx->line_dash.dashes);
-    free(ctx);
-    GLC_ERROR_TEST_FINISH;
-}
-
-/*
-    todo:
-        1. test double vs float in gl calls
-        2. int vs flat raster position
-        3. pixels stride vs bytes stride
-        4. improve non power of two.
-                glGetString(GL_EXTENSIONS);
-                ARB_texture_non_power_of_two
-                ARB_texture_rectangle
-                GL_TEXTURE_RECTANGLE_ARB
-        5. scale
-        6. origin
-        7. fonts
-        8. support more image formats
-        9. use GLCImage in mask ops?
-*/
-
diff --git a/common/glc.c.save b/common/glc.c.save
deleted file mode 100644
index 1958110..0000000
--- a/common/glc.c.save
+++ /dev/null
@@ -1,1413 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-#ifdef WIN32
-#include "glext.h"
-#include "wglext.h"
-#endif
-
-#include "glc.h"
-
-#define TRUE 1
-#define FALSE 0
-
-#define ASSERT(x) if (!(x)) {printf("%s: assert failed %s\n", __FUNCTION__, #x); for (;;);}
-
-#define GLC_ERROR_TETS {                                                                        \
-    GLenum gl_err;  glFlush();                                                                  \
-    if ((gl_err = glGetError()) != GL_NO_ERROR) {                                               \
-        printf("%s[%d]: opengl error: %s\n",  __FUNCTION__, __LINE__, gluErrorString(gl_err));  \
-        for(;;);                                                                                \
-    }                                                                                           \
-}
-
-#define WARN_ONCE(x) {      \
-    static int warn = TRUE; \
-    if (warn) {             \
-        printf x;           \
-        warn = FALSE;       \
-    }                       \
-}
-
-#define TESS_VERTEX_ALLOC_BUNCH 20
-
-typedef struct InternaCtx InternaCtx;
-typedef struct InternalPat {
-    InternaCtx *owner;
-    int refs;
-    GLuint texture;
-    int x_orign;
-    int y_orign;
-    int width;
-    int height;
-} InternalPat;
-
-typedef struct Pathpath {
-    int start_point;
-    int num_segments;
-} Path;
-
-enum  {
-    GLC_PATH_SEG_LINES,
-    GLC_PATH_SEG_BEIZER,
-};
-
-//todo: flatten cache
-typedef struct PathSegment {
-    int type;
-    int count;
-} PathSegment;
-
-typedef struct PathPoint {
-    double x;
-    double y;
-    double z;
-} PathPoint;
-
-typedef GLdouble Vertex[3];
-
-typedef struct InternalPath {
-    InternaCtx *owner;
-    
-    Path *paths;
-    int paths_size;
-    int paths_pos;
-
-    PathSegment *segments;
-    int segments_size;
-    int segments_pos;
-   
-    PathPoint *points;
-    int points_size;
-    int points_pos;
-    
-    Path *current_path;
-    PathSegment *current_segment;
-    
-} InternalPath;
-
-typedef struct TassVertex TassVertex;
-struct TassVertex {
-    PathPoint point;
-    TassVertex *list_link;
-    TassVertex *next;
-};
-
-typedef struct TassVertexBuf TassVertexBuf;
-struct TassVertexBuf {
-    TassVertexBuf *next;
-    TassVertex vertexs[0];
-};
-
-struct InternaCtx {
-    int draw_mode;
-    int stencil_refs;
-    int stencil_mask;
-    int width;
-    int height;
-    GLfloat line_width;
-    InternalPat *pat;
-    int max_texture_size;
-    GLUtesselator* tesselator;
-    TassVertex *free_tess_vertex;
-    TassVertex *used_tess_vertex;
-    TassVertexBuf *vertex_bufs;
-#ifdef WIN32
-    PFNGLBLENDEQUATIONPROC glBlendEquation;
-#endif
-};
-
-#define Y(y) -(y)
-#define VERTEX2(x, y) glVertex2d(x, Y(y))
-
-static void fill_rect(InternaCtx *ctx, void *rect);
-static void fill_path(InternaCtx *ctx, void *path);
-static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride,
-                      const uint8_t *bitmap);
-static void set_pat(InternaCtx *ctx, InternalPat *pat);
-
-static inline void *zmalloc(size_t size)
-{
-    return calloc(1, size);
-}
-
-static inline void set_raster_pos(InternaCtx *ctx, int x, int y)
-{
-    if (x >= 0 && y >= 0 && x < ctx->width && y < ctx->height) {
-        glRasterPos2i(x, Y(y));
-        return;
-    }
-    glRasterPos2i(0, 0);
-    glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL);
-}
-
-static TassVertex *alloc_tess_vertex(InternaCtx *ctx)
-{
-    TassVertex *vertex;
-    
-    if (!ctx->free_tess_vertex) {
-        TassVertexBuf *buf;
-        int i;
-        
-        if (!(buf = (TassVertexBuf *)malloc(sizeof(TassVertexBuf) +
-                                            sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH))) {
-            //warn
-            return NULL;
-        }
-        buf->next = ctx->vertex_bufs;
-        ctx->vertex_bufs = buf;
-        for (i = 0; i < TESS_VERTEX_ALLOC_BUNCH; i++) {
-            buf->vertexs[i].point.z = 0;
-            buf->vertexs[i].next = ctx->free_tess_vertex;
-            ctx->free_tess_vertex = &buf->vertexs[i];
-        }
-    }
-    
-    vertex = ctx->free_tess_vertex;
-    ctx->free_tess_vertex = vertex->next;
-    vertex->next = ctx->used_tess_vertex;
-    ctx->used_tess_vertex = vertex;
-    return vertex;
-}
-
-static void reset_tass_vertex(InternaCtx *ctx)
-{
-    TassVertex *vertex;
-    while ((vertex = ctx->used_tess_vertex)) {
-        ctx->used_tess_vertex = vertex->next;
-        vertex->next = ctx->free_tess_vertex;
-        ctx->free_tess_vertex = vertex;
-    }
-}
-
-static void free_tass_vertex_bufs(InternaCtx *ctx)
-{
-    TassVertexBuf *buf;
-    
-    ctx->used_tess_vertex = NULL;
-    ctx->free_tess_vertex = NULL;
-    while ((buf = ctx->vertex_bufs)) {
-        ctx->vertex_bufs = buf->next;
-        free(buf);
-    }
-}
-
-//naiev bezier flattener
-static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points)
-{
-    double   ax, bx, cx;
-    double   ay, by, cy;
-    const int num_points = 30;
-    double dt;
-    int i;
-    
-    TassVertex *vertex_list = NULL;
-    TassVertex *curr_vertex;
-    
-    for (i = 0; i < num_points - 2; i++) {
-        TassVertex *vertex;
-        
-        if (!(vertex = alloc_tess_vertex(ctx))) {
-            //warn
-            return NULL;
-        }
-        vertex->list_link = vertex_list;
-        vertex_list = vertex;
-    }
-    
-    curr_vertex = vertex_list;
- 
-    cx = 3.0 * (points[1].x - points[0].x);
-    bx = 3.0 * (points[2].x - points[1].x) - cx;
-    ax = points[3].x - points[0].x - cx - bx;
- 
-    cy = 3.0 * (points[1].y - points[0].y);
-    by = 3.0 * (points[2].y - points[1].y) - cy;
-    ay = points[3].y - points[0].y - cy - by;
- 
-    dt = 1.0 / ( num_points - 1 );
- 
-    for( i = 1; i < num_points - 1; i++, curr_vertex = curr_vertex->list_link) {
-        double  tSquared, tCubed;
-        double t;
-        t = i * dt;
-        
-        tSquared = t * t;
-        tCubed = tSquared * t;
- 
-        curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x;
-        curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y;
-    }
-    
-    return vertex_list;
-}
-
-#define MORE_X(path, Type, name) {\
-    Type *name;\
-    \
-    if (!(name = (Type *)zmalloc(sizeof(*name) * path->name##_size * 2))) {\
-        return FALSE;\
-    }\
-    memcpy(name, path->name, sizeof(*name) * path->name##_size);\
-    free(path->name);\
-    path->name = name;\
-    path->name##_size *= 2;\
-    return TRUE;\
-}
-
-static int more_points(InternalPath *path)
-{
-    MORE_X(path, PathPoint, points);
-}
-
-static int more_segments(InternalPath *path)
-{
-    MORE_X(path, PathSegment, segments);
-}
-
-static int more_paths(InternalPath *path)
-{
-    MORE_X(path, Path, paths);
-}
-
-static inline void put_point(InternalPath *path, double x, double y)
-{
-    path->points[path->points_pos].x = x;
-    path->points[path->points_pos++].y = Y(y + 0.5);
-    path->points[path->points_pos].z = 0;
-}
-
-void glc_path_move_to(GLCPath path, double x, double y)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    ASSERT(internal);
-    
-    if (internal->current_segment) {
-        internal->current_segment = NULL;
-        internal->current_path = NULL;
-        if (internal->points_pos == internal->points_size && !more_points(internal)) {
-            //warn
-            return;
-        }
-        internal->points_pos++;
-    }
-    internal->points[internal->points_pos - 1].x = x;
-    internal->points[internal->points_pos - 1].y = Y(y + 0.5); 
-    internal->points[internal->points_pos - 1].z = 0;
-}
-
-static int add_segment_common(InternalPath *internal, int type, int num_points)
-{
-    if (internal->points_size - internal->points_pos < num_points && !more_points(internal)) {
-        //warn
-        return FALSE;
-    }
-    
-    if (internal->current_segment) {
-        if (internal->current_segment->type == type) {
-            internal->current_segment->count++;
-            return TRUE;
-        }
-        if (internal->segments_pos == internal->segments_size && !more_segments(internal)) {
-            //warn
-            return FALSE;
-        }
-        internal->current_segment = &internal->segments[internal->segments_pos++];
-        internal->current_segment->type = type;
-        internal->current_segment->count = 1;
-        internal->current_path->num_segments++;
-        return TRUE;
-    } 
-    
-    if (internal->paths_pos == internal->paths_size && !more_paths(internal)) {
-        //warn
-        return FALSE;
-    }
-
-    if (internal->segments_pos == internal->segments_size && !more_segments(internal)) {
-        //warn
-        return FALSE;
-    }
-    
-    internal->current_path = &internal->paths[internal->paths_pos++];
-    internal->current_path->start_point = internal->points_pos - 1;
-    internal->current_path->num_segments = 1;
-    internal->current_segment = &internal->segments[internal->segments_pos++];
-    internal->current_segment->type = type;
-    internal->current_segment->count = 1;
-    return TRUE;
-}
-
-void glc_path_line_to(GLCPath path, double x, double y)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    ASSERT(internal);
-    
-    if (!add_segment_common(internal, GLC_PATH_SEG_LINES, 1)) {
-        return;
-    }
-    put_point(internal, x, y);
-}
-
-void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
-                       double p3_x, double p3_y)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    ASSERT(internal);
-    
-    if (!add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3)) {
-        return;
-    }   
-    put_point(internal, p1_x, p1_y);
-    put_point(internal, p2_x, p2_y);
-    put_point(internal, p3_x, p3_y);
-}
-
-void glc_path_close(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    ASSERT(internal);
-    if (!internal->current_path) {
-        return;
-    }
-    PathPoint *end_point = &internal->points[internal->current_path->start_point];
-    glc_path_line_to(path, end_point->x, Y(end_point->y));
-    glc_path_move_to(path, end_point->x, Y(end_point->y));
-}
-
-void glc_path_cleare(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    ASSERT(internal);
-    internal->paths_pos = internal->segments_pos = 0;
-    internal->current_segment = NULL;
-    internal->current_path = NULL;
-    
-    internal->points[0].x = 0;
-    internal->points[0].y = 0;
-    internal->points_pos = 1;
-}
-
-GLCPath glc_path_create(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPath *path;
-    
-    ASSERT(ctx);
-    if (!(path = (InternalPath *)zmalloc(sizeof(*path)))) {
-        return NULL;
-    }
-    
-    path->paths = (Path *)malloc(sizeof(*path->paths) * (path->paths_size = 2));
-    if (!path->paths) {
-        goto error_1;
-    }
-    
-    path->segments = (PathSegment *)malloc(sizeof(*path->segments) * (path->segments_size = 4));
-    if (!path->segments) {
-        goto error_2;
-    }
-    
-    path->points = (PathPoint *)malloc(sizeof(*path->points) * (path->points_size = 20));
-    if (!path->points) {
-        goto error_3;
-    }
-    
-    path->owner = ctx;
-    path->points_pos = 1;
-    return path;
-    
-error_3:
-    free(path->segments);
-    
-error_2:
-    free(path->paths);
-        
-error_1:
-    free(path);
-        
-    return NULL;
-}
-
-void glc_path_destroy(GLCPath path)
-{
-    InternalPath *internal = (InternalPath *)path;
-    
-    if (!path) {
-        return;
-    }
-
-    free(internal->points);
-    free(internal->segments);
-    free(internal->paths);
-    free(internal);
-}
-
-static inline void unref_pat(InternalPat *pat)
-{
-    if (!pat) { 
-        return;
-    }
-    ASSERT(pat->refs > 0);
-    if (--pat->refs == 0) {
-        glFinish();
-        glDeleteTextures(1, &pat->texture);
-        free(pat);
-    }
-    GLC_ERROR_TETS;
-}
-
-static inline InternalPat *ref_pat(InternalPat *pat)
-{
-    pat->refs++;
-    return pat;
-}
-
-#ifdef WIN32
-static inline int find_msb(uint32_t val)
-{
-   uint32_t r;
-   __asm {
-        bsr eax, val
-        jnz found
-        mov eax, -1
-        
-    found:
-        mov r, eax
-    }
-    return r + 1;
-}
-#else
-static inline int find_msb(uint32_t val)
-{
-    int ret;
-
-    asm("bsrl %1,%0\n\t"
-        "jnz 1f\n\t"
-        "movl $-1,%0\n"
-        "1:"
-        : "=r"(ret) : "r"(val));
-    return ret + 1;
-}
-#endif
-
-static int to_pwoer_two(uint32_t val)
-{
-    if ((val & (val - 1)) == 0) {
-        return val;
-    }
-    return 1 << find_msb(val);
-}
-
-static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height,
-                  uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride)
-{
-    double x_scale = (double)src_width / dest_width;
-    double y_scale = (double)src_height / dest_height;
-    uint32_t i;
-    uint32_t j;
-    int prev_row = -1;
-    
-    for (i = 0; i < dest_height; i++) {
-        int row = (int)(y_scale * i);
-        if (row == prev_row) {
-            memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t));
-            dest += dest_width; 
-            continue;
-        }
-        for (j = 0; j < dest_width; j++) {
-            int col = (int)(x_scale * j);
-            *(dest++) = *(src + col);
-        }
-        prev_row = row;
-        src = (uint32_t *)((uint8_t *)src + src_stride);
-    }
-}
-
-static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternaCtx *ctx = pat->owner;
-    uint32_t *tmp_pixmap = NULL;
-    int width;
-    int height;
-    int width2;
-    int height2;
-
-    const int pix_bytes = 4;
-    
-    ASSERT(image->format == GLC_IMAGE_RGB32); //for now
-
-    width = image->width;
-    height = image->height;
-    width2 = to_pwoer_two(width);
-    height2 = to_pwoer_two(height);
-
-    ASSERT(width > 0 && height > 0);
-    ASSERT(width > 0 &&  width <= pat->owner->max_texture_size);
-    ASSERT(height > 0 && height <= pat->owner->max_texture_size);
-    
-    if (width2 != width || height2 != height) {
-        if (!(tmp_pixmap = (uint32_t *)malloc(width2 * height2 * sizeof(uint32_t)))) {
-            //warn
-            return;
-        }
-        scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride);
-    }
-    
-    glBindTexture(GL_TEXTURE_2D, pat->texture);
-    
-    //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    if (tmp_pixmap) {
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, width2);
-        glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE,
-                 tmp_pixmap);
-        free(tmp_pixmap);
-    } else {
-        ASSERT(image->stride % pix_bytes == 0);
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
-        glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
-                     image->pixels);
-    }
-    
-    GLC_ERROR_TETS;
-    pat->x_orign = x_orign % width;
-    pat->y_orign = y_orign % height;
-    pat->width = width;
-    pat->height = height;
-    
-    if (ctx->pat == pat) {
-        set_pat(pat->owner, pat);
-    } else if (ctx->pat) {
-        glBindTexture(GL_TEXTURE_2D, ctx->pat->texture);
-    }
-}
-
-GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPat *pat;
-    
-    ASSERT(ctx && image);
-    
-    if (!(pat = (InternalPat *)zmalloc(sizeof(*pat)))) {
-        return NULL;
-    }
-    pat->refs = 1;
-    pat->owner = ctx;
-    glGenTextures(1, &pat->texture);
-    init_pattern(pat, x_orign, y_orign, image);
-    return pat;
-}
-
-void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image)
-{
-    InternalPat *pat = (InternalPat *)pattern;
-    ASSERT(pat && pat->owner);
-
-    glFinish();
-    init_pattern(pat, x_orign, y_orign, image);
-}
-
-void glc_pattern_destroy(GLCPattern pat)
-{
-    unref_pat((InternalPat *)pat);
-    GLC_ERROR_TETS;
-}
-
-static void set_pat(InternaCtx *ctx, InternalPat *pat)
-{
-    pat = ref_pat(pat);
-    unref_pat(ctx->pat);
-    ctx->pat = pat;
-    
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, pat->texture);
-
-    GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 }; 
-    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 };
-    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
-    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
-    
-    glMatrixMode(GL_TEXTURE);
-    glLoadIdentity();
-    glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0);
-    GLC_ERROR_TETS;
-}
-
-void glc_set_pattern(GLCCtx glc, GLCPattern pattern)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPat *pat = (InternalPat *)pattern;
-
-    ASSERT(ctx && pat && pat->owner == ctx);
-    set_pat(ctx, pat);
-}
-
-void glc_set_rgb(GLCCtx glc, double red, double green, double blue)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    
-    glDisable(GL_TEXTURE_2D);
-    unref_pat(ctx->pat);
-    ctx->pat = NULL;
-    glColor4d(red, green, blue, 1);
-    GLC_ERROR_TETS;
-}
-
-void glc_set_op(GLCCtx glc, GLCOp op)
-{
-    if (op == GL_COPY) {
-        glDisable(GL_COLOR_LOGIC_OP);
-        return;
-    }
-    glLogicOp(op);
-    glEnable(GL_COLOR_LOGIC_OP);
-}
-
-void glc_set_line_width(GLCCtx glc, double width)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    ctx->line_width = (GLfloat)width;
-    if (ctx->line_width > 0) {
-        glLineWidth(ctx->line_width);
-    } else {
-        ctx->line_width = 0;
-    }
-    GLC_ERROR_TETS;
-}
-
-void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    int mode;
-    switch (fill_mode) {
-        case GLC_FILL_MODE_WINDING_ODD:
-            mode = GLU_TESS_WINDING_ODD;
-        break;
-        case GLC_FILL_MODE_WINDING_NONZERO:
-            mode = GLU_TESS_WINDING_NONZERO;
-        break;
-        default:
-            //warn
-            return;
-    }
-    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode);
-}
-
-static inline void add_stencil_client(InternaCtx *ctx)
-{
-    if (!ctx->stencil_refs) {
-        glEnable(GL_STENCIL_TEST);
-    }
-    ctx->stencil_refs++;
-}
-
-static inline void remove_stencil_client(InternaCtx *ctx)
-{
-    ctx->stencil_refs--;
-    if (!ctx->stencil_refs) {
-        glDisable(GL_STENCIL_TEST);
-    }
-}
-
-void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
-                  int stride, const uint8_t *bitmap, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    ASSERT(ctx && bitmap);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-    
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    
-    glDisable(GL_BLEND);
-    
-    if (!(ctx->stencil_mask & mask)) {
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= mask;
-    }
-    
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-    glStencilMask(mask);
-    glClear(GL_STENCIL_BUFFER_BIT);
-    
-    glStencilFunc(GL_ALWAYS, mask, mask);
-    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
-}
-
-
-void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    GLCRect *end;
-    ASSERT(ctx && rects);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-    
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    
-    glDisable(GL_BLEND);
-    
-    if (!(ctx->stencil_mask & mask)) {
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= mask;
-    }
-    
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-    glStencilMask(mask);
-    glClear(GL_STENCIL_BUFFER_BIT);
-    
-    glStencilFunc(GL_ALWAYS, mask, mask);
-    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-    end = rects + num_rect;
-    for (; rects < end; rects++) {
-        fill_rect(ctx, rects);
-    }
-}
-
-void glc_clear_mask(GLCCtx glc, GLCMaskID id)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08;
-    ASSERT(ctx);
-    ASSERT(id == GLC_MASK_A || id == GLC_MASK_B);
-    
-    if ((ctx->stencil_mask & mask)) {
-        ctx->stencil_mask &= ~mask;
-        remove_stencil_client(ctx);
-    }
-}
-
-void glc_clip_reset(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    if (!(ctx->stencil_mask & 0x03)) {
-        return;
-    }
-    remove_stencil_client(ctx);
-    ctx->stencil_mask &= ~0x03;
-    glStencilMask(0x03);
-    glClear(GL_STENCIL_BUFFER_BIT);
-    GLC_ERROR_TETS;
-}
-
-static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *),
-                        void *data)
-{
-    int stencil_val;
-    
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    glDisable(GL_BLEND);
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    ctx->draw_mode = FALSE;
-    
-    if (op == GLC_CLIP_OP_SET) {
-        glc_clip_reset(ctx);
-        add_stencil_client(ctx);
-        ctx->stencil_mask |= 0x01;
-    } else if (!(ctx->stencil_mask & 0x03)) {
-        GLCRect area;
-        if (op == GLC_CLIP_OP_OR) {
-            return;
-        }
-        area.x =  area.y = 0;
-        area.width= ctx->width;
-        area.height = ctx->height;
-        clip_common(ctx, GLC_CLIP_OP_SET, fill_rect, &area);
-    }
-    glStencilMask(0x03);
-    switch (op) {
-        case GLC_CLIP_OP_SET:
-        case GLC_CLIP_OP_OR:
-            stencil_val = ctx->stencil_mask & 0x03;
-            glStencilFunc(GL_ALWAYS, stencil_val, stencil_val);
-            glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-            fill_func(ctx, data);
-            break;
-        case GLC_CLIP_OP_AND: {
-            int clear_mask;
-            stencil_val = ctx->stencil_mask & 0x03;
-            glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
-            if (stencil_val == 0x01) {
-                glStencilOp(GL_ZERO, GL_INCR, GL_INCR);
-                stencil_val = 0x02;
-                clear_mask = 0x01;
-            } else {
-                glStencilOp(GL_ZERO, GL_DECR, GL_DECR);
-                stencil_val = 0x01;
-                clear_mask = 0x02;
-            }
-            fill_func(ctx, data);
-            
-            glStencilMask(clear_mask);
-            glClear(GL_STENCIL_BUFFER_BIT);
-            ctx->stencil_mask = (ctx->stencil_mask & ~clear_mask) |stencil_val; 
-            break;
-        }
-        case GLC_CLIP_OP_EXCLUDE:
-            stencil_val = ctx->stencil_mask & 0x03;
-            glStencilFunc(GL_EQUAL, stencil_val, stencil_val);
-            glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
-            fill_func(ctx, data);
-            break;
-    }
-    GLC_ERROR_TETS;
-}
-
-void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx && rect);
-    clip_common(ctx, op, fill_rect, (void *)rect);
-}
-
-void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx && path);
-    clip_common(ctx, op, fill_path, path);
-}
-
-typedef struct FillMaskInfo {
-    int x_dest;
-    int y_dest;
-    int width;
-    int height;
-    int stride;
-    const uint8_t *bitmap;
-} FillMaskInfo;
-
-static void __fill_mask(InternaCtx *ctx, void *data)
-{
-    FillMaskInfo *info = (FillMaskInfo *)data;
-    fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride,
-              info->bitmap);
-}
-
-void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
-                   int stride, const uint8_t *bitmap, GLCClipOp op)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    FillMaskInfo mask_info;
-
-    ASSERT(ctx && bitmap);
-    mask_info.x_dest = x_dest;
-    mask_info.y_dest = y_dest;
-    mask_info.width = width;
-    mask_info.height = height;
-    mask_info.stride = stride;
-    mask_info.bitmap = bitmap;
-    clip_common(ctx, op, __fill_mask, &mask_info);
-}
-
-static inline void start_draw(InternaCtx *ctx)
-{
-    if (ctx->draw_mode) {
-        return;
-    }
-    ctx->draw_mode = TRUE;
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask);
-    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    } else {
-        glDisable(GL_TEXTURE_2D);
-    }
-    GLC_ERROR_TETS;
-}
-
-static void fill_rect(InternaCtx *ctx, void *r)
-{
-    GLCRect *rect = (GLCRect *)r;
-    glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height));
-    /*glBegin(GL_POLYGON);
-        VERTEX2(rect->x, rect->y);
-        VERTEX2 (rect->x + rect->width, rect->y);
-        VERTEX2 (rect->x + rect->width, rect->y + rect->height);
-        VERTEX2 (rect->x , rect->y + rect->height);
-    glEnd();*/
-    GLC_ERROR_TETS;
-}
-
-void glc_fill_rect(GLCCtx glc, const GLCRect *rect)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    start_draw(ctx);
-    fill_rect(ctx, (void *)rect);
-    GLC_ERROR_TETS;
-}
-
-static void fill_path(InternaCtx *ctx, void *p)
-{
-    InternalPath *path = (InternalPath *)p;
-    
-    PathPoint *current_point = path->points;
-    PathSegment *current_segment = path->segments;
-    Path *current_path = path->paths;
-    Path *end_path = current_path + path->paths_pos;
-    reset_tass_vertex(ctx);
-    gluTessBeginPolygon(ctx->tesselator, ctx);
-    for (; current_path < end_path; current_path++) {
-        gluTessBeginContour(ctx->tesselator);
-        PathSegment *end_segment = current_segment + current_path->num_segments;
-        gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point);
-        current_point++;
-        for (; current_segment < end_segment; current_segment++) {
-            PathPoint *end_point;
-            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
-                end_point = current_point + current_segment->count * 3;
-                for (; current_point < end_point; current_point += 3) {
-                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
-                    while (vertex) {
-                        gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point,
-                                      (GLdouble *)&vertex->point);
-                        vertex = vertex->list_link;
-                    }
-                    gluTessVertex(ctx->tesselator, (GLdouble *)&current_point[2],
-                                  (GLdouble *)&current_point[2]);
-                }
-            } else {
-                ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
-                end_point = current_point + current_segment->count;
-                for (; current_point < end_point; current_point++) {
-                    gluTessVertex(ctx->tesselator, (GLdouble *)current_point ,
-                                  (GLdouble *)current_point);
-                }
-            }
-        }
-        gluTessEndContour(ctx->tesselator);
-    }
-    gluTessEndPolygon(ctx->tesselator);
-}
-
-void glc_fill_path(GLCCtx glc, GLCPath path_ref)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx && path_ref);
-    start_draw(ctx);
-    fill_path(ctx, path_ref);
-}
-
-static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height,
-                      int stride, const uint8_t *bitmap)
-{
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-    glBitmap(width, height, 0, 0, 0, 0, bitmap);
-}
-
-void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                   const uint8_t *bitmap)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx && bitmap);
-    start_draw(ctx);
-    if (ctx->pat) {
-        WARN_ONCE(("%s: unimplemented fill mask with pattern\n", __FUNCTION__));
-    }
-    fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap);
-}
-
-void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                    const uint8_t *alpha_mask)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    GLCRect r;
-    
-    ASSERT(ctx);
-    start_draw(ctx);
-
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
-    glPixelZoom(1, 1);
-    glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask);
-
-    r.x = x_dest;
-    r.y = y_dest;
-    r.width = width;
-    r.height = height;
-
-    //todo: support color/texture alpah vals (GL_MODULATE)
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    fill_rect(ctx, &r);
-    glDisable(GL_BLEND);
-}
-
-void glc_stroke_rect(GLCCtx glc, const GLCRect *rect)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    if (ctx->line_width == 0) {
-        return;
-    }
-    
-    start_draw(ctx);
-    
-    glBegin(GL_LINES);
-        VERTEX2 (rect->x , rect->y + 0.5);
-        VERTEX2 (rect->x + rect->width, rect->y + 0.5);
-    glEnd();
-    
-    glBegin(GL_LINES);
-        VERTEX2 (rect->x + rect->width - 0.5, rect->y);
-        VERTEX2 (rect->x + rect->width - 0.5, rect->y + rect->height);
-    glEnd();
-    
-    glBegin(GL_LINES);
-        VERTEX2 (rect->x + rect->width, rect->y + rect->height - 0.5);
-        VERTEX2 (rect->x, rect->y + rect->height - 0.5);
-    glEnd();
-    
-    glBegin(GL_LINES);
-        VERTEX2(rect->x + 0.5, rect->y + rect->height);
-        VERTEX2(rect->x + 0.5 , rect->y);
-    glEnd();
-    GLC_ERROR_TETS;
-}
-
-void glc_stroke_path(GLCCtx glc, GLCPath path_ref)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    InternalPath *path = (InternalPath *)path_ref;
-    
-    ASSERT(ctx && path);
-    if (ctx->line_width == 0) {
-        return;
-    }
-    start_draw(ctx);
-
-    reset_tass_vertex(ctx);
-    PathPoint *current_point = path->points;
-    PathSegment *current_segment = path->segments;
-    Path *current_path = path->paths;
-    Path *end_path = current_path + path->paths_pos;
-    for (; current_path < end_path; current_path++) {
-        glBegin(GL_LINE_STRIP);
-        PathSegment *end_segment = current_segment + current_path->num_segments;
-        glVertex2d(current_point->x , current_point->y);
-        current_point++;
-        for (; current_segment < end_segment; current_segment++) {
-            PathPoint *end_point;
-            if (current_segment->type == GLC_PATH_SEG_BEIZER) {
-                end_point = current_point + current_segment->count * 3;
-                for (; current_point < end_point; current_point += 3) {
-                    TassVertex *vertex = bezier_flattener(ctx, current_point - 1);
-                    while (vertex) {
-                        glVertex2d(vertex->point.x, vertex->point.y);
-                        vertex = vertex->list_link;
-                    }
-                    glVertex2d(current_point[2].x , current_point[2].y);
-                }
-            } else {
-                ASSERT(current_segment->type == GLC_PATH_SEG_LINES);
-                end_point = current_point + current_segment->count;
-                for (; current_point < end_point; current_point++) {
-                    glVertex2d(current_point->x , current_point->y);
-                }
-            }
-        }
-        glEnd();
-    }
-}
-
-void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
-                    int scale_mode, double alpha)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    uint8_t *pixels;
-    const int pix_bytes = 4;
-
-    ASSERT(ctx && image);
-    ASSERT(src->width > 0 && src->height > 0);
-
-    ASSERT(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now
-    start_draw(ctx);
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    set_raster_pos(ctx, dest->x, dest->y + dest->height);
-
-    if (dest->width == src->width && src->height == dest->height) {
-        glPixelZoom(1, 1);
-    } else {
-        glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height);
-    }
-
-    pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride;
-    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
-        glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha);
-        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-        glEnable(GL_BLEND);
-    }
-    ASSERT(image->stride % pix_bytes == 0);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes);
-    glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
-
-    if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) {
-        glDisable(GL_BLEND);
-    }
-
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    }
-    GLC_ERROR_TETS;
-}
-
-void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
-                     int height)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    ASSERT(ctx);
-#ifdef USE_COPY_PIXELS
-    start_draw(ctx);
-    if (ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    }
-    set_raster_pos(ctx, x_dest, y_dest + height);
-    glPixelZoom(1, 1);
-    glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR);
-    if (ctx->pat) {
-        glEnable(GL_TEXTURE_2D);
-    }
-#else
-    GLuint texture;
-    int width2 = to_pwoer_two(width);
-    int height2 = to_pwoer_two(height);
-    
-    start_draw(ctx);
-    glEnable(GL_TEXTURE_2D);
-    glGenTextures(1, &texture);
-    glBindTexture(GL_TEXTURE_2D, texture);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
-    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height),
-                     width2, height2, 0);
-    
-    GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 }; 
-    GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 };
-    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params);
-    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);
-    
-    glMatrixMode(GL_TEXTURE);
-    glLoadIdentity();
-    glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0);
-
-    glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height));
-    glFinish();
-    glDeleteTextures(1, &texture);
-    if (!ctx->pat) {
-        glDisable(GL_TEXTURE_2D);
-    } else {
-        set_pat(ctx, ctx->pat);
-    }
-#endif
-    GLC_ERROR_TETS;
-}
-
-void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx && image);
-    ASSERT(image->format == GLC_IMAGE_RGB32); //for now
-    ASSERT((image->stride % 4) == 0); //for now
-    glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4);
-    glReadPixels(x, ctx->height - (y + image->height), image->width, image->height,
-                 GL_BGRA, GL_UNSIGNED_BYTE, image->pixels);
-}
-
-void glc_clear(GLCCtx glc)
-{
-    InternaCtx *ctx = (InternaCtx *)glc;
-    
-    ASSERT(ctx);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    glClear(GL_COLOR_BUFFER_BIT);
-}
-
-void glc_flush(GLCCtx glc)
-{
-    glFlush();
-    
-    GLC_ERROR_TETS;
-}
-
-static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4],
-                                 GLdouble **data_out, void *usr_data)
-{
-    TassVertex *vertex;
-    
-    if (!(vertex = alloc_tess_vertex((InternaCtx *)usr_data))) {
-        *data_out = NULL;
-        return;
-    }
-    vertex->point.x = coords[0];
-    vertex->point.y = coords[1];
-    //vertex->point.z = coords[2];
-    *data_out = (GLdouble *)&vertex->point;
-}
-
-static void tessellation_error(GLenum errorCode)
-{
-    printf ("%s: %s\n", __FUNCTION__, gluErrorString(errorCode));
-}
-
-#ifdef WIN32
-#define TESS_CALL_BACK_TYPE void (CALLBACK *)()
-#else
-#define TESS_CALL_BACK_TYPE void (*)()
-#endif
-
-static int init(InternaCtx *ctx, int width, int height)
-{
-#ifdef WIN32
-    if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) {
-        return FALSE;
-    }
-#endif
-    ctx->width = width;
-    ctx->height = height;
-    ctx->line_width = 1;
-
-    glClearColor(0, 0, 0, 0);
-    glClearStencil(0);
-    
-    if (!(ctx->tesselator = gluNewTess())) {
-        return FALSE;
-    }
-
-    glViewport(0, 0, width, height);
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(0, width, 0, height, -1, 1);
-
-    gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
-    gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin);
-    gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv);
-    gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd);
-    gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA, (TESS_CALL_BACK_TYPE)tessellation_combine);
-    gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error);
-
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 
-    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-    glEnable(GL_TEXTURE_GEN_S); 
-    glEnable(GL_TEXTURE_GEN_T);
-
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    glTranslatef(0, (GLfloat)height, 0);
-
-    glGetIntegerv( GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size);
-
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
-    glPixelTransferf(GL_ALPHA_BIAS, 0);
-#ifdef WIN32
-    ctx->glBlendEquation(GL_FUNC_ADD);
-#else
-    glBlendEquation(GL_FUNC_ADD);
-#endif
-
-    glStencilMask(0xff);
-    glClear(GL_STENCIL_BUFFER_BIT);
-
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    return TRUE;
-}
-
-GLCCtx glc_create(int width, int height)
-{
-    InternaCtx *ctx;
-    
-    ASSERT(sizeof(PathPoint) == sizeof(Vertex));
-    
-    if (!(ctx = (InternaCtx *)zmalloc(sizeof(*ctx)))) {
-        return NULL;
-    }
-    
-    if (!init(ctx, width, height)) {
-        free(ctx);
-        return NULL;
-    }
-    return ctx;
-}
-
-void glc_destroy(GLCCtx glc)
-{
-    InternaCtx *ctx;
-    
-    if (!(ctx = (InternaCtx *)glc)) {
-        return;
-    }
-
-    unref_pat(ctx->pat);
-    free_tass_vertex_bufs(ctx);
-    free(ctx);
-}
-
-/*
-    todo: 
-        1. test double vs float in gl calls
-        2. int vs flat raster position
-        3. pixels stride vs bytes stride
-        4. improve non power of two.
-                glGetString(GL_EXTENSIONS);
-                ARB_texture_non_power_of_two
-                ARB_texture_rectangle
-                GL_TEXTURE_RECTANGLE_ARB
-        5. scale
-        6. origin
-        7. fonts
-        8. support more image formats
-        9. use GLCImage in mask ops?
-*/
-
diff --git a/common/glc.h b/common/glc.h
deleted file mode 100644
index a6b8579..0000000
--- a/common/glc.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef _H_GL_CANVASE
-#define _H_GL_CANVASE
-
-#include <stdint.h>
-
-typedef void * GLCCtx;
-typedef void * GLCPattern;
-typedef void * GLCPath;
-
-typedef struct GLCRect {
-    double x;
-    double y;
-    double width;
-    double height;
-} GLCRect;
-
-typedef struct GLCRecti {
-    int x;
-    int y;
-    int width;
-    int height;
-} GLCRecti;
-
-typedef enum  {
-    GLC_IMAGE_RGB32,
-    GLC_IMAGE_ARGB32,
-} GLCImageFormat;
-
-typedef struct GLCPImage {
-    GLCImageFormat format;
-    int width;
-    int height;
-    int stride;
-    uint8_t *pixels;
-    uint32_t *pallet;
-} GLCImage;
-
-GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image);
-void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image);
-void glc_pattern_destroy(GLCPattern pattern);
-
-void glc_path_move_to(GLCPath path, double x, double y);
-void glc_path_line_to(GLCPath path, double x, double y);
-void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
-                       double p3_x, double p3_y);
-void glc_path_rel_move_to(GLCPath path, double x, double y);
-void glc_path_rel_line_to(GLCPath path, double x, double y);
-void glc_path_rel_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y,
-                           double p3_x, double p3_y);
-void glc_path_close(GLCPath path);
-
-void glc_path_cleare(GLCPath);
-GLCPath glc_path_create(GLCCtx glc);
-void glc_path_destroy(GLCPath path);
-
-void glc_set_rgb(GLCCtx glc, double red, double green, double blue);
-void glc_set_rgba(GLCCtx glc, double red, double green, double blue, double alpha);
-void glc_set_pattern(GLCCtx glc, GLCPattern pattern);
-
-typedef enum  {
-    GLC_OP_CLEAR = 0x1500,
-    GLC_OP_SET = 0x150F,
-    GLC_OP_COPY = 0x1503,
-    GLC_OP_COPY_INVERTED = 0x150C,
-    GLC_OP_NOOP = 0x1505,
-    GLC_OP_INVERT = 0x150A,
-    GLC_OP_AND = 0x1501,
-    GLC_OP_NAND = 0x150E,
-    GLC_OP_OR = 0x1507,
-    GLC_OP_NOR = 0x1508,
-    GLC_OP_XOR = 0x1506,
-    GLC_OP_EQUIV = 0x1509,
-    GLC_OP_AND_REVERSE = 0x1502,
-    GLC_OP_AND_INVERTED = 0x1504,
-    GLC_OP_OR_REVERSE = 0x150B,
-    GLC_OP_OR_INVERTED = 0x150D,
-} GLCOp;
-
-void glc_set_op(GLCCtx glc, GLCOp op);
-void glc_set_alpha_factor(GLCCtx glc, double alpah);
-
-typedef enum  {
-    GLC_FILL_MODE_WINDING_ODD,
-    GLC_FILL_MODE_WINDING_NONZERO,
-} GLCFillMode;
-
-void glc_set_fill_mode(GLCCtx glc, GLCFillMode mode);
-void glc_set_line_width(GLCCtx glc, double width);
-void glc_set_line_end_cap(GLCCtx glc, int style);
-void glc_set_line_join(GLCCtx glc, int style);
-void glc_set_miter_limit(GLCCtx glc, int limit);
-void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset);
-
-typedef enum  {
-    GLC_MASK_A,
-    GLC_MASK_B,
-} GLCMaskID;
-
-void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height,
-                  int stride, const uint8_t *bitmap, GLCMaskID id);
-void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id);
-void glc_clear_mask(GLCCtx glc, GLCMaskID id);
-
-typedef enum {
-    GLC_CLIP_OP_SET,
-    GLC_CLIP_OP_OR,
-    GLC_CLIP_OP_AND,
-    GLC_CLIP_OP_EXCLUDE,
-} GLCClipOp;
-
-void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op);
-void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op);
-void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                   const uint8_t *bitmap, GLCClipOp op);
-void glc_clip_reset(GLCCtx glc);
-
-void glc_fill_rect(GLCCtx glc, const GLCRect *rect);
-void glc_fill_path(GLCCtx glc, GLCPath path);
-void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                    const uint8_t *bitmap);
-void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride,
-                    const uint8_t *alpha_mask);
-
-void glc_stroke_rect(GLCCtx glc, const GLCRect *rect);
-void glc_stroke_path(GLCCtx glc, GLCPath path);
-
-void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image,
-                    int scale_mode, double alpha);
-
-void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width,
-                     int height);
-void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image);
-
-void glc_flush(GLCCtx glc);
-void glc_clear(GLCCtx glc);
-GLCCtx glc_create(int width, int height);
-void glc_destroy(GLCCtx glc, int textures_lost);
-
-#endif
diff --git a/common/lines.c b/common/lines.c
deleted file mode 100644
index ee52a46..0000000
--- a/common/lines.c
+++ /dev/null
@@ -1,3618 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/***********************************************************
-
-Copyright 1989, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-
-#include <stdio.h>
-#include <spice/macros.h>
-#ifdef _XOPEN_SOURCE
-#include <math.h>
-#else
-#define _XOPEN_SOURCE           /* to get prototype for hypot on some systems */
-#include <math.h>
-#undef _XOPEN_SOURCE
-#endif
-#include "lines.h"
-#include "mem.h"
-
-#define xalloc(i) spice_malloc(i)
-#define xrealloc(a,b) spice_realloc(a,b)
-#define xfree(i) free(i)
-
-typedef unsigned int CARD32;
-typedef int Boolean;
-typedef pixman_rectangle32_t xRectangle;
-typedef SpicePoint DDXPointRec;
-typedef DDXPointRec *DDXPointPtr;
-typedef struct lineGC *GCPtr;
-
-/* largest positive value that can fit into a component of a point.
- * Assumes that the point structure is {type x, y;} where type is
- * a signed type.
- */
-#define MAX_COORDINATE 2147483647
-#define MIN_COORDINATE -2147483647
-
-#define miZeroLine spice_canvas_zero_line
-#define miZeroDashLine spice_canvas_zero_dash_line
-#define miWideDash spice_canvas_wide_dash_line
-#define miWideLine spice_canvas_wide_line
-
-static inline int
-ICEIL (double x)
-{
-    int _cTmp = (int)x;
-    return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp + 1;
-}
-
-typedef struct {
-    int count;                  /* number of spans                  */
-    DDXPointPtr points;         /* pointer to list of start points  */
-    int *widths;                /* pointer to list of widths        */
-} Spans;
-
-typedef struct {
-    int size;                   /* Total number of *Spans allocated     */
-    int count;                  /* Number of *Spans actually in group   */
-    Spans *group;               /* List of Spans                        */
-    int ymin, ymax;             /* Min, max y values encountered        */
-} SpanGroup;
-
-/* Initialize SpanGroup.  MUST BE DONE before use. */
-static void miInitSpanGroup (SpanGroup *        /*spanGroup */
-    );
-
-/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
-static void miAppendSpans (SpanGroup * /*spanGroup */ ,
-                           SpanGroup * /*otherGroup */ ,
-                           Spans *      /*spans */
-    );
-
-/* Paint a span group, insuring that each pixel is painted at most once */
-static void miFillUniqueSpanGroup (GCPtr /*pGC */ ,
-                                   SpanGroup * /*spanGroup */ ,
-                                   Boolean /* foreground */
-    );
-
-/* Free up data in a span group.  MUST BE DONE or you'll suffer memory leaks */
-static void miFreeSpanGroup (SpanGroup *        /*spanGroup */
-    );
-
-/* Rops which must use span groups */
-#define miSpansCarefulRop(rop)  (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
-#define miSpansEasyRop(rop)     (!miSpansCarefulRop(rop))
-
-/*
- * Public definitions used for configuring basic pixelization aspects
- * of the sample implementation line-drawing routines provided in
- * {mfb,mi,cfb*} at run-time.
- */
-
-#define XDECREASING     4
-#define YDECREASING     2
-#define YMAJOR          1
-
-#define OCTANT1                 (1 << (YDECREASING))
-#define OCTANT2                 (1 << (YDECREASING|YMAJOR))
-#define OCTANT3                 (1 << (XDECREASING|YDECREASING|YMAJOR))
-#define OCTANT4                 (1 << (XDECREASING|YDECREASING))
-#define OCTANT5                 (1 << (XDECREASING))
-#define OCTANT6                 (1 << (XDECREASING|YMAJOR))
-#define OCTANT7                 (1 << (YMAJOR))
-#define OCTANT8                 (1 << (0))
-
-#define XMAJOROCTANTS           (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
-
-#define DEFAULTZEROLINEBIAS     (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
-
-/*
- * Devices can configure the rendering of routines in mi, mfb, and cfb*
- * by specifying a thin line bias to be applied to a particular screen
- * using the following function.  The bias parameter is an OR'ing of
- * the appropriate OCTANT constants defined above to indicate which
- * octants to bias a line to prefer an axial step when the Bresenham
- * error term is exactly zero.  The octants are mapped as follows:
- *
- *   \    |    /
- *    \ 3 | 2 /
- *     \  |  /
- *    4 \ | / 1
- *       \|/
- *   -----------
- *       /|\
- *    5 / | \ 8
- *     /  |  \
- *    / 6 | 7 \
- *   /    |    \
- *
- * For more information, see "Ambiguities in Incremental Line Rastering,"
- * Jack E. Bresenham, IEEE CG&A, May 1987.
- */
-
-/*
- * Private definitions needed for drawing thin (zero width) lines
- * Used by the mi, mfb, and all cfb* components.
- */
-
-#define X_AXIS  0
-#define Y_AXIS  1
-
-#define OUT_LEFT  0x08
-#define OUT_RIGHT 0x04
-#define OUT_ABOVE 0x02
-#define OUT_BELOW 0x01
-
-#define OUTCODES(_result, _x, _y, _pbox) \
-    if      ( (_x) <  (_pbox)->x1) (_result) |= OUT_LEFT; \
-    else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
-    if      ( (_y) <  (_pbox)->y1) (_result) |= OUT_ABOVE; \
-    else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
-
-#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
-{\
-     if (x < xmin) outcode |= OUT_LEFT;\
-     if (x > xmax) outcode |= OUT_RIGHT;\
-     if (y < ymin) outcode |= OUT_ABOVE;\
-     if (y > ymax) outcode |= OUT_BELOW;\
-}
-
-#define SWAPINT(i, j) \
-{  int _t = i;  i = j;  j = _t; }
-
-#define SWAPPT(i, j) \
-{  DDXPointRec _t; _t = i;  i = j; j = _t; }
-
-#define SWAPINT_PAIR(x1, y1, x2, y2)\
-{   int t = x1;  x1 = x2;  x2 = t;\
-        t = y1;  y1 = y2;  y2 = t;\
-}
-
-#define miGetZeroLineBias(_pScreen) (DEFAULTZEROLINEBIAS)
-
-#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
-    (_octant) = 0;                              \
-    (_sx) = (_SX);                              \
-    if (((_adx) = (_x2) - (_x1)) < 0) {                 \
-        (_adx) = -(_adx);                       \
-        (_sx = -(_sx));                                 \
-        (_octant) |= XDECREASING;               \
-    }                                           \
-    (_sy) = (_SY);                              \
-    if (((_ady) = (_y2) - (_y1)) < 0) {                 \
-        (_ady) = -(_ady);                       \
-        (_sy = -(_sy));                                 \
-        (_octant) |= YDECREASING;               \
-    }
-
-#define SetYMajorOctant(_octant)        ((_octant) |= YMAJOR)
-
-#define FIXUP_ERROR(_e, _octant, _bias) \
-    (_e) -= (((_bias) >> (_octant)) & 1)
-
-#define IsXMajorOctant(_octant)                 (!((_octant) & YMAJOR))
-#define IsYMajorOctant(_octant)                 ((_octant) & YMAJOR)
-#define IsXDecreasingOctant(_octant)    ((_octant) & XDECREASING)
-#define IsYDecreasingOctant(_octant)    ((_octant) & YDECREASING)
-
-static int miZeroClipLine (int /*xmin */ ,
-                           int /*ymin */ ,
-                           int /*xmax */ ,
-                           int /*ymax */ ,
-                           int * /*new_x1 */ ,
-                           int * /*new_y1 */ ,
-                           int * /*new_x2 */ ,
-                           int * /*new_y2 */ ,
-                           unsigned int /*adx */ ,
-                           unsigned int /*ady */ ,
-                           int * /*pt1_clipped */ ,
-                           int * /*pt2_clipped */ ,
-                           int /*octant */ ,
-                           unsigned int /*bias */ ,
-                           int /*oc1 */ ,
-                           int  /*oc2 */
-    );
-
-/*
- * interface data to span-merging polygon filler
- */
-
-typedef struct _SpanData {
-    SpanGroup fgGroup, bgGroup;
-} SpanDataRec, *SpanDataPtr;
-
-#define AppendSpanGroup(pGC, foreground, spanPtr, spanData) { \
-        SpanGroup   *group, *othergroup = NULL; \
-        if (foreground) \
-        { \
-            group = &spanData->fgGroup; \
-            if (pGC->lineStyle == LineDoubleDash) \
-                othergroup = &spanData->bgGroup; \
-        } \
-        else \
-        { \
-            group = &spanData->bgGroup; \
-            othergroup = &spanData->fgGroup; \
-        } \
-        miAppendSpans (group, othergroup, spanPtr); \
-}
-
-/*
- * Polygon edge description for integer wide-line routines
- */
-
-typedef struct _PolyEdge {
-    int height;                 /* number of scanlines to process */
-    int x;                      /* starting x coordinate */
-    int stepx;                  /* fixed integral dx */
-    int signdx;                 /* variable dx sign */
-    int e;                      /* initial error term */
-    int dy;
-    int dx;
-} PolyEdgeRec, *PolyEdgePtr;
-
-#define SQSECANT 108.856472512142       /* 1/sin^2(11/2) - miter limit constant */
-
-/*
- * types for general polygon routines
- */
-
-typedef struct _PolyVertex {
-    double x, y;
-} PolyVertexRec, *PolyVertexPtr;
-
-typedef struct _PolySlope {
-    int dx, dy;
-    double k;                   /* x0 * dy - y0 * dx */
-} PolySlopeRec, *PolySlopePtr;
-
-/*
- * Line face description for caps/joins
- */
-
-typedef struct _LineFace {
-    double xa, ya;
-    int dx, dy;
-    int x, y;
-    double k;
-} LineFaceRec, *LineFacePtr;
-
-/*
- * macros for polygon fillers
- */
-
-#define MIPOLYRELOADLEFT    if (!left_height && left_count) { \
-                                left_height = left->height; \
-                                left_x = left->x; \
-                                left_stepx = left->stepx; \
-                                left_signdx = left->signdx; \
-                                left_e = left->e; \
-                                left_dy = left->dy; \
-                                left_dx = left->dx; \
-                                --left_count; \
-                                ++left; \
-                            }
-
-#define MIPOLYRELOADRIGHT   if (!right_height && right_count) { \
-                                right_height = right->height; \
-                                right_x = right->x; \
-                                right_stepx = right->stepx; \
-                                right_signdx = right->signdx; \
-                                right_e = right->e; \
-                                right_dy = right->dy; \
-                                right_dx = right->dx; \
-                                --right_count; \
-                                ++right; \
-                        }
-
-#define MIPOLYSTEPLEFT  left_x += left_stepx; \
-                        left_e += left_dx; \
-                        if (left_e > 0) \
-                        { \
-                            left_x += left_signdx; \
-                            left_e -= left_dy; \
-                        }
-
-#define MIPOLYSTEPRIGHT right_x += right_stepx; \
-                        right_e += right_dx; \
-                        if (right_e > 0) \
-                        { \
-                            right_x += right_signdx; \
-                            right_e -= right_dy; \
-                        }
-
-static void miRoundJoinClip (LineFacePtr /*pLeft */ ,
-                             LineFacePtr /*pRight */ ,
-                             PolyEdgePtr /*edge1 */ ,
-                             PolyEdgePtr /*edge2 */ ,
-                             int * /*y1 */ ,
-                             int * /*y2 */ ,
-                             Boolean * /*left1 */ ,
-                             Boolean *     /*left2 */
-    );
-
-static int miRoundCapClip (LineFacePtr /*face */ ,
-                           Boolean /*isInt */ ,
-                           PolyEdgePtr /*edge */ ,
-                           Boolean *       /*leftEdge */
-    );
-
-static int miPolyBuildEdge (double x0, double y0, double k, int dx, int dy,
-                            int xi, int yi, int left, PolyEdgePtr edge);
-static int miPolyBuildPoly (PolyVertexPtr vertices, PolySlopePtr slopes,
-                            int count, int xi, int yi, PolyEdgePtr left,
-                            PolyEdgePtr right, int *pnleft, int *pnright, int *h);
-
-
-static void
-miStepDash (int dist,           /* distance to step */
-            int *pDashIndex,    /* current dash */
-            unsigned char *pDash,       /* dash list */
-            int numInDashList,  /* total length of dash list */
-            int *pDashOffset    /* offset into current dash */
-    )
-{
-    int dashIndex, dashOffset;
-    int totallen;
-    int i;
-
-    dashIndex = *pDashIndex;
-    dashOffset = *pDashOffset;
-    if (dist < pDash[dashIndex] - dashOffset) {
-        *pDashOffset = dashOffset + dist;
-        return;
-    }
-    dist -= pDash[dashIndex] - dashOffset;
-    if (++dashIndex == numInDashList)
-        dashIndex = 0;
-    totallen = 0;
-    for (i = 0; i < numInDashList; i++)
-        totallen += pDash[i];
-    if (totallen <= dist)
-        dist = dist % totallen;
-    while (dist >= pDash[dashIndex]) {
-        dist -= pDash[dashIndex];
-        if (++dashIndex == numInDashList)
-            dashIndex = 0;
-    }
-    *pDashIndex = dashIndex;
-    *pDashOffset = dist;
-}
-
-/*
-
-These routines maintain lists of Spans, in order to implement the
-``touch-each-pixel-once'' rules of wide lines and arcs.
-
-Written by Joel McCormack, Summer 1989.
-
-*/
-
-
-static void
-miInitSpanGroup (SpanGroup * spanGroup)
-{
-    spanGroup->size = 0;
-    spanGroup->count = 0;
-    spanGroup->group = NULL;
-    spanGroup->ymin = MAX_COORDINATE;
-    spanGroup->ymax = MIN_COORDINATE;
-}                               /* InitSpanGroup */
-
-#define YMIN(spans) (spans->points[0].y)
-#define YMAX(spans)  (spans->points[spans->count-1].y)
-
-static void
-miSubtractSpans (SpanGroup * spanGroup, Spans * sub)
-{
-    int i, subCount, spansCount;
-    int ymin, ymax, xmin, xmax;
-    Spans *spans;
-    DDXPointPtr subPt, spansPt;
-    int *subWid, *spansWid;
-    int extra;
-
-    ymin = YMIN (sub);
-    ymax = YMAX (sub);
-    spans = spanGroup->group;
-    for (i = spanGroup->count; i; i--, spans++) {
-        if (YMIN (spans) <= ymax && ymin <= YMAX (spans)) {
-            subCount = sub->count;
-            subPt = sub->points;
-            subWid = sub->widths;
-            spansCount = spans->count;
-            spansPt = spans->points;
-            spansWid = spans->widths;
-            extra = 0;
-            for (;;) {
-                while (spansCount && spansPt->y < subPt->y) {
-                    spansPt++;
-                    spansWid++;
-                    spansCount--;
-                }
-                if (!spansCount)
-                    break;
-                while (subCount && subPt->y < spansPt->y) {
-                    subPt++;
-                    subWid++;
-                    subCount--;
-                }
-                if (!subCount)
-                    break;
-                if (subPt->y == spansPt->y) {
-                    xmin = subPt->x;
-                    xmax = xmin + *subWid;
-                    if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax) {
-                        ;
-                    } else if (xmin <= spansPt->x) {
-                        if (xmax >= spansPt->x + *spansWid) {
-                            memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
-                            memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
-                            spansPt--;
-                            spansWid--;
-                            spans->count--;
-                            extra++;
-                        } else {
-                            *spansWid = *spansWid - (xmax - spansPt->x);
-                            spansPt->x = xmax;
-                        }
-                    } else {
-                        if (xmax >= spansPt->x + *spansWid) {
-                            *spansWid = xmin - spansPt->x;
-                        } else {
-                            if (!extra) {
-                                DDXPointPtr newPt;
-                                int *newwid;
-
-#define EXTRA 8
-                                newPt =
-                                    (DDXPointPtr) xrealloc (spans->points,
-                                                            (spans->count +
-                                                             EXTRA) * sizeof (DDXPointRec));
-                                if (!newPt)
-                                    break;
-                                spansPt = newPt + (spansPt - spans->points);
-                                spans->points = newPt;
-                                newwid =
-                                    (int *) xrealloc (spans->widths,
-                                                      (spans->count + EXTRA) * sizeof (int));
-                                if (!newwid)
-                                    break;
-                                spansWid = newwid + (spansWid - spans->widths);
-                                spans->widths = newwid;
-                                extra = EXTRA;
-                            }
-                            memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
-                            memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
-                            spans->count++;
-                            extra--;
-                            *spansWid = xmin - spansPt->x;
-                            spansWid++;
-                            spansPt++;
-                            *spansWid = *spansWid - (xmax - spansPt->x);
-                            spansPt->x = xmax;
-                        }
-                    }
-                }
-                spansPt++;
-                spansWid++;
-                spansCount--;
-            }
-        }
-    }
-}
-
-static void
-miAppendSpans (SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans)
-{
-    int ymin, ymax;
-    int spansCount;
-
-    spansCount = spans->count;
-    if (spansCount > 0) {
-        if (spanGroup->size == spanGroup->count) {
-            spanGroup->size = (spanGroup->size + 8) * 2;
-            spanGroup->group = (Spans *)
-                xrealloc (spanGroup->group, sizeof (Spans) * spanGroup->size);
-        }
-
-        spanGroup->group[spanGroup->count] = *spans;
-        (spanGroup->count)++;
-        ymin = spans->points[0].y;
-        if (ymin < spanGroup->ymin)
-            spanGroup->ymin = ymin;
-        ymax = spans->points[spansCount - 1].y;
-        if (ymax > spanGroup->ymax)
-            spanGroup->ymax = ymax;
-        if (otherGroup && otherGroup->ymin < ymax && ymin < otherGroup->ymax) {
-            miSubtractSpans (otherGroup, spans);
-        }
-    } else {
-        xfree (spans->points);
-        xfree (spans->widths);
-    }
-}                               /* AppendSpans */
-
-static void
-miFreeSpanGroup (SpanGroup * spanGroup)
-{
-    if (spanGroup->group != NULL)
-        xfree (spanGroup->group);
-}
-
-static void
-QuickSortSpansX (DDXPointRec points[], int widths[], int numSpans)
-{
-    int x;
-    int i, j, m;
-    DDXPointPtr r;
-
-/* Always called with numSpans > 1 */
-/* Sorts only by x, as all y should be the same */
-
-#define ExchangeSpans(a, b)                                 \
-{                                                           \
-    DDXPointRec         tpt;                                \
-    int                 tw;                                 \
-                                                            \
-    tpt = points[a]; points[a] = points[b]; points[b] = tpt;    \
-    tw = widths[a]; widths[a] = widths[b]; widths[b] = tw;  \
-}
-
-    do {
-        if (numSpans < 9) {
-            /* Do insertion sort */
-            int xprev;
-
-            xprev = points[0].x;
-            i = 1;
-            do {                /* while i != numSpans */
-                x = points[i].x;
-                if (xprev > x) {
-                    /* points[i] is out of order.  Move into proper location. */
-                    DDXPointRec tpt;
-                    int tw, k;
-
-                    for (j = 0; x >= points[j].x; j++) {
-                    }
-                    tpt = points[i];
-                    tw = widths[i];
-                    for (k = i; k != j; k--) {
-                        points[k] = points[k - 1];
-                        widths[k] = widths[k - 1];
-                    }
-                    points[j] = tpt;
-                    widths[j] = tw;
-                    x = points[i].x;
-                }               /* if out of order */
-                xprev = x;
-                i++;
-            } while (i != numSpans);
-            return;
-        }
-
-        /* Choose partition element, stick in location 0 */
-        m = numSpans / 2;
-        if (points[m].x > points[0].x)
-            ExchangeSpans (m, 0);
-        if (points[m].x > points[numSpans - 1].x)
-            ExchangeSpans (m, numSpans - 1);
-        if (points[m].x > points[0].x)
-            ExchangeSpans (m, 0);
-        x = points[0].x;
-
-        /* Partition array */
-        i = 0;
-        j = numSpans;
-        do {
-            r = &(points[i]);
-            do {
-                r++;
-                i++;
-            } while (i != numSpans && r->x < x);
-            r = &(points[j]);
-            do {
-                r--;
-                j--;
-            } while (x < r->x);
-            if (i < j)
-                ExchangeSpans (i, j);
-        } while (i < j);
-
-        /* Move partition element back to middle */
-        ExchangeSpans (0, j);
-
-        /* Recurse */
-        if (numSpans - j - 1 > 1)
-            QuickSortSpansX (&points[j + 1], &widths[j + 1], numSpans - j - 1);
-        numSpans = j;
-    } while (numSpans > 1);
-}                               /* QuickSortSpans */
-
-
-static int
-UniquifySpansX (Spans * spans, DDXPointRec * newPoints, int *newWidths)
-{
-    int newx1, newx2, oldpt, i, y;
-    DDXPointRec *oldPoints;
-    int *oldWidths;
-    int *startNewWidths;
-
-/* Always called with numSpans > 1 */
-/* Uniquify the spans, and stash them into newPoints and newWidths.  Return the
-   number of unique spans. */
-
-
-    startNewWidths = newWidths;
-
-    oldPoints = spans->points;
-    oldWidths = spans->widths;
-
-    y = oldPoints->y;
-    newx1 = oldPoints->x;
-    newx2 = newx1 + *oldWidths;
-
-    for (i = spans->count - 1; i != 0; i--) {
-        oldPoints++;
-        oldWidths++;
-        oldpt = oldPoints->x;
-        if (oldpt > newx2) {
-            /* Write current span, start a new one */
-            newPoints->x = newx1;
-            newPoints->y = y;
-            *newWidths = newx2 - newx1;
-            newPoints++;
-            newWidths++;
-            newx1 = oldpt;
-            newx2 = oldpt + *oldWidths;
-        } else {
-            /* extend current span, if old extends beyond new */
-            oldpt = oldpt + *oldWidths;
-            if (oldpt > newx2)
-                newx2 = oldpt;
-        }
-    }                           /* for */
-
-    /* Write final span */
-    newPoints->x = newx1;
-    *newWidths = newx2 - newx1;
-    newPoints->y = y;
-
-    return (newWidths - startNewWidths) + 1;
-}                               /* UniquifySpansX */
-
-static void
-miDisposeSpanGroup (SpanGroup * spanGroup)
-{
-    int i;
-    Spans *spans;
-
-    for (i = 0; i < spanGroup->count; i++) {
-        spans = spanGroup->group + i;
-        xfree (spans->points);
-        xfree (spans->widths);
-    }
-}
-
-static void
-miFillUniqueSpanGroup (GCPtr pGC, SpanGroup * spanGroup, Boolean foreground)
-{
-    int i;
-    Spans *spans;
-    Spans *yspans;
-    int *ysizes;
-    int ymin, ylength;
-
-    /* Outgoing spans for one big call to FillSpans */
-    DDXPointPtr points;
-    int *widths;
-    int count;
-
-    if (spanGroup->count == 0)
-        return;
-
-    if (spanGroup->count == 1) {
-        /* Already should be sorted, unique */
-        spans = spanGroup->group;
-        (*pGC->ops->FillSpans)
-            (pGC, spans->count, spans->points, spans->widths, TRUE, foreground);
-        xfree (spans->points);
-        xfree (spans->widths);
-    } else {
-        /* Yuck.  Gross.  Radix sort into y buckets, then sort x and uniquify */
-        /* This seems to be the fastest thing to do.  I've tried sorting on
-           both x and y at the same time rather than creating into all those
-           y buckets, but it was somewhat slower. */
-
-        ymin = spanGroup->ymin;
-        ylength = spanGroup->ymax - ymin + 1;
-
-        /* Allocate Spans for y buckets */
-        yspans = (Spans*)xalloc (ylength * sizeof (Spans));
-        ysizes = (int *)xalloc (ylength * sizeof (int));
-
-        if (!yspans || !ysizes) {
-            if (yspans)
-                xfree (yspans);
-            if (ysizes)
-                xfree (ysizes);
-            miDisposeSpanGroup (spanGroup);
-            return;
-        }
-
-        for (i = 0; i != ylength; i++) {
-            ysizes[i] = 0;
-            yspans[i].count = 0;
-            yspans[i].points = NULL;
-            yspans[i].widths = NULL;
-        }
-
-        /* Go through every single span and put it into the correct bucket */
-        count = 0;
-        for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
-            int index;
-            int j;
-
-            for (j = 0, points = spans->points, widths = spans->widths;
-                 j != spans->count; j++, points++, widths++) {
-                index = points->y - ymin;
-                if (index >= 0 && index < ylength) {
-                    Spans *newspans = &(yspans[index]);
-                    if (newspans->count == ysizes[index]) {
-                        DDXPointPtr newpoints;
-                        int *newwidths;
-                        ysizes[index] = (ysizes[index] + 8) * 2;
-                        newpoints = (DDXPointPtr) xrealloc (newspans->points,
-                                                            ysizes[index] * sizeof (DDXPointRec));
-                        newwidths = (int *) xrealloc (newspans->widths,
-                                                      ysizes[index] * sizeof (int));
-                        if (!newpoints || !newwidths) {
-                            int i;
-
-                            for (i = 0; i < ylength; i++) {
-                                xfree (yspans[i].points);
-                                xfree (yspans[i].widths);
-                            }
-                            xfree (yspans);
-                            xfree (ysizes);
-                            miDisposeSpanGroup (spanGroup);
-                            return;
-                        }
-                        newspans->points = newpoints;
-                        newspans->widths = newwidths;
-                    }
-                    newspans->points[newspans->count] = *points;
-                    newspans->widths[newspans->count] = *widths;
-                    (newspans->count)++;
-                }               /* if y value of span in range */
-            }                   /* for j through spans */
-            count += spans->count;
-            xfree (spans->points);
-            spans->points = NULL;
-            xfree (spans->widths);
-            spans->widths = NULL;
-        }                       /* for i thorough Spans */
-
-        /* Now sort by x and uniquify each bucket into the final array */
-        points = (DDXPointRec*)xalloc (count * sizeof (DDXPointRec));
-        widths = (int *)xalloc (count * sizeof (int));
-        if (!points || !widths) {
-            int i;
-
-            for (i = 0; i < ylength; i++) {
-                xfree (yspans[i].points);
-                xfree (yspans[i].widths);
-            }
-            xfree (yspans);
-            xfree (ysizes);
-            if (points)
-                xfree (points);
-            if (widths)
-                xfree (widths);
-            return;
-        }
-        count = 0;
-        for (i = 0; i != ylength; i++) {
-            int ycount = yspans[i].count;
-            if (ycount > 0) {
-                if (ycount > 1) {
-                    QuickSortSpansX (yspans[i].points, yspans[i].widths, ycount);
-                    count += UniquifySpansX (&(yspans[i]), &(points[count]), &(widths[count]));
-                } else {
-                    points[count] = yspans[i].points[0];
-                    widths[count] = yspans[i].widths[0];
-                    count++;
-                }
-                xfree (yspans[i].points);
-                xfree (yspans[i].widths);
-            }
-        }
-
-        (*pGC->ops->FillSpans) (pGC, count, points, widths, TRUE, foreground);
-        xfree (points);
-        xfree (widths);
-        xfree (yspans);
-        xfree (ysizes);         /* use (DE)xalloc for these? */
-    }
-
-    spanGroup->count = 0;
-    spanGroup->ymin = MAX_COORDINATE;
-    spanGroup->ymax = MIN_COORDINATE;
-}
-
-/*
-
-The bresenham error equation used in the mi/mfb/cfb line routines is:
-
-        e = error
-        dx = difference in raw X coordinates
-        dy = difference in raw Y coordinates
-        M = # of steps in X direction
-        N = # of steps in Y direction
-        B = 0 to prefer diagonal steps in a given octant,
-            1 to prefer axial steps in a given octant
-
-        For X major lines:
-                e = 2Mdy - 2Ndx - dx - B
-                -2dx <= e < 0
-
-        For Y major lines:
-                e = 2Ndx - 2Mdy - dy - B
-                -2dy <= e < 0
-
-At the start of the line, we have taken 0 X steps and 0 Y steps,
-so M = 0 and N = 0:
-
-        X major         e = 2Mdy - 2Ndx - dx - B
-                  = -dx - B
-
-        Y major         e = 2Ndx - 2Mdy - dy - B
-                  = -dy - B
-
-At the end of the line, we have taken dx X steps and dy Y steps,
-so M = dx and N = dy:
-
-        X major         e = 2Mdy - 2Ndx - dx - B
-                  = 2dxdy - 2dydx - dx - B
-                  = -dx - B
-        Y major e = 2Ndx - 2Mdy - dy - B
-                  = 2dydx - 2dxdy - dy - B
-                  = -dy - B
-
-Thus, the error term is the same at the start and end of the line.
-
-Let us consider clipping an X coordinate.  There are 4 cases which
-represent the two independent cases of clipping the start vs. the
-end of the line and an X major vs. a Y major line.  In any of these
-cases, we know the number of X steps (M) and we wish to find the
-number of Y steps (N).  Thus, we will solve our error term equation.
-If we are clipping the start of the line, we will find the smallest
-N that satisfies our error term inequality.  If we are clipping the
-end of the line, we will find the largest number of Y steps that
-satisfies the inequality.  In that case, since we are representing
-the Y steps as (dy - N), we will actually want to solve for the
-smallest N in that equation.
-
-Case 1:  X major, starting X coordinate moved by M steps
-
-                -2dx <= 2Mdy - 2Ndx - dx - B < 0
-        2Ndx <= 2Mdy - dx - B + 2dx     2Ndx > 2Mdy - dx - B
-        2Ndx <= 2Mdy + dx - B           N > (2Mdy - dx - B) / 2dx
-        N <= (2Mdy + dx - B) / 2dx
-
-Since we are trying to find the smallest N that satisfies these
-equations, we should use the > inequality to find the smallest:
-
-        N = floor((2Mdy - dx - B) / 2dx) + 1
-          = floor((2Mdy - dx - B + 2dx) / 2dx)
-          = floor((2Mdy + dx - B) / 2dx)
-
-Case 1b: X major, ending X coordinate moved to M steps
-
-Same derivations as Case 1, but we want the largest N that satisfies
-the equations, so we use the <= inequality:
-
-        N = floor((2Mdy + dx - B) / 2dx)
-
-Case 2: X major, ending X coordinate moved by M steps
-
-                -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
-                -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
-                -2dx <= 2Ndx - 2Mdy - dx - B < 0
-        2Ndx >= 2Mdy + dx + B - 2dx     2Ndx < 2Mdy + dx + B
-        2Ndx >= 2Mdy - dx + B           N < (2Mdy + dx + B) / 2dx
-        N >= (2Mdy - dx + B) / 2dx
-
-Since we are trying to find the highest number of Y steps that
-satisfies these equations, we need to find the smallest N, so
-we should use the >= inequality to find the smallest:
-
-        N = ceiling((2Mdy - dx + B) / 2dx)
-          = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
-          = floor((2Mdy + dx + B - 1) / 2dx)
-
-Case 2b: X major, starting X coordinate moved to M steps from end
-
-Same derivations as Case 2, but we want the smallest number of Y
-steps, so we want the highest N, so we use the < inequality:
-
-        N = ceiling((2Mdy + dx + B) / 2dx) - 1
-          = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
-          = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
-          = floor((2Mdy + dx + B - 1) / 2dx)
-
-Case 3: Y major, starting X coordinate moved by M steps
-
-                -2dy <= 2Ndx - 2Mdy - dy - B < 0
-        2Ndx >= 2Mdy + dy + B - 2dy     2Ndx < 2Mdy + dy + B
-        2Ndx >= 2Mdy - dy + B           N < (2Mdy + dy + B) / 2dx
-        N >= (2Mdy - dy + B) / 2dx
-
-Since we are trying to find the smallest N that satisfies these
-equations, we should use the >= inequality to find the smallest:
-
-        N = ceiling((2Mdy - dy + B) / 2dx)
-          = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
-          = floor((2Mdy - dy + B - 1) / 2dx) + 1
-
-Case 3b: Y major, ending X coordinate moved to M steps
-
-Same derivations as Case 3, but we want the largest N that satisfies
-the equations, so we use the < inequality:
-
-        N = ceiling((2Mdy + dy + B) / 2dx) - 1
-          = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
-          = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
-          = floor((2Mdy + dy + B - 1) / 2dx)
-
-Case 4: Y major, ending X coordinate moved by M steps
-
-                -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
-                -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
-                -2dy <= 2Mdy - 2Ndx - dy - B < 0
-        2Ndx <= 2Mdy - dy - B + 2dy     2Ndx > 2Mdy - dy - B
-        2Ndx <= 2Mdy + dy - B           N > (2Mdy - dy - B) / 2dx
-        N <= (2Mdy + dy - B) / 2dx
-
-Since we are trying to find the highest number of Y steps that
-satisfies these equations, we need to find the smallest N, so
-we should use the > inequality to find the smallest:
-
-        N = floor((2Mdy - dy - B) / 2dx) + 1
-
-Case 4b: Y major, starting X coordinate moved to M steps from end
-
-Same analysis as Case 4, but we want the smallest number of Y steps
-which means the largest N, so we use the <= inequality:
-
-        N = floor((2Mdy + dy - B) / 2dx)
-
-Now let's try the Y coordinates, we have the same 4 cases.
-
-Case 5: X major, starting Y coordinate moved by N steps
-
-                -2dx <= 2Mdy - 2Ndx - dx - B < 0
-        2Mdy >= 2Ndx + dx + B - 2dx     2Mdy < 2Ndx + dx + B
-        2Mdy >= 2Ndx - dx + B           M < (2Ndx + dx + B) / 2dy
-        M >= (2Ndx - dx + B) / 2dy
-
-Since we are trying to find the smallest M, we use the >= inequality:
-
-        M = ceiling((2Ndx - dx + B) / 2dy)
-          = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
-          = floor((2Ndx - dx + B - 1) / 2dy) + 1
-
-Case 5b: X major, ending Y coordinate moved to N steps
-
-Same derivations as Case 5, but we want the largest M that satisfies
-the equations, so we use the < inequality:
-
-        M = ceiling((2Ndx + dx + B) / 2dy) - 1
-          = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
-          = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
-          = floor((2Ndx + dx + B - 1) / 2dy)
-
-Case 6: X major, ending Y coordinate moved by N steps
-
-                -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
-                -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
-                -2dx <= 2Ndx - 2Mdy - dx - B < 0
-        2Mdy <= 2Ndx - dx - B + 2dx     2Mdy > 2Ndx - dx - B
-        2Mdy <= 2Ndx + dx - B           M > (2Ndx - dx - B) / 2dy
-        M <= (2Ndx + dx - B) / 2dy
-
-Largest # of X steps means smallest M, so use the > inequality:
-
-        M = floor((2Ndx - dx - B) / 2dy) + 1
-
-Case 6b: X major, starting Y coordinate moved to N steps from end
-
-Same derivations as Case 6, but we want the smallest # of X steps
-which means the largest M, so use the <= inequality:
-
-        M = floor((2Ndx + dx - B) / 2dy)
-
-Case 7: Y major, starting Y coordinate moved by N steps
-
-                -2dy <= 2Ndx - 2Mdy - dy - B < 0
-        2Mdy <= 2Ndx - dy - B + 2dy     2Mdy > 2Ndx - dy - B
-        2Mdy <= 2Ndx + dy - B           M > (2Ndx - dy - B) / 2dy
-        M <= (2Ndx + dy - B) / 2dy
-
-To find the smallest M, use the > inequality:
-
-        M = floor((2Ndx - dy - B) / 2dy) + 1
-          = floor((2Ndx - dy - B + 2dy) / 2dy)
-          = floor((2Ndx + dy - B) / 2dy)
-
-Case 7b: Y major, ending Y coordinate moved to N steps
-
-Same derivations as Case 7, but we want the largest M that satisfies
-the equations, so use the <= inequality:
-
-        M = floor((2Ndx + dy - B) / 2dy)
-
-Case 8: Y major, ending Y coordinate moved by N steps
-
-                -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
-                -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
-                -2dy <= 2Mdy - 2Ndx - dy - B < 0
-        2Mdy >= 2Ndx + dy + B - 2dy     2Mdy < 2Ndx + dy + B
-        2Mdy >= 2Ndx - dy + B           M < (2Ndx + dy + B) / 2dy
-        M >= (2Ndx - dy + B) / 2dy
-
-To find the highest X steps, find the smallest M, use the >= inequality:
-
-        M = ceiling((2Ndx - dy + B) / 2dy)
-          = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
-          = floor((2Ndx + dy + B - 1) / 2dy)
-
-Case 8b: Y major, starting Y coordinate moved to N steps from the end
-
-Same derivations as Case 8, but we want to find the smallest # of X
-steps which means the largest M, so we use the < inequality:
-
-        M = ceiling((2Ndx + dy + B) / 2dy) - 1
-          = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
-          = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
-          = floor((2Ndx + dy + B - 1) / 2dy)
-
-So, our equations are:
-
-        1:  X major move x1 to x1+M     floor((2Mdy + dx - B) / 2dx)
-        1b: X major move x2 to x1+M     floor((2Mdy + dx - B) / 2dx)
-        2:  X major move x2 to x2-M     floor((2Mdy + dx + B - 1) / 2dx)
-        2b: X major move x1 to x2-M     floor((2Mdy + dx + B - 1) / 2dx)
-
-        3:  Y major move x1 to x1+M     floor((2Mdy - dy + B - 1) / 2dx) + 1
-        3b: Y major move x2 to x1+M     floor((2Mdy + dy + B - 1) / 2dx)
-        4:  Y major move x2 to x2-M     floor((2Mdy - dy - B) / 2dx) + 1
-        4b: Y major move x1 to x2-M     floor((2Mdy + dy - B) / 2dx)
-
-        5:  X major move y1 to y1+N     floor((2Ndx - dx + B - 1) / 2dy) + 1
-        5b: X major move y2 to y1+N     floor((2Ndx + dx + B - 1) / 2dy)
-        6:  X major move y2 to y2-N     floor((2Ndx - dx - B) / 2dy) + 1
-        6b: X major move y1 to y2-N     floor((2Ndx + dx - B) / 2dy)
-
-        7:  Y major move y1 to y1+N     floor((2Ndx + dy - B) / 2dy)
-        7b: Y major move y2 to y1+N     floor((2Ndx + dy - B) / 2dy)
-        8:  Y major move y2 to y2-N     floor((2Ndx + dy + B - 1) / 2dy)
-        8b: Y major move y1 to y2-N     floor((2Ndx + dy + B - 1) / 2dy)
-
-We have the following constraints on all of the above terms:
-
-        0 < M,N <= 2^15          2^15 can be imposed by miZeroClipLine
-        0 <= dx/dy <= 2^16 - 1
-        0 <= B <= 1
-
-The floor in all of the above equations can be accomplished with a
-simple C divide operation provided that both numerator and denominator
-are positive.
-
-Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
-and moving a Y coordinate implies dy != 0, we know that the denominators
-are all > 0.
-
-For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
-bias.  Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
-or > 0 to prove that the numerators are positive (or zero).
-
-For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
-constraints, the first four equations all have numerators >= 0.
-
-For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
-So (2Mdy - dy) > 0, since they are Y major lines.  Also, (2Mdy + dy) >= 3dy
-or (2Mdy + dy) > 0.  So all of their numerators are >= 0.
-
-For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
->= dx > 0.  Similarly (2Ndx + dx) >= 3dx > 0.  So all numerators >= 0.
-
-For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
-are > 0.
-
-To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy.  This
-is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
-           <= 2^16 * (2^16 - 1) + (2^16 - 1)
-           <= 2^32 - 2^16 + 2^16 - 1
-           <= 2^32 - 1
-Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
-the numerator is therefore (2^32 - 1), which does not overflow an unsigned
-32 bit variable.
-
-*/
-
-/* Bit codes for the terms of the 16 clipping equations defined below. */
-
-#define T_2NDX          (1 << 0)
-#define T_2MDY          (0)     /* implicit term */
-#define T_DXNOTY        (1 << 1)
-#define T_DYNOTX        (0)     /* implicit term */
-#define T_SUBDXORY      (1 << 2)
-#define T_ADDDX                 (T_DXNOTY)      /* composite term */
-#define T_SUBDX                 (T_DXNOTY | T_SUBDXORY) /* composite term */
-#define T_ADDDY                 (T_DYNOTX)      /* composite term */
-#define T_SUBDY                 (T_DYNOTX | T_SUBDXORY) /* composite term */
-#define T_BIASSUBONE    (1 << 3)
-#define T_SUBBIAS       (0)     /* implicit term */
-#define T_DIV2DX        (1 << 4)
-#define T_DIV2DY        (0)     /* implicit term */
-#define T_ADDONE        (1 << 5)
-
-/* Bit masks defining the 16 equations used in miZeroClipLine. */
-
-#define EQN1    (T_2MDY | T_ADDDX | T_SUBBIAS    | T_DIV2DX)
-#define EQN1B   (T_2MDY | T_ADDDX | T_SUBBIAS    | T_DIV2DX)
-#define EQN2    (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
-#define EQN2B   (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
-
-#define EQN3    (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
-#define EQN3B   (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
-#define EQN4    (T_2MDY | T_SUBDY | T_SUBBIAS    | T_DIV2DX | T_ADDONE)
-#define EQN4B   (T_2MDY | T_ADDDY | T_SUBBIAS    | T_DIV2DX)
-
-#define EQN5    (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
-#define EQN5B   (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
-#define EQN6    (T_2NDX | T_SUBDX | T_SUBBIAS    | T_DIV2DY | T_ADDONE)
-#define EQN6B   (T_2NDX | T_ADDDX | T_SUBBIAS    | T_DIV2DY)
-
-#define EQN7    (T_2NDX | T_ADDDY | T_SUBBIAS    | T_DIV2DY)
-#define EQN7B   (T_2NDX | T_ADDDY | T_SUBBIAS    | T_DIV2DY)
-#define EQN8    (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
-#define EQN8B   (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
-
-/* miZeroClipLine
- *
- * returns:  1 for partially clipped line
- *          -1 for completely clipped line
- *
- */
-static int
-miZeroClipLine (int xmin, int ymin, int xmax, int ymax,
-                int *new_x1, int *new_y1, int *new_x2, int *new_y2,
-                unsigned int adx, unsigned int ady,
-                int *pt1_clipped, int *pt2_clipped, int octant, unsigned int bias, int oc1, int oc2)
-{
-    int swapped = 0;
-    int clipDone = 0;
-    CARD32 utmp = 0;
-    int clip1, clip2;
-    int x1, y1, x2, y2;
-    int x1_orig, y1_orig, x2_orig, y2_orig;
-    int xmajor;
-    int negslope = 0, anchorval = 0;
-    unsigned int eqn = 0;
-
-    x1 = x1_orig = *new_x1;
-    y1 = y1_orig = *new_y1;
-    x2 = x2_orig = *new_x2;
-    y2 = y2_orig = *new_y2;
-
-    clip1 = 0;
-    clip2 = 0;
-
-    xmajor = IsXMajorOctant (octant);
-    bias = ((bias >> octant) & 1);
-
-    while (1) {
-        if ((oc1 & oc2) != 0) { /* trivial reject */
-            clipDone = -1;
-            clip1 = oc1;
-            clip2 = oc2;
-            break;
-        } else if ((oc1 | oc2) == 0) {  /* trivial accept */
-            clipDone = 1;
-            if (swapped) {
-                SWAPINT_PAIR (x1, y1, x2, y2);
-                SWAPINT (clip1, clip2);
-            }
-            break;
-        } else {                /* have to clip */
-
-            /* only clip one point at a time */
-            if (oc1 == 0) {
-                SWAPINT_PAIR (x1, y1, x2, y2);
-                SWAPINT_PAIR (x1_orig, y1_orig, x2_orig, y2_orig);
-                SWAPINT (oc1, oc2);
-                SWAPINT (clip1, clip2);
-                swapped = !swapped;
-            }
-
-            clip1 |= oc1;
-            if (oc1 & OUT_LEFT) {
-                negslope = IsYDecreasingOctant (octant);
-                utmp = xmin - x1_orig;
-                if (utmp <= 32767) {    /* clip based on near endpt */
-                    if (xmajor)
-                        eqn = (swapped) ? EQN2 : EQN1;
-                    else
-                        eqn = (swapped) ? EQN4 : EQN3;
-                    anchorval = y1_orig;
-                } else {        /* clip based on far endpt */
-
-                    utmp = x2_orig - xmin;
-                    if (xmajor)
-                        eqn = (swapped) ? EQN1B : EQN2B;
-                    else
-                        eqn = (swapped) ? EQN3B : EQN4B;
-                    anchorval = y2_orig;
-                    negslope = !negslope;
-                }
-                x1 = xmin;
-            } else if (oc1 & OUT_ABOVE) {
-                negslope = IsXDecreasingOctant (octant);
-                utmp = ymin - y1_orig;
-                if (utmp <= 32767) {    /* clip based on near endpt */
-                    if (xmajor)
-                        eqn = (swapped) ? EQN6 : EQN5;
-                    else
-                        eqn = (swapped) ? EQN8 : EQN7;
-                    anchorval = x1_orig;
-                } else {        /* clip based on far endpt */
-
-                    utmp = y2_orig - ymin;
-                    if (xmajor)
-                        eqn = (swapped) ? EQN5B : EQN6B;
-                    else
-                        eqn = (swapped) ? EQN7B : EQN8B;
-                    anchorval = x2_orig;
-                    negslope = !negslope;
-                }
-                y1 = ymin;
-            } else if (oc1 & OUT_RIGHT) {
-                negslope = IsYDecreasingOctant (octant);
-                utmp = x1_orig - xmax;
-                if (utmp <= 32767) {    /* clip based on near endpt */
-                    if (xmajor)
-                        eqn = (swapped) ? EQN2 : EQN1;
-                    else
-                        eqn = (swapped) ? EQN4 : EQN3;
-                    anchorval = y1_orig;
-                } else {        /* clip based on far endpt */
-
-                    /*
-                     * Technically since the equations can handle
-                     * utmp == 32768, this overflow code isn't
-                     * needed since X11 protocol can't generate
-                     * a line which goes more than 32768 pixels
-                     * to the right of a clip rectangle.
-                     */
-                    utmp = xmax - x2_orig;
-                    if (xmajor)
-                        eqn = (swapped) ? EQN1B : EQN2B;
-                    else
-                        eqn = (swapped) ? EQN3B : EQN4B;
-                    anchorval = y2_orig;
-                    negslope = !negslope;
-                }
-                x1 = xmax;
-            } else if (oc1 & OUT_BELOW) {
-                negslope = IsXDecreasingOctant (octant);
-                utmp = y1_orig - ymax;
-                if (utmp <= 32767) {    /* clip based on near endpt */
-                    if (xmajor)
-                        eqn = (swapped) ? EQN6 : EQN5;
-                    else
-                        eqn = (swapped) ? EQN8 : EQN7;
-                    anchorval = x1_orig;
-                } else {        /* clip based on far endpt */
-
-                    /*
-                     * Technically since the equations can handle
-                     * utmp == 32768, this overflow code isn't
-                     * needed since X11 protocol can't generate
-                     * a line which goes more than 32768 pixels
-                     * below the bottom of a clip rectangle.
-                     */
-                    utmp = ymax - y2_orig;
-                    if (xmajor)
-                        eqn = (swapped) ? EQN5B : EQN6B;
-                    else
-                        eqn = (swapped) ? EQN7B : EQN8B;
-                    anchorval = x2_orig;
-                    negslope = !negslope;
-                }
-                y1 = ymax;
-            }
-
-            if (swapped)
-                negslope = !negslope;
-
-            utmp <<= 1;         /* utmp = 2N or 2M */
-            if (eqn & T_2NDX)
-                utmp = (utmp * adx);
-            else                /* (eqn & T_2MDY) */
-                utmp = (utmp * ady);
-            if (eqn & T_DXNOTY)
-                if (eqn & T_SUBDXORY)
-                    utmp -= adx;
-                else
-                    utmp += adx;
-            else /* (eqn & T_DYNOTX) */ if (eqn & T_SUBDXORY)
-                utmp -= ady;
-            else
-                utmp += ady;
-            if (eqn & T_BIASSUBONE)
-                utmp += bias - 1;
-            else                /* (eqn & T_SUBBIAS) */
-                utmp -= bias;
-            if (eqn & T_DIV2DX)
-                utmp /= (adx << 1);
-            else                /* (eqn & T_DIV2DY) */
-                utmp /= (ady << 1);
-            if (eqn & T_ADDONE)
-                utmp++;
-
-            if (negslope)
-                utmp = (uint32_t)(-(int32_t)utmp);
-
-            if (eqn & T_2NDX)   /* We are calculating X steps */
-                x1 = anchorval + utmp;
-            else                /* else, Y steps */
-                y1 = anchorval + utmp;
-
-            oc1 = 0;
-            MIOUTCODES (oc1, x1, y1, xmin, ymin, xmax, ymax);
-        }
-    }
-
-    *new_x1 = x1;
-    *new_y1 = y1;
-    *new_x2 = x2;
-    *new_y2 = y2;
-
-    *pt1_clipped = clip1;
-    *pt2_clipped = clip2;
-
-    return clipDone;
-}
-
-/* Draw lineSolid, fillStyle-independent zero width lines.
- *
- * Must keep X and Y coordinates in "ints" at least until after they're
- * translated and clipped to accomodate CoordModePrevious lines with very
- * large coordinates.
- *
- * Draws the same pixels regardless of sign(dx) or sign(dy).
- *
- * Ken Whaley
- *
- */
-
-#define MI_OUTPUT_POINT(xx, yy)\
-{\
-    if ( !new_span && yy == current_y)\
-    {\
-        if (xx < spans->x)\
-            spans->x = xx;\
-        ++*widths;\
-    }\
-    else\
-    {\
-        ++Nspans;\
-        ++spans;\
-        ++widths;\
-        spans->x = xx;\
-        spans->y = yy;\
-        *widths = 1;\
-        current_y = yy;\
-        new_span = FALSE;\
-    }\
-}
-
-void
-miZeroLine (GCPtr pGC, int mode,        /* Origin or Previous */
-            int npt,            /* number of points */
-            DDXPointPtr pptInit)
-{
-    int Nspans, current_y = 0;
-    DDXPointPtr ppt;
-    DDXPointPtr pspanInit, spans;
-    int *pwidthInit, *widths, list_len;
-    int xleft, ytop, xright, ybottom;
-    int new_x1, new_y1, new_x2, new_y2;
-    int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
-    int oc1, oc2;
-    int result;
-    int pt1_clipped, pt2_clipped = 0;
-    Boolean new_span;
-    int signdx, signdy;
-    int clipdx, clipdy;
-    int width, height;
-    int adx, ady;
-    int octant;
-    unsigned int bias = miGetZeroLineBias (screen);
-    int e, e1, e2, e3;          /* Bresenham error terms */
-    int length;                 /* length of lines == # of pixels on major axis */
-
-    xleft = 0;
-    ytop = 0;
-    xright = pGC->width - 1;
-    ybottom = pGC->height - 1;
-
-    /* it doesn't matter whether we're in drawable or screen coordinates,
-     * FillSpans simply cannot take starting coordinates outside of the
-     * range of a DDXPointRec component.
-     */
-    if (xright > MAX_COORDINATE)
-        xright = MAX_COORDINATE;
-    if (ybottom > MAX_COORDINATE)
-        ybottom = MAX_COORDINATE;
-
-    /* since we're clipping to the drawable's boundaries & coordinate
-     * space boundaries, we're guaranteed that the larger of width/height
-     * is the longest span we'll need to output
-     */
-    width = xright - xleft + 1;
-    height = ybottom - ytop + 1;
-    list_len = (height >= width) ? height : width;
-    pspanInit = (DDXPointRec *)xalloc (list_len * sizeof (DDXPointRec));
-    pwidthInit = (int *)xalloc (list_len * sizeof (int));
-    if (!pspanInit || !pwidthInit)
-        return;
-
-    Nspans = 0;
-    new_span = TRUE;
-    spans = pspanInit - 1;
-    widths = pwidthInit - 1;
-    ppt = pptInit;
-
-    xstart = ppt->x;
-    ystart = ppt->y;
-
-    /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
-     * iteration logic
-     */
-    x2 = xstart;
-    y2 = ystart;
-    oc2 = 0;
-    MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
-
-    while (--npt > 0) {
-        if (Nspans > 0)
-            (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
-        Nspans = 0;
-        new_span = TRUE;
-        spans = pspanInit - 1;
-        widths = pwidthInit - 1;
-
-        x1 = x2;
-        y1 = y2;
-        oc1 = oc2;
-        ++ppt;
-
-        x2 = ppt->x;
-        y2 = ppt->y;
-        if (mode == CoordModePrevious) {
-            x2 += x1;
-            y2 += y1;
-        }
-
-        oc2 = 0;
-        MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
-
-        CalcLineDeltas (x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
-
-        if (adx > ady) {
-            e1 = ady << 1;
-            e2 = e1 - (adx << 1);
-            e = e1 - adx;
-            length = adx;       /* don't draw endpoint in main loop */
-
-            FIXUP_ERROR (e, octant, bias);
-
-            new_x1 = x1;
-            new_y1 = y1;
-            new_x2 = x2;
-            new_y2 = y2;
-            pt1_clipped = 0;
-            pt2_clipped = 0;
-
-            if ((oc1 | oc2) != 0) {
-                result = miZeroClipLine (xleft, ytop, xright, ybottom,
-                                         &new_x1, &new_y1, &new_x2, &new_y2,
-                                         adx, ady,
-                                         &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2);
-                if (result == -1)
-                    continue;
-
-                length = abs (new_x2 - new_x1);
-
-                /* if we've clipped the endpoint, always draw the full length
-                 * of the segment, because then the capstyle doesn't matter
-                 */
-                if (pt2_clipped)
-                    length++;
-
-                if (pt1_clipped) {
-                    /* must calculate new error terms */
-                    clipdx = abs (new_x1 - x1);
-                    clipdy = abs (new_y1 - y1);
-                    e += (clipdy * e2) + ((clipdx - clipdy) * e1);
-                }
-            }
-
-            /* draw the segment */
-
-            x = new_x1;
-            y = new_y1;
-
-            e3 = e2 - e1;
-            e = e - e1;
-
-            while (length--) {
-                MI_OUTPUT_POINT (x, y);
-                e += e1;
-                if (e >= 0) {
-                    y += signdy;
-                    e += e3;
-                }
-                x += signdx;
-            }
-        } else {                /* Y major line */
-
-            e1 = adx << 1;
-            e2 = e1 - (ady << 1);
-            e = e1 - ady;
-            length = ady;       /* don't draw endpoint in main loop */
-
-            SetYMajorOctant (octant);
-            FIXUP_ERROR (e, octant, bias);
-
-            new_x1 = x1;
-            new_y1 = y1;
-            new_x2 = x2;
-            new_y2 = y2;
-            pt1_clipped = 0;
-            pt2_clipped = 0;
-
-            if ((oc1 | oc2) != 0) {
-                result = miZeroClipLine (xleft, ytop, xright, ybottom,
-                                         &new_x1, &new_y1, &new_x2, &new_y2,
-                                         adx, ady,
-                                         &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2);
-                if (result == -1)
-                    continue;
-
-                length = abs (new_y2 - new_y1);
-
-                /* if we've clipped the endpoint, always draw the full length
-                 * of the segment, because then the capstyle doesn't matter
-                 */
-                if (pt2_clipped)
-                    length++;
-
-                if (pt1_clipped) {
-                    /* must calculate new error terms */
-                    clipdx = abs (new_x1 - x1);
-                    clipdy = abs (new_y1 - y1);
-                    e += (clipdx * e2) + ((clipdy - clipdx) * e1);
-                }
-            }
-
-            /* draw the segment */
-
-            x = new_x1;
-            y = new_y1;
-
-            e3 = e2 - e1;
-            e = e - e1;
-
-            while (length--) {
-                MI_OUTPUT_POINT (x, y);
-                e += e1;
-                if (e >= 0) {
-                    x += signdx;
-                    e += e3;
-                }
-                y += signdy;
-            }
-        }
-    }
-
-    /* only do the capnotlast check on the last segment
-     * and only if the endpoint wasn't clipped.  And then, if the last
-     * point is the same as the first point, do not draw it, unless the
-     * line is degenerate
-     */
-    if ((!pt2_clipped) && (pGC->capStyle != CapNotLast) &&
-        (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1))) {
-        MI_OUTPUT_POINT (x, y);
-    }
-
-    if (Nspans > 0)
-        (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
-
-    xfree (pwidthInit);
-    xfree (pspanInit);
-}
-
-void
-miZeroDashLine (GCPtr pgc, int mode, int nptInit,       /* number of points in polyline */
-                DDXPointRec * pptInit   /* points in the polyline */
-    )
-{
-    /* XXX kludge until real zero-width dash code is written */
-    pgc->lineWidth = 1;
-    miWideDash (pgc, mode, nptInit, pptInit);
-    pgc->lineWidth = 0;
-}
-
-static void miLineArc (GCPtr pGC,
-                       Boolean foreground, SpanDataPtr spanData,
-                       LineFacePtr leftFace,
-                       LineFacePtr rightFace, double xorg, double yorg, Boolean isInt);
-
-
-/*
- * spans-based polygon filler
- */
-
-static void
-miFillPolyHelper (GCPtr pGC, Boolean foreground,
-                  SpanDataPtr spanData, int y, int overall_height,
-                  PolyEdgePtr left, PolyEdgePtr right, int left_count, int right_count)
-{
-    int left_x = 0, left_e = 0;
-    int left_stepx = 0;
-    int left_signdx = 0;
-    int left_dy = 0, left_dx = 0;
-
-    int right_x = 0, right_e = 0;
-    int right_stepx = 0;
-    int right_signdx = 0;
-    int right_dy = 0, right_dx = 0;
-
-    int height = 0;
-    int left_height = 0, right_height = 0;
-
-    DDXPointPtr ppt;
-    DDXPointPtr pptInit = NULL;
-    int *pwidth;
-    int *pwidthInit = NULL;
-    int xorg;
-    Spans spanRec;
-
-    left_height = 0;
-    right_height = 0;
-
-    if (!spanData) {
-        pptInit = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
-        if (!pptInit)
-            return;
-        pwidthInit = (int *)xalloc (overall_height * sizeof (*pwidth));
-        if (!pwidthInit) {
-            xfree (pptInit);
-            return;
-        }
-        ppt = pptInit;
-        pwidth = pwidthInit;
-    } else {
-        spanRec.points = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
-        if (!spanRec.points)
-            return;
-        spanRec.widths = (int *)xalloc (overall_height * sizeof (int));
-        if (!spanRec.widths) {
-            xfree (spanRec.points);
-            return;
-        }
-        ppt = spanRec.points;
-        pwidth = spanRec.widths;
-    }
-
-    xorg = 0;
-    while ((left_count || left_height) && (right_count || right_height)) {
-        MIPOLYRELOADLEFT MIPOLYRELOADRIGHT height = left_height;
-        if (height > right_height)
-            height = right_height;
-
-        left_height -= height;
-        right_height -= height;
-
-        while (--height >= 0) {
-            if (right_x >= left_x) {
-                ppt->y = y;
-                ppt->x = left_x + xorg;
-                ppt++;
-                *pwidth++ = right_x - left_x + 1;
-            }
-            y++;
-
-        MIPOLYSTEPLEFT MIPOLYSTEPRIGHT}
-    }
-    if (!spanData) {
-        (*pGC->ops->FillSpans) (pGC, ppt - pptInit, pptInit, pwidthInit, TRUE, foreground);
-        xfree (pwidthInit);
-        xfree (pptInit);
-    } else {
-        spanRec.count = ppt - spanRec.points;
-        AppendSpanGroup (pGC, foreground, &spanRec, spanData)
-    }
-}
-
-static void
-miFillRectPolyHelper (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, int x, int y, int w, int h)
-{
-    DDXPointPtr ppt;
-    int *pwidth;
-    Spans spanRec;
-    xRectangle rect;
-
-    if (!spanData) {
-        rect.x = x;
-        rect.y = y;
-        rect.width = w;
-        rect.height = h;
-        (*pGC->ops->FillRects) (pGC, 1, &rect, foreground);
-    } else {
-        spanRec.points = (DDXPointRec *)xalloc (h * sizeof (*ppt));
-        if (!spanRec.points)
-            return;
-        spanRec.widths = (int *)xalloc (h * sizeof (int));
-        if (!spanRec.widths) {
-            xfree (spanRec.points);
-            return;
-        }
-        ppt = spanRec.points;
-        pwidth = spanRec.widths;
-
-        while (h--) {
-            ppt->x = x;
-            ppt->y = y;
-            ppt++;
-            *pwidth++ = w;
-            y++;
-        }
-        spanRec.count = ppt - spanRec.points;
-        AppendSpanGroup (pGC, foreground, &spanRec, spanData)
-    }
-}
-
-static int
-miPolyBuildEdge (double x0, double y0, double k,        /* x0 * dy - y0 * dx */
-                 int dx, int dy, int xi, int yi, int left, PolyEdgePtr edge)
-{
-    int x, y, e;
-    int xady;
-
-    if (dy < 0) {
-        dy = -dy;
-        dx = -dx;
-        k = -k;
-    }
-#ifdef NOTDEF
-    {
-        double realk, kerror;
-        realk = x0 * dy - y0 * dx;
-        kerror = Fabs (realk - k);
-        if (kerror > .1)
-            printf ("realk: %g k: %g\n", realk, k);
-    }
-#endif
-    y = ICEIL (y0);
-    xady = ICEIL (k) + y * dx;
-
-    if (xady <= 0)
-        x = -(-xady / dy) - 1;
-    else
-        x = (xady - 1) / dy;
-
-    e = xady - x * dy;
-
-    if (dx >= 0) {
-        edge->signdx = 1;
-        edge->stepx = dx / dy;
-        edge->dx = dx % dy;
-    } else {
-        edge->signdx = -1;
-        edge->stepx = -(-dx / dy);
-        edge->dx = -dx % dy;
-        e = dy - e + 1;
-    }
-    edge->dy = dy;
-    edge->x = x + left + xi;
-    edge->e = e - dy;           /* bias to compare against 0 instead of dy */
-    return y + yi;
-}
-
-#define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr)))
-
-static int
-miPolyBuildPoly (PolyVertexPtr vertices,
-                 PolySlopePtr slopes,
-                 int count,
-                 int xi,
-                 int yi, PolyEdgePtr left, PolyEdgePtr right, int *pnleft, int *pnright, int *h)
-{
-    int top, bottom;
-    double miny, maxy;
-    int i;
-    int j;
-    int clockwise;
-    int slopeoff;
-    int s;
-    int nright, nleft;
-    int y, lasty = 0, bottomy, topy = 0;
-
-    /* find the top of the polygon */
-    maxy = miny = vertices[0].y;
-    bottom = top = 0;
-    for (i = 1; i < count; i++) {
-        if (vertices[i].y < miny) {
-            top = i;
-            miny = vertices[i].y;
-        }
-        if (vertices[i].y >= maxy) {
-            bottom = i;
-            maxy = vertices[i].y;
-        }
-    }
-    clockwise = 1;
-    slopeoff = 0;
-
-    i = top;
-    j = StepAround (top, -1, count);
-
-    if (slopes[j].dy * slopes[i].dx > slopes[i].dy * slopes[j].dx) {
-        clockwise = -1;
-        slopeoff = -1;
-    }
-
-    bottomy = ICEIL (maxy) + yi;
-
-    nright = 0;
-
-    s = StepAround (top, slopeoff, count);
-    i = top;
-    while (i != bottom) {
-        if (slopes[s].dy != 0) {
-            y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
-                                 slopes[s].k,
-                                 slopes[s].dx, slopes[s].dy, xi, yi, 0, &right[nright]);
-            if (nright != 0)
-                right[nright - 1].height = y - lasty;
-            else
-                topy = y;
-            nright++;
-            lasty = y;
-        }
-
-        i = StepAround (i, clockwise, count);
-        s = StepAround (s, clockwise, count);
-    }
-    if (nright != 0)
-        right[nright - 1].height = bottomy - lasty;
-
-    if (slopeoff == 0)
-        slopeoff = -1;
-    else
-        slopeoff = 0;
-
-    nleft = 0;
-    s = StepAround (top, slopeoff, count);
-    i = top;
-    while (i != bottom) {
-        if (slopes[s].dy != 0) {
-            y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
-                                 slopes[s].k, slopes[s].dx, slopes[s].dy, xi, yi, 1, &left[nleft]);
-
-            if (nleft != 0)
-                left[nleft - 1].height = y - lasty;
-            nleft++;
-            lasty = y;
-        }
-        i = StepAround (i, -clockwise, count);
-        s = StepAround (s, -clockwise, count);
-    }
-    if (nleft != 0)
-        left[nleft - 1].height = bottomy - lasty;
-    *pnleft = nleft;
-    *pnright = nright;
-    *h = bottomy - topy;
-    return topy;
-}
-
-static void
-miLineOnePoint (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, int x, int y)
-{
-    DDXPointRec pt;
-    int wid;
-
-    wid = 1;
-    pt.x = x;
-    pt.y = y;
-    (*pGC->ops->FillSpans) (pGC, 1, &pt, &wid, TRUE, foreground);
-}
-
-static void
-miLineJoin (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, LineFacePtr pLeft, LineFacePtr pRight)
-{
-    double mx = 0, my = 0;
-    double denom = 0.0;
-    PolyVertexRec vertices[4];
-    PolySlopeRec slopes[4];
-    int edgecount;
-    PolyEdgeRec left[4], right[4];
-    int nleft, nright;
-    int y, height;
-    int swapslopes;
-    int joinStyle = pGC->joinStyle;
-    int lw = pGC->lineWidth;
-
-    if (lw == 1 && !spanData) {
-        /* See if one of the lines will draw the joining pixel */
-        if (pLeft->dx > 0 || (pLeft->dx == 0 && pLeft->dy > 0))
-            return;
-        if (pRight->dx > 0 || (pRight->dx == 0 && pRight->dy > 0))
-            return;
-        if (joinStyle != JoinRound) {
-            denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
-            if (denom == 0)
-                return;         /* no join to draw */
-        }
-        if (joinStyle != JoinMiter) {
-            miLineOnePoint (pGC, foreground, spanData, pLeft->x, pLeft->y);
-            return;
-        }
-    } else {
-        if (joinStyle == JoinRound) {
-            miLineArc (pGC, foreground, spanData, pLeft, pRight, (double) 0.0, (double) 0.0, TRUE);
-            return;
-        }
-        denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
-        if (denom == 0.0)
-            return;             /* no join to draw */
-    }
-
-    swapslopes = 0;
-    if (denom > 0) {
-        pLeft->xa = -pLeft->xa;
-        pLeft->ya = -pLeft->ya;
-        pLeft->dx = -pLeft->dx;
-        pLeft->dy = -pLeft->dy;
-    } else {
-        swapslopes = 1;
-        pRight->xa = -pRight->xa;
-        pRight->ya = -pRight->ya;
-        pRight->dx = -pRight->dx;
-        pRight->dy = -pRight->dy;
-    }
-
-    vertices[0].x = pRight->xa;
-    vertices[0].y = pRight->ya;
-    slopes[0].dx = -pRight->dy;
-    slopes[0].dy = pRight->dx;
-    slopes[0].k = 0;
-
-    vertices[1].x = 0;
-    vertices[1].y = 0;
-    slopes[1].dx = pLeft->dy;
-    slopes[1].dy = -pLeft->dx;
-    slopes[1].k = 0;
-
-    vertices[2].x = pLeft->xa;
-    vertices[2].y = pLeft->ya;
-
-    if (joinStyle == JoinMiter) {
-        my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
-              pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx)) / denom;
-        if (pLeft->dy != 0) {
-            mx = pLeft->xa + (my - pLeft->ya) * (double) pLeft->dx / (double) pLeft->dy;
-        } else {
-            mx = pRight->xa + (my - pRight->ya) * (double) pRight->dx / (double) pRight->dy;
-        }
-        /* check miter limit */
-        if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
-            joinStyle = JoinBevel;
-    }
-
-    if (joinStyle == JoinMiter) {
-        slopes[2].dx = pLeft->dx;
-        slopes[2].dy = pLeft->dy;
-        slopes[2].k = pLeft->k;
-        if (swapslopes) {
-            slopes[2].dx = -slopes[2].dx;
-            slopes[2].dy = -slopes[2].dy;
-            slopes[2].k = -slopes[2].k;
-        }
-        vertices[3].x = mx;
-        vertices[3].y = my;
-        slopes[3].dx = pRight->dx;
-        slopes[3].dy = pRight->dy;
-        slopes[3].k = pRight->k;
-        if (swapslopes) {
-            slopes[3].dx = -slopes[3].dx;
-            slopes[3].dy = -slopes[3].dy;
-            slopes[3].k = -slopes[3].k;
-        }
-        edgecount = 4;
-    } else {
-        double scale, dx, dy, adx, ady;
-
-        adx = dx = pRight->xa - pLeft->xa;
-        ady = dy = pRight->ya - pLeft->ya;
-        if (adx < 0)
-            adx = -adx;
-        if (ady < 0)
-            ady = -ady;
-        scale = ady;
-        if (adx > ady)
-            scale = adx;
-        slopes[2].dx = (int) ((dx * 65536) / scale);
-        slopes[2].dy = (int) ((dy * 65536) / scale);
-        slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
-                       (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
-        edgecount = 3;
-    }
-
-    y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
-                         left, right, &nleft, &nright, &height);
-    miFillPolyHelper (pGC, foreground, spanData, y, height, left, right, nleft, nright);
-}
-
-static int
-miLineArcI (GCPtr pGC, int xorg, int yorg, DDXPointPtr points, int *widths)
-{
-    DDXPointPtr tpts, bpts;
-    int *twids, *bwids;
-    int x, y, e, ex, slw;
-
-    tpts = points;
-    twids = widths;
-    slw = pGC->lineWidth;
-    if (slw == 1) {
-        tpts->x = xorg;
-        tpts->y = yorg;
-        *twids = 1;
-        return 1;
-    }
-    bpts = tpts + slw;
-    bwids = twids + slw;
-    y = (slw >> 1) + 1;
-    if (slw & 1)
-        e = -((y << 2) + 3);
-    else
-        e = -(y << 3);
-    ex = -4;
-    x = 0;
-    while (y) {
-        e += (y << 3) - 4;
-        while (e >= 0) {
-            x++;
-            e += (ex = -((x << 3) + 4));
-        }
-        y--;
-        slw = (x << 1) + 1;
-        if ((e == ex) && (slw > 1))
-            slw--;
-        tpts->x = xorg - x;
-        tpts->y = yorg - y;
-        tpts++;
-        *twids++ = slw;
-        if ((y != 0) && ((slw > 1) || (e != ex))) {
-            bpts--;
-            bpts->x = xorg - x;
-            bpts->y = yorg + y;
-            *--bwids = slw;
-        }
-    }
-    return (pGC->lineWidth);
-}
-
-#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
-    if (ybase == edgey) \
-    { \
-        if (edgeleft) \
-        { \
-            if (edge->x > xcl) \
-                xcl = edge->x; \
-        } \
-        else \
-        { \
-            if (edge->x < xcr) \
-                xcr = edge->x; \
-        } \
-        edgey++; \
-        edge->x += edge->stepx; \
-        edge->e += edge->dx; \
-        if (edge->e > 0) \
-        { \
-            edge->x += edge->signdx; \
-            edge->e -= edge->dy; \
-        } \
-    }
-
-static int
-miLineArcD (GCPtr pGC,
-            double xorg,
-            double yorg,
-            DDXPointPtr points,
-            int *widths,
-            PolyEdgePtr edge1,
-            int edgey1, Boolean edgeleft1, PolyEdgePtr edge2, int edgey2, Boolean edgeleft2)
-{
-    DDXPointPtr pts;
-    int *wids;
-    double radius, x0, y0, el, er, yk, xlk, xrk, k;
-    int xbase, ybase, y, boty, xl, xr, xcl, xcr;
-    int ymin, ymax;
-    Boolean edge1IsMin, edge2IsMin;
-    int ymin1, ymin2;
-
-    pts = points;
-    wids = widths;
-    xbase = (int)floor (xorg);
-    x0 = xorg - xbase;
-    ybase = ICEIL (yorg);
-    y0 = yorg - ybase;
-    xlk = x0 + x0 + 1.0;
-    xrk = x0 + x0 - 1.0;
-    yk = y0 + y0 - 1.0;
-    radius = ((double) pGC->lineWidth) / 2.0;
-    y = (int)floor (radius - y0 + 1.0);
-    ybase -= y;
-    ymin = ybase;
-    ymax = 65536;
-    edge1IsMin = FALSE;
-    ymin1 = edgey1;
-    if (edge1->dy >= 0) {
-        if (!edge1->dy) {
-            if (edgeleft1)
-                edge1IsMin = TRUE;
-            else
-                ymax = edgey1;
-            edgey1 = 65536;
-        } else {
-            if ((edge1->signdx < 0) == edgeleft1)
-                edge1IsMin = TRUE;
-        }
-    }
-    edge2IsMin = FALSE;
-    ymin2 = edgey2;
-    if (edge2->dy >= 0) {
-        if (!edge2->dy) {
-            if (edgeleft2)
-                edge2IsMin = TRUE;
-            else
-                ymax = edgey2;
-            edgey2 = 65536;
-        } else {
-            if ((edge2->signdx < 0) == edgeleft2)
-                edge2IsMin = TRUE;
-        }
-    }
-    if (edge1IsMin) {
-        ymin = ymin1;
-        if (edge2IsMin && ymin1 > ymin2)
-            ymin = ymin2;
-    } else if (edge2IsMin)
-        ymin = ymin2;
-    el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
-    er = el + xrk;
-    xl = 1;
-    xr = 0;
-    if (x0 < 0.5) {
-        xl = 0;
-        el -= xlk;
-    }
-    boty = (y0 < -0.5) ? 1 : 0;
-    if (ybase + y - boty > ymax)
-        boty = ymax - ybase - y;
-    while (y > boty) {
-        k = (y << 1) + yk;
-        er += k;
-        while (er > 0.0) {
-            xr++;
-            er += xrk - (xr << 1);
-        }
-        el += k;
-        while (el >= 0.0) {
-            xl--;
-            el += (xl << 1) - xlk;
-        }
-        y--;
-        ybase++;
-        if (ybase < ymin)
-            continue;
-        xcl = xl + xbase;
-        xcr = xr + xbase;
-        CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
-        CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
-        if (xcr >= xcl) {
-            pts->x = xcl;
-            pts->y = ybase;
-            pts++;
-            *wids++ = xcr - xcl + 1;
-        }
-    }
-    er = xrk - (xr << 1) - er;
-    el = (xl << 1) - xlk - el;
-    boty = (int)floor (-y0 - radius + 1.0);
-    if (ybase + y - boty > ymax)
-        boty = ymax - ybase - y;
-    while (y > boty) {
-        k = (y << 1) + yk;
-        er -= k;
-        while ((er >= 0.0) && (xr >= 0)) {
-            xr--;
-            er += xrk - (xr << 1);
-        }
-        el -= k;
-        while ((el > 0.0) && (xl <= 0)) {
-            xl++;
-            el += (xl << 1) - xlk;
-        }
-        y--;
-        ybase++;
-        if (ybase < ymin)
-            continue;
-        xcl = xl + xbase;
-        xcr = xr + xbase;
-        CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
-        CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
-        if (xcr >= xcl) {
-            pts->x = xcl;
-            pts->y = ybase;
-            pts++;
-            *wids++ = xcr - xcl + 1;
-        }
-    }
-    return (pts - points);
-}
-
-static int
-miRoundJoinFace (LineFacePtr face, PolyEdgePtr edge, Boolean * leftEdge)
-{
-    int y;
-    int dx, dy;
-    double xa, ya;
-    Boolean left;
-
-    dx = -face->dy;
-    dy = face->dx;
-    xa = face->xa;
-    ya = face->ya;
-    left = 1;
-    if (ya > 0) {
-        ya = 0.0;
-        xa = 0.0;
-    }
-    if (dy < 0 || (dy == 0 && dx > 0)) {
-        dx = -dx;
-        dy = -dy;
-        left = !left;
-    }
-    if (dx == 0 && dy == 0)
-        dy = 1;
-    if (dy == 0) {
-        y = ICEIL (face->ya) + face->y;
-        edge->x = -32767;
-        edge->stepx = 0;
-        edge->signdx = 0;
-        edge->e = -1;
-        edge->dy = 0;
-        edge->dx = 0;
-        edge->height = 0;
-    } else {
-        y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge);
-        edge->height = 32767;
-    }
-    *leftEdge = !left;
-    return y;
-}
-
-static void
-miRoundJoinClip (LineFacePtr pLeft, LineFacePtr pRight,
-                 PolyEdgePtr edge1, PolyEdgePtr edge2, int *y1, int *y2, Boolean * left1, Boolean * left2)
-{
-    double denom;
-
-    denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
-
-    if (denom >= 0) {
-        pLeft->xa = -pLeft->xa;
-        pLeft->ya = -pLeft->ya;
-    } else {
-        pRight->xa = -pRight->xa;
-        pRight->ya = -pRight->ya;
-    }
-    *y1 = miRoundJoinFace (pLeft, edge1, left1);
-    *y2 = miRoundJoinFace (pRight, edge2, left2);
-}
-
-static int
-miRoundCapClip (LineFacePtr face, Boolean isInt, PolyEdgePtr edge, Boolean * leftEdge)
-{
-    int y;
-    int dx, dy;
-    double xa, ya, k;
-    Boolean left;
-
-    dx = -face->dy;
-    dy = face->dx;
-    xa = face->xa;
-    ya = face->ya;
-    k = 0.0;
-    if (!isInt)
-        k = face->k;
-    left = 1;
-    if (dy < 0 || (dy == 0 && dx > 0)) {
-        dx = -dx;
-        dy = -dy;
-        xa = -xa;
-        ya = -ya;
-        left = !left;
-    }
-    if (dx == 0 && dy == 0)
-        dy = 1;
-    if (dy == 0) {
-        y = ICEIL (face->ya) + face->y;
-        edge->x = -32767;
-        edge->stepx = 0;
-        edge->signdx = 0;
-        edge->e = -1;
-        edge->dy = 0;
-        edge->dx = 0;
-        edge->height = 0;
-    } else {
-        y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge);
-        edge->height = 32767;
-    }
-    *leftEdge = !left;
-    return y;
-}
-
-static void
-miLineArc (GCPtr pGC,
-           Boolean foreground,
-           SpanDataPtr spanData,
-           LineFacePtr leftFace, LineFacePtr rightFace, double xorg, double yorg, Boolean isInt)
-{
-    DDXPointPtr points;
-    int *widths;
-    int xorgi = 0, yorgi = 0;
-    Spans spanRec;
-    int n;
-    PolyEdgeRec edge1, edge2;
-    int edgey1, edgey2;
-    Boolean edgeleft1, edgeleft2;
-
-    if (isInt) {
-        xorgi = leftFace ? leftFace->x : rightFace->x;
-        yorgi = leftFace ? leftFace->y : rightFace->y;
-    }
-    edgey1 = 65536;
-    edgey2 = 65536;
-    edge1.x = 0;                /* not used, keep memory checkers happy */
-    edge1.dy = -1;
-    edge2.x = 0;                /* not used, keep memory checkers happy */
-    edge2.dy = -1;
-    edgeleft1 = FALSE;
-    edgeleft2 = FALSE;
-    if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) &&
-        ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
-         (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) {
-        if (isInt) {
-            xorg = (double) xorgi;
-            yorg = (double) yorgi;
-        }
-        if (leftFace && rightFace) {
-            miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
-                             &edgey1, &edgey2, &edgeleft1, &edgeleft2);
-        } else if (leftFace) {
-            edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
-        } else if (rightFace) {
-            edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
-        }
-        isInt = FALSE;
-    }
-    if (!spanData) {
-        points = (DDXPointRec *)xalloc (sizeof (DDXPointRec) * pGC->lineWidth);
-        if (!points)
-            return;
-        widths = (int *)xalloc (sizeof (int) * pGC->lineWidth);
-        if (!widths) {
-            xfree (points);
-            return;
-        }
-    } else {
-        points = (DDXPointRec *)xalloc (pGC->lineWidth * sizeof (DDXPointRec));
-        if (!points)
-            return;
-        widths = (int *)xalloc (pGC->lineWidth * sizeof (int));
-        if (!widths) {
-            xfree (points);
-            return;
-        }
-        spanRec.points = points;
-        spanRec.widths = widths;
-    }
-    if (isInt)
-        n = miLineArcI (pGC, xorgi, yorgi, points, widths);
-    else
-        n = miLineArcD (pGC, xorg, yorg, points, widths,
-                        &edge1, edgey1, edgeleft1, &edge2, edgey2, edgeleft2);
-
-    if (!spanData) {
-        (*pGC->ops->FillSpans) (pGC, n, points, widths, TRUE, foreground);
-        xfree (widths);
-        xfree (points);
-    } else {
-        spanRec.count = n;
-        AppendSpanGroup (pGC, foreground, &spanRec, spanData)
-    }
-}
-
-static void
-miLineProjectingCap (GCPtr pGC, Boolean foreground,
-                     SpanDataPtr spanData, LineFacePtr face, Boolean isLeft,
-                     double xorg, double yorg, Boolean isInt)
-{
-    int xorgi = 0, yorgi = 0;
-    int lw;
-    PolyEdgeRec lefts[2], rights[2];
-    int lefty, righty, topy, bottomy;
-    PolyEdgePtr left, right;
-    PolyEdgePtr top, bottom;
-    double xa, ya;
-    double k;
-    double xap, yap;
-    int dx, dy;
-    double projectXoff, projectYoff;
-    double maxy;
-    int finaly;
-
-    if (isInt) {
-        xorgi = face->x;
-        yorgi = face->y;
-    }
-    lw = pGC->lineWidth;
-    dx = face->dx;
-    dy = face->dy;
-    k = face->k;
-    if (dy == 0) {
-        lefts[0].height = lw;
-        lefts[0].x = xorgi;
-        if (isLeft)
-            lefts[0].x -= (lw >> 1);
-        lefts[0].stepx = 0;
-        lefts[0].signdx = 1;
-        lefts[0].e = -lw;
-        lefts[0].dx = 0;
-        lefts[0].dy = lw;
-        rights[0].height = lw;
-        rights[0].x = xorgi;
-        if (!isLeft)
-            rights[0].x += ((lw + 1) >> 1);
-        rights[0].stepx = 0;
-        rights[0].signdx = 1;
-        rights[0].e = -lw;
-        rights[0].dx = 0;
-        rights[0].dy = lw;
-        miFillPolyHelper (pGC, foreground, spanData, yorgi - (lw >> 1), lw, lefts, rights, 1, 1);
-    } else if (dx == 0) {
-        if (dy < 0) {
-            dy = -dy;
-            isLeft = !isLeft;
-        }
-        topy = yorgi;
-        bottomy = yorgi + dy;
-        if (isLeft)
-            topy -= (lw >> 1);
-        else
-            bottomy += (lw >> 1);
-        lefts[0].height = bottomy - topy;
-        lefts[0].x = xorgi - (lw >> 1);
-        lefts[0].stepx = 0;
-        lefts[0].signdx = 1;
-        lefts[0].e = -dy;
-        lefts[0].dx = dx;
-        lefts[0].dy = dy;
-
-        rights[0].height = bottomy - topy;
-        rights[0].x = lefts[0].x + (lw - 1);
-        rights[0].stepx = 0;
-        rights[0].signdx = 1;
-        rights[0].e = -dy;
-        rights[0].dx = dx;
-        rights[0].dy = dy;
-        miFillPolyHelper (pGC, foreground, spanData, topy, bottomy - topy, lefts, rights, 1, 1);
-    } else {
-        xa = face->xa;
-        ya = face->ya;
-        projectXoff = -ya;
-        projectYoff = xa;
-        if (dx < 0) {
-            right = &rights[1];
-            left = &lefts[0];
-            top = &rights[0];
-            bottom = &lefts[1];
-        } else {
-            right = &rights[0];
-            left = &lefts[1];
-            top = &lefts[0];
-            bottom = &rights[1];
-        }
-        if (isLeft) {
-            righty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 0, right);
-
-            xa = -xa;
-            ya = -ya;
-            k = -k;
-            lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
-                                     k, dx, dy, xorgi, yorgi, 1, left);
-            if (dx > 0) {
-                ya = -ya;
-                xa = -xa;
-            }
-            xap = xa - projectXoff;
-            yap = ya - projectYoff;
-            topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
-                                    -dy, dx, xorgi, yorgi, dx > 0, top);
-            bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom);
-            maxy = -ya;
-        } else {
-            righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
-                                      k, dx, dy, xorgi, yorgi, 0, right);
-
-            xa = -xa;
-            ya = -ya;
-            k = -k;
-            lefty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 1, left);
-            if (dx > 0) {
-                ya = -ya;
-                xa = -xa;
-            }
-            xap = xa - projectXoff;
-            yap = ya - projectYoff;
-            topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top);
-            bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
-                                       -dy, dx, xorgi, xorgi, dx < 0, bottom);
-            maxy = -ya + projectYoff;
-        }
-        finaly = ICEIL (maxy) + yorgi;
-        if (dx < 0) {
-            left->height = bottomy - lefty;
-            right->height = finaly - righty;
-            top->height = righty - topy;
-        } else {
-            right->height = bottomy - righty;
-            left->height = finaly - lefty;
-            top->height = lefty - topy;
-        }
-        bottom->height = finaly - bottomy;
-        miFillPolyHelper (pGC, foreground, spanData, topy,
-                          bottom->height + bottomy - topy, lefts, rights, 2, 2);
-    }
-}
-
-static void
-miWideSegment (GCPtr pGC,
-               Boolean foreground,
-               SpanDataPtr spanData,
-               int x1,
-               int y1,
-               int x2,
-               int y2,
-               Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
-{
-    double l, L, r;
-    double xa, ya;
-    double projectXoff = 0.0, projectYoff = 0.0;
-    double k;
-    double maxy;
-    int x, y;
-    int dx, dy;
-    int finaly;
-    PolyEdgePtr left, right;
-    PolyEdgePtr top, bottom;
-    int lefty, righty, topy, bottomy;
-    int signdx;
-    PolyEdgeRec lefts[2], rights[2];
-    LineFacePtr tface;
-    int lw = pGC->lineWidth;
-
-    /* draw top-to-bottom always */
-    if (y2 < y1 || (y2 == y1 && x2 < x1)) {
-        x = x1;
-        x1 = x2;
-        x2 = x;
-
-        y = y1;
-        y1 = y2;
-        y2 = y;
-
-        x = projectLeft;
-        projectLeft = projectRight;
-        projectRight = x;
-
-        tface = leftFace;
-        leftFace = rightFace;
-        rightFace = tface;
-    }
-
-    dy = y2 - y1;
-    signdx = 1;
-    dx = x2 - x1;
-    if (dx < 0)
-        signdx = -1;
-
-    leftFace->x = x1;
-    leftFace->y = y1;
-    leftFace->dx = dx;
-    leftFace->dy = dy;
-
-    rightFace->x = x2;
-    rightFace->y = y2;
-    rightFace->dx = -dx;
-    rightFace->dy = -dy;
-
-    if (dy == 0) {
-        rightFace->xa = 0;
-        rightFace->ya = (double) lw / 2.0;
-        rightFace->k = -(double) (lw * dx) / 2.0;
-        leftFace->xa = 0;
-        leftFace->ya = -rightFace->ya;
-        leftFace->k = rightFace->k;
-        x = x1;
-        if (projectLeft)
-            x -= (lw >> 1);
-        y = y1 - (lw >> 1);
-        dx = x2 - x;
-        if (projectRight)
-            dx += ((lw + 1) >> 1);
-        dy = lw;
-        miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
-    } else if (dx == 0) {
-        leftFace->xa = (double) lw / 2.0;
-        leftFace->ya = 0;
-        leftFace->k = (double) (lw * dy) / 2.0;
-        rightFace->xa = -leftFace->xa;
-        rightFace->ya = 0;
-        rightFace->k = leftFace->k;
-        y = y1;
-        if (projectLeft)
-            y -= lw >> 1;
-        x = x1 - (lw >> 1);
-        dy = y2 - y;
-        if (projectRight)
-            dy += ((lw + 1) >> 1);
-        dx = lw;
-        miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
-    } else {
-        l = ((double) lw) / 2.0;
-        L = hypot ((double) dx, (double) dy);
-
-        if (dx < 0) {
-            right = &rights[1];
-            left = &lefts[0];
-            top = &rights[0];
-            bottom = &lefts[1];
-        } else {
-            right = &rights[0];
-            left = &lefts[1];
-            top = &lefts[0];
-            bottom = &rights[1];
-        }
-        r = l / L;
-
-        /* coord of upper bound at integral y */
-        ya = -r * dx;
-        xa = r * dy;
-
-        if (projectLeft | projectRight) {
-            projectXoff = -ya;
-            projectYoff = xa;
-        }
-
-        /* xa * dy - ya * dx */
-        k = l * L;
-
-        leftFace->xa = xa;
-        leftFace->ya = ya;
-        leftFace->k = k;
-        rightFace->xa = -xa;
-        rightFace->ya = -ya;
-        rightFace->k = k;
-
-        if (projectLeft)
-            righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
-                                      k, dx, dy, x1, y1, 0, right);
-        else
-            righty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 0, right);
-
-        /* coord of lower bound at integral y */
-        ya = -ya;
-        xa = -xa;
-
-        /* xa * dy - ya * dx */
-        k = -k;
-
-        if (projectLeft)
-            lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
-                                     k, dx, dy, x1, y1, 1, left);
-        else
-            lefty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 1, left);
-
-        /* coord of top face at integral y */
-
-        if (signdx > 0) {
-            ya = -ya;
-            xa = -xa;
-        }
-
-        if (projectLeft) {
-            double xap = xa - projectXoff;
-            double yap = ya - projectYoff;
-            topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, -dy, dx, x1, y1, dx > 0, top);
-        } else
-            topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top);
-
-        /* coord of bottom face at integral y */
-
-        if (projectRight) {
-            double xap = xa + projectXoff;
-            double yap = ya + projectYoff;
-            bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
-                                       -dy, dx, x2, y2, dx < 0, bottom);
-            maxy = -ya + projectYoff;
-        } else {
-            bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x2, y2, dx < 0, bottom);
-            maxy = -ya;
-        }
-
-        finaly = ICEIL (maxy) + y2;
-
-        if (dx < 0) {
-            left->height = bottomy - lefty;
-            right->height = finaly - righty;
-            top->height = righty - topy;
-        } else {
-            right->height = bottomy - righty;
-            left->height = finaly - lefty;
-            top->height = lefty - topy;
-        }
-        bottom->height = finaly - bottomy;
-        miFillPolyHelper (pGC, foreground, spanData, topy,
-                          bottom->height + bottomy - topy, lefts, rights, 2, 2);
-    }
-}
-
-static SpanDataPtr
-miSetupSpanData (GCPtr pGC, SpanDataPtr spanData, int npt)
-{
-    if ((npt < 3 && pGC->capStyle != CapRound) || miSpansEasyRop (pGC->alu))
-        return (SpanDataPtr) NULL;
-    if (pGC->lineStyle == LineDoubleDash)
-        miInitSpanGroup (&spanData->bgGroup);
-    miInitSpanGroup (&spanData->fgGroup);
-    return spanData;
-}
-
-static void
-miCleanupSpanData (GCPtr pGC, SpanDataPtr spanData)
-{
-    if (pGC->lineStyle == LineDoubleDash) {
-        miFillUniqueSpanGroup (pGC, &spanData->bgGroup, FALSE);
-        miFreeSpanGroup (&spanData->bgGroup);
-    }
-    miFillUniqueSpanGroup (pGC, &spanData->fgGroup, TRUE);
-    miFreeSpanGroup (&spanData->fgGroup);
-}
-
-void
-miWideLine (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
-{
-    int x1, y1, x2, y2;
-    SpanDataRec spanDataRec;
-    SpanDataPtr spanData;
-    Boolean projectLeft, projectRight;
-    LineFaceRec leftFace, rightFace, prevRightFace;
-    LineFaceRec firstFace;
-    int first;
-    Boolean somethingDrawn = FALSE;
-    Boolean selfJoin;
-
-    spanData = miSetupSpanData (pGC, &spanDataRec, npt);
-    x2 = pPts->x;
-    y2 = pPts->y;
-    first = TRUE;
-    selfJoin = FALSE;
-    if (npt > 1) {
-        if (mode == CoordModePrevious) {
-            int nptTmp;
-            DDXPointPtr pPtsTmp;
-
-            x1 = x2;
-            y1 = y2;
-            nptTmp = npt;
-            pPtsTmp = pPts + 1;
-            while (--nptTmp) {
-                x1 += pPtsTmp->x;
-                y1 += pPtsTmp->y;
-                ++pPtsTmp;
-            }
-            if (x2 == x1 && y2 == y1)
-                selfJoin = TRUE;
-        } else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) {
-            selfJoin = TRUE;
-        }
-    }
-    projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
-    projectRight = FALSE;
-    while (--npt) {
-        x1 = x2;
-        y1 = y2;
-        ++pPts;
-        x2 = pPts->x;
-        y2 = pPts->y;
-        if (mode == CoordModePrevious) {
-            x2 += x1;
-            y2 += y1;
-        }
-        if (x1 != x2 || y1 != y2) {
-            somethingDrawn = TRUE;
-            if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin)
-                projectRight = TRUE;
-            miWideSegment (pGC, TRUE, spanData, x1, y1, x2, y2,
-                           projectLeft, projectRight, &leftFace, &rightFace);
-            if (first) {
-                if (selfJoin)
-                    firstFace = leftFace;
-                else if (pGC->capStyle == CapRound) {
-                    if (pGC->lineWidth == 1 && !spanData)
-                        miLineOnePoint (pGC, TRUE, spanData, x1, y1);
-                    else
-                        miLineArc (pGC, TRUE, spanData,
-                                   &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
-                }
-            } else {
-                miLineJoin (pGC, TRUE, spanData, &leftFace, &prevRightFace);
-            }
-            prevRightFace = rightFace;
-            first = FALSE;
-            projectLeft = FALSE;
-        }
-        if (npt == 1 && somethingDrawn) {
-            if (selfJoin)
-                miLineJoin (pGC, TRUE, spanData, &firstFace, &rightFace);
-            else if (pGC->capStyle == CapRound) {
-                if (pGC->lineWidth == 1 && !spanData)
-                    miLineOnePoint (pGC, TRUE, spanData, x2, y2);
-                else
-                    miLineArc (pGC, TRUE, spanData,
-                               (LineFacePtr) NULL, &rightFace, (double) 0.0, (double) 0.0, TRUE);
-            }
-        }
-    }
-    /* handle crock where all points are coincedent */
-    if (!somethingDrawn) {
-        projectLeft = pGC->capStyle == CapProjecting;
-        miWideSegment (pGC, TRUE, spanData,
-                       x2, y2, x2, y2, projectLeft, projectLeft, &leftFace, &rightFace);
-        if (pGC->capStyle == CapRound) {
-            miLineArc (pGC, TRUE, spanData,
-                       &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
-            rightFace.dx = -1;  /* sleezy hack to make it work */
-            miLineArc (pGC, TRUE, spanData,
-                       (LineFacePtr) NULL, &rightFace, (double) 0.0, (double) 0.0, TRUE);
-        }
-    }
-    if (spanData)
-        miCleanupSpanData (pGC, spanData);
-}
-
-#define V_TOP       0
-#define V_RIGHT     1
-#define V_BOTTOM    2
-#define V_LEFT      3
-
-static void
-miWideDashSegment (GCPtr pGC,
-                   SpanDataPtr spanData,
-                   int *pDashOffset,
-                   int *pDashIndex,
-                   int x1,
-                   int y1,
-                   int x2,
-                   int y2,
-                   Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
-{
-    int dashIndex, dashRemain;
-    unsigned char *pDash;
-    double L, l;
-    double k;
-    PolyVertexRec vertices[4];
-    PolyVertexRec saveRight = { 0 }, saveBottom;
-    PolySlopeRec slopes[4];
-    PolyEdgeRec left[2], right[2];
-    LineFaceRec lcapFace, rcapFace;
-    int nleft, nright;
-    int h;
-    int y;
-    int dy, dx;
-    Boolean foreground;
-    double LRemain;
-    double r;
-    double rdx, rdy;
-    double dashDx, dashDy;
-    double saveK = 0.0;
-    Boolean first = TRUE;
-    double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0;
-
-    dx = x2 - x1;
-    dy = y2 - y1;
-    dashIndex = *pDashIndex;
-    pDash = pGC->dash;
-    dashRemain = pDash[dashIndex] - *pDashOffset;
-
-    l = ((double) pGC->lineWidth) / 2.0;
-    if (dx == 0) {
-        L = dy;
-        rdx = 0;
-        rdy = l;
-        if (dy < 0) {
-            L = -dy;
-            rdy = -l;
-        }
-    } else if (dy == 0) {
-        L = dx;
-        rdx = l;
-        rdy = 0;
-        if (dx < 0) {
-            L = -dx;
-            rdx = -l;
-        }
-    } else {
-        L = hypot ((double) dx, (double) dy);
-        r = l / L;
-
-        rdx = r * dx;
-        rdy = r * dy;
-    }
-    k = l * L;
-    LRemain = L;
-    /* All position comments are relative to a line with dx and dy > 0,
-     * but the code does not depend on this */
-    /* top */
-    slopes[V_TOP].dx = dx;
-    slopes[V_TOP].dy = dy;
-    slopes[V_TOP].k = k;
-    /* right */
-    slopes[V_RIGHT].dx = -dy;
-    slopes[V_RIGHT].dy = dx;
-    slopes[V_RIGHT].k = 0;
-    /* bottom */
-    slopes[V_BOTTOM].dx = -dx;
-    slopes[V_BOTTOM].dy = -dy;
-    slopes[V_BOTTOM].k = k;
-    /* left */
-    slopes[V_LEFT].dx = dy;
-    slopes[V_LEFT].dy = -dx;
-    slopes[V_LEFT].k = 0;
-
-    /* preload the start coordinates */
-    vertices[V_RIGHT].x = vertices[V_TOP].x = rdy;
-    vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx;
-
-    vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy;
-    vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx;
-
-    if (projectLeft) {
-        vertices[V_TOP].x -= rdx;
-        vertices[V_TOP].y -= rdy;
-
-        vertices[V_LEFT].x -= rdx;
-        vertices[V_LEFT].y -= rdy;
-
-        slopes[V_LEFT].k = rdx * dx + rdy * dy;
-    }
-
-    lcenterx = x1;
-    lcentery = y1;
-
-    if (pGC->capStyle == CapRound) {
-        lcapFace.dx = dx;
-        lcapFace.dy = dy;
-        lcapFace.x = x1;
-        lcapFace.y = y1;
-
-        rcapFace.dx = -dx;
-        rcapFace.dy = -dy;
-        rcapFace.x = x1;
-        rcapFace.y = y1;
-    }
-    while (LRemain > dashRemain) {
-        dashDx = (dashRemain * dx) / L;
-        dashDy = (dashRemain * dy) / L;
-
-        rcenterx = lcenterx + dashDx;
-        rcentery = lcentery + dashDy;
-
-        vertices[V_RIGHT].x += dashDx;
-        vertices[V_RIGHT].y += dashDy;
-
-        vertices[V_BOTTOM].x += dashDx;
-        vertices[V_BOTTOM].y += dashDy;
-
-        slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy;
-
-        if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) {
-            if (pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapProjecting) {
-                saveRight = vertices[V_RIGHT];
-                saveBottom = vertices[V_BOTTOM];
-                saveK = slopes[V_RIGHT].k;
-
-                if (!first) {
-                    vertices[V_TOP].x -= rdx;
-                    vertices[V_TOP].y -= rdy;
-
-                    vertices[V_LEFT].x -= rdx;
-                    vertices[V_LEFT].y -= rdy;
-
-                    slopes[V_LEFT].k = vertices[V_LEFT].x *
-                        slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
-                }
-
-                vertices[V_RIGHT].x += rdx;
-                vertices[V_RIGHT].y += rdy;
-
-                vertices[V_BOTTOM].x += rdx;
-                vertices[V_BOTTOM].y += rdy;
-
-                slopes[V_RIGHT].k = vertices[V_RIGHT].x *
-                    slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
-            }
-            y = miPolyBuildPoly (vertices, slopes, 4, x1, y1, left, right, &nleft, &nright, &h);
-            foreground = (dashIndex & 1) == 0;
-            miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
-
-            if (pGC->lineStyle == LineOnOffDash) {
-                switch (pGC->capStyle) {
-                case CapProjecting:
-                    vertices[V_BOTTOM] = saveBottom;
-                    vertices[V_RIGHT] = saveRight;
-                    slopes[V_RIGHT].k = saveK;
-                    break;
-                case CapRound:
-                    if (!first) {
-                        if (dx < 0) {
-                            lcapFace.xa = -vertices[V_LEFT].x;
-                            lcapFace.ya = -vertices[V_LEFT].y;
-                            lcapFace.k = slopes[V_LEFT].k;
-                        } else {
-                            lcapFace.xa = vertices[V_TOP].x;
-                            lcapFace.ya = vertices[V_TOP].y;
-                            lcapFace.k = -slopes[V_LEFT].k;
-                        }
-                        miLineArc (pGC, foreground, spanData,
-                                   &lcapFace, (LineFacePtr) NULL, lcenterx, lcentery, FALSE);
-                    }
-                    if (dx < 0) {
-                        rcapFace.xa = vertices[V_BOTTOM].x;
-                        rcapFace.ya = vertices[V_BOTTOM].y;
-                        rcapFace.k = slopes[V_RIGHT].k;
-                    } else {
-                        rcapFace.xa = -vertices[V_RIGHT].x;
-                        rcapFace.ya = -vertices[V_RIGHT].y;
-                        rcapFace.k = -slopes[V_RIGHT].k;
-                    }
-                    miLineArc (pGC, foreground, spanData,
-                               (LineFacePtr) NULL, &rcapFace, rcenterx, rcentery, FALSE);
-                    break;
-                }
-            }
-        }
-        LRemain -= dashRemain;
-        ++dashIndex;
-        if (dashIndex == pGC->numInDashList)
-            dashIndex = 0;
-        dashRemain = pDash[dashIndex];
-
-        lcenterx = rcenterx;
-        lcentery = rcentery;
-
-        vertices[V_TOP] = vertices[V_RIGHT];
-        vertices[V_LEFT] = vertices[V_BOTTOM];
-        slopes[V_LEFT].k = -slopes[V_RIGHT].k;
-        first = FALSE;
-    }
-
-    if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) {
-        vertices[V_TOP].x -= dx;
-        vertices[V_TOP].y -= dy;
-
-        vertices[V_LEFT].x -= dx;
-        vertices[V_LEFT].y -= dy;
-
-        vertices[V_RIGHT].x = rdy;
-        vertices[V_RIGHT].y = -rdx;
-
-        vertices[V_BOTTOM].x = -rdy;
-        vertices[V_BOTTOM].y = rdx;
-
-
-        if (projectRight) {
-            vertices[V_RIGHT].x += rdx;
-            vertices[V_RIGHT].y += rdy;
-
-            vertices[V_BOTTOM].x += rdx;
-            vertices[V_BOTTOM].y += rdy;
-            slopes[V_RIGHT].k = vertices[V_RIGHT].x *
-                slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
-        } else
-            slopes[V_RIGHT].k = 0;
-
-        if (!first && pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapProjecting) {
-            vertices[V_TOP].x -= rdx;
-            vertices[V_TOP].y -= rdy;
-
-            vertices[V_LEFT].x -= rdx;
-            vertices[V_LEFT].y -= rdy;
-            slopes[V_LEFT].k = vertices[V_LEFT].x *
-                slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
-        } else
-            slopes[V_LEFT].k += dx * dx + dy * dy;
-
-
-        y = miPolyBuildPoly (vertices, slopes, 4, x2, y2, left, right, &nleft, &nright, &h);
-
-        foreground = (dashIndex & 1) == 0;
-        miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
-        if (!first && pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapRound) {
-            lcapFace.x = x2;
-            lcapFace.y = y2;
-            if (dx < 0) {
-                lcapFace.xa = -vertices[V_LEFT].x;
-                lcapFace.ya = -vertices[V_LEFT].y;
-                lcapFace.k = slopes[V_LEFT].k;
-            } else {
-                lcapFace.xa = vertices[V_TOP].x;
-                lcapFace.ya = vertices[V_TOP].y;
-                lcapFace.k = -slopes[V_LEFT].k;
-            }
-            miLineArc (pGC, foreground, spanData,
-                       &lcapFace, (LineFacePtr) NULL, rcenterx, rcentery, FALSE);
-        }
-    }
-    dashRemain = (int)(((double) dashRemain) - LRemain);
-    if (dashRemain == 0) {
-        dashIndex++;
-        if (dashIndex == pGC->numInDashList)
-            dashIndex = 0;
-        dashRemain = pDash[dashIndex];
-    }
-
-    leftFace->x = x1;
-    leftFace->y = y1;
-    leftFace->dx = dx;
-    leftFace->dy = dy;
-    leftFace->xa = rdy;
-    leftFace->ya = -rdx;
-    leftFace->k = k;
-
-    rightFace->x = x2;
-    rightFace->y = y2;
-    rightFace->dx = -dx;
-    rightFace->dy = -dy;
-    rightFace->xa = -rdy;
-    rightFace->ya = rdx;
-    rightFace->k = k;
-
-    *pDashIndex = dashIndex;
-    *pDashOffset = pDash[dashIndex] - dashRemain;
-}
-
-void
-miWideDash (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
-{
-    int x1, y1, x2, y2;
-    Boolean foreground;
-    Boolean projectLeft, projectRight;
-    LineFaceRec leftFace, rightFace, prevRightFace;
-    LineFaceRec firstFace;
-    int first;
-    int dashIndex, dashOffset;
-    int prevDashIndex;
-    SpanDataRec spanDataRec;
-    SpanDataPtr spanData;
-    Boolean somethingDrawn = FALSE;
-    Boolean selfJoin;
-    Boolean endIsFg = FALSE, startIsFg = FALSE;
-    Boolean firstIsFg = FALSE, prevIsFg = FALSE;
-
-    if (npt == 0)
-        return;
-    spanData = miSetupSpanData (pGC, &spanDataRec, npt);
-    x2 = pPts->x;
-    y2 = pPts->y;
-    first = TRUE;
-    selfJoin = FALSE;
-    if (mode == CoordModePrevious) {
-        int nptTmp;
-        DDXPointPtr pPtsTmp;
-
-        x1 = x2;
-        y1 = y2;
-        nptTmp = npt;
-        pPtsTmp = pPts + 1;
-        while (--nptTmp) {
-            x1 += pPtsTmp->x;
-            y1 += pPtsTmp->y;
-            ++pPtsTmp;
-        }
-        if (x2 == x1 && y2 == y1)
-            selfJoin = TRUE;
-    } else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) {
-        selfJoin = TRUE;
-    }
-    projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
-    projectRight = FALSE;
-    dashIndex = 0;
-    dashOffset = 0;
-    miStepDash ((int) pGC->dashOffset, &dashIndex,
-                pGC->dash, (int) pGC->numInDashList, &dashOffset);
-    while (--npt) {
-        x1 = x2;
-        y1 = y2;
-        ++pPts;
-        x2 = pPts->x;
-        y2 = pPts->y;
-        if (mode == CoordModePrevious) {
-            x2 += x1;
-            y2 += y1;
-        }
-        if (x1 != x2 || y1 != y2) {
-            somethingDrawn = TRUE;
-            if (npt == 1 && pGC->capStyle == CapProjecting && (!selfJoin || !firstIsFg))
-                projectRight = TRUE;
-            prevDashIndex = dashIndex;
-            miWideDashSegment (pGC, spanData, &dashOffset, &dashIndex,
-                               x1, y1, x2, y2, projectLeft, projectRight, &leftFace, &rightFace);
-            startIsFg = !(prevDashIndex & 1);
-            endIsFg = (dashIndex & 1) ^ (dashOffset != 0);
-            if (pGC->lineStyle == LineDoubleDash || startIsFg) {
-                foreground = startIsFg;
-                if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg)) {
-                    if (first && selfJoin) {
-                        firstFace = leftFace;
-                        firstIsFg = startIsFg;
-                    } else if (pGC->capStyle == CapRound)
-                        miLineArc (pGC, foreground, spanData,
-                                   &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
-                } else {
-                    miLineJoin (pGC, foreground, spanData, &leftFace, &prevRightFace);
-                }
-            }
-            prevRightFace = rightFace;
-            prevIsFg = endIsFg;
-            first = FALSE;
-            projectLeft = FALSE;
-        }
-        if (npt == 1 && somethingDrawn) {
-            if (pGC->lineStyle == LineDoubleDash || endIsFg) {
-                foreground = endIsFg;
-                if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg)) {
-                    miLineJoin (pGC, foreground, spanData, &firstFace, &rightFace);
-                } else {
-                    if (pGC->capStyle == CapRound)
-                        miLineArc (pGC, foreground, spanData,
-                                   (LineFacePtr) NULL, &rightFace,
-                                   (double) 0.0, (double) 0.0, TRUE);
-                }
-            } else {
-                /* glue a cap to the start of the line if
-                 * we're OnOffDash and ended on odd dash
-                 */
-                if (selfJoin && firstIsFg) {
-                    foreground = TRUE;
-                    if (pGC->capStyle == CapProjecting)
-                        miLineProjectingCap (pGC, foreground, spanData,
-                                             &firstFace, TRUE, (double) 0.0, (double) 0.0, TRUE);
-                    else if (pGC->capStyle == CapRound)
-                        miLineArc (pGC, foreground, spanData,
-                                   &firstFace, (LineFacePtr) NULL,
-                                   (double) 0.0, (double) 0.0, TRUE);
-                }
-            }
-        }
-    }
-    /* handle crock where all points are coincident */
-    if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))) {
-        /* not the same as endIsFg computation above */
-        foreground = (dashIndex & 1) == 0;
-        switch (pGC->capStyle) {
-        case CapRound:
-            miLineArc (pGC, foreground, spanData,
-                       (LineFacePtr) NULL, (LineFacePtr) NULL, (double) x2, (double) y2, FALSE);
-            break;
-        case CapProjecting:
-            x1 = pGC->lineWidth;
-            miFillRectPolyHelper (pGC, foreground, spanData,
-                                  x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1);
-            break;
-        }
-    }
-    if (spanData)
-        miCleanupSpanData (pGC, spanData);
-}
-
-#undef ExchangeSpans
-#define ExchangeSpans(a, b)                                 \
-{                                                           \
-    DDXPointRec tpt;                                        \
-    int         tw;                                         \
-                                                            \
-    tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt;    \
-    tw = widths[a]; widths[a] = widths[b]; widths[b] = tw;  \
-}
-
-static void QuickSortSpans(
-    DDXPointRec spans[],
-    int         widths[],
-    int         numSpans)
-{
-    int     y;
-    int     i, j, m;
-    DDXPointPtr    r;
-
-    /* Always called with numSpans > 1 */
-    /* Sorts only by y, doesn't bother to sort by x */
-
-    do
-    {
-        if (numSpans < 9)
-        {
-            /* Do insertion sort */
-            int yprev;
-
-            yprev = spans[0].y;
-            i = 1;
-            do
-            { /* while i != numSpans */
-                y = spans[i].y;
-                if (yprev > y)
-                {
-                    /* spans[i] is out of order.  Move into proper location. */
-                    DDXPointRec tpt;
-                    int     tw, k;
-
-                    for (j = 0; y >= spans[j].y; j++) {}
-                    tpt = spans[i];
-                    tw  = widths[i];
-                    for (k = i; k != j; k--)
-                    {
-                        spans[k] = spans[k-1];
-                        widths[k] = widths[k-1];
-                    }
-                    spans[j] = tpt;
-                    widths[j] = tw;
-                    y = spans[i].y;
-                } /* if out of order */
-                yprev = y;
-                i++;
-            } while (i != numSpans);
-            return;
-        }
-
-        /* Choose partition element, stick in location 0 */
-        m = numSpans / 2;
-        if (spans[m].y > spans[0].y)            ExchangeSpans(m, 0);
-        if (spans[m].y > spans[numSpans-1].y)   ExchangeSpans(m, numSpans-1);
-        if (spans[m].y > spans[0].y)            ExchangeSpans(m, 0);
-        y = spans[0].y;
-
-        /* Partition array */
-        i = 0;
-        j = numSpans;
-        do
-        {
-            r = &(spans[i]);
-            do
-            {
-                r++;
-                i++;
-            } while (i != numSpans && r->y < y);
-            r = &(spans[j]);
-            do
-            {
-                r--;
-                j--;
-            } while (y < r->y);
-            if (i < j)
-                ExchangeSpans(i, j);
-        } while (i < j);
-
-        /* Move partition element back to middle */
-        ExchangeSpans(0, j);
-
-        /* Recurse */
-        if (numSpans-j-1 > 1)
-            QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
-        numSpans = j;
-    } while (numSpans > 1);
-}
-
-#define NextBand()                                                  \
-{                                                                   \
-    clipy1 = pboxBandStart->y1;                                     \
-    clipy2 = pboxBandStart->y2;                                     \
-    pboxBandEnd = pboxBandStart + 1;                                \
-    while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) {  \
-        pboxBandEnd++;                                              \
-    }                                                               \
-    for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
-}
-
-/*
-    Clip a list of scanlines to a region.  The caller has allocated the
-    space.  FSorted is non-zero if the scanline origins are in ascending
-    order.
-    returns the number of new, clipped scanlines.
-*/
-
-int spice_canvas_clip_spans(pixman_region32_t *prgnDst,
-                            DDXPointPtr ppt,
-                            int         *pwidth,
-                            int                 nspans,
-                            DDXPointPtr         pptNew,
-                            int                 *pwidthNew,
-                            int                 fSorted)
-{
-    DDXPointPtr pptLast;
-    int         *pwidthNewStart;        /* the vengeance of Xerox! */
-    int         y, x1, x2;
-    int         numRects;
-    pixman_box32_t *pboxBandStart;
-
-    pptLast = ppt + nspans;
-    pwidthNewStart = pwidthNew;
-
-    pboxBandStart = pixman_region32_rectangles (prgnDst, &numRects);
-
-    if (numRects == 1) {
-        /* Do special fast code with clip boundaries in registers(?) */
-        /* It doesn't pay much to make use of fSorted in this case,
-           so we lump everything together. */
-
-        int clipx1, clipx2, clipy1, clipy2;
-
-        clipx1 = pboxBandStart->x1;
-        clipy1 = pboxBandStart->y1;
-        clipx2 = pboxBandStart->x2;
-        clipy2 = pboxBandStart->y2;
-
-        for (; ppt != pptLast; ppt++, pwidth++) {
-            y = ppt->y;
-            x1 = ppt->x;
-            if (clipy1 <= y && y < clipy2) {
-                x2 = x1 + *pwidth;
-                if (x1 < clipx1)
-                    x1 = clipx1;
-                if (x2 > clipx2)
-                    x2 = clipx2;
-                if (x1 < x2) {
-                    /* part of span in clip rectangle */
-                    pptNew->x = x1;
-                    pptNew->y = y;
-                    *pwidthNew = x2 - x1;
-                    pptNew++;
-                    pwidthNew++;
-                }
-            }
-        } /* end for */
-    } else if (numRects != 0) {
-        /* Have to clip against many boxes */
-        pixman_box32_t *pboxBandEnd, *pbox, *pboxLast;
-        int clipy1, clipy2;
-
-        /* In this case, taking advantage of sorted spans gains more than
-           the sorting costs. */
-        if ((! fSorted) && (nspans > 1))
-            QuickSortSpans(ppt, pwidth, nspans);
-
-        pboxLast = pboxBandStart + numRects;
-
-        NextBand();
-
-        for (; ppt != pptLast; ) {
-            y = ppt->y;
-            if (y < clipy2) {
-                /* span is in the current band */
-                pbox = pboxBandStart;
-                x1 = ppt->x;
-                x2 = x1 + *pwidth;
-                do { /* For each box in band */
-                    int newx1, newx2;
-
-                    newx1 = x1;
-                    newx2 = x2;
-                    if (newx1 < pbox->x1)
-                        newx1 = pbox->x1;
-                    if (newx2 > pbox->x2)
-                        newx2 = pbox->x2;
-                    if (newx1 < newx2) {
-                        /* Part of span in clip rectangle */
-                        pptNew->x = newx1;
-                        pptNew->y = y;
-                        *pwidthNew = newx2 - newx1;
-                        pptNew++;
-                        pwidthNew++;
-                    }
-                    pbox++;
-                } while (pbox != pboxBandEnd);
-                ppt++;
-                pwidth++;
-            } else {
-                /* Move to next band, adjust ppt as needed */
-                pboxBandStart = pboxBandEnd;
-                if (pboxBandStart == pboxLast)
-                    break; /* We're completely done */
-                NextBand();
-            }
-        }
-    }
-    return (pwidthNew - pwidthNewStart);
-}
diff --git a/common/lines.h b/common/lines.h
deleted file mode 100644
index 1d092f0..0000000
--- a/common/lines.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef LINES_H
-#define LINES_H
-
-#include <pixman_utils.h>
-#include <stdlib.h>
-#include <string.h>
-#include "draw.h"
-
-typedef struct lineGC lineGC;
-
-typedef struct {
-    void (*FillSpans)(lineGC * pGC,
-                      int num_spans, SpicePoint * points, int *widths,
-                      int sorted, int foreground);
-    void (*FillRects)(lineGC * pGC,
-                      int nun_rects, pixman_rectangle32_t * rects,
-                      int foreground);
-} lineGCOps;
-
-struct lineGC {
-    int width;
-    int height;
-    unsigned char alu;
-    unsigned short lineWidth;
-    unsigned short dashOffset;
-    unsigned short numInDashList;
-    unsigned char *dash;
-    unsigned int lineStyle:2;
-    unsigned int capStyle:2;
-    unsigned int joinStyle:2;
-    lineGCOps *ops;
-};
-
-/* CoordinateMode for drawing routines */
-
-#define CoordModeOrigin         0       /* relative to the origin */
-#define CoordModePrevious       1       /* relative to previous point */
-
-/* LineStyle */
-
-#define LineSolid               0
-#define LineOnOffDash           1
-#define LineDoubleDash          2
-
-/* capStyle */
-
-#define CapNotLast              0
-#define CapButt                 1
-#define CapRound                2
-#define CapProjecting           3
-
-/* joinStyle */
-
-#define JoinMiter               0
-#define JoinRound               1
-#define JoinBevel               2
-
-extern void spice_canvas_zero_line(lineGC *pgc,
-                                   int mode,
-                                   int num_points,
-                                   SpicePoint * points);
-extern void spice_canvas_zero_dash_line(lineGC * pgc,
-                                        int mode,
-                                        int n_points,
-                                        SpicePoint * points);
-extern void spice_canvas_wide_dash_line(lineGC * pGC,
-                                        int mode,
-                                        int num_points,
-                                        SpicePoint * points);
-extern void spice_canvas_wide_line(lineGC *pGC,
-                                   int mode,
-                                   int num_points,
-                                   SpicePoint * points);
-extern int spice_canvas_clip_spans(pixman_region32_t *clip_region,
-                                   SpicePoint *points,
-                                   int *widths,
-                                   int num_spans,
-                                   SpicePoint *new_points,
-                                   int *new_widths,
-                                   int sorted);
-
-#endif /* LINES_H */
diff --git a/common/lz.c b/common/lz.c
deleted file mode 100644
index d0d9511..0000000
--- a/common/lz.c
+++ /dev/null
@@ -1,738 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright 2009 Red Hat, Inc. and/or its affiliates.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-
- This file incorporates work covered by the following copyright and
- permission notice:
-   Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
-
-   Permission is hereby granted, free of charge, to any person
-   obtaining a copy of this software and associated documentation
-   files (the "Software"), to deal in the Software without
-   restriction, including without limitation the rights to use, copy,
-   modify, merge, publish, distribute, sublicense, and/or sell copies
-   of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be
-   included in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-
-*/
-
-#include "lz.h"
-
-#define DEBUG
-
-#ifdef DEBUG
-
-#define ASSERT(usr, x) \
-    if (!(x)) (usr)->error(usr, "%s: ASSERT %s failed\n", __FUNCTION__, #x);
-
-#else
-
-#define ASSERT(usr, x)
-
-#endif
-
-#define HASH_LOG 13
-#define HASH_SIZE (1 << HASH_LOG)
-#define HASH_MASK (HASH_SIZE - 1)
-
-
-typedef struct LzImageSegment LzImageSegment;
-struct LzImageSegment {
-    uint8_t            *lines;
-    uint8_t            *lines_end;
-    unsigned int size_delta;    // total size of the previous segments in units of
-                                // pixels for rgb and bytes for plt.
-    LzImageSegment    *next;
-};
-
-//    TODO: pack?
-typedef struct HashEntry {
-    LzImageSegment    *image_seg;
-    uint8_t            *ref;
-} HashEntry;
-
-typedef struct Encoder {
-    LzUsrContext    *usr;
-
-    LzImageType type;
-    const SpicePalette    *palette;    // for decoding images with palettes to rgb
-    int stride;                       // stride is in bytes. For rgb must be equal to
-                                      // width*bytes_per_pix.
-    // For palettes stride can be bigger than width/pixels_per_byte by 1 only if
-    // width%pixels_per_byte != 0.
-    int height;
-    int width;                       // the original width (in pixels)
-
-    LzImageSegment *head_image_segs;
-    LzImageSegment *tail_image_segs;
-    LzImageSegment *free_image_segs;
-
-    // the dictionary hash table is composed (1) a pointer to the segment the word was found in
-    // (2) a pointer to the first byte in the segment that matches the word
-    HashEntry htab[HASH_SIZE];
-
-    uint8_t            *io_start;
-    uint8_t            *io_now;
-    uint8_t            *io_end;
-    size_t io_bytes_count;
-
-    uint8_t            *io_last_copy;  // pointer to the last byte in which copy count was written
-} Encoder;
-
-/****************************************************/
-/* functions for managing the pool of image segments*/
-/****************************************************/
-static INLINE LzImageSegment *lz_alloc_image_seg(Encoder *encoder);
-static void lz_reset_image_seg(Encoder *encoder);
-static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
-                                  unsigned int num_first_lines);
-
-
-// return a free image segment if one exists. Make allocation if needed. adds it to the
-// tail of the image segments lists
-static INLINE LzImageSegment *lz_alloc_image_seg(Encoder *encoder)
-{
-    LzImageSegment *ret;
-
-    if (encoder->free_image_segs) {
-        ret = encoder->free_image_segs;
-        encoder->free_image_segs = ret->next;
-    } else {
-        if (!(ret = (LzImageSegment *)encoder->usr->malloc(encoder->usr, sizeof(*ret)))) {
-            return NULL;
-        }
-    }
-
-    ret->next = NULL;
-    if (encoder->tail_image_segs) {
-        encoder->tail_image_segs->next = ret;
-    }
-    encoder->tail_image_segs = ret;
-
-    if (!encoder->head_image_segs) {
-        encoder->head_image_segs = ret;
-    }
-
-    return ret;
-}
-
-// adding seg to the head of free segments (lz_reset_image_seg removes it from used ones)
-static INLINE void __lz_free_image_seg(Encoder *encoder, LzImageSegment *seg)
-{
-    seg->next = encoder->free_image_segs;
-    encoder->free_image_segs = seg;
-}
-
-// moves all the used image segments to the free pool
-static void lz_reset_image_seg(Encoder *encoder)
-{
-    while (encoder->head_image_segs) {
-        LzImageSegment *seg = encoder->head_image_segs;
-        encoder->head_image_segs = seg->next;
-        __lz_free_image_seg(encoder, seg);
-    }
-    encoder->tail_image_segs = NULL;
-}
-
-static void lz_dealloc_free_segments(Encoder *encoder)
-{
-    while (encoder->free_image_segs) {
-        LzImageSegment *seg = encoder->free_image_segs;
-        encoder->free_image_segs = seg->next;
-        encoder->usr->free(encoder->usr, seg);
-    }
-}
-
-// return FALSE when operation fails (due to failure in allocation)
-static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
-                                  unsigned int num_first_lines)
-{
-    LzImageSegment *image_seg;
-    uint32_t size_delta = 0;
-    unsigned int num_lines = num_first_lines;
-    uint8_t* lines = first_lines;
-    int row;
-
-    ASSERT(encoder->usr, !encoder->head_image_segs);
-
-    image_seg = lz_alloc_image_seg(encoder);
-    if (!image_seg) {
-        goto error_1;
-    }
-
-    image_seg->lines = lines;
-    image_seg->lines_end = lines + num_lines * encoder->stride;
-    image_seg->size_delta = size_delta;
-
-    size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
-
-    for (row = num_first_lines; row < encoder->height; row += num_lines) {
-        num_lines = encoder->usr->more_lines(encoder->usr, &lines);
-        if (num_lines <= 0) {
-            encoder->usr->error(encoder->usr, "more lines failed\n");
-        }
-        image_seg = lz_alloc_image_seg(encoder);
-
-        if (!image_seg) {
-            goto error_1;
-        }
-
-        image_seg->lines = lines;
-        image_seg->lines_end = lines + num_lines * encoder->stride;
-        image_seg->size_delta = size_delta;
-
-        size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
-    }
-
-    return TRUE;
-error_1:
-    lz_reset_image_seg(encoder);
-    return FALSE;
-}
-
-/**************************************************************************
-* Handling encoding and decoding of a byte
-***************************************************************************/
-static INLINE int more_io_bytes(Encoder *encoder)
-{
-    uint8_t *io_ptr;
-    int num_io_bytes = encoder->usr->more_space(encoder->usr, &io_ptr);
-    encoder->io_bytes_count += num_io_bytes;
-    encoder->io_now = io_ptr;
-    encoder->io_end = encoder->io_now + num_io_bytes;
-    return num_io_bytes;
-}
-
-static INLINE void encode(Encoder *encoder, uint8_t byte)
-{
-    if (encoder->io_now == encoder->io_end) {
-        if (more_io_bytes(encoder) <= 0) {
-            encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
-        }
-        ASSERT(encoder->usr, encoder->io_now);
-    }
-
-    ASSERT(encoder->usr, encoder->io_now < encoder->io_end);
-    *(encoder->io_now++) = byte;
-}
-
-static INLINE void encode_32(Encoder *encoder, unsigned int word)
-{
-    encode(encoder, (uint8_t)(word >> 24));
-    encode(encoder, (uint8_t)(word >> 16) & 0x0000ff);
-    encode(encoder, (uint8_t)(word >> 8) & 0x0000ff);
-    encode(encoder, (uint8_t)(word & 0x0000ff));
-}
-
-static INLINE void encode_copy_count(Encoder *encoder, uint8_t copy_count)
-{
-    encode(encoder, copy_count);
-    encoder->io_last_copy = encoder->io_now - 1; // io_now cannot be the first byte of the buffer
-}
-
-static INLINE void update_copy_count(Encoder *encoder, uint8_t copy_count)
-{
-    ASSERT(encoder->usr, encoder->io_last_copy);
-    *(encoder->io_last_copy) = copy_count;
-}
-
-static INLINE void encode_level(Encoder *encoder, uint8_t level_code)
-{
-    *(encoder->io_start) |= level_code;
-}
-
-// decrease the io ptr by 1
-static INLINE void compress_output_prev(Encoder *encoder)
-{
-    // io_now cannot be the first byte of the buffer
-    encoder->io_now--;
-    // the function should be called only when copy count is written unnecessarily by lz_compress
-    ASSERT(encoder->usr, encoder->io_now == encoder->io_last_copy)
-}
-
-static int encoder_reset(Encoder *encoder, uint8_t *io_ptr, uint8_t *io_ptr_end)
-{
-    ASSERT(encoder->usr, io_ptr <= io_ptr_end);
-    encoder->io_bytes_count = io_ptr_end - io_ptr;
-    encoder->io_start = io_ptr;
-    encoder->io_now = io_ptr;
-    encoder->io_end = io_ptr_end;
-    encoder->io_last_copy = NULL;
-
-    return TRUE;
-}
-
-static INLINE uint8_t decode(Encoder *encoder)
-{
-    if (encoder->io_now == encoder->io_end) {
-        int num_io_bytes = more_io_bytes(encoder);
-        if (num_io_bytes <= 0) {
-            encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
-        }
-        ASSERT(encoder->usr, encoder->io_now);
-    }
-    ASSERT(encoder->usr, encoder->io_now < encoder->io_end);
-    return *(encoder->io_now++);
-}
-
-static INLINE uint32_t decode_32(Encoder *encoder)
-{
-    uint32_t word = 0;
-    word |= decode(encoder);
-    word <<= 8;
-    word |= decode(encoder);
-    word <<= 8;
-    word |= decode(encoder);
-    word <<= 8;
-    word |= decode(encoder);
-    return word;
-}
-
-static INLINE int is_io_to_decode_end(Encoder *encoder)
-{
-    if (encoder->io_now != encoder->io_end) {
-        return FALSE;
-    } else {
-        int num_io_bytes = more_io_bytes(encoder); //disable inline optimizations
-        return (num_io_bytes <= 0);
-    }
-}
-
-/*******************************************************************
-* intialization and finalization of lz
-********************************************************************/
-static int init_encoder(Encoder *encoder, LzUsrContext *usr)
-{
-    encoder->usr = usr;
-    encoder->free_image_segs = NULL;
-    encoder->head_image_segs = NULL;
-    encoder->tail_image_segs = NULL;
-    return TRUE;
-}
-
-LzContext *lz_create(LzUsrContext *usr)
-{
-    Encoder *encoder;
-
-    if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
-        !usr->free || !usr->more_space || !usr->more_lines) {
-        return NULL;
-    }
-
-    if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
-        return NULL;
-    }
-
-    if (!init_encoder(encoder, usr)) {
-        usr->free(usr, encoder);
-        return NULL;
-    }
-    return (LzContext *)encoder;
-}
-
-void lz_destroy(LzContext *lz)
-{
-    Encoder *encoder = (Encoder *)lz;
-
-    if (!lz) {
-        return;
-    }
-
-    if (encoder->head_image_segs) {
-        encoder->usr->error(encoder->usr, "%s: used_image_segments not empty\n", __FUNCTION__);
-        lz_reset_image_seg(encoder);
-    }
-    lz_dealloc_free_segments(encoder);
-
-    encoder->usr->free(encoder->usr, encoder);
-}
-
-/*******************************************************************
-*                encoding and decoding the image
-********************************************************************/
-/*
- * Give hints to the compiler for branch prediction optimization.
- */
-#if defined(__GNUC__) && (__GNUC__ > 2)
-#define LZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
-#define LZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
-#else
-#define LZ_EXPECT_CONDITIONAL(c) (c)
-#define LZ_UNEXPECT_CONDITIONAL(c) (c)
-#endif
-
-
-#ifdef __GNUC__
-#define ATTR_PACKED __attribute__ ((__packed__))
-#else
-#define ATTR_PACKED
-#pragma pack(push)
-#pragma pack(1)
-#endif
-
-
-/* the palette images will be treated as one byte pixels. Their width should be transformed
-   accordingly.
-*/
-typedef struct ATTR_PACKED one_byte_pixel_t {
-    uint8_t a;
-} one_byte_pixel_t;
-
-typedef struct ATTR_PACKED rgb32_pixel_t {
-    uint8_t b;
-    uint8_t g;
-    uint8_t r;
-    uint8_t pad;
-} rgb32_pixel_t;
-
-typedef struct ATTR_PACKED rgb24_pixel_t {
-    uint8_t b;
-    uint8_t g;
-    uint8_t r;
-} rgb24_pixel_t;
-
-typedef uint16_t rgb16_pixel_t;
-
-#ifndef __GNUC__
-#pragma pack(pop)
-#endif
-
-#undef ATTR_PACKED
-
-
-#define MAX_COPY 32
-#define MAX_LEN 264          /* 256 + 8 */
-#define BOUND_OFFSET 2
-#define LIMIT_OFFSET 6
-#define MIN_FILE_SIZE 4
-#define COMP_LEVEL_SIZE_LIMIT 65536
-
-// TODO: implemented lz2. should lz1 be an option (no RLE + distance limitation of MAX_DISTANCE)
-// TODO: I think MAX_FARDISTANCE can be changed easily to 2^29 
-//       (and maybe even more when pixel > byte).
-// i.e. we can support 512M Bytes/Pixels distance instead of only ~68K.
-#define MAX_DISTANCE 8191                        // 2^13
-#define MAX_FARDISTANCE (65535 + MAX_DISTANCE - 1)    // ~2^16+2^13
-
-
-#define LZ_PLT
-#include "lz_compress_tmpl.c"
-#define LZ_PLT
-#include "lz_decompress_tmpl.c"
-
-#define LZ_PLT
-#define PLT8
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_PLT
-#define PLT4_BE
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_PLT
-#define PLT4_LE
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_PLT
-#define PLT1_BE
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_PLT
-#define PLT1_LE
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-
-#define LZ_RGB16
-#include "lz_compress_tmpl.c"
-#define LZ_RGB16
-#include "lz_decompress_tmpl.c"
-#define LZ_RGB16
-#define TO_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_RGB24
-#include "lz_compress_tmpl.c"
-#define LZ_RGB24
-#include "lz_decompress_tmpl.c"
-
-
-#define LZ_RGB32
-#include "lz_compress_tmpl.c"
-#define LZ_RGB32
-#include "lz_decompress_tmpl.c"
-
-#define LZ_RGB_ALPHA
-#include "lz_compress_tmpl.c"
-#define LZ_RGB_ALPHA
-#include "lz_decompress_tmpl.c"
-
-#undef LZ_UNEXPECT_CONDITIONAL
-#undef LZ_EXPECT_CONDITIONAL
-
-int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
-              uint8_t *lines, unsigned int num_lines, int stride,
-              uint8_t *io_ptr, unsigned int num_io_bytes)
-{
-    Encoder *encoder = (Encoder *)lz;
-    uint8_t *io_ptr_end = io_ptr + num_io_bytes;
-
-    encoder->type = type;
-    encoder->width = width;
-    encoder->height = height;
-    encoder->stride = stride;
-
-    if (IS_IMAGE_TYPE_PLT[encoder->type]) {
-        if (encoder->stride > (width / PLT_PIXELS_PER_BYTE[encoder->type])) {
-            if (((width % PLT_PIXELS_PER_BYTE[encoder->type]) == 0) || (
-                    (encoder->stride - (width / PLT_PIXELS_PER_BYTE[encoder->type])) > 1)) {
-                encoder->usr->error(encoder->usr, "stride overflows (plt)\n");
-            }
-        }
-    } else {
-        if (encoder->stride != width * RGB_BYTES_PER_PIXEL[encoder->type]) {
-            encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb)\n");
-        }
-    }
-
-    // assign the output buffer
-    if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
-        encoder->usr->error(encoder->usr, "lz encoder io reset failed\n");
-    }
-
-    // first read the list of the image segments
-    if (!lz_read_image_segments(encoder, lines, num_lines)) {
-        encoder->usr->error(encoder->usr, "lz encoder reading image segments failed\n");
-    }
-
-    encode_32(encoder, LZ_MAGIC);
-    encode_32(encoder, LZ_VERSION);
-    encode_32(encoder, type);
-    encode_32(encoder, width);
-    encode_32(encoder, height);
-    encode_32(encoder, stride);
-    encode_32(encoder, top_down); // TODO: maybe compress type and top_down to one byte
-
-    switch (encoder->type) {
-    case LZ_IMAGE_TYPE_PLT1_BE:
-    case LZ_IMAGE_TYPE_PLT1_LE:
-    case LZ_IMAGE_TYPE_PLT4_BE:
-    case LZ_IMAGE_TYPE_PLT4_LE:
-    case LZ_IMAGE_TYPE_PLT8:
-        lz_plt_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_RGB16:
-        lz_rgb16_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_RGB24:
-        lz_rgb24_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_RGB32:
-        lz_rgb32_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_RGBA:
-        lz_rgb32_compress(encoder);
-        lz_rgb_alpha_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_XXXA:
-        lz_rgb_alpha_compress(encoder);
-        break;
-    case LZ_IMAGE_TYPE_INVALID:
-    default:
-        encoder->usr->error(encoder->usr, "bad image type\n");
-    }
-
-    // move all the used segments to the free ones
-    lz_reset_image_seg(encoder);
-
-    encoder->io_bytes_count -= (encoder->io_end - encoder->io_now);
-
-    return encoder->io_bytes_count;
-}
-
-/*
-    initialize and read lz magic
-*/
-void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
-                     LzImageType *out_type, int *out_width, int *out_height,
-                     int *out_n_pixels, int *out_top_down, const SpicePalette *palette)
-{
-    Encoder *encoder = (Encoder *)lz;
-    uint8_t *io_ptr_end = io_ptr + num_io_bytes;
-    uint32_t magic;
-    uint32_t version;
-
-    if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
-        encoder->usr->error(encoder->usr, "io reset failed");
-    }
-
-    magic = decode_32(encoder);
-    if (magic != LZ_MAGIC) {
-        encoder->usr->error(encoder->usr, "bad magic\n");
-    }
-
-    version = decode_32(encoder);
-    if (version != LZ_VERSION) {
-        encoder->usr->error(encoder->usr, "bad version\n");
-    }
-
-    encoder->type = (LzImageType)decode_32(encoder);
-    encoder->width = decode_32(encoder);
-    encoder->height = decode_32(encoder);
-    encoder->stride = decode_32(encoder);
-    *out_top_down = decode_32(encoder);
-
-    *out_width = encoder->width;
-    *out_height = encoder->height;
-//    *out_stride = encoder->stride;
-    *out_type = encoder->type;
-
-    // TODO: maybe instead of stride we can encode out_n_pixels
-    //       (if stride is not necessary in decoding).
-    if (IS_IMAGE_TYPE_PLT[encoder->type]) {
-        encoder->palette = palette;
-        *out_n_pixels = encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type] * encoder->height;
-    } else {
-        *out_n_pixels = encoder->width * encoder->height;
-    }
-}
-
-void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf)
-{
-    Encoder *encoder = (Encoder *)lz;
-    size_t out_size = 0;
-    size_t alpha_size = 0;
-    size_t size = 0;
-    if (IS_IMAGE_TYPE_PLT[encoder->type]) {
-        if (to_type == encoder->type) {
-            size = encoder->height * encoder->stride;
-            out_size = lz_plt_decompress(encoder, (one_byte_pixel_t *)buf, size);
-        } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
-            size = encoder->height * encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type];
-            if (!encoder->palette) {
-                encoder->usr->error(encoder->usr,
-                                    "a palette is missing (for bpp to rgb decoding)\n");
-            }
-            switch (encoder->type) {
-            case LZ_IMAGE_TYPE_PLT1_BE:
-                out_size = lz_plt1_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                break;
-            case LZ_IMAGE_TYPE_PLT1_LE:
-                out_size = lz_plt1_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                break;
-            case LZ_IMAGE_TYPE_PLT4_BE:
-                out_size = lz_plt4_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                break;
-            case LZ_IMAGE_TYPE_PLT4_LE:
-                out_size = lz_plt4_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                break;
-            case LZ_IMAGE_TYPE_PLT8:
-                out_size = lz_plt8_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                break;
-            case LZ_IMAGE_TYPE_RGB16:
-            case LZ_IMAGE_TYPE_RGB24:
-            case LZ_IMAGE_TYPE_RGB32:
-            case LZ_IMAGE_TYPE_RGBA:
-            case LZ_IMAGE_TYPE_XXXA:
-            case LZ_IMAGE_TYPE_INVALID:
-            default:
-                encoder->usr->error(encoder->usr, "bad image type\n");
-            }
-        } else {
-            encoder->usr->error(encoder->usr, "unsupported output format\n");
-        }
-    } else {
-        size = encoder->height * encoder->width;
-        switch (encoder->type) {
-        case LZ_IMAGE_TYPE_RGB16:
-            if (encoder->type == to_type) {
-                out_size = lz_rgb16_decompress(encoder, (rgb16_pixel_t *)buf, size);
-            } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
-                out_size = lz_rgb16_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-            } else {
-                encoder->usr->error(encoder->usr, "unsupported output format\n");
-            }
-            break;
-        case LZ_IMAGE_TYPE_RGB24:
-            if (encoder->type == to_type) {
-                out_size = lz_rgb24_decompress(encoder, (rgb24_pixel_t *)buf, size);
-            } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
-                out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-            } else {
-                encoder->usr->error(encoder->usr, "unsupported output format\n");
-            }
-            break;
-        case LZ_IMAGE_TYPE_RGB32:
-            if (encoder->type == to_type) {
-                out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-            } else {
-                encoder->usr->error(encoder->usr, "unsupported output format\n");
-            }
-            break;
-        case LZ_IMAGE_TYPE_RGBA:
-            if (encoder->type == to_type) {
-                out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                ASSERT(encoder->usr, alpha_size == size);
-            } else {
-                encoder->usr->error(encoder->usr, "unsupported output format\n");
-            }
-            break;
-        case LZ_IMAGE_TYPE_XXXA:
-            if (encoder->type == to_type) {
-                alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
-                out_size = alpha_size;
-            } else {
-                encoder->usr->error(encoder->usr, "unsupported output format\n");
-            }
-            break;
-        case LZ_IMAGE_TYPE_PLT1_LE:
-        case LZ_IMAGE_TYPE_PLT1_BE:
-        case LZ_IMAGE_TYPE_PLT4_LE:
-        case LZ_IMAGE_TYPE_PLT4_BE:
-        case LZ_IMAGE_TYPE_PLT8:
-        case LZ_IMAGE_TYPE_INVALID:
-        default:
-            encoder->usr->error(encoder->usr, "bad image type\n");
-        }
-    }
-
-    ASSERT(encoder->usr, is_io_to_decode_end(encoder));
-    ASSERT(encoder->usr, out_size == size);
-
-    if (out_size != size) {
-        encoder->usr->error(encoder->usr, "bad decode size\n");
-    }
-}
-
diff --git a/common/lz.h b/common/lz.h
deleted file mode 100644
index a51ccc0..0000000
--- a/common/lz.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-        dictionary compression for images based on fastlz (http://www.fastlz.org/)
-        (Distributed under MIT license).
-*/
-#ifndef __LZ_H
-#define __LZ_H
-
-#include "lz_common.h"
-#include "lz_config.h"
-#include "draw.h"
-#include "macros.h"
-
-typedef void *LzContext;
-
-typedef struct LzUsrContext LzUsrContext;
-struct LzUsrContext {
-    ATTR_PRINTF(2, 3) void (*error)(LzUsrContext *usr, const char *fmt, ...);
-    ATTR_PRINTF(2, 3) void (*warn)(LzUsrContext *usr, const char *fmt, ...);
-    ATTR_PRINTF(2, 3) void (*info)(LzUsrContext *usr, const char *fmt, ...);
-    void    *(*malloc)(LzUsrContext *usr, int size);
-    void (*free)(LzUsrContext *usr, void *ptr);
-    int (*more_space)(LzUsrContext *usr, uint8_t **io_ptr);     // get the next chunk of the
-                                                                // compressed buffer. return
-                                                                // number of bytes in the chunk.
-    int (*more_lines)(LzUsrContext *usr, uint8_t **lines);      // get the next chunk of the
-                                                                // original image. If the image
-                                                                // is down to top, return it from
-                                                                // the last line to the first one
-                                                                // (stride should always be
-                                                                // positive)
-};
-
-/*
-        assumes width is in pixels and stride is in bytes
-        return: the number of bytes in the compressed data
-
-        TODO :	determine size limit for the first segment and each chunk. check validity
-                        of the segment or go to literal copy.
-        TODO :	currently support only rgb images in which width*bytes_per_pixel = stride OR
-                        palette images in which stride equals the min number of bytes to
-                        hold a line. stride is not necessary for now. just for sanity check.
-                        stride should be > 0
-*/
-int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
-              uint8_t *lines, unsigned int num_lines, int stride,
-              uint8_t *io_ptr, unsigned int num_io_bytes);
-
-/*
-        prepare encoder and read lz magic.
-        out_n_pixels number of compressed pixels. May differ from Width*height in plt1/4.
-        Use it for allocation the decompressed buffer.
-
-*/
-void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
-                     LzImageType *out_type, int *out_width, int *out_height,
-                     int *out_n_pixels, int *out_top_down, const SpicePalette *palette);
-
-/*
-        to_type = the image output type.
-        We assume the buffer is consecutive. i.e. width = stride
-
-        Important: if the image is plt1/4 and to_type is rgb32, the image
-        will decompressed including the last bits in each line. This means buffer should be
-        larger than width*height if needed and you should use stride to fix it.
-        Note: If the image is down to top, set the stride in the sw surface to negative.
-        use alloc_lz_image_surface create the surface.
-*/
-void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf);
-
-LzContext *lz_create(LzUsrContext *usr);
-
-void lz_destroy(LzContext *lz);
-
-
-#endif  // __LZ_H
diff --git a/common/lz_common.h b/common/lz_common.h
deleted file mode 100644
index 34276af..0000000
--- a/common/lz_common.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-/*common header for encoder and decoder*/
-
-#ifndef _LZ_COMMON_H
-#define _LZ_COMMON_H
-
-//#define DEBUG
-
-/* change the max window size will require change in the encoding format*/
-#define LZ_MAX_WINDOW_SIZE (1 << 25)
-#define MAX_COPY 32
-
-typedef enum {
-    LZ_IMAGE_TYPE_INVALID,
-    LZ_IMAGE_TYPE_PLT1_LE,
-    LZ_IMAGE_TYPE_PLT1_BE,      // PLT stands for palette
-    LZ_IMAGE_TYPE_PLT4_LE,
-    LZ_IMAGE_TYPE_PLT4_BE,
-    LZ_IMAGE_TYPE_PLT8,
-    LZ_IMAGE_TYPE_RGB16,
-    LZ_IMAGE_TYPE_RGB24,
-    LZ_IMAGE_TYPE_RGB32,
-    LZ_IMAGE_TYPE_RGBA,
-    LZ_IMAGE_TYPE_XXXA
-} LzImageType;
-
-#define LZ_IMAGE_TYPE_MASK 0x0f
-#define LZ_IMAGE_TYPE_LOG 4 // number of bits required for coding the image type
-
-/* access to the arrays is based on the image types */
-static const int IS_IMAGE_TYPE_PLT[] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
-static const int IS_IMAGE_TYPE_RGB[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
-static const int PLT_PIXELS_PER_BYTE[] = {0, 8, 8, 2, 2, 1};
-static const int RGB_BYTES_PER_PIXEL[] = {0, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4};
-
-
-#define LZ_MAGIC (*(uint32_t *)"LZ  ")
-#define LZ_VERSION_MAJOR 1U
-#define LZ_VERSION_MINOR 1U
-#define LZ_VERSION ((LZ_VERSION_MAJOR << 16) | (LZ_VERSION_MINOR & 0xffff))
-
-
-#endif  // _LZ_COMMON_H
diff --git a/common/lz_compress_tmpl.c b/common/lz_compress_tmpl.c
deleted file mode 100644
index 18d6697..0000000
--- a/common/lz_compress_tmpl.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright 2009 Red Hat, Inc. and/or its affiliates.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
- This file incorporates work covered by the following copyright and
- permission notice:
-   Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
-
-   Permission is hereby granted, free of charge, to any person
-   obtaining a copy of this software and associated documentation
-   files (the "Software"), to deal in the Software without
-   restriction, including without limitation the rights to use, copy,
-   modify, merge, publish, distribute, sublicense, and/or sell copies
-   of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be
-   included in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-
-*/
-
-#define DJB2_START 5381;
-#define DJB2_HASH(hash, c) (hash = ((hash << 5) + hash) ^ (c)) //|{hash = ((hash << 5) + hash) + c;}
-
-/*
-    For each pixel type the following macros are defined:
-    PIXEL                         : input type
-    FNAME(name)
-    ENCODE_PIXEL(encoder, pixel) : writing a pixel to the compressed buffer (byte by byte)
-    SAME_PIXEL(pix1, pix2)         : comparing two pixels
-    HASH_FUNC(value, pix_ptr)    : hash func of 3 consecutive pixels
-*/
-
-#ifdef LZ_PLT
-#define PIXEL one_byte_pixel_t
-#define FNAME(name) lz_plt_##name
-#define ENCODE_PIXEL(e, pix) encode(e, (pix).a)   // gets the pixel and write only the needed bytes
-                                                  // from the pixel
-#define SAME_PIXEL(pix1, pix2) ((pix1).a == (pix2).a)
-#define HASH_FUNC(v, p) {  \
-    v = DJB2_START;        \
-    DJB2_HASH(v, p[0].a);  \
-    DJB2_HASH(v, p[1].a);  \
-    DJB2_HASH(v, p[2].a);  \
-    v &= HASH_MASK;        \
-    }
-#endif
-
-#ifdef LZ_RGB_ALPHA
-//#undef LZ_RGB_ALPHA
-#define PIXEL rgb32_pixel_t
-#define FNAME(name) lz_rgb_alpha_##name
-#define ENCODE_PIXEL(e, pix) {encode(e, (pix).pad);}
-#define SAME_PIXEL(pix1, pix2) ((pix1).pad == (pix2).pad)
-#define HASH_FUNC(v, p) {    \
-    v = DJB2_START;          \
-    DJB2_HASH(v, p[0].pad);  \
-    DJB2_HASH(v, p[1].pad);  \
-    DJB2_HASH(v, p[2].pad);  \
-    v &= HASH_MASK;          \
-    }
-#endif
-
-
-#ifdef LZ_RGB16
-#define PIXEL rgb16_pixel_t
-#define FNAME(name) lz_rgb16_##name
-#define GET_r(pix) (((pix) >> 10) & 0x1f)
-#define GET_g(pix) (((pix) >> 5) & 0x1f)
-#define GET_b(pix) ((pix) & 0x1f)
-#define ENCODE_PIXEL(e, pix) {encode(e, (pix) >> 8); encode(e, (pix) & 0xff);}
-
-#define HASH_FUNC(v, p) {                 \
-    v = DJB2_START;                       \
-    DJB2_HASH(v, p[0] & (0x00ff));        \
-    DJB2_HASH(v, (p[0] >> 8) & (0x007f)); \
-    DJB2_HASH(v, p[1]&(0x00ff));          \
-    DJB2_HASH(v, (p[1] >> 8) & (0x007f)); \
-    DJB2_HASH(v, p[2] & (0x00ff));        \
-    DJB2_HASH(v, (p[2] >> 8) & (0x007f)); \
-    v &= HASH_MASK;                       \
-}
-#endif
-
-#ifdef LZ_RGB24
-#define PIXEL rgb24_pixel_t
-#define FNAME(name) lz_rgb24_##name
-#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
-#endif
-
-#ifdef LZ_RGB32
-#define PIXEL rgb32_pixel_t
-#define FNAME(name) lz_rgb32_##name
-#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
-#endif
-
-
-#if  defined(LZ_RGB24) || defined(LZ_RGB32)
-#define GET_r(pix) ((pix).r)
-#define GET_g(pix) ((pix).g)
-#define GET_b(pix) ((pix).b)
-#define HASH_FUNC(v, p) {    \
-    v = DJB2_START;          \
-    DJB2_HASH(v, p[0].r);    \
-    DJB2_HASH(v, p[0].g);    \
-    DJB2_HASH(v, p[0].b);    \
-    DJB2_HASH(v, p[1].r);    \
-    DJB2_HASH(v, p[1].g);    \
-    DJB2_HASH(v, p[1].b);    \
-    DJB2_HASH(v, p[2].r);    \
-    DJB2_HASH(v, p[2].g);    \
-    DJB2_HASH(v, p[2].b);    \
-    v &= HASH_MASK;          \
-    }
-#endif
-
-#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
-#define SAME_PIXEL(p1, p2) (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \
-                            GET_b(p1) == GET_b(p2))
-
-#endif
-
-#define PIXEL_ID(pix_ptr, seg_ptr) (pix_ptr - ((PIXEL *)seg_ptr->lines) + seg_ptr->size_delta)
-
-// when encoding, the ref can be in previous segment, and we should check that it doesn't
-// exceeds its bounds.
-// TODO: optimization: when only one chunk exists or when the reference is in the same segment,
-//       don't make checks if we reach end of segments
-// TODO: optimize to continue match between segments?
-// TODO: check hash function
-// TODO: check times
-
-/* compresses one segment starting from 'from'.*/
-static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *from, int copied)
-{
-    const PIXEL *ip = from;
-    const PIXEL *ip_bound = (PIXEL *)(seg->lines_end) - BOUND_OFFSET;
-    const PIXEL *ip_limit = (PIXEL *)(seg->lines_end) - LIMIT_OFFSET;
-    HashEntry    *hslot;
-    int hval;
-    int copy = copied;
-
-    if (copy == 0) {
-        encode_copy_count(encoder, MAX_COPY - 1);
-    }
-
-
-    while (LZ_EXPECT_CONDITIONAL(ip < ip_limit)) {   // TODO: maybe change ip_limit and enabling
-                                                     //       moving to the next seg
-        const PIXEL            *ref;
-        const PIXEL            *ref_limit;
-        size_t distance;
-
-        /* minimum match length */
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
-        size_t len = 3;
-#elif defined(LZ_RGB16)
-        size_t len = 2;
-#else
-        size_t len = 1;
-#endif
-        /* comparison starting-point */
-        const PIXEL            *anchor = ip;
-
-
-
-        // TODO: RLE without checking if not first byte.
-        // TODO: optimize comparisons
-
-        /* check for a run */ // TODO for RGB we can use less pixels
-        if (LZ_EXPECT_CONDITIONAL(ip > (PIXEL *)(seg->lines))) {
-            if (SAME_PIXEL(ip[-1], ip[0]) && SAME_PIXEL(ip[0], ip[1]) && SAME_PIXEL(ip[1], ip[2])) {
-                distance = 1;
-                ip += 3;
-                ref = anchor + 2;
-                ref_limit = (PIXEL *)(seg->lines_end);
-#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
-                len = 3;
-#endif
-                goto match;
-            }
-        }
-
-        /* find potential match */
-        HASH_FUNC(hval, ip);
-        hslot = encoder->htab + hval;
-        ref = (PIXEL *)(hslot->ref);
-        ref_limit = (PIXEL *)(hslot->image_seg->lines_end);
-
-        /* calculate distance to the match */
-        distance = PIXEL_ID(anchor, seg) - PIXEL_ID(ref, hslot->image_seg);
-
-        /* update hash table */
-        hslot->image_seg = seg;
-        hslot->ref = (uint8_t *)anchor;
-
-        /* is this a match? check the first 3 pixels */
-        if (distance == 0 || (distance >= MAX_FARDISTANCE)) {
-            goto literal;
-        }
-        /* check if the hval key identical*/
-        // no need to check ref limit here because the word size in the htab is 3 pixels
-        if (!SAME_PIXEL(*ref, *ip)) {
-            ref++;
-            ip++;
-            goto literal;
-        }
-        ref++;
-        ip++;
-
-        /* minimum match length for rgb16 is 2 and for plt and alpha is 3 */
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_RGB16)
-        if (!SAME_PIXEL(*ref, *ip)) {
-            ref++;
-            ip++;
-            goto literal;
-        }
-        ref++;
-        ip++;
-#endif
-
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
-        if (!SAME_PIXEL(*ref, *ip)) {
-            ref++;
-            ip++;
-            goto literal;
-        }
-        ref++;
-        ip++;
-#endif
-        /* far, needs at least 5-byte match */
-        if (distance >= MAX_DISTANCE) {
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
-            if (ref >= (ref_limit - 1)) {
-                goto literal;
-            }
-#else
-            if (ref > (ref_limit - 1)) {
-                goto literal;
-            }
-#endif
-            if (!SAME_PIXEL(*ref, *ip)) {
-                ref++;
-                ip++;
-                goto literal;
-            }
-            ref++;
-            ip++;
-            len++;
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
-            if (!SAME_PIXEL(*ref, *ip)) {
-                ref++;
-                ip++;
-                goto literal;
-            }
-            ref++;
-            ip++;
-            len++;
-#endif
-        }
-match:        // RLE or dictionary (both are encoded by distance from ref (-1) and length)
-
-        /* distance is biased */
-        distance--;
-
-        // ip is located now at the position of the second mismatch.
-        // later it will be subtracted by 3
-
-        if (!distance) {
-            /* zero distance means a run */
-            PIXEL x = *ref;
-            while ((ip < ip_bound) && (ref < ref_limit)) { // TODO: maybe separate a run from
-                                                           //       the same seg or from different
-                                                           //       ones in order to spare 
-                                                           //       ref < ref_limit
-                if (!SAME_PIXEL(*ref, x)) {
-                    ref++;
-                    break;
-                } else {
-                    ref++;
-                    ip++;
-                }
-            }
-        } else {
-            // TODO: maybe separate a run from the same seg or from different ones in order
-            //       to spare ref < ref_limit and that way we can also perform 8 calls of
-            //       (ref++ != ip++) outside a loop
-            for (;;) {
-                while ((ip < ip_bound) && (ref < ref_limit)) {
-                    if (!SAME_PIXEL(*ref, *ip)) {
-                        ref++;
-                        ip++;
-                        break;
-                    } else {
-                        ref++;
-                        ip++;
-                    }
-                }
-                break;
-            }
-        }
-
-        /* if we have copied something, adjust the copy count */
-        if (copy) {
-            /* copy is biased, '0' means 1 byte copy */
-            update_copy_count(encoder, copy - 1);
-        } else {
-            /* back, to overwrite the copy count */
-            compress_output_prev(encoder);
-        }
-
-        /* reset literal counter */
-        copy = 0;
-
-        /* length is biased, '1' means a match of 3 pixels for PLT and alpha*/
-        /* for RGB 16 1 means 2 */
-        /* for RGB24/32 1 means 1...*/
-        ip -= 3;
-        len = ip - anchor;
-#if defined(LZ_RGB16)
-        len++;
-#elif defined(LZ_RGB24) || defined(LZ_RGB32)
-        len += 2;
-#endif
-        /* encode the match (like fastlz level 2)*/
-        if (distance < MAX_DISTANCE) { // MAX_DISTANCE is 2^13 - 1
-            // when copy is performed, the byte that holds the copy count is smaller than 32.
-            // When there is a reference, the first byte is always larger then 32
-
-            // 3 bits = length, 5 bits = 5 MSB of distance, 8 bits = 8 LSB of distance
-            if (len < 7) {
-                encode(encoder, (uint8_t)((len << 5) + (distance >> 8)));
-                encode(encoder, (uint8_t)(distance & 255));
-            } else { // more than 3 bits are needed for length
-                    // 3 bits 7, 5 bits = 5 MSB of distance, next bytes are 255 till we
-                    // receive a smaller number, last byte = 8 LSB of distance
-                encode(encoder, (uint8_t)((7 << 5) + (distance >> 8)));
-                for (len -= 7; len >= 255; len -= 255) {
-                    encode(encoder, 255);
-                }
-                encode(encoder, (uint8_t)len);
-                encode(encoder, (uint8_t)(distance & 255));
-            }
-        } else {
-            /* far away */
-            if (len < 7) { // the max_far_distance is ~2^16+2^13 so two more bytes are needed
-                // 3 bits = length, 5 bits = 5 MSB of MAX_DISTANCE, 8 bits = 8 LSB of MAX_DISTANCE,
-                // 8 bits = 8 MSB distance-MAX_distance (smaller than 2^16),8 bits=8 LSB of
-                // distance-MAX_distance
-                distance -= MAX_DISTANCE;
-                encode(encoder, (uint8_t)((len << 5) + 31));
-                encode(encoder, (uint8_t)255);
-                encode(encoder, (uint8_t)(distance >> 8));
-                encode(encoder, (uint8_t)(distance & 255));
-            } else {
-                // same as before, but the first byte is followed by the left overs of len
-                distance -= MAX_DISTANCE;
-                encode(encoder, (uint8_t)((7 << 5) + 31));
-                for (len -= 7; len >= 255; len -= 255) {
-                    encode(encoder, 255);
-                }
-                encode(encoder, (uint8_t)len);
-                encode(encoder, 255);
-                encode(encoder, (uint8_t)(distance >> 8));
-                encode(encoder, (uint8_t)(distance & 255));
-            }
-        }
-
-        /* update the hash at match boundary */
-#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
-        if (ip > anchor) {
-#endif
-        HASH_FUNC(hval, ip);
-        encoder->htab[hval].ref = (uint8_t *)ip;
-        ip++;
-        encoder->htab[hval].image_seg = seg;
-#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
-    } else {ip++;
-    }
-#endif
-#if defined(LZ_RGB24) || defined(LZ_RGB32)
-        if (ip > anchor) {
-#endif
-        HASH_FUNC(hval, ip);
-        encoder->htab[hval].ref = (uint8_t *)ip;
-        ip++;
-        encoder->htab[hval].image_seg = seg;
-#if defined(LZ_RGB24) || defined(LZ_RGB32)
-    } else {ip++;
-    }
-#endif
-        /* assuming literal copy */
-        encode_copy_count(encoder, MAX_COPY - 1);
-        continue;
-
-literal:
-        ENCODE_PIXEL(encoder, *anchor);
-        anchor++;
-        ip = anchor;
-        copy++;
-
-        if (LZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) {
-            copy = 0;
-            encode_copy_count(encoder, MAX_COPY - 1);
-        }
-    } // END LOOP (ip < ip_limit)
-
-
-    /* left-over as literal copy */
-    ip_bound++;
-    while (ip <= ip_bound) {
-        ENCODE_PIXEL(encoder, *ip);
-        ip++;
-        copy++;
-        if (copy == MAX_COPY) {
-            copy = 0;
-            encode_copy_count(encoder, MAX_COPY - 1);
-        }
-    }
-
-    /* if we have copied something, adjust the copy length */
-    if (copy) {
-        update_copy_count(encoder, copy - 1);
-    } else {
-        compress_output_prev(encoder); // in case we created a new buffer for copy, check that
-                                       // red_worker could handle size that do not contain the
-                                       // ne buffer
-    }
-}
-
-
-/*    initializes the hash table. if the file is very small, copies it.
-    copies the first two pixels of the first segment, and sends the segments
-    one by one to compress_seg.
-    the number of bytes compressed are stored inside encoder.
-    */
-static void FNAME(compress)(Encoder *encoder)
-{
-    LzImageSegment    *cur_seg = encoder->head_image_segs;
-    HashEntry        *hslot;
-    PIXEL            *ip;
-
-    // fetch the first image segment that is not too small
-    while (cur_seg && ((((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) < 4)) {
-        // coping the segment
-        if (cur_seg->lines != cur_seg->lines_end) {
-            ip = (PIXEL *)cur_seg->lines;
-            // Note: we assume MAX_COPY > 3
-            encode_copy_count(encoder, (uint8_t)(
-                                  (((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) - 1));
-            while (ip < (PIXEL *)cur_seg->lines_end) {
-                ENCODE_PIXEL(encoder, *ip);
-                ip++;
-            }
-        }
-        cur_seg = cur_seg->next;
-    }
-
-    if (!cur_seg) {
-        return;
-    }
-
-    ip = (PIXEL *)cur_seg->lines;
-
-    /* initialize hash table */
-    for (hslot = encoder->htab; hslot < encoder->htab + HASH_SIZE; hslot++) {
-        hslot->ref = (uint8_t*)ip;
-        hslot->image_seg = cur_seg;
-    }
-
-    encode_copy_count(encoder, MAX_COPY - 1);
-    ENCODE_PIXEL(encoder, *ip);
-    ip++;
-    ENCODE_PIXEL(encoder, *ip);
-    ip++;
-
-    // compressing the first segment
-    FNAME(compress_seg)(encoder, cur_seg, ip, 2);
-
-    // compressing the next segments
-    for (cur_seg = cur_seg->next; cur_seg; cur_seg = cur_seg->next) {
-        FNAME(compress_seg)(encoder, cur_seg, (PIXEL *)cur_seg->lines, 0);
-    }
-}
-
-#undef FNAME
-#undef PIXEL_ID
-#undef PIXEL
-#undef ENCODE_PIXEL
-#undef SAME_PIXEL
-#undef LZ_READU16
-#undef HASH_FUNC
-#undef BYTES_TO_16
-#undef HASH_FUNC_16
-#undef GET_r
-#undef GET_g
-#undef GET_b
-#undef GET_CODE
-#undef LZ_PLT
-#undef LZ_RGB_ALPHA
-#undef LZ_RGB16
-#undef LZ_RGB24
-#undef LZ_RGB32
-#undef HASH_FUNC2
diff --git a/common/lz_config.h b/common/lz_config.h
deleted file mode 100644
index 439f413..0000000
--- a/common/lz_config.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef __LZ_CONFIG_H
-#define __LZ_CONFIG_H
-
-#include <spice/types.h>
-#include <spice/macros.h>
-
-#ifdef __GNUC__
-
-#include <string.h>
-
-#define INLINE inline
-
-#else
-
-#ifdef QXLDD
-#include <windef.h>
-#include "os_dep.h"
-#define INLINE _inline
-
-#else
-#include <stddef.h>
-#include <string.h>
-
-#define INLINE inline
-#endif  // QXLDD
-
-#endif  //__GNUC__
-#endif  //__LZ_CONFIG_H
diff --git a/common/lz_decompress_tmpl.c b/common/lz_decompress_tmpl.c
deleted file mode 100644
index aa403f6..0000000
--- a/common/lz_decompress_tmpl.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright 2009 Red Hat, Inc. and/or its affiliates.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-
- This file incorporates work covered by the following copyright and
- permission notice:
-      Copyright (C) 2007 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
-   Copyright (C) 2005 Ariya Hidayat (ariya at kde.org)
-
-   Permission is hereby granted, free of charge, to any person
-   obtaining a copy of this software and associated documentation
-   files (the "Software"), to deal in the Software without
-   restriction, including without limitation the rights to use, copy,
-   modify, merge, publish, distribute, sublicense, and/or sell copies
-   of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be
-   included in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-
-*/
-
-// External defines: PLT, RGBX/PLTXX/ALPHA, TO_RGB32.
-// If PLT4/1 and TO_RGB32 are defined, we need CAST_PLT_DISTANCE (because then the number of
-// pixels differ from the units used in the compression)
-
-/*
-    For each output pixel type the following macros are defined:
-    OUT_PIXEL                      - the output pixel type
-    COPY_PIXEL(p, out)              - assigns the pixel to the place pointed by out and increases
-                                      out. Used in RLE. Need special handling because in alpha we
-                                      copy only the pad byte.
-    COPY_REF_PIXEL(ref, out)      - copies the pixel pointed by ref to the pixel pointed by out.
-                                    Increases ref and out.
-    COPY_COMP_PIXEL(encoder, out) - copies pixel from the compressed buffer to the decompressed
-                                    buffer. Increases out.
-*/
-#if !defined(LZ_RGB_ALPHA)
-#define COPY_PIXEL(p, out) (*out++ = p)
-#define COPY_REF_PIXEL(ref, out) (*out++ = *ref++)
-#endif
-
-
-// decompressing plt to plt
-#ifdef LZ_PLT
-#ifndef TO_RGB32
-#define OUT_PIXEL one_byte_pixel_t
-#define FNAME(name) lz_plt_##name
-#define COPY_COMP_PIXEL(encoder, out) {out->a = decode(encoder); out++;}
-#else // TO_RGB32
-#define OUT_PIXEL rgb32_pixel_t
-#define COPY_PLT_ENTRY(ent, out) {    \
-    (out)->b = ent;                   \
-    (out)->g = (ent >> 8);            \
-    (out)->r = (ent >> 16);           \
-    (out)->pad = 0;                   \
-}
-#ifdef PLT8
-#define FNAME(name) lz_plt8_to_rgb32_##name
-#define COPY_COMP_PIXEL(encoder, out) {                     \
-    uint32_t rgb = encoder->palette->ents[decode(encoder)]; \
-    COPY_PLT_ENTRY(rgb, out);                               \
-    out++;}
-#elif defined(PLT4_BE)
-#define FNAME(name) lz_plt4_be_to_rgb32_##name
-#define COPY_COMP_PIXEL(encoder, out){                                                             \
-    uint8_t byte = decode(encoder);                                                                \
-    uint32_t rgb = encoder->palette->ents[((byte >> 4) & 0x0f) % (encoder->palette->num_ents)];    \
-    COPY_PLT_ENTRY(rgb, out);                                                                      \
-    out++;                                                                                         \
-    rgb = encoder->palette->ents[(byte & 0x0f) % (encoder->palette->num_ents)];                    \
-    COPY_PLT_ENTRY(rgb, out);                                                                      \
-    out++;                                                                                         \
-}
-#define CAST_PLT_DISTANCE(dist) (dist*2)
-#elif  defined(PLT4_LE)
-#define FNAME(name) lz_plt4_le_to_rgb32_##name
-#define COPY_COMP_PIXEL(encoder, out){                                                      \
-    uint8_t byte = decode(encoder);                                                         \
-    uint32_t rgb = encoder->palette->ents[(byte & 0x0f) % (encoder->palette->num_ents)];    \
-    COPY_PLT_ENTRY(rgb, out);                                                               \
-    out++;                                                                                  \
-    rgb = encoder->palette->ents[((byte >> 4) & 0x0f) % (encoder->palette->num_ents)];      \
-    COPY_PLT_ENTRY(rgb, out);                                                               \
-    out++;                                                                                  \
-}
-#define CAST_PLT_DISTANCE(dist) (dist*2)
-#elif defined(PLT1_BE) // TODO store palette entries for direct access
-#define FNAME(name) lz_plt1_be_to_rgb32_##name
-#define COPY_COMP_PIXEL(encoder, out){                                    \
-    uint8_t byte = decode(encoder);                                       \
-    int i;                                                                \
-    uint32_t fore = encoder->palette->ents[1];                            \
-    uint32_t back = encoder->palette->ents[0];                            \
-    for (i = 7; i >= 0; i--)                                              \
-    {                                                                     \
-        if ((byte >> i) & 1) {                                            \
-            COPY_PLT_ENTRY(fore, out);                                    \
-        } else {                                                          \
-            COPY_PLT_ENTRY(back, out);                                    \
-        }                                                                 \
-        out++;                                                            \
-    }                                                                     \
-}
-#define CAST_PLT_DISTANCE(dist) (dist*8)
-#elif defined(PLT1_LE)
-#define FNAME(name) lz_plt1_le_to_rgb32_##name
-#define COPY_COMP_PIXEL(encoder, out){                                    \
-    uint8_t byte = decode(encoder);                                       \
-    int i;                                                                \
-    uint32_t fore = encoder->palette->ents[1];                            \
-    uint32_t back = encoder->palette->ents[0];                            \
-    for (i = 0; i < 8; i++)                                               \
-    {                                                                     \
-        if ((byte >> i) & 1) {                                            \
-            COPY_PLT_ENTRY(fore, out);                                    \
-        } else {                                                          \
-            COPY_PLT_ENTRY(back, out);                                    \
-        }                                                                 \
-        out++;                                                            \
-    }                                                                     \
-}
-#define CAST_PLT_DISTANCE(dist) (dist*8)
-#endif // PLT Type
-#endif // TO_RGB32
-#endif
-
-#ifdef LZ_RGB16
-#ifndef TO_RGB32
-#define OUT_PIXEL rgb16_pixel_t
-#define FNAME(name) lz_rgb16_##name
-#define COPY_COMP_PIXEL(e, out) {*out = ((decode(e) << 8) | decode(e)); out++;}
-#else
-#define OUT_PIXEL rgb32_pixel_t
-#define FNAME(name) lz_rgb16_to_rgb32_##name
-#define COPY_COMP_PIXEL(e, out) {                                      \
-    out->r = decode(e);                                                \
-    out->b = decode(e);                                                \
-    out->g = (((out->r) << 6) | ((out->b) >> 2)) & ~0x07;              \
-    out->g |= (out->g >> 5);                                           \
-    out->r = ((out->r << 1) & ~0x07)| ((out->r >> 4) & 0x07);          \
-    out->b =  (out->b << 3) | ((out->b >> 2) & 0x07);                  \
-    out->pad = 0;                                                      \
-    out++;                                                             \
-}                                                        
-#endif
-#endif
-
-#ifdef LZ_RGB24
-#define OUT_PIXEL rgb24_pixel_t
-#define FNAME(name) lz_rgb24_##name
-#define COPY_COMP_PIXEL(e, out) {out->b = decode(e); out->g = decode(e); out->r = decode(e); out++;}
-#endif
-
-#ifdef LZ_RGB32
-#define OUT_PIXEL rgb32_pixel_t
-#define FNAME(name) lz_rgb32_##name
-#define COPY_COMP_PIXEL(e, out) {   \
-    out->b = decode(e);             \
-    out->g = decode(e);             \
-    out->r = decode(e);             \
-    out->pad = 0;                   \
-    out++;                          \
-}
-#endif
-
-#ifdef LZ_RGB_ALPHA
-#define OUT_PIXEL rgb32_pixel_t
-#define FNAME(name) lz_rgb_alpha_##name
-#define COPY_PIXEL(p, out) {out->pad = p.pad; out++;}
-#define COPY_REF_PIXEL(ref, out) {out->pad = ref->pad; out++; ref++;}
-#define COPY_COMP_PIXEL(e, out) {out->pad = decode(e); out++;}
-#endif
-
-// return num of bytes in out_buf
-static size_t FNAME(decompress)(Encoder *encoder, OUT_PIXEL *out_buf, int size)
-{
-    OUT_PIXEL    *op = out_buf;
-    OUT_PIXEL    *op_limit = out_buf + size;
-    uint32_t ctrl = decode(encoder);
-    int loop = TRUE;
-
-    do {
-        const OUT_PIXEL *ref = op;
-        uint32_t len = ctrl >> 5;
-        uint32_t ofs = (ctrl & 31) << 8; // 5 MSb of distance
-
-        if (ctrl >= MAX_COPY) { // reference (dictionary/RLE)
-            /* retrieving the reference and the match length */
-
-            uint8_t code;
-            len--;
-            //ref -= ofs;
-            if (len == 7 - 1) { // match length is bigger than 7
-                do {
-                    code = decode(encoder);
-                    len += code;
-                } while (code == 255); // remaining of len
-            }
-            code = decode(encoder);
-            ofs += code;
-
-            /* match from 16-bit distance */
-            if (LZ_UNEXPECT_CONDITIONAL(code == 255)) {
-                if (LZ_EXPECT_CONDITIONAL((ofs - code) == (31 << 8))) {
-                    ofs = decode(encoder) << 8;
-                    ofs += decode(encoder);
-                    ofs += MAX_DISTANCE;
-                }
-            }
-
-#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
-            len += 3; // length is biased by 2 + 1 (fixing bias)
-#elif defined(LZ_RGB16)
-            len += 2; // length is biased by 1 + 1 (fixing bias)
-#else
-            len += 1;
-#endif
-            ofs += 1; // offset is biased by 1       (fixing bias)
-
-#if defined(TO_RGB32)
-#if defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || defined(PLT1_LE)
-            ofs = CAST_PLT_DISTANCE(ofs);
-            len = CAST_PLT_DISTANCE(len);
-#endif
-#endif
-            ref -= ofs;
-
-            ASSERT(encoder->usr, op + len <= op_limit);
-            ASSERT(encoder->usr, ref + len <= op_limit);
-            ASSERT(encoder->usr, ref >= out_buf);
-
-            // TODO: optimize by not calling loop at least 3 times when not PLT_TO_RGB32 (len is
-            //       always >=3). in PLT_TO_RGB32 len >= 3*number_of_pixels_per_byte
-
-            /* copying the match*/
-
-            if (ref == (op - 1)) { // run // TODO: this will never be called in PLT4/1_TO_RGB
-                                          //       because the number of pixel copied is larger
-                                          //       then one...
-                /* optimize copy for a run */
-                OUT_PIXEL b = *ref;
-                for (; len; --len) {
-                    COPY_PIXEL(b, op);
-                    ASSERT(encoder->usr, op <= op_limit);
-                }
-            } else {
-                for (; len; --len) {
-                    COPY_REF_PIXEL(ref, op);
-                    ASSERT(encoder->usr, op <= op_limit);
-                }
-            }
-        } else { // copy
-            ctrl++; // copy count is biased by 1
-#if defined(TO_RGB32) && (defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || \
-                                                                                   defined(PLT1_LE))
-            ASSERT(encoder->usr, op + CAST_PLT_DISTANCE(ctrl) <= op_limit);
-#else
-            ASSERT(encoder->usr, op + ctrl <= op_limit);
-#endif
-            COPY_COMP_PIXEL(encoder, op);
-
-            ASSERT(encoder->usr, op <= op_limit);
-
-            for (--ctrl; ctrl; ctrl--) {
-                COPY_COMP_PIXEL(encoder, op);
-                ASSERT(encoder->usr, op <= op_limit);
-            }
-        }
-
-        if (LZ_EXPECT_CONDITIONAL(op < op_limit)) {
-            ctrl = decode(encoder);
-        } else {
-            loop = FALSE;
-        }
-    } while (LZ_EXPECT_CONDITIONAL(loop));
-
-    return (op - out_buf);
-}
-
-#undef LZ_PLT
-#undef PLT8
-#undef PLT4_BE
-#undef PLT4_LE
-#undef PLT1_BE
-#undef PLT1_LE
-#undef LZ_RGB16
-#undef LZ_RGB24
-#undef LZ_RGB32
-#undef LZ_RGB_ALPHA
-#undef TO_RGB32
-#undef OUT_PIXEL
-#undef FNAME
-#undef COPY_PIXEL
-#undef COPY_REF_PIXEL
-#undef COPY_COMP_PIXEL
-#undef COPY_PLT_ENTRY
-#undef CAST_PLT_DISTANCE
-
diff --git a/common/macros.h b/common/macros.h
deleted file mode 100644
index 44a37e4..0000000
--- a/common/macros.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __MACROS_H
-#define __MACROS_H
-
-#if    __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-#define ATTR_PRINTF(a,b)                               \
-    __attribute__((format(printf,a,b)))
-#else
-#define ATTR_PRINTF(a,b)
-#endif /* __GNUC__ */
-
-
-#endif /* __MACROS_H */
diff --git a/common/marshaller.c b/common/marshaller.c
deleted file mode 100644
index 57ca32e..0000000
--- a/common/marshaller.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include "marshaller.h"
-#include "mem.h"
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#ifdef WORDS_BIGENDIAN
-#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
-#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
-#define write_int16(ptr,v) (*((int16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
-#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
-#define write_int32(ptr,v) (*((int32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
-#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
-#define write_int64(ptr,v) (*((int64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
-#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
-#else
-#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
-#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
-#define write_int16(ptr,v) (*((int16_t *)(ptr)) = v)
-#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = v)
-#define write_int32(ptr,v) (*((int32_t *)(ptr)) = v)
-#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = v)
-#define write_int64(ptr,v) (*((int64_t *)(ptr)) = v)
-#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = v)
-#endif
-
-typedef struct {
-    uint8_t *data;
-    size_t len;
-    spice_marshaller_item_free_func free_data;
-    void *opaque;
-} MarshallerItem;
-
-/* Try to fit in 4k page with 2*pointer-size overhead (next ptr and malloc size) */
-#define MARSHALLER_BUFFER_SIZE (4096 - sizeof(void *) * 2)
-
-typedef struct MarshallerBuffer MarshallerBuffer;
-struct MarshallerBuffer {
-    MarshallerBuffer *next;
-    uint8_t data[MARSHALLER_BUFFER_SIZE];
-};
-
-#define N_STATIC_ITEMS 4
-
-typedef struct SpiceMarshallerData SpiceMarshallerData;
-
-typedef struct {
-    SpiceMarshaller *marshaller;
-    int item_nr;
-    int is_64bit;
-    size_t offset;
-} MarshallerRef;
-
-struct SpiceMarshaller {
-    size_t total_size;
-    SpiceMarshallerData *data;
-    SpiceMarshaller *next;
-
-    MarshallerRef pointer_ref;
-
-    int n_items;
-    int items_size; /* number of items availible in items */
-    MarshallerItem *items;
-
-    MarshallerItem static_items[N_STATIC_ITEMS];
-};
-
-struct SpiceMarshallerData {
-    size_t total_size;
-    size_t base;
-    SpiceMarshaller *marshallers;
-    SpiceMarshaller *last_marshaller;
-
-    size_t current_buffer_position;
-    MarshallerBuffer *current_buffer;
-    MarshallerItem *current_buffer_item;
-    MarshallerBuffer *buffers;
-
-    SpiceMarshaller static_marshaller;
-    MarshallerBuffer static_buffer;
-};
-
-static void spice_marshaller_init(SpiceMarshaller *m,
-                                  SpiceMarshallerData *data)
-{
-    m->data = data;
-    m->next = NULL;
-    m->total_size = 0;
-    m->pointer_ref.marshaller = NULL;
-    m->n_items = 0;
-    m->items_size = N_STATIC_ITEMS;
-    m->items = m->static_items;
-}
-
-SpiceMarshaller *spice_marshaller_new(void)
-{
-    SpiceMarshallerData *d;
-    SpiceMarshaller *m;
-
-    d = spice_new(SpiceMarshallerData, 1);
-
-    d->last_marshaller = d->marshallers = &d->static_marshaller;
-    d->total_size = 0;
-    d->base = 0;
-    d->buffers = &d->static_buffer;
-    d->buffers->next = NULL;
-    d->current_buffer = d->buffers;
-    d->current_buffer_position = 0;
-    d->current_buffer_item = NULL;
-
-    m = &d->static_marshaller;
-    spice_marshaller_init(m, d);
-
-    return m;
-}
-
-static void free_item_data(SpiceMarshaller *m)
-{
-    MarshallerItem *item;
-    int i;
-
-    /* Free all user data */
-    for (i = 0; i < m->n_items; i++) {
-        item = &m->items[i];
-        if (item->free_data != NULL) {
-            item->free_data(item->data, item->opaque);
-        }
-    }
-}
-
-static void free_items(SpiceMarshaller *m)
-{
-    if (m->items != m->static_items) {
-        free(m->items);
-    }
-}
-
-void spice_marshaller_reset(SpiceMarshaller *m)
-{
-    SpiceMarshaller *m2, *next;
-    SpiceMarshallerData *d;
-
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    for (m2 = m; m2 != NULL; m2 = next) {
-        next = m2->next;
-        free_item_data(m2);
-
-        /* Free non-root marshallers */
-        if (m2 != m) {
-            free_items(m2);
-            free(m2);
-        }
-    }
-
-    m->next = NULL;
-    m->n_items = 0;
-    m->total_size = 0;
-
-    d = m->data;
-    d->last_marshaller = d->marshallers;
-    d->total_size = 0;
-    d->base = 0;
-    d->current_buffer_item = NULL;
-    d->current_buffer = d->buffers;
-    d->current_buffer_position = 0;
-}
-
-void spice_marshaller_destroy(SpiceMarshaller *m)
-{
-    MarshallerBuffer *buf, *next;
-    SpiceMarshallerData *d;
-
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    spice_marshaller_reset(m);
-
-    free_items(m);
-
-    d = m->data;
-
-    buf = d->buffers->next;
-    while (buf != NULL) {
-        next = buf->next;
-        free(buf);
-        buf = next;
-    }
-
-    free(d);
-}
-
-static MarshallerItem *spice_marshaller_add_item(SpiceMarshaller *m)
-{
-    MarshallerItem *item;
-
-    if (m->n_items == m->items_size) {
-        int items_size = m->items_size * 2;
-
-        if (m->items == m->static_items) {
-            m->items = spice_new(MarshallerItem, items_size);
-            memcpy(m->items, m->static_items, sizeof(MarshallerItem) * m->n_items);
-        } else {
-            m->items = spice_renew(MarshallerItem, m->items, items_size);
-        }
-        m->items_size = items_size;
-    }
-    item = &m->items[m->n_items++];
-    item->free_data = NULL;
-
-    return item;
-}
-
-static size_t remaining_buffer_size(SpiceMarshallerData *d)
-{
-    return MARSHALLER_BUFFER_SIZE - d->current_buffer_position;
-}
-
-uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size)
-{
-    MarshallerItem *item;
-    SpiceMarshallerData *d;
-    uint8_t *res;
-
-    if (size == 0) {
-        return NULL;
-    }
-
-    d = m->data;
-
-    /* Check current item */
-    item = &m->items[m->n_items - 1];
-    if (item == d->current_buffer_item &&
-        remaining_buffer_size(d) >= size) {
-        assert(m->n_items >= 1);
-        /* We can piggy back on existing item+buffer */
-        res = item->data + item->len;
-        item->len += size;
-        d->current_buffer_position += size;
-        d->total_size += size;
-        m->total_size += size;
-        return res;
-    }
-
-    item = spice_marshaller_add_item(m);
-
-    if (remaining_buffer_size(d) >= size) {
-        /* Fits in current buffer */
-        item->data = d->current_buffer->data + d->current_buffer_position;
-        item->len = size;
-        d->current_buffer_position += size;
-        d->current_buffer_item = item;
-    } else if (size > MARSHALLER_BUFFER_SIZE / 2) {
-        /* Large item, allocate by itself */
-        item->data = (uint8_t *)spice_malloc(size);
-        item->len = size;
-        item->free_data = (spice_marshaller_item_free_func)free;
-        item->opaque = NULL;
-    } else {
-        /* Use next buffer */
-        if (d->current_buffer->next == NULL) {
-            d->current_buffer->next = spice_new(MarshallerBuffer, 1);
-            d->current_buffer->next->next = NULL;
-        }
-        d->current_buffer = d->current_buffer->next;
-        d->current_buffer_position = size;
-        d->current_buffer_item = item;
-        item->data = d->current_buffer->data;
-        item->len = size;
-    }
-
-    d->total_size += size;
-    m->total_size += size;
-    return item->data;
-}
-
-void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size)
-{
-    MarshallerItem *item;
-
-    if (size == 0) {
-        return;
-    }
-
-    item = &m->items[m->n_items - 1];
-
-    assert(item->len >= size);
-    item->len -= size;
-}
-
-uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
-                                       spice_marshaller_item_free_func free_data, void *opaque)
-{
-    MarshallerItem *item;
-    SpiceMarshallerData *d;
-
-    if (data == NULL || size == 0) {
-        return NULL;
-    }
-
-    item = spice_marshaller_add_item(m);
-    item->data = data;
-    item->len = size;
-    item->free_data = free_data;
-    item->opaque = opaque;
-
-    d = m->data;
-    m->total_size += size;
-    d->total_size += size;
-
-    return data;
-}
-
-uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, size);
-    memcpy(ptr, data, size);
-    return ptr;
-}
-
-uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, uint8_t *data, size_t size)
-{
-    return spice_marshaller_add_ref_full(m, data, size, NULL, NULL);
-}
-
-void spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks)
-{
-    unsigned int i;
-
-    for (i = 0; i < chunks->num_chunks; i++) {
-        spice_marshaller_add_ref(m, chunks->chunk[i].data,
-                                 chunks->chunk[i].len);
-    }
-}
-
-SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m)
-{
-    SpiceMarshallerData *d;
-    SpiceMarshaller *m2;
-
-    d = m->data;
-
-    m2 = spice_new(SpiceMarshaller, 1);
-    spice_marshaller_init(m2, d);
-
-    d->last_marshaller->next = m2;
-    d->last_marshaller = m2;
-
-    return m2;
-}
-
-SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit)
-{
-    SpiceMarshaller *m2;
-    uint8_t *p;
-    int size;
-
-    size = is_64bit ? 8 : 4;
-
-    p = spice_marshaller_reserve_space(m, size);
-    memset(p, 0, size);
-    m2 = spice_marshaller_get_submarshaller(m);
-    m2->pointer_ref.marshaller = m;
-    m2->pointer_ref.item_nr = m->n_items - 1;
-    m2->pointer_ref.offset = m->items[m->n_items - 1].len - size;
-    m2->pointer_ref.is_64bit = is_64bit;
-
-    return m2;
-}
-
-static uint8_t *lookup_ref(MarshallerRef *ref)
-{
-    MarshallerItem *item;
-
-    item = &ref->marshaller->items[ref->item_nr];
-    return item->data + ref->offset;
-}
-
-
-void spice_marshaller_set_base(SpiceMarshaller *m, size_t base)
-{
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    m->data->base = base;
-}
-
-uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip_bytes,
-                                    size_t *len, int *free_res)
-{
-    MarshallerItem *item;
-    uint8_t *res, *p;
-    int i;
-
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    if (m->n_items == 1) {
-        *free_res = FALSE;
-        if (m->items[0].len <= skip_bytes) {
-            *len = 0;
-            return NULL;
-        }
-        *len = m->items[0].len - skip_bytes;
-        return m->items[0].data + skip_bytes;
-    }
-
-    *free_res = TRUE;
-    res = (uint8_t *)spice_malloc(m->data->total_size - skip_bytes);
-    *len = m->data->total_size - skip_bytes;
-    p = res;
-
-    do {
-        for (i = 0; i < m->n_items; i++) {
-            item = &m->items[i];
-
-            if (item->len <= skip_bytes) {
-                skip_bytes -= item->len;
-                continue;
-            }
-            memcpy(p, item->data + skip_bytes, item->len - skip_bytes);
-            p += item->len - skip_bytes;
-            skip_bytes = 0;
-        }
-        m = m->next;
-    } while (m != NULL);
-
-    return res;
-}
-
-uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m)
-{
-    return m->items[0].data;
-}
-
-size_t spice_marshaller_get_offset(SpiceMarshaller *m)
-{
-    SpiceMarshaller *m2;
-    size_t offset;
-
-    offset = 0;
-    m2 = m->data->marshallers;
-    while (m2 != m) {
-        offset += m2->total_size;
-        m2 = m2->next;
-    }
-    return offset - m->data->base;
-}
-
-size_t spice_marshaller_get_size(SpiceMarshaller *m)
-{
-    return m->total_size;
-}
-
-size_t spice_marshaller_get_total_size(SpiceMarshaller *m)
-{
-    return m->data->total_size;
-}
-
-void spice_marshaller_flush(SpiceMarshaller *m)
-{
-    SpiceMarshaller *m2;
-    uint8_t *ptr_pos;
-
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    for (m2 = m; m2 != NULL; m2 = m2->next) {
-        if (m2->pointer_ref.marshaller != NULL && m2->total_size > 0) {
-            ptr_pos = lookup_ref(&m2->pointer_ref);
-            if (m2->pointer_ref.is_64bit) {
-                write_uint64(ptr_pos,
-                             spice_marshaller_get_offset(m2));
-            } else {
-                write_uint32(ptr_pos,
-                             spice_marshaller_get_offset(m2));
-            }
-        }
-    }
-}
-
-#ifndef WIN32
-int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
-                                int n_vec, size_t skip_bytes)
-{
-    MarshallerItem *item;
-    int v, i;
-
-    /* Only supported for root marshaller */
-    assert(m->data->marshallers == m);
-
-    v = 0;
-    do {
-        for (i = 0; i < m->n_items; i++) {
-            item = &m->items[i];
-
-            if (item->len <= skip_bytes) {
-                skip_bytes -= item->len;
-                continue;
-            }
-            if (v == n_vec) {
-                return v; /* Not enough space in vec */
-            }
-            vec[v].iov_base = item->data + skip_bytes;
-            vec[v].iov_len = item->len - skip_bytes;
-            skip_bytes = 0;
-            v++;
-        }
-        m = m->next;
-    } while (m != NULL);
-
-    return v;
-}
-#endif
-
-void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(uint64_t));
-    write_uint64(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(int64_t));
-    write_int64(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(uint32_t));
-    write_uint32(ptr, v);
-    return (void *)ptr;
-}
-
-void spice_marshaller_set_uint32(SpiceMarshaller *m, void *ref, uint32_t v)
-{
-    write_uint32((uint8_t *)ref, v);
-}
-
-void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(int32_t));
-    write_int32(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(uint16_t));
-    write_uint16(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(int16_t));
-    write_int16(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(uint8_t));
-    write_uint8(ptr, v);
-    return (void *)ptr;
-}
-
-void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v)
-{
-    uint8_t *ptr;
-
-    ptr = spice_marshaller_reserve_space(m, sizeof(int8_t));
-    write_int8(ptr, v);
-    return (void *)ptr;
-}
diff --git a/common/marshaller.h b/common/marshaller.h
deleted file mode 100644
index ae68e85..0000000
--- a/common/marshaller.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_MARSHALLER
-#define _H_MARSHALLER
-
-#include <spice/types.h>
-#include "mem.h"
-#ifndef WIN32
-#include <sys/uio.h>
-#endif
-
-typedef struct SpiceMarshaller SpiceMarshaller;
-typedef void (*spice_marshaller_item_free_func)(uint8_t *data, void *opaque);
-
-SpiceMarshaller *spice_marshaller_new(void);
-void spice_marshaller_reset(SpiceMarshaller *m);
-void spice_marshaller_destroy(SpiceMarshaller *m);
-uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size);
-void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size);
-uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size);
-uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, uint8_t *data, size_t size);
-uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
-                                       spice_marshaller_item_free_func free_data, void *opaque);
-void     spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks);
-void spice_marshaller_flush(SpiceMarshaller *m);
-void spice_marshaller_set_base(SpiceMarshaller *m, size_t base);
-uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip,
-                                    size_t *len, int *free_res);
-uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m);
-size_t spice_marshaller_get_offset(SpiceMarshaller *m);
-size_t spice_marshaller_get_size(SpiceMarshaller *m);
-size_t spice_marshaller_get_total_size(SpiceMarshaller *m);
-SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m);
-SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit);
-#ifndef WIN32
-int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
-                                int n_vec, size_t skip_bytes);
-#endif
-void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v);
-void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v);
-void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v);
-void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v);
-void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v);
-void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v);
-void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v);
-void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v);
-
-void  spice_marshaller_set_uint32(SpiceMarshaller *m, void *ref, uint32_t v);
-
-#endif
diff --git a/common/marshallers.h b/common/marshallers.h
deleted file mode 100644
index c192d5b..0000000
--- a/common/marshallers.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_MARSHALLERS
-#define _H_MARSHALLERS
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <spice/protocol.h>
-#include <marshaller.h>
-#include <messages.h>
-
-typedef struct {
-    void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, SpiceMsgEmpty *msg);
-    void (*msg_SpiceMsgData)(SpiceMarshaller *m, SpiceMsgData *msg);
-    void (*msg_SpiceMsgAudioVolume)(SpiceMarshaller *m, SpiceMsgAudioVolume *msg);
-    void (*msg_SpiceMsgAudioMute)(SpiceMarshaller *m, SpiceMsgAudioMute *msg);
-    void (*msgc_ack_sync)(SpiceMarshaller *m, SpiceMsgcAckSync *msg);
-    void (*msgc_pong)(SpiceMarshaller *m, SpiceMsgPing *msg);
-    void (*msgc_disconnecting)(SpiceMarshaller *m, SpiceMsgDisconnect *msg);
-    void (*msgc_main_client_info)(SpiceMarshaller *m, SpiceMsgcClientInfo *msg);
-    void (*msgc_main_mouse_mode_request)(SpiceMarshaller *m, SpiceMsgcMainMouseModeRequest *msg);
-    void (*msgc_main_agent_start)(SpiceMarshaller *m, SpiceMsgcMainAgentStart *msg);
-    void (*msgc_main_agent_token)(SpiceMarshaller *m, SpiceMsgcMainAgentTokens *msg);
-    void (*msgc_display_init)(SpiceMarshaller *m, SpiceMsgcDisplayInit *msg);
-    void (*msgc_inputs_key_down)(SpiceMarshaller *m, SpiceMsgcKeyDown *msg);
-    void (*msgc_inputs_key_up)(SpiceMarshaller *m, SpiceMsgcKeyUp *msg);
-    void (*msgc_inputs_key_modifiers)(SpiceMarshaller *m, SpiceMsgcKeyModifiers *msg);
-    void (*msgc_inputs_mouse_motion)(SpiceMarshaller *m, SpiceMsgcMouseMotion *msg);
-    void (*msgc_inputs_mouse_position)(SpiceMarshaller *m, SpiceMsgcMousePosition *msg);
-    void (*msgc_inputs_mouse_press)(SpiceMarshaller *m, SpiceMsgcMousePress *msg);
-    void (*msgc_inputs_mouse_release)(SpiceMarshaller *m, SpiceMsgcMouseRelease *msg);
-    void (*msgc_record_data)(SpiceMarshaller *m, SpiceMsgcRecordPacket *msg);
-    void (*msgc_record_mode)(SpiceMarshaller *m, SpiceMsgcRecordMode *msg);
-    void (*msgc_record_start_mark)(SpiceMarshaller *m, SpiceMsgcRecordStartMark *msg);
-    void (*msgc_tunnel_service_add)(SpiceMarshaller *m, SpiceMsgcTunnelAddGenericService *msg, SpiceMarshaller **name_out, SpiceMarshaller **description_out);
-    void (*msgc_tunnel_service_remove)(SpiceMarshaller *m, SpiceMsgcTunnelRemoveService *msg);
-    void (*msgc_tunnel_socket_open_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenAck *msg);
-    void (*msgc_tunnel_socket_open_nack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenNack *msg);
-    void (*msgc_tunnel_socket_fin)(SpiceMarshaller *m, SpiceMsgcTunnelSocketFin *msg);
-    void (*msgc_tunnel_socket_closed)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosed *msg);
-    void (*msgc_tunnel_socket_closed_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosedAck *msg);
-    void (*msgc_tunnel_socket_data)(SpiceMarshaller *m, SpiceMsgcTunnelSocketData *msg);
-    void (*msgc_tunnel_socket_token)(SpiceMarshaller *m, SpiceMsgcTunnelSocketTokens *msg);
-#ifdef USE_SMARTCARD
-    void (*msgc_smartcard_atr)(SpiceMarshaller *m, VSCMsgATR *msg);
-    void (*msgc_smartcard_error)(SpiceMarshaller *m, VSCMsgError *msg);
-    void (*msgc_smartcard_header)(SpiceMarshaller *m, VSCMsgHeader *msg);
-    void (*msgc_smartcard_msg)(SpiceMarshaller *m, SpiceMsgcSmartcard *msg, SpiceMarshaller **reader_name_out);
-    void (*msgc_smartcard_reader_add)(SpiceMarshaller *m, VSCMsgReaderAdd *msg);
-#endif
-} SpiceMessageMarshallers;
-
-SpiceMessageMarshallers *spice_message_marshallers_get(void);
-SpiceMessageMarshallers *spice_message_marshallers_get1(void);
-
-#endif
diff --git a/common/mem.c b/common/mem.c
deleted file mode 100644
index 4db8a2c..0000000
--- a/common/mem.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "mem.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef MALLOC_ERROR
-#define MALLOC_ERROR(format, ...) {                             \
-    printf(format "\n", ## __VA_ARGS__);   \
-    abort();                                                    \
-}
-#endif
-
-size_t spice_strnlen(const char *str, size_t max_len)
-{
-    size_t len = 0;
-
-    while (len < max_len && *str != 0) {
-        len++;
-        str++;
-    }
-
-    return len;
-}
-
-char *spice_strdup(const char *str)
-{
-    char *copy;
-
-    if (str == NULL) {
-        return NULL;
-    }
-
-    copy = (char *)spice_malloc(strlen(str) + 1);
-    strcpy(copy, str);
-    return copy;
-}
-
-char *spice_strndup(const char *str, size_t n_bytes)
-{
-    char *copy;
-
-    if (str == NULL) {
-        return NULL;
-    }
-
-    copy = (char *)spice_malloc(n_bytes + 1);
-    strncpy(copy, str, n_bytes);
-    copy[n_bytes] = 0;
-    return copy;
-}
-
-void *spice_memdup(const void *mem, size_t n_bytes)
-{
-    void *copy;
-
-    if (mem == NULL) {
-        return NULL;
-    }
-
-    copy = spice_malloc(n_bytes);
-    memcpy(copy, mem, n_bytes);
-    return copy;
-}
-
-void *spice_malloc(size_t n_bytes)
-{
-    void *mem;
-
-    if (SPICE_LIKELY(n_bytes)) {
-        mem = malloc(n_bytes);
-
-        if (SPICE_LIKELY(mem != NULL)) {
-            return mem;
-        }
-
-        MALLOC_ERROR("spice_malloc: panic: unable to allocate %lu bytes\n",
-                     (unsigned long)n_bytes);
-    }
-    return NULL;
-}
-
-void *spice_malloc0(size_t n_bytes)
-{
-    void *mem;
-
-    if (SPICE_LIKELY(n_bytes)) {
-        mem = calloc(1, n_bytes);
-
-        if (SPICE_LIKELY(mem != NULL)) {
-            return mem;
-        }
-
-        MALLOC_ERROR("spice_malloc0: panic: unable to allocate %lu bytes\n",
-                     (unsigned long)n_bytes);
-    }
-    return NULL;
-}
-
-void *spice_realloc(void *mem, size_t n_bytes)
-{
-    if (SPICE_LIKELY(n_bytes)) {
-        mem = realloc(mem, n_bytes);
-
-        if (SPICE_LIKELY(mem != NULL)) {
-            return mem;
-        }
-
-        MALLOC_ERROR("spice_realloc: panic: unable to allocate %lu bytes\n",
-                     (unsigned long)n_bytes);
-    }
-
-    if (mem) {
-        free(mem);
-    }
-
-    return NULL;
-}
-
-#define SIZE_OVERFLOWS(a,b) (SPICE_UNLIKELY ((a) > SIZE_MAX / (b)))
-
-void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes)
-{
-    if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
-        MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu bytes",
-                     (unsigned long)n_blocks, (unsigned long)n_block_bytes);
-    }
-
-    return spice_malloc(n_blocks * n_block_bytes);
-}
-
-void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size)
-{
-    size_t size1, size2;
-    if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
-        MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
-                     (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
-    }
-    size1 = n_blocks * n_block_bytes;
-    size2 = size1 + extra_size;
-    if (size2 < size1) {
-        MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
-                     (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
-    }
-    return spice_malloc(size2);
-}
-
-
-void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes)
-{
-    if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
-        MALLOC_ERROR("spice_malloc0_n: overflow allocating %lu*%lu bytes",
-                     (unsigned long)n_blocks, (unsigned long)n_block_bytes);
-    }
-
-    return spice_malloc0 (n_blocks * n_block_bytes);
-}
-
-void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes)
-{
-    if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
-        MALLOC_ERROR("spice_realloc_n: overflow allocating %lu*%lu bytes",
-                     (unsigned long)n_blocks, (unsigned long)n_block_bytes);
-  }
-
-    return spice_realloc(mem, n_blocks * n_block_bytes);
-}
-
-SpiceChunks *spice_chunks_new(uint32_t count)
-{
-    SpiceChunks *chunks;
-
-    chunks = (SpiceChunks *)spice_malloc_n_m(count, sizeof(SpiceChunk), sizeof(SpiceChunks));
-    chunks->flags = 0;
-    chunks->num_chunks = count;
-
-    return chunks;
-}
-
-SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len)
-{
-    SpiceChunks *chunks;
-
-    chunks = spice_chunks_new(1);
-    chunks->data_size = chunks->chunk[0].len = len;
-    chunks->chunk[0].data = data;
-    return chunks;
-}
-
-void spice_chunks_destroy(SpiceChunks *chunks)
-{
-    unsigned int i;
-
-    if (chunks->flags & SPICE_CHUNKS_FLAGS_FREE) {
-        for (i = 0; i < chunks->num_chunks; i++) {
-            free(chunks->chunk[i].data);
-        }
-    }
-
-    free(chunks);
-}
-
-void spice_chunks_linearize(SpiceChunks *chunks)
-{
-    uint8_t *data, *p;
-    unsigned int i;
-
-    if (chunks->num_chunks > 1) {
-        data = (uint8_t*)spice_malloc(chunks->data_size);
-        for (p = data, i = 0; i < chunks->num_chunks; i++) {
-            memcpy(p, chunks->chunk[i].data,
-                   chunks->chunk[i].len);
-            p += chunks->chunk[i].len;
-        }
-        if (chunks->flags & SPICE_CHUNKS_FLAGS_FREE) {
-            for (i = 0; i < chunks->num_chunks; i++) {
-                free(chunks->chunk[i].data);
-            }
-        }
-        chunks->num_chunks = 1;
-        chunks->flags |= SPICE_CHUNKS_FLAGS_FREE;
-        chunks->flags &= ~SPICE_CHUNKS_FLAGS_UNSTABLE;
-        chunks->chunk[0].data = data;
-        chunks->chunk[0].len = chunks->data_size;
-    }
-}
diff --git a/common/mem.h b/common/mem.h
deleted file mode 100644
index 6863953..0000000
--- a/common/mem.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_MEM
-#define _H_MEM
-
-#include <stdlib.h>
-#include <spice/macros.h>
-
-/* alloca definition from glib/galloca.h */
-#ifdef  __GNUC__
-/* GCC does the right thing */
-# undef alloca
-# define alloca(size)   __builtin_alloca (size)
-#elif defined (GLIB_HAVE_ALLOCA_H)
-/* a native and working alloca.h is there */
-# include <alloca.h>
-#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
-# if defined(_MSC_VER) || defined(__DMC__)
-#  include <malloc.h>
-#  define alloca _alloca
-# else /* !_MSC_VER && !__DMC__ */
-#  ifdef _AIX
-#   pragma alloca
-#  else /* !_AIX */
-#   ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#   endif /* !alloca */
-#  endif /* !_AIX */
-# endif /* !_MSC_VER && !__DMC__ */
-#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
-
-typedef struct SpiceChunk {
-    uint8_t *data;
-    uint32_t len;
-} SpiceChunk;
-
-enum {
-    SPICE_CHUNKS_FLAGS_UNSTABLE = (1<<0),
-    SPICE_CHUNKS_FLAGS_FREE = (1<<1)
-};
-
-typedef struct SpiceChunks {
-    uint32_t     data_size;
-    uint32_t     num_chunks;
-    uint32_t     flags;
-    SpiceChunk   chunk[0];
-} SpiceChunks;
-
-char *spice_strdup(const char *str) SPICE_GNUC_MALLOC;
-char *spice_strndup(const char *str, size_t n_bytes) SPICE_GNUC_MALLOC;
-void *spice_memdup(const void *mem, size_t n_bytes) SPICE_GNUC_MALLOC;
-void *spice_malloc(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
-void *spice_malloc0(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
-void *spice_realloc(void *mem, size_t n_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
-void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
-void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size) SPICE_GNUC_MALLOC;
-void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
-void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
-SpiceChunks *spice_chunks_new(uint32_t count) SPICE_GNUC_MALLOC;
-SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len) SPICE_GNUC_MALLOC;
-void spice_chunks_destroy(SpiceChunks *chunks);
-void spice_chunks_linearize(SpiceChunks *chunks);
-
-size_t spice_strnlen(const char *str, size_t max_len);
-
-/* Optimize: avoid the call to the (slower) _n function if we can
- * determine at compile-time that no overflow happens.
- */
-#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
-#  define _SPICE_NEW(struct_type, n_structs, func)        \
-    (struct_type *) (__extension__ ({                     \
-        size_t __n = (size_t) (n_structs);                \
-        size_t __s = sizeof (struct_type);                \
-        void *__p;                                        \
-        if (__s == 1)                                     \
-            __p = spice_##func (__n);                     \
-        else if (__builtin_constant_p (__n) &&            \
-                 __n <= SIZE_MAX / __s)                   \
-            __p = spice_##func (__n * __s);               \
-        else                                              \
-            __p = spice_##func##_n (__n, __s);            \
-        __p;                                              \
-    }))
-#  define _SPICE_RENEW(struct_type, mem, n_structs, func) \
-    (struct_type *) (__extension__ ({                             \
-        size_t __n = (size_t) (n_structs);                \
-        size_t __s = sizeof (struct_type);                \
-        void *__p = (void *) (mem);                       \
-        if (__s == 1)                                     \
-            __p = spice_##func (__p, __n);                \
-        else if (__builtin_constant_p (__n) &&            \
-                 __n <= SIZE_MAX / __s)                   \
-            __p = spice_##func (__p, __n * __s);          \
-        else                                              \
-            __p = spice_##func##_n (__p, __n, __s);       \
-        __p;                                              \
-    }))
-#else
-
-/* Unoptimized version: always call the _n() function. */
-
-#define _SPICE_NEW(struct_type, n_structs, func)                        \
-    ((struct_type *) spice_##func##_n ((n_structs), sizeof (struct_type)))
-#define _SPICE_RENEW(struct_type, mem, n_structs, func)                 \
-    ((struct_type *) spice_##func##_n (mem, (n_structs), sizeof (struct_type)))
-
-#endif
-
-#define spice_new(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc)
-#define spice_new0(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc0)
-#define spice_renew(struct_type, mem, n_structs) _SPICE_RENEW(struct_type, mem, n_structs, realloc)
-
-#endif
diff --git a/common/messages.h b/common/messages.h
deleted file mode 100644
index 01689cd..0000000
--- a/common/messages.h
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
-   Copyright (C) 2009-2010 Red Hat, Inc.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are
-   met:
-
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in
-         the documentation and/or other materials provided with the
-         distribution.
-       * Neither the name of the copyright holder nor the names of its
-         contributors may be used to endorse or promote products derived
-         from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
-   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-   TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-   PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef _H_MESSAGES
-#define _H_MESSAGES
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <spice/protocol.h>
-#ifdef USE_SMARTCARD
-#include <vscard_common.h>
-#endif
-#include "draw.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct SpiceMsgData {
-    uint32_t data_size;
-    uint8_t data[0];
-} SpiceMsgData;
-
-typedef struct SpiceMsgEmpty {
-} SpiceMsgEmpty;
-
-typedef struct SpiceMsgInputsInit {
-    uint32_t keyboard_modifiers;
-} SpiceMsgInputsInit;
-
-typedef struct SpiceMsgInputsKeyModifiers {
-    uint32_t modifiers;
-} SpiceMsgInputsKeyModifiers;
-
-typedef struct SpiceMsgMainMultiMediaTime {
-    uint32_t time;
-} SpiceMsgMainMultiMediaTime;
-
-typedef struct SpiceMsgMainMigrationBegin {
-    uint16_t port;
-    uint16_t sport;
-    uint32_t host_size;
-    uint8_t *host_data;
-    uint16_t pub_key_type;
-    uint32_t pub_key_size;
-    uint8_t *pub_key_data;
-    uint32_t cert_subject_size;
-    uint8_t *cert_subject_data;
-} SpiceMsgMainMigrationBegin;
-
-typedef struct SpiceMsgMainMigrationSwitchHost {
-    uint16_t port;
-    uint16_t sport;
-    uint32_t host_size;
-    uint8_t *host_data;
-    uint32_t cert_subject_size;
-    uint8_t *cert_subject_data;
-} SpiceMsgMainMigrationSwitchHost;
-
-
-typedef struct SpiceMsgMigrate {
-    uint32_t flags;
-} SpiceMsgMigrate;
-
-typedef struct SpiceResourceID {
-    uint8_t type;
-    uint64_t id;
-} SpiceResourceID;
-
-typedef struct SpiceResourceList {
-    uint16_t count;
-    SpiceResourceID resources[0];
-} SpiceResourceList;
-
-typedef struct SpiceMsgSetAck {
-    uint32_t generation;
-    uint32_t window;
-} SpiceMsgSetAck;
-
-typedef struct SpiceMsgcAckSync {
-  uint32_t generation;
-} SpiceMsgcAckSync;
-
-typedef struct SpiceWaitForChannel {
-    uint8_t channel_type;
-    uint8_t channel_id;
-    uint64_t message_serial;
-} SpiceWaitForChannel;
-
-typedef struct SpiceMsgWaitForChannels {
-    uint8_t wait_count;
-    SpiceWaitForChannel wait_list[0];
-} SpiceMsgWaitForChannels;
-
-typedef struct SpiceChannelId {
-    uint8_t type;
-    uint8_t id;
-} SpiceChannelId;
-
-typedef struct SpiceMsgMainInit {
-    uint32_t session_id;
-    uint32_t display_channels_hint;
-    uint32_t supported_mouse_modes;
-    uint32_t current_mouse_mode;
-    uint32_t agent_connected;
-    uint32_t agent_tokens;
-    uint32_t multi_media_time;
-    uint32_t ram_hint;
-} SpiceMsgMainInit;
-
-typedef struct SpiceMsgDisconnect {
-    uint64_t time_stamp;
-    uint32_t reason; // SPICE_ERR_?
-} SpiceMsgDisconnect;
-
-typedef struct SpiceMsgNotify {
-    uint64_t time_stamp;
-    uint32_t severity;
-    uint32_t visibilty;
-    uint32_t what;
-    uint32_t message_len;
-    uint8_t message[0];
-} SpiceMsgNotify;
-
-typedef struct SpiceMsgChannels {
-    uint32_t num_of_channels;
-    SpiceChannelId channels[0];
-} SpiceMsgChannels;
-
-typedef struct SpiceMsgMainName {
-    uint32_t name_len;
-    uint8_t name[0];
-} SpiceMsgMainName;
-
-typedef struct SpiceMsgMainUuid {
-    uint8_t uuid[16];
-} SpiceMsgMainUuid;
-
-typedef struct SpiceMsgMainMouseMode {
-    uint32_t supported_modes;
-    uint32_t current_mode;
-} SpiceMsgMainMouseMode;
-
-typedef struct SpiceMsgPing {
-    uint32_t id;
-    uint64_t timestamp;
-    void *data;
-    uint32_t data_len;
-} SpiceMsgPing;
-
-typedef struct SpiceMsgMainAgentDisconnect {
-    uint32_t error_code; // SPICE_ERR_?
-} SpiceMsgMainAgentDisconnect;
-
-#define SPICE_AGENT_MAX_DATA_SIZE 2048
-
-typedef struct SpiceMsgMainAgentTokens {
-    uint32_t num_tokens;
-} SpiceMsgMainAgentTokens, SpiceMsgcMainAgentTokens, SpiceMsgcMainAgentStart;
-
-typedef struct SpiceMsgcClientInfo {
-    uint64_t cache_size;
-} SpiceMsgcClientInfo;
-
-typedef struct SpiceMsgcMainMouseModeRequest {
-    uint32_t mode;
-} SpiceMsgcMainMouseModeRequest;
-
-typedef struct SpiceCursor {
-    uint32_t flags;
-    SpiceCursorHeader header;
-    uint32_t data_size;
-    uint8_t *data;
-} SpiceCursor;
-
-typedef struct SpiceMsgDisplayMode {
-    uint32_t x_res;
-    uint32_t y_res;
-    uint32_t bits;
-} SpiceMsgDisplayMode;
-
-typedef struct SpiceMsgSurfaceCreate {
-    uint32_t surface_id;
-    uint32_t width;
-    uint32_t height;
-    uint32_t format;
-    uint32_t flags;
-} SpiceMsgSurfaceCreate;
-
-typedef struct SpiceMsgSurfaceDestroy {
-    uint32_t surface_id;
-} SpiceMsgSurfaceDestroy;
-
-typedef struct SpiceMsgDisplayBase {
-    uint32_t surface_id;
-    SpiceRect box;
-    SpiceClip clip;
-} SpiceMsgDisplayBase;
-
-typedef struct SpiceMsgDisplayDrawFill {
-    SpiceMsgDisplayBase base;
-    SpiceFill data;
-} SpiceMsgDisplayDrawFill;
-
-typedef struct SpiceMsgDisplayDrawOpaque {
-    SpiceMsgDisplayBase base;
-    SpiceOpaque data;
-} SpiceMsgDisplayDrawOpaque;
-
-typedef struct SpiceMsgDisplayDrawCopy {
-    SpiceMsgDisplayBase base;
-    SpiceCopy data;
-} SpiceMsgDisplayDrawCopy;
-
-typedef struct SpiceMsgDisplayDrawTransparent {
-    SpiceMsgDisplayBase base;
-    SpiceTransparent data;
-} SpiceMsgDisplayDrawTransparent;
-
-typedef struct SpiceMsgDisplayDrawAlphaBlend {
-    SpiceMsgDisplayBase base;
-    SpiceAlphaBlend data;
-} SpiceMsgDisplayDrawAlphaBlend;
-
-typedef struct SpiceMsgDisplayCopyBits {
-    SpiceMsgDisplayBase base;
-    SpicePoint src_pos;
-} SpiceMsgDisplayCopyBits;
-
-typedef SpiceMsgDisplayDrawCopy SpiceMsgDisplayDrawBlend;
-
-typedef struct SpiceMsgDisplayDrawRop3 {
-    SpiceMsgDisplayBase base;
-    SpiceRop3 data;
-} SpiceMsgDisplayDrawRop3;
-
-typedef struct SpiceMsgDisplayDrawBlackness {
-    SpiceMsgDisplayBase base;
-    SpiceBlackness data;
-} SpiceMsgDisplayDrawBlackness;
-
-typedef struct SpiceMsgDisplayDrawWhiteness {
-    SpiceMsgDisplayBase base;
-    SpiceWhiteness data;
-} SpiceMsgDisplayDrawWhiteness;
-
-typedef struct SpiceMsgDisplayDrawInvers {
-    SpiceMsgDisplayBase base;
-    SpiceInvers data;
-} SpiceMsgDisplayDrawInvers;
-
-typedef struct SpiceMsgDisplayDrawStroke {
-    SpiceMsgDisplayBase base;
-    SpiceStroke data;
-} SpiceMsgDisplayDrawStroke;
-
-typedef struct SpiceMsgDisplayDrawText {
-    SpiceMsgDisplayBase base;
-    SpiceText data;
-} SpiceMsgDisplayDrawText;
-
-typedef struct SpiceMsgDisplayInvalOne {
-    uint64_t id;
-} SpiceMsgDisplayInvalOne;
-
-typedef struct SpiceMsgDisplayStreamCreate {
-    uint32_t surface_id;
-    uint32_t id;
-    uint32_t flags;
-    uint32_t codec_type;
-    uint64_t stamp;
-    uint32_t stream_width;
-    uint32_t stream_height;
-    uint32_t src_width;
-    uint32_t src_height;
-    SpiceRect dest;
-    SpiceClip clip;
-} SpiceMsgDisplayStreamCreate;
-
-typedef struct SpiceMsgDisplayStreamData {
-    uint32_t id;
-    uint32_t multi_media_time;
-    uint32_t data_size;
-    uint8_t data[0];
-} SpiceMsgDisplayStreamData;
-
-typedef struct SpiceMsgDisplayStreamClip {
-    uint32_t id;
-    SpiceClip clip;
-} SpiceMsgDisplayStreamClip;
-
-typedef struct SpiceMsgDisplayStreamDestroy {
-    uint32_t id;
-} SpiceMsgDisplayStreamDestroy;
-
-typedef struct SpiceMsgCursorInit {
-    SpicePoint16 position;
-    uint16_t trail_length;
-    uint16_t trail_frequency;
-    uint8_t visible;
-    SpiceCursor cursor;
-} SpiceMsgCursorInit;
-
-typedef struct SpiceMsgCursorSet {
-    SpicePoint16 position;
-    uint8_t visible;
-    SpiceCursor cursor;
-} SpiceMsgCursorSet;
-
-typedef struct SpiceMsgCursorMove {
-    SpicePoint16 position;
-} SpiceMsgCursorMove;
-
-typedef struct SpiceMsgCursorTrail {
-    uint16_t length;
-    uint16_t frequency;
-} SpiceMsgCursorTrail;
-
-typedef struct SpiceMsgcDisplayInit {
-    uint8_t pixmap_cache_id;
-    int64_t pixmap_cache_size; //in pixels
-    uint8_t glz_dictionary_id;
-    int32_t glz_dictionary_window_size;       // in pixels
-} SpiceMsgcDisplayInit;
-
-typedef struct SpiceMsgcKeyDown {
-    uint32_t code;
-} SpiceMsgcKeyDown;
-
-typedef struct SpiceMsgcKeyUp {
-    uint32_t code;
-} SpiceMsgcKeyUp;
-
-typedef struct SpiceMsgcKeyModifiers {
-    uint32_t modifiers;
-} SpiceMsgcKeyModifiers;
-
-typedef struct SpiceMsgcMouseMotion {
-    int32_t dx;
-    int32_t dy;
-    uint32_t buttons_state;
-} SpiceMsgcMouseMotion;
-
-typedef struct SpiceMsgcMousePosition {
-    uint32_t x;
-    uint32_t y;
-    uint32_t buttons_state;
-    uint8_t display_id;
-} SpiceMsgcMousePosition;
-
-typedef struct SpiceMsgcMousePress {
-    int32_t button;
-    int32_t buttons_state;
-} SpiceMsgcMousePress;
-
-typedef struct SpiceMsgcMouseRelease {
-    int32_t button;
-    int32_t buttons_state;
-} SpiceMsgcMouseRelease;
-
-typedef struct SpiceMsgAudioVolume {
-    uint8_t nchannels;
-    uint16_t volume[0];
-} SpiceMsgAudioVolume;
-
-typedef struct SpiceMsgAudioMute {
-    uint8_t mute;
-} SpiceMsgAudioMute;
-
-typedef struct SpiceMsgPlaybackMode {
-    uint32_t time;
-    uint32_t mode; //SPICE_AUDIO_DATA_MODE_?
-    uint8_t *data;
-    uint32_t data_size;
-} SpiceMsgPlaybackMode, SpiceMsgcRecordMode;
-
-typedef struct SpiceMsgPlaybackStart {
-    uint32_t channels;
-    uint32_t format; //SPICE_AUDIO_FMT_?
-    uint32_t frequency;
-    uint32_t time;
-} SpiceMsgPlaybackStart;
-
-typedef struct SpiceMsgPlaybackPacket {
-    uint32_t time;
-    uint8_t *data;
-    uint32_t data_size;
-} SpiceMsgPlaybackPacket, SpiceMsgcRecordPacket;
-
-typedef struct SpiceMsgRecordStart {
-    uint32_t channels;
-    uint32_t format; //SPICE_AUDIO_FMT_?
-    uint32_t frequency;
-} SpiceMsgRecordStart;
-
-typedef struct SpiceMsgcRecordStartMark {
-    uint32_t time;
-} SpiceMsgcRecordStartMark;
-
-typedef struct SpiceMsgTunnelInit {
-    uint16_t max_num_of_sockets;
-    uint32_t max_socket_data_size;
-} SpiceMsgTunnelInit;
-
-typedef uint8_t SpiceTunnelIPv4[4];
-
-typedef struct SpiceMsgTunnelIpInfo {
-    uint16_t type;
-    union {
-      SpiceTunnelIPv4 ipv4;
-    } u;
-    uint8_t data[0];
-} SpiceMsgTunnelIpInfo;
-
-typedef struct SpiceMsgTunnelServiceIpMap {
-    uint32_t service_id;
-    SpiceMsgTunnelIpInfo virtual_ip;
-} SpiceMsgTunnelServiceIpMap;
-
-typedef struct SpiceMsgTunnelSocketOpen {
-    uint16_t connection_id;
-    uint32_t service_id;
-    uint32_t tokens;
-} SpiceMsgTunnelSocketOpen;
-
-/* connection id must be the first field in msgs directed to a specific connection */
-
-typedef struct SpiceMsgTunnelSocketFin {
-    uint16_t connection_id;
-} SpiceMsgTunnelSocketFin;
-
-typedef struct SpiceMsgTunnelSocketClose {
-    uint16_t connection_id;
-} SpiceMsgTunnelSocketClose;
-
-typedef struct SpiceMsgTunnelSocketData {
-    uint16_t connection_id;
-    uint8_t data[0];
-} SpiceMsgTunnelSocketData;
-
-typedef struct SpiceMsgTunnelSocketTokens {
-    uint16_t connection_id;
-    uint32_t num_tokens;
-} SpiceMsgTunnelSocketTokens;
-
-typedef struct SpiceMsgTunnelSocketClosedAck {
-    uint16_t connection_id;
-} SpiceMsgTunnelSocketClosedAck;
-
-typedef struct SpiceMsgcTunnelAddGenericService {
-    uint32_t type;
-    uint32_t id;
-    uint32_t group;
-    uint32_t port;
-    uint64_t name;
-    uint64_t description;
-    union {
-        SpiceMsgTunnelIpInfo ip;
-    } u;
-} SpiceMsgcTunnelAddGenericService;
-
-typedef struct SpiceMsgcTunnelRemoveService {
-    uint32_t id;
-} SpiceMsgcTunnelRemoveService;
-
-/* connection id must be the first field in msgs directed to a specific connection */
-
-typedef struct SpiceMsgcTunnelSocketOpenAck {
-    uint16_t connection_id;
-    uint32_t tokens;
-} SpiceMsgcTunnelSocketOpenAck;
-
-typedef struct SpiceMsgcTunnelSocketOpenNack {
-    uint16_t connection_id;
-} SpiceMsgcTunnelSocketOpenNack;
-
-typedef struct SpiceMsgcTunnelSocketData {
-    uint16_t connection_id;
-    uint8_t data[0];
-} SpiceMsgcTunnelSocketData;
-
-typedef struct SpiceMsgcTunnelSocketFin {
-    uint16_t connection_id;
-} SpiceMsgcTunnelSocketFin;
-
-typedef struct SpiceMsgcTunnelSocketClosed {
-    uint16_t connection_id;
-} SpiceMsgcTunnelSocketClosed;
-
-typedef struct SpiceMsgcTunnelSocketClosedAck {
-    uint16_t connection_id;
-} SpiceMsgcTunnelSocketClosedAck;
-
-typedef struct SpiceMsgcTunnelSocketTokens {
-    uint16_t connection_id;
-    uint32_t num_tokens;
-} SpiceMsgcTunnelSocketTokens;
-
-#ifdef USE_SMARTCARD
-typedef struct SpiceMsgSmartcard {
-    VSCMsgType type;
-    uint32_t length;
-    uint32_t reader_id;
-    uint8_t data[0];
-} SpiceMsgSmartcard;
-
-typedef struct SpiceMsgcSmartcard {
-    VSCMsgHeader header;
-    union {
-        VSCMsgError error;
-        VSCMsgATR atr_data;
-        VSCMsgReaderAdd add;
-    };
-} SpiceMsgcSmartcard;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _H_SPICE_PROTOCOL */
diff --git a/common/mutex.h b/common/mutex.h
deleted file mode 100644
index a2d35de..0000000
--- a/common/mutex.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_MUTEX
-#define _H_MUTEX
-#ifdef _WIN32
-#include <windows.h>
-typedef CRITICAL_SECTION mutex_t;
-#define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex)
-#define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex)
-#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
-#else
-#include <pthread.h>
-typedef pthread_mutex_t mutex_t;
-#define MUTEX_INIT(mutex) pthread_mutex_init(&mutex, NULL);
-#define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex)
-#define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex)
-#endif
-
-#endif // _H_MUTEX
diff --git a/common/ogl_ctx.c b/common/ogl_ctx.c
deleted file mode 100644
index ae25c2d..0000000
--- a/common/ogl_ctx.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <GL/glx.h>
-
-#include "ogl_ctx.h"
-
-
-#define PANIC(str) {                                \
-    printf("%s: panic: %s", __FUNCTION__, str);     \
-    abort();                                        \
-}
-
-enum {
-    OGLCTX_TYPE_PBUF,
-    OGLCTX_TYPE_PIXMAP,
-};
-
-struct OGLCtx {
-    int type;
-    Display *x_display;
-    GLXContext glx_context;
-    GLXDrawable drawable;
-};
-
-typedef struct OGLPixmapCtx {
-    OGLCtx base;
-    Pixmap pixmap;
-} OGLPixmapCtx;
-
-
-
-const char *oglctx_type_str(OGLCtx *ctx)
-{
-    static const char *pbuf_str = "pbuf";
-    static const char *pixmap_str = "pixmap";
-    static const char *invalid_str = "invalid";
-
-    switch (ctx->type) {
-    case OGLCTX_TYPE_PBUF:
-        return pbuf_str;
-    case OGLCTX_TYPE_PIXMAP:
-        return pixmap_str;
-    default:
-        return invalid_str;
-    }
-}
-
-void oglctx_make_current(OGLCtx *ctx)
-{
-    if (!glXMakeCurrent(ctx->x_display, ctx->drawable, ctx->glx_context)) {
-        printf("%s: failed\n", __FUNCTION__);
-    }
-}
-
-OGLCtx *pbuf_create(int width, int heigth)
-{
-    OGLCtx *ctx;
-    Display *x_display;
-    int num_configs;
-    GLXFBConfig *fb_config;
-    GLXPbuffer glx_pbuf;
-    GLXContext glx_context;
-
-    const int glx_attributes[] = {  GLX_RENDER_TYPE, GLX_RGBA_BIT,
-                                    GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
-                                    GLX_RED_SIZE, 8,
-                                    GLX_GREEN_SIZE, 8,
-                                    GLX_BLUE_SIZE, 8,
-                                    GLX_ALPHA_SIZE, 8,
-                                    GLX_STENCIL_SIZE, 4,
-                                    0 };
-
-    int pbuf_attrib[] = { GLX_PRESERVED_CONTENTS, True,
-                          GLX_PBUFFER_WIDTH, width,
-                          GLX_PBUFFER_HEIGHT, heigth,
-                          GLX_LARGEST_PBUFFER, False,
-                          0, 0 };
-
-    if (!(ctx = calloc(1, sizeof(*ctx)))) {
-        printf("%s: alloc pbuf failed\n", __FUNCTION__);
-        return NULL;
-    }
-
-    if (!(x_display = XOpenDisplay(NULL))) {
-        printf("%s: open display failed\n", __FUNCTION__);
-        goto error_1;
-    }
-
-    if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) ||
-                                                                            !num_configs) {
-        printf("%s: choose fb config failed\n", __FUNCTION__);
-        goto error_2;
-    }
-
-    if (!(glx_pbuf = glXCreatePbuffer(x_display, fb_config[0], pbuf_attrib))) {
-        goto error_3;
-    }
-
-    if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
-        printf("%s: create context failed\n", __FUNCTION__);
-        goto error_4;
-    }
-
-    XFree(fb_config);
-
-    ctx->type = OGLCTX_TYPE_PBUF;
-    ctx->drawable = glx_pbuf;
-    ctx->glx_context = glx_context;
-    ctx->x_display = x_display;
-
-    return ctx;
-
-error_4:
-    glXDestroyPbuffer(x_display, glx_pbuf);
-
-error_3:
-    XFree(fb_config);
-
-error_2:
-    XCloseDisplay(x_display);
-
-error_1:
-    free(ctx);
-
-    return NULL;
-}
-
-OGLCtx *pixmap_create(int width, int heigth)
-{
-    Display *x_display;
-    int num_configs;
-    GLXFBConfig *fb_config;
-    GLXPixmap glx_pixmap;
-    GLXContext glx_context;
-    Pixmap pixmap;
-    int screen;
-    Window root_window;
-    OGLPixmapCtx *pix;
-
-    const int glx_attributes[] = {  GLX_RENDER_TYPE, GLX_RGBA_BIT,
-                                    GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
-                                    GLX_RED_SIZE, 8,
-                                    GLX_GREEN_SIZE, 8,
-                                    GLX_BLUE_SIZE, 8,
-                                    GLX_ALPHA_SIZE, 8,
-                                    GLX_STENCIL_SIZE, 4,
-                                    0 };
-
-    if (!(pix = calloc(1, sizeof(*pix)))) {
-        printf("%s: alloc pix failed\n", __FUNCTION__);
-        return NULL;
-    }
-
-    if (!(x_display = XOpenDisplay(NULL))) {
-        printf("%s: open display failed\n", __FUNCTION__);
-        goto error_1;
-    }
-
-    screen = DefaultScreen(x_display);
-    root_window = RootWindow(x_display, screen);
-
-    if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) ||
-                                                                              !num_configs) {
-        printf("%s: choose fb config failed\n", __FUNCTION__);
-        goto error_2;
-    }
-
-    if (!(pixmap = XCreatePixmap(x_display, root_window, width, heigth, 32 /*use fb config*/))) {
-        printf("%s: create x pixmap failed\n", __FUNCTION__);
-        goto error_3;
-    }
-
-    if (!(glx_pixmap = glXCreatePixmap(x_display, fb_config[0], pixmap, NULL))) {
-        printf("%s: create glx pixmap failed\n", __FUNCTION__);
-        goto error_4;
-    }
-
-
-    if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) {
-        printf("%s: create context failed\n", __FUNCTION__);
-        goto error_5;
-    }
-
-    XFree(fb_config);
-
-    pix->base.type = OGLCTX_TYPE_PIXMAP;
-    pix->base.x_display = x_display;
-    pix->base.drawable = glx_pixmap;
-    pix->base.glx_context = glx_context;
-    pix->pixmap = pixmap;
-
-    return &pix->base;
-
-error_5:
-    glXDestroyPixmap(x_display, glx_pixmap);
-
-error_4:
-    XFreePixmap(x_display, pixmap);
-
-error_3:
-    XFree(fb_config);
-
-error_2:
-    XCloseDisplay(x_display);
-
-error_1:
-    free(pix);
-
-    return NULL;
-}
-
-void oglctx_destroy(OGLCtx *ctx)
-{
-    if (!ctx) {
-        return;
-    }
-    // test is current ?
-
-    glXDestroyContext(ctx->x_display, ctx->glx_context);
-    switch (ctx->type) {
-    case OGLCTX_TYPE_PBUF:
-        glXDestroyPbuffer(ctx->x_display, ctx->drawable);
-        break;
-    case OGLCTX_TYPE_PIXMAP:
-        glXDestroyPixmap(ctx->x_display, ctx->drawable);
-        XFreePixmap(ctx->x_display, ((OGLPixmapCtx *)ctx)->pixmap);
-        break;
-    default:
-        PANIC("invalid ogl ctx type");
-    }
-
-    XCloseDisplay(ctx->x_display);
-    free(ctx);
-}
-
diff --git a/common/ogl_ctx.h b/common/ogl_ctx.h
deleted file mode 100644
index 3abe6d7..0000000
--- a/common/ogl_ctx.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_GLCTX
-#define _H_GLCTX
-
-typedef struct OGLCtx OGLCtx;
-
-const char *oglctx_type_str(OGLCtx *ctx);
-void oglctx_make_current(OGLCtx *ctx);
-OGLCtx *pbuf_create(int width, int heigth);
-OGLCtx *pixmap_create(int width, int heigth);
-void oglctx_destroy(OGLCtx *ctx);
-
-#endif
-
diff --git a/common/pixman_utils.c b/common/pixman_utils.c
deleted file mode 100644
index 914c97e..0000000
--- a/common/pixman_utils.c
+++ /dev/null
@@ -1,1614 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-#include "pixman_utils.h"
-#include <spice/macros.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "mem.h"
-
-#ifndef ASSERT
-#define ASSERT(x) if (!(x)) {                               \
-    printf("%s: ASSERT %s failed\n", __FUNCTION__, #x);     \
-    abort();                                                \
-}
-#endif
-
-#ifndef PANIC
-#define PANIC(str) {                                \
-    printf("%s: panic: %s", __FUNCTION__, str);     \
-    abort();                                        \
-}
-#endif
-
-#define SOLID_RASTER_OP(_name, _size, _type, _equation)  \
-static void                                        \
-solid_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type src)  \
-{                                                  \
-    while (len--) {                                \
-        _type dst = *ptr;                          \
-        if (dst) /* avoid unused warning */{};       \
-        *ptr = (_type)(_equation);                 \
-        ptr++;                                     \
-    }                                              \
-}                                                  \
-
-#define TILED_RASTER_OP(_name, _size, _type, _equation) \
-static void                                        \
-tiled_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width)   \
-{                                                  \
-    while (len--) {                                \
-        _type src = *tile;                         \
-        _type dst = *ptr;                          \
-        if (src) /* avoid unused warning */{};       \
-        if (dst) /* avoid unused warning */{};       \
-        *ptr = (_type)(_equation);                 \
-        ptr++;                                     \
-        tile++;                                    \
-        if (tile == tile_end)                      \
-            tile -= tile_width;                    \
-    }                                              \
-}                                                  \
-
-#define COPY_RASTER_OP(_name, _size, _type, _equation) \
-static void                                        \
- copy_rop_ ## _name ## _ ## _size (_type *ptr, _type *src_line, int len)        \
-{                                                  \
-    while (len--) {                                \
-        _type src = *src_line;                     \
-        _type dst = *ptr;                          \
-        if (src) /* avoid unused warning */ {};       \
-        if (dst) /* avoid unused warning */{};       \
-        *ptr = (_type)(_equation);                 \
-        ptr++;                                     \
-        src_line++;                                \
-    }                                              \
-}                                                  \
-
-#define RASTER_OP(name, equation) \
-    SOLID_RASTER_OP(name, 8, uint8_t, equation) \
-    SOLID_RASTER_OP(name, 16, uint16_t, equation) \
-    SOLID_RASTER_OP(name, 32, uint32_t, equation) \
-    TILED_RASTER_OP(name, 8, uint8_t, equation) \
-    TILED_RASTER_OP(name, 16, uint16_t, equation) \
-    TILED_RASTER_OP(name, 32, uint32_t, equation) \
-    COPY_RASTER_OP(name, 8, uint8_t, equation) \
-    COPY_RASTER_OP(name, 16, uint16_t, equation) \
-    COPY_RASTER_OP(name, 32, uint32_t, equation)
-
-RASTER_OP(clear, 0x0)
-RASTER_OP(and, src & dst)
-RASTER_OP(and_reverse, src & ~dst)
-RASTER_OP(copy, src)
-RASTER_OP(and_inverted, ~src & dst)
-RASTER_OP(noop, dst)
-RASTER_OP(xor, src ^ dst)
-RASTER_OP(or, src | dst)
-RASTER_OP(nor, ~src & ~dst)
-RASTER_OP(equiv, ~src ^ dst)
-RASTER_OP(invert, ~dst)
-RASTER_OP(or_reverse, src | ~dst)
-RASTER_OP(copy_inverted, ~src)
-RASTER_OP(or_inverted, ~src | dst)
-RASTER_OP(nand, ~src | ~dst)
-RASTER_OP(set, 0xffffffff)
-
-typedef void (*solid_rop_8_func_t)(uint8_t *ptr, int len, uint8_t src);
-typedef void (*solid_rop_16_func_t)(uint16_t *ptr, int len, uint16_t src);
-typedef void (*solid_rop_32_func_t)(uint32_t *ptr, int len, uint32_t src);
-typedef void (*tiled_rop_8_func_t)(uint8_t *ptr, int len,
-                                   uint8_t *tile, uint8_t *tile_end, int tile_width);
-typedef void (*tiled_rop_16_func_t)(uint16_t *ptr, int len,
-                                    uint16_t *tile, uint16_t *tile_end, int tile_width);
-typedef void (*tiled_rop_32_func_t)(uint32_t *ptr, int len,
-                                    uint32_t *tile, uint32_t *tile_end, int tile_width);
-typedef void (*copy_rop_8_func_t)(uint8_t *ptr, uint8_t *src, int len);
-typedef void (*copy_rop_16_func_t)(uint16_t *ptr, uint16_t *src, int len);
-typedef void (*copy_rop_32_func_t)(uint32_t *ptr, uint32_t *src, int len);
-
-#define ROP_TABLE(_type, _size)                                                 \
-static void (*solid_rops_ ## _size[16]) (_type *ptr, int len, _type src) = { \
-    solid_rop_clear_ ## _size,  \
-    solid_rop_and_ ## _size,    \
-    solid_rop_and_reverse_ ## _size,    \
-    solid_rop_copy_ ## _size,    \
-    solid_rop_and_inverted_ ## _size,    \
-    solid_rop_noop_ ## _size,    \
-    solid_rop_xor_ ## _size,    \
-    solid_rop_or_ ## _size,    \
-    solid_rop_nor_ ## _size,    \
-    solid_rop_equiv_ ## _size,    \
-    solid_rop_invert_ ## _size,    \
-    solid_rop_or_reverse_ ## _size,    \
-    solid_rop_copy_inverted_ ## _size,    \
-    solid_rop_or_inverted_ ## _size,    \
-    solid_rop_nand_ ## _size,    \
-    solid_rop_set_ ## _size    \
-};                          \
-static void (*tiled_rops_ ## _size[16]) (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) = { \
-    tiled_rop_clear_ ## _size,  \
-    tiled_rop_and_ ## _size,    \
-    tiled_rop_and_reverse_ ## _size,    \
-    tiled_rop_copy_ ## _size,    \
-    tiled_rop_and_inverted_ ## _size,    \
-    tiled_rop_noop_ ## _size,    \
-    tiled_rop_xor_ ## _size,    \
-    tiled_rop_or_ ## _size,    \
-    tiled_rop_nor_ ## _size,    \
-    tiled_rop_equiv_ ## _size,    \
-    tiled_rop_invert_ ## _size,    \
-    tiled_rop_or_reverse_ ## _size,    \
-    tiled_rop_copy_inverted_ ## _size,    \
-    tiled_rop_or_inverted_ ## _size,    \
-    tiled_rop_nand_ ## _size,    \
-    tiled_rop_set_ ## _size    \
-}; \
-static void (*copy_rops_ ## _size[16]) (_type *ptr, _type *tile, int len) = { \
-    copy_rop_clear_ ## _size,  \
-    copy_rop_and_ ## _size,    \
-    copy_rop_and_reverse_ ## _size,    \
-    copy_rop_copy_ ## _size,    \
-    copy_rop_and_inverted_ ## _size,    \
-    copy_rop_noop_ ## _size,    \
-    copy_rop_xor_ ## _size,    \
-    copy_rop_or_ ## _size,    \
-    copy_rop_nor_ ## _size,    \
-    copy_rop_equiv_ ## _size,    \
-    copy_rop_invert_ ## _size,    \
-    copy_rop_or_reverse_ ## _size,    \
-    copy_rop_copy_inverted_ ## _size,    \
-    copy_rop_or_inverted_ ## _size,    \
-    copy_rop_nand_ ## _size,    \
-    copy_rop_set_ ## _size    \
-};
-
-ROP_TABLE(uint8_t, 8)
-ROP_TABLE(uint16_t, 16)
-ROP_TABLE(uint32_t, 32)
-
-/* We can't get the real bits per pixel info from pixman_image_t,
-   only the DEPTH which is the sum of all a+r+g+b bits, which
-   is e.g. 24 for 32bit xRGB. We really want the bpp, so
-   we have this ugly conversion thing */
-int spice_pixman_image_get_bpp(pixman_image_t *image)
-{
-    int depth;
-
-    depth = pixman_image_get_depth(image);
-    if (depth == 24) {
-        return 32;
-    }
-    if (depth == 15) {
-        return 16;
-    }
-    return depth;
-}
-
-void spice_pixman_fill_rect(pixman_image_t *dest,
-                            int x, int y,
-                            int width, int height,
-                            uint32_t value)
-{
-    uint32_t *bits;
-    int stride, depth;
-    uint32_t byte_width;
-    uint8_t *byte_line;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    ASSERT(x >= 0);
-    ASSERT(y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(x + width <= pixman_image_get_width(dest));
-    ASSERT(y + height <= pixman_image_get_height(dest));
-
-    if (pixman_fill(bits,
-                    stride / 4,
-                    depth,
-                    x, y,
-                    width, height,
-                    value)) {
-        return;
-    }
-
-    if (depth == 8) {
-        byte_line = ((uint8_t *)bits) + stride * y + x;
-        byte_width = width;
-        value = (value & 0xff) * 0x01010101;
-    } else if (depth == 16) {
-        byte_line = ((uint8_t *)bits) + stride * y + x * 2;
-        byte_width = 2 * width;
-        value = (value & 0xffff) * 0x00010001;
-    } else {
-        ASSERT (depth == 32)
-        byte_line = ((uint8_t *)bits) + stride * y + x * 4;
-        byte_width = 4 * width;
-    }
-
-    while (height--) {
-        int w;
-        uint8_t *d = byte_line;
-
-        byte_line += stride;
-        w = byte_width;
-
-        while (w >= 1 && ((uintptr_t)d & 1)) {
-            *(uint8_t *)d = (value & 0xff);
-            w--;
-            d++;
-        }
-
-        while (w >= 2 && ((uintptr_t)d & 3)) {
-            *(uint16_t *)d = value;
-            w -= 2;
-            d += 2;
-        }
-
-        while (w >= 4 && ((uintptr_t)d & 7)) {
-            *(uint32_t *)d = value;
-
-            w -= 4;
-            d += 4;
-        }
-
-        while (w >= 4) {
-            *(uint32_t *)d = value;
-
-            w -= 4;
-            d += 4;
-        }
-
-        while (w >= 2) {
-            *(uint16_t *)d = value;
-            w -= 2;
-            d += 2;
-        }
-
-        while (w >= 1) {
-            *(uint8_t *)d = (value & 0xff);
-            w--;
-            d++;
-        }
-    }
-}
-
-void spice_pixman_fill_rect_rop(pixman_image_t *dest,
-                                int x, int y,
-                                int width, int height,
-                                uint32_t value,
-                                SpiceROP rop)
-{
-    uint32_t *bits;
-    int stride, depth;
-    uint8_t *byte_line;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    ASSERT(x >= 0);
-    ASSERT(y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(x + width <= pixman_image_get_width(dest));
-    ASSERT(y + height <= pixman_image_get_height(dest));
-    ASSERT(rop < 16);
-
-    if (depth == 8) {
-        solid_rop_8_func_t rop_func = solid_rops_8[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * y + x;
-        while (height--) {
-            rop_func((uint8_t *)byte_line, width, (uint8_t)value);
-            byte_line += stride;
-        }
-
-    } else if (depth == 16) {
-        solid_rop_16_func_t rop_func = solid_rops_16[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * y + x * 2;
-        while (height--) {
-            rop_func((uint16_t *)byte_line, width, (uint16_t)value);
-            byte_line += stride;
-        }
-    }  else {
-        solid_rop_32_func_t rop_func = solid_rops_32[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * y + x * 4;
-        while (height--) {
-            rop_func((uint32_t *)byte_line, width, (uint32_t)value);
-            byte_line += stride;
-        }
-    }
-}
-
-void spice_pixman_tile_rect(pixman_image_t *dest,
-                            int x, int y,
-                            int width, int height,
-                            pixman_image_t *tile,
-                            int offset_x,
-                            int offset_y)
-{
-    uint32_t *bits, *tile_bits;
-    int stride, depth;
-    int tile_width, tile_height, tile_stride;
-    uint8_t *byte_line;
-    uint8_t *tile_line;
-    int tile_start_x, tile_start_y, tile_end_dx;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    tile_bits = pixman_image_get_data(tile);
-    tile_stride = pixman_image_get_stride(tile);
-    tile_width = pixman_image_get_width(tile);
-    tile_height = pixman_image_get_height(tile);
-
-    ASSERT(x >= 0);
-    ASSERT(y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(x + width <= pixman_image_get_width(dest));
-    ASSERT(y + height <= pixman_image_get_height(dest));
-    ASSERT(depth == spice_pixman_image_get_bpp(tile));
-
-    tile_start_x = (x - offset_x) % tile_width;
-    if (tile_start_x < 0) {
-        tile_start_x += tile_width;
-    }
-    tile_start_y = (y - offset_y) % tile_height;
-    if (tile_start_y < 0) {
-        tile_start_y += tile_height;
-    }
-    tile_end_dx = tile_width - tile_start_x;
-
-    if (depth == 8) {
-        byte_line = ((uint8_t *)bits) + stride * y + x;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
-        while (height--) {
-            tiled_rop_copy_8((uint8_t *)byte_line, width,
-                             (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
-                             tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-
-    } else if (depth == 16) {
-        byte_line = ((uint8_t *)bits) + stride * y + x * 2;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
-        while (height--) {
-            tiled_rop_copy_16((uint16_t *)byte_line, width,
-                              (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
-                              tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-    }  else {
-        ASSERT (depth == 32);
-
-        byte_line = ((uint8_t *)bits) + stride * y + x * 4;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
-        while (height--) {
-            tiled_rop_copy_32((uint32_t *)byte_line, width,
-                              (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
-                              tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-    }
-}
-
-void spice_pixman_tile_rect_rop(pixman_image_t *dest,
-                                int x, int y,
-                                int width, int height,
-                                pixman_image_t *tile,
-                                int offset_x,
-                                int offset_y,
-                                SpiceROP rop)
-{
-    uint32_t *bits, *tile_bits;
-    int stride, depth;
-    int tile_width, tile_height, tile_stride;
-    uint8_t *byte_line;
-    uint8_t *tile_line;
-    int tile_start_x, tile_start_y, tile_end_dx;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    tile_bits = pixman_image_get_data(tile);
-    tile_stride = pixman_image_get_stride(tile);
-    tile_width = pixman_image_get_width(tile);
-    tile_height = pixman_image_get_height(tile);
-
-    ASSERT(x >= 0);
-    ASSERT(y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(x + width <= pixman_image_get_width(dest));
-    ASSERT(y + height <= pixman_image_get_height(dest));
-    ASSERT(rop < 16);
-    ASSERT(depth == spice_pixman_image_get_bpp(tile));
-
-    tile_start_x = (x - offset_x) % tile_width;
-    if (tile_start_x < 0) {
-        tile_start_x += tile_width;
-    }
-    tile_start_y = (y - offset_y) % tile_height;
-    if (tile_start_y < 0) {
-        tile_start_y += tile_height;
-    }
-    tile_end_dx = tile_width - tile_start_x;
-
-    if (depth == 8) {
-        tiled_rop_8_func_t rop_func = tiled_rops_8[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * y + x;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
-        while (height--) {
-            rop_func((uint8_t *)byte_line, width,
-                     (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
-                     tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-
-    } else if (depth == 16) {
-        tiled_rop_16_func_t rop_func = tiled_rops_16[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * y + x * 2;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
-        while (height--) {
-            rop_func((uint16_t *)byte_line, width,
-                     (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
-                     tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-    }  else {
-        tiled_rop_32_func_t rop_func = tiled_rops_32[rop];
-
-        ASSERT (depth == 32);
-
-        byte_line = ((uint8_t *)bits) + stride * y + x * 4;
-        tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
-        while (height--) {
-            rop_func((uint32_t *)byte_line, width,
-                     (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
-                     tile_width);
-            byte_line += stride;
-            tile_line += tile_stride;
-            if (++tile_start_y == tile_height) {
-                tile_line -= tile_height * tile_stride;
-                tile_start_y = 0;
-            }
-        }
-    }
-}
-
-
-void spice_pixman_blit(pixman_image_t *dest,
-                       pixman_image_t *src,
-                       int src_x, int src_y,
-                       int dest_x, int dest_y,
-                       int width, int height)
-{
-    uint32_t *bits, *src_bits;
-    int stride, depth, src_depth;
-    int src_width, src_height, src_stride;
-    uint8_t *byte_line;
-    uint8_t *src_line;
-    int byte_width;
-
-    if (!src) {
-        fprintf(stderr, "missing src!");
-        return;
-    }
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    src_bits = pixman_image_get_data(src);
-    src_stride = pixman_image_get_stride(src);
-    src_width = pixman_image_get_width(src);
-    src_height = pixman_image_get_height(src);
-    src_depth = spice_pixman_image_get_bpp(src);
-
-    /* Clip source */
-    if (src_x < 0) {
-        width += src_x;
-        dest_x -= src_x;
-        src_x = 0;
-    }
-    if (src_y < 0) {
-        height += src_y;
-        dest_y -= src_y;
-        src_y = 0;
-    }
-    if (src_x + width > src_width) {
-        width = src_width - src_x;
-    }
-    if (src_y + height > src_height) {
-        height = src_height - src_y;
-    }
-
-    if (width <= 0 || height <= 0) {
-        return;
-    }
-
-    ASSERT(src_x >= 0);
-    ASSERT(src_y >= 0);
-    ASSERT(dest_x >= 0);
-    ASSERT(dest_y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(dest_x + width <= pixman_image_get_width(dest));
-    ASSERT(dest_y + height <= pixman_image_get_height(dest));
-    ASSERT(src_x + width <= pixman_image_get_width(src));
-    ASSERT(src_y + height <= pixman_image_get_height(src));
-    ASSERT(depth == src_depth);
-
-    if (pixman_blt(src_bits,
-                   bits,
-                   src_stride / 4,
-                   stride / 4,
-                   depth, depth,
-                   src_x, src_y,
-                   dest_x, dest_y,
-                   width, height)) {
-        return;
-    }
-
-    if (depth == 8) {
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
-        byte_width = width;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
-    } else if (depth == 16) {
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
-        byte_width = width * 2;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
-    }  else {
-        ASSERT (depth == 32);
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
-        byte_width = width * 4;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
-    }
-
-    while (height--) {
-        memcpy(byte_line, src_line, byte_width);
-        byte_line += stride;
-        src_line += src_stride;
-    }
-}
-
-void spice_pixman_blit_rop (pixman_image_t *dest,
-                            pixman_image_t *src,
-                            int src_x, int src_y,
-                            int dest_x, int dest_y,
-                            int width, int height,
-                            SpiceROP rop)
-{
-    uint32_t *bits, *src_bits;
-    int stride, depth, src_depth;
-    int src_width, src_height, src_stride;
-    uint8_t *byte_line;
-    uint8_t *src_line;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    src_bits = pixman_image_get_data(src);
-    src_stride = pixman_image_get_stride(src);
-    src_width = pixman_image_get_width(src);
-    src_height = pixman_image_get_height(src);
-    src_depth = spice_pixman_image_get_bpp(src);
-
-    /* Clip source */
-    if (src_x < 0) {
-        width += src_x;
-        dest_x -= src_x;
-        src_x = 0;
-    }
-    if (src_y < 0) {
-        height += src_y;
-        dest_y -= src_y;
-        src_y = 0;
-    }
-    if (src_x + width > src_width) {
-        width = src_width - src_x;
-    }
-    if (src_y + height > src_height) {
-        height = src_height - src_y;
-    }
-
-    if (width <= 0 || height <= 0) {
-        return;
-    }
-
-    ASSERT(src_x >= 0);
-    ASSERT(src_y >= 0);
-    ASSERT(dest_x >= 0);
-    ASSERT(dest_y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(dest_x + width <= pixman_image_get_width(dest));
-    ASSERT(dest_y + height <= pixman_image_get_height(dest));
-    ASSERT(src_x + width <= pixman_image_get_width(src));
-    ASSERT(src_y + height <= pixman_image_get_height(src));
-    ASSERT(depth == src_depth);
-
-    if (depth == 8) {
-        copy_rop_8_func_t rop_func = copy_rops_8[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
-
-        while (height--) {
-            rop_func((uint8_t *)byte_line, (uint8_t *)src_line, width);
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    } else if (depth == 16) {
-        copy_rop_16_func_t rop_func = copy_rops_16[rop];
-
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
-
-        while (height--) {
-            rop_func((uint16_t *)byte_line, (uint16_t *)src_line, width);
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    }  else {
-        copy_rop_32_func_t rop_func = copy_rops_32[rop];
-
-        ASSERT (depth == 32);
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
-
-        while (height--) {
-            rop_func((uint32_t *)byte_line, (uint32_t *)src_line, width);
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    }
-
-}
-
-void spice_pixman_blit_colorkey (pixman_image_t *dest,
-                                 pixman_image_t *src,
-                                 int src_x, int src_y,
-                                 int dest_x, int dest_y,
-                                 int width, int height,
-                                 uint32_t transparent_color)
-{
-    uint32_t *bits, *src_bits;
-    int stride, depth;
-    int src_width, src_height, src_stride;
-    uint8_t *byte_line;
-    uint8_t *src_line;
-    int x;
-
-    bits = pixman_image_get_data(dest);
-    stride = pixman_image_get_stride(dest);
-    depth = spice_pixman_image_get_bpp(dest);
-    /* stride is in bytes, depth in bits */
-
-    src_bits = pixman_image_get_data(src);
-    src_stride = pixman_image_get_stride(src);
-    src_width = pixman_image_get_width(src);
-    src_height = pixman_image_get_height(src);
-
-    /* Clip source */
-    if (src_x < 0) {
-        width += src_x;
-        dest_x -= src_x;
-        src_x = 0;
-    }
-    if (src_y < 0) {
-        height += src_y;
-        dest_y -= src_y;
-        src_y = 0;
-    }
-    if (src_x + width > src_width) {
-        width = src_width - src_x;
-    }
-    if (src_y + height > src_height) {
-        height = src_height - src_y;
-    }
-
-    if (width <= 0 || height <= 0) {
-        return;
-    }
-
-    ASSERT(src_x >= 0);
-    ASSERT(src_y >= 0);
-    ASSERT(dest_x >= 0);
-    ASSERT(dest_y >= 0);
-    ASSERT(width > 0);
-    ASSERT(height > 0);
-    ASSERT(dest_x + width <= pixman_image_get_width(dest));
-    ASSERT(dest_y + height <= pixman_image_get_height(dest));
-    ASSERT(src_x + width <= pixman_image_get_width(src));
-    ASSERT(src_y + height <= pixman_image_get_height(src));
-    ASSERT(depth == spice_pixman_image_get_bpp(src));
-
-    if (depth == 8) {
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
-
-        while (height--) {
-            uint8_t *d = (uint8_t *)byte_line;
-            uint8_t *s = (uint8_t *)byte_line;
-
-            s = (uint8_t *)src_line;
-            for (x = 0; x < width; x++) {
-                uint8_t val = *s;
-                if (val != (uint8_t)transparent_color) {
-                    *d = val;
-                }
-                s++; d++;
-            }
-
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    } else if (depth == 16) {
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
-
-        while (height--) {
-            uint16_t *d = (uint16_t *)byte_line;
-            uint16_t *s = (uint16_t *)byte_line;
-
-            s = (uint16_t *)src_line;
-            for (x = 0; x < width; x++) {
-                uint16_t val = *s;
-                if (val != (uint16_t)transparent_color) {
-                    *d = val;
-                }
-                s++; d++;
-            }
-
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    }  else {
-        ASSERT (depth == 32);
-        byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
-        src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
-
-        while (height--) {
-            uint32_t *d = (uint32_t *)byte_line;
-            uint32_t *s = (uint32_t *)byte_line;
-
-            transparent_color &= 0xffffff;
-            s = (uint32_t *)src_line;
-            for (x = 0; x < width; x++) {
-                uint32_t val = *s;
-                if ((0xffffff & val) != transparent_color) {
-                    *d = val;
-                }
-                s++; d++;
-            }
-
-            byte_line += stride;
-            src_line += src_stride;
-        }
-    }
-}
-
-static void copy_bits_up(uint8_t *data, const int stride, int bpp,
-                         const int src_x, const int src_y,
-                         const int width, const int height,
-                         const int dest_x, const int dest_y)
-{
-    uint8_t *src = data + src_y * stride + src_x * bpp;
-    uint8_t *dest = data + dest_y * stride + dest_x * bpp;
-    uint8_t *end = dest + height * stride;
-    for (; dest != end; dest += stride, src += stride) {
-        memcpy(dest, src, width * bpp);
-    }
-}
-
-static void copy_bits_down(uint8_t *data, const int stride, int bpp,
-                           const int src_x, const int src_y,
-                           const int width, const int height,
-                           const int dest_x, const int dest_y)
-{
-    uint8_t *src = data + (src_y + height - 1) * stride + src_x * bpp;
-    uint8_t *end = data + (dest_y - 1) * stride + dest_x * bpp;
-    uint8_t *dest = end + height * stride;
-
-    for (; dest != end; dest -= stride, src -= stride) {
-        memcpy(dest, src, width * bpp);
-    }
-}
-
-static void copy_bits_same_line(uint8_t *data, const int stride, int bpp,
-                                const int src_x, const int src_y,
-                                const int width, const int height,
-                                const int dest_x, const int dest_y)
-{
-    uint8_t *src = data + src_y * stride + src_x * bpp;
-    uint8_t *dest = data + dest_y * stride + dest_x * bpp;
-    uint8_t *end = dest + height * stride;
-    for (; dest != end; dest += stride, src += stride) {
-        memmove(dest, src, width * bpp);
-    }
-}
-
-void spice_pixman_copy_rect (pixman_image_t *image,
-                             int src_x, int src_y,
-                             int width, int height,
-                             int dest_x, int dest_y)
-{
-    uint8_t *data;
-    int stride;
-    int bpp;
-
-    data = (uint8_t *)pixman_image_get_data(image);
-    stride = pixman_image_get_stride(image);
-    bpp = spice_pixman_image_get_bpp(image) / 8;
-
-    if (dest_y > src_y) {
-        copy_bits_down(data, stride, bpp,
-                       src_x, src_y,
-                       width, height,
-                       dest_x, dest_y);
-    } else if (dest_y < src_y) {
-        copy_bits_up(data, stride, bpp,
-                     src_x, src_y,
-                     width, height,
-                     dest_x, dest_y);
-    } else {
-        copy_bits_same_line(data, stride, bpp,
-                            src_x, src_y,
-                            width, height,
-                            dest_x, dest_y);
-    }
-}
-
-pixman_bool_t spice_pixman_region32_init_rects (pixman_region32_t *region,
-                                                const SpiceRect   *rects,
-                                                int                count)
-{
-    /* These types are compatible, so just cast */
-    return pixman_region32_init_rects(region, (pixman_box32_t *)rects, count);
-}
-
-pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format)
-{
-    switch (surface_format) {
-    case SPICE_SURFACE_FMT_1_A:
-        return PIXMAN_a1;
-    case SPICE_SURFACE_FMT_8_A:
-        return PIXMAN_a8;
-    case SPICE_SURFACE_FMT_16_555:
-        return PIXMAN_x1r5g5b5;
-    case SPICE_SURFACE_FMT_16_565:
-        return PIXMAN_r5g6b5;
-    case SPICE_SURFACE_FMT_32_xRGB:
-        return PIXMAN_x8r8g8b8;
-    case SPICE_SURFACE_FMT_32_ARGB:
-        return PIXMAN_a8r8g8b8;
-    default:
-        printf("Unknown surface format %d\n", surface_format);
-        abort();
-        break;
-    }
-	return (pixman_format_code_t)0; /* Not reached */
-}
-
-/* Returns the "spice native" pixman version of a specific bitmap format.
- * This isn't bitwise the same as the bitmap format, for instance we
- * typically convert indexed to real color modes and use the standard
- * surface modes rather than weird things like 24bit
- */
-pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
-                                                   uint32_t palette_surface_format)
-{
-    switch (bitmap_format) {
-    case SPICE_BITMAP_FMT_1BIT_LE:
-    case SPICE_BITMAP_FMT_1BIT_BE:
-    case SPICE_BITMAP_FMT_4BIT_LE:
-    case SPICE_BITMAP_FMT_4BIT_BE:
-    case SPICE_BITMAP_FMT_8BIT:
-        /* Indexed mode palettes are the same as their destination canvas format */
-        return spice_surface_format_to_pixman(palette_surface_format);
-
-    case SPICE_BITMAP_FMT_16BIT:
-        return PIXMAN_x1r5g5b5;
-
-    case SPICE_BITMAP_FMT_24BIT:
-    case SPICE_BITMAP_FMT_32BIT:
-        return PIXMAN_x8r8g8b8;
-
-    case SPICE_BITMAP_FMT_RGBA:
-        return PIXMAN_a8r8g8b8;
-
-    case SPICE_BITMAP_FMT_INVALID:
-    default:
-        printf("Unknown bitmap format %d\n", bitmap_format);
-        abort();
-        return PIXMAN_a8r8g8b8;
-    }
-}
-
-/* Tries to view a spice bitmap as a pixman_image_t without copying,
- * will often fail due to unhandled formats or strides.
- */
-pixman_image_t *spice_bitmap_try_as_pixman(int src_format,
-                                           int flags,
-                                           int width,
-                                           int height,
-                                           uint8_t *data,
-                                           int stride)
-{
-    pixman_format_code_t pixman_format;
-
-    /* Pixman stride must be multiple of 4 */
-    if (stride % 4 != 0) {
-        return NULL;
-    }
-
-    switch (src_format) {
-    case SPICE_BITMAP_FMT_32BIT:
-#ifdef WORDS_BIGENDIAN
-        pixman_format = PIXMAN_b8g8r8x8;
-#else
-        pixman_format = PIXMAN_x8r8g8b8;
-#endif
-        break;
-    case SPICE_BITMAP_FMT_RGBA:
-#ifdef WORDS_BIGENDIAN
-        pixman_format = PIXMAN_b8g8r8a8;
-#else
-        pixman_format = PIXMAN_a8r8g8b8;
-#endif
-        break;
-    case SPICE_BITMAP_FMT_24BIT:
-#ifdef WORDS_BIGENDIAN
-        pixman_format = PIXMAN_b8g8r8;
-#else
-        pixman_format = PIXMAN_r8g8b8;
-#endif
-        break;
-    case SPICE_BITMAP_FMT_16BIT:
-#ifdef WORDS_BIGENDIAN
-        return NULL;
-#else
-        pixman_format = PIXMAN_x1r5g5b5;
-#endif
-        break;
-
-    default:
-        return NULL;
-    }
-
-    if (!(flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
-        data += stride * (height - 1);
-        stride = -stride;
-    }
-
-    return pixman_image_create_bits (pixman_format,
-                                     width,
-                                     height,
-                                     (uint32_t *)data,
-                                     stride);
-}
-
-#ifdef WORDS_BIGENDIAN
-#define UINT16_FROM_LE(x) SPICE_BYTESWAP16(x)
-#define UINT32_FROM_LE(x) SPICE_BYTESWAP32(x)
-#else
-#define UINT16_FROM_LE(x) (x)
-#define UINT32_FROM_LE(x) (x)
-#endif
-
-static inline uint32_t rgb_16_555_to_32(uint16_t color)
-{
-    uint32_t ret;
-
-    ret = ((color & 0x001f) << 3) | ((color & 0x001c) >> 2);
-    ret |= ((color & 0x03e0) << 6) | ((color & 0x0380) << 1);
-    ret |= ((color & 0x7c00) << 9) | ((color & 0x7000) << 4);
-
-    return ret;
-}
-
-static inline uint16_t rgb_32_to_16_555(uint32_t color)
-{
-    return
-        (((color) >> 3) & 0x001f) |
-        (((color) >> 6) & 0x03e0) |
-        (((color) >> 9) & 0x7c00);
-}
-
-
-static void bitmap_32_to_32(uint8_t* dest, int dest_stride,
-                            uint8_t* src, int src_stride,
-                            int width, uint8_t* end)
-{
-#ifdef WORDS_BIGENDIAN
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint32_t* src_line = (uint32_t *)src;
-        uint32_t* src_line_end = src_line + width;
-        uint32_t* dest_line = (uint32_t *)dest;
-
-        for (; src_line < src_line_end; ++dest_line, ++src_line) {
-            *dest_line = UINT32_FROM_LE(*src_line);
-        }
-    }
-#else
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        memcpy(dest, src, width * 4);
-    }
-#endif
-}
-
-static void bitmap_24_to_32(uint8_t* dest, int dest_stride,
-                            uint8_t* src, int src_stride,
-                            int width, uint8_t* end)
-{
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint8_t* src_line = src;
-        uint8_t* src_line_end = src_line + width * 3;
-        uint32_t* dest_line = (uint32_t *)dest;
-
-        for (; src_line < src_line_end; ++dest_line) {
-            uint32_t r, g, b;
-            b = *(src_line++);
-            g = *(src_line++);
-            r = *(src_line++);
-            *dest_line = (r << 16) | (g << 8) | (b);
-        }
-    }
-}
-
-static void bitmap_16_to_16_555(uint8_t* dest, int dest_stride,
-                                uint8_t* src, int src_stride,
-                                int width, uint8_t* end)
-{
-#ifdef WORDS_BIGENDIAN
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint16_t* src_line = (uint16_t *)src;
-        uint16_t* src_line_end = src_line + width;
-        uint16_t* dest_line = (uint16_t *)dest;
-
-        for (; src_line < src_line_end; ++dest_line, ++src_line) {
-            *dest_line = UINT16_FROM_LE(*src_line);
-        }
-    }
-#else
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        memcpy(dest, src, width * 2);
-    }
-#endif
-}
-
-static void bitmap_8_32_to_32(uint8_t *dest, int dest_stride,
-                              uint8_t *src, int src_stride,
-                              int width, uint8_t *end,
-                              SpicePalette *palette)
-{
-    uint32_t local_ents[256];
-    uint32_t *ents;
-    int n_ents;
-#ifdef WORDS_BIGENDIAN
-    int i;
-#endif
-
-    if (!palette) {
-        PANIC("No palette");
-        return;
-    }
-
-    n_ents = MIN(palette->num_ents, 256);
-    ents = palette->ents;
-
-    if (n_ents < 255
-#ifdef WORDS_BIGENDIAN
-        || TRUE
-#endif
-        ) {
-        memcpy(local_ents, ents, n_ents*4);
-        ents = local_ents;
-
-#ifdef WORDS_BIGENDIAN
-        for (i = 0; i < n_ents; i++) {
-            ents[i] = UINT32_FROM_LE(ents[i]);
-        }
-#endif
-    }
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint32_t *dest_line = (uint32_t*)dest;
-        uint8_t *src_line = src;
-        uint8_t *src_line_end = src_line + width;
-
-        while (src_line < src_line_end) {
-            *(dest_line++) = ents[*(src_line++)];
-        }
-    }
-}
-
-static void bitmap_8_16_to_16_555(uint8_t *dest, int dest_stride,
-                                  uint8_t *src, int src_stride,
-                                  int width, uint8_t *end,
-                                  SpicePalette *palette)
-{
-    uint32_t local_ents[256];
-    uint32_t *ents;
-    int n_ents;
-#ifdef WORDS_BIGENDIAN
-    int i;
-#endif
-
-    if (!palette) {
-        PANIC("No palette");
-        return;
-    }
-
-    n_ents = MIN(palette->num_ents, 256);
-    ents = palette->ents;
-
-    if (n_ents < 255
-#ifdef WORDS_BIGENDIAN
-        || TRUE
-#endif
-        ) {
-        memcpy(local_ents, ents, n_ents*4);
-        ents = local_ents;
-
-#ifdef WORDS_BIGENDIAN
-        for (i = 0; i < n_ents; i++) {
-            ents[i] = UINT32_FROM_LE(ents[i]);
-        }
-#endif
-    }
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint16_t *dest_line = (uint16_t*)dest;
-        uint8_t *src_line = src;
-        uint8_t *src_line_end = src_line + width;
-
-        while (src_line < src_line_end) {
-            *(dest_line++) = ents[*(src_line++)];
-        }
-    }
-}
-
-static void bitmap_4be_32_to_32(uint8_t* dest, int dest_stride,
-                                uint8_t* src, int src_stride,
-                                int width, uint8_t* end,
-                                SpicePalette *palette)
-{
-    uint32_t local_ents[16];
-    uint32_t *ents;
-    int n_ents;
-#ifdef WORDS_BIGENDIAN
-    int i;
-#endif
-
-    if (!palette) {
-        PANIC("No palette");
-        return;
-    }
-
-    n_ents = MIN(palette->num_ents, 16);
-    ents = palette->ents;
-
-    if (n_ents < 16
-#ifdef WORDS_BIGENDIAN
-        || TRUE
-#endif
-        ) {
-        memcpy(local_ents, ents, n_ents*4);
-        ents = local_ents;
-
-#ifdef WORDS_BIGENDIAN
-        for (i = 0; i < n_ents; i++) {
-            ents[i] = UINT32_FROM_LE(ents[i]);
-        }
-#endif
-    }
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint32_t *dest_line = (uint32_t *)dest;
-        uint8_t *row = src;
-        int i;
-
-        for (i = 0; i < (width >> 1); i++) {
-            *(dest_line++) = ents[(*row >> 4) & 0x0f];
-            *(dest_line++) = ents[*(row++) & 0x0f];
-        }
-        if (width & 1) {
-            *(dest_line) = ents[(*row >> 4) & 0x0f];
-        }
-    }
-}
-
-static void bitmap_4be_16_to_16_555(uint8_t* dest, int dest_stride,
-                                    uint8_t* src, int src_stride,
-                                    int width, uint8_t* end,
-                                    SpicePalette *palette)
-{
-    uint32_t local_ents[16];
-    uint32_t *ents;
-    int n_ents;
-#ifdef WORDS_BIGENDIAN
-    int i;
-#endif
-
-    if (!palette) {
-        PANIC("No palette");
-        return;
-    }
-
-    n_ents = MIN(palette->num_ents, 16);
-    ents = palette->ents;
-
-    if (n_ents < 16
-#ifdef WORDS_BIGENDIAN
-        || TRUE
-#endif
-        ) {
-        memcpy(local_ents, ents, n_ents*4);
-        ents = local_ents;
-
-#ifdef WORDS_BIGENDIAN
-        for (i = 0; i < n_ents; i++) {
-            ents[i] = UINT32_FROM_LE(ents[i]);
-        }
-#endif
-    }
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint16_t *dest_line = (uint16_t *)dest;
-        uint8_t *row = src;
-        int i;
-
-        for (i = 0; i < (width >> 1); i++) {
-            *(dest_line++) = ents[(*row >> 4) & 0x0f];
-            *(dest_line++) = ents[*(row++) & 0x0f];
-        }
-        if (width & 1) {
-            *(dest_line) = ents[(*row >> 4) & 0x0f];
-        }
-    }
-}
-
-static inline int test_bit_be(void* addr, int bit)
-{
-    return !!(((uint8_t*)addr)[bit >> 3] & (0x80 >> (bit & 0x07)));
-}
-
-static void bitmap_1be_32_to_32(uint8_t* dest, int dest_stride,
-                                uint8_t* src, int src_stride,
-                                int width, uint8_t* end,
-                                SpicePalette *palette)
-{
-    uint32_t fore_color;
-    uint32_t back_color;
-
-    ASSERT(palette != NULL);
-
-    if (!palette) {
-        return;
-    }
-
-    fore_color = UINT32_FROM_LE(palette->ents[1]);
-    back_color = UINT32_FROM_LE(palette->ents[0]);
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint32_t* dest_line = (uint32_t*)dest;
-        int i;
-
-        for (i = 0; i < width; i++) {
-            if (test_bit_be(src, i)) {
-                *(dest_line++) = fore_color;
-            } else {
-                *(dest_line++) = back_color;
-            }
-        }
-    }
-}
-
-
-static void bitmap_1be_16_to_16_555(uint8_t* dest, int dest_stride,
-                                    uint8_t* src, int src_stride,
-                                    int width, uint8_t* end,
-                                    SpicePalette *palette)
-{
-    uint16_t fore_color;
-    uint16_t back_color;
-
-    ASSERT(palette != NULL);
-
-    if (!palette) {
-        return;
-    }
-
-    fore_color = (uint16_t) UINT32_FROM_LE(palette->ents[1]);
-    back_color = (uint16_t) UINT32_FROM_LE(palette->ents[0]);
-
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint16_t* dest_line = (uint16_t*)dest;
-        int i;
-
-        for (i = 0; i < width; i++) {
-            if (test_bit_be(src, i)) {
-                *(dest_line++) = fore_color;
-            } else {
-                *(dest_line++) = back_color;
-            }
-        }
-    }
-}
-
-#ifdef NOT_USED_ATM
-
-static void bitmap_16_to_32(uint8_t* dest, int dest_stride,
-                            uint8_t* src, int src_stride,
-                            int width, uint8_t* end)
-{
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint16_t* src_line = (uint16_t*)src;
-        uint16_t* src_line_end = src_line + width;
-        uint32_t* dest_line = (uint32_t*)dest;
-
-        for (; src_line < src_line_end; ++dest_line, src_line++) {
-            *dest_line = rgb_16_555_to_32(UINT16_FROM_LE(*src_line));
-        }
-    }
-}
-
-static void bitmap_32_to_16_555(uint8_t* dest, int dest_stride,
-                                uint8_t* src, int src_stride,
-                                int width, uint8_t* end)
-{
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint32_t* src_line = (uint32_t *)src;
-        uint32_t* src_line_end = src_line + width;
-        uint16_t* dest_line = (uint16_t *)dest;
-
-        for (; src_line < src_line_end; ++dest_line, ++src_line) {
-            *dest_line = rgb_32_to_16_555(UINT16_FROM_LE(*src_line));
-        }
-    }
-}
-
-
-static void bitmap_24_to_16_555(uint8_t* dest, int dest_stride,
-                                uint8_t* src, int src_stride,
-                                int width, uint8_t* end)
-{
-    for (; src != end; src += src_stride, dest += dest_stride) {
-        uint8_t* src_line = src;
-        uint8_t* src_line_end = src_line + width * 3;
-        uint16_t* dest_line = (uint16_t *)dest;
-
-        for (; src_line < src_line_end; ++dest_line) {
-            uint8_t r, g, b;
-            b = *(src_line++);
-            g = *(src_line++);
-            r = *(src_line++);
-            *dest_line = rgb_32_to_16_555(r << 24 | g << 16 | b);
-        }
-    }
-}
-
-#endif
-
-/* This assumes that the dest, if set is the same format as
-   spice_bitmap_format_to_pixman would have picked */
-pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
-                                       int src_format,
-                                       int flags,
-                                       int width,
-                                       int height,
-                                       uint8_t *src,
-                                       int src_stride,
-                                       uint32_t palette_surface_format,
-                                       SpicePalette *palette)
-{
-    uint8_t* dest;
-    int dest_stride;
-    uint8_t* end;
-
-    if (dest_image == NULL) {
-        pixman_format_code_t dest_format;
-
-        dest_format = spice_bitmap_format_to_pixman(src_format,
-                                                    palette_surface_format);
-        dest_image = pixman_image_create_bits (dest_format,
-                                               width, height,
-                                               NULL, 0);
-    }
-
-    dest = (uint8_t *)pixman_image_get_data(dest_image);
-    dest_stride = pixman_image_get_stride(dest_image);
-    if (!(flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
-        ASSERT(height > 0);
-        dest += dest_stride * (height - 1);
-        dest_stride = -dest_stride;
-    }
-    end = src + (height * src_stride);
-
-    switch (src_format) {
-    case SPICE_BITMAP_FMT_32BIT:
-    case SPICE_BITMAP_FMT_RGBA:
-        bitmap_32_to_32(dest, dest_stride, src, src_stride, width, end);
-        break;
-    case SPICE_BITMAP_FMT_24BIT:
-        bitmap_24_to_32(dest, dest_stride, src, src_stride, width, end);
-        break;
-    case SPICE_BITMAP_FMT_16BIT:
-        bitmap_16_to_16_555(dest, dest_stride, src, src_stride, width, end);
-        break;
-    case SPICE_BITMAP_FMT_8BIT:
-        if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
-            palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
-            bitmap_8_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
-        } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
-            bitmap_8_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
-        } else {
-            PANIC("Unsupported palette format");
-        }
-        break;
-    case SPICE_BITMAP_FMT_4BIT_BE:
-        if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
-            palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
-            bitmap_4be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
-        } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
-            bitmap_4be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
-        } else {
-            PANIC("Unsupported palette format");
-        }
-        break;
-    case SPICE_BITMAP_FMT_1BIT_BE:
-        if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
-            palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
-            bitmap_1be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
-        } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
-            bitmap_1be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
-        } else {
-            PANIC("Unsupported palette format");
-        }
-        break;
-    default:
-        PANIC("Unsupported bitmap format");
-        break;
-    }
-
-    return dest_image;
-}
-
-static int pixman_format_compatible (pixman_format_code_t dest_format,
-                              pixman_format_code_t src_format)
-{
-    if (dest_format == src_format) {
-        return TRUE;
-    }
-
-    if (src_format == PIXMAN_a8r8g8b8 &&
-        dest_format == PIXMAN_x8r8g8b8) {
-        /* This is the same, we just ignore the alphas */
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
-                                               pixman_image_t *dest_image,
-                                               int src_format,
-                                               int flags,
-                                               int width,
-                                               int height,
-                                               uint8_t *src,
-                                               int src_stride,
-                                               uint32_t palette_surface_format,
-                                               SpicePalette *palette)
-{
-    pixman_image_t *src_image;
-    pixman_format_code_t native_format;
-
-    if (dest_image == NULL) {
-        dest_image = pixman_image_create_bits (dest_format,
-                                               width, height,
-                                               NULL, 0);
-    }
-
-    native_format =
-        spice_bitmap_format_to_pixman(src_format, palette_surface_format);
-
-    if (pixman_format_compatible (dest_format, native_format)) {
-        return spice_bitmap_to_pixman(dest_image,
-                                      src_format,
-                                      flags, width,height,
-                                      src, src_stride,
-                                      palette_surface_format, palette);
-    }
-
-    src_image = spice_bitmap_try_as_pixman(src_format,
-                                           flags, width,height,
-                                           src, src_stride);
-
-    /* Can't convert directly, need a temporary copy
-     * Hopefully most bitmap reads should not need conversion (i.e.
-     * hit the spice_bitmap_to_pixmap case above) or work with the
-     * try_as_pixmap case, but in case some specific combination
-     * shows up here commonly we might want to add non-temporary
-     * conversion special casing here */
-    if (src_image == NULL) {
-        src_image = spice_bitmap_to_pixman(NULL,
-                                           src_format,
-                                           flags, width,height,
-                                           src, src_stride,
-                                           palette_surface_format, palette);
-    }
-
-    pixman_image_composite32 (PIXMAN_OP_SRC,
-                              src_image, NULL, dest_image,
-                              0, 0,
-                              0, 0,
-                              0, 0,
-                              width, height);
-
-    pixman_image_unref (src_image);
-
-    return dest_image;
-}
diff --git a/common/pixman_utils.h b/common/pixman_utils.h
deleted file mode 100644
index e15b682..0000000
--- a/common/pixman_utils.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H__PIXMAN_UTILS
-#define _H__PIXMAN_UTILS
-
-#include <spice/types.h>
-#include <stdlib.h>
-#define PIXMAN_DONT_DEFINE_STDINT
-#include <pixman.h>
-
-#include "draw.h"
-
-/* This lists all possible 2 argument binary raster ops.
- * This enum has the same values as the X11 GXcopy type
- * and same as the GL constants (GL_AND etc) if you
- * or it with 0x1500. However it is not exactly the
- * same as the win32 ROP2 type (they use another order).
- */
-typedef enum {
-    SPICE_ROP_CLEAR,         /* 0x0    0 */
-    SPICE_ROP_AND,           /* 0x1    src AND dst */
-    SPICE_ROP_AND_REVERSE,   /* 0x2    src AND NOT dst */
-    SPICE_ROP_COPY,          /* 0x3    src */
-    SPICE_ROP_AND_INVERTED,  /* 0x4    (NOT src) AND dst */
-    SPICE_ROP_NOOP,          /* 0x5    dst */
-    SPICE_ROP_XOR,           /* 0x6    src XOR dst */
-    SPICE_ROP_OR,            /* 0x7    src OR dst */
-    SPICE_ROP_NOR,           /* 0x8    (NOT src) AND (NOT dst) */
-    SPICE_ROP_EQUIV,         /* 0x9    (NOT src) XOR dst */
-    SPICE_ROP_INVERT,        /* 0xa    NOT dst */
-    SPICE_ROP_OR_REVERSE,    /* 0xb    src OR (NOT dst) */
-    SPICE_ROP_COPY_INVERTED, /* 0xc    NOT src */
-    SPICE_ROP_OR_INVERTED,   /* 0xd    (NOT src) OR dst */
-    SPICE_ROP_NAND,          /* 0xe    (NOT src) OR (NOT dst) */
-    SPICE_ROP_SET            /* 0xf    1 */
-} SpiceROP;
-
-
-int spice_pixman_image_get_bpp(pixman_image_t *image);
-
-pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format);
-pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
-                                                   uint32_t palette_surface_format);
-pixman_image_t *spice_bitmap_try_as_pixman(int src_format, int flags,
-                                           int width, int height,
-                                           uint8_t *data, int stride);
-pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
-                                       int src_format, int flags,
-                                       int width, int height,
-                                       uint8_t *src, int src_stride,
-                                       uint32_t palette_surface_format,
-                                       SpicePalette *palette);
-pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
-                                               pixman_image_t *dest_image,
-                                               int src_format, int flags,
-                                               int width, int height,
-                                               uint8_t *src, int src_stride,
-                                               uint32_t palette_surface_format,
-                                               SpicePalette *palette);
-
-void spice_pixman_region32_init_from_bitmap(pixman_region32_t *region,
-                                            uint32_t *data,
-                                            int width, int height,
-                                            int stride);
-pixman_bool_t spice_pixman_region32_init_rects(pixman_region32_t *region,
-                                               const SpiceRect   *rects,
-                                               int                count);
-void spice_pixman_fill_rect(pixman_image_t *dest,
-                            int x, int y,
-                            int w, int h,
-                            uint32_t value);
-void spice_pixman_fill_rect_rop(pixman_image_t *dest,
-                                int x, int y,
-                                int w, int h,
-                                uint32_t value,
-                                SpiceROP rop);
-void spice_pixman_tile_rect(pixman_image_t *dest,
-                            int x, int y,
-                            int w, int h,
-                            pixman_image_t *tile,
-                            int offset_x,
-                            int offset_y);
-void spice_pixman_tile_rect_rop(pixman_image_t *dest,
-                                int x, int y,
-                                int w, int h,
-                                pixman_image_t *tile,
-                                int offset_x,
-                                int offset_y,
-                                SpiceROP rop);
-void spice_pixman_blit(pixman_image_t *dest,
-                       pixman_image_t *src,
-                       int src_x, int src_y,
-                       int dest_x, int dest_y,
-                       int w, int h);
-void spice_pixman_blit_rop(pixman_image_t *dest,
-                           pixman_image_t *src,
-                           int src_x, int src_y,
-                           int dest_x, int dest_y,
-                           int w, int h,
-                           SpiceROP rop);
-void spice_pixman_blit_colorkey(pixman_image_t *dest,
-                                pixman_image_t *src,
-                                int src_x, int src_y,
-                                int dest_x, int dest_y,
-                                int width, int height,
-                                uint32_t transparent_color);
-void spice_pixman_copy_rect(pixman_image_t *image,
-                            int src_x, int src_y,
-                            int w, int h,
-                            int dest_x, int dest_y);
-
-#endif /* _H__PIXMAN_UTILS */
diff --git a/common/quic.c b/common/quic.c
deleted file mode 100644
index 9f2c978..0000000
--- a/common/quic.c
+++ /dev/null
@@ -1,1706 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-// Red Hat image compression based on SFALIC by Roman Starosolski
-// http://sun.iinf.polsl.gliwice.pl/~rstaros/sfalic/index.html
-
-#include "quic.h"
-#include <spice/macros.h>
-
-//#define DEBUG
-
-#define RLE
-#define RLE_STAT
-#define PRED_1
-//#define RLE_PRED_1
-#define RLE_PRED_2
-//#define RLE_PRED_3
-#define QUIC_RGB
-
-#define QUIC_MAGIC (*(uint32_t *)"QUIC")
-#define QUIC_VERSION_MAJOR 0U
-#define QUIC_VERSION_MINOR 1U
-#define QUIC_VERSION ((QUIC_VERSION_MAJOR << 16) | (QUIC_VERSION_MAJOR & 0xffff))
-
-#ifdef DEBUG
-
-#define ASSERT(usr, x) \
-    if (!(x)) (usr)->error(usr, "%s: ASSERT %s failed\n", __FUNCTION__, #x);
-
-#else
-
-#define ASSERT(usr, x)
-
-#endif
-
-typedef uint8_t BYTE;
-
-/* maximum number of codes in family */
-#define MAXNUMCODES 8
-
-/* model evolution, warning: only 1,3 and 5 allowed */
-#define DEFevol 3
-#define MINevol 0
-#define MAXevol 5
-
-/* starting wait mask index */
-#define DEFwmistart 0
-#define MINwmistart 0
-
-/* codeword length limit */
-#define DEFmaxclen 26
-
-/* target wait mask index */
-#define DEFwmimax 6
-
-/* number of symbols to encode before increasing wait mask index */
-#define DEFwminext 2048
-#define MINwminext 1
-#define MAXwminext 100000000
-
-typedef struct QuicFamily {
-    unsigned int nGRcodewords[MAXNUMCODES];      /* indexed by code number, contains number of
-                                                    unmodified GR codewords in the code */
-    unsigned int notGRcwlen[MAXNUMCODES];        /* indexed by code number, contains codeword
-                                                    length of the not-GR codeword */
-    unsigned int notGRprefixmask[MAXNUMCODES];   /* indexed by code number, contains mask to
-                                                    determine if the codeword is GR or not-GR */
-    unsigned int notGRsuffixlen[MAXNUMCODES];    /* indexed by code number, contains suffix
-                                                    length of the not-GR codeword */
-
-    /* array for translating distribution U to L for depths up to 8 bpp,
-    initialized by decorelateinit() */
-    BYTE xlatU2L[256];
-
-    /* array for translating distribution L to U for depths up to 8 bpp,
-       initialized by corelateinit() */
-    unsigned int xlatL2U[256];
-} QuicFamily;
-
-static QuicFamily family_8bpc;
-static QuicFamily family_5bpc;
-
-typedef unsigned COUNTER;   /* counter in the array of counters in bucket of the data model */
-
-typedef struct s_bucket {
-    COUNTER *pcounters;     /* pointer to array of counters */
-    unsigned int bestcode;  /* best code so far */
-} s_bucket;
-
-typedef struct Encoder Encoder;
-
-typedef struct CommonState {
-    Encoder *encoder;
-
-    unsigned int waitcnt;
-    unsigned int tabrand_seed;
-    unsigned int wm_trigger;
-    unsigned int wmidx;
-    unsigned int wmileft;
-
-#ifdef RLE_STAT
-    int melcstate; /* index to the state array */
-
-    int melclen;  /* contents of the state array location
-                     indexed by melcstate: the "expected"
-                     run length is 2^melclen, shorter runs are
-                     encoded by a 1 followed by the run length
-                     in binary representation, wit a fixed length
-                     of melclen bits */
-
-    unsigned long melcorder;  /* 2^ melclen */
-#endif
-} CommonState;
-
-
-#define MAX_CHANNELS 4
-
-typedef struct FamilyStat {
-    s_bucket **buckets_ptrs;
-    s_bucket *buckets_buf;
-    COUNTER *counters;
-} FamilyStat;
-
-typedef struct Channel {
-    Encoder *encoder;
-
-    int correlate_row_width;
-    BYTE *correlate_row;
-
-    s_bucket **_buckets_ptrs;
-
-    FamilyStat family_stat_8bpc;
-    FamilyStat family_stat_5bpc;
-
-    CommonState state;
-} Channel;
-
-struct Encoder {
-    QuicUsrContext *usr;
-    QuicImageType type;
-    unsigned int width;
-    unsigned int height;
-    unsigned int num_channels;
-
-    unsigned int n_buckets_8bpc;
-    unsigned int n_buckets_5bpc;
-
-    unsigned int io_available_bits;
-    uint32_t io_word;
-    uint32_t io_next_word;
-    uint32_t *io_now;
-    uint32_t *io_end;
-    uint32_t io_words_count;
-
-    int rows_completed;
-
-    Channel channels[MAX_CHANNELS];
-
-    CommonState rgb_state;
-};
-
-/* target wait mask index */
-static int wmimax = DEFwmimax;
-
-/* number of symbols to encode before increasing wait mask index */
-static int wminext = DEFwminext;
-
-/* model evolution mode */
-static int evol = DEFevol;
-
-/* bppmask[i] contains i ones as lsb-s */
-static const unsigned long int bppmask[33] = {
-    0x00000000, /* [0] */
-    0x00000001, 0x00000003, 0x00000007, 0x0000000f,
-    0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
-    0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
-    0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
-    0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
-    0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
-    0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
-    0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff /* [32] */
-};
-
-static const unsigned int bitat[32] = {
-    0x00000001, 0x00000002, 0x00000004, 0x00000008,
-    0x00000010, 0x00000020, 0x00000040, 0x00000080,
-    0x00000100, 0x00000200, 0x00000400, 0x00000800,
-    0x00001000, 0x00002000, 0x00004000, 0x00008000,
-    0x00010000, 0x00020000, 0x00040000, 0x00080000,
-    0x00100000, 0x00200000, 0x00400000, 0x00800000,
-    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-    0x10000000, 0x20000000, 0x40000000, 0x80000000 /* [31]*/
-};
-
-
-#define TABRAND_TABSIZE 256
-#define TABRAND_SEEDMASK 0x0ff
-
-static const unsigned int tabrand_chaos[TABRAND_TABSIZE] = {
-    0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
-    0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
-    0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
-    0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
-    0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
-    0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
-    0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
-    0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
-    0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
-    0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
-    0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
-    0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
-    0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
-    0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
-    0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
-    0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
-    0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
-    0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
-    0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
-    0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
-    0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
-    0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
-    0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
-    0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
-    0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
-    0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
-    0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
-    0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
-    0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
-    0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
-    0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
-    0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5,
-};
-
-static unsigned int stabrand(void)
-{
-    //ASSERT( !(TABRAND_SEEDMASK & TABRAND_TABSIZE));
-    //ASSERT( TABRAND_SEEDMASK + 1 == TABRAND_TABSIZE );
-
-    return TABRAND_SEEDMASK;
-}
-
-static unsigned int tabrand(unsigned int *tabrand_seed)
-{
-    return tabrand_chaos[++*tabrand_seed & TABRAND_SEEDMASK];
-}
-
-static const unsigned short besttrigtab[3][11] = { /* array of wm_trigger for waitmask and evol,
-                                                    used by set_wm_trigger() */
-    /* 1 */ { 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160},
-    /* 3 */ { 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140},
-    /* 5 */ { 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160}
-};
-
-/* set wm_trigger knowing waitmask (param) and evol (glob)*/
-static void set_wm_trigger(CommonState *state)
-{
-    unsigned int wm = state->wmidx;
-    if (wm > 10) {
-        wm = 10;
-    }
-
-    ASSERT(state->encoder->usr, evol < 6);
-
-    state->wm_trigger = besttrigtab[evol / 2][wm];
-
-    ASSERT(state->encoder->usr, state->wm_trigger <= 2000);
-    ASSERT(state->encoder->usr, state->wm_trigger >= 1);
-}
-
-static int ceil_log_2(int val) /* ceil(log_2(val)) */
-{
-    int result;
-
-    //ASSERT(val>0);
-
-    if (val == 1) {
-        return 0;
-    }
-
-    result = 1;
-    val -= 1;
-    while (val >>= 1) {
-        result++;
-    }
-
-    return result;
-}
-
-/* number of leading zeroes in the byte, used by cntlzeroes(uint)*/
-static const BYTE lzeroes[256] = {
-    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* count leading zeroes */
-static unsigned int cnt_l_zeroes(const unsigned int bits)
-{
-    if (bits & 0xff800000) {
-        return lzeroes[bits >> 24];
-    } else if (bits & 0xffff8000) {
-        return 8 + lzeroes[(bits >> 16) & 0x000000ff];
-    } else if (bits & 0xffffff80) {
-        return 16 + lzeroes[(bits >> 8) & 0x000000ff];
-    } else {
-        return 24 + lzeroes[bits & 0x000000ff];
-    }
-}
-
-#define QUIC_FAMILY_8BPC
-#include "quic_family_tmpl.c"
-
-#ifdef QUIC_RGB
-#define QUIC_FAMILY_5BPC
-#include "quic_family_tmpl.c"
-#endif
-
-static void decorelate_init(QuicFamily *family, int bpc)
-{
-    const unsigned int pixelbitmask = bppmask[bpc];
-    const unsigned int pixelbitmaskshr = pixelbitmask >> 1;
-    unsigned int s;
-
-    //ASSERT(bpc <= 8);
-
-    for (s = 0; s <= pixelbitmask; s++) {
-        if (s <= pixelbitmaskshr) {
-            family->xlatU2L[s] = s << 1;
-        } else {
-            family->xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
-        }
-    }
-}
-
-static void corelate_init(QuicFamily *family, int bpc)
-{
-    const unsigned long int pixelbitmask = bppmask[bpc];
-    unsigned long int s;
-
-    //ASSERT(bpc <= 8);
-
-    for (s = 0; s <= pixelbitmask; s++) {
-        if (s & 0x01) {
-            family->xlatL2U[s] = pixelbitmask - (s >> 1);
-        } else {
-            family->xlatL2U[s] = (s >> 1);
-        }
-    }
-}
-
-static void family_init(QuicFamily *family, int bpc, int limit)
-{
-    int l;
-
-    for (l = 0; l < bpc; l++) { /* fill arrays indexed by code number */
-        int altprefixlen, altcodewords;
-
-        altprefixlen = limit - bpc;
-        if (altprefixlen > (int)(bppmask[bpc - l])) {
-            altprefixlen = bppmask[bpc - l];
-        }
-
-        altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
-
-        family->nGRcodewords[l] = (altprefixlen << l);
-        family->notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
-        family->notGRprefixmask[l] = bppmask[32 - altprefixlen]; /* needed for decoding only */
-        family->notGRsuffixlen[l] = ceil_log_2(altcodewords); /* needed for decoding only */
-    }
-
-    decorelate_init(family, bpc);
-    corelate_init(family, bpc);
-}
-
-static void more_io_words(Encoder *encoder)
-{
-    uint32_t *io_ptr;
-    int num_io_words = encoder->usr->more_space(encoder->usr, &io_ptr, encoder->rows_completed);
-    if (num_io_words <= 0) {
-        encoder->usr->error(encoder->usr, "%s: no more words\n", __FUNCTION__);
-    }
-    ASSERT(encoder->usr, io_ptr);
-    encoder->io_words_count += num_io_words;
-    encoder->io_now = io_ptr;
-    encoder->io_end = encoder->io_now + num_io_words;
-}
-
-static void __write_io_word(Encoder *encoder)
-{
-    more_io_words(encoder);
-    *(encoder->io_now++) = encoder->io_word;
-}
-
-static void (*__write_io_word_ptr)(Encoder *encoder) = __write_io_word;
-
-static INLINE void write_io_word(Encoder *encoder)
-{
-    if (encoder->io_now == encoder->io_end) {
-        __write_io_word_ptr(encoder); //disable inline optimizations
-        return;
-    }
-    *(encoder->io_now++) = encoder->io_word;
-}
-
-static INLINE void encode(Encoder *encoder, unsigned int word, unsigned int len)
-{
-    int delta;
-
-    ASSERT(encoder->usr, len > 0 && len < 32);
-    ASSERT(encoder->usr, !(word & ~bppmask[len]));
-    if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
-        encoder->io_available_bits = delta;
-        encoder->io_word |= word << encoder->io_available_bits;
-        return;
-    }
-    delta = -delta;
-    encoder->io_word |= word >> delta;
-    write_io_word(encoder);
-    encoder->io_available_bits = 32 - delta;
-    encoder->io_word = word << encoder->io_available_bits;
-
-    ASSERT(encoder->usr, encoder->io_available_bits < 32);
-    ASSERT(encoder->usr, (encoder->io_word & bppmask[encoder->io_available_bits]) == 0);
-}
-
-static INLINE void encode_32(Encoder *encoder, unsigned int word)
-{
-    encode(encoder, word >> 16, 16);
-    encode(encoder, word & 0x0000ffff, 16);
-}
-
-static INLINE void flush(Encoder *encoder)
-{
-    if (encoder->io_available_bits > 0 && encoder->io_available_bits != 32) {
-        encode(encoder, 0, encoder->io_available_bits);
-    }
-    encode_32(encoder, 0);
-    encode(encoder, 0, 1);
-}
-
-static void __read_io_word(Encoder *encoder)
-{
-    more_io_words(encoder);
-    encoder->io_next_word = *(encoder->io_now++);
-}
-
-static void (*__read_io_word_ptr)(Encoder *encoder) = __read_io_word;
-
-
-static INLINE void read_io_word(Encoder *encoder)
-{
-    if (encoder->io_now == encoder->io_end) {
-        __read_io_word_ptr(encoder); //disable inline optimizations
-        return;
-    }
-    ASSERT(encoder->usr, encoder->io_now < encoder->io_end);
-    encoder->io_next_word = *(encoder->io_now++);
-}
-
-static INLINE void decode_eatbits(Encoder *encoder, int len)
-{
-    int delta;
-
-    ASSERT(encoder->usr, len > 0 && len < 32);
-    encoder->io_word <<= len;
-
-    if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
-        encoder->io_available_bits = delta;
-        encoder->io_word |= encoder->io_next_word >> encoder->io_available_bits;
-        return;
-    }
-
-    delta = -delta;
-    encoder->io_word |= encoder->io_next_word << delta;
-    read_io_word(encoder);
-    encoder->io_available_bits = 32 - delta;
-    encoder->io_word |= (encoder->io_next_word >> encoder->io_available_bits);
-}
-
-static INLINE void decode_eat32bits(Encoder *encoder)
-{
-    decode_eatbits(encoder, 16);
-    decode_eatbits(encoder, 16);
-}
-
-#ifdef RLE
-
-#ifdef RLE_STAT
-
-static INLINE void encode_ones(Encoder *encoder, unsigned int n)
-{
-    unsigned int count;
-
-    for (count = n >> 5; count; count--) {
-        encode(encoder, ~0U, 32);
-    }
-
-    if ((n &= 0x1f)) {
-        encode(encoder, (1U << n) - 1, n);
-    }
-}
-
-#define MELCSTATES 32 /* number of melcode states */
-
-static int zeroLUT[256]; /* table to find out number of leading zeros */
-
-static int J[MELCSTATES] = {
-    0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
-    7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-/* creates the bit counting look-up table. */
-static void init_zeroLUT(void)
-{
-    int i, j, k, l;
-
-    j = k = 1;
-    l = 8;
-    for (i = 0; i < 256; ++i) {
-        zeroLUT[i] = l;
-        --k;
-        if (k == 0) {
-            k = j;
-            --l;
-            j *= 2;
-        }
-    }
-}
-
-static void encoder_init_rle(CommonState *state)
-{
-    state->melcstate = 0;
-    state->melclen = J[0];
-    state->melcorder = 1 << state->melclen;
-}
-
-#ifdef QUIC_RGB
-
-static void encode_run(Encoder *encoder, unsigned int runlen) //todo: try use end of line
-{
-    int hits = 0;
-
-    while (runlen >= encoder->rgb_state.melcorder) {
-        hits++;
-        runlen -= encoder->rgb_state.melcorder;
-        if (encoder->rgb_state.melcstate < MELCSTATES) {
-            encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
-            encoder->rgb_state.melcorder = (1L << encoder->rgb_state.melclen);
-        }
-    }
-
-    /* send the required number of "hit" bits (one per occurrence
-       of a run of length melcorder). This number is never too big:
-       after 31 such "hit" bits, each "hit" would represent a run of 32K
-       pixels.
-    */
-    encode_ones(encoder, hits);
-
-    encode(encoder, runlen, encoder->rgb_state.melclen + 1);
-
-    /* adjust melcoder parameters */
-    if (encoder->rgb_state.melcstate) {
-        encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
-        encoder->rgb_state.melcorder = (1L << encoder->rgb_state.melclen);
-    }
-}
-
-#endif
-
-static void encode_channel_run(Encoder *encoder, Channel *channel, unsigned int runlen)
-{
-    //todo: try use end of line
-    int hits = 0;
-
-    while (runlen >= channel->state.melcorder) {
-        hits++;
-        runlen -= channel->state.melcorder;
-        if (channel->state.melcstate < MELCSTATES) {
-            channel->state.melclen = J[++channel->state.melcstate];
-            channel->state.melcorder = (1L << channel->state.melclen);
-        }
-    }
-
-    /* send the required number of "hit" bits (one per occurrence
-       of a run of length melcorder). This number is never too big:
-       after 31 such "hit" bits, each "hit" would represent a run of 32K
-       pixels.
-    */
-    encode_ones(encoder, hits);
-
-    encode(encoder, runlen, channel->state.melclen + 1);
-
-    /* adjust melcoder parameters */
-    if (channel->state.melcstate) {
-        channel->state.melclen = J[--channel->state.melcstate];
-        channel->state.melcorder = (1L << channel->state.melclen);
-    }
-}
-
-/* decoding routine: reads bits from the input and returns a run length. */
-/* argument is the number of pixels left to end-of-line (bound on run length) */
-
-#ifdef QUIC_RGB
-static int decode_run(Encoder *encoder)
-{
-    int runlen = 0;
-
-    do {
-        register int temp, hits;
-        temp = zeroLUT[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
-                                                                      input stream, up to 8 */
-        for (hits = 1; hits <= temp; hits++) {
-            runlen += encoder->rgb_state.melcorder;
-
-            if (encoder->rgb_state.melcstate < MELCSTATES) {
-                encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
-                encoder->rgb_state.melcorder = (1U << encoder->rgb_state.melclen);
-            }
-        }
-        if (temp != 8) {
-            decode_eatbits(encoder, temp + 1);  /* consume the leading
-                                                            0 of the remainder encoding */
-            break;
-        }
-        decode_eatbits(encoder, 8);
-    } while (1);
-
-    /* read the length of the remainder */
-    if (encoder->rgb_state.melclen) {
-        runlen += encoder->io_word >> (32 - encoder->rgb_state.melclen);
-        decode_eatbits(encoder, encoder->rgb_state.melclen);
-    }
-
-    /* adjust melcoder parameters */
-    if (encoder->rgb_state.melcstate) {
-        encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
-        encoder->rgb_state.melcorder = (1U << encoder->rgb_state.melclen);
-    }
-
-    return runlen;
-}
-
-#endif
-
-static int decode_channel_run(Encoder *encoder, Channel *channel)
-{
-    int runlen = 0;
-
-    do {
-        register int temp, hits;
-        temp = zeroLUT[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
-                                                                      input stream, up to 8 */
-        for (hits = 1; hits <= temp; hits++) {
-            runlen += channel->state.melcorder;
-
-            if (channel->state.melcstate < MELCSTATES) {
-                channel->state.melclen = J[++channel->state.melcstate];
-                channel->state.melcorder = (1U << channel->state.melclen);
-            }
-        }
-        if (temp != 8) {
-            decode_eatbits(encoder, temp + 1);  /* consume the leading
-                                                            0 of the remainder encoding */
-            break;
-        }
-        decode_eatbits(encoder, 8);
-    } while (1);
-
-    /* read the length of the remainder */
-    if (channel->state.melclen) {
-        runlen += encoder->io_word >> (32 - channel->state.melclen);
-        decode_eatbits(encoder, channel->state.melclen);
-    }
-
-    /* adjust melcoder parameters */
-    if (channel->state.melcstate) {
-        channel->state.melclen = J[--channel->state.melcstate];
-        channel->state.melcorder = (1U << channel->state.melclen);
-    }
-
-    return runlen;
-}
-
-#else
-
-static INLINE int find_msb(int x)
-{
-    int r;
-
-    __asm__("bsrl %1,%0\n\t"
-            "jnz 1f\n\t"
-            "movl $-1,%0\n"
-            "1:" : "=r" (r) : "rm" (x));
-    return r + 1;
-}
-
-static INLINE void encode_run(Encoder *encoder, unsigned int len)
-{
-    int odd = len & 1U;
-    int msb;
-
-    len &= ~1U;
-
-    while ((msb = find_msb(len))) {
-        len &= ~(1 << (msb - 1));
-        ASSERT(encoder->usr, msb < 32);
-        encode(encoder, (1 << (msb)) - 1, msb);
-        encode(encoder, 0, 1);
-    }
-
-    if (odd) {
-        encode(encoder, 2, 2);
-    } else {
-        encode(encoder, 0, 1);
-    }
-}
-
-static INLINE unsigned int decode_run(Encoder *encoder)
-{
-    unsigned int len = 0;
-    int count;
-
-    do {
-        count = 0;
-        while (encoder->io_word & (1U << 31)) {
-            decode_eatbits(encoder, 1);
-            count++;
-            ASSERT(encoder->usr, count < 32);
-        }
-        decode_eatbits(encoder, 1);
-        len += (1U << count) >> 1;
-    } while (count > 1);
-
-    return len;
-}
-
-#endif
-#endif
-
-static INLINE void init_decode_io(Encoder *encoder)
-{
-    encoder->io_next_word = encoder->io_word = *(encoder->io_now++);
-    encoder->io_available_bits = 0;
-}
-
-#ifdef __GNUC__
-#define ATTR_PACKED __attribute__ ((__packed__))
-#else
-#define ATTR_PACKED
-#pragma pack(push)
-#pragma pack(1)
-#endif
-
-typedef struct ATTR_PACKED one_byte_pixel_t {
-    BYTE a;
-} one_byte_t;
-
-typedef struct ATTR_PACKED three_bytes_pixel_t {
-    BYTE a;
-    BYTE b;
-    BYTE c;
-} three_bytes_t;
-
-typedef struct ATTR_PACKED four_bytes_pixel_t {
-    BYTE a;
-    BYTE b;
-    BYTE c;
-    BYTE d;
-} four_bytes_t;
-
-typedef struct ATTR_PACKED rgb32_pixel_t {
-    BYTE b;
-    BYTE g;
-    BYTE r;
-    BYTE pad;
-} rgb32_pixel_t;
-
-typedef struct ATTR_PACKED rgb24_pixel_t {
-    BYTE b;
-    BYTE g;
-    BYTE r;
-} rgb24_pixel_t;
-
-typedef uint16_t rgb16_pixel_t;
-
-#ifndef __GNUC__
-#pragma pack(pop)
-#endif
-
-#undef ATTR_PACKED
-
-#define ONE_BYTE
-#include "quic_tmpl.c"
-
-#define FOUR_BYTE
-#include "quic_tmpl.c"
-
-#ifdef QUIC_RGB
-
-#define QUIC_RGB32
-#include "quic_rgb_tmpl.c"
-
-#define QUIC_RGB24
-#include "quic_rgb_tmpl.c"
-
-#define QUIC_RGB16
-#include "quic_rgb_tmpl.c"
-
-#define QUIC_RGB16_TO_32
-#include "quic_rgb_tmpl.c"
-
-#else
-
-#define THREE_BYTE
-#include "quic_tmpl.c"
-
-#endif
-
-static void fill_model_structures(Encoder *encoder, FamilyStat *family_stat,
-                                  unsigned int rep_first, unsigned int first_size,
-                                  unsigned int rep_next, unsigned int mul_size,
-                                  unsigned int levels, unsigned int ncounters,
-                                  unsigned int nbuckets, unsigned int n_buckets_ptrs)
-{
-    unsigned int
-    bsize,
-    bstart,
-    bend = 0,
-    repcntr,
-    bnumber;
-
-    COUNTER * free_counter = family_stat->counters;/* first free location in the array of
-                                                      counters */
-
-    bnumber = 0;
-
-    repcntr = rep_first + 1;    /* first bucket */
-    bsize = first_size;
-
-    do { /* others */
-        if (bnumber) {
-            bstart = bend + 1;
-        } else {
-            bstart = 0;
-        }
-
-        if (!--repcntr) {
-            repcntr = rep_next;
-            bsize *= mul_size;
-        }
-
-        bend = bstart + bsize - 1;
-        if (bend + bsize >= levels) {
-            bend = levels - 1;
-        }
-
-        family_stat->buckets_buf[bnumber].pcounters = free_counter;
-        free_counter += ncounters;
-
-        ASSERT(encoder->usr, bstart < n_buckets_ptrs);
-        {
-            unsigned int i;
-            ASSERT(encoder->usr, bend < n_buckets_ptrs);
-            for (i = bstart; i <= bend; i++) {
-                family_stat->buckets_ptrs[i] = family_stat->buckets_buf + bnumber;
-            }
-        }
-
-        bnumber++;
-    } while (bend < levels - 1);
-
-    ASSERT(encoder->usr, free_counter - family_stat->counters == nbuckets * ncounters);
-}
-
-static void find_model_params(Encoder *encoder,
-                              const int bpc,
-                              unsigned int *ncounters,
-                              unsigned int *levels,
-                              unsigned int *n_buckets_ptrs,
-                              unsigned int *repfirst,
-                              unsigned int *firstsize,
-                              unsigned int *repnext,
-                              unsigned int *mulsize,
-                              unsigned int *nbuckets)
-{
-    unsigned int bsize;              /* bucket size */
-    unsigned int bstart, bend = 0;   /* bucket start and end, range : 0 to levels-1*/
-    unsigned int repcntr;            /* helper */
-
-    ASSERT(encoder->usr, bpc <= 8 && bpc > 0);
-
-
-    *ncounters = 8;
-
-    *levels = 0x1 << bpc;
-
-    *n_buckets_ptrs = 0;  /* ==0 means: not set yet */
-
-    switch (evol) {   /* set repfirst firstsize repnext mulsize */
-    case 1: /* buckets contain following numbers of contexts: 1 1 1 2 2 4 4 8 8 ... */
-        *repfirst = 3;
-        *firstsize = 1;
-        *repnext = 2;
-        *mulsize = 2;
-        break;
-    case 3: /* 1 2 4 8 16 32 64 ... */
-        *repfirst = 1;
-        *firstsize = 1;
-        *repnext = 1;
-        *mulsize = 2;
-        break;
-    case 5:                     /* 1 4 16 64 256 1024 4096 16384 65536 */
-        *repfirst = 1;
-        *firstsize = 1;
-        *repnext = 1;
-        *mulsize = 4;
-        break;
-    case 0: /* obsolete */
-    case 2: /* obsolete */
-    case 4: /* obsolete */
-        encoder->usr->error(encoder->usr, "findmodelparams(): evol value obsolete!!!\n");
-    default:
-        encoder->usr->error(encoder->usr, "findmodelparams(): evol out of range!!!\n");
-    }
-
-    *nbuckets = 0;
-    repcntr = *repfirst + 1;    /* first bucket */
-    bsize = *firstsize;
-
-    do { /* other buckets */
-        if (nbuckets) {         /* bucket start */
-            bstart = bend + 1;
-        } else {
-            bstart = 0;
-        }
-
-        if (!--repcntr) {         /* bucket size */
-            repcntr = *repnext;
-            bsize *= *mulsize;
-        }
-
-        bend = bstart + bsize - 1;  /* bucket end */
-        if (bend + bsize >= *levels) {  /* if following bucked was bigger than current one */
-            bend = *levels - 1;     /* concatenate them */
-        }
-
-        if (!*n_buckets_ptrs) {           /* array size not set yet? */
-            *n_buckets_ptrs = *levels;
- #if 0
-            if (bend == *levels - 1) {   /* this bucket is last - all in the first array */
-                *n_buckets_ptrs = *levels;
-            } else if (bsize >= 256) { /* this bucket is allowed to reside in the 2nd table */
-                b_lo_ptrs = bstart;
-                assert(bstart);     /* previous bucket exists */
-            }
- #endif
-        }
-
-        (*nbuckets)++;
-    } while (bend < *levels - 1);
-}
-
-static int init_model_structures(Encoder *encoder, FamilyStat *family_stat,
-                                 unsigned int rep_first, unsigned int first_size,
-                                 unsigned int rep_next, unsigned int mul_size,
-                                 unsigned int levels, unsigned int ncounters,
-                                 unsigned int n_buckets_ptrs, unsigned int n_buckets)
-{
-    family_stat->buckets_ptrs = (s_bucket **)encoder->usr->malloc(encoder->usr,
-                                                                  n_buckets_ptrs *
-                                                                  sizeof(s_bucket *));
-    if (!family_stat->buckets_ptrs) {
-        return FALSE;
-    }
-
-    family_stat->counters = (COUNTER *)encoder->usr->malloc(encoder->usr,
-                                                            n_buckets * sizeof(COUNTER) *
-                                                            MAXNUMCODES);
-    if (!family_stat->counters) {
-        goto error_1;
-    }
-
-    family_stat->buckets_buf = (s_bucket *)encoder->usr->malloc(encoder->usr,
-                                                                n_buckets * sizeof(s_bucket));
-    if (!family_stat->buckets_buf) {
-        goto error_2;
-    }
-
-    fill_model_structures(encoder, family_stat, rep_first, first_size, rep_next, mul_size, levels,
-                          ncounters, n_buckets, n_buckets_ptrs);
-
-    return TRUE;
-
-error_2:
-    encoder->usr->free(encoder->usr, family_stat->counters);
-
-error_1:
-    encoder->usr->free(encoder->usr, family_stat->buckets_ptrs);
-
-    return FALSE;
-}
-
-static void free_family_stat(QuicUsrContext *usr, FamilyStat *family_stat)
-{
-    usr->free(usr, family_stat->buckets_ptrs);
-    usr->free(usr, family_stat->counters);
-    usr->free(usr, family_stat->buckets_buf);
-}
-
-static int init_channel(Encoder *encoder, Channel *channel)
-{
-    unsigned int ncounters;
-    unsigned int levels;
-    unsigned int rep_first;
-    unsigned int first_size;
-    unsigned int rep_next;
-    unsigned int mul_size;
-    unsigned int n_buckets;
-    unsigned int n_buckets_ptrs;
-
-    channel->encoder = encoder;
-    channel->state.encoder = encoder;
-    channel->correlate_row_width = 0;
-    channel->correlate_row = NULL;
-
-    find_model_params(encoder, 8, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
-                      &first_size, &rep_next, &mul_size, &n_buckets);
-    encoder->n_buckets_8bpc = n_buckets;
-    if (!init_model_structures(encoder, &channel->family_stat_8bpc, rep_first, first_size,
-                               rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
-                               n_buckets)) {
-        return FALSE;
-    }
-
-    find_model_params(encoder, 5, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
-                      &first_size, &rep_next, &mul_size, &n_buckets);
-    encoder->n_buckets_5bpc = n_buckets;
-    if (!init_model_structures(encoder, &channel->family_stat_5bpc, rep_first, first_size,
-                               rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
-                               n_buckets)) {
-        free_family_stat(encoder->usr, &channel->family_stat_8bpc);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static void destroy_channel(Channel *channel)
-{
-    QuicUsrContext *usr = channel->encoder->usr;
-    if (channel->correlate_row) {
-        usr->free(usr, channel->correlate_row - 1);
-    }
-    free_family_stat(usr, &channel->family_stat_8bpc);
-    free_family_stat(usr, &channel->family_stat_5bpc);
-}
-
-static int init_encoder(Encoder *encoder, QuicUsrContext *usr)
-{
-    int i;
-
-    encoder->usr = usr;
-    encoder->rgb_state.encoder = encoder;
-
-    for (i = 0; i < MAX_CHANNELS; i++) {
-        if (!init_channel(encoder, &encoder->channels[i])) {
-            for (--i; i >= 0; i--) {
-                destroy_channel(&encoder->channels[i]);
-            }
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
-static int encoder_reste(Encoder *encoder, uint32_t *io_ptr, uint32_t *io_ptr_end)
-{
-    ASSERT(encoder->usr, ((unsigned long)io_ptr % 4) == ((unsigned long)io_ptr_end % 4));
-    ASSERT(encoder->usr, io_ptr <= io_ptr_end);
-
-    encoder->rgb_state.waitcnt = 0;
-    encoder->rgb_state.tabrand_seed = stabrand();
-    encoder->rgb_state.wmidx = DEFwmistart;
-    encoder->rgb_state.wmileft = wminext;
-    set_wm_trigger(&encoder->rgb_state);
-
-#if defined(RLE) && defined(RLE_STAT)
-    encoder_init_rle(&encoder->rgb_state);
-#endif
-
-    encoder->io_words_count = io_ptr_end - io_ptr;
-    encoder->io_now = io_ptr;
-    encoder->io_end = io_ptr_end;
-    encoder->rows_completed = 0;
-
-    return TRUE;
-}
-
-static int encoder_reste_channels(Encoder *encoder, int channels, int width, int bpc)
-{
-    int i;
-
-    encoder->num_channels = channels;
-
-    for (i = 0; i < channels; i++) {
-        s_bucket *bucket;
-        s_bucket *end_bucket;
-
-        if (encoder->channels[i].correlate_row_width < width) {
-            encoder->channels[i].correlate_row_width = 0;
-            if (encoder->channels[i].correlate_row) {
-                encoder->usr->free(encoder->usr, encoder->channels[i].correlate_row - 1);
-            }
-            if (!(encoder->channels[i].correlate_row = (BYTE *)encoder->usr->malloc(encoder->usr,
-                                                                                    width + 1))) {
-                return FALSE;
-            }
-            encoder->channels[i].correlate_row++;
-            encoder->channels[i].correlate_row_width = width;
-        }
-
-        if (bpc == 8) {
-            MEMCLEAR(encoder->channels[i].family_stat_8bpc.counters,
-                     encoder->n_buckets_8bpc * sizeof(COUNTER) * MAXNUMCODES);
-            bucket = encoder->channels[i].family_stat_8bpc.buckets_buf;
-            end_bucket = bucket + encoder->n_buckets_8bpc;
-            for (; bucket < end_bucket; bucket++) {
-                bucket->bestcode = /*BPC*/ 8 - 1;
-            }
-            encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_8bpc.buckets_ptrs;
-        } else if (bpc == 5) {
-            MEMCLEAR(encoder->channels[i].family_stat_5bpc.counters,
-                     encoder->n_buckets_5bpc * sizeof(COUNTER) * MAXNUMCODES);
-            bucket = encoder->channels[i].family_stat_5bpc.buckets_buf;
-            end_bucket = bucket + encoder->n_buckets_5bpc;
-            for (; bucket < end_bucket; bucket++) {
-                bucket->bestcode = /*BPC*/ 5 - 1;
-            }
-            encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_5bpc.buckets_ptrs;
-        } else {
-            encoder->usr->warn(encoder->usr, "%s: bad bpc %d\n", __FUNCTION__, bpc);
-            return FALSE;
-        }
-
-        encoder->channels[i].state.waitcnt = 0;
-        encoder->channels[i].state.tabrand_seed = stabrand();
-        encoder->channels[i].state.wmidx = DEFwmistart;
-        encoder->channels[i].state.wmileft = wminext;
-        set_wm_trigger(&encoder->channels[i].state);
-
-#if defined(RLE) && defined(RLE_STAT)
-        encoder_init_rle(&encoder->channels[i].state);
-#endif
-    }
-    return TRUE;
-}
-
-static void quic_image_params(Encoder *encoder, QuicImageType type, int *channels, int *bpc)
-{
-    ASSERT(encoder->usr, channels && bpc);
-    switch (type) {
-    case QUIC_IMAGE_TYPE_GRAY:
-        *channels = 1;
-        *bpc = 8;
-        break;
-    case QUIC_IMAGE_TYPE_RGB16:
-        *channels = 3;
-        *bpc = 5;
-#ifndef QUIC_RGB
-        encoder->usr->error(encoder->usr, "not implemented\n");
-#endif
-        break;
-    case QUIC_IMAGE_TYPE_RGB24:
-        *channels = 3;
-        *bpc = 8;
-        break;
-    case QUIC_IMAGE_TYPE_RGB32:
-        *channels = 3;
-        *bpc = 8;
-        break;
-    case QUIC_IMAGE_TYPE_RGBA:
-        *channels = 4;
-        *bpc = 8;
-        break;
-    case QUIC_IMAGE_TYPE_INVALID:
-    default:
-        *channels = 0;
-        *bpc = 0;
-        encoder->usr->error(encoder->usr, "bad image type\n");
-    }
-}
-
-#define FILL_LINES() {                                                  \
-    if (line == lines_end) {                                            \
-        int n = encoder->usr->more_lines(encoder->usr, &line);          \
-        if (n <= 0) {                                                   \
-            encoder->usr->error(encoder->usr, "more lines failed\n");   \
-        }                                                               \
-        lines_end = line + n * stride;                                  \
-    }                                                                   \
-}
-
-#define NEXT_LINE() {       \
-    line += stride;         \
-    FILL_LINES();           \
-}
-
-#define QUIC_COMPRESS_RGB(bits)                                                                 \
-        encoder->channels[0].correlate_row[-1] = 0;                                             \
-        encoder->channels[1].correlate_row[-1] = 0;                                             \
-        encoder->channels[2].correlate_row[-1] = 0;                                             \
-        quic_rgb##bits##_compress_row0(encoder, (rgb##bits##_pixel_t *)(line), width);          \
-        encoder->rows_completed++;                                                              \
-        for (row = 1; row < height; row++) {                                                    \
-            prev = line;                                                                        \
-            NEXT_LINE();                                                                        \
-            encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];     \
-            encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];     \
-            encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];     \
-            quic_rgb##bits##_compress_row(encoder, (rgb##bits##_pixel_t *)prev,                 \
-                                          (rgb##bits##_pixel_t *)line, width);                  \
-            encoder->rows_completed++;                                                          \
-        }
-
-int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
-                uint8_t *line, unsigned int num_lines, int stride,
-                uint32_t *io_ptr, unsigned int num_io_words)
-{
-    Encoder *encoder = (Encoder *)quic;
-    uint32_t *io_ptr_end = io_ptr + num_io_words;
-    uint8_t *lines_end;
-    int row;
-    uint8_t *prev;
-    int channels;
-    int bpc;
-#ifndef QUIC_RGB
-    int i;
-#endif
-
-    ASSERT(encoder->usr, line);
-    lines_end = line + num_lines * stride;
-
-    quic_image_params(encoder, type, &channels, &bpc);
-
-    if (!encoder_reste(encoder, io_ptr, io_ptr_end) ||
-        !encoder_reste_channels(encoder, channels, width, bpc)) {
-        return QUIC_ERROR;
-    }
-
-    encoder->io_word = 0;
-    encoder->io_available_bits = 32;
-
-    encode_32(encoder, QUIC_MAGIC);
-    encode_32(encoder, QUIC_VERSION);
-    encode_32(encoder, type);
-    encode_32(encoder, width);
-    encode_32(encoder, height);
-
-    FILL_LINES();
-
-    switch (type) {
-#ifdef QUIC_RGB
-    case QUIC_IMAGE_TYPE_RGB32:
-        ASSERT(encoder->usr, ABS(stride) >= width * 4);
-        QUIC_COMPRESS_RGB(32);
-        break;
-    case QUIC_IMAGE_TYPE_RGB24:
-        ASSERT(encoder->usr, ABS(stride) >= width * 3);
-        QUIC_COMPRESS_RGB(24);
-        break;
-    case QUIC_IMAGE_TYPE_RGB16:
-        ASSERT(encoder->usr, ABS(stride) >= width * 2);
-        QUIC_COMPRESS_RGB(16);
-        break;
-    case QUIC_IMAGE_TYPE_RGBA:
-        ASSERT(encoder->usr, ABS(stride) >= width * 4);
-
-        encoder->channels[0].correlate_row[-1] = 0;
-        encoder->channels[1].correlate_row[-1] = 0;
-        encoder->channels[2].correlate_row[-1] = 0;
-        quic_rgb32_compress_row0(encoder, (rgb32_pixel_t *)(line), width);
-
-        encoder->channels[3].correlate_row[-1] = 0;
-        quic_four_compress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(line + 3), width);
-
-        encoder->rows_completed++;
-
-        for (row = 1; row < height; row++) {
-            prev = line;
-            NEXT_LINE();
-            encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
-            encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
-            encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
-            quic_rgb32_compress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)line, width);
-
-            encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
-            quic_four_compress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
-                                   (four_bytes_t *)(line + 3), width);
-            encoder->rows_completed++;
-        }
-        break;
-#else
-    case QUIC_IMAGE_TYPE_RGB24:
-        ASSERT(encoder->usr, ABS(stride) >= width * 3);
-        for (i = 0; i < 3; i++) {
-            encoder->channels[i].correlate_row[-1] = 0;
-            quic_three_compress_row0(encoder, &encoder->channels[i], (three_bytes_t *)(line + i),
-                                     width);
-        }
-        encoder->rows_completed++;
-        for (row = 1; row < height; row++) {
-            prev = line;
-            NEXT_LINE();
-            for (i = 0; i < 3; i++) {
-                encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
-                quic_three_compress_row(encoder, &encoder->channels[i], (three_bytes_t *)(prev + i),
-                                        (three_bytes_t *)(line + i), width);
-            }
-            encoder->rows_completed++;
-        }
-        break;
-    case QUIC_IMAGE_TYPE_RGB32:
-    case QUIC_IMAGE_TYPE_RGBA:
-        ASSERT(encoder->usr, ABS(stride) >= width * 4);
-        for (i = 0; i < channels; i++) {
-            encoder->channels[i].correlate_row[-1] = 0;
-            quic_four_compress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(line + i),
-                                    width);
-        }
-        encoder->rows_completed++;
-        for (row = 1; row < height; row++) {
-            prev = line;
-            NEXT_LINE();
-            for (i = 0; i < channels; i++) {
-                encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
-                quic_four_compress_row(encoder, &encoder->channels[i], (four_bytes_t *)(prev + i),
-                                       (four_bytes_t *)(line + i), width);
-            }
-            encoder->rows_completed++;
-        }
-        break;
-#endif
-    case QUIC_IMAGE_TYPE_GRAY:
-        ASSERT(encoder->usr, ABS(stride) >= width);
-        encoder->channels[0].correlate_row[-1] = 0;
-        quic_one_compress_row0(encoder, &encoder->channels[0], (one_byte_t *)line, width);
-        encoder->rows_completed++;
-        for (row = 1; row < height; row++) {
-            prev = line;
-            NEXT_LINE();
-            encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
-            quic_one_compress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
-                                  (one_byte_t *)line, width);
-            encoder->rows_completed++;
-        }
-        break;
-    case QUIC_IMAGE_TYPE_INVALID:
-    default:
-        encoder->usr->error(encoder->usr, "bad image type\n");
-    }
-
-    flush(encoder);
-    encoder->io_words_count -= (encoder->io_end - encoder->io_now);
-
-    return encoder->io_words_count;
-}
-
-int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
-                      QuicImageType *out_type, int *out_width, int *out_height)
-{
-    Encoder *encoder = (Encoder *)quic;
-    uint32_t *io_ptr_end = io_ptr + num_io_words;
-    QuicImageType type;
-    int width;
-    int height;
-    uint32_t magic;
-    uint32_t version;
-    int channels;
-    int bpc;
-
-    if (!encoder_reste(encoder, io_ptr, io_ptr_end)) {
-        return QUIC_ERROR;
-    }
-
-    init_decode_io(encoder);
-
-    magic = encoder->io_word;
-    decode_eat32bits(encoder);
-    if (magic != QUIC_MAGIC) {
-        encoder->usr->warn(encoder->usr, "bad magic\n");
-        return QUIC_ERROR;
-    }
-
-    version = encoder->io_word;
-    decode_eat32bits(encoder);
-    if (version != QUIC_VERSION) {
-        encoder->usr->warn(encoder->usr, "bad version\n");
-        return QUIC_ERROR;
-    }
-
-    type = (QuicImageType)encoder->io_word;
-    decode_eat32bits(encoder);
-
-    width = encoder->io_word;
-    decode_eat32bits(encoder);
-
-    height = encoder->io_word;
-    decode_eat32bits(encoder);
-
-    quic_image_params(encoder, type, &channels, &bpc);
-
-    if (!encoder_reste_channels(encoder, channels, width, bpc)) {
-        return QUIC_ERROR;
-    }
-
-    *out_width = encoder->width = width;
-    *out_height = encoder->height = height;
-    *out_type = encoder->type = type;
-    return QUIC_OK;
-}
-
-#ifndef QUIC_RGB
-static void clear_row(four_bytes_t *row, int width)
-{
-    four_bytes_t *end;
-    for (end = row + width; row < end; row++) {
-        row->a = 0;
-    }
-}
-
-#endif
-
-#ifdef QUIC_RGB
-
-static void uncompress_rgba(Encoder *encoder, uint8_t *buf, int stride)
-{
-    unsigned int row;
-    uint8_t *prev;
-
-    encoder->channels[0].correlate_row[-1] = 0;
-    encoder->channels[1].correlate_row[-1] = 0;
-    encoder->channels[2].correlate_row[-1] = 0;
-    quic_rgb32_uncompress_row0(encoder, (rgb32_pixel_t *)buf, encoder->width);
-
-    encoder->channels[3].correlate_row[-1] = 0;
-    quic_four_uncompress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(buf + 3),
-                              encoder->width);
-
-    encoder->rows_completed++;
-    for (row = 1; row < encoder->height; row++) {
-        prev = buf;
-        buf += stride;
-
-        encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
-        encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
-        encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
-        quic_rgb32_uncompress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)buf,
-                                  encoder->width);
-
-        encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
-        quic_four_uncompress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
-                                 (four_bytes_t *)(buf + 3), encoder->width);
-
-        encoder->rows_completed++;
-    }
-}
-
-#endif
-
-static void uncompress_gray(Encoder *encoder, uint8_t *buf, int stride)
-{
-    unsigned int row;
-    uint8_t *prev;
-
-    encoder->channels[0].correlate_row[-1] = 0;
-    quic_one_uncompress_row0(encoder, &encoder->channels[0], (one_byte_t *)buf, encoder->width);
-    encoder->rows_completed++;
-    for (row = 1; row < encoder->height; row++) {
-        prev = buf;
-        buf += stride;
-        encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
-        quic_one_uncompress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
-                                (one_byte_t *)buf, encoder->width);
-        encoder->rows_completed++;
-    }
-}
-
-#define QUIC_UNCOMPRESS_RGB(prefix, type)                                                       \
-        encoder->channels[0].correlate_row[-1] = 0;                                             \
-        encoder->channels[1].correlate_row[-1] = 0;                                             \
-        encoder->channels[2].correlate_row[-1] = 0;                                             \
-        quic_rgb##prefix##_uncompress_row0(encoder, (type *)buf, encoder->width);  \
-        encoder->rows_completed++;                                                              \
-        for (row = 1; row < encoder->height; row++) {                                           \
-            prev = buf;                                                                         \
-            buf += stride;                                                                      \
-            encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];     \
-            encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];     \
-            encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];     \
-            quic_rgb##prefix##_uncompress_row(encoder, (type *)prev, (type *)buf,               \
-                                              encoder->width);                                  \
-            encoder->rows_completed++;                                                          \
-        }
-        
-int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride)
-{
-    Encoder *encoder = (Encoder *)quic;
-    unsigned int row;
-    uint8_t *prev;
-#ifndef QUIC_RGB
-    int i;
-#endif
-
-    ASSERT(encoder->usr, buf);
-
-    switch (encoder->type) {
-#ifdef QUIC_RGB
-    case QUIC_IMAGE_TYPE_RGB32:
-    case QUIC_IMAGE_TYPE_RGB24:
-        if (type == QUIC_IMAGE_TYPE_RGB32) {
-            ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
-            QUIC_UNCOMPRESS_RGB(32, rgb32_pixel_t);
-            break;
-        } else if (type == QUIC_IMAGE_TYPE_RGB24) {
-            ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 3);
-            QUIC_UNCOMPRESS_RGB(24, rgb24_pixel_t);
-            break;
-        }
-        encoder->usr->warn(encoder->usr, "unsupported output format\n");
-        return QUIC_ERROR;
-    case QUIC_IMAGE_TYPE_RGB16:
-        if (type == QUIC_IMAGE_TYPE_RGB16) {
-            ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 2);
-            QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
-        } else if (type == QUIC_IMAGE_TYPE_RGB32) {
-            ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
-            QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
-        } else {
-            encoder->usr->warn(encoder->usr, "unsupported output format\n");
-            return QUIC_ERROR;
-        }
-
-        break;
-    case QUIC_IMAGE_TYPE_RGBA:
-
-        if (type != QUIC_IMAGE_TYPE_RGBA) {
-            encoder->usr->warn(encoder->usr, "unsupported output format\n");
-            return QUIC_ERROR;
-        }
-        ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
-        uncompress_rgba(encoder, buf, stride);
-        break;
-#else
-    case QUIC_IMAGE_TYPE_RGB24:
-        ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 3);
-        for (i = 0; i < 3; i++) {
-            encoder->channels[i].correlate_row[-1] = 0;
-            quic_three_uncompress_row0(encoder, &encoder->channels[i], (three_bytes_t *)(buf + i),
-                                       encoder->width);
-        }
-        encoder->rows_completed++;
-        for (row = 1; row < encoder->height; row++) {
-            prev = buf;
-            buf += stride;
-            for (i = 0; i < 3; i++) {
-                encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
-                quic_three_uncompress_row(encoder, &encoder->channels[i],
-                                          (three_bytes_t *)(prev + i),
-                                          (three_bytes_t *)(buf + i),
-                                          encoder->width);
-            }
-            encoder->rows_completed++;
-        }
-        break;
-    case QUIC_IMAGE_TYPE_RGB32:
-        ASSERT(encoder->usr, ABS(stride) >= encoder->width * 4);
-        for (i = 0; i < 3; i++) {
-            encoder->channels[i].correlate_row[-1] = 0;
-            quic_four_uncompress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(buf + i),
-                                      encoder->width);
-        }
-        clear_row((four_bytes_t *)(buf + 3), encoder->width);
-        encoder->rows_completed++;
-        for (row = 1; row < encoder->height; row++) {
-            prev = buf;
-            buf += stride;
-            for (i = 0; i < 3; i++) {
-                encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
-                quic_four_uncompress_row(encoder, &encoder->channels[i],
-                                         (four_bytes_t *)(prev + i),
-                                         (four_bytes_t *)(buf + i),
-                                         encoder->width);
-            }
-            clear_row((four_bytes_t *)(buf + 3), encoder->width);
-            encoder->rows_completed++;
-        }
-        break;
-    case QUIC_IMAGE_TYPE_RGBA:
-        ASSERT(encoder->usr, ABS(stride) >= encoder->width * 4);
-        for (i = 0; i < 4; i++) {
-            encoder->channels[i].correlate_row[-1] = 0;
-            quic_four_uncompress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(buf + i),
-                                      encoder->width);
-        }
-        encoder->rows_completed++;
-        for (row = 1; row < encoder->height; row++) {
-            prev = buf;
-            buf += stride;
-            for (i = 0; i < 4; i++) {
-                encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
-                quic_four_uncompress_row(encoder, &encoder->channels[i],
-                                         (four_bytes_t *)(prev + i),
-                                         (four_bytes_t *)(buf + i),
-                                         encoder->width);
-            }
-            encoder->rows_completed++;
-        }
-        break;
-#endif
-    case QUIC_IMAGE_TYPE_GRAY:
-
-        if (type != QUIC_IMAGE_TYPE_GRAY) {
-            encoder->usr->warn(encoder->usr, "unsupported output format\n");
-            return QUIC_ERROR;
-        }
-        ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width);
-        uncompress_gray(encoder, buf, stride);
-        break;
-    case QUIC_IMAGE_TYPE_INVALID:
-    default:
-        encoder->usr->error(encoder->usr, "bad image type\n");
-    }
-    return QUIC_OK;
-}
-
-static int need_init = TRUE;
-
-QuicContext *quic_create(QuicUsrContext *usr)
-{
-    Encoder *encoder;
-
-    if (!usr || need_init || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
-        !usr->free || !usr->more_space || !usr->more_lines) {
-        return NULL;
-    }
-
-    if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
-        return NULL;
-    }
-
-    if (!init_encoder(encoder, usr)) {
-        usr->free(usr, encoder);
-        return NULL;
-    }
-    return (QuicContext *)encoder;
-}
-
-void quic_destroy(QuicContext *quic)
-{
-    Encoder *encoder = (Encoder *)quic;
-    int i;
-
-    if (!quic) {
-        return;
-    }
-
-    for (i = 0; i < MAX_CHANNELS; i++) {
-        destroy_channel(&encoder->channels[i]);
-    }
-    encoder->usr->free(encoder->usr, encoder);
-}
-
-void quic_init(void)
-{
-    if (!need_init) {
-        return;
-    }
-    need_init = FALSE;
-
-    family_init(&family_8bpc, 8, DEFmaxclen);
-    family_init(&family_5bpc, 5, DEFmaxclen);
-#if defined(RLE) && defined(RLE_STAT)
-    init_zeroLUT();
-#endif
-}
-
diff --git a/common/quic.h b/common/quic.h
deleted file mode 100644
index 35683d2..0000000
--- a/common/quic.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __QUIC_H
-#define __QUIC_H
-
-#include "quic_config.h"
-#include "macros.h"
-
-typedef enum {
-    QUIC_IMAGE_TYPE_INVALID,
-    QUIC_IMAGE_TYPE_GRAY,
-    QUIC_IMAGE_TYPE_RGB16,
-    QUIC_IMAGE_TYPE_RGB24,
-    QUIC_IMAGE_TYPE_RGB32,
-    QUIC_IMAGE_TYPE_RGBA
-} QuicImageType;
-
-#define QUIC_ERROR -1
-#define QUIC_OK 0
-
-typedef void *QuicContext;
-
-typedef struct QuicUsrContext QuicUsrContext;
-struct QuicUsrContext {
-    ATTR_PRINTF(2, 3) void (*error)(QuicUsrContext *usr, const char *fmt, ...);
-    ATTR_PRINTF(2, 3) void (*warn)(QuicUsrContext *usr, const char *fmt, ...);
-    ATTR_PRINTF(2, 3) void (*info)(QuicUsrContext *usr, const char *fmt, ...);
-    void *(*malloc)(QuicUsrContext *usr, int size);
-    void (*free)(QuicUsrContext *usr, void *ptr);
-    int (*more_space)(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed);
-    int (*more_lines)(QuicUsrContext *usr, uint8_t **lines); // on return the last line of previous
-                                                             // lines bunch must still be valid
-};
-
-int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
-                uint8_t *lines, unsigned int num_lines, int stride,
-                uint32_t *io_ptr, unsigned int num_io_words);
-
-int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
-                      QuicImageType *type, int *width, int *height);
-int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride);
-
-
-QuicContext *quic_create(QuicUsrContext *usr);
-void quic_destroy(QuicContext *quic);
-
-void quic_init(void);
-
-#endif
-
diff --git a/common/quic_config.h b/common/quic_config.h
deleted file mode 100644
index 1273dbc..0000000
--- a/common/quic_config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __QUIC_CONFIG_H
-#define __QUIC_CONFIG_H
-
-#include <spice/types.h>
-
-#ifdef __GNUC__
-
-#include <string.h>
-
-#define INLINE inline
-
-#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
-
-#else
-
-#ifdef QXLDD
-#include <windef.h>
-#include "os_dep.h"
-#define INLINE _inline
-#define MEMCLEAR(ptr, size) RtlZeroMemory(ptr, size)
-#else
-#include <stddef.h>
-#include <string.h>
-
-#define INLINE inline
-#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
-#endif
-
-
-#endif
-
-#endif
-
diff --git a/common/quic_family_tmpl.c b/common/quic_family_tmpl.c
deleted file mode 100644
index e07596b..0000000
--- a/common/quic_family_tmpl.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef QUIC_FAMILY_8BPC
-#undef QUIC_FAMILY_8BPC
-#define FNAME(name) name##_8bpc
-#define VNAME(name) name##_8bpc
-#define BPC 8
-#endif
-
-
-#ifdef QUIC_FAMILY_5BPC
-#undef QUIC_FAMILY_5BPC
-#define FNAME(name) name##_5bpc
-#define VNAME(name) name##_5bpc
-#define BPC 5
-#endif
-
-
-static unsigned int FNAME(golomb_code_len)(const BYTE n, const unsigned int l)
-{
-    if (n < VNAME(family).nGRcodewords[l]) {
-        return (n >> l) + 1 + l;
-    } else {
-        return VNAME(family).notGRcwlen[l];
-    }
-}
-
-static void FNAME(golomb_coding)(const BYTE n, const unsigned int l, unsigned int * const codeword,
-                                 unsigned int * const codewordlen)
-{
-    if (n < VNAME(family).nGRcodewords[l]) {
-        (*codeword) = bitat[l] | (n & bppmask[l]);
-        (*codewordlen) = (n >> l) + l + 1;
-    } else {
-        (*codeword) = n - VNAME(family).nGRcodewords[l];
-        (*codewordlen) = VNAME(family).notGRcwlen[l];
-    }
-}
-
-static unsigned int FNAME(golomb_decoding)(const unsigned int l, const unsigned int bits,
-                                           unsigned int * const codewordlen)
-{
-    if (bits > VNAME(family).notGRprefixmask[l]) { /*GR*/
-        const unsigned int zeroprefix = cnt_l_zeroes(bits);       /* leading zeroes in codeword */
-        const unsigned int cwlen = zeroprefix + 1 + l;            /* codeword length */
-        (*codewordlen) = cwlen;
-        return (zeroprefix << l) | ((bits >> (32 - cwlen)) & bppmask[l]);
-    } else { /* not-GR */
-        const unsigned int cwlen = VNAME(family).notGRcwlen[l];
-        (*codewordlen) = cwlen;
-        return VNAME(family).nGRcodewords[l] + ((bits) >> (32 - cwlen) &
-                                                bppmask[VNAME(family).notGRsuffixlen[l]]);
-    }
-}
-
-/* update the bucket using just encoded curval */
-static void FNAME(update_model)(CommonState *state, s_bucket * const bucket,
-                                const BYTE curval, unsigned int bpp)
-{
-    COUNTER * const pcounters = bucket->pcounters;
-    unsigned int i;
-    unsigned int bestcode;
-    unsigned int bestcodelen;
-    //unsigned int bpp = encoder->bpp;
-
-    /* update counters, find minimum */
-
-    bestcode = bpp - 1;
-    bestcodelen = (pcounters[bestcode] += FNAME(golomb_code_len)(curval, bestcode));
-
-    for (i = bpp - 2; i < bpp; i--) { /* NOTE: expression i<bpp for signed int i would be: i>=0 */
-        const unsigned int ithcodelen = (pcounters[i] += FNAME(golomb_code_len)(curval, i));
-
-        if (ithcodelen < bestcodelen) {
-            bestcode = i;
-            bestcodelen = ithcodelen;
-        }
-    }
-
-    bucket->bestcode = bestcode; /* store the found minimum */
-
-    if (bestcodelen > state->wm_trigger) { /* halving counters? */
-        for (i = 0; i < bpp; i++) {
-            pcounters[i] >>= 1;
-        }
-    }
-}
-
-static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val)
-{
-    ASSERT(channel->encoder->usr, val < (0x1U << BPC));
-
-    return channel->_buckets_ptrs[val];
-}
-
-#undef FNAME
-#undef VNAME
-#undef BPC
-
diff --git a/common/quic_rgb_tmpl.c b/common/quic_rgb_tmpl.c
deleted file mode 100644
index 681493a..0000000
--- a/common/quic_rgb_tmpl.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef QUIC_RGB32
-#undef QUIC_RGB32
-#define PIXEL rgb32_pixel_t
-#define FNAME(name) quic_rgb32_##name
-#define golomb_coding golomb_coding_8bpc
-#define golomb_decoding golomb_decoding_8bpc
-#define update_model update_model_8bpc
-#define find_bucket find_bucket_8bpc
-#define family family_8bpc
-#define BPC 8
-#define BPC_MASK 0xffU
-#define COMPRESS_IMP
-#define SET_r(pix, val) ((pix)->r = val)
-#define GET_r(pix) ((pix)->r)
-#define SET_g(pix, val) ((pix)->g = val)
-#define GET_g(pix) ((pix)->g)
-#define SET_b(pix, val) ((pix)->b = val)
-#define GET_b(pix) ((pix)->b)
-#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
-#endif
-
-#ifdef QUIC_RGB24
-#undef QUIC_RGB24
-#define PIXEL rgb24_pixel_t
-#define FNAME(name) quic_rgb24_##name
-#define golomb_coding golomb_coding_8bpc
-#define golomb_decoding golomb_decoding_8bpc
-#define update_model update_model_8bpc
-#define find_bucket find_bucket_8bpc
-#define family family_8bpc
-#define BPC 8
-#define BPC_MASK 0xffU
-#define COMPRESS_IMP
-#define SET_r(pix, val) ((pix)->r = val)
-#define GET_r(pix) ((pix)->r)
-#define SET_g(pix, val) ((pix)->g = val)
-#define GET_g(pix) ((pix)->g)
-#define SET_b(pix, val) ((pix)->b = val)
-#define GET_b(pix) ((pix)->b)
-#define UNCOMPRESS_PIX_START(pix)
-#endif
-
-#ifdef QUIC_RGB16
-#undef QUIC_RGB16
-#define PIXEL rgb16_pixel_t
-#define FNAME(name) quic_rgb16_##name
-#define golomb_coding golomb_coding_5bpc
-#define golomb_decoding golomb_decoding_5bpc
-#define update_model update_model_5bpc
-#define find_bucket find_bucket_5bpc
-#define family family_5bpc
-#define BPC 5
-#define BPC_MASK 0x1fU
-#define COMPRESS_IMP
-#define SET_r(pix, val) (*(pix) = (*(pix) & ~(0x1f << 10)) | ((val) << 10))
-#define GET_r(pix) ((*(pix) >> 10) & 0x1f)
-#define SET_g(pix, val) (*(pix) = (*(pix) & ~(0x1f << 5)) | ((val) << 5))
-#define GET_g(pix) ((*(pix) >> 5) & 0x1f)
-#define SET_b(pix, val) (*(pix) = (*(pix) & ~0x1f) | (val))
-#define GET_b(pix) (*(pix) & 0x1f)
-#define UNCOMPRESS_PIX_START(pix) (*(pix) = 0)
-#endif
-
-#ifdef QUIC_RGB16_TO_32
-#undef QUIC_RGB16_TO_32
-#define PIXEL rgb32_pixel_t
-#define FNAME(name) quic_rgb16_to_32_##name
-#define golomb_coding golomb_coding_5bpc
-#define golomb_decoding golomb_decoding_5bpc
-#define update_model update_model_5bpc
-#define find_bucket find_bucket_5bpc
-#define family family_5bpc
-#define BPC 5
-#define BPC_MASK 0x1fU
-
-#define SET_r(pix, val) ((pix)->r = ((val) << 3) | (((val) & 0x1f) >> 2))
-#define GET_r(pix) ((pix)->r >> 3)
-#define SET_g(pix, val) ((pix)->g = ((val) << 3) | (((val) & 0x1f) >> 2))
-#define GET_g(pix) ((pix)->g >> 3)
-#define SET_b(pix, val) ((pix)->b = ((val) << 3) | (((val) & 0x1f) >> 2))
-#define GET_b(pix) ((pix)->b >> 3)
-#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
-#endif
-
-#define SAME_PIXEL(p1, p2)                                 \
-    (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) &&   \
-     GET_b(p1) == GET_b(p2))
-
-
-#define _PIXEL_A(channel, curr) ((unsigned int)GET_##channel((curr) - 1))
-#define _PIXEL_B(channel, prev) ((unsigned int)GET_##channel(prev))
-#define _PIXEL_C(channel, prev) ((unsigned int)GET_##channel((prev) - 1))
-
-/*  a  */
-
-#define DECORELATE_0(channel, curr, bpc_mask)\
-    family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)_PIXEL_A(channel, curr)) & bpc_mask]
-
-#define CORELATE_0(channel, curr, correlate, bpc_mask)\
-    ((family.xlatL2U[correlate] + _PIXEL_A(channel, curr)) & bpc_mask)
-
-#ifdef PRED_1
-
-/*  (a+b)/2  */
-#define DECORELATE(channel, prev, curr, bpc_mask, r)                                            \
-    r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)((_PIXEL_A(channel, curr) +   \
-                        _PIXEL_B(channel, prev)) >> 1)) & bpc_mask]
-
-#define CORELATE(channel, prev, curr, correlate, bpc_mask, r)                                   \
-    SET_##channel(r, ((family.xlatL2U[correlate] +                                              \
-          (int)((_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev)) >> 1)) & bpc_mask))
-#endif
-
-#ifdef PRED_2
-
-/*  .75a+.75b-.5c  */
-#define DECORELATE(channel, prev, curr, bpc_mask, r) {                          \
-    int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) -   \
-                        (int)(_PIXEL_C(channel, prev) << 1)) >> 2;              \
-    if (p < 0) {                                                                \
-        p = 0;                                                                  \
-    } else if ((unsigned)p > bpc_mask) {                                        \
-        p = bpc_mask;                                                           \
-    }                                                                           \
-    r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - p) & bpc_mask];    \
-}
-
-#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) {                         \
-    const int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) -     \
-                        (int)(_PIXEL_C(channel, prev) << 1) ) >> 2;                     \
-    const unsigned int s = family.xlatL2U[correlate];                                   \
-    if (!(p & ~bpc_mask)) {                                                             \
-        SET_##channel(r, (s + (unsigned)p) & bpc_mask);                                 \
-    } else if (p < 0) {                                                                 \
-        SET_##channel(r, s);                                                            \
-    } else {                                                                            \
-        SET_##channel(r, (s + bpc_mask) & bpc_mask);                                    \
-    }                                                                                   \
-}
-
-#endif
-
-
-#define COMPRESS_ONE_ROW0_0(channel)                                                \
-    correlate_row_##channel[0] = family.xlatU2L[GET_##channel(cur_row)];            \
-    golomb_coding(correlate_row_##channel[0], find_bucket(channel_##channel,        \
-                  correlate_row_##channel[-1])->bestcode,                           \
-                  &codeword, &codewordlen);                                         \
-    encode(encoder, codeword, codewordlen);
-
-#define COMPRESS_ONE_ROW0(channel, index)                                               \
-    correlate_row_##channel[index] = DECORELATE_0(channel, &cur_row[index], bpc_mask);  \
-    golomb_coding(correlate_row_##channel[index], find_bucket(channel_##channel,        \
-                  correlate_row_##channel[index -1])->bestcode,                         \
-                  &codeword, &codewordlen);                                             \
-    encode(encoder, codeword, codewordlen);
-
-#define UPDATE_MODEL(index)                                                                 \
-    update_model(&encoder->rgb_state, find_bucket(channel_r, correlate_row_r[index - 1]),   \
-                correlate_row_r[index], bpc);                                               \
-    update_model(&encoder->rgb_state, find_bucket(channel_g, correlate_row_g[index - 1]),   \
-                correlate_row_g[index], bpc);                                               \
-    update_model(&encoder->rgb_state, find_bucket(channel_b, correlate_row_b[index - 1]),   \
-                correlate_row_b[index], bpc);
-
-
-#ifdef RLE_PRED_1
-#define RLE_PRED_1_IMP                                                                          \
-if (SAME_PIXEL(&cur_row[i - 1], &prev_row[i])) {                                                \
-    if (run_index != i && SAME_PIXEL(&prev_row[i - 1], &prev_row[i]) &&                         \
-                                i + 1 < end && SAME_PIXEL(&prev_row[i], &prev_row[i + 1])) {    \
-        goto do_run;                                                                            \
-    }                                                                                           \
-}
-#else
-#define RLE_PRED_1_IMP
-#endif
-
-#ifdef RLE_PRED_2
-#define RLE_PRED_2_IMP                                                              \
-if (SAME_PIXEL(&prev_row[i - 1], &prev_row[i])) {                                   \
-    if (run_index != i && i > 2 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2])) {  \
-        goto do_run;                                                                \
-    }                                                                               \
-}
-#else
-#define RLE_PRED_2_IMP
-#endif
-
-#ifdef RLE_PRED_3
-#define RLE_PRED_3_IMP                                                              \
-if (i > 1 &&  SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2]) && i != run_index) {     \
-    goto do_run;                                                                    \
-}
-#else
-#define RLE_PRED_3_IMP
-#endif
-
-#ifdef COMPRESS_IMP
-
-static void FNAME(compress_row0_seg)(Encoder *encoder, int i,
-                                     const PIXEL * const cur_row,
-                                     const int end,
-                                     const unsigned int waitmask,
-                                     const unsigned int bpc,
-                                     const unsigned int bpc_mask)
-{
-    Channel * const channel_r = encoder->channels;
-    Channel * const channel_g = channel_r + 1;
-    Channel * const channel_b = channel_g + 1;
-
-    BYTE * const correlate_row_r = channel_r->correlate_row;
-    BYTE * const correlate_row_g = channel_g->correlate_row;
-    BYTE * const correlate_row_b = channel_b->correlate_row;
-    int stopidx;
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (!i) {
-        unsigned int codeword, codewordlen;
-
-        COMPRESS_ONE_ROW0_0(r);
-        COMPRESS_ONE_ROW0_0(g);
-        COMPRESS_ONE_ROW0_0(b);
-
-        if (encoder->rgb_state.waitcnt) {
-            encoder->rgb_state.waitcnt--;
-        } else {
-            encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-            UPDATE_MODEL(0);
-        }
-        stopidx = ++i + encoder->rgb_state.waitcnt;
-    } else {
-        stopidx = i + encoder->rgb_state.waitcnt;
-    }
-
-    while (stopidx < end) {
-        for (; i <= stopidx; i++) {
-            unsigned int codeword, codewordlen;
-            COMPRESS_ONE_ROW0(r, i);
-            COMPRESS_ONE_ROW0(g, i);
-            COMPRESS_ONE_ROW0(b, i);
-        }
-
-        UPDATE_MODEL(stopidx);
-        stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-    }
-
-    for (; i < end; i++) {
-        unsigned int codeword, codewordlen;
-
-        COMPRESS_ONE_ROW0(r, i);
-        COMPRESS_ONE_ROW0(g, i);
-        COMPRESS_ONE_ROW0(b, i);
-    }
-    encoder->rgb_state.waitcnt = stopidx - end;
-}
-
-static void FNAME(compress_row0)(Encoder *encoder, const PIXEL *cur_row,
-                                 unsigned int width)
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    int pos = 0;
-
-    while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
-        if (encoder->rgb_state.wmileft) {
-            FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + encoder->rgb_state.wmileft,
-                                     bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
-            width -= encoder->rgb_state.wmileft;
-            pos += encoder->rgb_state.wmileft;
-        }
-
-        encoder->rgb_state.wmidx++;
-        set_wm_trigger(&encoder->rgb_state);
-        encoder->rgb_state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + width,
-                                 bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)encoder->rgb_state.wmidx) {
-            encoder->rgb_state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax);
-    ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-#define COMPRESS_ONE_0(channel) \
-    correlate_row_##channel[0] = family.xlatU2L[(unsigned)((int)GET_##channel(cur_row) -    \
-                                                (int)GET_##channel(prev_row) ) & bpc_mask]; \
-    golomb_coding(correlate_row_##channel[0],                                               \
-                  find_bucket(channel_##channel, correlate_row_##channel[-1])->bestcode,    \
-                  &codeword, &codewordlen);                                                 \
-    encode(encoder, codeword, codewordlen);
-
-#define COMPRESS_ONE(channel, index)                                                            \
-    DECORELATE(channel, &prev_row[index], &cur_row[index],bpc_mask,                             \
-               correlate_row_##channel[index]);                                                 \
-    golomb_coding(correlate_row_##channel[index],                                               \
-                 find_bucket(channel_##channel, correlate_row_##channel[index - 1])->bestcode,  \
-                 &codeword, &codewordlen);                                                      \
-    encode(encoder, codeword, codewordlen);
-
-static void FNAME(compress_row_seg)(Encoder *encoder, int i,
-                                    const PIXEL * const prev_row,
-                                    const PIXEL * const cur_row,
-                                    const int end,
-                                    const unsigned int waitmask,
-                                    const unsigned int bpc,
-                                    const unsigned int bpc_mask)
-{
-    Channel * const channel_r = encoder->channels;
-    Channel * const channel_g = channel_r + 1;
-    Channel * const channel_b = channel_g + 1;
-
-    BYTE * const correlate_row_r = channel_r->correlate_row;
-    BYTE * const correlate_row_g = channel_g->correlate_row;
-    BYTE * const correlate_row_b = channel_b->correlate_row;
-    int stopidx;
-#ifdef RLE
-    int run_index = 0;
-    int run_size;
-#endif
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (!i) {
-        unsigned int codeword, codewordlen;
-
-        COMPRESS_ONE_0(r);
-        COMPRESS_ONE_0(g);
-        COMPRESS_ONE_0(b);
-
-        if (encoder->rgb_state.waitcnt) {
-            encoder->rgb_state.waitcnt--;
-        } else {
-            encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-            UPDATE_MODEL(0);
-        }
-        stopidx = ++i + encoder->rgb_state.waitcnt;
-    } else {
-        stopidx = i + encoder->rgb_state.waitcnt;
-    }
-    for (;;) {
-        while (stopidx < end) {
-            for (; i <= stopidx; i++) {
-                unsigned int codeword, codewordlen;
-#ifdef RLE
-                RLE_PRED_1_IMP;
-                RLE_PRED_2_IMP;
-                RLE_PRED_3_IMP;
-#endif
-                COMPRESS_ONE(r, i);
-                COMPRESS_ONE(g, i);
-                COMPRESS_ONE(b, i);
-            }
-
-            UPDATE_MODEL(stopidx);
-            stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-        }
-
-        for (; i < end; i++) {
-            unsigned int codeword, codewordlen;
-#ifdef RLE
-            RLE_PRED_1_IMP;
-            RLE_PRED_2_IMP;
-            RLE_PRED_3_IMP;
-#endif
-            COMPRESS_ONE(r, i);
-            COMPRESS_ONE(g, i);
-            COMPRESS_ONE(b, i);
-        }
-        encoder->rgb_state.waitcnt = stopidx - end;
-
-        return;
-
-#ifdef RLE
-do_run:
-        run_index = i;
-        encoder->rgb_state.waitcnt = stopidx - i;
-        run_size = 0;
-
-        while (SAME_PIXEL(&cur_row[i], &cur_row[i - 1])) {
-            run_size++;
-            if (++i == end) {
-                encode_run(encoder, run_size);
-                return;
-            }
-        }
-        encode_run(encoder, run_size);
-        stopidx = i + encoder->rgb_state.waitcnt;
-#endif
-    }
-}
-
-static void FNAME(compress_row)(Encoder *encoder,
-                                const PIXEL * const prev_row,
-                                const PIXEL * const cur_row,
-                                unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
-        if (encoder->rgb_state.wmileft) {
-            FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row,
-                                    pos + encoder->rgb_state.wmileft,
-                                    bppmask[encoder->rgb_state.wmidx],
-                                    bpc, bpc_mask);
-            width -= encoder->rgb_state.wmileft;
-            pos += encoder->rgb_state.wmileft;
-        }
-
-        encoder->rgb_state.wmidx++;
-        set_wm_trigger(&encoder->rgb_state);
-        encoder->rgb_state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row, pos + width,
-                                bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)encoder->rgb_state.wmidx) {
-            encoder->rgb_state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax);
-    ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-#endif
-
-#define UNCOMPRESS_ONE_ROW0_0(channel)                                                          \
-    correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel,           \
-                                                       correlate_row_##channel[-1])->bestcode,  \
-                                                       encoder->io_word, &codewordlen);         \
-    SET_##channel(&cur_row[0], (BYTE)family.xlatL2U[correlate_row_##channel[0]]);               \
-    decode_eatbits(encoder, codewordlen);
-
-#define UNCOMPRESS_ONE_ROW0(channel)                                                              \
-    correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel,             \
-                                                       correlate_row_##channel[i - 1])->bestcode, \
-                                                       encoder->io_word,                          \
-                                                       &codewordlen);                             \
-    SET_##channel(&cur_row[i], CORELATE_0(channel, &cur_row[i], correlate_row_##channel[i],       \
-                  bpc_mask));                                                                     \
-    decode_eatbits(encoder, codewordlen);
-
-static void FNAME(uncompress_row0_seg)(Encoder *encoder, int i,
-                                       PIXEL * const cur_row,
-                                       const int end,
-                                       const unsigned int waitmask,
-                                       const unsigned int bpc,
-                                       const unsigned int bpc_mask)
-{
-    Channel * const channel_r = encoder->channels;
-    Channel * const channel_g = channel_r + 1;
-    Channel * const channel_b = channel_g + 1;
-
-    BYTE * const correlate_row_r = channel_r->correlate_row;
-    BYTE * const correlate_row_g = channel_g->correlate_row;
-    BYTE * const correlate_row_b = channel_b->correlate_row;
-    int stopidx;
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (!i) {
-        unsigned int codewordlen;
-
-        UNCOMPRESS_PIX_START(&cur_row[i]);
-        UNCOMPRESS_ONE_ROW0_0(r);
-        UNCOMPRESS_ONE_ROW0_0(g);
-        UNCOMPRESS_ONE_ROW0_0(b);
-
-        if (encoder->rgb_state.waitcnt) {
-            --encoder->rgb_state.waitcnt;
-        } else {
-            encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-            UPDATE_MODEL(0);
-        }
-        stopidx = ++i + encoder->rgb_state.waitcnt;
-    } else {
-        stopidx = i + encoder->rgb_state.waitcnt;
-    }
-
-    while (stopidx < end) {
-        for (; i <= stopidx; i++) {
-            unsigned int codewordlen;
-
-            UNCOMPRESS_PIX_START(&cur_row[i]);
-            UNCOMPRESS_ONE_ROW0(r);
-            UNCOMPRESS_ONE_ROW0(g);
-            UNCOMPRESS_ONE_ROW0(b);
-        }
-        UPDATE_MODEL(stopidx);
-        stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-    }
-
-    for (; i < end; i++) {
-        unsigned int codewordlen;
-
-        UNCOMPRESS_PIX_START(&cur_row[i]);
-        UNCOMPRESS_ONE_ROW0(r);
-        UNCOMPRESS_ONE_ROW0(g);
-        UNCOMPRESS_ONE_ROW0(b);
-    }
-    encoder->rgb_state.waitcnt = stopidx - end;
-}
-
-static void FNAME(uncompress_row0)(Encoder *encoder,
-                                   PIXEL * const cur_row,
-                                   unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
-        if (encoder->rgb_state.wmileft) {
-            FNAME(uncompress_row0_seg)(encoder, pos, cur_row,
-                                       pos + encoder->rgb_state.wmileft,
-                                       bppmask[encoder->rgb_state.wmidx],
-                                       bpc, bpc_mask);
-            pos += encoder->rgb_state.wmileft;
-            width -= encoder->rgb_state.wmileft;
-        }
-
-        encoder->rgb_state.wmidx++;
-        set_wm_trigger(&encoder->rgb_state);
-        encoder->rgb_state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(uncompress_row0_seg)(encoder, pos, cur_row, pos + width,
-                                   bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)encoder->rgb_state.wmidx) {
-            encoder->rgb_state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax);
-    ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-#define UNCOMPRESS_ONE_0(channel) \
-    correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel,           \
-                                                       correlate_row_##channel[-1])->bestcode,  \
-                                                       encoder->io_word, &codewordlen);         \
-    SET_##channel(&cur_row[0], (family.xlatL2U[correlate_row_##channel[0]] +                    \
-                          GET_##channel(prev_row)) & bpc_mask);                                 \
-    decode_eatbits(encoder, codewordlen);
-
-#define UNCOMPRESS_ONE(channel)                                                                   \
-    correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel,             \
-                                                       correlate_row_##channel[i - 1])->bestcode, \
-                                                       encoder->io_word,                          \
-                                                       &codewordlen);                             \
-    CORELATE(channel, &prev_row[i], &cur_row[i], correlate_row_##channel[i], bpc_mask,            \
-             &cur_row[i]);                                                                        \
-    decode_eatbits(encoder, codewordlen);
-
-static void FNAME(uncompress_row_seg)(Encoder *encoder,
-                                      const PIXEL * const prev_row,
-                                      PIXEL * const cur_row,
-                                      int i,
-                                      const int end,
-                                      const unsigned int bpc,
-                                      const unsigned int bpc_mask)
-{
-    Channel * const channel_r = encoder->channels;
-    Channel * const channel_g = channel_r + 1;
-    Channel * const channel_b = channel_g + 1;
-
-    BYTE * const correlate_row_r = channel_r->correlate_row;
-    BYTE * const correlate_row_g = channel_g->correlate_row;
-    BYTE * const correlate_row_b = channel_b->correlate_row;
-    const unsigned int waitmask = bppmask[encoder->rgb_state.wmidx];
-    int stopidx;
-#ifdef RLE
-    int run_index = 0;
-    int run_end;
-#endif
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (!i) {
-        unsigned int codewordlen;
-
-        UNCOMPRESS_PIX_START(&cur_row[i]);
-        UNCOMPRESS_ONE_0(r);
-        UNCOMPRESS_ONE_0(g);
-        UNCOMPRESS_ONE_0(b);
-
-        if (encoder->rgb_state.waitcnt) {
-            --encoder->rgb_state.waitcnt;
-        } else {
-            encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-            UPDATE_MODEL(0);
-        }
-        stopidx = ++i + encoder->rgb_state.waitcnt;
-    } else {
-        stopidx = i + encoder->rgb_state.waitcnt;
-    }
-    for (;;) {
-        while (stopidx < end) {
-            for (; i <= stopidx; i++) {
-                unsigned int codewordlen;
-#ifdef RLE
-                RLE_PRED_1_IMP;
-                RLE_PRED_2_IMP;
-                RLE_PRED_3_IMP;
-#endif
-                UNCOMPRESS_PIX_START(&cur_row[i]);
-                UNCOMPRESS_ONE(r);
-                UNCOMPRESS_ONE(g);
-                UNCOMPRESS_ONE(b);
-            }
-
-            UPDATE_MODEL(stopidx);
-
-            stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
-        }
-
-        for (; i < end; i++) {
-            unsigned int codewordlen;
-#ifdef RLE
-            RLE_PRED_1_IMP;
-            RLE_PRED_2_IMP;
-            RLE_PRED_3_IMP;
-#endif
-            UNCOMPRESS_PIX_START(&cur_row[i]);
-            UNCOMPRESS_ONE(r);
-            UNCOMPRESS_ONE(g);
-            UNCOMPRESS_ONE(b);
-        }
-
-        encoder->rgb_state.waitcnt = stopidx - end;
-
-        return;
-
-#ifdef RLE
-do_run:
-        encoder->rgb_state.waitcnt = stopidx - i;
-        run_index = i;
-        run_end = i + decode_run(encoder);
-
-        for (; i < run_end; i++) {
-            UNCOMPRESS_PIX_START(&cur_row[i]);
-            SET_r(&cur_row[i], GET_r(&cur_row[i - 1]));
-            SET_g(&cur_row[i], GET_g(&cur_row[i - 1]));
-            SET_b(&cur_row[i], GET_b(&cur_row[i - 1]));
-        }
-
-        if (i == end) {
-            return;
-        }
-
-        stopidx = i + encoder->rgb_state.waitcnt;
-#endif
-    }
-}
-
-static void FNAME(uncompress_row)(Encoder *encoder,
-                                  const PIXEL * const prev_row,
-                                  PIXEL * const cur_row,
-                                  unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
-        if (encoder->rgb_state.wmileft) {
-            FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
-                                      pos + encoder->rgb_state.wmileft, bpc, bpc_mask);
-            pos += encoder->rgb_state.wmileft;
-            width -= encoder->rgb_state.wmileft;
-        }
-
-        encoder->rgb_state.wmidx++;
-        set_wm_trigger(&encoder->rgb_state);
-        encoder->rgb_state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
-                                  pos + width, bpc, bpc_mask);
-        if (wmimax > (int)encoder->rgb_state.wmidx) {
-            encoder->rgb_state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax);
-    ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-#undef PIXEL
-#undef FNAME
-#undef _PIXEL_A
-#undef _PIXEL_B
-#undef _PIXEL_C
-#undef SAME_PIXEL
-#undef RLE_PRED_1_IMP
-#undef RLE_PRED_2_IMP
-#undef RLE_PRED_3_IMP
-#undef UPDATE_MODEL
-#undef DECORELATE_0
-#undef DECORELATE
-#undef COMPRESS_ONE_ROW0_0
-#undef COMPRESS_ONE_ROW0
-#undef COMPRESS_ONE_0
-#undef COMPRESS_ONE
-#undef CORELATE_0
-#undef CORELATE
-#undef UNCOMPRESS_ONE_ROW0_0
-#undef UNCOMPRESS_ONE_ROW0
-#undef UNCOMPRESS_ONE_0
-#undef UNCOMPRESS_ONE
-#undef golomb_coding
-#undef golomb_decoding
-#undef update_model
-#undef find_bucket
-#undef family
-#undef BPC
-#undef BPC_MASK
-#undef COMPRESS_IMP
-#undef SET_r
-#undef GET_r
-#undef SET_g
-#undef GET_g
-#undef SET_b
-#undef GET_b
-#undef UNCOMPRESS_PIX_START
-
diff --git a/common/quic_tmpl.c b/common/quic_tmpl.c
deleted file mode 100644
index 47a6a23..0000000
--- a/common/quic_tmpl.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef ONE_BYTE
-#undef ONE_BYTE
-#define FNAME(name) quic_one_##name
-#define PIXEL one_byte_t
-#endif
-
-#ifdef THREE_BYTE
-#undef THREE_BYTE
-#define FNAME(name) quic_three_##name
-#define PIXEL three_bytes_t
-#endif
-
-#ifdef FOUR_BYTE
-#undef FOUR_BYTE
-#define FNAME(name) quic_four_##name
-#define PIXEL four_bytes_t
-#endif
-
-#define golomb_coding golomb_coding_8bpc
-#define golomb_decoding golomb_decoding_8bpc
-#define update_model update_model_8bpc
-#define find_bucket find_bucket_8bpc
-#define family family_8bpc
-
-#define BPC 8
-#define BPC_MASK 0xffU
-
-#define _PIXEL_A ((unsigned int)curr[-1].a)
-#define _PIXEL_B ((unsigned int)prev[0].a)
-#define _PIXEL_C ((unsigned int)prev[-1].a)
-
-#ifdef RLE_PRED_1
-#define RLE_PRED_1_IMP                                                              \
-if (cur_row[i - 1].a == prev_row[i].a) {                                            \
-    if (run_index != i && prev_row[i - 1].a == prev_row[i].a &&                     \
-                        i + 1 < end && prev_row[i].a == prev_row[i + 1].a) {        \
-        goto do_run;                                                                \
-    }                                                                               \
-}
-#else
-#define RLE_PRED_1_IMP
-#endif
-
-#ifdef RLE_PRED_2
-#define RLE_PRED_2_IMP                                                     \
-if (prev_row[i - 1].a == prev_row[i].a) {                                  \
-    if (run_index != i && i > 2 && cur_row[i - 1].a == cur_row[i - 2].a) { \
-        goto do_run;                                                       \
-    }                                                                      \
-}
-#else
-#define RLE_PRED_2_IMP
-#endif
-
-#ifdef RLE_PRED_3
-#define RLE_PRED_3_IMP                                                  \
-if (i > 1 && cur_row[i - 1].a == cur_row[i - 2].a && i != run_index) {  \
-    goto do_run;                                                        \
-}
-#else
-#define RLE_PRED_3_IMP
-#endif
-
-/*  a  */
-static INLINE BYTE FNAME(decorelate_0)(const PIXEL * const curr, const unsigned int bpc_mask)
-{
-    return family.xlatU2L[(unsigned)((int)curr[0].a - (int)_PIXEL_A) & bpc_mask];
-}
-
-static INLINE void FNAME(corelate_0)(PIXEL *curr, const BYTE corelate,
-                                     const unsigned int bpc_mask)
-{
-    curr->a = (family.xlatL2U[corelate] + _PIXEL_A) & bpc_mask;
-}
-
-#ifdef PRED_1
-
-/*  (a+b)/2  */
-static INLINE BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
-                                     const unsigned int bpc_mask)
-{
-    return family.xlatU2L[(unsigned)((int)curr->a - (int)((_PIXEL_A + _PIXEL_B) >> 1)) & bpc_mask];
-}
-
-
-static INLINE void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
-                                   const unsigned int bpc_mask)
-{
-    curr->a = (family.xlatL2U[corelate] + (int)((_PIXEL_A + _PIXEL_B) >> 1)) & bpc_mask;
-}
-
-#endif
-
-#ifdef PRED_2
-
-/*  .75a+.75b-.5c  */
-static INLINE BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
-                                     const unsigned int bpc_mask)
-{
-    int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C << 1)) >> 2;
-
-    if (p < 0) {
-        p = 0;
-    } else if ((unsigned)p > bpc_mask) {
-        p = bpc_mask;
-    }
-
-    {
-        return family.xlatU2L[(unsigned)((int)curr->a - p) & bpc_mask];
-    }
-}
-
-static INLINE void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
-                                   const unsigned int bpc_mask)
-{
-    const int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C << 1)) >> 2;
-    const unsigned int s = family.xlatL2U[corelate];
-
-    if (!(p & ~bpc_mask)) {
-        curr->a = (s + (unsigned)p) & bpc_mask;
-    } else if (p < 0) {
-        curr->a = s;
-    } else {
-        curr->a = (s + bpc_mask) & bpc_mask;
-    }
-}
-
-#endif
-
-static void FNAME(compress_row0_seg)(Encoder *encoder, Channel *channel, int i,
-                                     const PIXEL * const cur_row,
-                                     const int end,
-                                     const unsigned int waitmask,
-                                     const unsigned int bpc,
-                                     const unsigned int bpc_mask)
-{
-    BYTE * const decorelate_drow = channel->correlate_row;
-    int stopidx;
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (i == 0) {
-        unsigned int codeword, codewordlen;
-
-        decorelate_drow[0] = family.xlatU2L[cur_row->a];
-        golomb_coding(decorelate_drow[0], find_bucket(channel, decorelate_drow[-1])->bestcode,
-                      &codeword, &codewordlen);
-        encode(encoder, codeword, codewordlen);
-
-        if (channel->state.waitcnt) {
-            channel->state.waitcnt--;
-        } else {
-            channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
-            update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
-                         decorelate_drow[i], bpc);
-        }
-        stopidx = ++i + channel->state.waitcnt;
-    } else {
-        stopidx = i + channel->state.waitcnt;
-    }
-
-    while (stopidx < end) {
-        for (; i <= stopidx; i++) {
-            unsigned int codeword, codewordlen;
-            decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
-            golomb_coding(decorelate_drow[i],
-                          find_bucket(channel, decorelate_drow[i - 1])->bestcode, &codeword,
-                          &codewordlen);
-            encode(encoder, codeword, codewordlen);
-        }
-
-        update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
-                     decorelate_drow[stopidx], bpc);
-        stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
-    }
-
-    for (; i < end; i++) {
-        unsigned int codeword, codewordlen;
-        decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
-        golomb_coding(decorelate_drow[i], find_bucket(channel, decorelate_drow[i - 1])->bestcode,
-                      &codeword, &codewordlen);
-        encode(encoder, codeword, codewordlen);
-    }
-    channel->state.waitcnt = stopidx - end;
-}
-
-static void FNAME(compress_row0)(Encoder *encoder, Channel *channel, const PIXEL *cur_row,
-                                 unsigned int width)
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    int pos = 0;
-
-    while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
-        if (channel->state.wmileft) {
-            FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + channel->state.wmileft,
-                                     bppmask[channel->state.wmidx], bpc, bpc_mask);
-            width -= channel->state.wmileft;
-            pos += channel->state.wmileft;
-        }
-
-        channel->state.wmidx++;
-        set_wm_trigger(&channel->state);
-        channel->state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + width,
-                                 bppmask[channel->state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)channel->state.wmidx) {
-            channel->state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)channel->state.wmidx <= wmimax);
-    ASSERT(encoder->usr, channel->state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-static void FNAME(compress_row_seg)(Encoder *encoder, Channel *channel, int i,
-                                    const PIXEL * const prev_row,
-                                    const PIXEL * const cur_row,
-                                    const int end,
-                                    const unsigned int waitmask,
-                                    const unsigned int bpc,
-                                    const unsigned int bpc_mask)
-{
-    BYTE * const decorelate_drow = channel->correlate_row;
-    int stopidx;
-#ifdef RLE
-    int run_index = 0;
-    int run_size;
-#endif
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (!i) {
-        unsigned int codeword, codewordlen;
-
-        decorelate_drow[0] = family.xlatU2L[(unsigned)((int)cur_row->a -
-                                                       (int)prev_row->a) & bpc_mask];
-
-        golomb_coding(decorelate_drow[0],
-                      find_bucket(channel, decorelate_drow[-1])->bestcode,
-                      &codeword,
-                      &codewordlen);
-        encode(encoder, codeword, codewordlen);
-
-        if (channel->state.waitcnt) {
-            channel->state.waitcnt--;
-        } else {
-            channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
-            update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
-                         decorelate_drow[0], bpc);
-        }
-        stopidx = ++i + channel->state.waitcnt;
-    } else {
-        stopidx = i + channel->state.waitcnt;
-    }
-    for (;;) {
-        while (stopidx < end) {
-            for (; i <= stopidx; i++) {
-                unsigned int codeword, codewordlen;
-#ifdef RLE
-                RLE_PRED_1_IMP;
-                RLE_PRED_2_IMP;
-                RLE_PRED_3_IMP;
-#endif
-                decorelate_drow[i] = FNAME(decorelate)(&prev_row[i], &cur_row[i], bpc_mask);
-                golomb_coding(decorelate_drow[i],
-                              find_bucket(channel, decorelate_drow[i - 1])->bestcode, &codeword,
-                              &codewordlen);
-                encode(encoder, codeword, codewordlen);
-            }
-
-            update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
-                         decorelate_drow[stopidx], bpc);
-            stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
-        }
-
-        for (; i < end; i++) {
-            unsigned int codeword, codewordlen;
-#ifdef RLE
-            RLE_PRED_1_IMP;
-            RLE_PRED_2_IMP;
-            RLE_PRED_3_IMP;
-#endif
-            decorelate_drow[i] = FNAME(decorelate)(&prev_row[i], &cur_row[i], bpc_mask);
-            golomb_coding(decorelate_drow[i], find_bucket(channel,
-                                                          decorelate_drow[i - 1])->bestcode,
-                          &codeword, &codewordlen);
-            encode(encoder, codeword, codewordlen);
-        }
-        channel->state.waitcnt = stopidx - end;
-
-        return;
-
-#ifdef RLE
-do_run:
-        run_index = i;
-        channel->state.waitcnt = stopidx - i;
-        run_size = 0;
-
-        while (cur_row[i].a == cur_row[i - 1].a) {
-            run_size++;
-            if (++i == end) {
-#ifdef RLE_STAT
-                encode_channel_run(encoder, channel, run_size);
-#else
-                encode_run(encoder, run_size);
-#endif
-                return;
-            }
-        }
-#ifdef RLE_STAT
-        encode_channel_run(encoder, channel, run_size);
-#else
-        encode_run(encoder, run_size);
-#endif
-        stopidx = i + channel->state.waitcnt;
-#endif
-    }
-}
-
-static void FNAME(compress_row)(Encoder *encoder, Channel *channel,
-                                const PIXEL * const prev_row,
-                                const PIXEL * const cur_row,
-                                unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
-        if (channel->state.wmileft) {
-            FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row,
-                                    pos + channel->state.wmileft, bppmask[channel->state.wmidx],
-                                    bpc, bpc_mask);
-            width -= channel->state.wmileft;
-            pos += channel->state.wmileft;
-        }
-
-        channel->state.wmidx++;
-        set_wm_trigger(&channel->state);
-        channel->state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row, pos + width,
-                                bppmask[channel->state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)channel->state.wmidx) {
-            channel->state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)channel->state.wmidx <= wmimax);
-    ASSERT(encoder->usr, channel->state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-static void FNAME(uncompress_row0_seg)(Encoder *encoder, Channel *channel, int i,
-                                       BYTE * const correlate_row,
-                                       PIXEL * const cur_row,
-                                       const int end,
-                                       const unsigned int waitmask,
-                                       const unsigned int bpc,
-                                       const unsigned int bpc_mask)
-{
-    int stopidx;
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (i == 0) {
-        unsigned int codewordlen;
-
-        correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel,
-                                                             correlate_row[-1])->bestcode,
-                                                 encoder->io_word, &codewordlen);
-        cur_row[0].a = (BYTE)family.xlatL2U[correlate_row[0]];
-        decode_eatbits(encoder, codewordlen);
-
-        if (channel->state.waitcnt) {
-            --channel->state.waitcnt;
-        } else {
-            channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
-            update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
-                         correlate_row[0], bpc);
-        }
-        stopidx = ++i + channel->state.waitcnt;
-    } else {
-        stopidx = i + channel->state.waitcnt;
-    }
-
-    while (stopidx < end) {
-        struct s_bucket * pbucket = NULL;
-
-        for (; i <= stopidx; i++) {
-            unsigned int codewordlen;
-
-            pbucket = find_bucket(channel, correlate_row[i - 1]);
-            correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
-                                                     &codewordlen);
-            FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
-            decode_eatbits(encoder, codewordlen);
-        }
-
-        update_model(&channel->state, pbucket, correlate_row[stopidx], bpc);
-
-        stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
-    }
-
-    for (; i < end; i++) {
-        unsigned int codewordlen;
-
-        correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
-                                                             correlate_row[i - 1])->bestcode,
-                                                 encoder->io_word, &codewordlen);
-        FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
-        decode_eatbits(encoder, codewordlen);
-    }
-    channel->state.waitcnt = stopidx - end;
-}
-
-static void FNAME(uncompress_row0)(Encoder *encoder, Channel *channel,
-                                   PIXEL * const cur_row,
-                                   unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    BYTE * const correlate_row = channel->correlate_row;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
-        if (channel->state.wmileft) {
-            FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row,
-                                       pos + channel->state.wmileft, bppmask[channel->state.wmidx],
-                                       bpc, bpc_mask);
-            pos += channel->state.wmileft;
-            width -= channel->state.wmileft;
-        }
-
-        channel->state.wmidx++;
-        set_wm_trigger(&channel->state);
-        channel->state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row, pos + width,
-                                   bppmask[channel->state.wmidx], bpc, bpc_mask);
-        if (wmimax > (int)channel->state.wmidx) {
-            channel->state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)channel->state.wmidx <= wmimax);
-    ASSERT(encoder->usr, channel->state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-static void FNAME(uncompress_row_seg)(Encoder *encoder, Channel *channel,
-                                      BYTE *correlate_row,
-                                      const PIXEL * const prev_row,
-                                      PIXEL * const cur_row,
-                                      int i,
-                                      const int end,
-                                      const unsigned int bpc,
-                                      const unsigned int bpc_mask)
-{
-    const unsigned int waitmask = bppmask[channel->state.wmidx];
-    int stopidx;
-#ifdef RLE
-    int run_index = 0;
-    int run_end;
-#endif
-
-    ASSERT(encoder->usr, end - i > 0);
-
-    if (i == 0) {
-        unsigned int codewordlen;
-
-        correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel, correlate_row[-1])->bestcode,
-                                                             encoder->io_word, &codewordlen);
-        cur_row[0].a = (family.xlatL2U[correlate_row[0]] + prev_row[0].a) & bpc_mask;
-        decode_eatbits(encoder, codewordlen);
-
-        if (channel->state.waitcnt) {
-            --channel->state.waitcnt;
-        } else {
-            channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
-            update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
-                         correlate_row[0], bpc);
-        }
-        stopidx = ++i + channel->state.waitcnt;
-    } else {
-        stopidx = i + channel->state.waitcnt;
-    }
-    for (;;) {
-        while (stopidx < end) {
-            struct s_bucket * pbucket = NULL;
-
-            for (; i <= stopidx; i++) {
-                unsigned int codewordlen;
-#ifdef RLE
-                RLE_PRED_1_IMP;
-                RLE_PRED_2_IMP;
-                RLE_PRED_3_IMP;
-#endif
-                pbucket = find_bucket(channel, correlate_row[i - 1]);
-                correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
-                                                         &codewordlen);
-                FNAME(corelate)(&prev_row[i], &cur_row[i], correlate_row[i], bpc_mask);
-                decode_eatbits(encoder, codewordlen);
-            }
-
-            update_model(&channel->state, pbucket, correlate_row[stopidx], bpc);
-
-            stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
-        }
-
-        for (; i < end; i++) {
-            unsigned int codewordlen;
-#ifdef RLE
-            RLE_PRED_1_IMP;
-            RLE_PRED_2_IMP;
-            RLE_PRED_3_IMP;
-#endif
-            correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
-                                                                 correlate_row[i - 1])->bestcode,
-                                                     encoder->io_word, &codewordlen);
-            FNAME(corelate)(&prev_row[i], &cur_row[i], correlate_row[i], bpc_mask);
-            decode_eatbits(encoder, codewordlen);
-        }
-
-        channel->state.waitcnt = stopidx - end;
-
-        return;
-
-#ifdef RLE
-do_run:
-        channel->state.waitcnt = stopidx - i;
-        run_index = i;
-#ifdef RLE_STAT
-        run_end = i + decode_channel_run(encoder, channel);
-#else
-        run_end = i + decode_run(encoder);
-#endif
-
-        for (; i < run_end; i++) {
-            cur_row[i].a = cur_row[i - 1].a;
-        }
-
-        if (i == end) {
-            return;
-        }
-
-        stopidx = i + channel->state.waitcnt;
-#endif
-    }
-}
-
-static void FNAME(uncompress_row)(Encoder *encoder, Channel *channel,
-                                  const PIXEL * const prev_row,
-                                  PIXEL * const cur_row,
-                                  unsigned int width)
-
-{
-    const unsigned int bpc = BPC;
-    const unsigned int bpc_mask = BPC_MASK;
-    BYTE * const correlate_row = channel->correlate_row;
-    unsigned int pos = 0;
-
-    while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
-        if (channel->state.wmileft) {
-            FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
-                                      pos + channel->state.wmileft, bpc, bpc_mask);
-            pos += channel->state.wmileft;
-            width -= channel->state.wmileft;
-        }
-
-        channel->state.wmidx++;
-        set_wm_trigger(&channel->state);
-        channel->state.wmileft = wminext;
-    }
-
-    if (width) {
-        FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
-                                  pos + width, bpc, bpc_mask);
-        if (wmimax > (int)channel->state.wmidx) {
-            channel->state.wmileft -= width;
-        }
-    }
-
-    ASSERT(encoder->usr, (int)channel->state.wmidx <= wmimax);
-    ASSERT(encoder->usr, channel->state.wmidx <= 32);
-    ASSERT(encoder->usr, wminext > 0);
-}
-
-#undef PIXEL
-#undef FNAME
-#undef _PIXEL_A
-#undef _PIXEL_B
-#undef _PIXEL_C
-#undef RLE_PRED_1_IMP
-#undef RLE_PRED_2_IMP
-#undef RLE_PRED_3_IMP
-#undef golomb_coding
-#undef golomb_deoding
-#undef update_model
-#undef find_bucket
-#undef family
-#undef BPC
-#undef BPC_MASK
-
diff --git a/common/rect.h b/common/rect.h
deleted file mode 100644
index cdd4335..0000000
--- a/common/rect.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_RECT
-#define _H_RECT
-
-#include "draw.h"
-#include <spice/macros.h>
-
-static inline void rect_sect(SpiceRect* r, const SpiceRect* bounds)
-{
-    r->left = MAX(r->left, bounds->left);
-    r->right = MIN(r->right, bounds->right);
-    r->right = MAX(r->left, r->right);
-
-    r->top = MAX(r->top, bounds->top);
-    r->bottom = MIN(r->bottom, bounds->bottom);
-    r->bottom = MAX(r->top, r->bottom);
-}
-
-static inline void rect_offset(SpiceRect* r, int dx, int dy)
-{
-    r->left += dx;
-    r->right += dx;
-    r->top += dy;
-    r->bottom += dy;
-}
-
-static inline int rect_is_empty(const SpiceRect* r)
-{
-    return r->top == r->bottom || r->left == r->right;
-}
-
-static inline int rect_intersects(const SpiceRect* r1, const SpiceRect* r2)
-{
-    return r1->left < r2->right && r1->right > r2->left &&
-           r1->top < r2->bottom && r1->bottom > r2->top;
-}
-
-static inline int rect_is_equal(const SpiceRect *r1, const SpiceRect *r2)
-{
-    return r1->top == r2->top && r1->left == r2->left &&
-           r1->bottom == r2->bottom && r1->right == r2->right;
-}
-
-static inline void rect_union(SpiceRect *dest, const SpiceRect *r)
-{
-    dest->top = MIN(dest->top, r->top);
-    dest->left = MIN(dest->left, r->left);
-    dest->bottom = MAX(dest->bottom, r->bottom);
-    dest->right = MAX(dest->right, r->right);
-}
-
-static inline int rect_is_same_size(const SpiceRect *r1, const SpiceRect *r2)
-{
-    return r1->right - r1->left == r2->right - r2->left &&
-           r1->bottom - r1->top == r2->bottom - r2->top;
-}
-
-#ifdef __cplusplus
-
-static inline void rect_sect(SpiceRect& r, const SpiceRect& bounds)
-{
-    rect_sect(&r, &bounds);
-}
-
-static inline void rect_offset(SpiceRect& r, int dx, int dy)
-{
-    rect_offset(&r, dx, dy);
-}
-
-static inline int rect_is_empty(const SpiceRect& r)
-{
-    return rect_is_empty(&r);
-}
-
-static inline int rect_intersects(const SpiceRect& r1, const SpiceRect& r2)
-{
-    return rect_intersects(&r1, &r2);
-}
-
-static inline int rect_is_equal(const SpiceRect& r1, const SpiceRect& r2)
-{
-    return rect_is_equal(&r1, &r2);
-}
-
-static inline void rect_union(SpiceRect& dest, const SpiceRect& r)
-{
-    rect_union(&dest, &r);
-}
-
-static inline int rect_is_same_size(const SpiceRect& r1, const SpiceRect& r2)
-{
-    return rect_is_same_size(&r1, &r2);
-}
-
-#endif
-
-#endif
-
diff --git a/common/region.c b/common/region.c
deleted file mode 100644
index 3f51f7b..0000000
--- a/common/region.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <spice/macros.h>
-
-#include "region.h"
-#include "rect.h"
-#include "mem.h"
-
-#define ASSERT(x) if (!(x)) {                               \
-    printf("%s: ASSERT %s failed\n", __FUNCTION__, #x);     \
-    abort();                                                \
-}
-
-/*  true iff two Boxes overlap */
-#define EXTENTCHECK(r1, r2)        \
-    (!( ((r1)->x2 <= (r2)->x1)  || \
-        ((r1)->x1 >= (r2)->x2)  || \
-        ((r1)->y2 <= (r2)->y1)  || \
-        ((r1)->y1 >= (r2)->y2) ) )
-
-/* true iff Box r1 contains Box r2 */
-#define SUBSUMES(r1, r2)        \
-    ( ((r1)->x1 <= (r2)->x1) && \
-      ((r1)->x2 >= (r2)->x2) && \
-      ((r1)->y1 <= (r2)->y1) && \
-      ((r1)->y2 >= (r2)->y2) )
-
-
-void region_init(QRegion *rgn)
-{
-    pixman_region32_init(rgn);
-}
-
-void region_clear(QRegion *rgn)
-{
-    pixman_region32_fini(rgn);
-    pixman_region32_init(rgn);
-}
-
-void region_destroy(QRegion *rgn)
-{
-    pixman_region32_fini(rgn);
-}
-
-void region_clone(QRegion *dest, const QRegion *src)
-{
-    pixman_region32_init(dest);
-    pixman_region32_copy(dest, (pixman_region32_t *)src);
-}
-
-#define FIND_BAND(r, r_band_end, r_end, ry1)                         \
-    do {                                                             \
-        ry1 = r->y1;                                                 \
-        r_band_end = r + 1;                                          \
-        while ((r_band_end != r_end) && (r_band_end->y1 == ry1)) {   \
-            r_band_end++;                                            \
-        }                                                            \
-    } while (0)
-
-static int test_band(int query,
-                     int res,
-                     pixman_box32_t *r1,
-                     pixman_box32_t *r1_end,
-                     pixman_box32_t *r2,
-                     pixman_box32_t *r2_end)
-{
-    int x1;
-    int x2;
-
-    do {
-        x1 = MAX(r1->x1, r2->x1);
-        x2 = MIN(r1->x2, r2->x2);
-
-        /*
-         * Is there any overlap between the two rectangles?
-         */
-        if (x1 < x2) {
-            res |= REGION_TEST_SHARED;
-
-            if (r1->x1 < r2->x1 || r1->x2 > r2->x2) {
-                res |= REGION_TEST_LEFT_EXCLUSIVE;
-            }
-
-            if (r2->x1 < r1->x1 || r2->x2 > r1->x2) {
-                res |= REGION_TEST_RIGHT_EXCLUSIVE;
-            }
-        } else {
-            /* No overlap at all, the leftmost is exclusive */
-            if (r1->x1 < r2->x1) {
-                res |= REGION_TEST_LEFT_EXCLUSIVE;
-            } else {
-                res |= REGION_TEST_RIGHT_EXCLUSIVE;
-            }
-        }
-
-        if ((res & query) == query) {
-            return res;
-        }
-
-        /*
-         * Advance the pointer(s) with the leftmost right side, since the next
-         * rectangle on that list may still overlap the other region's
-         * current rectangle.
-         */
-        if (r1->x2 == x2) {
-            r1++;
-        }
-        if (r2->x2 == x2) {
-            r2++;
-        }
-    } while ((r1 != r1_end) && (r2 != r2_end));
-
-    /*
-     * Deal with whichever band (if any) still has rectangles left.
-     */
-    if (r1 != r1_end) {
-        res |= REGION_TEST_LEFT_EXCLUSIVE;
-    } else if (r2 != r2_end) {
-        res |= REGION_TEST_RIGHT_EXCLUSIVE;
-    }
-
-    return res;
-}
-
-static int test_generic (pixman_region32_t *reg1,
-                         pixman_region32_t *reg2,
-                         int query)
-{
-    pixman_box32_t *r1;             /* Pointer into first region     */
-    pixman_box32_t *r2;             /* Pointer into 2d region        */
-    pixman_box32_t *r1_end;         /* End of 1st region             */
-    pixman_box32_t *r2_end;         /* End of 2d region              */
-    int ybot;                       /* Bottom of intersection        */
-    int ytop;                       /* Top of intersection           */
-    pixman_box32_t * r1_band_end;   /* End of current band in r1     */
-    pixman_box32_t * r2_band_end;   /* End of current band in r2     */
-    int top;                        /* Top of non-overlapping band   */
-    int bot;                        /* Bottom of non-overlapping band*/
-    int r1y1;                       /* Temps for r1->y1 and r2->y1   */
-    int r2y1;
-    int r1_num_rects;
-    int r2_num_rects;
-    int res;
-
-    r1 = pixman_region32_rectangles(reg1, &r1_num_rects);
-    r1_end = r1 + r1_num_rects;
-
-    r2 = pixman_region32_rectangles(reg2, &r2_num_rects);
-    r2_end = r2 + r2_num_rects;
-
-    res = 0;
-
-    /*
-     * Initialize ybot.
-     * In the upcoming loop, ybot and ytop serve different functions depending
-     * on whether the band being handled is an overlapping or non-overlapping
-     * band.
-     *  In the case of a non-overlapping band (only one of the regions
-     * has points in the band), ybot is the bottom of the most recent
-     * intersection and thus clips the top of the rectangles in that band.
-     * ytop is the top of the next intersection between the two regions and
-     * serves to clip the bottom of the rectangles in the current band.
-     *  For an overlapping band (where the two regions intersect), ytop clips
-     * the top of the rectangles of both regions and ybot clips the bottoms.
-     */
-
-    ybot = MIN(r1->y1, r2->y1);
-
-    do {
-        /*
-         * This algorithm proceeds one source-band (as opposed to a
-         * destination band, which is determined by where the two regions
-         * intersect) at a time. r1_band_end and r2_band_end serve to mark the
-         * rectangle after the last one in the current band for their
-         * respective regions.
-         */
-        FIND_BAND(r1, r1_band_end, r1_end, r1y1);
-        FIND_BAND(r2, r2_band_end, r2_end, r2y1);
-
-        /*
-         * First handle the band that doesn't intersect, if any.
-         *
-         * Note that attention is restricted to one band in the
-         * non-intersecting region at once, so if a region has n
-         * bands between the current position and the next place it overlaps
-         * the other, this entire loop will be passed through n times.
-         */
-        if (r1y1 < r2y1) {
-            top = MAX (r1y1, ybot);
-            bot = MIN (r1->y2, r2y1);
-            if (top != bot) {
-                res |= REGION_TEST_LEFT_EXCLUSIVE;
-
-                if ((res & query) == query) {
-                    return res & query;
-                }
-            }
-
-            ytop = r2y1;
-        } else if (r2y1 < r1y1) {
-            top = MAX (r2y1, ybot);
-            bot = MIN (r2->y2, r1y1);
-
-            if (top != bot) {
-                res |= REGION_TEST_RIGHT_EXCLUSIVE;
-
-                if ((res & query) == query) {
-                    return res & query;
-                }
-            }
-            ytop = r1y1;
-        } else {
-            ytop = r1y1;
-        }
-
-        /*
-         * Now see if we've hit an intersecting band. The two bands only
-         * intersect if ybot > ytop
-         */
-        ybot = MIN (r1->y2, r2->y2);
-        if (ybot > ytop) {
-            res = test_band(query, res,
-                            r1, r1_band_end,
-                            r2, r2_band_end);
-            if ((res & query) == query) {
-                return res & query;
-            }
-        }
-
-        /*
-         * If we've finished with a band (y2 == ybot) we skip forward
-         * in the region to the next band.
-         */
-        if (r1->y2 == ybot) {
-            r1 = r1_band_end;
-        }
-
-        if (r2->y2 == ybot) {
-            r2 = r2_band_end;
-        }
-
-    }
-    while (r1 != r1_end && r2 != r2_end);
-
-    /*
-     * Deal with whichever region (if any) still has rectangles left.
-     */
-
-    if (r1 != r1_end) {
-        res |= REGION_TEST_LEFT_EXCLUSIVE;
-    } else if (r2 != r2_end) {
-        res |= REGION_TEST_RIGHT_EXCLUSIVE;
-    }
-
-    return res & query;
-}
-
-int region_test(const QRegion *_reg1, const QRegion *_reg2, int query)
-{
-    int res;
-    pixman_region32_t *reg1 = (pixman_region32_t *)_reg1;
-    pixman_region32_t *reg2 = (pixman_region32_t *)_reg2;
-
-    query = (query) ? query & REGION_TEST_ALL : REGION_TEST_ALL;
-
-    res = 0;
-
-    if (!pixman_region32_not_empty(reg1) || !pixman_region32_not_empty(reg2) ||
-        !EXTENTCHECK (&reg1->extents, &reg2->extents)) {
-        /* One or more regions are empty or they are disjoint */
-
-        if (pixman_region32_not_empty(reg1)) {
-            res |= REGION_TEST_LEFT_EXCLUSIVE;
-        }
-
-        if (pixman_region32_not_empty(reg2)) {
-            res |= REGION_TEST_RIGHT_EXCLUSIVE;
-        }
-
-        return res & query;
-    } else if (!reg1->data && !reg2->data) {
-        /* Just two rectangles that intersect */
-        res |= REGION_TEST_SHARED;
-
-        if (!SUBSUMES(&reg1->extents, &reg2->extents)) {
-            res |= REGION_TEST_RIGHT_EXCLUSIVE;
-        }
-
-        if (!SUBSUMES(&reg2->extents, &reg1->extents)) {
-            res |= REGION_TEST_LEFT_EXCLUSIVE;
-        }
-
-        return res & query;
-    } else if (!reg2->data && SUBSUMES (&reg2->extents, &reg1->extents)) {
-        /* reg2 is just a rect that contains all of reg1 */
-
-        res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
-        res |= REGION_TEST_RIGHT_EXCLUSIVE; /* reg2 contains all of reg1 and then some */
-
-        return res & query;
-    } else if (!reg1->data && SUBSUMES (&reg1->extents, &reg2->extents)) {
-        /* reg1 is just a rect that contains all of reg2 */
-
-        res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
-        res |= REGION_TEST_LEFT_EXCLUSIVE; /* reg1 contains all of reg2 and then some */
-
-        return res & query;
-    } else if (reg1 == reg2) {
-        res |= REGION_TEST_SHARED;
-        return res & query;
-    } else {
-        /* General purpose intersection */
-        return test_generic (reg1, reg2, query);
-    }
-}
-
-int region_is_valid(const QRegion *rgn)
-{
-    return pixman_region32_selfcheck((pixman_region32_t *)rgn);
-}
-
-int region_is_empty(const QRegion *rgn)
-{
-    return !pixman_region32_not_empty((pixman_region32_t *)rgn);
-}
-
-SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects)
-{
-    pixman_box32_t *boxes;
-    SpiceRect *rects;
-    int n, i;
-
-    boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, &n);
-    if (num_rects) {
-        *num_rects = n;
-    }
-    rects = spice_new(SpiceRect, n);
-    for (i = 0; i < n; i++) {
-        rects[i].left = boxes[i].x1;
-        rects[i].top = boxes[i].y1;
-        rects[i].right = boxes[i].x2;
-        rects[i].bottom = boxes[i].y2;
-    }
-    return rects;
-}
-
-void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects)
-{
-    pixman_box32_t *boxes;
-    unsigned int n, i;
-
-    boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, (int *)&n);
-    for (i = 0; i < n && i < num_rects; i++) {
-        rects[i].left = boxes[i].x1;
-        rects[i].top = boxes[i].y1;
-        rects[i].right = boxes[i].x2;
-        rects[i].bottom = boxes[i].y2;
-    }
-
-    if (i && i != n) {
-        unsigned int x;
-
-        for (x = 0; x < (n - num_rects); ++x) {
-            rects[i - 1].left = MIN(rects[i - 1].left, boxes[i + x].x1);
-            rects[i - 1].top = MIN(rects[i - 1].top, boxes[i + x].y1);
-            rects[i - 1].right = MAX(rects[i - 1].right, boxes[i + x].x2);
-            rects[i - 1].bottom = MAX(rects[i - 1].bottom, boxes[i + x].y2);
-        }
-    }
-}
-
-
-int region_is_equal(const QRegion *rgn1, const QRegion *rgn2)
-{
-    return pixman_region32_equal((pixman_region32_t *)rgn1, (pixman_region32_t *)rgn2);
-}
-
-int region_intersects(const QRegion *rgn1, const QRegion *rgn2)
-{
-    int test_res;
-
-    if (!region_bounds_intersects(rgn1, rgn2)) {
-        return FALSE;
-    }
-
-    test_res = region_test(rgn1, rgn2, REGION_TEST_SHARED);
-    return !!test_res;
-}
-
-int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2)
-{
-    pixman_box32_t *extents1, *extents2;
-
-    extents1 = pixman_region32_extents((pixman_region32_t *)rgn1);
-    extents2 = pixman_region32_extents((pixman_region32_t *)rgn1);
-
-    return EXTENTCHECK(extents1, extents2);
-}
-
-int region_contains(const QRegion *rgn, const QRegion *other)
-{
-    int test_res;
-
-    test_res = region_test(rgn, other, REGION_TEST_RIGHT_EXCLUSIVE);
-    return !test_res;
-}
-
-int region_contains_point(const QRegion *rgn, int32_t x, int32_t y)
-{
-    return pixman_region32_contains_point((pixman_region32_t *)rgn, x, y, NULL);
-}
-
-void region_or(QRegion *rgn, const QRegion *other_rgn)
-{
-    pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
-}
-
-void region_and(QRegion *rgn, const QRegion *other_rgn)
-{
-    pixman_region32_intersect(rgn, rgn, (pixman_region32_t *)other_rgn);
-}
-
-void region_xor(QRegion *rgn, const QRegion *other_rgn)
-{
-    pixman_region32_t intersection;
-
-    pixman_region32_copy(&intersection, rgn);
-    pixman_region32_intersect(&intersection,
-                              &intersection,
-                              (pixman_region32_t *)other_rgn);
-    pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
-    pixman_region32_subtract(rgn, rgn, &intersection);
-    pixman_region32_fini(&intersection);
-}
-
-void region_exclude(QRegion *rgn, const QRegion *other_rgn)
-{
-    pixman_region32_subtract(rgn, rgn, (pixman_region32_t *)other_rgn);
-}
-
-void region_add(QRegion *rgn, const SpiceRect *r)
-{
-    pixman_region32_union_rect(rgn, rgn, r->left, r->top,
-                               r->right - r->left,
-                               r->bottom - r->top);
-}
-
-void region_remove(QRegion *rgn, const SpiceRect *r)
-{
-    pixman_region32_t rg;
-
-    pixman_region32_init_rect(&rg, r->left, r->top,
-                              r->right - r->left,
-                              r->bottom - r->top);
-    pixman_region32_subtract(rgn, rgn, &rg);
-    pixman_region32_fini(&rg);
-}
-
-
-void region_offset(QRegion *rgn, int32_t dx, int32_t dy)
-{
-    pixman_region32_translate(rgn, dx, dy);
-}
-
-void region_dump(const QRegion *rgn, const char *prefix)
-{
-    pixman_box32_t *rects, *extents;
-    int n_rects, i;
-
-    printf("%sREGION: %p, ", prefix, rgn);
-
-    if (!pixman_region32_not_empty((pixman_region32_t *)rgn)) {
-        printf("EMPTY\n");
-        return;
-    }
-
-    extents = pixman_region32_extents((pixman_region32_t *)rgn);
-    rects = pixman_region32_rectangles((pixman_region32_t *)rgn, &n_rects);
-    printf("num %u bounds (%d, %d, %d, %d)\n",
-           n_rects,
-           extents->x1,
-           extents->y1,
-           extents->x2,
-           extents->y2);
-
-
-    for (i = 0; i < n_rects; i++) {
-        printf("%*s  %12d %12d %12d %12d\n",
-               (int)strlen(prefix), "",
-               rects[i].x1,
-               rects[i].y1,
-               rects[i].x2,
-               rects[i].y2);
-    }
-}
-
-#ifdef REGION_TEST
-
-static int slow_region_test(const QRegion *rgn, const QRegion *other_rgn, int query)
-{
-    pixman_region32_t intersection;
-    int res;
-
-    pixman_region32_init(&intersection);
-    pixman_region32_intersect(&intersection,
-                              (pixman_region32_t *)rgn,
-                              (pixman_region32_t *)other_rgn);
-
-    res = 0;
-
-    if (query & REGION_TEST_SHARED &&
-        pixman_region32_not_empty(&intersection)) {
-        res |= REGION_TEST_SHARED;
-    }
-
-    if (query & REGION_TEST_LEFT_EXCLUSIVE &&
-        !pixman_region32_equal(&intersection, (pixman_region32_t *)rgn)) {
-        res |= REGION_TEST_LEFT_EXCLUSIVE;
-    }
-
-    if (query & REGION_TEST_RIGHT_EXCLUSIVE &&
-        !pixman_region32_equal(&intersection, (pixman_region32_t *)other_rgn)) {
-        res |= REGION_TEST_RIGHT_EXCLUSIVE;
-    }
-
-    pixman_region32_fini(&intersection);
-
-    return res;
-}
-
-
-static int rect_is_valid(const SpiceRect *r)
-{
-    if (r->top > r->bottom || r->left > r->right) {
-        printf("%s: invalid rect\n", __FUNCTION__);
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static void rect_set(SpiceRect *r, int32_t top, int32_t left, int32_t bottom, int32_t right)
-{
-    r->top = top;
-    r->left = left;
-    r->bottom = bottom;
-    r->right = right;
-    ASSERT(rect_is_valid(r));
-}
-
-static void random_region(QRegion *reg)
-{
-    int i;
-    int num_rects;
-    int x, y, w, h;
-    SpiceRect _r;
-    SpiceRect *r = &_r;
-
-    region_clear(reg);
-
-    num_rects = rand() % 20;
-    for (i = 0; i < num_rects; i++) {
-        x = rand()%100;
-        y = rand()%100;
-        w = rand()%100;
-        h = rand()%100;
-        rect_set(r,
-                 x, y,
-                 x+w, y+h);
-        region_add(reg, r);
-    }
-}
-
-static void test(const QRegion *r1, const QRegion *r2, int *expected)
-{
-    printf("r1 is_empty %s [%s]\n",
-           region_is_empty(r1) ? "TRUE" : "FALSE",
-           (region_is_empty(r1) == *(expected++)) ? "OK" : "ERR");
-    printf("r2 is_empty %s [%s]\n",
-           region_is_empty(r2) ? "TRUE" : "FALSE",
-           (region_is_empty(r2) == *(expected++)) ? "OK" : "ERR");
-    printf("is_equal %s [%s]\n",
-           region_is_equal(r1, r2) ? "TRUE" : "FALSE",
-           (region_is_equal(r1, r2) == *(expected++)) ? "OK" : "ERR");
-    printf("intersects %s [%s]\n",
-           region_intersects(r1, r2) ? "TRUE" : "FALSE",
-           (region_intersects(r1, r2) == *(expected++)) ? "OK" : "ERR");
-    printf("contains %s [%s]\n",
-           region_contains(r1, r2) ? "TRUE" : "FALSE",
-           (region_contains(r1, r2) == *(expected++)) ? "OK" : "ERR");
-}
-
-enum {
-    EXPECT_R1_EMPTY,
-    EXPECT_R2_EMPTY,
-    EXPECT_EQUAL,
-    EXPECT_SECT,
-    EXPECT_CONT,
-};
-
-int main(void)
-{
-    QRegion _r1, _r2, _r3;
-    QRegion *r1 = &_r1;
-    QRegion *r2 = &_r2;
-    QRegion *r3 = &_r3;
-    SpiceRect _r;
-    SpiceRect *r = &_r;
-    int expected[5];
-    int i, j;
-
-    region_init(r1);
-    region_init(r2);
-
-    printf("dump r1 empty rgn [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = TRUE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = TRUE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clone(r3, r1);
-    printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
-    region_dump(r3, "");
-    expected[EXPECT_R1_EMPTY] = TRUE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = TRUE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r3, expected);
-    region_destroy(r3);
-    printf("\n");
-
-    rect_set(r, 0, 0, 100, 100);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r1);
-    rect_set(r, 0, 0, 0, 0);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = TRUE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = TRUE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    rect_set(r, -100, -100, 0, 0);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r1);
-    rect_set(r, -100, -100, 100, 100);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-
-    region_clear(r1);
-    region_clear(r2);
-
-    rect_set(r, 100, 100, 200, 200);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    rect_set(r, 300, 300, 400, 400);
-    region_add(r1, r);
-    printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
-    region_dump(r1, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = TRUE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    rect_set(r, 500, 500, 600, 600);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = FALSE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, 100, 100, 200, 200);
-    region_add(r2, r);
-    rect_set(r, 300, 300, 400, 400);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = TRUE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, 100, 100, 200, 200);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, -2000, -2000, -1000, -1000);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = FALSE;
-    expected[EXPECT_CONT] = FALSE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, -2000, -2000, 1000, 1000);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = FALSE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, 150, 150, 175, 175);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_clear(r2);
-
-    rect_set(r, 150, 150, 350, 350);
-    region_add(r2, r);
-    printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = FALSE;
-    test(r1, r2, expected);
-    printf("\n");
-
-    region_and(r2, r1);
-    printf("dump r2 and r1 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
-    region_dump(r2, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = FALSE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = FALSE;
-    test(r2, r1, expected);
-    printf("\n");
-
-
-    region_clone(r3, r1);
-    printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
-    region_dump(r3, "");
-    expected[EXPECT_R1_EMPTY] = FALSE;
-    expected[EXPECT_R2_EMPTY] = FALSE;
-    expected[EXPECT_EQUAL] = TRUE;
-    expected[EXPECT_SECT] = TRUE;
-    expected[EXPECT_CONT] = TRUE;
-    test(r1, r3, expected);
-    printf("\n");
-
-    j = 0;
-    for (i = 0; i < 1000000; i++) {
-        int res1, res2, test;
-        int tests[] = {
-            REGION_TEST_LEFT_EXCLUSIVE,
-            REGION_TEST_RIGHT_EXCLUSIVE,
-            REGION_TEST_SHARED,
-            REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE,
-            REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_SHARED,
-            REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED,
-            REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED
-        };
-
-        random_region(r1);
-        random_region(r2);
-
-        for (test = 0; test < 7; test++) {
-            res1 = region_test(r1, r2, tests[test]);
-            res2 = slow_region_test(r1, r2, tests[test]);
-            if (res1 != res2) {
-                printf ("Error in region_test %d, got %d, expected %d, query=%d\n",
-                        j, res1, res2, tests[test]);
-                printf ("r1:\n");
-                region_dump(r1, "");
-                printf ("r2:\n");
-                region_dump(r2, "");
-            }
-            j++;
-        }
-    }
-
-    region_destroy(r3);
-    region_destroy(r1);
-    region_destroy(r2);
-
-    return 0;
-}
-
-#endif
-
diff --git a/common/region.h b/common/region.h
deleted file mode 100644
index bad7494..0000000
--- a/common/region.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_REGION
-#define _H_REGION
-
-#include <stdint.h>
-#include "draw.h"
-#include <pixman_utils.h>
-
-typedef pixman_region32_t QRegion;
-
-#define REGION_TEST_LEFT_EXCLUSIVE (1 << 0)
-#define REGION_TEST_RIGHT_EXCLUSIVE (1 << 1)
-#define REGION_TEST_SHARED (1 << 2)
-#define REGION_TEST_ALL \
-    (REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED)
-
-void region_init(QRegion *rgn);
-void region_clear(QRegion *rgn);
-void region_destroy(QRegion *rgn);
-void region_clone(QRegion *dest, const QRegion *src);
-SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects);
-void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects);
-
-int region_test(const QRegion *rgn, const QRegion *other_rgn, int query);
-int region_is_valid(const QRegion *rgn);
-int region_is_empty(const QRegion *rgn);
-int region_is_equal(const QRegion *rgn1, const QRegion *rgn2);
-int region_intersects(const QRegion *rgn1, const QRegion *rgn2);
-int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2);
-int region_contains(const QRegion *rgn, const QRegion *other);
-int region_contains_point(const QRegion *rgn, int32_t x, int32_t y);
-
-void region_or(QRegion *rgn, const QRegion *other_rgn);
-void region_and(QRegion *rgn, const QRegion *other_rgn);
-void region_xor(QRegion *rgn, const QRegion *other_rgn);
-void region_exclude(QRegion *rgn, const QRegion *other_rgn);
-
-void region_add(QRegion *rgn, const SpiceRect *r);
-void region_remove(QRegion *rgn, const SpiceRect *r);
-
-void region_offset(QRegion *rgn, int32_t dx, int32_t dy);
-
-void region_dump(const QRegion *rgn, const char *prefix);
-
-#endif
-
diff --git a/common/ring.h b/common/ring.h
deleted file mode 100644
index 0194959..0000000
--- a/common/ring.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_RING2
-#define _H_RING2
-
-#include <stddef.h>
-
-#ifndef ASSERT
-# include <assert.h>
-# define ASSERT(X) assert(X)
-#endif
-
-typedef struct Ring RingItem;
-typedef struct Ring {
-    RingItem *prev;
-    RingItem *next;
-} Ring;
-
-static inline void ring_init(Ring *ring)
-{
-    ring->next = ring->prev = ring;
-}
-
-static inline void ring_item_init(RingItem *item)
-{
-    item->next = item->prev = NULL;
-}
-
-static inline int ring_item_is_linked(RingItem *item)
-{
-    return !!item->next;
-}
-
-static inline int ring_is_empty(Ring *ring)
-{
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-    return ring == ring->next;
-}
-
-static inline void ring_add(Ring *ring, RingItem *item)
-{
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-    ASSERT(item->next == NULL && item->prev == NULL);
-
-    item->next = ring->next;
-    item->prev = ring;
-    ring->next = item->next->prev = item;
-}
-
-static inline void ring_add_after(RingItem *item, RingItem *pos)
-{
-    ring_add(pos, item);
-}
-
-static inline void ring_add_before(RingItem *item, RingItem *pos)
-{
-    ring_add(pos->prev, item);
-}
-
-static inline void __ring_remove(RingItem *item)
-{
-    item->next->prev = item->prev;
-    item->prev->next = item->next;
-    item->prev = item->next = 0;
-}
-
-static inline void ring_remove(RingItem *item)
-{
-    ASSERT(item->next != NULL && item->prev != NULL);
-    ASSERT(item->next != item);
-
-    __ring_remove(item);
-}
-
-static inline RingItem *ring_get_head(Ring *ring)
-{
-    RingItem *ret;
-
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-
-    if (ring_is_empty(ring)) {
-        return NULL;
-    }
-    ret = ring->next;
-    return ret;
-}
-
-static inline RingItem *ring_get_tail(Ring *ring)
-{
-    RingItem *ret;
-
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-
-    if (ring_is_empty(ring)) {
-        return NULL;
-    }
-    ret = ring->prev;
-    return ret;
-}
-
-static inline RingItem *ring_next(Ring *ring, RingItem *pos)
-{
-    RingItem *ret;
-
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-    ASSERT(pos);
-    ASSERT(pos->next != NULL && pos->prev != NULL);
-    ret = pos->next;
-    return (ret == ring) ? NULL : ret;
-}
-
-static inline RingItem *ring_prev(Ring *ring, RingItem *pos)
-{
-    RingItem *ret;
-
-    ASSERT(ring->next != NULL && ring->prev != NULL);
-    ASSERT(pos);
-    ASSERT(pos->next != NULL && pos->prev != NULL);
-    ret = pos->prev;
-    return (ret == ring) ? NULL : ret;
-}
-
-static inline unsigned int ring_get_length(Ring *ring)
-{
-    RingItem *i;
-    unsigned int ret = 0;
-
-    for (i = ring_get_head(ring);
-         i != NULL;
-         i = ring_next(ring, i))
-        ret++;
-
-    return ret;
-}
-
-#endif
-
diff --git a/common/rop3.c b/common/rop3.c
deleted file mode 100644
index 15de023..0000000
--- a/common/rop3.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#include "rop3.h"
-
-#ifndef ASSERT
-#define ASSERT(x) if (!(x)) {                               \
-    printf("%s: ASSERT %s failed\n", __FUNCTION__, #x);     \
-    abort();                                                \
-}
-#endif
-
-#ifndef WARN
-#define WARN(x) printf("warning: %s\n", x)
-#endif
-
-typedef void (*rop3_with_pattern_handler_t)(pixman_image_t *d, pixman_image_t *s,
-                                            SpicePoint *src_pos, pixman_image_t *p,
-                                            SpicePoint *pat_pos);
-
-typedef void (*rop3_with_color_handler_t)(pixman_image_t *d, pixman_image_t *s,
-                                          SpicePoint *src_pos, uint32_t rgb);
-
-typedef void (*rop3_test_handler_t)(void);
-
-#define ROP3_NUM_OPS 256
-
-static rop3_with_pattern_handler_t rop3_with_pattern_handlers_32[ROP3_NUM_OPS];
-static rop3_with_pattern_handler_t rop3_with_pattern_handlers_16[ROP3_NUM_OPS];
-static rop3_with_color_handler_t rop3_with_color_handlers_32[ROP3_NUM_OPS];
-static rop3_with_color_handler_t rop3_with_color_handlers_16[ROP3_NUM_OPS];
-static rop3_test_handler_t rop3_test_handlers_32[ROP3_NUM_OPS];
-static rop3_test_handler_t rop3_test_handlers_16[ROP3_NUM_OPS];
-
-
-static void default_rop3_with_pattern_handler(pixman_image_t *d, pixman_image_t *s,
-                                              SpicePoint *src_pos, pixman_image_t *p,
-                                              SpicePoint *pat_pos)
-{
-    WARN("not implemented 0x%x");
-}
-
-static void default_rop3_withe_color_handler(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
-                                             uint32_t rgb)
-{
-    WARN("not implemented 0x%x");
-}
-
-static void default_rop3_test_handler(void)
-{
-}
-
-#define ROP3_HANDLERS_DEPTH(name, formula, index, depth)                            \
-static void rop3_handle_p##depth##_##name(pixman_image_t *d, pixman_image_t *s,                 \
-                                          SpicePoint *src_pos,                                  \
-                                          pixman_image_t *p, SpicePoint *pat_pos)               \
-{                                                                                               \
-    int width = pixman_image_get_width(d);                                                      \
-    int height = pixman_image_get_height(d);                                                    \
-    uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d);                                   \
-    int dest_stride = pixman_image_get_stride(d);                                               \
-    uint8_t *end_line = dest_line + height * dest_stride;                                       \
-                                                                                                \
-    int pat_width = pixman_image_get_width(p);                                                  \
-    int pat_height = pixman_image_get_height(p);                                                \
-    uint8_t *pat_base = (uint8_t *)pixman_image_get_data(p);                                    \
-    int pat_stride = pixman_image_get_stride(p);                                                \
-    int pat_v_offset = pat_pos->y;                                                              \
-                                                                                                \
-    int src_stride = pixman_image_get_stride(s);                                                \
-    uint8_t *src_line;                                                                          \
-    src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8); \
-                                                                                                \
-    for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) {            \
-        uint##depth##_t *dest = (uint##depth##_t *)dest_line;                                   \
-        uint##depth##_t *end = dest + width;                                                    \
-        uint##depth##_t *src = (uint##depth##_t *)src_line;                                     \
-                                                                                                \
-        int pat_h_offset = pat_pos->x;                                                          \
-                                                                                                \
-        for (; dest < end; dest++, src++) {                                                     \
-            uint##depth##_t *pat;                                                               \
-            pat  = (uint##depth##_t *)                                                          \
-                        (pat_base + pat_v_offset * pat_stride + (pat_h_offset * depth / 8));    \
-            *dest = formula;                                                                    \
-            pat_h_offset = (pat_h_offset + 1) % pat_width;                                      \
-        }                                                                                       \
-                                                                                                \
-        pat_v_offset = (pat_v_offset + 1) % pat_height;                                         \
-    }                                                                                           \
-}                                                                                               \
-                                                                                                \
-static void rop3_handle_c##depth##_##name(pixman_image_t *d, pixman_image_t *s,                 \
-                                          SpicePoint *src_pos,                                  \
-                                          uint32_t rgb)                                         \
-{                                                                                               \
-    int width = pixman_image_get_width(d);                                                      \
-    int height = pixman_image_get_height(d);                                                    \
-    uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d);                                   \
-    int dest_stride = pixman_image_get_stride(d);                                               \
-    uint8_t *end_line = dest_line + height * dest_stride;                                       \
-    uint##depth##_t _pat = rgb;                                                                \
-    uint##depth##_t *pat = &_pat;                                                               \
-                                                                                                \
-    int src_stride = pixman_image_get_stride(s);                                                \
-    uint8_t *src_line;                                                                          \
-    src_line = (uint8_t *)                                                                      \
-        pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8);          \
-                                                                                                \
-    for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) {            \
-        uint##depth##_t *dest = (uint##depth##_t *)dest_line;                                   \
-        uint##depth##_t *end = dest + width;                                                    \
-        uint##depth##_t *src = (uint##depth##_t *)src_line;                                     \
-        for (; dest < end; dest++, src++) {                                                     \
-            *dest = formula;                                                                    \
-        }                                                                                       \
-    }                                                                                           \
-}                                                                                               \
-                                                                                                \
-static void rop3_test##depth##_##name(void)                                                     \
-{                                                                                               \
-    uint8_t d = 0xaa;                                                                           \
-    uint8_t s = 0xcc;                                                                           \
-    uint8_t p = 0xf0;                                                                           \
-    uint8_t *pat = &p;                                                                          \
-    uint8_t *src = &s;                                                                          \
-    uint8_t *dest = &d;                                                                         \
-                                                                                                \
-    d = formula;                                                                                \
-    if (d != index) {                                                                           \
-        printf("%s: failed, result is 0x%x expect 0x%x\n", __FUNCTION__, d, index);             \
-    }                                                                                           \
-}
-
-#define ROP3_HANDLERS(name, formula, index) \
-    ROP3_HANDLERS_DEPTH(name, formula, index, 32)  \
-    ROP3_HANDLERS_DEPTH(name, formula, index, 16)
-
-ROP3_HANDLERS(DPSoon, ~(*pat | *src | *dest), 0x01);
-ROP3_HANDLERS(DPSona, ~(*pat | *src) & *dest, 0x02);
-ROP3_HANDLERS(SDPona, ~(*pat | *dest) & *src, 0x04);
-ROP3_HANDLERS(PDSxnon, ~(~(*src ^ *dest) | *pat), 0x06);
-ROP3_HANDLERS(PDSaon, ~((*src & *dest) | *pat), 0x07);
-ROP3_HANDLERS(SDPnaa, ~*pat & *dest & *src, 0x08);
-ROP3_HANDLERS(PDSxon, ~((*src ^ *dest) | *pat), 0x09);
-ROP3_HANDLERS(PSDnaon, ~((~*dest & *src) | *pat), 0x0b);
-ROP3_HANDLERS(PDSnaon, ~((~*src & *dest) | *pat), 0x0d);
-ROP3_HANDLERS(PDSonon, ~(~(*src | *dest) | *pat), 0x0e);
-ROP3_HANDLERS(PDSona, ~(*src | *dest) & *pat, 0x10);
-ROP3_HANDLERS(SDPxnon, ~(~(*pat ^ *dest) | *src), 0x12);
-ROP3_HANDLERS(SDPaon, ~((*pat & *dest) | *src), 0x13);
-ROP3_HANDLERS(DPSxnon, ~(~(*pat ^ *src) | *dest), 0x14);
-ROP3_HANDLERS(DPSaon, ~((*pat & *src) | *dest), 0x15);
-ROP3_HANDLERS(PSDPSanaxx, (~(*pat & *src) & *dest) ^ *src ^ *pat, 0x16);
-ROP3_HANDLERS(SSPxDSxaxn, ~(((*src ^ *dest) & (*src ^ *pat)) ^ *src), 0x17);
-ROP3_HANDLERS(SPxPDxa, (*src ^ *pat) & (*pat ^ *dest), 0x18);
-ROP3_HANDLERS(SDPSanaxn, ~((~(*pat & *src) & *dest) ^ *src), 0x19);
-ROP3_HANDLERS(PDSPaox, ((*pat & *src) | *dest) ^ *pat, 0x1a);
-ROP3_HANDLERS(SDPSxaxn, ~(((*pat ^ *src) & *dest) ^ *src), 0x1b);
-ROP3_HANDLERS(PSDPaox, ((*pat & *dest) | *src) ^ *pat, 0x1c);
-ROP3_HANDLERS(DSPDxaxn, ~(((*pat ^ *dest) & *src) ^ *dest), 0x1d);
-ROP3_HANDLERS(PDSox, (*dest | *src) ^ *pat, 0x1e);
-ROP3_HANDLERS(PDSoan, ~((*src | *dest) & *pat), 0x1f);
-ROP3_HANDLERS(DPSnaa, ~*src & *pat & *dest, 0x20);
-ROP3_HANDLERS(SDPxon, ~((*pat ^ *dest) | *src), 0x21);
-ROP3_HANDLERS(SPDnaon, ~((~*dest & *pat) | *src), 0x23);
-ROP3_HANDLERS(SPxDSxa, (*src ^ *pat) & (*dest ^ *src), 0x24);
-ROP3_HANDLERS(PDSPanaxn, ~((~(*src & *pat) & *dest) ^ *pat), 0x25);
-ROP3_HANDLERS(SDPSaox, ((*src & *pat) | *dest) ^ *src, 0x26);
-ROP3_HANDLERS(SDPSxnox, (~(*src ^ *pat) | *dest) ^ *src, 0x27);
-ROP3_HANDLERS(DPSxa, (*pat ^ *src) & *dest, 0x28);
-ROP3_HANDLERS(PSDPSaoxxn, ~(((*src & *pat) | *dest) ^ *src ^ *pat), 0x29);
-ROP3_HANDLERS(DPSana, ~(*src & *pat) & *dest, 0x2a);
-ROP3_HANDLERS(SSPxPDxaxn, ~(((*pat ^ *dest) & (*src ^ *pat)) ^ *src), 0x2b);
-ROP3_HANDLERS(SPDSoax, ((*src | *dest) & *pat) ^ *src, 0x2c);
-ROP3_HANDLERS(PSDnox, (~*dest | *src) ^ *pat, 0x2d);
-ROP3_HANDLERS(PSDPxox, ((*pat ^ *dest) | *src) ^ *pat, 0x2e);
-ROP3_HANDLERS(PSDnoan, ~((~*dest | *src) & *pat), 0x2f);
-ROP3_HANDLERS(SDPnaon, ~((~*pat & *dest) | *src), 0x31);
-ROP3_HANDLERS(SDPSoox, (*src | *pat | *dest) ^ *src, 0x32);
-ROP3_HANDLERS(SPDSaox, ((*src & *dest) | *pat) ^ *src, 0x34);
-ROP3_HANDLERS(SPDSxnox, (~(*src ^ *dest) | *pat) ^ *src, 0x35);
-ROP3_HANDLERS(SDPox, (*pat | *dest) ^ *src, 0x36);
-ROP3_HANDLERS(SDPoan, ~((*pat | *dest) & *src), 0x37);
-ROP3_HANDLERS(PSDPoax, ((*pat | *dest) & *src) ^ *pat, 0x38);
-ROP3_HANDLERS(SPDnox, (~*dest | *pat) ^ *src, 0x39);
-ROP3_HANDLERS(SPDSxox, ((*src ^ *dest) | *pat) ^ *src, 0x3a);
-ROP3_HANDLERS(SPDnoan, ~((~*dest | *pat) & *src), 0x3b);
-ROP3_HANDLERS(SPDSonox, (~(*src | *dest) | *pat) ^ *src, 0x3d);
-ROP3_HANDLERS(SPDSnaox, ((~*src & *dest) | *pat) ^ *src, 0x3e);
-ROP3_HANDLERS(PSDnaa, ~*dest & *src & *pat, 0x40);
-ROP3_HANDLERS(DPSxon, ~((*src ^ *pat) | *dest), 0x41);
-ROP3_HANDLERS(SDxPDxa, (*src ^ *dest) & (*pat ^ *dest), 0x42);
-ROP3_HANDLERS(SPDSanaxn, ~((~(*src & *dest) & *pat) ^ *src), 0x43);
-ROP3_HANDLERS(DPSnaon, ~((~*src & *pat) | *dest), 0x45);
-ROP3_HANDLERS(DSPDaox, ((*dest & *pat) | *src) ^ *dest, 0x46);
-ROP3_HANDLERS(PSDPxaxn, ~(((*pat ^ *dest) & *src) ^ *pat), 0x47);
-ROP3_HANDLERS(SDPxa, (*pat ^ *dest) & *src, 0x48);
-ROP3_HANDLERS(PDSPDaoxxn, ~(((*dest & *pat) | *src) ^ *dest ^ *pat), 0x49);
-ROP3_HANDLERS(DPSDoax, ((*dest | *src) & *pat) ^ *dest, 0x4a);
-ROP3_HANDLERS(PDSnox, (~*src | *dest) ^ *pat, 0x4b);
-ROP3_HANDLERS(SDPana, ~(*pat & *dest) & *src, 0x4c);
-ROP3_HANDLERS(SSPxDSxoxn, ~(((*src ^ *dest) | (*src ^ *pat)) ^ *src), 0x4d);
-ROP3_HANDLERS(PDSPxox, ((*pat ^ *src) | *dest) ^ *pat, 0x4e);
-ROP3_HANDLERS(PDSnoan, ~((~*src | *dest) & *pat), 0x4f);
-ROP3_HANDLERS(DSPnaon, ~((~*pat & *src) | *dest), 0x51);
-ROP3_HANDLERS(DPSDaox, ((*dest & *src) | *pat) ^ *dest, 0x52);
-ROP3_HANDLERS(SPDSxaxn, ~(((*src ^ *dest) & *pat) ^ *src), 0x53);
-ROP3_HANDLERS(DPSonon, ~(~(*src | *pat) | *dest), 0x54);
-ROP3_HANDLERS(DPSox, (*src | *pat) ^ *dest, 0x56);
-ROP3_HANDLERS(DPSoan, ~((*src | *pat) & *dest), 0x57);
-ROP3_HANDLERS(PDSPoax, ((*pat | *src) & *dest) ^ *pat, 0x58);
-ROP3_HANDLERS(DPSnox, (~*src | *pat) ^ *dest, 0x59);
-ROP3_HANDLERS(DPSDonox, (~(*dest | *src) | *pat) ^ *dest, 0x5b);
-ROP3_HANDLERS(DPSDxox, ((*dest ^ *src) | *pat) ^ *dest, 0x5c);
-ROP3_HANDLERS(DPSnoan, ~((~*src | *pat) & *dest), 0x5d);
-ROP3_HANDLERS(DPSDnaox, ((~*dest & *src) | *pat) ^ *dest, 0x5e);
-ROP3_HANDLERS(PDSxa, (*src ^ *dest) & *pat, 0x60);
-ROP3_HANDLERS(DSPDSaoxxn, ~(((*src & *dest) | *pat) ^ *src ^ *dest), 0x61);
-ROP3_HANDLERS(DSPDoax, ((*dest | *pat) & *src) ^ *dest, 0x62);
-ROP3_HANDLERS(SDPnox, (~*pat | *dest) ^ *src, 0x63);
-ROP3_HANDLERS(SDPSoax, ((*src | *pat) & *dest) ^ *src, 0x64);
-ROP3_HANDLERS(DSPnox, (~*pat | *src) ^ *dest, 0x65);
-ROP3_HANDLERS(SDPSonox, (~(*src | *pat) | *dest) ^ *src, 0x67);
-ROP3_HANDLERS(DSPDSonoxxn, ~((~(*src | *dest) | *pat) ^ *src ^ *dest), 0x68);
-ROP3_HANDLERS(PDSxxn, ~(*src ^ *dest ^ *pat), 0x69);
-ROP3_HANDLERS(DPSax, (*src & *pat) ^ *dest, 0x6a);
-ROP3_HANDLERS(PSDPSoaxxn, ~(((*src | *pat) & *dest) ^ *src ^ *pat), 0x6b);
-ROP3_HANDLERS(SDPax, (*pat & *dest) ^ *src, 0x6c);
-ROP3_HANDLERS(PDSPDoaxxn, ~(((*dest | *pat) & *src) ^ *dest ^ *pat), 0x6d);
-ROP3_HANDLERS(SDPSnoax, ((~*src | *pat) & *dest) ^ *src, 0x6e);
-ROP3_HANDLERS(PDSxnan, ~(~(*src ^ *dest) & *pat), 0x6f);
-ROP3_HANDLERS(PDSana, ~(*src & *dest) & *pat, 0x70);
-ROP3_HANDLERS(SSDxPDxaxn, ~(((*dest ^ *pat) & (*src ^ *dest)) ^ *src), 0x71);
-ROP3_HANDLERS(SDPSxox, ((*src ^ *pat) | *dest) ^ *src, 0x72);
-ROP3_HANDLERS(SDPnoan, ~((~*pat | *dest) & *src), 0x73);
-ROP3_HANDLERS(DSPDxox, ((*dest ^ *pat) | *src) ^ *dest, 0x74);
-ROP3_HANDLERS(DSPnoan, ~((~*pat | *src) & *dest), 0x75);
-ROP3_HANDLERS(SDPSnaox, ((~*src & *pat) | *dest) ^ *src, 0x76);
-ROP3_HANDLERS(PDSax, (*src & *dest) ^ *pat, 0x78);
-ROP3_HANDLERS(DSPDSoaxxn, ~(((*src | *dest) & *pat) ^ *src ^ *dest), 0x79);
-ROP3_HANDLERS(DPSDnoax, ((~*dest | *src) & *pat) ^ *dest, 0x7a);
-ROP3_HANDLERS(SDPxnan, ~(~(*pat ^ *dest) & *src), 0x7b);
-ROP3_HANDLERS(SPDSnoax, ((~*src | *dest) & *pat) ^ *src, 0x7c);
-ROP3_HANDLERS(DPSxnan, ~(~(*src ^ *pat) & *dest), 0x7d);
-ROP3_HANDLERS(SPxDSxo, (*src ^ *dest) | (*pat ^ *src), 0x7e);
-ROP3_HANDLERS(DPSaan, ~(*src & *pat & *dest), 0x7f);
-ROP3_HANDLERS(DPSaa, *src & *pat & *dest, 0x80);
-ROP3_HANDLERS(SPxDSxon, ~((*src ^ *dest) | (*pat ^ *src)), 0x81);
-ROP3_HANDLERS(DPSxna, ~(*src ^ *pat) & *dest, 0x82);
-ROP3_HANDLERS(SPDSnoaxn, ~(((~*src | *dest) & *pat) ^ *src), 0x83);
-ROP3_HANDLERS(SDPxna, ~(*pat ^ *dest) & *src, 0x84);
-ROP3_HANDLERS(PDSPnoaxn, ~(((~*pat | *src) & *dest) ^ *pat), 0x85);
-ROP3_HANDLERS(DSPDSoaxx, ((*src | *dest) & *pat) ^ *src ^ *dest, 0x86);
-ROP3_HANDLERS(PDSaxn, ~((*src & *dest) ^ *pat), 0x87);
-ROP3_HANDLERS(SDPSnaoxn, ~(((~*src & *pat) | *dest) ^ *src), 0x89);
-ROP3_HANDLERS(DSPnoa, (~*pat | *src) & *dest, 0x8a);
-ROP3_HANDLERS(DSPDxoxn, ~(((*dest ^ *pat) | *src) ^ *dest), 0x8b);
-ROP3_HANDLERS(SDPnoa, (~*pat | *dest) & *src, 0x8c);
-ROP3_HANDLERS(SDPSxoxn, ~(((*src ^ *pat) | *dest) ^ *src), 0x8d);
-ROP3_HANDLERS(SSDxPDxax, ((*dest ^ *pat) & (*dest ^ *src)) ^ *src, 0x8e);
-ROP3_HANDLERS(PDSanan, ~(~(*src & *dest) & *pat), 0x8f);
-ROP3_HANDLERS(PDSxna, ~(*src ^ *dest) & *pat, 0x90);
-ROP3_HANDLERS(SDPSnoaxn, ~(((~*src | *pat) & *dest) ^ *src), 0x91);
-ROP3_HANDLERS(DPSDPoaxx, ((*pat | *dest) & *src) ^ *pat ^ *dest, 0x92);
-ROP3_HANDLERS(SPDaxn, ~((*dest & *pat) ^ *src), 0x93);
-ROP3_HANDLERS(PSDPSoaxx, ((*src | *pat) & *dest) ^ *src ^ *pat, 0x94);
-ROP3_HANDLERS(DPSaxn, ~((*src & *pat) ^ *dest), 0x95);
-ROP3_HANDLERS(DPSxx, *src ^ *pat ^ *dest, 0x96);
-ROP3_HANDLERS(PSDPSonoxx, (~(*src | *pat) | *dest) ^ *src ^ *pat, 0x97);
-ROP3_HANDLERS(SDPSonoxn, ~((~(*src | *pat) | *dest) ^ *src), 0x98);
-ROP3_HANDLERS(DPSnax, (~*src & *pat) ^ *dest, 0x9a);
-ROP3_HANDLERS(SDPSoaxn, ~(((*src | *pat) & *dest) ^ *src), 0x9b);
-ROP3_HANDLERS(SPDnax, (~*dest & *pat) ^ *src, 0x9c);
-ROP3_HANDLERS(DSPDoaxn, ~(((*dest | *pat) & *src) ^ *dest), 0x9d);
-ROP3_HANDLERS(DSPDSaoxx, ((*src & *dest) | *pat) ^ *src ^ *dest, 0x9e);
-ROP3_HANDLERS(PDSxan, ~((*src ^ *dest) & *pat), 0x9f);
-ROP3_HANDLERS(PDSPnaoxn, ~(((~*pat & *src) | *dest) ^ *pat), 0xa1);
-ROP3_HANDLERS(DPSnoa, (~*src | *pat) & *dest, 0xa2);
-ROP3_HANDLERS(DPSDxoxn, ~(((*dest ^ *src) | *pat) ^ *dest), 0xa3);
-ROP3_HANDLERS(PDSPonoxn, ~((~(*pat | *src) | *dest) ^ *pat), 0xa4);
-ROP3_HANDLERS(DSPnax, (~*pat & *src) ^ *dest, 0xa6);
-ROP3_HANDLERS(PDSPoaxn, ~(((*pat | *src) & *dest) ^ *pat), 0xa7);
-ROP3_HANDLERS(DPSoa, (*src | *pat) & *dest, 0xa8);
-ROP3_HANDLERS(DPSoxn, ~((*src | *pat) ^ *dest), 0xa9);
-ROP3_HANDLERS(DPSono, ~(*src | *pat) | *dest, 0xab);
-ROP3_HANDLERS(SPDSxax, ((*src ^ *dest) & *pat) ^ *src, 0xac);
-ROP3_HANDLERS(DPSDaoxn, ~(((*dest & *src) | *pat) ^ *dest), 0xad);
-ROP3_HANDLERS(DSPnao, (~*pat & *src) | *dest, 0xae);
-ROP3_HANDLERS(PDSnoa, (~*src | *dest) & *pat, 0xb0);
-ROP3_HANDLERS(PDSPxoxn, ~(((*pat ^ *src) | *dest) ^ *pat), 0xb1);
-ROP3_HANDLERS(SSPxDSxox, ((*src ^ *dest) | (*pat ^ *src)) ^ *src, 0xb2);
-ROP3_HANDLERS(SDPanan, ~(~(*pat & *dest) & *src), 0xb3);
-ROP3_HANDLERS(PSDnax, (~*dest & *src) ^ *pat, 0xb4);
-ROP3_HANDLERS(DPSDoaxn, ~(((*dest | *src) & *pat) ^ *dest), 0xb5);
-ROP3_HANDLERS(DPSDPaoxx, ((*pat & *dest) | *src) ^ *pat ^ *dest, 0xb6);
-ROP3_HANDLERS(SDPxan, ~((*pat ^ *dest) & *src), 0xb7);
-ROP3_HANDLERS(PSDPxax, ((*dest ^ *pat) & *src) ^ *pat, 0xb8);
-ROP3_HANDLERS(DSPDaoxn, ~(((*dest & *pat) | *src) ^ *dest), 0xb9);
-ROP3_HANDLERS(DPSnao, (~*src & *pat) | *dest, 0xba);
-ROP3_HANDLERS(SPDSanax, (~(*src & *dest) & *pat) ^ *src, 0xbc);
-ROP3_HANDLERS(SDxPDxan, ~((*dest ^ *pat) & (*dest ^ *src)), 0xbd);
-ROP3_HANDLERS(DPSxo, (*src ^ *pat) | *dest, 0xbe);
-ROP3_HANDLERS(DPSano, ~(*src & *pat) | *dest, 0xbf);
-ROP3_HANDLERS(SPDSnaoxn, ~(((~*src & *dest) | *pat) ^ *src), 0xc1);
-ROP3_HANDLERS(SPDSonoxn, ~((~(*src | *dest) | *pat) ^ *src), 0xc2);
-ROP3_HANDLERS(SPDnoa, (~*dest | *pat) & *src, 0xc4);
-ROP3_HANDLERS(SPDSxoxn, ~(((*src ^ *dest) | *pat) ^ *src), 0xc5);
-ROP3_HANDLERS(SDPnax, (~*pat & *dest) ^ *src, 0xc6);
-ROP3_HANDLERS(PSDPoaxn, ~(((*pat | *dest) & *src) ^ *pat), 0xc7);
-ROP3_HANDLERS(SDPoa, (*pat | *dest) & *src, 0xc8);
-ROP3_HANDLERS(SPDoxn, ~((*dest | *pat) ^ *src), 0xc9);
-ROP3_HANDLERS(DPSDxax, ((*dest ^ *src) & *pat) ^ *dest, 0xca);
-ROP3_HANDLERS(SPDSaoxn, ~(((*src & *dest) | *pat) ^ *src), 0xcb);
-ROP3_HANDLERS(SDPono, ~(*pat | *dest) | *src, 0xcd);
-ROP3_HANDLERS(SDPnao, (~*pat & *dest) | *src, 0xce);
-ROP3_HANDLERS(PSDnoa, (~*dest | *src) & *pat, 0xd0);
-ROP3_HANDLERS(PSDPxoxn, ~(((*pat ^ *dest) | *src) ^ *pat), 0xd1);
-ROP3_HANDLERS(PDSnax, (~*src & *dest) ^ *pat, 0xd2);
-ROP3_HANDLERS(SPDSoaxn, ~(((*src | *dest) & *pat) ^ *src), 0xd3);
-ROP3_HANDLERS(SSPxPDxax, ((*dest ^ *pat) & (*pat ^ *src)) ^ *src, 0xd4);
-ROP3_HANDLERS(DPSanan, ~(~(*src & *pat) & *dest), 0xd5);
-ROP3_HANDLERS(PSDPSaoxx, ((*src & *pat) | *dest) ^ *src ^ *pat, 0xd6);
-ROP3_HANDLERS(DPSxan, ~((*src ^ *pat) & *dest), 0xd7);
-ROP3_HANDLERS(PDSPxax, ((*pat ^ *src) & *dest) ^ *pat, 0xd8);
-ROP3_HANDLERS(SDPSaoxn, ~(((*src & *pat) | *dest) ^ *src), 0xd9);
-ROP3_HANDLERS(DPSDanax, (~(*dest & *src) & *pat) ^ *dest, 0xda);
-ROP3_HANDLERS(SPxDSxan, ~((*src ^ *dest) & (*pat ^ *src)), 0xdb);
-ROP3_HANDLERS(SPDnao, (~*dest & *pat) | *src, 0xdc);
-ROP3_HANDLERS(SDPxo, (*pat ^ *dest) | *src, 0xde);
-ROP3_HANDLERS(SDPano, ~(*pat & *dest) | *src, 0xdf);
-ROP3_HANDLERS(PDSoa, (*src | *dest) & *pat, 0xe0);
-ROP3_HANDLERS(PDSoxn, ~((*src | *dest) ^ *pat), 0xe1);
-ROP3_HANDLERS(DSPDxax, ((*dest ^ *pat) & *src) ^ *dest, 0xe2);
-ROP3_HANDLERS(PSDPaoxn, ~(((*pat & *dest) | *src) ^ *pat), 0xe3);
-ROP3_HANDLERS(SDPSxax, ((*src ^ *pat) & *dest) ^ *src, 0xe4);
-ROP3_HANDLERS(PDSPaoxn, ~(((*pat & *src) | *dest) ^ *pat), 0xe5);
-ROP3_HANDLERS(SDPSanax, (~(*src & *pat) & *dest) ^ *src, 0xe6);
-ROP3_HANDLERS(SPxPDxan, ~((*dest ^ *pat) & (*pat ^ *src)), 0xe7);
-ROP3_HANDLERS(SSPxDSxax, ((*src ^ *dest) & (*pat ^ *src)) ^ *src, 0xe8);
-ROP3_HANDLERS(DSPDSanaxxn, ~((~(*src & *dest) & *pat) ^ *src ^ *dest), 0xe9);
-ROP3_HANDLERS(DPSao, (*src & *pat) | *dest, 0xea);
-ROP3_HANDLERS(DPSxno, ~(*src ^ *pat) | *dest, 0xeb);
-ROP3_HANDLERS(SDPao, (*pat & *dest) | *src, 0xec);
-ROP3_HANDLERS(SDPxno, ~(*pat ^ *dest) | *src, 0xed);
-ROP3_HANDLERS(SDPnoo, ~*pat | *dest | *src, 0xef);
-ROP3_HANDLERS(PDSono, ~(*src | *dest) | *pat, 0xf1);
-ROP3_HANDLERS(PDSnao, (~*src & *dest) | *pat, 0xf2);
-ROP3_HANDLERS(PSDnao, (~*dest & *src) | *pat, 0xf4);
-ROP3_HANDLERS(PDSxo, (*src ^ *dest) | *pat, 0xf6);
-ROP3_HANDLERS(PDSano, ~(*src & *dest) | *pat, 0xf7);
-ROP3_HANDLERS(PDSao, (*src & *dest) | *pat, 0xf8);
-ROP3_HANDLERS(PDSxno, ~(*src ^ *dest) | *pat, 0xf9);
-ROP3_HANDLERS(DPSnoo, ~*src | *pat | *dest, 0xfb);
-ROP3_HANDLERS(PSDnoo, ~*dest | *src | *pat, 0xfd);
-ROP3_HANDLERS(DPSoo, *src | *pat | *dest, 0xfe);
-
-
-#define ROP3_FILL_HANDLERS(op, index)                       \
-    rop3_with_pattern_handlers_32[index] = rop3_handle_p32_##op; \
-    rop3_with_pattern_handlers_16[index] = rop3_handle_p16_##op; \
-    rop3_with_color_handlers_32[index] = rop3_handle_c32_##op;   \
-    rop3_with_color_handlers_16[index] = rop3_handle_c16_##op;   \
-    rop3_test_handlers_32[index] = rop3_test32_##op;             \
-    rop3_test_handlers_16[index] = rop3_test16_##op;
-
-void rop3_init(void)
-{
-    static int need_init = 1;
-    int i;
-
-    if (!need_init) {
-        return;
-    }
-    need_init = 0;
-
-    for (i = 0; i < ROP3_NUM_OPS; i++) {
-        rop3_with_pattern_handlers_32[i] = default_rop3_with_pattern_handler;
-        rop3_with_pattern_handlers_16[i] = default_rop3_with_pattern_handler;
-        rop3_with_color_handlers_32[i] = default_rop3_withe_color_handler;
-        rop3_with_color_handlers_16[i] = default_rop3_withe_color_handler;
-        rop3_test_handlers_32[i] = default_rop3_test_handler;
-        rop3_test_handlers_16[i] = default_rop3_test_handler;
-    }
-
-    ROP3_FILL_HANDLERS(DPSoon, 0x01);
-    ROP3_FILL_HANDLERS(DPSona, 0x02);
-    ROP3_FILL_HANDLERS(SDPona, 0x04);
-    ROP3_FILL_HANDLERS(PDSxnon, 0x06);
-    ROP3_FILL_HANDLERS(PDSaon, 0x07);
-    ROP3_FILL_HANDLERS(SDPnaa, 0x08);
-    ROP3_FILL_HANDLERS(PDSxon, 0x09);
-    ROP3_FILL_HANDLERS(PSDnaon, 0x0b);
-    ROP3_FILL_HANDLERS(PDSnaon, 0x0d);
-    ROP3_FILL_HANDLERS(PDSonon, 0x0e);
-    ROP3_FILL_HANDLERS(PDSona, 0x10);
-    ROP3_FILL_HANDLERS(SDPxnon, 0x12);
-    ROP3_FILL_HANDLERS(SDPaon, 0x13);
-    ROP3_FILL_HANDLERS(DPSxnon, 0x14);
-    ROP3_FILL_HANDLERS(DPSaon, 0x15);
-    ROP3_FILL_HANDLERS(PSDPSanaxx, 0x16);
-    ROP3_FILL_HANDLERS(SSPxDSxaxn, 0x17);
-    ROP3_FILL_HANDLERS(SPxPDxa, 0x18);
-    ROP3_FILL_HANDLERS(SDPSanaxn, 0x19);
-    ROP3_FILL_HANDLERS(PDSPaox, 0x1a);
-    ROP3_FILL_HANDLERS(SDPSxaxn, 0x1b);
-    ROP3_FILL_HANDLERS(PSDPaox, 0x1c);
-    ROP3_FILL_HANDLERS(DSPDxaxn, 0x1d);
-    ROP3_FILL_HANDLERS(PDSox, 0x1e);
-    ROP3_FILL_HANDLERS(PDSoan, 0x1f);
-    ROP3_FILL_HANDLERS(DPSnaa, 0x20);
-    ROP3_FILL_HANDLERS(SDPxon, 0x21);
-    ROP3_FILL_HANDLERS(SPDnaon, 0x23);
-    ROP3_FILL_HANDLERS(SPxDSxa, 0x24);
-    ROP3_FILL_HANDLERS(PDSPanaxn, 0x25);
-    ROP3_FILL_HANDLERS(SDPSaox, 0x26);
-    ROP3_FILL_HANDLERS(SDPSxnox, 0x27);
-    ROP3_FILL_HANDLERS(DPSxa, 0x28);
-    ROP3_FILL_HANDLERS(PSDPSaoxxn, 0x29);
-    ROP3_FILL_HANDLERS(DPSana, 0x2a);
-    ROP3_FILL_HANDLERS(SSPxPDxaxn, 0x2b);
-    ROP3_FILL_HANDLERS(SPDSoax, 0x2c);
-    ROP3_FILL_HANDLERS(PSDnox, 0x2d);
-    ROP3_FILL_HANDLERS(PSDPxox, 0x2e);
-    ROP3_FILL_HANDLERS(PSDnoan, 0x2f);
-    ROP3_FILL_HANDLERS(SDPnaon, 0x31);
-    ROP3_FILL_HANDLERS(SDPSoox, 0x32);
-    ROP3_FILL_HANDLERS(SPDSaox, 0x34);
-    ROP3_FILL_HANDLERS(SPDSxnox, 0x35);
-    ROP3_FILL_HANDLERS(SDPox, 0x36);
-    ROP3_FILL_HANDLERS(SDPoan, 0x37);
-    ROP3_FILL_HANDLERS(PSDPoax, 0x38);
-    ROP3_FILL_HANDLERS(SPDnox, 0x39);
-    ROP3_FILL_HANDLERS(SPDSxox, 0x3a);
-    ROP3_FILL_HANDLERS(SPDnoan, 0x3b);
-    ROP3_FILL_HANDLERS(SPDSonox, 0x3d);
-    ROP3_FILL_HANDLERS(SPDSnaox, 0x3e);
-    ROP3_FILL_HANDLERS(PSDnaa, 0x40);
-    ROP3_FILL_HANDLERS(DPSxon, 0x41);
-    ROP3_FILL_HANDLERS(SDxPDxa, 0x42);
-    ROP3_FILL_HANDLERS(SPDSanaxn, 0x43);
-    ROP3_FILL_HANDLERS(DPSnaon, 0x45);
-    ROP3_FILL_HANDLERS(DSPDaox, 0x46);
-    ROP3_FILL_HANDLERS(PSDPxaxn, 0x47);
-    ROP3_FILL_HANDLERS(SDPxa, 0x48);
-    ROP3_FILL_HANDLERS(PDSPDaoxxn, 0x49);
-    ROP3_FILL_HANDLERS(DPSDoax, 0x4a);
-    ROP3_FILL_HANDLERS(PDSnox, 0x4b);
-    ROP3_FILL_HANDLERS(SDPana, 0x4c);
-    ROP3_FILL_HANDLERS(SSPxDSxoxn, 0x4d);
-    ROP3_FILL_HANDLERS(PDSPxox, 0x4e);
-    ROP3_FILL_HANDLERS(PDSnoan, 0x4f);
-    ROP3_FILL_HANDLERS(DSPnaon, 0x51);
-    ROP3_FILL_HANDLERS(DPSDaox, 0x52);
-    ROP3_FILL_HANDLERS(SPDSxaxn, 0x53);
-    ROP3_FILL_HANDLERS(DPSonon, 0x54);
-    ROP3_FILL_HANDLERS(DPSox, 0x56);
-    ROP3_FILL_HANDLERS(DPSoan, 0x57);
-    ROP3_FILL_HANDLERS(PDSPoax, 0x58);
-    ROP3_FILL_HANDLERS(DPSnox, 0x59);
-    ROP3_FILL_HANDLERS(DPSDonox, 0x5b);
-    ROP3_FILL_HANDLERS(DPSDxox, 0x5c);
-    ROP3_FILL_HANDLERS(DPSnoan, 0x5d);
-    ROP3_FILL_HANDLERS(DPSDnaox, 0x5e);
-    ROP3_FILL_HANDLERS(PDSxa, 0x60);
-    ROP3_FILL_HANDLERS(DSPDSaoxxn, 0x61);
-    ROP3_FILL_HANDLERS(DSPDoax, 0x62);
-    ROP3_FILL_HANDLERS(SDPnox, 0x63);
-    ROP3_FILL_HANDLERS(SDPSoax, 0x64);
-    ROP3_FILL_HANDLERS(DSPnox, 0x65);
-    ROP3_FILL_HANDLERS(SDPSonox, 0x67);
-    ROP3_FILL_HANDLERS(DSPDSonoxxn, 0x68);
-    ROP3_FILL_HANDLERS(PDSxxn, 0x69);
-    ROP3_FILL_HANDLERS(DPSax, 0x6a);
-    ROP3_FILL_HANDLERS(PSDPSoaxxn, 0x6b);
-    ROP3_FILL_HANDLERS(SDPax, 0x6c);
-    ROP3_FILL_HANDLERS(PDSPDoaxxn, 0x6d);
-    ROP3_FILL_HANDLERS(SDPSnoax, 0x6e);
-    ROP3_FILL_HANDLERS(PDSxnan, 0x6f);
-    ROP3_FILL_HANDLERS(PDSana, 0x70);
-    ROP3_FILL_HANDLERS(SSDxPDxaxn, 0x71);
-    ROP3_FILL_HANDLERS(SDPSxox, 0x72);
-    ROP3_FILL_HANDLERS(SDPnoan, 0x73);
-    ROP3_FILL_HANDLERS(DSPDxox, 0x74);
-    ROP3_FILL_HANDLERS(DSPnoan, 0x75);
-    ROP3_FILL_HANDLERS(SDPSnaox, 0x76);
-    ROP3_FILL_HANDLERS(PDSax, 0x78);
-    ROP3_FILL_HANDLERS(DSPDSoaxxn, 0x79);
-    ROP3_FILL_HANDLERS(DPSDnoax, 0x7a);
-    ROP3_FILL_HANDLERS(SDPxnan, 0x7b);
-    ROP3_FILL_HANDLERS(SPDSnoax, 0x7c);
-    ROP3_FILL_HANDLERS(DPSxnan, 0x7d);
-    ROP3_FILL_HANDLERS(SPxDSxo, 0x7e);
-    ROP3_FILL_HANDLERS(DPSaan, 0x7f);
-    ROP3_FILL_HANDLERS(DPSaa, 0x80);
-    ROP3_FILL_HANDLERS(SPxDSxon, 0x81);
-    ROP3_FILL_HANDLERS(DPSxna, 0x82);
-    ROP3_FILL_HANDLERS(SPDSnoaxn, 0x83);
-    ROP3_FILL_HANDLERS(SDPxna, 0x84);
-    ROP3_FILL_HANDLERS(PDSPnoaxn, 0x85);
-    ROP3_FILL_HANDLERS(DSPDSoaxx, 0x86);
-    ROP3_FILL_HANDLERS(PDSaxn, 0x87);
-    ROP3_FILL_HANDLERS(SDPSnaoxn, 0x89);
-    ROP3_FILL_HANDLERS(DSPnoa, 0x8a);
-    ROP3_FILL_HANDLERS(DSPDxoxn, 0x8b);
-    ROP3_FILL_HANDLERS(SDPnoa, 0x8c);
-    ROP3_FILL_HANDLERS(SDPSxoxn, 0x8d);
-    ROP3_FILL_HANDLERS(SSDxPDxax, 0x8e);
-    ROP3_FILL_HANDLERS(PDSanan, 0x8f);
-    ROP3_FILL_HANDLERS(PDSxna, 0x90);
-    ROP3_FILL_HANDLERS(SDPSnoaxn, 0x91);
-    ROP3_FILL_HANDLERS(DPSDPoaxx, 0x92);
-    ROP3_FILL_HANDLERS(SPDaxn, 0x93);
-    ROP3_FILL_HANDLERS(PSDPSoaxx, 0x94);
-    ROP3_FILL_HANDLERS(DPSaxn, 0x95);
-    ROP3_FILL_HANDLERS(DPSxx, 0x96);
-    ROP3_FILL_HANDLERS(PSDPSonoxx, 0x97);
-    ROP3_FILL_HANDLERS(SDPSonoxn, 0x98);
-    ROP3_FILL_HANDLERS(DPSnax, 0x9a);
-    ROP3_FILL_HANDLERS(SDPSoaxn, 0x9b);
-    ROP3_FILL_HANDLERS(SPDnax, 0x9c);
-    ROP3_FILL_HANDLERS(DSPDoaxn, 0x9d);
-    ROP3_FILL_HANDLERS(DSPDSaoxx, 0x9e);
-    ROP3_FILL_HANDLERS(PDSxan, 0x9f);
-    ROP3_FILL_HANDLERS(PDSPnaoxn, 0xa1);
-    ROP3_FILL_HANDLERS(DPSnoa, 0xa2);
-    ROP3_FILL_HANDLERS(DPSDxoxn, 0xa3);
-    ROP3_FILL_HANDLERS(PDSPonoxn, 0xa4);
-    ROP3_FILL_HANDLERS(DSPnax, 0xa6);
-    ROP3_FILL_HANDLERS(PDSPoaxn, 0xa7);
-    ROP3_FILL_HANDLERS(DPSoa, 0xa8);
-    ROP3_FILL_HANDLERS(DPSoxn, 0xa9);
-    ROP3_FILL_HANDLERS(DPSono, 0xab);
-    ROP3_FILL_HANDLERS(SPDSxax, 0xac);
-    ROP3_FILL_HANDLERS(DPSDaoxn, 0xad);
-    ROP3_FILL_HANDLERS(DSPnao, 0xae);
-    ROP3_FILL_HANDLERS(PDSnoa, 0xb0);
-    ROP3_FILL_HANDLERS(PDSPxoxn, 0xb1);
-    ROP3_FILL_HANDLERS(SSPxDSxox, 0xb2);
-    ROP3_FILL_HANDLERS(SDPanan, 0xb3);
-    ROP3_FILL_HANDLERS(PSDnax, 0xb4);
-    ROP3_FILL_HANDLERS(DPSDoaxn, 0xb5);
-    ROP3_FILL_HANDLERS(DPSDPaoxx, 0xb6);
-    ROP3_FILL_HANDLERS(SDPxan, 0xb7);
-    ROP3_FILL_HANDLERS(PSDPxax, 0xb8);
-    ROP3_FILL_HANDLERS(DSPDaoxn, 0xb9);
-    ROP3_FILL_HANDLERS(DPSnao, 0xba);
-    ROP3_FILL_HANDLERS(SPDSanax, 0xbc);
-    ROP3_FILL_HANDLERS(SDxPDxan, 0xbd);
-    ROP3_FILL_HANDLERS(DPSxo, 0xbe);
-    ROP3_FILL_HANDLERS(DPSano, 0xbf);
-    ROP3_FILL_HANDLERS(SPDSnaoxn, 0xc1);
-    ROP3_FILL_HANDLERS(SPDSonoxn, 0xc2);
-    ROP3_FILL_HANDLERS(SPDnoa, 0xc4);
-    ROP3_FILL_HANDLERS(SPDSxoxn, 0xc5);
-    ROP3_FILL_HANDLERS(SDPnax, 0xc6);
-    ROP3_FILL_HANDLERS(PSDPoaxn, 0xc7);
-    ROP3_FILL_HANDLERS(SDPoa, 0xc8);
-    ROP3_FILL_HANDLERS(SPDoxn, 0xc9);
-    ROP3_FILL_HANDLERS(DPSDxax, 0xca);
-    ROP3_FILL_HANDLERS(SPDSaoxn, 0xcb);
-    ROP3_FILL_HANDLERS(SDPono, 0xcd);
-    ROP3_FILL_HANDLERS(SDPnao, 0xce);
-    ROP3_FILL_HANDLERS(PSDnoa, 0xd0);
-    ROP3_FILL_HANDLERS(PSDPxoxn, 0xd1);
-    ROP3_FILL_HANDLERS(PDSnax, 0xd2);
-    ROP3_FILL_HANDLERS(SPDSoaxn, 0xd3);
-    ROP3_FILL_HANDLERS(SSPxPDxax, 0xd4);
-    ROP3_FILL_HANDLERS(DPSanan, 0xd5);
-    ROP3_FILL_HANDLERS(PSDPSaoxx, 0xd6);
-    ROP3_FILL_HANDLERS(DPSxan, 0xd7);
-    ROP3_FILL_HANDLERS(PDSPxax, 0xd8);
-    ROP3_FILL_HANDLERS(SDPSaoxn, 0xd9);
-    ROP3_FILL_HANDLERS(DPSDanax, 0xda);
-    ROP3_FILL_HANDLERS(SPxDSxan, 0xdb);
-    ROP3_FILL_HANDLERS(SPDnao, 0xdc);
-    ROP3_FILL_HANDLERS(SDPxo, 0xde);
-    ROP3_FILL_HANDLERS(SDPano, 0xdf);
-    ROP3_FILL_HANDLERS(PDSoa, 0xe0);
-    ROP3_FILL_HANDLERS(PDSoxn, 0xe1);
-    ROP3_FILL_HANDLERS(DSPDxax, 0xe2);
-    ROP3_FILL_HANDLERS(PSDPaoxn, 0xe3);
-    ROP3_FILL_HANDLERS(SDPSxax, 0xe4);
-    ROP3_FILL_HANDLERS(PDSPaoxn, 0xe5);
-    ROP3_FILL_HANDLERS(SDPSanax, 0xe6);
-    ROP3_FILL_HANDLERS(SPxPDxan, 0xe7);
-    ROP3_FILL_HANDLERS(SSPxDSxax, 0xe8);
-    ROP3_FILL_HANDLERS(DSPDSanaxxn, 0xe9);
-    ROP3_FILL_HANDLERS(DPSao, 0xea);
-    ROP3_FILL_HANDLERS(DPSxno, 0xeb);
-    ROP3_FILL_HANDLERS(SDPao, 0xec);
-    ROP3_FILL_HANDLERS(SDPxno, 0xed);
-    ROP3_FILL_HANDLERS(SDPnoo, 0xef);
-    ROP3_FILL_HANDLERS(PDSono, 0xf1);
-    ROP3_FILL_HANDLERS(PDSnao, 0xf2);
-    ROP3_FILL_HANDLERS(PSDnao, 0xf4);
-    ROP3_FILL_HANDLERS(PDSxo, 0xf6);
-    ROP3_FILL_HANDLERS(PDSano, 0xf7);
-    ROP3_FILL_HANDLERS(PDSao, 0xf8);
-    ROP3_FILL_HANDLERS(PDSxno, 0xf9);
-    ROP3_FILL_HANDLERS(DPSnoo, 0xfb);
-    ROP3_FILL_HANDLERS(PSDnoo, 0xfd);
-    ROP3_FILL_HANDLERS(DPSoo, 0xfe);
-
-    for (i = 0; i < ROP3_NUM_OPS; i++) {
-        rop3_test_handlers_32[i]();
-        rop3_test_handlers_16[i]();
-    }
-}
-
-void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
-                          pixman_image_t *p, SpicePoint *pat_pos)
-{
-    int bpp;
-
-    bpp = spice_pixman_image_get_bpp(d);
-    ASSERT (bpp == spice_pixman_image_get_bpp(s));
-    ASSERT (bpp == spice_pixman_image_get_bpp(p));
-
-    if (bpp == 32) {
-        rop3_with_pattern_handlers_32[rop3](d, s, src_pos, p, pat_pos);
-    } else {
-        rop3_with_pattern_handlers_16[rop3](d, s, src_pos, p, pat_pos);
-    }
-}
-
-void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
-                        uint32_t rgb)
-{
-    int bpp;
-
-    bpp = spice_pixman_image_get_bpp(d);
-    ASSERT (bpp == spice_pixman_image_get_bpp(s));
-
-    if (bpp == 32) {
-        rop3_with_color_handlers_32[rop3](d, s, src_pos, rgb);
-    } else {
-        rop3_with_color_handlers_16[rop3](d, s, src_pos, rgb);
-    }
-}
diff --git a/common/rop3.h b/common/rop3.h
deleted file mode 100644
index cbfa940..0000000
--- a/common/rop3.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_ROP3
-#define _H_ROP3
-
-#include <stdint.h>
-
-#include "draw.h"
-#include "pixman_utils.h"
-
-void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
-                          pixman_image_t *p, SpicePoint *pat_pos);
-void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
-                        uint32_t rgb);
-
-void rop3_init(void);
-#endif
-
diff --git a/common/ssl_verify.c b/common/ssl_verify.c
deleted file mode 100644
index b19a323..0000000
--- a/common/ssl_verify.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2011 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "mem.h"
-#include "ssl_verify.h"
-
-#ifndef WIN32
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-#include <ctype.h>
-#include <string.h>
-
-#ifndef SPICE_DEBUG
-# define SPICE_DEBUG(format, ...)
-#endif
-
-#ifdef WIN32
-static int inet_aton(const char* ip, struct in_addr* in_addr)
-{
-    unsigned long addr = inet_addr(ip);
-
-    if (addr == INADDR_NONE) {
-        return 0;
-    }
-    in_addr->S_un.S_addr = addr;
-    return 1;
-}
-#endif
-
-static int verify_pubkey(X509* cert, const char *key, size_t key_size)
-{
-    EVP_PKEY* cert_pubkey = NULL;
-    EVP_PKEY* orig_pubkey = NULL;
-    BIO* bio = NULL;
-    int ret = 0;
-
-    if (!key || key_size == 0)
-        return 0;
-
-    if (!cert) {
-        SPICE_DEBUG("warning: no cert!");
-        return 0;
-    }
-
-    cert_pubkey = X509_get_pubkey(cert);
-    if (!cert_pubkey) {
-        SPICE_DEBUG("warning: reading public key from certificate failed");
-        goto finish;
-    }
-
-    bio = BIO_new_mem_buf((void*)key, key_size);
-    if (!bio) {
-        SPICE_DEBUG("creating BIO failed");
-        goto finish;
-    }
-
-    orig_pubkey = d2i_PUBKEY_bio(bio, NULL);
-    if (!orig_pubkey) {
-        SPICE_DEBUG("reading pubkey from bio failed");
-        goto finish;
-    }
-
-    ret = EVP_PKEY_cmp(orig_pubkey, cert_pubkey);
-
-    if (ret == 1) {
-        SPICE_DEBUG("public keys match");
-    } else if (ret == 0) {
-        SPICE_DEBUG("public keys mismatch");
-    } else {
-        SPICE_DEBUG("public keys types mismatch");
-    }
-
-finish:
-    if (bio)
-        BIO_free(bio);
-
-    if (orig_pubkey)
-        EVP_PKEY_free(orig_pubkey);
-
-    if (cert_pubkey)
-        EVP_PKEY_free(cert_pubkey);
-
-    return ret;
-}
-
-/* from gnutls
- * compare hostname against certificate, taking account of wildcards
- * return 1 on success or 0 on error
- *
- * note: certnamesize is required as X509 certs can contain embedded NULs in
- * the strings such as CN or subjectAltName
- */
-static int _gnutls_hostname_compare(const char *certname,
-                                    size_t certnamesize, const char *hostname)
-{
-    /* find the first different character */
-    for (; *certname && *hostname && toupper (*certname) == toupper (*hostname);
-         certname++, hostname++, certnamesize--)
-        ;
-
-    /* the strings are the same */
-    if (certnamesize == 0 && *hostname == '\0')
-        return 1;
-
-    if (*certname == '*')
-        {
-            /* a wildcard certificate */
-
-            certname++;
-            certnamesize--;
-
-            while (1)
-                {
-                    /* Use a recursive call to allow multiple wildcards */
-                    if (_gnutls_hostname_compare (certname, certnamesize, hostname))
-                        return 1;
-
-                    /* wildcards are only allowed to match a single domain
-                       component or component fragment */
-                    if (*hostname == '\0' || *hostname == '.')
-                        break;
-                    hostname++;
-                }
-
-            return 0;
-        }
-
-    return 0;
-}
-
-/**
- * From gnutls and spice red_peer.c
- * TODO: switch to gnutls and get rid of this
- *
- * This function will check if the given certificate's subject matches
- * the given hostname.  This is a basic implementation of the matching
- * described in RFC2818 (HTTPS), which takes into account wildcards,
- * and the DNSName/IPAddress subject alternative name PKIX extension.
- *
- * Returns: 1 for a successful match, and 0 on failure.
- **/
-static int verify_hostname(X509* cert, const char *hostname)
-{
-    GENERAL_NAMES* subject_alt_names;
-    int found_dns_name = 0;
-    struct in_addr addr;
-    int addr_len = 0;
-    int cn_match = 0;
-
-    if (!cert) {
-        SPICE_DEBUG("warning: no cert!");
-        return 0;
-    }
-
-    // only IpV4 supported
-    if (inet_aton(hostname, &addr)) {
-        addr_len = sizeof(struct in_addr);
-    }
-
-    /* try matching against:
-     *  1) a DNS name as an alternative name (subjectAltName) extension
-     *     in the certificate
-     *  2) the common name (CN) in the certificate
-     *
-     *  either of these may be of the form: *.domain.tld
-     *
-     *  only try (2) if there is no subjectAltName extension of
-     *  type dNSName
-     */
-
-    /* Check through all included subjectAltName extensions, comparing
-     * against all those of type dNSName.
-     */
-    subject_alt_names = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
-
-    if (subject_alt_names) {
-        int num_alts = sk_GENERAL_NAME_num(subject_alt_names);
-        int i;
-        for (i = 0; i < num_alts; i++) {
-            const GENERAL_NAME* name = sk_GENERAL_NAME_value(subject_alt_names, i);
-            if (name->type == GEN_DNS) {
-                found_dns_name = 1;
-                if (_gnutls_hostname_compare((char *)ASN1_STRING_data(name->d.dNSName),
-                                             ASN1_STRING_length(name->d.dNSName),
-                                             hostname)) {
-                    SPICE_DEBUG("alt name match=%s", ASN1_STRING_data(name->d.dNSName));
-                    GENERAL_NAMES_free(subject_alt_names);
-                    return 1;
-                }
-            } else if (name->type == GEN_IPADD) {
-                int alt_ip_len = ASN1_STRING_length(name->d.iPAddress);
-                found_dns_name = 1;
-                if ((addr_len == alt_ip_len)&&
-                    !memcmp(ASN1_STRING_data(name->d.iPAddress), &addr, addr_len)) {
-                    SPICE_DEBUG("alt name IP match=%s",
-                                inet_ntoa(*((struct in_addr*)ASN1_STRING_data(name->d.dNSName))));
-                    GENERAL_NAMES_free(subject_alt_names);
-                    return 1;
-                }
-            }
-        }
-        GENERAL_NAMES_free(subject_alt_names);
-    }
-
-    if (found_dns_name) {
-        SPICE_DEBUG("warning: SubjectAltName mismatch");
-        return 0;
-    }
-
-    /* extracting commonNames */
-    X509_NAME* subject = X509_get_subject_name(cert);
-    if (subject) {
-        int pos = -1;
-        X509_NAME_ENTRY* cn_entry;
-        ASN1_STRING* cn_asn1;
-
-        while ((pos = X509_NAME_get_index_by_NID(subject, NID_commonName, pos)) != -1) {
-            cn_entry = X509_NAME_get_entry(subject, pos);
-            if (!cn_entry) {
-                continue;
-            }
-            cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
-            if (!cn_asn1) {
-                continue;
-            }
-
-            if (_gnutls_hostname_compare((char*)ASN1_STRING_data(cn_asn1),
-                                         ASN1_STRING_length(cn_asn1),
-                                         hostname)) {
-                SPICE_DEBUG("common name match=%s", (char*)ASN1_STRING_data(cn_asn1));
-                cn_match = 1;
-                break;
-            }
-        }
-    }
-
-    if (!cn_match) {
-        SPICE_DEBUG("warning: common name mismatch");
-    }
-
-    return cn_match;
-}
-
-static X509_NAME* subject_to_x509_name(const char *subject, int *nentries)
-{
-    X509_NAME* in_subject;
-    const char *p;
-    char *key, *val, *k, *v = NULL;
-    int escape;
-    enum {
-        KEY,
-        VALUE
-    } state;
-
-    key = (char*)alloca(strlen(subject));
-    val = (char*)alloca(strlen(subject));
-    in_subject = X509_NAME_new();
-
-    if (!in_subject || !key || !val) {
-        SPICE_DEBUG("failed to allocate");
-        return NULL;
-    }
-
-    *nentries = 0;
-
-    k = key;
-    state = KEY;
-    for (p = subject;; ++p) {
-        escape = 0;
-        if (*p == '\\') {
-            ++p;
-            if (*p != '\\' && *p != ',') {
-                SPICE_DEBUG("Invalid character after \\");
-                goto fail;
-            }
-            escape = 1;
-        }
-
-        switch (state) {
-        case KEY:
-            if (*p == 0) {
-                if (k == key) /* empty key */
-                    goto success;
-                goto fail;
-            } else if (*p == '=' && !escape) {
-                state = VALUE;
-                *k = 0;
-                v = val;
-            } else
-                *k++ = *p;
-            break;
-        case VALUE:
-            if (*p == 0 || (*p == ',' && !escape)) {
-                if (v == val) /* empty value */
-                    goto fail;
-
-                *v = 0;
-
-                if (!X509_NAME_add_entry_by_txt(in_subject, key,
-                                                MBSTRING_UTF8,
-                                                (const unsigned char*)val,
-                                                strlen(val), -1, 0)) {
-                    SPICE_DEBUG("warning: failed to add entry %s=%s to X509_NAME",
-                                key, val);
-                    goto fail;
-                }
-                *nentries += 1;
-
-                if (*p == 0)
-                    goto success;
-
-                state = KEY;
-                k = key;
-            } else
-                *v++ = *p;
-        }
-    }
-
-success:
-    return in_subject;
-
-fail:
-    if (in_subject)
-        X509_NAME_free(in_subject);
-
-    return NULL;
-}
-
-static int verify_subject(X509* cert, SpiceOpenSSLVerify* verify)
-{
-    X509_NAME *cert_subject = NULL;
-    int ret;
-    int in_entries;
-
-    if (!cert) {
-        SPICE_DEBUG("warning: no cert!");
-        return 0;
-    }
-
-    cert_subject = X509_get_subject_name(cert);
-    if (!cert_subject) {
-        SPICE_DEBUG("warning: reading certificate subject failed");
-        return 0;
-    }
-
-    if (!verify->in_subject) {
-        verify->in_subject = subject_to_x509_name(verify->subject, &in_entries);
-        if (!verify->in_subject) {
-            SPICE_DEBUG("warning: no in_subject!");
-            return 0;
-        }
-    }
-
-    /* Note: this check is redundant with the pre-condition in X509_NAME_cmp */
-    if (X509_NAME_entry_count(cert_subject) != in_entries) {
-        SPICE_DEBUG("subject mismatch: #entries cert=%d, input=%d",
-            X509_NAME_entry_count(cert_subject), in_entries);
-        return 0;
-    }
-
-    ret = X509_NAME_cmp(cert_subject, verify->in_subject);
-
-    if (ret == 0) {
-        SPICE_DEBUG("subjects match");
-    } else {
-        SPICE_DEBUG("subjects mismatch");
-    }
-
-    return !ret;
-}
-
-static int openssl_verify(int preverify_ok, X509_STORE_CTX *ctx)
-{
-    int depth;
-    SpiceOpenSSLVerify *v;
-    SSL *ssl;
-    X509* cert;
-
-    ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
-    v = (SpiceOpenSSLVerify*)SSL_get_app_data(ssl);
-
-    depth = X509_STORE_CTX_get_error_depth(ctx);
-    if (depth > 0) {
-        if (!preverify_ok) {
-            SPICE_DEBUG("openssl verify failed at depth=%d", depth);
-            v->all_preverify_ok = 0;
-            return 0;
-        } else
-            return 1;
-    }
-
-    /* depth == 0 */
-    cert = X509_STORE_CTX_get_current_cert(ctx);
-    if (!cert) {
-        SPICE_DEBUG("failed to get server certificate");
-        return 0;
-    }
-
-    if (v->verifyop & SPICE_SSL_VERIFY_OP_PUBKEY &&
-        verify_pubkey(cert, v->pubkey, v->pubkey_size))
-        return 1;
-
-    if (!v->all_preverify_ok || !preverify_ok)
-        return 0;
-
-    if (v->verifyop & SPICE_SSL_VERIFY_OP_HOSTNAME &&
-        verify_hostname(cert, v->hostname))
-        return 1;
-
-    if (v->verifyop & SPICE_SSL_VERIFY_OP_SUBJECT &&
-        verify_subject(cert, v))
-        return 1;
-
-    return 0;
-}
-
-SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
-                                             const char *hostname,
-                                             const char *pubkey, size_t pubkey_size,
-                                             const char *subject)
-{
-    SpiceOpenSSLVerify *v;
-
-    if (!verifyop)
-        return NULL;
-
-    v = spice_new0(SpiceOpenSSLVerify, 1);
-
-    v->ssl              = ssl;
-    v->verifyop         = verifyop;
-    v->hostname         = spice_strdup(hostname);
-    v->pubkey           = (char*)spice_memdup(pubkey, pubkey_size);
-    v->pubkey_size      = pubkey_size;
-    v->subject          = spice_strdup(subject);
-
-    v->all_preverify_ok = 1;
-
-    SSL_set_app_data(ssl, v);
-    SSL_set_verify(ssl,
-                   SSL_VERIFY_PEER, openssl_verify);
-
-    return v;
-}
-
-void spice_openssl_verify_free(SpiceOpenSSLVerify* verify)
-{
-    if (!verify)
-        return;
-
-    free(verify->pubkey);
-    free(verify->subject);
-    free(verify->hostname);
-
-    if (verify->in_subject)
-        X509_NAME_free(verify->in_subject);
-
-    if (verify->ssl)
-        SSL_set_app_data(verify->ssl, NULL);
-    free(verify);
-}
diff --git a/common/ssl_verify.h b/common/ssl_verify.h
deleted file mode 100644
index 6922c56..0000000
--- a/common/ssl_verify.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2011 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __SSL_VERIFY_H
-#define __SSL_VERIFY_H
-
-#include "ring.h"
-
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#ifdef X509_NAME
-/* wincrypt.h has already a different define... */
-#undef X509_NAME
-#endif
-#include <openssl/x509v3.h>
-
-typedef enum {
-  SPICE_SSL_VERIFY_OP_NONE     = 0,
-  SPICE_SSL_VERIFY_OP_PUBKEY   = (1 << 0),
-  SPICE_SSL_VERIFY_OP_HOSTNAME = (1 << 1),
-  SPICE_SSL_VERIFY_OP_SUBJECT  = (1 << 2),
-} SPICE_SSL_VERIFY_OP;
-
-typedef struct {
-    SSL                 *ssl;
-    SPICE_SSL_VERIFY_OP verifyop;
-    int                 all_preverify_ok;
-    char                *hostname;
-    char                *pubkey;
-    size_t              pubkey_size;
-    char                *subject;
-    X509_NAME           *in_subject;
-} SpiceOpenSSLVerify;
-
-SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
-                                             const char *hostname,
-                                             const char *pubkey, size_t pubkey_size,
-                                             const char *subject);
-void spice_openssl_verify_free(SpiceOpenSSLVerify* verify);
-
-#endif
diff --git a/common/sw_canvas.c b/common/sw_canvas.c
deleted file mode 100644
index 34ca910..0000000
--- a/common/sw_canvas.c
+++ /dev/null
@@ -1,1321 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <math.h>
-#include "sw_canvas.h"
-#define CANVAS_USE_PIXMAN
-#define CANVAS_SINGLE_INSTANCE
-#include "canvas_base.c"
-#include "rect.h"
-#include "region.h"
-#include "pixman_utils.h"
-
-typedef struct SwCanvas SwCanvas;
-
-struct SwCanvas {
-    CanvasBase base;
-    uint32_t *private_data;
-    int private_data_size;
-    pixman_image_t *image;
-};
-
-static pixman_image_t *canvas_get_pixman_brush(SwCanvas *canvas,
-                                               SpiceBrush *brush)
-{
-    switch (brush->type) {
-    case SPICE_BRUSH_TYPE_SOLID: {
-        uint32_t color = brush->u.color;
-        pixman_color_t c;
-
-        c.blue = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
-        color >>= canvas->base.color_shift;
-        c.green = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
-        color >>= canvas->base.color_shift;
-        c.red = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
-        c.alpha = 0xffff;
-
-        return pixman_image_create_solid_fill(&c);
-    }
-    case SPICE_BRUSH_TYPE_PATTERN: {
-        SwCanvas *surface_canvas;
-        pixman_image_t* surface;
-        pixman_transform_t t;
-
-        surface_canvas = (SwCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
-        if (surface_canvas) {
-            surface = surface_canvas->image;
-            surface = pixman_image_ref(surface);
-        } else {
-            surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
-        }
-        pixman_transform_init_translate(&t,
-                                        pixman_int_to_fixed(-brush->u.pattern.pos.x),
-                                        pixman_int_to_fixed(-brush->u.pattern.pos.y));
-        pixman_image_set_transform(surface, &t);
-        pixman_image_set_repeat(surface, PIXMAN_REPEAT_NORMAL);
-        return surface;
-    }
-    case SPICE_BRUSH_TYPE_NONE:
-        return NULL;
-    default:
-        spice_warn_if_reached();
-        return NULL;
-    }
-    return NULL;
-}
-
-static pixman_image_t *get_image(SpiceCanvas *canvas)
-{
-    SwCanvas *sw_canvas = (SwCanvas *)canvas;
-
-    pixman_image_ref(sw_canvas->image);
-
-    return sw_canvas->image;
-}
-
-static void copy_region(SpiceCanvas *spice_canvas,
-                        pixman_region32_t *dest_region,
-                        int dx, int dy)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_box32_t *dest_rects;
-    int n_rects;
-    int i, j, end_line;
-
-    dest_rects = pixman_region32_rectangles(dest_region, &n_rects);
-
-    if (dy > 0) {
-        if (dx >= 0) {
-            /* south-east: copy x and y in reverse order */
-            for (i = n_rects - 1; i >= 0; i--) {
-                spice_pixman_copy_rect(canvas->image,
-                                       dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
-                                       dest_rects[i].x2 - dest_rects[i].x1,
-                                       dest_rects[i].y2 - dest_rects[i].y1,
-                                       dest_rects[i].x1, dest_rects[i].y1);
-            }
-        } else {
-            /* south-west: Copy y in reverse order, but x in forward order */
-            i = n_rects - 1;
-
-            while (i >= 0) {
-                /* Copy all rects with same y in forward order */
-                for (end_line = i - 1;
-                     end_line >= 0 && dest_rects[end_line].y1 == dest_rects[i].y1;
-                     end_line--) {
-                }
-                for (j = end_line + 1; j <= i; j++) {
-                    spice_pixman_copy_rect(canvas->image,
-                                           dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
-                                           dest_rects[j].x2 - dest_rects[j].x1,
-                                           dest_rects[j].y2 - dest_rects[j].y1,
-                                           dest_rects[j].x1, dest_rects[j].y1);
-                }
-                i = end_line;
-            }
-        }
-    } else {
-        if (dx > 0) {
-            /* north-east: copy y in forward order, but x in reverse order */
-            i = 0;
-
-            while (i < n_rects) {
-                /* Copy all rects with same y in reverse order */
-                for (end_line = i;
-                     end_line < n_rects && dest_rects[end_line].y1 == dest_rects[i].y1;
-                     end_line++) {
-                }
-                for (j = end_line - 1; j >= i; j--) {
-                    spice_pixman_copy_rect(canvas->image,
-                                           dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
-                                           dest_rects[j].x2 - dest_rects[j].x1,
-                                           dest_rects[j].y2 - dest_rects[j].y1,
-                                           dest_rects[j].x1, dest_rects[j].y1);
-                }
-                i = end_line;
-            }
-        } else {
-            /* north-west: Copy x and y in forward order */
-            for (i = 0; i < n_rects; i++) {
-                spice_pixman_copy_rect(canvas->image,
-                                       dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
-                                       dest_rects[i].x2 - dest_rects[i].x1,
-                                       dest_rects[i].y2 - dest_rects[i].y1,
-                                       dest_rects[i].x1, dest_rects[i].y1);
-            }
-        }
-    }
-}
-
-static void fill_solid_spans(SpiceCanvas *spice_canvas,
-                             SpicePoint *points,
-                             int *widths,
-                             int n_spans,
-                             uint32_t color)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    int i;
-
-   for (i = 0; i < n_spans; i++) {
-        spice_pixman_fill_rect(canvas->image,
-                               points[i].x, points[i].y,
-                               widths[i],
-                               1,
-                               color);
-    }
-}
-
-static void fill_solid_rects(SpiceCanvas *spice_canvas,
-                             pixman_box32_t *rects,
-                             int n_rects,
-                             uint32_t color)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    int i;
-
-   for (i = 0; i < n_rects; i++) {
-        spice_pixman_fill_rect(canvas->image,
-                               rects[i].x1, rects[i].y1,
-                               rects[i].x2 - rects[i].x1,
-                               rects[i].y2 - rects[i].y1,
-                               color);
-    }
-}
-
-static void fill_solid_rects_rop(SpiceCanvas *spice_canvas,
-                                 pixman_box32_t *rects,
-                                 int n_rects,
-                                 uint32_t color,
-                                 SpiceROP rop)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    int i;
-
-   for (i = 0; i < n_rects; i++) {
-        spice_pixman_fill_rect_rop(canvas->image,
-                                   rects[i].x1, rects[i].y1,
-                                   rects[i].x2 - rects[i].x1,
-                                   rects[i].y2 - rects[i].y1,
-                                   color, rop);
-    }
-}
-
-static void __fill_tiled_rects(SpiceCanvas *spice_canvas,
-                               pixman_box32_t *rects,
-                               int n_rects,
-                               pixman_image_t *tile,
-                               int offset_x, int offset_y)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    int i;
-
-    for (i = 0; i < n_rects; i++) {
-        spice_pixman_tile_rect(canvas->image,
-                               rects[i].x1, rects[i].y1,
-                               rects[i].x2 - rects[i].x1,
-                               rects[i].y2 - rects[i].y1,
-                               tile, offset_x, offset_y);
-    }
-}
-
-static void fill_tiled_rects(SpiceCanvas *spice_canvas,
-                               pixman_box32_t *rects,
-                               int n_rects,
-                               pixman_image_t *tile,
-                               int offset_x, int offset_y)
-{
-    __fill_tiled_rects(spice_canvas, rects, n_rects, tile, offset_x, offset_y);
-}
-
-static void fill_tiled_rects_from_surface(SpiceCanvas *spice_canvas,
-                                          pixman_box32_t *rects,
-                                          int n_rects,
-                                          SpiceCanvas *surface_canvas,
-                                          int offset_x, int offset_y)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __fill_tiled_rects(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
-                       offset_y);
-}
-
-static void __fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
-                                   pixman_box32_t *rects,
-                                   int n_rects,
-                                   pixman_image_t *tile,
-                                   int offset_x, int offset_y,
-                                   SpiceROP rop)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    int i;
-
-    for (i = 0; i < n_rects; i++) {
-        spice_pixman_tile_rect_rop(canvas->image,
-                                   rects[i].x1, rects[i].y1,
-                                   rects[i].x2 - rects[i].x1,
-                                   rects[i].y2 - rects[i].y1,
-                                   tile, offset_x, offset_y,
-                                   rop);
-    }
-}
-static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
-                                 pixman_box32_t *rects,
-                                 int n_rects,
-                                 pixman_image_t *tile,
-                                 int offset_x, int offset_y,
-                                 SpiceROP rop)
-{
-    __fill_tiled_rects_rop(spice_canvas, rects, n_rects, tile, offset_x, offset_y, rop);
-}
-
-static void fill_tiled_rects_rop_from_surface(SpiceCanvas *spice_canvas,
-                                              pixman_box32_t *rects,
-                                              int n_rects,
-                                              SpiceCanvas *surface_canvas,
-                                              int offset_x, int offset_y,
-                                              SpiceROP rop)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __fill_tiled_rects_rop(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
-                           offset_y, rop);
-}
-
-/* Some pixman implementations of OP_OVER on xRGB32 sets
-   the high bit to 0xff (which is the right value if the
-   destination was ARGB32, and it should be ignored for
-   xRGB32. However, this fills our alpha bits with
-   data that is not wanted or expected by windows, and its
-   causing us to send rgba images rather than rgb images to
-   the client. So, we manually clear these bytes. */
-static void clear_dest_alpha(pixman_image_t *dest,
-                             int x, int y,
-                             int width, int height)
-{
-    uint32_t *data;
-    int stride;
-    int w, h;
-
-    w = pixman_image_get_width(dest);
-    h = pixman_image_get_height(dest);
-
-    if (x + width <= 0 || x >= w ||
-        y + height <= 0 || y >= h ||
-        width == 0 || height == 0) {
-        return;
-    }
-
-    if (x < 0) {
-        width += x;
-        x = 0;
-    }
-    if (x + width > w) {
-        width = w - x;
-    }
-
-    if (y < 0) {
-        height += y;
-        y = 0;
-    }
-    if (y + height > h) {
-        height = h - y;
-    }
-
-    stride = pixman_image_get_stride(dest);
-    data = (uint32_t *) (
-        (uint8_t *)pixman_image_get_data(dest) + y * stride + 4 * x);
-
-    if ((*data & 0xff000000U) == 0xff000000U) {
-        spice_pixman_fill_rect_rop(dest,
-                                   x, y, width, height,
-                                   0x00ffffff, SPICE_ROP_AND);
-    }
-}
-
-static void __blit_image(SpiceCanvas *spice_canvas,
-                         pixman_region32_t *region,
-                         pixman_image_t *src_image,
-                         int offset_x, int offset_y)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_box32_t *rects;
-    int n_rects, i;
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-    for (i = 0; i < n_rects; i++) {
-        int src_x, src_y, dest_x, dest_y, width, height;
-
-        dest_x = rects[i].x1;
-        dest_y = rects[i].y1;
-        width = rects[i].x2 - rects[i].x1;
-        height = rects[i].y2 - rects[i].y1;
-
-        src_x = rects[i].x1 - offset_x;
-        src_y = rects[i].y1 - offset_y;
-
-        spice_pixman_blit(canvas->image,
-                          src_image,
-                          src_x, src_y,
-                          dest_x, dest_y,
-                          width, height);
-    }
-}
-
-static void blit_image(SpiceCanvas *spice_canvas,
-                       pixman_region32_t *region,
-                       pixman_image_t *src_image,
-                       int offset_x, int offset_y)
-{
-    __blit_image(spice_canvas, region, src_image, offset_x, offset_y);
-}
-
-static void blit_image_from_surface(SpiceCanvas *spice_canvas,
-                                    pixman_region32_t *region,
-                                    SpiceCanvas *surface_canvas,
-                                    int offset_x, int offset_y)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __blit_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y);
-}
-
-static void __blit_image_rop(SpiceCanvas *spice_canvas,
-                             pixman_region32_t *region,
-                             pixman_image_t *src_image,
-                             int offset_x, int offset_y,
-                             SpiceROP rop)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_box32_t *rects;
-    int n_rects, i;
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-    for (i = 0; i < n_rects; i++) {
-        int src_x, src_y, dest_x, dest_y, width, height;
-
-        dest_x = rects[i].x1;
-        dest_y = rects[i].y1;
-        width = rects[i].x2 - rects[i].x1;
-        height = rects[i].y2 - rects[i].y1;
-
-        src_x = rects[i].x1 - offset_x;
-        src_y = rects[i].y1 - offset_y;
-
-        spice_pixman_blit_rop(canvas->image,
-                              src_image,
-                              src_x, src_y,
-                              dest_x, dest_y,
-                              width, height, rop);
-    }
-}
-
-static void blit_image_rop(SpiceCanvas *spice_canvas,
-                           pixman_region32_t *region,
-                           pixman_image_t *src_image,
-                           int offset_x, int offset_y,
-                           SpiceROP rop)
-{
-    __blit_image_rop(spice_canvas, region, src_image, offset_x, offset_y, rop);
-}
-
-static void blit_image_rop_from_surface(SpiceCanvas *spice_canvas,
-                                        pixman_region32_t *region,
-                                        SpiceCanvas *surface_canvas,
-                                        int offset_x, int offset_y,
-                                        SpiceROP rop)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __blit_image_rop(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y, rop);
-}
-
-
-
-static void __scale_image(SpiceCanvas *spice_canvas,
-                          pixman_region32_t *region,
-                          pixman_image_t *src,
-                          int src_x, int src_y,
-                          int src_width, int src_height,
-                          int dest_x, int dest_y,
-                          int dest_width, int dest_height,
-                          int scale_mode)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_transform_t transform;
-    pixman_fixed_t fsx, fsy;
-
-    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
-    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
-
-    pixman_image_set_clip_region32(canvas->image, region);
-
-    pixman_transform_init_scale(&transform, fsx, fsy);
-    pixman_transform_translate(&transform, NULL,
-			       pixman_int_to_fixed (src_x),
-			       pixman_int_to_fixed (src_y));
-
-    pixman_image_set_transform(src, &transform);
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-    spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
-                         scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
-    pixman_image_set_filter(src,
-                            (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
-                            PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
-                            NULL, 0);
-
-    pixman_image_composite32(PIXMAN_OP_SRC,
-                             src, NULL, canvas->image,
-                             0, 0, /* src */
-                             0, 0, /* mask */
-                             dest_x, dest_y, /* dst */
-                             dest_width, dest_height);
-
-    pixman_transform_init_identity(&transform);
-    pixman_image_set_transform(src, &transform);
-
-    pixman_image_set_clip_region32(canvas->image, NULL);
-}
-
-static void scale_image(SpiceCanvas *spice_canvas,
-                        pixman_region32_t *region,
-                        pixman_image_t *src,
-                        int src_x, int src_y,
-                        int src_width, int src_height,
-                        int dest_x, int dest_y,
-                        int dest_width, int dest_height,
-                        int scale_mode)
-{
-    __scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x, dest_y,
-                  dest_width,dest_height,scale_mode);
-}
-
-static void scale_image_from_surface(SpiceCanvas *spice_canvas,
-                                     pixman_region32_t *region,
-                                     SpiceCanvas *surface_canvas,
-                                     int src_x, int src_y,
-                                     int src_width, int src_height,
-                                     int dest_x, int dest_y,
-                                     int dest_width, int dest_height,
-                                     int scale_mode)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
-                  src_height, dest_x, dest_y, dest_width,dest_height,scale_mode);
-}
-
-static void __scale_image_rop(SpiceCanvas *spice_canvas,
-                              pixman_region32_t *region,
-                              pixman_image_t *src,
-                              int src_x, int src_y,
-                              int src_width, int src_height,
-                              int dest_x, int dest_y,
-                              int dest_width, int dest_height,
-                              int scale_mode, SpiceROP rop)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_transform_t transform;
-    pixman_image_t *scaled;
-    pixman_box32_t *rects;
-    int n_rects, i;
-    pixman_fixed_t fsx, fsy;
-
-    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
-    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
-
-    scaled = pixman_image_create_bits(spice_pixman_image_get_format(src),
-                                      dest_width,
-                                      dest_height,
-                                      NULL, 0);
-
-    pixman_region32_translate(region, -dest_x, -dest_y);
-    pixman_image_set_clip_region32(scaled, region);
-
-    pixman_transform_init_scale(&transform, fsx, fsy);
-    pixman_transform_translate(&transform, NULL,
-			       pixman_int_to_fixed (src_x),
-			       pixman_int_to_fixed (src_y));
-
-    pixman_image_set_transform(src, &transform);
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-    spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
-                         scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
-    pixman_image_set_filter(src,
-                            (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
-                            PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
-                            NULL, 0);
-
-    pixman_image_composite32(PIXMAN_OP_SRC,
-                             src, NULL, scaled,
-                             0, 0, /* src */
-                             0, 0, /* mask */
-                             0, 0, /* dst */
-                             dest_width,
-                             dest_height);
-
-    pixman_transform_init_identity(&transform);
-    pixman_image_set_transform(src, &transform);
-
-    /* Translate back */
-    pixman_region32_translate(region, dest_x, dest_y);
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-    for (i = 0; i < n_rects; i++) {
-        spice_pixman_blit_rop(canvas->image,
-                              scaled,
-                              rects[i].x1 - dest_x,
-                              rects[i].y1 - dest_y,
-                              rects[i].x1, rects[i].y1,
-                              rects[i].x2 - rects[i].x1,
-                              rects[i].y2 - rects[i].y1,
-                              rop);
-    }
-
-    pixman_image_unref(scaled);
-}
-
-static void scale_image_rop(SpiceCanvas *spice_canvas,
-                            pixman_region32_t *region,
-                            pixman_image_t *src,
-                            int src_x, int src_y,
-                            int src_width, int src_height,
-                            int dest_x, int dest_y,
-                            int dest_width, int dest_height,
-                            int scale_mode, SpiceROP rop)
-{
-    __scale_image_rop(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
-                      dest_y, dest_width, dest_height, scale_mode, rop);
-}
-
-static void scale_image_rop_from_surface(SpiceCanvas *spice_canvas,
-                                         pixman_region32_t *region,
-                                         SpiceCanvas *surface_canvas,
-                                         int src_x, int src_y,
-                                         int src_width, int src_height,
-                                         int dest_x, int dest_y,
-                                         int dest_width, int dest_height,
-                                         int scale_mode, SpiceROP rop)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __scale_image_rop(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
-                      src_height, dest_x, dest_y, dest_width, dest_height, scale_mode, rop);
-}
-
-static pixman_image_t *canvas_get_as_surface(SwCanvas *canvas,
-                                          int with_alpha)
-{
-    pixman_image_t *target;
-
-    if (with_alpha &&
-        canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
-        target = pixman_image_create_bits(PIXMAN_a8r8g8b8,
-                                          pixman_image_get_width(canvas->image),
-                                          pixman_image_get_height(canvas->image),
-                                          pixman_image_get_data(canvas->image),
-                                          pixman_image_get_stride(canvas->image));
-    } else {
-        target = pixman_image_ref(canvas->image);
-    }
-
-    return target;
-}
-
-static void __blend_image(SpiceCanvas *spice_canvas,
-                          pixman_region32_t *region,
-                          int dest_has_alpha,
-                          pixman_image_t *src,
-                          int src_x, int src_y,
-                          int dest_x, int dest_y,
-                          int width, int height,
-                          int overall_alpha)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_image_t *mask, *dest;
-
-    dest = canvas_get_as_surface(canvas, dest_has_alpha);
-
-    pixman_image_set_clip_region32(dest, region);
-
-    mask = NULL;
-    if (overall_alpha != 0xff) {
-        pixman_color_t color = { 0 };
-        color.alpha = overall_alpha * 0x101;
-        mask = pixman_image_create_solid_fill(&color);
-    }
-
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-
-    pixman_image_composite32(PIXMAN_OP_OVER,
-                             src, mask, dest,
-                             src_x, src_y, /* src */
-                             0, 0, /* mask */
-                             dest_x, dest_y, /* dst */
-                             width,
-                             height);
-
-    if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB &&
-        !dest_has_alpha) {
-        clear_dest_alpha(dest, dest_x, dest_y, width, height);
-    }
-
-    if (mask) {
-        pixman_image_unref(mask);
-    }
-
-    pixman_image_set_clip_region32(dest, NULL);
-    pixman_image_unref(dest);
-}
-
-static void blend_image(SpiceCanvas *spice_canvas,
-                        pixman_region32_t *region,
-                        int dest_has_alpha,
-                        pixman_image_t *src,
-                        int src_x, int src_y,
-                        int dest_x, int dest_y,
-                        int width, int height,
-                        int overall_alpha)
-{
-    __blend_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y,
-                  dest_x, dest_y, width, height,
-                  overall_alpha);
-}
-
-static void blend_image_from_surface(SpiceCanvas *spice_canvas,
-                                     pixman_region32_t *region,
-                                     int dest_has_alpha,
-                                     SpiceCanvas *surface_canvas,
-                                     int src_has_alpha,
-                                     int src_x, int src_y,
-                                     int dest_x, int dest_y,
-                                     int width, int height,
-                                     int overall_alpha)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    pixman_image_t *src;
-
-    src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
-    __blend_image(spice_canvas, region, dest_has_alpha,
-                  src, src_x, src_y,
-                  dest_x, dest_y,
-                  width, height, overall_alpha);
-    pixman_image_unref(src);
-}
-
-static void __blend_scale_image(SpiceCanvas *spice_canvas,
-                                pixman_region32_t *region,
-                                int dest_has_alpha,
-                                pixman_image_t *src,
-                                int src_x, int src_y,
-                                int src_width, int src_height,
-                                int dest_x, int dest_y,
-                                int dest_width, int dest_height,
-                                int scale_mode,
-                                int overall_alpha)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_transform_t transform;
-    pixman_image_t *mask, *dest;
-    pixman_fixed_t fsx, fsy;
-
-    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
-    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
-
-    dest = canvas_get_as_surface(canvas, dest_has_alpha);
-
-    pixman_image_set_clip_region32(dest, region);
-
-    pixman_transform_init_scale(&transform, fsx, fsy);
-    pixman_transform_translate(&transform, NULL,
-			       pixman_int_to_fixed (src_x),
-			       pixman_int_to_fixed (src_y));
-
-    mask = NULL;
-    if (overall_alpha != 0xff) {
-        pixman_color_t color = { 0 };
-        color.alpha = overall_alpha * 0x101;
-        mask = pixman_image_create_solid_fill(&color);
-    }
-
-    pixman_image_set_transform(src, &transform);
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-    spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
-                         scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
-    pixman_image_set_filter(src,
-                            (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
-                            PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
-                            NULL, 0);
-
-    pixman_image_composite32(PIXMAN_OP_OVER,
-                             src, mask, dest,
-                             0, 0, /* src */
-                             0, 0, /* mask */
-                             dest_x, dest_y, /* dst */
-                             dest_width, dest_height);
-
-    if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB &&
-        !dest_has_alpha) {
-        clear_dest_alpha(dest, dest_x, dest_y, dest_width, dest_height);
-    }
-
-    pixman_transform_init_identity(&transform);
-    pixman_image_set_transform(src, &transform);
-
-    if (mask) {
-        pixman_image_unref(mask);
-    }
-
-    pixman_image_set_clip_region32(dest, NULL);
-    pixman_image_unref(dest);
-}
-
-static void blend_scale_image(SpiceCanvas *spice_canvas,
-                              pixman_region32_t *region,
-                              int dest_has_alpha,
-                              pixman_image_t *src,
-                              int src_x, int src_y,
-                              int src_width, int src_height,
-                              int dest_x, int dest_y,
-                              int dest_width, int dest_height,
-                              int scale_mode,
-                              int overall_alpha)
-{
-    __blend_scale_image(spice_canvas, region, dest_has_alpha,
-                        src, src_x, src_y, src_width, src_height,
-                        dest_x, dest_y, dest_width, dest_height,
-                        scale_mode, overall_alpha);
-}
-
-static void blend_scale_image_from_surface(SpiceCanvas *spice_canvas,
-                                           pixman_region32_t *region,
-                                           int dest_has_alpha,
-                                           SpiceCanvas *surface_canvas,
-                                           int src_has_alpha,
-                                           int src_x, int src_y,
-                                           int src_width, int src_height,
-                                           int dest_x, int dest_y,
-                                           int dest_width, int dest_height,
-                                           int scale_mode,
-                                           int overall_alpha)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    pixman_image_t *src;
-
-    src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
-    __blend_scale_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y, src_width,
-                        src_height, dest_x, dest_y, dest_width, dest_height, scale_mode,
-                        overall_alpha);
-    pixman_image_unref(src);
-}
-
-static void __colorkey_image(SpiceCanvas *spice_canvas,
-                             pixman_region32_t *region,
-                             pixman_image_t *src_image,
-                             int offset_x, int offset_y,
-                             uint32_t transparent_color)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_box32_t *rects;
-    int n_rects, i;
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-    for (i = 0; i < n_rects; i++) {
-        int src_x, src_y, dest_x, dest_y, width, height;
-
-        dest_x = rects[i].x1;
-        dest_y = rects[i].y1;
-        width = rects[i].x2 - rects[i].x1;
-        height = rects[i].y2 - rects[i].y1;
-
-        src_x = rects[i].x1 - offset_x;
-        src_y = rects[i].y1 - offset_y;
-
-        spice_pixman_blit_colorkey(canvas->image,
-                                   src_image,
-                                   src_x, src_y,
-                                   dest_x, dest_y,
-                                   width, height,
-                                   transparent_color);
-    }
-}
-
-static void colorkey_image(SpiceCanvas *spice_canvas,
-                           pixman_region32_t *region,
-                           pixman_image_t *src_image,
-                           int offset_x, int offset_y,
-                           uint32_t transparent_color)
-{
-    __colorkey_image(spice_canvas, region, src_image, offset_x, offset_y, transparent_color);
-}
-
-static void colorkey_image_from_surface(SpiceCanvas *spice_canvas,
-                                        pixman_region32_t *region,
-                                        SpiceCanvas *surface_canvas,
-                                        int offset_x, int offset_y,
-                                        uint32_t transparent_color)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __colorkey_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y,
-                     transparent_color);
-}
-
-static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
-                                   pixman_region32_t *region,
-                                   pixman_image_t *src,
-                                   int src_x, int src_y,
-                                   int src_width, int src_height,
-                                   int dest_x, int dest_y,
-                                   int dest_width, int dest_height,
-                                   uint32_t transparent_color)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_transform_t transform;
-    pixman_image_t *scaled;
-    pixman_box32_t *rects;
-    int n_rects, i;
-    pixman_fixed_t fsx, fsy;
-
-    fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
-    fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
-
-    scaled = pixman_image_create_bits(spice_pixman_image_get_format (src),
-                                      dest_width,
-                                      dest_height,
-                                      NULL, 0);
-
-    pixman_region32_translate(region, -dest_x, -dest_y);
-    pixman_image_set_clip_region32(scaled, region);
-
-    pixman_transform_init_scale(&transform, fsx, fsy);
-    pixman_transform_translate(&transform, NULL,
-			       pixman_int_to_fixed (src_x),
-			       pixman_int_to_fixed (src_y));
-
-    pixman_image_set_transform(src, &transform);
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-    pixman_image_set_filter(src,
-                            PIXMAN_FILTER_NEAREST,
-                            NULL, 0);
-
-    pixman_image_composite32(PIXMAN_OP_SRC,
-                             src, NULL, scaled,
-                             0, 0, /* src */
-                             0, 0, /* mask */
-                             0, 0, /* dst */
-                             dest_width,
-                             dest_height);
-
-    pixman_transform_init_identity(&transform);
-    pixman_image_set_transform(src, &transform);
-
-    /* Translate back */
-    pixman_region32_translate(region, dest_x, dest_y);
-
-    rects = pixman_region32_rectangles(region, &n_rects);
-
-    for (i = 0; i < n_rects; i++) {
-        spice_pixman_blit_colorkey(canvas->image,
-                                   scaled,
-                                   rects[i].x1 - dest_x,
-                                   rects[i].y1 - dest_y,
-                                   rects[i].x1, rects[i].y1,
-                                   rects[i].x2 - rects[i].x1,
-                                   rects[i].y2 - rects[i].y1,
-                                   transparent_color);
-    }
-
-    pixman_image_unref(scaled);
-}
-
-static void colorkey_scale_image(SpiceCanvas *spice_canvas,
-                                 pixman_region32_t *region,
-                                 pixman_image_t *src,
-                                 int src_x, int src_y,
-                                 int src_width, int src_height,
-                                 int dest_x, int dest_y,
-                                 int dest_width, int dest_height,
-                                 uint32_t transparent_color)
-{
-    __colorkey_scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
-                           dest_y, dest_width, dest_height, transparent_color);
-}
-
-static void colorkey_scale_image_from_surface(SpiceCanvas *spice_canvas,
-                                              pixman_region32_t *region,
-                                              SpiceCanvas *surface_canvas,
-                                              int src_x, int src_y,
-                                              int src_width, int src_height,
-                                              int dest_x, int dest_y,
-                                              int dest_width, int dest_height,
-                                              uint32_t transparent_color)
-{
-    SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
-    __colorkey_scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y,
-                           src_width, src_height, dest_x, dest_y, dest_width, dest_height,
-                           transparent_color);
-}
-
-static void canvas_put_image(SpiceCanvas *spice_canvas,
-#ifdef WIN32
-                             HDC dc,
-#endif
-                             const SpiceRect *dest, const uint8_t *src_data,
-                             uint32_t src_width, uint32_t src_height, int src_stride,
-                             const QRegion *clip)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_image_t *src;
-    uint32_t dest_width;
-    uint32_t dest_height;
-    double sx, sy;
-    pixman_transform_t transform;
-
-    src = pixman_image_create_bits(PIXMAN_x8r8g8b8,
-                                   src_width,
-                                   src_height,
-                                   (uint32_t*)src_data,
-                                   src_stride);
-
-
-    if (clip) {
-        pixman_image_set_clip_region32 (canvas->image, (pixman_region32_t *)clip);
-    }
-
-    dest_width = dest->right - dest->left;
-    dest_height = dest->bottom - dest->top;
-
-    if (dest_width != src_width || dest_height != src_height) {
-        sx = (double)(src_width) / (dest_width);
-        sy = (double)(src_height) / (dest_height);
-
-        pixman_transform_init_scale(&transform,
-                                    pixman_double_to_fixed(sx),
-                                    pixman_double_to_fixed(sy));
-        pixman_image_set_transform(src, &transform);
-        pixman_image_set_filter(src,
-                                PIXMAN_FILTER_NEAREST,
-                                NULL, 0);
-    }
-
-    pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
-
-    pixman_image_composite32(PIXMAN_OP_SRC,
-                             src, NULL, canvas->image,
-                             0, 0, /* src */
-                             0, 0, /* mask */
-                             dest->left, dest->top, /* dst */
-                             dest_width, dest_height);
-
-
-    if (clip) {
-        pixman_image_set_clip_region32(canvas->image, NULL);
-    }
-    pixman_image_unref(src);
-}
-
-
-static void canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox,
-                             SpiceClip *clip, SpiceText *text)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_region32_t dest_region;
-    pixman_image_t *str_mask, *brush;
-    SpiceString *str;
-    SpicePoint pos = { 0, };
-    int depth;
-
-    pixman_region32_init_rect(&dest_region,
-                              bbox->left, bbox->top,
-                              bbox->right - bbox->left,
-                              bbox->bottom - bbox->top);
-
-    canvas_clip_pixman(&canvas->base, &dest_region, clip);
-
-    if (!pixman_region32_not_empty(&dest_region)) {
-        touch_brush(&canvas->base, &text->fore_brush);
-        touch_brush(&canvas->base, &text->back_brush);
-        pixman_region32_fini(&dest_region);
-        return;
-    }
-
-    if (!rect_is_empty(&text->back_area)) {
-        pixman_region32_t back_region;
-
-        /* Nothing else makes sense for text and we should deprecate it
-         * and actually it means OVER really */
-        spice_return_if_fail(text->fore_mode == SPICE_ROPD_OP_PUT);
-
-        pixman_region32_init_rect(&back_region,
-                                  text->back_area.left,
-                                  text->back_area.top,
-                                  text->back_area.right - text->back_area.left,
-                                  text->back_area.bottom - text->back_area.top);
-
-        pixman_region32_intersect(&back_region, &back_region, &dest_region);
-
-        if (pixman_region32_not_empty(&back_region)) {
-            draw_brush(spice_canvas, &back_region, &text->back_brush, SPICE_ROP_COPY);
-        }
-
-        pixman_region32_fini(&back_region);
-    }
-    str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
-
-    if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
-        depth = 1;
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
-        depth = 4;
-    } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
-        spice_warning("untested path A8 glyphs");
-        depth = 8;
-    } else {
-        spice_warning("unsupported path vector glyphs");
-        pixman_region32_fini (&dest_region);
-        return;
-    }
-
-    brush = canvas_get_pixman_brush(canvas, &text->fore_brush);
-
-    str_mask = canvas_get_str_mask(&canvas->base, str, depth, &pos);
-    if (brush) {
-        pixman_image_set_clip_region32(canvas->image, &dest_region);
-
-        pixman_image_composite32(PIXMAN_OP_OVER,
-                                 brush,
-                                 str_mask,
-                                 canvas->image,
-                                 0, 0,
-                                 0, 0,
-                                 pos.x, pos.y,
-                                 pixman_image_get_width(str_mask),
-                                 pixman_image_get_height(str_mask));
-        if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
-            clear_dest_alpha(canvas->image, pos.x, pos.y,
-                             pixman_image_get_width(str_mask),
-                             pixman_image_get_height(str_mask));
-        }
-        pixman_image_unref(brush);
-
-        pixman_image_set_clip_region32(canvas->image, NULL);
-    }
-    pixman_image_unref(str_mask);
-    pixman_region32_fini(&dest_region);
-}
-
-static void canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest,
-                             int dest_stride, const SpiceRect *area)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    pixman_image_t* surface;
-    uint8_t *src;
-    int src_stride;
-    uint8_t *dest_end;
-    int bpp;
-
-    spice_return_if_fail(canvas && area);
-
-    surface = canvas->image;
-
-    bpp = spice_pixman_image_get_bpp(surface) / 8;
-
-    src_stride = pixman_image_get_stride(surface);
-    src = (uint8_t *)pixman_image_get_data(surface) +
-        area->top * src_stride + area->left * bpp;
-    dest_end = dest + (area->bottom - area->top) * dest_stride;
-    for (; dest != dest_end; dest += dest_stride, src += src_stride) {
-        memcpy(dest, src, (area->right - area->left) * bpp);
-    }
-}
-
-static void canvas_clear(SpiceCanvas *spice_canvas)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    spice_pixman_fill_rect(canvas->image,
-                           0, 0,
-                           pixman_image_get_width(canvas->image),
-                           pixman_image_get_height(canvas->image),
-                           0);
-}
-
-static void canvas_destroy(SpiceCanvas *spice_canvas)
-{
-    SwCanvas *canvas = (SwCanvas *)spice_canvas;
-    if (!canvas) {
-        return;
-    }
-    pixman_image_unref(canvas->image);
-    canvas_base_destroy(&canvas->base);
-    if (canvas->private_data) {
-        free(canvas->private_data);
-    }
-    free(canvas);
-}
-
-static int need_init = 1;
-static SpiceCanvasOps sw_canvas_ops;
-
-static SpiceCanvas *canvas_create_common(pixman_image_t *image,
-                                         uint32_t format
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-                           , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           )
-{
-    SwCanvas *canvas;
-
-    if (need_init) {
-        return NULL;
-    }
-    spice_pixman_image_set_format(image,
-                                  spice_surface_format_to_pixman (format));
-
-    canvas = spice_new0(SwCanvas, 1);
-    canvas_base_init(&canvas->base, &sw_canvas_ops,
-		     pixman_image_get_width (image),
-		     pixman_image_get_height (image),
-		     format
-#ifdef SW_CANVAS_CACHE
-		     , bits_cache
-		     , palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-		     , bits_cache
-#endif
-		     , surfaces
-		     , glz_decoder
-		     , jpeg_decoder
-		     , zlib_decoder
-		    );
-    canvas->private_data = NULL;
-    canvas->private_data_size = 0;
-
-    canvas->image = image;
-
-    return (SpiceCanvas *)canvas;
-}
-
-SpiceCanvas *canvas_create(int width, int height, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-                           , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           )
-{
-    pixman_image_t *image;
-
-    image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
-                                     width, height, NULL, 0);
-
-    return canvas_create_common(image, format
-#ifdef SW_CANVAS_CACHE
-                                , bits_cache
-                                , palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                                , bits_cache
-#endif
-                                , surfaces
-                                , glz_decoder
-                                , jpeg_decoder
-                                , zlib_decoder
-                                );
-}
-
-SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
-                                    uint8_t *data, int stride
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-                           , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           )
-{
-    pixman_image_t *image;
-
-    image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
-                                     width, height, (uint32_t *)data, stride);
-
-    return canvas_create_common(image, format
-#ifdef SW_CANVAS_CACHE
-                                , bits_cache
-                                , palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                                , bits_cache
-#endif
-                                , surfaces
-                                , glz_decoder
-                                , jpeg_decoder
-                                , zlib_decoder
-                                );
-}
-
-void sw_canvas_init(void) //unsafe global function
-{
-    if (!need_init) {
-        return;
-    }
-    need_init = 0;
-
-    canvas_base_init_ops(&sw_canvas_ops);
-    sw_canvas_ops.draw_text = canvas_draw_text;
-    sw_canvas_ops.put_image = canvas_put_image;
-    sw_canvas_ops.clear = canvas_clear;
-    sw_canvas_ops.read_bits = canvas_read_bits;
-    sw_canvas_ops.destroy = canvas_destroy;
-
-    sw_canvas_ops.fill_solid_spans = fill_solid_spans;
-    sw_canvas_ops.fill_solid_rects = fill_solid_rects;
-    sw_canvas_ops.fill_solid_rects_rop = fill_solid_rects_rop;
-    sw_canvas_ops.fill_tiled_rects = fill_tiled_rects;
-    sw_canvas_ops.fill_tiled_rects_from_surface = fill_tiled_rects_from_surface;
-    sw_canvas_ops.fill_tiled_rects_rop = fill_tiled_rects_rop;
-    sw_canvas_ops.fill_tiled_rects_rop_from_surface = fill_tiled_rects_rop_from_surface;
-    sw_canvas_ops.blit_image = blit_image;
-    sw_canvas_ops.blit_image_from_surface = blit_image_from_surface;
-    sw_canvas_ops.blit_image_rop = blit_image_rop;
-    sw_canvas_ops.blit_image_rop_from_surface = blit_image_rop_from_surface;
-    sw_canvas_ops.scale_image = scale_image;
-    sw_canvas_ops.scale_image_from_surface = scale_image_from_surface;
-    sw_canvas_ops.scale_image_rop = scale_image_rop;
-    sw_canvas_ops.scale_image_rop_from_surface = scale_image_rop_from_surface;
-    sw_canvas_ops.blend_image = blend_image;
-    sw_canvas_ops.blend_image_from_surface = blend_image_from_surface;
-    sw_canvas_ops.blend_scale_image = blend_scale_image;
-    sw_canvas_ops.blend_scale_image_from_surface = blend_scale_image_from_surface;
-    sw_canvas_ops.colorkey_image = colorkey_image;
-    sw_canvas_ops.colorkey_image_from_surface = colorkey_image_from_surface;
-    sw_canvas_ops.colorkey_scale_image = colorkey_scale_image;
-    sw_canvas_ops.colorkey_scale_image_from_surface = colorkey_scale_image_from_surface;
-    sw_canvas_ops.copy_region = copy_region;
-    sw_canvas_ops.get_image = get_image;
-    rop3_init();
-}
diff --git a/common/sw_canvas.h b/common/sw_canvas.h
deleted file mode 100644
index 51e594c..0000000
--- a/common/sw_canvas.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H__CANVAS
-#define _H__CANVAS
-
-#include <stdint.h>
-
-#include "draw.h"
-#include "pixman_utils.h"
-#include "canvas_base.h"
-#include "region.h"
-
-SpiceCanvas *canvas_create(int width, int height, uint32_t format
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-			   , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           );
-
-SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint8_t *data, int stride
-#ifdef SW_CANVAS_CACHE
-                           , SpiceImageCache *bits_cache
-                           , SpicePaletteCache *palette_cache
-#elif defined(SW_CANVAS_IMAGE_CACHE)
-                           , SpiceImageCache *bits_cache
-#endif
-			   , SpiceImageSurfaces *surfaces
-                           , SpiceGlzDecoder *glz_decoder
-                           , SpiceJpegDecoder *jpeg_decoder
-                           , SpiceZlibDecoder *zlib_decoder
-                           );
-
-
-void sw_canvas_init(void);
-
-#endif
diff --git a/configure.ac b/configure.ac
index 2d062b1..760736a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,8 @@ GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
 
 # Define default SPICE_COMMON_SRCDIR
 SPICE_COMMON_SRCDIR='$(top_srcdir)'/common
+# no opengl support yet
+AM_CONDITIONAL(SUPPORT_GL, false)
 
 AC_PROG_CC
 AC_PROG_CC_C99
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index f4869b9..9628cc7 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -233,6 +233,8 @@ libspice_client_glib_2_0_la_SOURCES =	\
 	decode-jpeg.c			\
 	decode-zlib.c			\
 	\
+	$(COMMON_DIR)/backtrace.c	\
+	$(COMMON_DIR)/backtrace.h	\
 	$(COMMON_DIR)/mem.c		\
 	$(COMMON_DIR)/mem.h		\
 	$(COMMON_DIR)/marshaller.c	\
@@ -249,6 +251,8 @@ libspice_client_glib_2_0_la_SOURCES =	\
 	$(COMMON_DIR)/rop3.h		\
 	$(COMMON_DIR)/quic.c		\
 	$(COMMON_DIR)/quic.h		\
+	$(COMMON_DIR)/log.c		\
+	$(COMMON_DIR)/log.h		\
 	$(COMMON_DIR)/lz.c		\
 	$(COMMON_DIR)/lz.h		\
 	$(COMMON_DIR)/region.c		\
@@ -503,10 +507,10 @@ generated_demarshallers1.c: $(top_srcdir)/spice1.proto
 	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include messages.h --prefix 1 --ptrsize 8 $< $@ >/dev/null
 
 generated_marshallers.c: $(top_srcdir)/spice.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include marshallers.h --client $< $@ >/dev/null
+	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include client_marshallers.h --client $< $@ >/dev/null
 
 generated_marshallers1.c: $(top_srcdir)/spice1.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include marshallers.h --client --prefix 1 --ptrsize 8 $< $@ >/dev/null
+	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include messages.h --include client_marshallers.h --client --prefix 1 --ptrsize 8 $< $@ >/dev/null
 
 vncdisplaykeymap.c: $(KEYMAPS)
 
diff --git a/gtk/decode.h b/gtk/decode.h
index 9fee749..9db6383 100644
--- a/gtk/decode.h
+++ b/gtk/decode.h
@@ -19,6 +19,7 @@
 # define SPICEGTK_DECODE_H_
 
 #include <glib.h>
+
 #include "canvas_base.h"
 
 G_BEGIN_DECLS
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index 482927b..88611d0 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -32,9 +32,8 @@
 #include "coroutine.h"
 #include "gio-coroutine.h"
 
-/* common/ */
-#include "marshallers.h"
-#include "demarshallers.h"
+#include "client_marshallers.h"
+#include "client_demarshallers.h"
 
 #include "ssl_verify.h"
 
-- 
1.7.7.6



More information about the Spice-devel mailing list