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

Hans de Goede hdegoede at redhat.com
Thu Mar 15 02:54:48 PDT 2012


Looks good, ack.

On 03/15/2012 02:20 AM, Marc-André Lureau wrote:
> ---
>   .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"
>


More information about the Spice-devel mailing list