[Spice-commits] 3 commits - autogen.sh client/application.cpp client/canvas.h client/cursor_channel.cpp client/cursor.h client/demarshallers.h client/display_channel.cpp client/display_channel.h client/glz_decoder_config.h client/glz_decoder.h client/jpeg_decoder.h client/Makefile.am client/marshallers.h client/monitor.h client/pixels_source.h client/red_canvas_base.h client/red_channel.h client/red_client.cpp client/red_client.h client/red_drawable.h client/red_gdi_canvas.cpp client/red_gdi_canvas.h client/red_gl_canvas.cpp client/red_gl_canvas.h client/red_peer.cpp client/red_peer.h client/red_sw_canvas.cpp client/red_sw_canvas.h client/screen.h client/screen_layer.h client/smartcard_channel.cpp client/windows client/x11 common/backtrace.c common/backtrace.h common/bitops.h common/canvas_base.c common/canvas_base.h common/canvas_utils.c common/canvas_utils.h common/draw.h common/gdi_canvas.c common/gdi_canvas.h common/.gitignore common/gl_canvas.c common/gl_canvas.h common/glc.c c ommon/glc.h common/gl_utils.h common/lines.c common/lines.h common/lz.c common/lz_common.h common/lz_compress_tmpl.c common/lz_config.h common/lz_decompress_tmpl.c common/lz.h common/Makefile.am common/marshaller.c common/marshaller.h common/mem.c common/mem.h common/messages.h common/mutex.h common/ogl_ctx.c common/ogl_ctx.h common/pixman_utils.c common/pixman_utils.h common/quic.c common/quic_config.h common/quic_family_tmpl.c common/quic.h common/quic_rgb_tmpl.c common/quic_tmpl.c common/rect.h common/region.c common/region.h common/ring.h common/rop3.c common/rop3.h common/spice_common.h common/ssl_verify.c common/ssl_verify.h common/sw_canvas.c common/sw_canvas.h common/win configure.ac .gitignore .gitmodules Makefile.am server/agent-msg-filter.c server/dispatcher.c server/glz_encoder_config.h server/glz_encoder.h server/inputs_channel.c server/jpeg_encoder.c server/main_channel.c server/Makefile.am server/mjpeg_encoder.c server/red_channel.c server/red_channel.h server /red_client_cache.h server/red_client_shared_cache.h server/red_common.h server/red_dispatcher.c server/red_memslots.c server/red_parse_qxl.c server/reds.c server/reds_gl_canvas.c server/reds_gl_canvas.h server/reds_sw_canvas.c server/reds_sw_canvas.h server/red_tunnel_worker.c server/red_worker.c server/red_worker.h server/smartcard.c server/smartcard.h server/snd_worker.c server/spicevmc.c server/tests server/zlib_encoder.c spice-common spice-protocol

Marc-André Lureau elmarco at kemper.freedesktop.org
Sun Mar 25 10:13:41 PDT 2012


 .gitignore                             |    1 
 .gitmodules                            |    6 
 Makefile.am                            |   18 
 autogen.sh                             |    3 
 client/Makefile.am                     |   62 
 client/application.cpp                 |    7 
 client/canvas.h                        |   10 
 client/cursor.h                        |    2 
 client/cursor_channel.cpp              |    3 
 client/demarshallers.h                 |   27 
 client/display_channel.cpp             |    1 
 client/display_channel.h               |    3 
 client/glz_decoder.h                   |    2 
 client/glz_decoder_config.h            |    4 
 client/jpeg_decoder.h                  |    5 
 client/marshallers.h                   |   63 
 client/monitor.h                       |    2 
 client/pixels_source.h                 |    2 
 client/red_canvas_base.h               |    2 
 client/red_channel.h                   |    5 
 client/red_client.cpp                  |    7 
 client/red_client.h                    |    2 
 client/red_drawable.h                  |    2 
 client/red_gdi_canvas.cpp              |   18 
 client/red_gdi_canvas.h                |    2 
 client/red_gl_canvas.cpp               |   15 
 client/red_gl_canvas.h                 |    4 
 client/red_peer.cpp                    |    8 
 client/red_peer.h                      |    7 
 client/red_sw_canvas.cpp               |   20 
 client/red_sw_canvas.h                 |    2 
 client/screen.h                        |    3 
 client/screen_layer.h                  |    2 
 client/smartcard_channel.cpp           |    2 
 client/windows/my_getopt.cpp           |  301 ++
 client/windows/my_getopt.h             |   72 
 client/x11/pixels_source_p.h           |    3 
 client/x11/platform.cpp                |    5 
 client/x11/red_drawable.cpp            |    2 
 client/x11/red_pixmap_gl.cpp           |    2 
 client/x11/red_window.cpp              |   15 
 common/.gitignore                      |    9 
 common/Makefile.am                     |   76 
 common/backtrace.c                     |  133 -
 common/backtrace.h                     |   34 
 common/bitops.h                        |   91 
 common/canvas_base.c                   | 3394 ------------------------------
 common/canvas_base.h                   |  327 --
 common/canvas_utils.c                  |  299 --
 common/canvas_utils.h                  |   80 
 common/draw.h                          |  281 --
 common/gdi_canvas.c                    | 1858 ----------------
 common/gdi_canvas.h                    |   51 
 common/gl_canvas.c                     |  906 --------
 common/gl_canvas.h                     |   53 
 common/gl_utils.h                      |   61 
 common/glc.c                           | 1513 -------------
 common/glc.h                           |  167 -
 common/lines.c                         | 3613 ---------------------------------
 common/lines.h                         |  138 -
 common/lz.c                            |  740 ------
 common/lz.h                            |   82 
 common/lz_common.h                     |   69 
 common/lz_compress_tmpl.c              |  529 ----
 common/lz_config.h                     |   39 
 common/lz_decompress_tmpl.c            |  326 --
 common/marshaller.c                    |  615 -----
 common/marshaller.h                    |   74 
 common/mem.c                           |  297 --
 common/mem.h                           |  162 -
 common/messages.h                      |  525 ----
 common/mutex.h                         |   44 
 common/ogl_ctx.c                       |  251 --
 common/ogl_ctx.h                       |   38 
 common/pixman_utils.c                  | 1594 --------------
 common/pixman_utils.h                  |  136 -
 common/quic.c                          | 1699 ---------------
 common/quic.h                          |   72 
 common/quic_config.h                   |   48 
 common/quic_family_tmpl.c              |  117 -
 common/quic_rgb_tmpl.c                 |  765 ------
 common/quic_tmpl.c                     |  635 -----
 common/rect.h                          |  122 -
 common/region.c                        |  890 --------
 common/region.h                        |   70 
 common/ring.h                          |  172 -
 common/rop3.c                          |  650 -----
 common/rop3.h                          |   42 
 common/spice_common.h                  |   78 
 common/ssl_verify.c                    |  482 ----
 common/ssl_verify.h                    |   66 
 common/sw_canvas.c                     | 1327 ------------
 common/sw_canvas.h                     |   70 
 common/win/Makefile.am                 |    1 
 common/win/my_getopt-1.5/ChangeLog     |   22 
 common/win/my_getopt-1.5/LICENSE       |   22 
 common/win/my_getopt-1.5/Makefile.am   |   14 
 common/win/my_getopt-1.5/Makefile.test |   26 
 common/win/my_getopt-1.5/README        |  140 -
 common/win/my_getopt-1.5/getopt.3      |  288 --
 common/win/my_getopt-1.5/getopt.h      |   56 
 common/win/my_getopt-1.5/getopt.txt    |  330 ---
 common/win/my_getopt-1.5/main.c        |  387 ---
 common/win/my_getopt-1.5/my_getopt.c   |  281 --
 common/win/my_getopt-1.5/my_getopt.h   |   72 
 configure.ac                           |   10 
 server/Makefile.am                     |   47 
 server/agent-msg-filter.c              |    8 
 server/dispatcher.c                    |   57 
 server/glz_encoder.h                   |    2 
 server/glz_encoder_config.h            |    2 
 server/inputs_channel.c                |   40 
 server/jpeg_encoder.c                  |   14 
 server/main_channel.c                  |   77 
 server/mjpeg_encoder.c                 |    2 
 server/red_channel.c                   |  102 
 server/red_channel.h                   |    9 
 server/red_client_cache.h              |    4 
 server/red_client_shared_cache.h       |    8 
 server/red_common.h                    |    9 
 server/red_dispatcher.c                |   40 
 server/red_memslots.c                  |   28 
 server/red_parse_qxl.c                 |   45 
 server/red_tunnel_worker.c             |  240 +-
 server/red_worker.c                    |  628 ++---
 server/red_worker.h                    |    4 
 server/reds.c                          |  464 ++--
 server/reds_gl_canvas.c                |    4 
 server/reds_gl_canvas.h                |    2 
 server/reds_sw_canvas.c                |    4 
 server/reds_sw_canvas.h                |    2 
 server/smartcard.c                     |   34 
 server/smartcard.h                     |    2 
 server/snd_worker.c                    |  103 
 server/spicevmc.c                      |   12 
 server/tests/Makefile.am               |   21 
 server/zlib_encoder.c                  |   16 
 spice-common                           |    1 
 spice-protocol                         |    1 
 139 files changed, 1511 insertions(+), 28802 deletions(-)

New commits:
commit 4d8f39020ac83602c1647d4af04e8b19bf74ed6e
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Mar 14 21:31:40 2012 +0100

    Copy common/win/my_getopt-1.5/my_getopt client/windows

diff --git a/client/windows/my_getopt.cpp b/client/windows/my_getopt.cpp
index 905b717..5237b8e 100644
--- a/client/windows/my_getopt.cpp
+++ b/client/windows/my_getopt.cpp
@@ -1,22 +1,281 @@
 /*
-   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 HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "common.h"
-#include "../../common/win/my_getopt-1.5/my_getopt.c"
+ *  my_getopt.c - my re-implementation of getopt.
+ *  Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
+ *
+ *  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 <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "my_getopt.h"
+
+int my_optind=1, my_opterr=1, my_optopt=0;
+char *my_optarg=0;
+
+/* reset argument parser to start-up values */
+int my_getopt_reset(void)
+{
+    my_optind = 1;
+    my_opterr = 1;
+    my_optopt = 0;
+    my_optarg = 0;
+    return 0;
+}
+
+/* this is the plain old UNIX getopt, with GNU-style extensions. */
+/* if you're porting some piece of UNIX software, this is all you need. */
+/* this supports GNU-style permution and optional arguments */
+
+int my_getopt(int argc, char * argv[], const char *opts)
+{
+  static int charind=0;
+  char mode, colon_mode;
+  int off = 0, opt = -1;
+
+  if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
+  else {
+    if((colon_mode = *opts) == ':') off ++;
+    if(((mode = opts[off]) == '+') || (mode == '-')) {
+      off++;
+      if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
+        off ++;
+    }
+  }
+  my_optarg = 0;
+  if(charind) {
+    const char *s;
+    my_optopt = argv[my_optind][charind];
+    for(s=opts+off; *s; s++) if(my_optopt == *s) {
+      charind++;
+      if((*(++s) == ':') || ((my_optopt == 'W') && (*s == ';'))) {
+        if(argv[my_optind][charind]) {
+          my_optarg = &(argv[my_optind++][charind]);
+          charind = 0;
+        } else if(*(++s) != ':') {
+          charind = 0;
+          if(++my_optind >= argc) {
+            if(my_opterr) fprintf(stderr,
+                                "%s: option requires an argument -- %c\n",
+                                argv[0], my_optopt);
+            opt = (colon_mode == ':') ? ':' : '?';
+            goto my_getopt_ok;
+          }
+          my_optarg = argv[my_optind++];
+        }
+      }
+      opt = my_optopt;
+      goto my_getopt_ok;
+    }
+    if(my_opterr) fprintf(stderr,
+                        "%s: illegal option -- %c\n",
+                        argv[0], my_optopt);
+    opt = '?';
+    if(argv[my_optind][++charind] == '\0') {
+      my_optind++;
+      charind = 0;
+    }
+  my_getopt_ok:
+    if(charind && ! argv[my_optind][charind]) {
+      my_optind++;
+      charind = 0;
+    }
+  } else if((my_optind >= argc) ||
+             ((argv[my_optind][0] == '-') &&
+              (argv[my_optind][1] == '-') &&
+              (argv[my_optind][2] == '\0'))) {
+    my_optind++;
+    opt = -1;
+  } else if((argv[my_optind][0] != '-') ||
+             (argv[my_optind][1] == '\0')) {
+    char *tmp;
+    int i, j, k;
+
+    if(mode == '+') opt = -1;
+    else if(mode == '-') {
+      my_optarg = argv[my_optind++];
+      charind = 0;
+      opt = 1;
+    } else {
+      for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
+                                        (argv[i][1] != '\0')) {
+        my_optind=i;
+        opt=my_getopt(argc, argv, opts);
+        while(i > j) {
+          tmp=argv[--i];
+          for(k=i; k+1<my_optind; k++) argv[k]=argv[k+1];
+          argv[--my_optind]=tmp;
+        }
+        break;
+      }
+      if(i == argc) opt = -1;
+    }
+  } else {
+    charind++;
+    opt = my_getopt(argc, argv, opts);
+  }
+  if (my_optind > argc) my_optind = argc;
+  return opt;
+}
+
+/* this is the extended getopt_long{,_only}, with some GNU-like
+ * extensions. Implements _getopt_internal in case any programs
+ * expecting GNU libc getopt call it.
+ */
+
+int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
+                     const struct option *longopts, int *longind,
+                     int long_only)
+{
+  char mode, colon_mode = *shortopts;
+  int shortoff = 0, opt = -1;
+
+  if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
+  else {
+    if((colon_mode = *shortopts) == ':') shortoff ++;
+    if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
+      shortoff++;
+      if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
+        shortoff ++;
+    }
+  }
+  my_optarg = 0;
+  if((my_optind >= argc) ||
+      ((argv[my_optind][0] == '-') &&
+       (argv[my_optind][1] == '-') &&
+       (argv[my_optind][2] == '\0'))) {
+    my_optind++;
+    opt = -1;
+  } else if((argv[my_optind][0] != '-') ||
+            (argv[my_optind][1] == '\0')) {
+    char *tmp;
+    int i, j, k;
+
+    opt = -1;
+    if(mode == '+') return -1;
+    else if(mode == '-') {
+      my_optarg = argv[my_optind++];
+      return 1;
+    }
+    for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
+                                    (argv[i][1] != '\0')) {
+      my_optind=i;
+      opt=_my_getopt_internal(argc, argv, shortopts,
+                              longopts, longind,
+                              long_only);
+      while(i > j) {
+        tmp=argv[--i];
+        for(k=i; k+1<my_optind; k++)
+          argv[k]=argv[k+1];
+        argv[--my_optind]=tmp;
+      }
+      break;
+    }
+  } else if((!long_only) && (argv[my_optind][1] != '-'))
+    opt = my_getopt(argc, argv, shortopts);
+  else {
+    int charind, offset;
+    int found = 0, ind, hits = 0;
+
+    if(((my_optopt = argv[my_optind][1]) != '-') && ! argv[my_optind][2]) {
+      int c;
+
+      ind = shortoff;
+      while((c = shortopts[ind++])) {
+        if(((shortopts[ind] == ':') ||
+            ((c == 'W') && (shortopts[ind] == ';'))) &&
+           (shortopts[++ind] == ':'))
+          ind ++;
+        if(my_optopt == c) return my_getopt(argc, argv, shortopts);
+      }
+    }
+    offset = 2 - (argv[my_optind][1] != '-');
+    for(charind = offset;
+        (argv[my_optind][charind] != '\0') &&
+          (argv[my_optind][charind] != '=');
+        charind++);
+    for(ind = 0; longopts[ind].name && !hits; ind++)
+      if((strlen(longopts[ind].name) == (size_t) (charind - offset)) &&
+         (strncmp(longopts[ind].name,
+                  argv[my_optind] + offset, charind - offset) == 0))
+        found = ind, hits++;
+    if(!hits) for(ind = 0; longopts[ind].name; ind++)
+      if(strncmp(longopts[ind].name,
+                 argv[my_optind] + offset, charind - offset) == 0)
+        found = ind, hits++;
+    if(hits == 1) {
+      opt = 0;
+
+      if(argv[my_optind][charind] == '=') {
+        if(longopts[found].has_arg == 0) {
+          opt = '?';
+          if(my_opterr) fprintf(stderr,
+                             "%s: option `--%s' doesn't allow an argument\n",
+                             argv[0], longopts[found].name);
+        } else {
+          my_optarg = argv[my_optind] + ++charind;
+          charind = 0;
+        }
+      } else if(longopts[found].has_arg == 1) {
+        if(++my_optind >= argc) {
+          opt = (colon_mode == ':') ? ':' : '?';
+          if(my_opterr) fprintf(stderr,
+                             "%s: option `--%s' requires an argument\n",
+                             argv[0], longopts[found].name);
+        } else my_optarg = argv[my_optind];
+      }
+      if(!opt) {
+        if (longind) *longind = found;
+        if(!longopts[found].flag) opt = longopts[found].val;
+        else *(longopts[found].flag) = longopts[found].val;
+      }
+      my_optind++;
+    } else if(!hits) {
+      if(offset == 1) opt = my_getopt(argc, argv, shortopts);
+      else {
+        opt = '?';
+        if(my_opterr) fprintf(stderr,
+                           "%s: unrecognized option `%s'\n",
+                           argv[0], argv[my_optind++]);
+      }
+    } else {
+      opt = '?';
+      if(my_opterr) fprintf(stderr,
+                         "%s: option `%s' is ambiguous\n",
+                         argv[0], argv[my_optind++]);
+    }
+  }
+  if (my_optind > argc) my_optind = argc;
+  return opt;
+}
+
+int my_getopt_long(int argc, char * argv[], const char *shortopts,
+                const struct option *longopts, int *longind)
+{
+  return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
+}
+
+int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
+                const struct option *longopts, int *longind)
+{
+  return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
+}
diff --git a/client/windows/my_getopt.h b/client/windows/my_getopt.h
new file mode 100644
index 0000000..c75101a
--- /dev/null
+++ b/client/windows/my_getopt.h
@@ -0,0 +1,72 @@
+/*
+ *  my_getopt.h - interface to my re-implementation of getopt.
+ *  Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
+ *
+ *  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.
+ */
+
+#ifndef MY_GETOPT_H_INCLUDED
+#define MY_GETOPT_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* reset argument parser to start-up values */
+extern int my_getopt_reset(void);
+
+/* UNIX-style short-argument parser */
+extern int my_getopt(int argc, char * argv[], const char *opts);
+
+extern int my_optind, my_opterr, my_optopt;
+extern char *my_optarg;
+
+struct option {
+  const char *name;
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* human-readable values for has_arg */
+#undef no_argument
+#define no_argument 0
+#undef required_argument
+#define required_argument 1
+#undef optional_argument
+#define optional_argument 2
+
+/* GNU-style long-argument parsers */
+extern int my_getopt_long(int argc, char * argv[], const char *shortopts,
+                       const struct option *longopts, int *longind);
+
+extern int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+extern int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MY_GETOPT_H_INCLUDED */
commit b34fd7432d61b992446a3cd9c6f8eb7747ba0a76
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Mar 14 19:34:35 2012 +0100

    Use the spice-common logging functions
    
    It will abort by default for critical level messages. That behaviour
    can be tuned at runtime.

diff --git a/.gitignore b/.gitignore
index 6c15c13..e66f617 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ Makefile
 Makefile.in
 spice-server.pc
 stamp-h1
+INSTALL
diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
index 71ff49b..7584b52 100644
--- a/server/agent-msg-filter.c
+++ b/server/agent-msg-filter.c
@@ -39,7 +39,7 @@ int agent_msg_filter_process_data(struct AgentMsgFilter *filter,
     struct VDAgentMessage msg_header;
 
     if (len > VD_AGENT_MAX_DATA_SIZE) {
-        red_printf("invalid agent message: too large");
+        spice_printerr("invalid agent message: too large");
         return AGENT_MSG_FILTER_PROTO_ERROR;
     }
 
@@ -47,7 +47,7 @@ int agent_msg_filter_process_data(struct AgentMsgFilter *filter,
     if (filter->msg_data_to_read) {
 data_to_read:
         if (len > filter->msg_data_to_read) {
-            red_printf("invalid agent message: data exceeds size from header");
+            spice_printerr("invalid agent message: data exceeds size from header");
             return AGENT_MSG_FILTER_PROTO_ERROR;
         }
         filter->msg_data_to_read -= len;
@@ -55,14 +55,14 @@ data_to_read:
     }
 
     if (len < sizeof(msg_header)) {
-        red_printf("invalid agent message: incomplete header");
+        spice_printerr("invalid agent message: incomplete header");
         return AGENT_MSG_FILTER_PROTO_ERROR;
     }
     memcpy(&msg_header, data, sizeof(msg_header));
     len -= sizeof(msg_header);
 
     if (msg_header.protocol != VD_AGENT_PROTOCOL) {
-        red_printf("invalid agent protocol: %u", msg_header.protocol);
+        spice_printerr("invalid agent protocol: %u", msg_header.protocol);
         return AGENT_MSG_FILTER_PROTO_ERROR;
     }
 
diff --git a/server/dispatcher.c b/server/dispatcher.c
index c15a7a1..cc20f89 100644
--- a/server/dispatcher.c
+++ b/server/dispatcher.c
@@ -27,14 +27,12 @@
 #include <fcntl.h>
 #include <poll.h>
 
+#define SPICE_LOG_DOMAIN "SpiceDispatcher"
+
 #include "common/mem.h"
 #include "common/spice_common.h"
-
 #include "dispatcher.h"
 
-#define DISPATCHER_DEBUG_PRINTF(level, ...) \
-    red_printf_debug(level, "DISP", ##__VA_ARGS__)
-
 //#define DEBUG_DISPATCHER
 
 #ifdef DEBUG_DISPATCHER
@@ -64,10 +62,10 @@ static int read_safe(int fd, void *buf, size_t size, int block)
     if (!block) {
         while ((ret = poll(&pollfd, 1, 0)) == -1) {
             if (errno == EINTR) {
-                DISPATCHER_DEBUG_PRINTF(3, "EINTR in poll");
+                spice_debug("EINTR in poll");
                 continue;
             }
-            red_error("poll failed");
+            spice_error("poll failed");
             return -1;
         }
         if (!(pollfd.revents & POLLIN)) {
@@ -78,13 +76,13 @@ static int read_safe(int fd, void *buf, size_t size, int block)
         ret = read(fd, buf + read_size, size - read_size);
         if (ret == -1) {
             if (errno == EINTR) {
-                DISPATCHER_DEBUG_PRINTF(3, "EINTR in read");
+                spice_debug("EINTR in read");
                 continue;
             }
             return -1;
         }
         if (ret == 0) {
-            red_error("broken pipe on read");
+            spice_error("broken pipe on read");
             return -1;
         }
         read_size += ret;
@@ -105,7 +103,7 @@ static int write_safe(int fd, void *buf, size_t size)
         ret = write(fd, buf + written_size, size - written_size);
         if (ret == -1) {
             if (errno != EINTR) {
-                DISPATCHER_DEBUG_PRINTF(3, "EINTR in write\n");
+                spice_debug("EINTR in write");
                 return -1;
             }
             continue;
@@ -124,7 +122,7 @@ static int dispatcher_handle_single_read(Dispatcher *dispatcher)
     uint32_t ack = ACK;
 
     if ((ret = read_safe(dispatcher->recv_fd, &type, sizeof(type), 0)) == -1) {
-        red_printf("error reading from dispatcher: %d", errno);
+        spice_printerr("error reading from dispatcher: %d", errno);
         return 0;
     }
     if (ret == 0) {
@@ -133,19 +131,19 @@ static int dispatcher_handle_single_read(Dispatcher *dispatcher)
     }
     msg = &dispatcher->messages[type];
     if (read_safe(dispatcher->recv_fd, payload, msg->size, 1) == -1) {
-        red_printf("error reading from dispatcher: %d", errno);
+        spice_printerr("error reading from dispatcher: %d", errno);
         /* TODO: close socketpair? */
         return 0;
     }
     if (msg->handler) {
         msg->handler(dispatcher->opaque, (void *)payload);
     } else {
-        red_printf("error: no handler for message type %d", type);
+        spice_printerr("error: no handler for message type %d", type);
     }
     if (msg->ack == DISPATCHER_ACK) {
         if (write_safe(dispatcher->recv_fd,
                        &ack, sizeof(ack)) == -1) {
-            red_printf("error writing ack for message %d", type);
+            spice_printerr("error writing ack for message %d", type);
             /* TODO: close socketpair? */
         }
     } else if (msg->ack == DISPATCHER_ASYNC && dispatcher->handle_async_done) {
@@ -177,20 +175,20 @@ void dispatcher_send_message(Dispatcher *dispatcher, uint32_t message_type,
     msg = &dispatcher->messages[message_type];
     pthread_mutex_lock(&dispatcher->lock);
     if (write_safe(send_fd, &message_type, sizeof(message_type)) == -1) {
-        red_printf("error: failed to send message type for message %d",
+        spice_printerr("error: failed to send message type for message %d",
                    message_type);
         goto unlock;
     }
     if (write_safe(send_fd, payload, msg->size) == -1) {
-        red_printf("error: failed to send message body for message %d",
+        spice_printerr("error: failed to send message body for message %d",
                    message_type);
         goto unlock;
     }
     if (msg->ack == DISPATCHER_ACK) {
         if (read_safe(send_fd, &ack, sizeof(ack), 1) == -1) {
-            red_printf("error: failed to read ack");
+            spice_printerr("error: failed to read ack");
         } else if (ack != ACK) {
-            red_printf("error: got wrong ack value in dispatcher "
+            spice_printerr("error: got wrong ack value in dispatcher "
                        "for message %d\n", message_type);
             /* TODO handling error? */
         }
@@ -259,7 +257,7 @@ void dispatcher_init(Dispatcher *dispatcher, size_t max_message_type,
 #endif
     dispatcher->opaque = opaque;
     if (socketpair(AF_LOCAL, SOCK_STREAM, 0, channels) == -1) {
-        red_error("socketpair failed %s", strerror(errno));
+        spice_error("socketpair failed %s", strerror(errno));
         return;
     }
     pthread_mutex_init(&dispatcher->lock, NULL);
diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index da4c53c..ad247f4 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -115,7 +115,7 @@ int inputs_inited(void)
 int inputs_set_keyboard(SpiceKbdInstance *_keyboard)
 {
     if (keyboard) {
-        red_printf("already have keyboard");
+        spice_printerr("already have keyboard");
         return -1;
     }
     keyboard = _keyboard;
@@ -126,7 +126,7 @@ int inputs_set_keyboard(SpiceKbdInstance *_keyboard)
 int inputs_set_mouse(SpiceMouseInstance *_mouse)
 {
     if (mouse) {
-        red_printf("already have mouse");
+        spice_printerr("already have mouse");
         return -1;
     }
     mouse = _mouse;
@@ -137,7 +137,7 @@ int inputs_set_mouse(SpiceMouseInstance *_mouse)
 int inputs_set_tablet(SpiceTabletInstance *_tablet)
 {
     if (tablet) {
-        red_printf("already have tablet");
+        spice_printerr("already have tablet");
         return -1;
     }
     tablet = _tablet;
@@ -152,7 +152,7 @@ int inputs_has_tablet(void)
 
 void inputs_detach_tablet(SpiceTabletInstance *_tablet)
 {
-    red_printf("");
+    spice_printerr("");
     tablet = NULL;
 }
 
@@ -166,7 +166,7 @@ void inputs_set_tablet_logical_size(int x_res, int y_res)
 
 const VDAgentMouseState *inputs_get_mouse_state(void)
 {
-    ASSERT(g_inputs_channel);
+    spice_assert(g_inputs_channel);
     return &g_inputs_channel->mouse_state;
 }
 
@@ -177,7 +177,7 @@ static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
     InputsChannel *inputs_channel = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
 
     if (size > RECEIVE_BUF_SIZE) {
-        red_printf("error: too large incoming message");
+        spice_printerr("error: too large incoming message");
         return NULL;
     }
     return inputs_channel->recv_buf;
@@ -291,7 +291,7 @@ static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, ui
     InputsChannelClient *icc = (InputsChannelClient *)rcc;
     uint8_t *buf = (uint8_t *)message;
 
-    ASSERT(g_inputs_channel == inputs_channel);
+    spice_assert(g_inputs_channel == inputs_channel);
     switch (type) {
     case SPICE_MSGC_INPUTS_KEY_DOWN: {
         SpiceMsgcKeyDown *key_up = (SpiceMsgcKeyDown *)buf;
@@ -333,7 +333,7 @@ static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, ui
         if (reds_get_mouse_mode() != SPICE_MOUSE_MODE_CLIENT) {
             break;
         }
-        ASSERT((reds_get_agent_mouse() && reds_has_vdagent()) || tablet);
+        spice_assert((reds_get_agent_mouse() && reds_has_vdagent()) || tablet);
         if (!reds_get_agent_mouse() || !reds_has_vdagent()) {
             SpiceTabletInterface *sif;
             sif = SPICE_CONTAINEROF(tablet->base.sif, SpiceTabletInterface, base);
@@ -425,7 +425,7 @@ static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, ui
     case SPICE_MSGC_DISCONNECTING:
         break;
     default:
-        red_printf("unexpected type %d", type);
+        spice_printerr("unexpected type %d", type);
         return FALSE;
     }
     return TRUE;
@@ -451,7 +451,7 @@ static void inputs_channel_on_disconnect(RedChannelClient *rcc)
 
 static void inputs_migrate(RedChannelClient *rcc)
 {
-    ASSERT(g_inputs_channel == (InputsChannel *)rcc->channel);
+    spice_assert(g_inputs_channel == (InputsChannel *)rcc->channel);
     red_channel_client_pipe_add_type(rcc, PIPE_ITEM_MIGRATE);
 }
 
@@ -473,7 +473,7 @@ static int inputs_channel_config_socket(RedChannelClient *rcc)
     if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY,
             &delay_val, sizeof(delay_val)) == -1) {
         if (errno != ENOTSUP && errno != ENOPROTOOPT) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
             return FALSE;
         }
     }
@@ -492,10 +492,10 @@ static void inputs_connect(RedChannel *channel, RedClient *client,
 {
     InputsChannelClient *icc;
 
-    ASSERT(g_inputs_channel);
-    ASSERT(channel == &g_inputs_channel->base);
+    spice_assert(g_inputs_channel);
+    spice_assert(channel == &g_inputs_channel->base);
 
-    red_printf("inputs channel client create");
+    spice_printerr("inputs channel client create");
     icc = (InputsChannelClient*)red_channel_client_create(sizeof(InputsChannelClient),
                                                           channel,
                                                           client,
@@ -530,7 +530,7 @@ void inputs_init(void)
     ChannelCbs channel_cbs = { NULL, };
     ClientCbs client_cbs = { NULL, };
 
-    ASSERT(!g_inputs_channel);
+    spice_assert(!g_inputs_channel);
 
     channel_cbs.config_socket = inputs_channel_config_socket;
     channel_cbs.on_disconnect = inputs_channel_on_disconnect;
@@ -551,7 +551,7 @@ void inputs_init(void)
                                     &channel_cbs);
 
     if (!g_inputs_channel) {
-        red_error("failed to allocate Inputs Channel");
+        spice_error("failed to allocate Inputs Channel");
     }
 
     client_cbs.connect = inputs_connect;
@@ -561,6 +561,6 @@ void inputs_init(void)
     reds_register_channel(&g_inputs_channel->base);
 
     if (!(key_modifiers_timer = core->timer_add(key_modifiers_sender, NULL))) {
-        red_error("key modifiers timer create failed");
+        spice_error("key modifiers timer create failed");
     }
 }
diff --git a/server/jpeg_encoder.c b/server/jpeg_encoder.c
index d0e2fc1..01732ff 100644
--- a/server/jpeg_encoder.c
+++ b/server/jpeg_encoder.c
@@ -49,7 +49,7 @@ static void dest_mgr_init_destination(j_compress_ptr cinfo)
                                                             &enc->dest_mgr.next_output_byte);
 
         if (enc->dest_mgr.free_in_buffer == 0) {
-            red_error("not enough space");
+            spice_error("not enough space");
         }
     }
 
@@ -63,7 +63,7 @@ static boolean dest_mgr_empty_output_buffer(j_compress_ptr cinfo)
                                                         &enc->dest_mgr.next_output_byte);
 
     if (enc->dest_mgr.free_in_buffer == 0) {
-        red_error("not enough space");
+        spice_error("not enough space");
     }
     enc->cur_image.out_size += enc->dest_mgr.free_in_buffer;
     return TRUE;
@@ -110,7 +110,7 @@ static void convert_RGB16_to_RGB24(uint8_t *line, int width, uint8_t **out_line)
     uint8_t *out_pix;
     int x;
 
-    ASSERT(out_line && *out_line);
+    spice_assert(out_line && *out_line);
 
     out_pix = *out_line;
 
@@ -127,7 +127,7 @@ static void convert_BGR24_to_RGB24(uint8_t *line, int width, uint8_t **out_line)
     int x;
     uint8_t *out_pix;
 
-    ASSERT(out_line && *out_line);
+    spice_assert(out_line && *out_line);
 
     out_pix = *out_line;
 
@@ -145,7 +145,7 @@ static void convert_BGRX32_to_RGB24(uint8_t *line, int width, uint8_t **out_line
     uint8_t *out_pix;
     int x;
 
-    ASSERT(out_line && *out_line);
+    spice_assert(out_line && *out_line);
 
     out_pix = *out_line;
 
@@ -167,7 +167,7 @@ static void convert_RGB24_to_RGB24(uint8_t *line, int width, uint8_t **out_line)
     if (lines == lines_end) {                                           \
         int n = jpeg->usr->more_lines(jpeg->usr, &lines);               \
         if (n <= 0) {                                                   \
-            red_error("more lines failed\n");                           \
+            spice_error("more lines failed");                           \
         }                                                               \
         lines_end = lines + n * stride;                                 \
     }                                                                   \
@@ -226,7 +226,7 @@ int jpeg_encode(JpegEncoderContext *jpeg, int quality, JpegEncoderImageType type
         enc->cur_image.convert_line_to_RGB24 = convert_BGRX32_to_RGB24;
         break;
     default:
-        red_error("bad image type");
+        spice_error("bad image type");
     }
 
     enc->cinfo.image_width = width;
diff --git a/server/main_channel.c b/server/main_channel.c
index 7a2938c..713f121 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -162,7 +162,7 @@ int main_channel_is_connected(MainChannel *main_chan)
 // real disconnection of main channel
 static void main_channel_client_on_disconnect(RedChannelClient *rcc)
 {
-    red_printf("rcc=%p", rcc);
+    spice_printerr("rcc=%p", rcc);
     reds_client_disconnect(rcc->client);
 //    red_channel_client_disconnect(rcc);
 }
@@ -333,7 +333,7 @@ static PipeItem *main_multi_media_time_item_new(
 static void main_channel_push_channels(MainChannelClient *mcc)
 {
     if (red_client_during_migrate_at_target(mcc->base.client)) {
-        red_printf("warning: ignoring unexpected SPICE_MSGC_MAIN_ATTACH_CHANNELS"
+        spice_printerr("warning: ignoring unexpected SPICE_MSGC_MAIN_ATTACH_CHANNELS"
                    "during migration");
         return;
     }
@@ -482,7 +482,7 @@ static uint64_t main_channel_handle_migrate_data_get_serial(RedChannelClient *ba
     MainMigrateData *data = message;
 
     if (size < sizeof(*data)) {
-        red_printf("bad message size");
+        spice_printerr("bad message size");
         return 0;
     }
     return data->serial;
@@ -495,7 +495,7 @@ static uint64_t main_channel_handle_migrate_data(RedChannelClient *base,
     MainMigrateData *data = message;
 
     if (size < sizeof(*data)) {
-        red_printf("bad message size");
+        spice_printerr("bad message size");
         return FALSE;
     }
     mcc->ping_id = data->ping_id;
@@ -636,7 +636,7 @@ void main_channel_push_multi_media_time(MainChannel *main_chan, int time)
 
 static void main_channel_fill_mig_target(MainChannel *main_channel, RedsMigSpice *mig_target)
 {
-    ASSERT(mig_target);
+    spice_assert(mig_target);
     free(main_channel->mig_target.host);
     main_channel->mig_target.host = spice_strdup(mig_target->host);
     free(main_channel->mig_target.cert_subject);
@@ -658,7 +658,7 @@ static void main_channel_marshall_migrate_switch(SpiceMarshaller *m, RedChannelC
     SpiceMsgMainMigrationSwitchHost migrate;
     MainChannel *main_ch;
 
-    red_printf("");
+    spice_printerr("");
     main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
     migrate.port = main_ch->mig_target.port;
     migrate.sport = main_ch->mig_target.sport;
@@ -689,7 +689,7 @@ static void main_channel_send_item(RedChannelClient *rcc, PipeItem *base)
     SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
 
     if (!mcc->init_sent && base->type != SPICE_MSG_MAIN_INIT) {
-        red_printf("Init msg for client %p was not sent yet "
+        spice_printerr("Init msg for client %p was not sent yet "
                    "(client is probably during migration). Ignoring msg type %d",
                    rcc->client, base->type);
         main_channel_release_pipe_item(rcc, base, FALSE);
@@ -769,8 +769,8 @@ static void main_channel_release_pipe_item(RedChannelClient *rcc,
         case SPICE_MSG_MAIN_AGENT_DATA: {
             AgentDataPipeItem *data = (AgentDataPipeItem*)base;
             if (!--data->refs->refs) {
-                red_printf_debug(1, "MAIN", "SPICE_MSG_MAIN_AGENT_DATA %p %p, %d",
-                                 data, data->refs, data->refs->refs);
+                spice_debug("SPICE_MSG_MAIN_AGENT_DATA %p %p, %d",
+                            data, data->refs, data->refs->refs);
                 free(data->refs);
                 data->free_data(data->data, data->opaque);
             }
@@ -784,19 +784,19 @@ static void main_channel_release_pipe_item(RedChannelClient *rcc,
 
 void main_channel_client_handle_migrate_connected(MainChannelClient *mcc, int success)
 {
-    red_printf("client %p connected: %d", mcc->base.client, success);
+    spice_printerr("client %p connected: %d", mcc->base.client, success);
     if (mcc->mig_wait_connect) {
         MainChannel *main_channel = SPICE_CONTAINEROF(mcc->base.channel, MainChannel, base);
 
         mcc->mig_wait_connect = FALSE;
         mcc->mig_connect_ok = success;
-        ASSERT(main_channel->num_clients_mig_wait);
+        spice_assert(main_channel->num_clients_mig_wait);
         if (!--main_channel->num_clients_mig_wait) {
             reds_on_main_migrate_connected();
         }
     } else {
         if (success) {
-            red_printf("client %p MIGRATE_CANCEL", mcc->base.client);
+            spice_printerr("client %p MIGRATE_CANCEL", mcc->base.client);
             red_channel_client_pipe_add_type(&mcc->base, SPICE_MSG_MAIN_MIGRATE_CANCEL);
         }
     }
@@ -805,12 +805,12 @@ void main_channel_client_handle_migrate_connected(MainChannelClient *mcc, int su
 void main_channel_client_handle_migrate_end(MainChannelClient *mcc)
 {
     if (!red_client_during_migrate_at_target(mcc->base.client)) {
-        red_printf("unexpected SPICE_MSGC_MIGRATE_END");
+        spice_printerr("unexpected SPICE_MSGC_MIGRATE_END");
         return;
     }
     if (!red_channel_client_test_remote_cap(&mcc->base,
                                             SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE)) {
-        red_printf("unexpected SPICE_MSGC_MIGRATE_END, "
+        spice_printerr("unexpected SPICE_MSGC_MIGRATE_END, "
                    "client does not support semi-seamless migration");
             return;
     }
@@ -829,7 +829,7 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
 
     switch (type) {
     case SPICE_MSGC_MAIN_AGENT_START:
-        red_printf("agent start");
+        spice_printerr("agent start");
         if (!main_chan) {
             return FALSE;
         }
@@ -877,14 +877,14 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
                 if (roundtrip <= mcc->latency) {
                     // probably high load on client or server result with incorrect values
                     mcc->latency = 0;
-                    red_printf("net test: invalid values, latency %" PRIu64
+                    spice_printerr("net test: invalid values, latency %" PRIu64
                                " roundtrip %" PRIu64 ". assuming high"
                                "bandwidth", mcc->latency, roundtrip);
                     break;
                 }
                 mcc->bitrate_per_sec = (uint64_t)(NET_TEST_BYTES * 8) * 1000000
                                         / (roundtrip - mcc->latency);
-                red_printf("net test: latency %f ms, bitrate %"PRIu64" bps (%f Mbps)%s",
+                spice_printerr("net test: latency %f ms, bitrate %"PRIu64" bps (%f Mbps)%s",
                            (double)mcc->latency / 1000,
                            mcc->bitrate_per_sec,
                            (double)mcc->bitrate_per_sec / 1024 / 1024,
@@ -892,7 +892,7 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
                 mcc->net_test_stage = NET_TEST_STAGE_INVALID;
                 break;
             default:
-                red_printf("invalid net test stage, ping id %d test id %d stage %d",
+                spice_printerr("invalid net test stage, ping id %d test id %d stage %d",
                            ping->id,
                            mcc->net_test_id,
                            mcc->net_test_stage);
@@ -914,7 +914,7 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
         main_channel_client_handle_migrate_end(mcc);
         break;
     default:
-        red_printf("unexpected type %d", type);
+        spice_printerr("unexpected type %d", type);
     }
     return TRUE;
 }
@@ -955,7 +955,7 @@ static int main_channel_handle_migrate_flush_mark(RedChannelClient *rcc)
 static void do_ping_client(MainChannelClient *mcc,
     const char *opt, int has_interval, int interval)
 {
-    red_printf("");
+    spice_printerr("");
     if (!opt) {
         main_channel_client_push_ping(mcc, 0);
     } else if (!strcmp(opt, "on")) {
@@ -975,7 +975,7 @@ static void ping_timer_cb(void *opaque)
     MainChannelClient *mcc = opaque;
 
     if (!red_channel_client_is_connected(&mcc->base)) {
-        red_printf("not connected to peer, ping off");
+        spice_printerr("not connected to peer, ping off");
         core->timer_cancel(mcc->ping_timer);
         return;
     }
@@ -1003,7 +1003,7 @@ static MainChannelClient *main_channel_client_create(MainChannel *main_chan, Red
     mcc->bitrate_per_sec = ~0;
 #ifdef RED_STATISTICS
     if (!(mcc->ping_timer = core->timer_add(ping_timer_cb, NULL))) {
-        red_error("ping timer create failed");
+        spice_error("ping timer create failed");
     }
     mcc->ping_interval = PING_INTERVAL;
 #endif
@@ -1017,12 +1017,12 @@ MainChannelClient *main_channel_link(MainChannel *channel, RedClient *client,
 {
     MainChannelClient *mcc;
 
-    ASSERT(channel);
+    spice_assert(channel);
 
     // TODO - migration - I removed it from channel creation, now put it
     // into usage somewhere (not an issue until we return migration to it's
     // former glory)
-    red_printf("add main channel client");
+    spice_printerr("add main channel client");
     mcc = main_channel_client_create(channel, client, stream, connection_id,
                                      num_common_caps, common_caps,
                                      num_caps, caps);
@@ -1083,14 +1083,14 @@ MainChannel* main_channel_init(void)
                                         spice_get_client_channel_parser(SPICE_CHANNEL_MAIN, NULL),
                                         main_channel_handle_parsed,
                                         &channel_cbs);
-    ASSERT(channel);
+    spice_assert(channel);
     red_channel_set_cap(channel, SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
     return (MainChannel *)channel;
 }
 
 RedChannelClient* main_channel_client_get_base(MainChannelClient* mcc)
 {
-    ASSERT(mcc);
+    spice_assert(mcc);
     return &mcc->base;
 }
 
@@ -1107,7 +1107,7 @@ int main_channel_migrate_connect(MainChannel *main_channel, RedsMigSpice *mig_ta
         if (red_channel_client_test_remote_cap(&mcc->base,
                                                SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE)) {
             if (red_client_during_migrate_at_target(mcc->base.client)) {
-                red_printf("client %p: wait till previous migration completes", mcc->base.client);
+                spice_printerr("client %p: wait till previous migration completes", mcc->base.client);
                 mcc->mig_wait_prev_complete = TRUE;
             } else {
                 red_channel_client_pipe_add_type(&mcc->base, SPICE_MSG_MAIN_MIGRATE_BEGIN);
@@ -1129,7 +1129,7 @@ void main_channel_migrate_cancel_wait(MainChannel *main_chan)
 
         mcc = SPICE_CONTAINEROF(client_link, MainChannelClient, base.channel_link);
         if (mcc->mig_wait_connect) {
-            red_printf("client %p cancel wait connect", mcc->base.client);
+            spice_printerr("client %p cancel wait connect", mcc->base.client);
             mcc->mig_wait_connect = FALSE;
             mcc->mig_connect_ok = FALSE;
         }
@@ -1143,10 +1143,10 @@ int main_channel_migrate_complete(MainChannel *main_chan, int success)
     RingItem *client_link;
     int semi_seamless_count = 0;
 
-    red_printf("");
+    spice_printerr("");
 
     if (ring_is_empty(&main_chan->base.clients)) {
-        red_printf("no peer connected");
+        spice_printerr("no peer connected");
         return 0;
     }
 
@@ -1159,16 +1159,16 @@ int main_channel_migrate_complete(MainChannel *main_chan, int success)
                                                    SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
         if (semi_seamless_support && mcc->mig_connect_ok) {
             if (success) {
-                red_printf("client %p MIGRATE_END", mcc->base.client);
+                spice_printerr("client %p MIGRATE_END", mcc->base.client);
                 red_channel_client_pipe_add_type(&mcc->base, SPICE_MSG_MAIN_MIGRATE_END);
                 semi_seamless_count++;
             } else {
-                red_printf("client %p MIGRATE_CANCEL", mcc->base.client);
+                spice_printerr("client %p MIGRATE_CANCEL", mcc->base.client);
                 red_channel_client_pipe_add_type(&mcc->base, SPICE_MSG_MAIN_MIGRATE_CANCEL);
             }
         } else {
             if (success) {
-                red_printf("client %p SWITCH_HOST", mcc->base.client);
+                spice_printerr("client %p SWITCH_HOST", mcc->base.client);
                 red_channel_client_pipe_add_type(&mcc->base, SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST);
             }
         }
diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
index 6b68549..4692315 100644
--- a/server/mjpeg_encoder.c
+++ b/server/mjpeg_encoder.c
@@ -228,7 +228,7 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
 #endif
         break;
     default:
-        red_printf_some(1000, "unsupported format %d", format);
+        spice_warning("unsupported format %d", format);
         return FALSE;
     }
 
diff --git a/server/red_channel.c b/server/red_channel.c
index f27abed..4858bb5 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -89,7 +89,7 @@ static void full_header_set_msg_serial(SpiceDataHeaderOpaque *header, uint64_t s
 
 static void mini_header_set_msg_serial(SpiceDataHeaderOpaque *header, uint64_t serial)
 {
-    red_error("attempt to set header serial on mini header");
+    spice_error("attempt to set header serial on mini header");
 }
 
 static void full_header_set_msg_sub_list(SpiceDataHeaderOpaque *header, uint32_t sub_list)
@@ -99,7 +99,7 @@ static void full_header_set_msg_sub_list(SpiceDataHeaderOpaque *header, uint32_t
 
 static void mini_header_set_msg_sub_list(SpiceDataHeaderOpaque *header, uint32_t sub_list)
 {
-    red_error("attempt to set header sub list on mini header");
+    spice_error("attempt to set header sub list on mini header");
 }
 
 static SpiceDataHeaderOpaque full_header_wrapper = {NULL, sizeof(SpiceDataHeader),
@@ -132,7 +132,7 @@ static int red_peer_receive(RedsStream *stream, uint8_t *buf, uint32_t size)
             if (now == 0) {
                 return -1;
             }
-            ASSERT(now == -1);
+            spice_assert(now == -1);
             if (errno == EAGAIN) {
                 break;
             } else if (errno == EINTR) {
@@ -140,7 +140,7 @@ static int red_peer_receive(RedsStream *stream, uint8_t *buf, uint32_t size)
             } else if (errno == EPIPE) {
                 return -1;
             } else {
-                red_printf("%s", strerror(errno));
+                spice_printerr("%s", strerror(errno));
                 return -1;
             }
         } else {
@@ -193,7 +193,7 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
             if (!handler->msg) {
                 handler->msg = handler->cb->alloc_msg_buf(handler->opaque, msg_type, msg_size);
                 if (handler->msg == NULL) {
-                    red_printf("ERROR: channel refused to allocate buffer.");
+                    spice_printerr("ERROR: channel refused to allocate buffer.");
                     handler->cb->on_error(handler->opaque);
                     return;
                 }
@@ -218,7 +218,7 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
                 handler->msg + msg_size, msg_type,
                 SPICE_VERSION_MINOR, &parsed_size, &parsed_free);
             if (parsed == NULL) {
-                red_printf("failed to parse message type %d", msg_type);
+                spice_printerr("failed to parse message type %d", msg_type);
                 handler->cb->release_msg_buf(handler->opaque, msg_type, msg_size, handler->msg);
                 handler->cb->on_error(handler->opaque);
                 return;
@@ -285,7 +285,7 @@ static void red_peer_handle_outgoing(RedsStream *stream, OutgoingHandler *handle
                 handler->cb->on_error(handler->opaque);
                 return;
             default:
-                red_printf("%s", strerror(errno));
+                spice_printerr("%s", strerror(errno));
                 handler->cb->on_error(handler->opaque);
                 return;
             }
@@ -362,7 +362,7 @@ static void red_channel_client_reset_send_data(RedChannelClient *rcc)
      * has been called before, but no message has been sent since then.
      */
     if (rcc->send_data.last_sent_serial != rcc->send_data.serial) {
-        ASSERT(rcc->send_data.serial - rcc->send_data.last_sent_serial == 1);
+        spice_assert(rcc->send_data.serial - rcc->send_data.last_sent_serial == 1);
         /*  When the urgent marshaller is active, the serial was incremented by
          *  the call to reset_send_data that was made for the main marshaller.
          *  The urgent msg receives this serial, and the main msg serial is
@@ -375,7 +375,7 @@ static void red_channel_client_reset_send_data(RedChannelClient *rcc)
     rcc->send_data.serial++;
 
     if (!rcc->is_mini_header) {
-        ASSERT(rcc->send_data.marshaller != rcc->send_data.urgent.marshaller);
+        spice_assert(rcc->send_data.marshaller != rcc->send_data.urgent.marshaller);
         rcc->send_data.header.set_msg_sub_list(&rcc->send_data.header, 0);
         rcc->send_data.header.set_msg_serial(&rcc->send_data.header, rcc->send_data.serial);
     }
@@ -395,7 +395,7 @@ static void red_channel_client_send_set_ack(RedChannelClient *rcc)
 {
     SpiceMsgSetAck ack;
 
-    ASSERT(rcc);
+    spice_assert(rcc);
     red_channel_client_init_send_data(rcc, SPICE_MSG_SET_ACK, NULL);
     ack.generation = ++rcc->ack_data.generation;
     ack.window = rcc->ack_data.client_window;
@@ -410,7 +410,7 @@ static void red_channel_client_send_item(RedChannelClient *rcc, PipeItem *item)
 {
     int handled = TRUE;
 
-    ASSERT(red_channel_client_no_item_being_sent(rcc));
+    spice_assert(red_channel_client_no_item_being_sent(rcc));
     red_channel_client_reset_send_data(rcc);
     switch (item->type) {
         case PIPE_ITEM_TYPE_SET_ACK:
@@ -463,7 +463,7 @@ static void red_channel_peer_on_out_msg_done(void *opaque)
 
     if (red_channel_client_urgent_marshaller_is_active(rcc)) {
         red_channel_client_restore_main_sender(rcc);
-        ASSERT(rcc->send_data.header.data != NULL);
+        spice_assert(rcc->send_data.header.data != NULL);
         red_channel_client_begin_send_message(rcc);
     }
 }
@@ -476,7 +476,7 @@ static void red_channel_client_pipe_remove(RedChannelClient *rcc, PipeItem *item
 
 static void red_channel_add_client(RedChannel *channel, RedChannelClient *rcc)
 {
-    ASSERT(rcc);
+    spice_assert(rcc);
     ring_add(&channel->clients, &rcc->channel_link);
     channel->clients_num++;
 }
@@ -521,7 +521,7 @@ RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedCl
 {
     RedChannelClient *rcc;
 
-    ASSERT(stream && channel && size >= sizeof(RedChannelClient));
+    spice_assert(stream && channel && size >= sizeof(RedChannelClient));
     rcc = spice_malloc0(size);
     rcc->stream = stream;
     rcc->channel = channel;
@@ -583,7 +583,7 @@ static void red_channel_client_default_connect(RedChannel *channel, RedClient *c
                                                int num_common_caps, uint32_t *common_caps,
                                                int num_caps, uint32_t *caps)
 {
-    red_error("not implemented");
+    spice_error("not implemented");
 }
 
 static void red_channel_client_default_disconnect(RedChannelClient *base)
@@ -605,8 +605,8 @@ RedChannel *red_channel_create(int size,
     RedChannel *channel;
     ClientCbs client_cbs = { NULL, };
 
-    ASSERT(size >= sizeof(*channel));
-    ASSERT(channel_cbs->config_socket && channel_cbs->on_disconnect && handle_message &&
+    spice_assert(size >= sizeof(*channel));
+    spice_assert(channel_cbs->config_socket && channel_cbs->on_disconnect && handle_message &&
            channel_cbs->alloc_recv_buf && channel_cbs->release_item);
     channel = spice_malloc0(size);
     channel->type = type;
@@ -672,7 +672,7 @@ RedChannel *red_channel_create_dummy(int size, uint32_t type, uint32_t id)
     RedChannel *channel;
     ClientCbs client_cbs = { NULL, };
 
-    ASSERT(size >= sizeof(*channel));
+    spice_assert(size >= sizeof(*channel));
     channel = spice_malloc0(size);
     channel->type = type;
     channel->id = id;
@@ -723,7 +723,7 @@ RedChannel *red_channel_create_parser(int size,
 
 void red_channel_register_client_cbs(RedChannel *channel, ClientCbs *client_cbs)
 {
-    ASSERT(client_cbs->connect);
+    spice_assert(client_cbs->connect);
     channel->client_cbs.connect = client_cbs->connect;
 
     if (client_cbs->disconnect) {
@@ -769,7 +769,7 @@ void red_channel_set_cap(RedChannel *channel, uint32_t cap)
 
 void red_channel_set_data(RedChannel *channel, void *data)
 {
-    ASSERT(channel);
+    spice_assert(channel);
     channel->data = data;
 }
 
@@ -876,7 +876,7 @@ void red_channel_client_push(RedChannelClient *rcc)
 
     if (!red_channel_client_no_item_being_sent(rcc) && !rcc->send_data.blocked) {
         rcc->send_data.blocked = TRUE;
-        red_printf("ERROR: an item waiting to be sent and not blocked");
+        spice_printerr("ERROR: an item waiting to be sent and not blocked");
     }
 
     while ((pipe_item = red_channel_client_pipe_item_get(rcc))) {
@@ -938,7 +938,7 @@ static void red_channel_handle_migrate_data(RedChannelClient *rcc, uint32_t size
     if (!rcc->channel->channel_cbs.handle_migrate_data) {
         return;
     }
-    ASSERT(red_channel_client_get_message_serial(rcc) == 0);
+    spice_assert(red_channel_client_get_message_serial(rcc) == 0);
     red_channel_client_set_message_serial(rcc,
         rcc->channel->channel_cbs.handle_migrate_data_get_serial(rcc, size, message));
     rcc->channel->channel_cbs.handle_migrate_data(rcc, size, message);
@@ -950,7 +950,7 @@ int red_channel_client_handle_message(RedChannelClient *rcc, uint32_t size,
     switch (type) {
     case SPICE_MSGC_ACK_SYNC:
         if (size != sizeof(uint32_t)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
         rcc->ack_data.client_generation = *(uint32_t *)(message);
@@ -970,7 +970,7 @@ int red_channel_client_handle_message(RedChannelClient *rcc, uint32_t size,
         red_channel_handle_migrate_data(rcc, size, message);
         break;
     default:
-        red_printf("invalid message type %u", type);
+        spice_printerr("invalid message type %u", type);
         return FALSE;
     }
     return TRUE;
@@ -990,8 +990,8 @@ static void red_channel_client_event(int fd, int event, void *data)
 
 void red_channel_client_init_send_data(RedChannelClient *rcc, uint16_t msg_type, PipeItem *item)
 {
-    ASSERT(red_channel_client_no_item_being_sent(rcc));
-    ASSERT(msg_type != 0);
+    spice_assert(red_channel_client_no_item_being_sent(rcc));
+    spice_assert(msg_type != 0);
     rcc->send_data.header.set_msg_type(&rcc->send_data.header, msg_type);
     rcc->send_data.item = item;
     if (item) {
@@ -1005,7 +1005,7 @@ void red_channel_client_begin_send_message(RedChannelClient *rcc)
 
     // TODO - better check: type in channel_allowed_types. Better: type in channel_allowed_types(channel_state)
     if (rcc->send_data.header.get_msg_type(&rcc->send_data.header) == 0) {
-        red_printf("BUG: header->type == 0");
+        spice_printerr("BUG: header->type == 0");
         return;
     }
     spice_marshaller_flush(m);
@@ -1020,8 +1020,8 @@ void red_channel_client_begin_send_message(RedChannelClient *rcc)
 
 SpiceMarshaller *red_channel_client_switch_to_urgent_sender(RedChannelClient *rcc)
 {
-    ASSERT(red_channel_client_no_item_being_sent(rcc));
-    ASSERT(rcc->send_data.header.data != NULL);
+    spice_assert(red_channel_client_no_item_being_sent(rcc));
+    spice_assert(rcc->send_data.header.data != NULL);
     rcc->send_data.main.header_data = rcc->send_data.header.data;
     rcc->send_data.main.item = rcc->send_data.item;
 
@@ -1060,7 +1060,7 @@ void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type)
 
 void red_channel_client_pipe_add(RedChannelClient *rcc, PipeItem *item)
 {
-    ASSERT(rcc && item);
+    spice_assert(rcc && item);
     rcc->pipe_size++;
     ring_add(&rcc->pipe, &item->link);
 }
@@ -1074,9 +1074,9 @@ void red_channel_client_pipe_add_push(RedChannelClient *rcc, PipeItem *item)
 void red_channel_client_pipe_add_after(RedChannelClient *rcc,
                                        PipeItem *item, PipeItem *pos)
 {
-    ASSERT(rcc);
-    ASSERT(pos);
-    ASSERT(item);
+    spice_assert(rcc);
+    spice_assert(pos);
+    spice_assert(item);
 
     rcc->pipe_size++;
     ring_add_after(&item->link, &pos->link);
@@ -1091,14 +1091,14 @@ int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc,
 void red_channel_client_pipe_add_tail_no_push(RedChannelClient *rcc,
                                               PipeItem *item)
 {
-    ASSERT(rcc);
+    spice_assert(rcc);
     rcc->pipe_size++;
     ring_add_before(&item->link, &rcc->pipe);
 }
 
 void red_channel_client_pipe_add_tail(RedChannelClient *rcc, PipeItem *item)
 {
-    ASSERT(rcc);
+    spice_assert(rcc);
     rcc->pipe_size++;
     ring_add_before(&item->link, &rcc->pipe);
     red_channel_client_push(rcc);
@@ -1170,9 +1170,9 @@ void red_channel_client_ack_set_client_window(RedChannelClient *rcc, int client_
 
 static void red_channel_remove_client(RedChannelClient *rcc)
 {
-    ASSERT(pthread_equal(pthread_self(), rcc->channel->thread_id));
+    spice_assert(pthread_equal(pthread_self(), rcc->channel->thread_id));
     ring_remove(&rcc->channel_link);
-    ASSERT(rcc->channel->clients_num > 0);
+    spice_assert(rcc->channel->clients_num > 0);
     rcc->channel->clients_num--;
     // TODO: should we set rcc->channel to NULL???
 }
@@ -1187,7 +1187,7 @@ static void red_client_remove_channel(RedChannelClient *rcc)
 
 void red_channel_client_disconnect(RedChannelClient *rcc)
 {
-    red_printf("%p (channel %p type %d id %d)", rcc, rcc->channel,
+    spice_printerr("%p (channel %p type %d id %d)", rcc, rcc->channel,
                                                 rcc->channel->type, rcc->channel->id);
     if (!red_channel_client_is_connected(rcc)) {
         return;
@@ -1222,7 +1222,7 @@ RedChannelClient *red_channel_client_create_dummy(int size,
 {
     RedChannelClient *rcc;
 
-    ASSERT(size >= sizeof(RedChannelClient));
+    spice_assert(size >= sizeof(RedChannelClient));
     rcc = spice_malloc0(size);
     rcc->client = client;
     rcc->channel = channel;
@@ -1416,8 +1416,8 @@ void red_client_migrate(RedClient *client)
     RingItem *link, *next;
     RedChannelClient *rcc;
 
-    red_printf("migrate client with #channels %d", client->channels_num);
-    ASSERT(pthread_equal(pthread_self(), client->thread_id));
+    spice_printerr("migrate client with #channels %d", client->channels_num);
+    spice_assert(pthread_equal(pthread_self(), client->thread_id));
     RING_FOREACH_SAFE(link, next, &client->channels) {
         rcc = SPICE_CONTAINEROF(link, RedChannelClient, client_link);
         if (red_channel_client_is_connected(rcc)) {
@@ -1431,8 +1431,8 @@ void red_client_destroy(RedClient *client)
     RingItem *link, *next;
     RedChannelClient *rcc;
 
-    red_printf("destroy client with #channels %d", client->channels_num);
-    ASSERT(pthread_equal(pthread_self(), client->thread_id));
+    spice_printerr("destroy client with #channels %d", client->channels_num);
+    spice_assert(pthread_equal(pthread_self(), client->thread_id));
     RING_FOREACH_SAFE(link, next, &client->channels) {
         // some channels may be in other threads, so disconnection
         // is not synchronous.
@@ -1444,9 +1444,9 @@ void red_client_destroy(RedClient *client)
         // TODO: should we go back to async. For this we need to use
         // ref count for channel clients.
         rcc->channel->client_cbs.disconnect(rcc);
-        ASSERT(ring_is_empty(&rcc->pipe));
-        ASSERT(rcc->pipe_size == 0);
-        ASSERT(rcc->send_data.size == 0);
+        spice_assert(ring_is_empty(&rcc->pipe));
+        spice_assert(rcc->pipe_size == 0);
+        spice_assert(rcc->send_data.size == 0);
         red_channel_client_destroy(rcc);
     }
 
@@ -1456,7 +1456,7 @@ void red_client_destroy(RedClient *client)
 
 static void red_client_add_channel(RedClient *client, RedChannelClient *rcc)
 {
-    ASSERT(rcc && client);
+    spice_assert(rcc && client);
     pthread_mutex_lock(&client->lock);
     ring_add(&client->channels, &rcc->client_link);
     client->channels_num++;
@@ -1473,7 +1473,7 @@ void red_client_set_main(RedClient *client, MainChannelClient *mcc) {
 
 void red_client_migrate_complete(RedClient *client)
 {
-    ASSERT(client->migrated);
+    spice_assert(client->migrated);
     client->migrated = FALSE;
     reds_on_client_migrate_complete(client);
 }
diff --git a/server/red_client_cache.h b/server/red_client_cache.h
index 0da11a6..dc314c0 100644
--- a/server/red_client_cache.h
+++ b/server/red_client_cache.h
@@ -63,11 +63,11 @@ static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, CacheItem *item)
 {
     CacheItem **now;
     CHANNEL *channel = CHANNEL_FROM_RCC(&channel_client->common.base);
-    ASSERT(item);
+    spice_assert(item);
 
     now = &channel_client->CACHE_NAME[CACHE_HASH_KEY(item->id)];
     for (;;) {
-        ASSERT(*now);
+        spice_assert(*now);
         if (*now == item) {
             *now = item->u.cache_data.next;
             break;
diff --git a/server/red_client_shared_cache.h b/server/red_client_shared_cache.h
index fb405c3..821ee18 100644
--- a/server/red_client_shared_cache.h
+++ b/server/red_client_shared_cache.h
@@ -49,7 +49,7 @@ static int FUNC_NAME(hit)(CACHE *cache, uint64_t id, int *lossy, DisplayChannelC
         if (item->id == id) {
             ring_remove(&item->lru_link);
             ring_add(&cache->lru, &item->lru_link);
-            ASSERT(dcc->common.id < MAX_CACHE_CLIENTS)
+            spice_assert(dcc->common.id < MAX_CACHE_CLIENTS);
             item->sync[dcc->common.id] = serial;
             cache->sync[dcc->common.id] = serial;
             *lossy = item->lossy;
@@ -86,7 +86,7 @@ static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, D
     uint64_t serial;
     int key;
 
-    ASSERT(size > 0);
+    spice_assert(size > 0);
 
     item = spice_new(NewCacheItem, 1);
     serial = red_channel_client_get_message_serial(&dcc->common.base);
@@ -119,7 +119,7 @@ static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, D
 
         now = &cache->hash_table[CACHE_HASH_KEY(tail->id)];
         for (;;) {
-            ASSERT(*now);
+            spice_assert(*now);
             if (*now == tail) {
                 *now = tail->next;
                 break;
@@ -217,7 +217,7 @@ static int FUNC_NAME(freeze)(CACHE *cache)
 
 static void FUNC_NAME(destroy)(CACHE *cache)
 {
-    ASSERT(cache);
+    spice_assert(cache);
 
     pthread_mutex_lock(&cache->lock);
     PRIVATE_FUNC_NAME(clear)(cache);
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 9a04948..6b96a2e 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -44,13 +44,6 @@
 
 static int num_active_workers = 0;
 
-//volatile
-
-#define DBG_ASYNC(s, ...)   \
-    do {                    \
-        red_printf_debug(2, "ASYNC", s, ##__VA_ARGS__);   \
-    } while (0)
-
 struct AsyncCommand {
     RingItem link;
     RedWorkerMessage message;
@@ -98,7 +91,7 @@ static void red_dispatcher_set_display_peer(RedChannel *channel, RedClient *clie
     RedWorkerMessageDisplayConnect payload;
     RedDispatcher *dispatcher;
 
-    red_printf("");
+    spice_printerr("");
     dispatcher = (RedDispatcher *)channel->data;
     payload.client = client;
     payload.stream = stream;
@@ -127,7 +120,7 @@ static void red_dispatcher_disconnect_display_peer(RedChannelClient *rcc)
 
     dispatcher = (RedDispatcher *)rcc->channel->data;
 
-    red_printf("");
+    spice_printerr("");
     payload.rcc = rcc;
 
     // TODO: we turned it to be sync, due to client_destroy . Should we support async? - for this we will need ref count
@@ -145,7 +138,7 @@ static void red_dispatcher_display_migrate(RedChannelClient *rcc)
         return;
     }
     dispatcher = (RedDispatcher *)rcc->channel->data;
-    red_printf("channel type %u id %u", rcc->channel->type, rcc->channel->id);
+    spice_printerr("channel type %u id %u", rcc->channel->type, rcc->channel->id);
     payload.rcc = rcc;
     dispatcher_send_message(&dispatcher->dispatcher,
                             RED_WORKER_MESSAGE_DISPLAY_MIGRATE,
@@ -159,7 +152,7 @@ static void red_dispatcher_set_cursor_peer(RedChannel *channel, RedClient *clien
 {
     RedWorkerMessageCursorConnect payload;
     RedDispatcher *dispatcher = (RedDispatcher *)channel->data;
-    red_printf("");
+    spice_printerr("");
     payload.client = client;
     payload.stream = stream;
     payload.migration = migration;
@@ -186,7 +179,7 @@ static void red_dispatcher_disconnect_cursor_peer(RedChannelClient *rcc)
     }
 
     dispatcher = (RedDispatcher *)rcc->channel->data;
-    red_printf("");
+    spice_printerr("");
     payload.rcc = rcc;
 
     dispatcher_send_message(&dispatcher->dispatcher,
@@ -203,7 +196,7 @@ static void red_dispatcher_cursor_migrate(RedChannelClient *rcc)
         return;
     }
     dispatcher = (RedDispatcher *)rcc->channel->data;
-    red_printf("channel type %u id %u", rcc->channel->type, rcc->channel->id);
+    spice_printerr("channel type %u id %u", rcc->channel->type, rcc->channel->id);
     payload.rcc = rcc;
     dispatcher_send_message(&dispatcher->dispatcher,
                             RED_WORKER_MESSAGE_CURSOR_MIGRATE,
@@ -313,7 +306,7 @@ static AsyncCommand *async_command_alloc(RedDispatcher *dispatcher,
     async_command->message = message;
     ring_add(&dispatcher->async_commands, &async_command->link);
     pthread_mutex_unlock(&dispatcher->async_lock);
-    DBG_ASYNC("%p", async_command);
+    spice_debug("%p", async_command);
     return async_command;
 }
 
@@ -675,7 +668,7 @@ static void red_dispatcher_loadvm_commands(RedDispatcher *dispatcher,
 {
     RedWorkerMessageLoadvmCommands payload;
 
-    red_printf("");
+    spice_printerr("");
     payload.count = count;
     payload.ext = ext;
     dispatcher_send_message(&dispatcher->dispatcher,
@@ -701,7 +694,7 @@ void red_dispatcher_set_mm_time(uint32_t mm_time)
 
 static inline int calc_compression_level(void)
 {
-    ASSERT(streaming_video != STREAM_VIDEO_INVALID);
+    spice_assert(streaming_video != STREAM_VIDEO_INVALID);
     if ((streaming_video != STREAM_VIDEO_OFF) ||
         (image_compression != SPICE_IMAGE_COMPRESS_QUIC)) {
         return 0;
@@ -920,9 +913,9 @@ void red_dispatcher_async_complete(struct RedDispatcher *dispatcher,
 {
     pthread_mutex_lock(&dispatcher->async_lock);
     ring_remove(&async_command->link);
-    DBG_ASYNC("%p: cookie %" PRId64, async_command, async_command->cookie);
+    spice_debug("%p: cookie %" PRId64, async_command, async_command->cookie);
     if (ring_is_empty(&dispatcher->async_commands)) {
-        red_printf_debug(2, "ASYNC", "no more async commands");
+        spice_debug("no more async commands");
     }
     pthread_mutex_unlock(&dispatcher->async_lock);
     switch (async_command->message) {
@@ -943,7 +936,7 @@ void red_dispatcher_async_complete(struct RedDispatcher *dispatcher,
     case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
         break;
     default:
-        WARN("unexpected message");
+        spice_warning("unexpected message %d", async_command->message);
     }
     dispatcher->qxl->st->qif->async_complete(dispatcher->qxl,
                                              async_command->cookie);
@@ -995,7 +988,7 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
 
     red_dispatcher = spice_new0(RedDispatcher, 1);
     ring_init(&red_dispatcher->async_commands);
-    DBG_ASYNC("red_dispatcher->async_commands.next %p", red_dispatcher->async_commands.next);
+    spice_debug("red_dispatcher->async_commands.next %p", red_dispatcher->async_commands.next);
     dispatcher_init(&red_dispatcher->dispatcher, RED_WORKER_MESSAGE_COUNT, NULL);
     init_data.qxl = red_dispatcher->qxl = qxl;
     init_data.id = qxl->id;
@@ -1046,12 +1039,12 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
     sigdelset(&thread_sig_mask, SIGSEGV);
     pthread_sigmask(SIG_SETMASK, &thread_sig_mask, &curr_sig_mask);
     if ((r = pthread_create(&red_dispatcher->worker_thread, NULL, red_worker_main, &init_data))) {
-        red_error("create thread failed %d", r);
+        spice_error("create thread failed %d", r);
     }
     pthread_sigmask(SIG_SETMASK, &curr_sig_mask, NULL);
 
     read_message(red_dispatcher->dispatcher.send_fd, &message);
-    ASSERT(message == RED_WORKER_MESSAGE_READY);
+    spice_assert(message == RED_WORKER_MESSAGE_READY);
 
     display_channel = red_dispatcher_display_channel_create(red_dispatcher);
 
diff --git a/server/red_memslots.c b/server/red_memslots.c
index 249b241..ae2c6e4 100644
--- a/server/red_memslots.c
+++ b/server/red_memslots.c
@@ -55,19 +55,19 @@ unsigned long get_virt_delta(RedMemSlotInfo *info, QXLPHYSICAL addr, int group_i
     int generation;
 
     if (group_id > info->num_memslots_groups) {
-        PANIC("group_id %d too big", group_id);
+        spice_critical("group_id %d too big", group_id);
     }
 
     slot_id = get_memslot_id(info, addr);
     if (slot_id > info->num_memslots) {
-        PANIC("slot_id %d too big", slot_id);
+        spice_critical("slot_id %d too big", slot_id);
     }
 
     slot = &info->mem_slots[group_id][slot_id];
 
     generation = get_generation(info, addr);
     if (generation != slot->generation) {
-        PANIC("address generation is not valid");
+        spice_critical("address generation is not valid");
     }
 
     return (slot->address_delta - (addr - __get_clean_virt(info, addr)));
@@ -80,12 +80,12 @@ void validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
 
     slot = &info->mem_slots[group_id][slot_id];
     if ((virt + add_size) < virt) {
-        PANIC("virtual address overlap");
+        spice_critical("virtual address overlap");
     }
 
     if (virt < slot->virt_start_addr || (virt + add_size) > slot->virt_end_addr) {
         print_memslots(info);
-        PANIC("virtual address out of range\n"
+        spice_critical("virtual address out of range\n"
               "    virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
               "    slot=0x%lx-0x%lx delta=0x%lx",
               virt, add_size, slot_id, group_id,
@@ -103,13 +103,13 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
     MemSlot *slot;
 
     if (group_id > info->num_memslots_groups) {
-        PANIC("group_id too big");
+        spice_critical("group_id too big");
     }
 
     slot_id = get_memslot_id(info, addr);
     if (slot_id > info->num_memslots) {
         print_memslots(info);
-        PANIC("slot_id too big, addr=%" PRIx64, addr);
+        spice_critical("slot_id too big, addr=%" PRIx64, addr);
     }
 
     slot = &info->mem_slots[group_id][slot_id];
@@ -117,7 +117,7 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
     generation = get_generation(info, addr);
     if (generation != slot->generation) {
         print_memslots(info);
-        PANIC("address generation is not valid, group_id %d, slot_id %d, gen %d, slot_gen %d\n",
+        spice_critical("address generation is not valid, group_id %d, slot_id %d, gen %d, slot_gen %d\n",
               group_id, slot_id, generation, slot->generation);
     }
 
@@ -152,8 +152,8 @@ void red_memslot_info_init(RedMemSlotInfo *info,
 {
     uint32_t i;
 
-    ASSERT(num_slots > 0);
-    ASSERT(num_groups > 0);
+    spice_assert(num_slots > 0);
+    spice_assert(num_groups > 0);
 
     info->num_memslots_groups = num_groups;
     info->num_memslots = num_slots;
@@ -179,8 +179,8 @@ void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uin
                                uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
                                uint32_t generation)
 {
-    ASSERT(info->num_memslots_groups > slot_group_id);
-    ASSERT(info->num_memslots > slot_id);
+    spice_assert(info->num_memslots_groups > slot_group_id);
+    spice_assert(info->num_memslots > slot_id);
 
     info->mem_slots[slot_group_id][slot_id].address_delta = addr_delta;
     info->mem_slots[slot_group_id][slot_id].virt_start_addr = virt_start;
@@ -190,8 +190,8 @@ void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uin
 
 void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id)
 {
-    ASSERT(info->num_memslots_groups > slot_group_id);
-    ASSERT(info->num_memslots > slot_id);
+    spice_assert(info->num_memslots_groups > slot_group_id);
+    spice_assert(info->num_memslots > slot_id);
 
     info->mem_slots[slot_group_id][slot_id].virt_start_addr = 0;
     info->mem_slots[slot_group_id][slot_id].virt_end_addr = 0;
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 201e683..811e427 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -66,7 +66,7 @@ static uint8_t *red_linearize_chunk(RedDataChunk *head, size_t size, bool *free_
     uint32_t copy;
 
     if (head->next_chunk == NULL) {
-        ASSERT(size <= head->data_size);
+        spice_assert(size <= head->data_size);
         *free_chunk = false;
         return head->data;
     }
@@ -79,7 +79,7 @@ static uint8_t *red_linearize_chunk(RedDataChunk *head, size_t size, bool *free_
         ptr += copy;
         size -= copy;
     }
-    ASSERT(size == 0);
+    spice_assert(size == 0);
     return data;
 }
 
@@ -205,15 +205,15 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
 
         /* Protect against overflow in size calculations before
            writing to memory */
-        ASSERT(mem_size2 + sizeof(SpicePathSeg) > mem_size2);
+        spice_assert(mem_size2 + sizeof(SpicePathSeg) > mem_size2);
         mem_size2  += sizeof(SpicePathSeg);
-        ASSERT(count < UINT32_MAX / sizeof(SpicePointFix));
+        spice_assert(count < UINT32_MAX / sizeof(SpicePointFix));
         dsize = count * sizeof(SpicePointFix);
-        ASSERT(mem_size2 + dsize > mem_size2);
+        spice_assert(mem_size2 + dsize > mem_size2);
         mem_size2  += dsize;
 
         /* Verify that we didn't overflow due to guest changing data */
-        ASSERT(mem_size2 <= mem_size);
+        spice_assert(mem_size2 <= mem_size);
 
         seg->flags = start->flags;
         seg->count = count;
@@ -225,7 +225,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
         seg = (SpicePathSeg*)(&seg->points[i]);
     }
     /* Ensure guest didn't tamper with segment count */
-    ASSERT(n_segments == red->num_segments);
+    spice_assert(n_segments == red->num_segments);
 
     if (free_data) {
         free(data);
@@ -252,7 +252,7 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id,
     data = red_linearize_chunk(&chunks, size, &free_data);
     red_put_data_chunks(&chunks);
 
-    ASSERT(qxl->num_rects * sizeof(QXLRect) == size);
+    spice_assert(qxl->num_rects * sizeof(QXLRect) == size);
     red = spice_malloc(sizeof(*red) + qxl->num_rects * sizeof(SpiceRect));
     red->num_rects = qxl->num_rects;
 
@@ -299,7 +299,7 @@ static SpiceChunks *red_get_image_data_chunked(RedMemSlotInfo *slots, int group_
         data->chunk[i].len   = chunk->data_size;
         data->data_size     += chunk->data_size;
     }
-    ASSERT(i == data->num_chunks);
+    spice_assert(i == data->num_chunks);
     return data;
 }
 
@@ -373,7 +373,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
         } else {
             size = red_get_data_chunks(slots, group_id,
                                        &chunks, qxl->bitmap.data);
-            ASSERT(size == bitmap_size);
+            spice_assert(size == bitmap_size);
             red->u.bitmap.data = red_get_image_data_chunked(slots, group_id,
                                                             &chunks);
             red_put_data_chunks(&chunks);
@@ -390,14 +390,13 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
         size = red_get_data_chunks_ptr(slots, group_id,
                                        get_memslot_id(slots, addr),
                                        &chunks, (QXLDataChunk *)qxl->quic.data);
-        ASSERT(size == red->u.quic.data_size);
+        spice_assert(size == red->u.quic.data_size);
         red->u.quic.data = red_get_image_data_chunked(slots, group_id,
                                                       &chunks);
         red_put_data_chunks(&chunks);
         break;
     default:
-        red_error("%s: unknown type %d", __FUNCTION__, red->descriptor.type);
-        abort();
+        spice_error("unknown type %d", red->descriptor.type);
     }
     return red;
 }
@@ -593,7 +592,7 @@ static void red_get_stroke_ptr(RedMemSlotInfo *slots, int group_id,
         style_nseg = qxl->attr.style_nseg;
         red->attr.style = spice_malloc_n(style_nseg, sizeof(SPICE_FIXED28_4));
         red->attr.style_nseg  = style_nseg;
-        ASSERT(qxl->attr.style);
+        spice_assert(qxl->attr.style);
         buf = (uint8_t *)get_virt(slots, qxl->attr.style,
                                   style_nseg * sizeof(QXLFIXED), group_id);
         memcpy(red->attr.style, buf, style_nseg * sizeof(QXLFIXED));
@@ -636,7 +635,7 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
     red_put_data_chunks(&chunks);
 
     qxl_size = qxl->data_size;
-    ASSERT(chunk_size == qxl_size);
+    spice_assert(chunk_size == qxl_size);
 
     if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A1) {
         bpp = 1;
@@ -645,21 +644,21 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
     } else if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A8) {
         bpp = 8;
     }
-    ASSERT(bpp != 0);
+    spice_assert(bpp != 0);
 
     start = (QXLRasterGlyph*)data;
     end = (QXLRasterGlyph*)(data + chunk_size);
     red_size = sizeof(SpiceString);
     glyphs = 0;
     while (start < end) {
-        ASSERT((QXLRasterGlyph*)(&start->data[0]) <= end);
+        spice_assert((QXLRasterGlyph*)(&start->data[0]) <= end);
         glyphs++;
         glyph_size = start->height * ((start->width * bpp + 7) / 8);
         red_size += sizeof(SpiceRasterGlyph *) + SPICE_ALIGN(sizeof(SpiceRasterGlyph) + glyph_size, 4);
         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
     }
-    ASSERT(start <= end);
-    ASSERT(glyphs == qxl->length);
+    spice_assert(start <= end);
+    spice_assert(glyphs == qxl->length);
 
     red = spice_malloc(red_size);
     red->length = qxl->length;
@@ -669,14 +668,14 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
     end = (QXLRasterGlyph*)(data + chunk_size);
     glyph = (SpiceRasterGlyph *)&red->glyphs[red->length];
     for (i = 0; i < red->length; i++) {
-        ASSERT((QXLRasterGlyph*)(&start->data[0]) <= end);
+        spice_assert((QXLRasterGlyph*)(&start->data[0]) <= end);
         red->glyphs[i] = glyph;
         glyph->width = start->width;
         glyph->height = start->height;
         red_get_point_ptr(&glyph->render_pos, &start->render_pos);
         red_get_point_ptr(&glyph->glyph_origin, &start->glyph_origin);
         glyph_size = glyph->height * ((glyph->width * bpp + 7) / 8);
-        ASSERT((QXLRasterGlyph*)(&start->data[glyph_size]) <= end);
+        spice_assert((QXLRasterGlyph*)(&start->data[glyph_size]) <= end);
         memcpy(glyph->data, start->data, glyph_size);
         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
         glyph = (SpiceRasterGlyph*)
@@ -831,7 +830,7 @@ static void red_get_native_drawable(RedMemSlotInfo *slots, int group_id,
                               &red->u.whiteness, &qxl->u.whiteness, flags);
         break;
     default:
-        red_error("%s: unknown type %d", __FUNCTION__, red->type);
+        spice_error("unknown type %d", red->type);
         break;
     };
 }
@@ -911,7 +910,7 @@ static void red_get_compat_drawable(RedMemSlotInfo *slots, int group_id,
                               &red->u.whiteness, &qxl->u.whiteness, flags);
         break;
     default:
-        red_error("%s: unknown type %d", __FUNCTION__, red->type);
+        spice_error("unknown type %d", red->type);
         break;
     };
 }
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 45bf6e1..384c36d 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -44,7 +44,7 @@
 //#define DEBUG_NETWORK
 
 #ifdef DEBUG_NETWORK
-#define PRINT_SCKT(sckt) red_printf("TUNNEL_DBG SOCKET(connection_id=%d port=%d, service=%d)",\
+#define PRINT_SCKT(sckt) spice_printerr("TUNNEL_DBG SOCKET(connection_id=%d port=%d, service=%d)",\
                                     sckt->connection_id, ntohs(sckt->local_port),             \
                                     sckt->far_service->id)
 #endif
@@ -479,7 +479,7 @@ static inline void tunnel_channel_activate_migrated_sockets(TunnelChannelClient
    failed (which triggered from a call to slirp) */
 #define SET_TUNNEL_ERROR(channel,format, ...) {   \
     channel->tunnel_error = TRUE;                 \
-    red_printf(format, ## __VA_ARGS__);           \
+    spice_printerr(format, ## __VA_ARGS__);           \
 }
 
 /* should be checked after each subroutine that may cause error or after calls to slirp routines */
@@ -614,7 +614,7 @@ static void red_tunnel_channel_create(TunnelWorker *worker);
 static void tunnel_shutdown(TunnelWorker *worker)
 {
     int i;
-    red_printf("");
+    spice_printerr("");
     /* shutdown input from channel */
     if (worker->channel_client) {
         red_channel_client_shutdown(&worker->channel_client->base);
@@ -695,7 +695,7 @@ static void snd_tunnled_buffer_release(RawTunneledBuffer *buf)
 static inline void tunnel_socket_assign_rcv_buf(RedSocket *sckt,
                                                 RedSocketRawRcvBuf *recv_buf, int buf_size)
 {
-    ASSERT(!recv_buf->base.usr_opaque);
+    spice_assert(!recv_buf->base.usr_opaque);
     // the rcv buffer was allocated by tunnel_channel_alloc_msg_rcv_buf
     // before we could know which of the sockets it belongs to, so the
     // assignment to the socket is performed now
@@ -824,7 +824,7 @@ static void process_queue_append(TunneledBufferProcessQueue *queue, uint8_t *dat
 static void process_queue_pop(TunneledBufferProcessQueue *queue)
 {
     RawTunneledBuffer *prev_head;
-    ASSERT(queue->head && queue->tail);
+    spice_assert(queue->head && queue->tail);
     prev_head = queue->head;
     queue->head = queue->head->next;
     if (!queue->head) {
@@ -868,7 +868,7 @@ static void ready_queue_add_orig_chunk(ReadyTunneledChunkQueue *queue, RawTunnel
 static void ready_queue_pop_chunk(ReadyTunneledChunkQueue *queue)
 {
     ReadyTunneledChunk *chunk = queue->head;
-    ASSERT(queue->head);
+    spice_assert(queue->head);
     queue->head = queue->head->next;
 
     if (!queue->head) {
@@ -892,8 +892,8 @@ static void ready_queue_clear(ReadyTunneledChunkQueue *queue)
 static void process_queue_simple_analysis(TunneledBufferProcessQueue *queue,
                                           RawTunneledBuffer *start_last_added, int offset, int len)
 {
-    ASSERT(offset == 0);
-    ASSERT(start_last_added == queue->head);
+    spice_assert(offset == 0);
+    spice_assert(start_last_added == queue->head);
 
     while (queue->head) {
         ready_queue_add_orig_chunk(queue->ready_chunks_queue, queue->head, queue->head->data,
@@ -912,7 +912,7 @@ static int process_queue_simple_get_migrate_data(TunneledBufferProcessQueue *que
 static void process_queue_simple_release_migrate_data(TunneledBufferProcessQueue *queue,
                                                       void *migrate_data)
 {
-    ASSERT(!migrate_data);
+    spice_assert(!migrate_data);
 }
 
 static void process_queue_simple_restore(TunneledBufferProcessQueue *queue, uint8_t *migrate_data)
@@ -971,7 +971,7 @@ SPICE_GNUC_VISIBLE void spice_server_net_wire_recv_packet(SpiceNetWireInstance *
                                                           const uint8_t *pkt, int pkt_len)
 {
     TunnelWorker *worker = sin->st->worker;
-    ASSERT(worker);
+    spice_assert(worker);
 
     if (worker->channel_client && worker->channel_client->base.channel->migrate) {
         return; // during migration and the tunnel state hasn't been restored yet.
@@ -1054,7 +1054,7 @@ static inline TunnelService *__tunnel_worker_add_service(TunnelWorker *worker, u
         TunnelService *service_of_same_group;
         if (!(service_of_same_group = __tunnel_worker_find_service_of_group(worker, group))) {
             if (!net_slirp_allocate_virtual_ip(&new_service->virt_ip)) {
-                red_printf("failed to allocate virtual ip");
+                spice_printerr("failed to allocate virtual ip");
                 free(new_service);
                 return NULL;
             }
@@ -1062,7 +1062,7 @@ static inline TunnelService *__tunnel_worker_add_service(TunnelWorker *worker, u
             if (strcmp(name, service_of_same_group->name) == 0) {
                 new_service->virt_ip.s_addr = service_of_same_group->virt_ip.s_addr;
             } else {
-                red_printf("inconsistent name for service group %d", group);
+                spice_printerr("inconsistent name for service group %d", group);
                 free(new_service);
                 return NULL;
             }
@@ -1084,7 +1084,7 @@ static inline TunnelService *__tunnel_worker_add_service(TunnelWorker *worker, u
     worker->num_services++;
 
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL_DBG: ==>SERVICE ADDED: id=%d virt ip=%s port=%d name=%s desc=%s",
+    spice_printerr("TUNNEL_DBG: ==>SERVICE ADDED: id=%d virt ip=%s port=%d name=%s desc=%s",
                new_service->id, inet_ntoa(new_service->virt_ip),
                new_service->port, new_service->name, new_service->description);
 #endif
@@ -1137,12 +1137,12 @@ static TunnelPrintService *tunnel_worker_add_print_service(TunnelWorker *worker,
     if (redc_service->type == SPICE_TUNNEL_IP_TYPE_IPv4) {
         memcpy(service->ip, redc_service->u.ip.data, sizeof(SpiceTunnelIPv4));
     } else {
-        red_printf("unexpected ip type=%d", redc_service->type);
+        spice_printerr("unexpected ip type=%d", redc_service->type);
         tunnel_worker_free_print_service(worker, service);
         return NULL;
     }
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL_DBG: ==>PRINT SERVICE ADDED: ip=%d.%d.%d.%d", service->ip[0],
+    spice_printerr("TUNNEL_DBG: ==>PRINT SERVICE ADDED: ip=%d.%d.%d.%d", service->ip[0],
                service->ip[1], service->ip[2], service->ip[3]);
 #endif
     return service;
@@ -1159,7 +1159,7 @@ static int tunnel_channel_handle_service_add(TunnelChannelClient *channel,
         out_service = tunnel_worker_add_service(channel->worker, sizeof(TunnelService),
                                                 service_msg);
     } else {
-        red_printf("invalid service type");
+        spice_printerr("invalid service type");
     }
 
     free(service_msg);
@@ -1205,7 +1205,7 @@ static inline void tunnel_worker_clear_routed_network(TunnelWorker *worker)
         } else if (service->type == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
             tunnel_worker_free_print_service(worker, (TunnelPrintService *)service);
         } else {
-            red_error("unexpected service type");
+            spice_error("unexpected service type");
         }
     }
 
@@ -1229,13 +1229,13 @@ static inline RedSocket *__tunnel_worker_find_free_socket(TunnelWorker *worker)
         }
     }
 
-    ASSERT(ret);
+    spice_assert(ret);
     return ret;
 }
 
 static inline void __tunnel_worker_add_socket(TunnelWorker *worker, RedSocket *sckt)
 {
-    ASSERT(!sckt->allocated);
+    spice_assert(!sckt->allocated);
     sckt->allocated = TRUE;
     worker->num_sockets++;
 }
@@ -1244,7 +1244,7 @@ static inline void tunnel_worker_alloc_socket(TunnelWorker *worker, RedSocket *s
                                               uint16_t local_port, TunnelService *far_service,
                                               SlirpSocket *slirp_s)
 {
-    ASSERT(far_service);
+    spice_assert(far_service);
     sckt->worker = worker;
     sckt->local_port = local_port;
     sckt->far_service = far_service;
@@ -1272,11 +1272,11 @@ static RedSocket *tunnel_worker_create_socket(TunnelWorker *worker, uint16_t loc
                                               SlirpSocket *slirp_s)
 {
     RedSocket *new_socket;
-    ASSERT(worker);
+    spice_assert(worker);
     new_socket = __tunnel_worker_find_free_socket(worker);
 
     if (!new_socket) {
-        red_error("creation of RedSocket failed");
+        spice_error("creation of RedSocket failed");
     }
 
     tunnel_worker_alloc_socket(worker, new_socket, local_port, far_service, slirp_s);
@@ -1341,17 +1341,17 @@ static inline RedSocket *tunnel_worker_find_socket(TunnelWorker *worker,
 
 static inline void __tunnel_socket_add_fin_to_pipe(TunnelChannelClient *channel, RedSocket *sckt)
 {
-    ASSERT(!red_channel_client_pipe_item_is_linked(&channel->base, &sckt->out_data.status_pipe_item));
+    spice_assert(!red_channel_client_pipe_item_is_linked(&channel->base, &sckt->out_data.status_pipe_item));
     sckt->out_data.status_pipe_item.type = PIPE_ITEM_TYPE_SOCKET_FIN;
     red_channel_client_pipe_add(&channel->base, &sckt->out_data.status_pipe_item);
 }
 
 static inline void __tunnel_socket_add_close_to_pipe(TunnelChannelClient *channel, RedSocket *sckt)
 {
-    ASSERT(!channel->mig_inprogress);
+    spice_assert(!channel->mig_inprogress);
 
     if (red_channel_client_pipe_item_is_linked(&channel->base, &sckt->out_data.status_pipe_item)) {
-        ASSERT(sckt->out_data.status_pipe_item.type == PIPE_ITEM_TYPE_SOCKET_FIN);
+        spice_assert(sckt->out_data.status_pipe_item.type == PIPE_ITEM_TYPE_SOCKET_FIN);
         // close is stronger than FIN
         red_channel_client_pipe_remove_and_release(&channel->base,
                                         &sckt->out_data.status_pipe_item);
@@ -1363,10 +1363,10 @@ static inline void __tunnel_socket_add_close_to_pipe(TunnelChannelClient *channe
 
 static inline void __tunnel_socket_add_close_ack_to_pipe(TunnelChannelClient *channel, RedSocket *sckt)
 {
-    ASSERT(!channel->mig_inprogress);
+    spice_assert(!channel->mig_inprogress);
 
     if (red_channel_client_pipe_item_is_linked(&channel->base, &sckt->out_data.status_pipe_item)) {
-        ASSERT(sckt->out_data.status_pipe_item.type == PIPE_ITEM_TYPE_SOCKET_FIN);
+        spice_assert(sckt->out_data.status_pipe_item.type == PIPE_ITEM_TYPE_SOCKET_FIN);
         // close is stronger than FIN
         red_channel_client_pipe_remove_and_release(&channel->base,
                                     &sckt->out_data.status_pipe_item);
@@ -1414,7 +1414,7 @@ static int tunnel_channel_handle_socket_connect_ack(TunnelChannelClient *channel
                                                     uint32_t tokens)
 {
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL_DBG");
+    spice_printerr("TUNNEL_DBG");
 #endif
     if (channel->mig_inprogress || channel->base.channel->migrate) {
         sckt->mig_client_status_msg = SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK;
@@ -1423,21 +1423,21 @@ static int tunnel_channel_handle_socket_connect_ack(TunnelChannelClient *channel
     }
 
     if (sckt->client_status != CLIENT_SCKT_STATUS_WAIT_OPEN) {
-        red_printf("unexpected SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK status=%d", sckt->client_status);
+        spice_printerr("unexpected SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK status=%d", sckt->client_status);
         return FALSE;
     }
     sckt->client_status = CLIENT_SCKT_STATUS_OPEN;
 
     // SLIRP_SCKT_STATUS_CLOSED is possible after waiting for a connection has timed out
     if (sckt->slirp_status == SLIRP_SCKT_STATUS_CLOSED) {
-        ASSERT(!sckt->pushed_close);
+        spice_assert(!sckt->pushed_close);
         __tunnel_socket_add_close_to_pipe(channel, sckt);
     } else if (sckt->slirp_status == SLIRP_SCKT_STATUS_OPEN) {
         sckt->out_data.window_size = tokens;
         sckt->out_data.num_tokens = tokens;
         net_slirp_socket_connected_notify(sckt->slirp_sckt);
     } else {
-        red_printf("unexpected slirp status status=%d", sckt->slirp_status);
+        spice_printerr("unexpected slirp status status=%d", sckt->slirp_status);
         return FALSE;
     }
 
@@ -1455,7 +1455,7 @@ static int tunnel_channel_handle_socket_connect_nack(TunnelChannelClient *channe
     }
 
     if (sckt->client_status != CLIENT_SCKT_STATUS_WAIT_OPEN) {
-        red_printf("unexpected SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK status=%d", sckt->client_status);
+        spice_printerr("unexpected SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK status=%d", sckt->client_status);
         return FALSE;
     }
     sckt->client_status = CLIENT_SCKT_STATUS_CLOSED;
@@ -1480,7 +1480,7 @@ static int tunnel_channel_handle_socket_fin(TunnelChannelClient *channel, RedSoc
     }
 
     if (sckt->client_status != CLIENT_SCKT_STATUS_OPEN) {
-        red_printf("unexpected SPICE_MSGC_TUNNEL_SOCKET_FIN status=%d", sckt->client_status);
+        spice_printerr("unexpected SPICE_MSGC_TUNNEL_SOCKET_FIN status=%d", sckt->client_status);
         return FALSE;
     }
     sckt->client_status = CLIENT_SCKT_STATUS_SHUTDOWN_SEND;
@@ -1497,7 +1497,7 @@ static int tunnel_channel_handle_socket_fin(TunnelChannelClient *channel, RedSoc
         net_slirp_socket_can_receive_notify(sckt->slirp_sckt);
     } else if (sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_RECV) {
         // it already received the FIN
-        red_printf("unexpected slirp status=%d", sckt->slirp_status);
+        spice_printerr("unexpected slirp status=%d", sckt->slirp_status);
         return FALSE;
     }
 
@@ -1546,7 +1546,7 @@ static int tunnel_channel_handle_socket_closed(TunnelChannelClient *channel, Red
         // slirp can be in wait close if both slirp and client sent fin previously
         // otherwise, the prev client status would also have been wait close, and this
         // case was handled above
-        red_printf("unexpected slirp_status=%d", sckt->slirp_status);
+        spice_printerr("unexpected slirp_status=%d", sckt->slirp_status);
         return FALSE;
     }
 
@@ -1571,7 +1571,7 @@ static int tunnel_channel_handle_socket_closed_ack(TunnelChannelClient *channel,
     }
 
     if (sckt->slirp_status != SLIRP_SCKT_STATUS_CLOSED) {
-        red_printf("unexpected SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK slirp_status=%d",
+        spice_printerr("unexpected SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK slirp_status=%d",
                    sckt->slirp_status);
         return FALSE;
     }
@@ -1585,7 +1585,7 @@ static int tunnel_channel_handle_socket_receive_data(TunnelChannelClient *channe
 {
     if ((sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND) ||
         (sckt->client_status == CLIENT_SCKT_STATUS_CLOSED)) {
-        red_printf("unexpected SPICE_MSGC_TUNNEL_SOCKET_DATA client_status=%d",
+        spice_printerr("unexpected SPICE_MSGC_TUNNEL_SOCKET_DATA client_status=%d",
                    sckt->client_status);
         return FALSE;
     }
@@ -1597,7 +1597,7 @@ static int tunnel_channel_handle_socket_receive_data(TunnelChannelClient *channe
         return (!CHECK_TUNNEL_ERROR(channel));
     } else if ((sckt->in_data.num_buffers == MAX_SOCKET_IN_BUFFERS) &&
                !channel->mig_inprogress && !channel->base.channel->migrate) {
-        red_printf("socket in buffers overflow, socket will be closed"
+        spice_printerr("socket in buffers overflow, socket will be closed"
                    " (local_port=%d, service_id=%d)",
                    ntohs(sckt->local_port), sckt->far_service->id);
         __tunnel_worker_free_socket_rcv_buf(sckt->worker, recv_data);
@@ -1607,7 +1607,7 @@ static int tunnel_channel_handle_socket_receive_data(TunnelChannelClient *channe
 
     tunnel_socket_assign_rcv_buf(sckt, recv_data, buf_size);
     if (!sckt->in_data.client_total_num_tokens) {
-        red_printf("token violation");
+        spice_printerr("token violation");
         return FALSE;
     }
 
@@ -1665,7 +1665,7 @@ static void tunnel_channel_release_msg_rcv_buf(RedChannelClient *rcc, uint16_t t
     TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel;
 
     if (type == SPICE_MSGC_TUNNEL_SOCKET_DATA) {
-        ASSERT(!(SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf)->base.usr_opaque));
+        spice_assert(!(SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf)->base.usr_opaque));
         __tunnel_worker_free_socket_rcv_buf(tunnel_channel->worker,
                                             SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf));
     }
@@ -1683,7 +1683,8 @@ static void __tunnel_channel_fill_service_migrate_item(TunnelChannelClient *chan
         general_data = &migrate_item->u.print_service.base;
         memcpy(migrate_item->u.print_service.ip, ((TunnelPrintService *)service)->ip, 4);
     } else {
-        red_error("unexpected service type");
+        spice_error("unexpected service type");
+        abort();
     }
 
     general_data->type = service->type;
@@ -1755,7 +1756,7 @@ static int tunnel_channel_handle_migrate_mark(RedChannelClient *base)
     RedSocket *sckt;
 
     if (!channel->expect_migrate_mark) {
-        red_printf("unexpected");
+        spice_printerr("unexpected");
         return FALSE;
     }
     channel->expect_migrate_mark = FALSE;
@@ -1764,7 +1765,7 @@ static int tunnel_channel_handle_migrate_mark(RedChannelClient *base)
 
     migrate_item->slirp_state_size = net_slirp_state_export(&migrate_item->slirp_state);
     if (!migrate_item->slirp_state) {
-        red_printf("failed export slirp state");
+        spice_printerr("failed export slirp state");
         goto error;
     }
 
@@ -1897,7 +1898,7 @@ RawTunneledBuffer *__tunnel_socket_alloc_restore_tokens_buf(RedSocket *sckt, int
     buf->base.base.release_proc = restore_tokens_buf_release;
     buf->num_tokens = num_tokens;
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL DBG: num_tokens=%d", num_tokens);
+    spice_printerr("TUNNEL DBG: num_tokens=%d", num_tokens);
 #endif
     return &buf->base.base;
 }
@@ -1982,7 +1983,7 @@ static void tunnel_channel_restore_migrated_socket(TunnelChannelClient *channel,
     TunnelService *service;
     sckt = channel->worker->sockets + mig_socket->connection_id;
     sckt->connection_id = mig_socket->connection_id;
-    ASSERT(!sckt->allocated);
+    spice_assert(!sckt->allocated);
 
     /* Services must be restored before sockets */
     service = tunnel_worker_find_service_by_id(channel->worker, mig_socket->far_service_id);
@@ -2061,7 +2062,7 @@ static void tunnel_channel_restore_migrated_socket(TunnelChannelClient *channel,
 static void tunnel_channel_restore_socket_state(TunnelChannelClient *channel, RedSocket *sckt)
 {
     int ret = TRUE;
-    red_printf("");
+    spice_printerr("");
     // handling client status msgs that were received during migration
     switch (sckt->mig_client_status_msg) {
     case 0:
@@ -2183,18 +2184,18 @@ static uint64_t tunnel_channel_handle_migrate_data(RedChannelClient *base,
     int i;
 
     if (size < sizeof(TunnelMigrateData)) {
-        red_printf("bad message size");
+        spice_printerr("bad message size");
         goto error;
     }
     if (!channel->expect_migrate_data) {
-        red_printf("unexpected");
+        spice_printerr("unexpected");
         goto error;
     }
     channel->expect_migrate_data = FALSE;
 
     if (migrate_data->magic != TUNNEL_MIGRATE_DATA_MAGIC ||
         migrate_data->version != TUNNEL_MIGRATE_DATA_VERSION) {
-        red_printf("invalid content");
+        spice_printerr("invalid content");
         goto error;
     }
 
@@ -2208,7 +2209,7 @@ static uint64_t tunnel_channel_handle_migrate_data(RedChannelClient *base,
                                                                         services_list->services[i]),
                                                 migrate_data->data);
         if (CHECK_TUNNEL_ERROR(channel)) {
-            red_printf("failed restoring service");
+            spice_printerr("failed restoring service");
             goto error;
         }
     }
@@ -2221,7 +2222,7 @@ static uint64_t tunnel_channel_handle_migrate_data(RedChannelClient *base,
                                                                        sockets_list->sockets[i]),
                                                migrate_data->data);
         if (CHECK_TUNNEL_ERROR(channel)) {
-            red_printf("failed restoring socket");
+            spice_printerr("failed restoring socket");
             goto error;
         }
     }
@@ -2265,7 +2266,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
         // the first field in these messages is connection id
         sckt = tunnel_channel->worker->sockets + (*((uint16_t *)msg));
         if (!sckt->allocated) {
-            red_printf("red socket not found");
+            spice_printerr("red socket not found");
             return FALSE;
         }
         break;
@@ -2276,18 +2277,18 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
     switch (type) {
     case SPICE_MSGC_TUNNEL_SERVICE_ADD:
         if (size < sizeof(SpiceMsgcTunnelAddGenericService)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             free(msg);
             return FALSE;
         }
         return tunnel_channel_handle_service_add(tunnel_channel,
                                                  (SpiceMsgcTunnelAddGenericService *)msg);
     case SPICE_MSGC_TUNNEL_SERVICE_REMOVE:
-        red_printf("REDC_TUNNEL_REMOVE_SERVICE not supported yet");
+        spice_printerr("REDC_TUNNEL_REMOVE_SERVICE not supported yet");
         return FALSE;
     case SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK:
         if (size != sizeof(SpiceMsgcTunnelSocketOpenAck)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
 
@@ -2296,7 +2297,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
 
     case SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK:
         if (size != sizeof(SpiceMsgcTunnelSocketOpenNack)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
 
@@ -2304,7 +2305,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
     case SPICE_MSGC_TUNNEL_SOCKET_DATA:
     {
         if (size < sizeof(SpiceMsgcTunnelSocketData)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
 
@@ -2314,25 +2315,25 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
     }
     case SPICE_MSGC_TUNNEL_SOCKET_FIN:
         if (size != sizeof(SpiceMsgcTunnelSocketFin)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_fin(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_CLOSED:
         if (size != sizeof(SpiceMsgcTunnelSocketClosed)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_closed(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK:
         if (size != sizeof(SpiceMsgcTunnelSocketClosedAck)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_closed_ack(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_TOKEN:
         if (size != sizeof(SpiceMsgcTunnelSocketTokens)) {
-            red_printf("bad message size");
+            spice_printerr("bad message size");
             return FALSE;
         }
 
@@ -2352,7 +2353,7 @@ static void tunnel_channel_marshall_migrate(RedChannelClient *rcc, SpiceMarshall
 {
     TunnelChannelClient *tunnel_channel;
 
-    ASSERT(rcc);
+    spice_assert(rcc);
     tunnel_channel = SPICE_CONTAINEROF(rcc->channel, TunnelChannelClient, base);
     tunnel_channel->send_data.u.migrate.flags =
         SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER;
@@ -2417,7 +2418,8 @@ static int __tunnel_channel_marshall_service_migrate_data(TunnelChannelClient *c
                             sizeof(item->u.print_service));
         cur_offset += sizeof(item->u.print_service);
     } else {
-        red_error("unexpected service type");
+        spice_error("unexpected service type");
+        abort();
     }
 
     generic_data->name = cur_offset;
@@ -2506,7 +2508,7 @@ static void tunnel_channel_marshall_migrate_data(RedChannelClient *rcc,
     int i;
 
     uint32_t data_buf_offset = 0; // current location in data[0] field
-    ASSERT(rcc);
+    spice_assert(rcc);
     tunnel_channel = SPICE_CONTAINEROF(rcc->channel, TunnelChannelClient, base);
     migrate_data = &tunnel_channel->send_data.u.migrate_data;
 
@@ -2550,7 +2552,7 @@ static void tunnel_channel_marshall_init(RedChannelClient *rcc, SpiceMarshaller
 {
     TunnelChannelClient *channel;
 
-    ASSERT(rcc);
+    spice_assert(rcc);
     channel = SPICE_CONTAINEROF(rcc->channel, TunnelChannelClient, base);
     channel->send_data.u.init.max_socket_data_size = MAX_SOCKET_DATA_SIZE;
     channel->send_data.u.init.max_num_of_sockets = MAX_SOCKETS_NUM;
@@ -2601,11 +2603,11 @@ static void tunnel_channel_marshall_socket_fin(RedChannelClient *rcc, SpiceMarsh
     RedSocketOutData *sckt_out_data = SPICE_CONTAINEROF(item, RedSocketOutData, status_pipe_item);
     RedSocket *sckt = SPICE_CONTAINEROF(sckt_out_data, RedSocket, out_data);
 
-    ASSERT(!sckt->out_data.ready_chunks_queue.head);
+    spice_assert(!sckt->out_data.ready_chunks_queue.head);
 
     tunnel_channel = SPICE_CONTAINEROF(rcc->channel, TunnelChannelClient, base);
     if (sckt->out_data.process_queue->head) {
-        red_printf("socket sent FIN but there are still buffers in outgoing process queue"
+        spice_printerr("socket sent FIN but there are still buffers in outgoing process queue"
                    "(local_port=%d, service_id=%d)",
                    ntohs(sckt->local_port), sckt->far_service->id);
     }
@@ -2629,14 +2631,14 @@ static void tunnel_channel_marshall_socket_close(RedChannelClient *rcc, SpiceMar
     tunnel_channel = SPICE_CONTAINEROF(rcc->channel, TunnelChannelClient, base);
     // can happen when it is a forced close
     if (sckt->out_data.ready_chunks_queue.head) {
-        red_printf("socket closed but there are still buffers in outgoing ready queue"
+        spice_printerr("socket closed but there are still buffers in outgoing ready queue"
                    "(local_port=%d, service_id=%d)",
                    ntohs(sckt->local_port),
                    sckt->far_service->id);
     }
 
     if (sckt->out_data.process_queue->head) {
-        red_printf("socket closed but there are still buffers in outgoing process queue"
+        spice_printerr("socket closed but there are still buffers in outgoing process queue"
                    "(local_port=%d, service_id=%d)",
                    ntohs(sckt->local_port), sckt->far_service->id);
     }
@@ -2668,7 +2670,7 @@ static void tunnel_channel_marshall_socket_closed_ack(RedChannelClient *rcc, Spi
     PRINT_SCKT(sckt);
 #endif
 
-    ASSERT(sckt->client_waits_close_ack && (sckt->client_status == CLIENT_SCKT_STATUS_CLOSED));
+    spice_assert(sckt->client_waits_close_ack && (sckt->client_status == CLIENT_SCKT_STATUS_CLOSED));
     tunnel_worker_free_socket(tunnel_channel->worker, sckt);
     if (CHECK_TUNNEL_ERROR(tunnel_channel)) {
         tunnel_shutdown(tunnel_channel->worker);
@@ -2690,12 +2692,12 @@ static void tunnel_channel_marshall_socket_token(RedChannelClient *rcc, SpiceMar
     if (sckt->in_data.num_tokens > 0) {
         tunnel_channel->send_data.u.socket_token.num_tokens = sckt->in_data.num_tokens;
     } else {
-        ASSERT(!sckt->in_data.client_total_num_tokens && !sckt->in_data.ready_chunks_queue.head);
+        spice_assert(!sckt->in_data.client_total_num_tokens && !sckt->in_data.ready_chunks_queue.head);
         tunnel_channel->send_data.u.socket_token.num_tokens = SOCKET_TOKENS_TO_SEND_FOR_PROCESS;
     }
     sckt->in_data.num_tokens -= tunnel_channel->send_data.u.socket_token.num_tokens;
     sckt->in_data.client_total_num_tokens += tunnel_channel->send_data.u.socket_token.num_tokens;
-    ASSERT(sckt->in_data.client_total_num_tokens <= SOCKET_WINDOW_SIZE);
+    spice_assert(sckt->in_data.client_total_num_tokens <= SOCKET_WINDOW_SIZE);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_TUNNEL_SOCKET_TOKEN, item);
     spice_marshaller_add_ref(m, (uint8_t*)&tunnel_channel->send_data.u.socket_token,
@@ -2712,7 +2714,7 @@ static void tunnel_channel_marshall_socket_out_data(RedChannelClient *rcc, Spice
     uint32_t total_push_size = 0;
     uint32_t pushed_bufs_num = 0;
 
-    ASSERT(!sckt->pushed_close);
+    spice_assert(!sckt->pushed_close);
     if (sckt->client_status == CLIENT_SCKT_STATUS_CLOSED) {
         return;
     }
@@ -2721,9 +2723,9 @@ static void tunnel_channel_marshall_socket_out_data(RedChannelClient *rcc, Spice
         return; // only when an we will receive tokens, data will be sent again.
     }
 
-    ASSERT(sckt->out_data.ready_chunks_queue.head);
-    ASSERT(!sckt->out_data.push_tail);
-    ASSERT(sckt->out_data.ready_chunks_queue.head->size <= MAX_SOCKET_DATA_SIZE);
+    spice_assert(sckt->out_data.ready_chunks_queue.head);
+    spice_assert(!sckt->out_data.push_tail);
+    spice_assert(sckt->out_data.ready_chunks_queue.head->size <= MAX_SOCKET_DATA_SIZE);
 
     tunnel_channel->send_data.u.socket_data.connection_id = sckt->connection_id;
 
@@ -2763,7 +2765,7 @@ static void tunnel_worker_release_socket_out_data(TunnelWorker *worker, PipeItem
     RedSocketOutData *sckt_out_data = SPICE_CONTAINEROF(item, RedSocketOutData, data_pipe_item);
     RedSocket *sckt = SPICE_CONTAINEROF(sckt_out_data, RedSocket, out_data);
 
-    ASSERT(sckt_out_data->ready_chunks_queue.head);
+    spice_assert(sckt_out_data->ready_chunks_queue.head);
 
     while (sckt_out_data->ready_chunks_queue.head != sckt_out_data->push_tail) {
         sckt_out_data->data_size -= sckt_out_data->ready_chunks_queue.head->size;
@@ -2850,7 +2852,7 @@ static void tunnel_channel_send_item(RedChannelClient *rcc, PipeItem *item)
         tunnel_channel_marshall_migrate_data(rcc, m, item);
         break;
     default:
-        red_error("invalid pipe item type");
+        spice_error("invalid pipe item type");
     }
     red_channel_client_begin_send_message(rcc);
 }
@@ -2886,7 +2888,7 @@ static void tunnel_channel_release_pipe_item(RedChannelClient *rcc, PipeItem *it
         release_migrate_item((TunnelMigrateItem *)item);
         break;
     default:
-        red_error("invalid pipe item type");
+        spice_error("invalid pipe item type");
     }
 }
 
@@ -2924,14 +2926,14 @@ static int tunnel_socket_connect(SlirpUsrNetworkInterface *usr_interface,
     RedSocket *sckt;
     TunnelService *far_service;
 
-    ASSERT(usr_interface);
+    spice_assert(usr_interface);
 
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL_DBG");
+    spice_printerr("TUNNEL_DBG");
 #endif
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
-    ASSERT(worker->channel_client);
-    ASSERT(!worker->channel_client->mig_inprogress);
+    spice_assert(worker->channel_client);
+    spice_assert(!worker->channel_client->mig_inprogress);
 
     far_service = tunnel_worker_find_service_by_addr(worker, &dst_addr, (uint32_t)ntohs(dst_port));
 
@@ -2941,13 +2943,13 @@ static int tunnel_socket_connect(SlirpUsrNetworkInterface *usr_interface,
     }
 
     if (tunnel_worker_find_socket(worker, src_port, far_service->id)) {
-        red_printf("slirp tried to open a socket that is still opened");
+        spice_printerr("slirp tried to open a socket that is still opened");
         errno = EADDRINUSE;
         return -1;
     }
 
     if (worker->num_sockets == MAX_SOCKETS_NUM) {
-        red_printf("number of tunneled sockets exceeds the limit");
+        spice_printerr("number of tunneled sockets exceeds the limit");
         errno = ENFILE;
         return -1;
     }
@@ -2979,12 +2981,12 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
     RedSocket *sckt;
     size_t size_to_send;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
 
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 
-    ASSERT(!worker->channel_client->mig_inprogress);
+    spice_assert(!worker->channel_client->mig_inprogress);
 
     sckt = (RedSocket *)opaque;
 
@@ -2995,7 +2997,7 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
 
     if ((sckt->client_status != CLIENT_SCKT_STATUS_OPEN) &&
         (sckt->client_status != CLIENT_SCKT_STATUS_SHUTDOWN_SEND)) {
-        red_printf("client socket is unable to receive data");
+        spice_printerr("client socket is unable to receive data");
         errno = ECONNRESET;
         return -1;
     }
@@ -3003,7 +3005,7 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
 
     if ((sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_SEND) ||
         (sckt->slirp_status == SLIRP_SCKT_STATUS_WAIT_CLOSE)) {
-        red_printf("send was shutdown");
+        spice_printerr("send was shutdown");
         errno = EPIPE;
         return -1;
     }
@@ -3026,10 +3028,10 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
             // and buffers will be released, we will try to send again.
             size_to_send = 0;
         } else {
-            ASSERT(sckt->out_data.process_queue->head);
+            spice_assert(sckt->out_data.process_queue->head);
             if ((sckt->out_data.data_size + len) >
                                                   (MAX_SOCKET_OUT_BUFFERS * MAX_SOCKET_DATA_SIZE)) {
-                red_printf("socket out buffers overflow, socket will be closed"
+                spice_printerr("socket out buffers overflow, socket will be closed"
                            " (local_port=%d, service_id=%d)",
                            ntohs(sckt->local_port), sckt->far_service->id);
                 tunnel_socket_force_close(worker->channel_client, sckt);
@@ -3084,11 +3086,11 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
     RedSocket *sckt;
     int copied = 0;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 
-    ASSERT(!worker->channel_client->mig_inprogress);
+    spice_assert(!worker->channel_client->mig_inprogress);
 
     sckt = (RedSocket *)opaque;
 
@@ -3112,7 +3114,7 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
         return -1;
     }
 
-    ASSERT((sckt->client_status == CLIENT_SCKT_STATUS_OPEN) ||
+    spice_assert((sckt->client_status == CLIENT_SCKT_STATUS_OPEN) ||
            (sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND) ||
            ((sckt->client_status == CLIENT_SCKT_STATUS_CLOSED) &&
             (sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_SEND)));
@@ -3121,7 +3123,7 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
     // if there is data in ready queue, when it is acked, slirp will call recv and get 0
     if (__should_send_fin_to_guest(sckt)) {
         if (sckt->in_data.process_queue->head) {
-            red_printf("client socket sent FIN but there are still buffers in incoming process"
+            spice_printerr("client socket sent FIN but there are still buffers in incoming process"
                        "queue (local_port=%d, service_id=%d)",
                        ntohs(sckt->local_port), sckt->far_service->id);
         }
@@ -3139,7 +3141,7 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
             ready_queue_pop_chunk(&sckt->in_data.ready_chunks_queue);
             sckt->in_data.ready_chunks_queue.offset = 0;
         } else {
-            ASSERT(copied == len);
+            spice_assert(copied == len);
             sckt->in_data.ready_chunks_queue.offset += copy_count;
         }
     }
@@ -3164,15 +3166,15 @@ static void tunnel_socket_shutdown_send(SlirpUsrNetworkInterface *usr_interface,
     TunnelWorker *worker;
     RedSocket *sckt;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
     sckt = (RedSocket *)opaque;
 
 #ifdef DEBUG_NETWORK
     PRINT_SCKT(sckt);
 #endif
-    ASSERT(!worker->channel_client->mig_inprogress);
+    spice_assert(!worker->channel_client->mig_inprogress);
 
     if (sckt->slirp_status == SLIRP_SCKT_STATUS_DELAY_ABORT) {
         return;
@@ -3181,7 +3183,7 @@ static void tunnel_socket_shutdown_send(SlirpUsrNetworkInterface *usr_interface,
     if (sckt->slirp_status == SLIRP_SCKT_STATUS_OPEN) {
         sckt->slirp_status = SLIRP_SCKT_STATUS_SHUTDOWN_SEND;
     } else if (sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_RECV) {
-        ASSERT(sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND);
+        spice_assert(sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND);
         sckt->slirp_status = SLIRP_SCKT_STATUS_WAIT_CLOSE;
     } else {
         SET_TUNNEL_ERROR(worker->channel_client, "unexpected tunnel_socket_shutdown_send slirp_status=%d",
@@ -3216,15 +3218,15 @@ static void tunnel_socket_shutdown_recv(SlirpUsrNetworkInterface *usr_interface,
     TunnelWorker *worker;
     RedSocket *sckt;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
     sckt = (RedSocket *)opaque;
 
 #ifdef DEBUG_NETWORK
     PRINT_SCKT(sckt);
 #endif
-    ASSERT(!worker->channel_client->mig_inprogress);
+    spice_assert(!worker->channel_client->mig_inprogress);
 
     /* failure in recv can happen after the client sckt was shutdown
       (after client sent FIN, or after slirp sent FIN and client socket was closed */
@@ -3253,8 +3255,8 @@ static void null_tunnel_socket_close(SlirpUsrNetworkInterface *usr_interface, Us
     TunnelWorker *worker;
     RedSocket *sckt;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
 
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 
@@ -3278,8 +3280,8 @@ static void tunnel_socket_close(SlirpUsrNetworkInterface *usr_interface, UserSoc
     TunnelWorker *worker;
     RedSocket *sckt;
 
-    ASSERT(usr_interface);
-    ASSERT(opaque);
+    spice_assert(usr_interface);
+    spice_assert(opaque);
 
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 
@@ -3313,7 +3315,7 @@ static UserTimer *create_timer(SlirpUsrNetworkInterface *usr_interface,
 {
     TunnelWorker *worker;
 
-    ASSERT(usr_interface);
+    spice_assert(usr_interface);
 
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 
@@ -3324,12 +3326,12 @@ static void arm_timer(SlirpUsrNetworkInterface *usr_interface, UserTimer *timer,
 {
     TunnelWorker *worker;
 
-    ASSERT(usr_interface);
+    spice_assert(usr_interface);
 
     worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
 #ifdef DEBUG_NETWORK
     if (!worker->channel_client) {
-        red_printf("channel not connected");
+        spice_printerr("channel not connected");
     }
 #endif
     if (worker->channel_client && worker->channel_client->mig_inprogress) {
@@ -3352,12 +3354,12 @@ static int tunnel_channel_config_socket(RedChannelClient *rcc)
     RedsStream *stream = red_channel_client_get_stream(rcc);
 
     if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
-        red_printf("accept failed, %s", strerror(errno)); // can't we just use red_error?
+        spice_printerr("accept failed, %s", strerror(errno)); // can't we just use spice_error?
         return FALSE;
     }
 
     if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         return FALSE;
     }
 
@@ -3366,7 +3368,7 @@ static int tunnel_channel_config_socket(RedChannelClient *rcc)
     if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
                    sizeof(delay_val)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
 
@@ -3401,7 +3403,7 @@ static void tunnel_channel_on_disconnect(RedChannel *channel)
     if (!channel) {
         return;
     }
-    red_printf("");
+    spice_printerr("");
     worker = (TunnelWorker *)channel->data;
 
     tunnel_worker_disconnect_slirp(worker);
@@ -3444,7 +3446,7 @@ static void handle_tunnel_channel_link(RedChannel *channel, RedClient *client,
     TunnelWorker *worker = (TunnelWorker *)channel->data;
 
     if (worker->channel_client) {
-        red_error("tunnel does not support multiple client");
+        spice_error("tunnel does not support multiple client");
     }
 
     tcc = (TunnelChannelClient*)red_channel_client_create(sizeof(TunnelChannelClient),
@@ -3462,10 +3464,10 @@ static void handle_tunnel_channel_client_migrate(RedChannelClient *rcc)
 {
     TunnelChannelClient *tunnel_channel;
 #ifdef DEBUG_NETWORK
-    red_printf("TUNNEL_DBG: MIGRATE STARTED");
+    spice_printerr("TUNNEL_DBG: MIGRATE STARTED");
 #endif
     tunnel_channel = (TunnelChannelClient *)rcc;
-    ASSERT(tunnel_channel == tunnel_channel->worker->channel_client);
+    spice_assert(tunnel_channel == tunnel_channel->worker->channel_client);
     tunnel_channel->mig_inprogress = TRUE;
     net_slirp_freeze();
     red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_MIGRATE);
diff --git a/server/red_worker.c b/server/red_worker.c
index 172a571..c17a7d0 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -19,6 +19,8 @@
 #include <config.h>
 #endif
 
+#define SPICE_LOG_DOMAIN "SpiceWorker"
+
 /* Common variable abberiviations:
  *
  * rcc - RedChannelClient
@@ -1113,46 +1115,46 @@ static void print_compress_stats(DisplayChannel *display_channel)
                        display_channel->zlib_glz_stat.comp_size :
                        display_channel->glz_stat.comp_size;
 
-    red_printf("==> Compression stats for display %u", display_channel->common.id);
-    red_printf("Method   \t  count  \torig_size(MB)\tenc_size(MB)\tenc_time(s)");
-    red_printf("QUIC     \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("==> Compression stats for display %u", display_channel->common.id);
+    spice_printerr("Method   \t  count  \torig_size(MB)\tenc_size(MB)\tenc_time(s)");
+    spice_printerr("QUIC     \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->quic_stat.count,
                stat_byte_to_mega(display_channel->quic_stat.orig_size),
                stat_byte_to_mega(display_channel->quic_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->quic_stat.total)
                );
-    red_printf("GLZ      \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("GLZ      \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->glz_stat.count,
                stat_byte_to_mega(display_channel->glz_stat.orig_size),
                stat_byte_to_mega(display_channel->glz_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->glz_stat.total)
                );
-    red_printf("ZLIB GLZ \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("ZLIB GLZ \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->zlib_glz_stat.count,
                stat_byte_to_mega(display_channel->zlib_glz_stat.orig_size),
                stat_byte_to_mega(display_channel->zlib_glz_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->zlib_glz_stat.total)
                );
-    red_printf("LZ       \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("LZ       \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->lz_stat.count,
                stat_byte_to_mega(display_channel->lz_stat.orig_size),
                stat_byte_to_mega(display_channel->lz_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->lz_stat.total)
                );
-    red_printf("JPEG     \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("JPEG     \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->jpeg_stat.count,
                stat_byte_to_mega(display_channel->jpeg_stat.orig_size),
                stat_byte_to_mega(display_channel->jpeg_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->jpeg_stat.total)
                );
-    red_printf("JPEG-RGBA\t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("JPEG-RGBA\t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->jpeg_alpha_stat.count,
                stat_byte_to_mega(display_channel->jpeg_alpha_stat.orig_size),
                stat_byte_to_mega(display_channel->jpeg_alpha_stat.comp_size),
                stat_cpu_time_to_sec(display_channel->jpeg_alpha_stat.total)
                );
-    red_printf("-------------------------------------------------------------------");
-    red_printf("Total    \t%8d\t%13.2f\t%12.2f\t%12.2f",
+    spice_printerr("-------------------------------------------------------------------");
+    spice_printerr("Total    \t%8d\t%13.2f\t%12.2f\t%12.2f",
                display_channel->lz_stat.count + display_channel->glz_stat.count +
                                                 display_channel->quic_stat.count +
                                                 display_channel->jpeg_stat.count +
@@ -1188,15 +1190,15 @@ static inline int is_primary_surface(RedWorker *worker, uint32_t surface_id)
 
 static inline void __validate_surface(RedWorker *worker, uint32_t surface_id)
 {
-    PANIC_ON(surface_id >= worker->n_surfaces);
+    spice_warn_if(surface_id >= worker->n_surfaces);
 }
 
 static inline void validate_surface(RedWorker *worker, uint32_t surface_id)
 {
-    PANIC_ON(surface_id >= worker->n_surfaces);
+    spice_warn_if(surface_id >= worker->n_surfaces);
     if (!worker->surfaces[surface_id].context.canvas) {
-        red_printf("failed on %d", surface_id);
-        PANIC_ON(!worker->surfaces[surface_id].context.canvas);
+        spice_printerr("failed on %d", surface_id);
+        spice_warn_if(!worker->surfaces[surface_id].context.canvas);
     }
 }
 
@@ -1264,7 +1266,7 @@ static void show_red_drawable(RedWorker *worker, RedDrawable *drawable, const ch
     case QXL_DRAW_TEXT:
         break;
     default:
-        red_error("bad drawable type");
+        spice_error("bad drawable type");
     }
     printf("\n");
 }
@@ -1363,8 +1365,8 @@ static void put_drawable_pipe_item(DrawablePipeItem *dpi)
         return;
     }
 
-    ASSERT(!ring_item_is_linked(&dpi->dpi_pipe_item.link));
-    ASSERT(!ring_item_is_linked(&dpi->base));
+    spice_assert(!ring_item_is_linked(&dpi->dpi_pipe_item.link));
+    spice_assert(!ring_item_is_linked(&dpi->base));
     release_drawable(worker, dpi->drawable);
     free(dpi);
 }
@@ -1387,7 +1389,7 @@ static inline DrawablePipeItem *get_drawable_pipe_item(DisplayChannelClient *dcc
 
 static inline DrawablePipeItem *ref_drawable_pipe_item(DrawablePipeItem *dpi)
 {
-    ASSERT(dpi->drawable);
+    spice_assert(dpi->drawable);
     dpi->refs++;
     return dpi;
 }
@@ -1406,7 +1408,7 @@ static inline void red_pipes_add_drawable(RedWorker *worker, Drawable *drawable)
     DisplayChannelClient *dcc;
     RingItem *dcc_ring_item;
 
-    PANIC_ON(!ring_is_empty(&drawable->pipes));
+    spice_warn_if(!ring_is_empty(&drawable->pipes));
     WORKER_FOREACH_DCC(worker, dcc_ring_item, dcc) {
         red_pipe_add_drawable(dcc, drawable);
     }
@@ -1446,7 +1448,7 @@ static inline void red_pipes_add_drawable_after(RedWorker *worker,
     }
     if (num_other_linked != worker->display_channel->common.base.clients_num) {
         RingItem *worker_item;
-        red_printf("TODO: not O(n^2)");
+        spice_printerr("TODO: not O(n^2)");
         WORKER_FOREACH_DCC(worker, worker_item, dcc) {
             int sent = 0;
             DRAWABLE_FOREACH_DPI(pos_after, dpi_link, dpi_pos_after) {
@@ -1592,7 +1594,7 @@ static SurfaceDestroyItem *get_surface_destroy_item(RedChannel *channel,
     SurfaceDestroyItem *destroy;
 
     destroy = (SurfaceDestroyItem *)malloc(sizeof(SurfaceDestroyItem));
-    PANIC_ON(!destroy);
+    spice_warn_if(!destroy);
 
     destroy->surface_destroy.surface_id = surface_id;
 
@@ -1628,7 +1630,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
         if (is_primary_surface(worker, surface_id)) {
             red_reset_stream_trace(worker);
         }
-        ASSERT(surface->context.canvas);
+        spice_assert(surface->context.canvas);
 
         surface->context.canvas->ops->destroy(surface->context.canvas);
         if (surface->create.info) {
@@ -1644,7 +1646,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
             red_destroy_surface_item(worker, dcc, surface_id);
         }
 
-        PANIC_ON(!ring_is_empty(&surface->depend_on_me));
+        spice_warn_if(!ring_is_empty(&surface->depend_on_me));
     }
 }
 
@@ -1693,8 +1695,8 @@ static inline void put_red_drawable(RedWorker *worker, RedDrawable *drawable, ui
 
 static void remove_depended_item(DependItem *item)
 {
-    ASSERT(item->drawable);
-    ASSERT(ring_item_is_linked(&item->ring_item));
+    spice_assert(item->drawable);
+    spice_assert(ring_item_is_linked(&item->ring_item));
     item->drawable = NULL;
     ring_remove(&item->ring_item);
 }
@@ -1731,9 +1733,9 @@ static inline void release_drawable(RedWorker *worker, Drawable *drawable)
     RingItem *item, *next;
 
     if (!--drawable->refs) {
-        ASSERT(!drawable->stream);
-        ASSERT(!drawable->tree_item.shadow);
-        ASSERT(ring_is_empty(&drawable->pipes));
+        spice_assert(!drawable->stream);
+        spice_assert(!drawable->tree_item.shadow);
+        spice_assert(ring_is_empty(&drawable->pipes));
         region_destroy(&drawable->tree_item.base.rgn);
 
         remove_drawable_dependencies(worker, drawable);
@@ -1769,7 +1771,7 @@ static inline void remove_shadow(RedWorker *worker, DrawItem *item)
 
 static inline void current_remove_container(RedWorker *worker, Container *container)
 {
-    ASSERT(ring_is_empty(&container->items));
+    spice_assert(ring_is_empty(&container->items));
     worker->containers_count--;
     ring_remove(&container->base.siblings_link);
     region_destroy(&container->base.rgn);
@@ -1782,7 +1784,7 @@ static inline void container_cleanup(RedWorker *worker, Container *container)
         Container *next = container->base.container;
         if (container->items.next != &container->items) {
             TreeItem *item = (TreeItem *)ring_get_head(&container->items);
-            ASSERT(item);
+            spice_assert(item);
             ring_remove(&item->siblings_link);
             ring_add_after(&item->siblings_link, &container->base.siblings_link);
             item->container = container->base.container;
@@ -1867,7 +1869,7 @@ static inline void current_remove(RedWorker *worker, TreeItem *item)
         } else {
             Container *container = (Container *)now;
 
-            ASSERT(now->type == TREE_ITEM_TYPE_CONTAINER);
+            spice_assert(now->type == TREE_ITEM_TYPE_CONTAINER);
 
             if ((ring_item = ring_get_head(&container->items))) {
                 now = SPICE_CONTAINEROF(ring_item, TreeItem, siblings_link);
@@ -2080,7 +2082,7 @@ static void print_base_item(const char* prefix, const TreeItem *base)
         print_container_item(prefix, (const Container *)base);
         break;
     default:
-        red_error("invalid type %u", base->type);
+        spice_error("invalid type %u", base->type);
     }
 }
 
@@ -2092,7 +2094,7 @@ void __show_current(TreeItem *item, void *data)
 static void show_current(RedWorker *worker, Ring *ring)
 {
     if (ring_is_empty(ring)) {
-        red_printf("TEST: TREE: EMPTY");
+        spice_printerr("TEST: TREE: EMPTY");
         return;
     }
     current_tree_for_each(ring, __show_current, NULL);
@@ -2128,7 +2130,7 @@ static inline Ring *ring_of(RedWorker *worker, Ring *ring, TreeItem *item)
 
 static inline int __contained_by(RedWorker *worker, TreeItem *item, Ring *ring)
 {
-    ASSERT(item && ring);
+    spice_assert(item && ring);
     do {
         Ring *now = ring_of(worker, ring, item);
         if (now == ring) {
@@ -2200,7 +2202,7 @@ static inline void __exclude_region(RedWorker *worker, Ring *ring, TreeItem *ite
         } else {
             Shadow *shadow;
 
-            ASSERT(item->type == TREE_ITEM_TYPE_SHADOW);
+            spice_assert(item->type == TREE_ITEM_TYPE_SHADOW);
             shadow = (Shadow *)item;
             region_exclude(rgn, &and_rgn);
             region_or(&shadow->on_hold, &and_rgn);
@@ -2228,7 +2230,7 @@ static void exclude_region(RedWorker *worker, Ring *ring, RingItem *ring_item, Q
         TreeItem *now = SPICE_CONTAINEROF(ring_item, TreeItem, siblings_link);
         Container *container = now->container;
 
-        ASSERT(!region_is_empty(&now->rgn));
+        spice_assert(!region_is_empty(&now->rgn));
 
         if (region_intersects(rgn, &now->rgn)) {
             print_base_item("EXCLUDE2", now);
@@ -2236,7 +2238,7 @@ static void exclude_region(RedWorker *worker, Ring *ring, RingItem *ring_item, Q
             print_base_item("EXCLUDE3", now);
 
             if (region_is_empty(&now->rgn)) {
-                ASSERT(now->type != TREE_ITEM_TYPE_SHADOW);
+                spice_assert(now->type != TREE_ITEM_TYPE_SHADOW);
                 ring_item = now->siblings_link.prev;
                 print_base_item("EXCLUDE_REMOVE", now);
                 current_remove(worker, now);
@@ -2247,7 +2249,7 @@ static void exclude_region(RedWorker *worker, Ring *ring, RingItem *ring_item, Q
                 Container *container = (Container *)now;
                 if ((ring_item = ring_get_head(&container->items))) {
                     ring = &container->items;
-                    ASSERT(((TreeItem *)ring_item)->container);
+                    spice_assert(((TreeItem *)ring_item)->container);
                     continue;
                 }
                 ring_item = &now->siblings_link;
@@ -2402,7 +2404,7 @@ static inline void red_free_stream(RedWorker *worker, Stream *stream)
 static void red_release_stream(RedWorker *worker, Stream *stream)
 {
     if (!--stream->refs) {
-        ASSERT(!ring_item_is_linked(&stream->link));
+        spice_assert(!ring_item_is_linked(&stream->link));
         if (stream->mjpeg_encoder) {
             mjpeg_encoder_destroy(stream->mjpeg_encoder);
         }
@@ -2413,8 +2415,8 @@ static void red_release_stream(RedWorker *worker, Stream *stream)
 
 static inline void red_detach_stream(RedWorker *worker, Stream *stream)
 {
-    ASSERT(stream->current && stream->current->stream);
-    ASSERT(stream->current->stream == stream);
+    spice_assert(stream->current && stream->current->stream);
+    spice_assert(stream->current->stream == stream);
     stream->current->stream = NULL;
     stream->current = NULL;
 }
@@ -2438,7 +2440,7 @@ static void push_stream_clip_by_drawable(DisplayChannelClient* dcc, StreamAgent
     int n_rects;
 
     if (!item) {
-        PANIC("alloc failed");
+        spice_critical("alloc failed");
     }
 
     if (drawable->red_drawable->clip.type == SPICE_CLIP_TYPE_NONE) {
@@ -2462,7 +2464,7 @@ static void push_stream_clip(DisplayChannelClient* dcc, StreamAgent *agent)
     int n_rects;
 
     if (!item) {
-        PANIC("alloc failed");
+        spice_critical("alloc failed");
     }
     item->clip_type = SPICE_CLIP_TYPE_RECTS;
 
@@ -2489,8 +2491,8 @@ static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *str
     StreamAgent *agent;
     RingItem *item;
 
-    ASSERT(!drawable->stream && !stream->current);
-    ASSERT(drawable && stream);
+    spice_assert(!drawable->stream && !stream->current);
+    spice_assert(drawable && stream);
     stream->current = drawable;
     drawable->stream = stream;
     stream->last_time = drawable->creation_time;
@@ -2510,13 +2512,13 @@ static void red_stop_stream(RedWorker *worker, Stream *stream)
     DisplayChannelClient *dcc;
     RingItem *item;
 
-    ASSERT(ring_item_is_linked(&stream->link));
-    ASSERT(!stream->current);
+    spice_assert(ring_item_is_linked(&stream->link));
+    spice_assert(!stream->current);
     WORKER_FOREACH_DCC(worker, item, dcc) {
         StreamAgent *stream_agent;
         stream_agent = &dcc->stream_agents[stream - worker->streams_buf];
         region_clear(&stream_agent->vis_region);
-        ASSERT(!pipe_item_is_linked(&stream_agent->destroy_item));
+        spice_assert(!pipe_item_is_linked(&stream_agent->destroy_item));
         stream->refs++;
         red_channel_client_pipe_add(&dcc->common.base, &stream_agent->destroy_item);
     }
@@ -2536,7 +2538,7 @@ static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *strea
     RedChannelClient *rcc;
     DisplayChannelClient *dcc;
 
-    ASSERT(stream->current);
+    spice_assert(stream->current);
     WORKER_FOREACH_DCC(worker, item, dcc) {
         UpgradeItem *upgrade_item;
         int n_rects;
@@ -2682,7 +2684,7 @@ static inline void red_handle_streams_timout(RedWorker *worker)
 
 static void red_display_release_stream(RedWorker *worker, StreamAgent *agent)
 {
-    ASSERT(agent->stream);
+    spice_assert(agent->stream);
     red_release_stream(worker, agent->stream);
 }
 
@@ -2736,7 +2738,7 @@ static void red_display_create_stream(DisplayChannelClient *dcc, Stream *stream)
     StreamAgent *agent = &dcc->stream_agents[stream - dcc->common.worker->streams_buf];
 
     stream->refs++;
-    ASSERT(region_is_empty(&agent->vis_region));
+    spice_assert(region_is_empty(&agent->vis_region));
     if (stream->current) {
         agent->frames = 1;
         region_clone(&agent->vis_region, &stream->current->tree_item.base.rgn);
@@ -2760,13 +2762,13 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
     int stream_width;
     int stream_height;
 
-    ASSERT(!drawable->stream);
+    spice_assert(!drawable->stream);
 
     if (!(stream = red_alloc_stream(worker))) {
         return;
     }
 
-    ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY);
+    spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
     src_rect = &drawable->red_drawable->u.copy.src_area;
     stream_width = src_rect->right - src_rect->left;
     stream_height = src_rect->bottom - src_rect->top;
@@ -2919,7 +2921,7 @@ static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream)
     StreamAgent *agent;
     RingItem *ring_item;
 
-    ASSERT(stream->current);
+    spice_assert(stream->current);
 
     if (!display_is_connected(worker)) {
         return;
@@ -2962,7 +2964,7 @@ static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream)
 static inline void red_update_copy_graduality(RedWorker* worker, Drawable *drawable)
 {
     SpiceBitmap *bitmap;
-    ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY);
+    spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
 
     if (worker->streaming_video != STREAM_VIDEO_FILTER) {
         drawable->copy_bitmap_graduality = BITMAP_GRADUAL_INVALID;
@@ -3211,7 +3213,7 @@ static void red_reset_stream_trace(RedWorker *worker)
         if (!stream->current) {
             red_stop_stream(worker, stream);
         } else {
-            red_printf("attached stream");
+            spice_printerr("attached stream");
         }
     }
 
@@ -3230,7 +3232,7 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
     RingItem *exclude_base = NULL;
 
     print_base_item("ADD", &item->base);
-    ASSERT(!region_is_empty(&item->base.rgn));
+    spice_assert(!region_is_empty(&item->base.rgn));
     region_init(&exclude_rgn);
     now = ring_next(ring, ring);
 
@@ -3298,11 +3300,11 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
                     now = ring_next(ring, ring);
                     continue;
                 }
-                ASSERT(IS_DRAW_ITEM(sibling));
+                spice_assert(IS_DRAW_ITEM(sibling));
                 if (!((DrawItem *)sibling)->container_root) {
                     container = __new_container(worker, (DrawItem *)sibling);
                     if (!container) {
-                        red_printf("create new container failed");
+                        spice_printerr("create new container failed");
                         region_destroy(&exclude_rgn);
                         return FALSE;
                     }
@@ -3465,17 +3467,17 @@ static inline int red_current_add_qxl(RedWorker *worker, Ring *ring, Drawable *d
 #ifdef RED_WORKER_STAT
     if ((++worker->add_count % 100) == 0) {
         stat_time_t total = worker->add_stat.total;
-        red_printf("add with shadow count %u",
+        spice_printerr("add with shadow count %u",
                    worker->add_with_shadow_count);
         worker->add_with_shadow_count = 0;
-        red_printf("add[%u] %f exclude[%u] %f __exclude[%u] %f",
+        spice_printerr("add[%u] %f exclude[%u] %f __exclude[%u] %f",
                    worker->add_stat.count,
                    stat_cpu_time_to_sec(total),
                    worker->exclude_stat.count,
                    stat_cpu_time_to_sec(worker->exclude_stat.total),
                    worker->__exclude_stat.count,
                    stat_cpu_time_to_sec(worker->__exclude_stat.total));
-        red_printf("add %f%% exclude %f%% exclude2 %f%% __exclude %f%%",
+        spice_printerr("add %f%% exclude %f%% exclude2 %f%% __exclude %f%%",
                    (double)(total - worker->exclude_stat.total) / total * 100,
                    (double)(worker->exclude_stat.total) / total * 100,
                    (double)(worker->exclude_stat.total -
@@ -3514,7 +3516,7 @@ static int surface_format_to_image_type(uint32_t surface_format)
     case SPICE_SURFACE_FMT_32_ARGB:
         return SPICE_BITMAP_FMT_RGBA;
     default:
-        PANIC("Unsupported surface format");
+        spice_critical("Unsupported surface format");
     }
     return 0;
 }
@@ -3614,7 +3616,7 @@ static void free_one_drawable(RedWorker *worker, int force_glz_free)
     Drawable *drawable;
     Container *container;
 
-    ASSERT(ring_item);
+    spice_assert(ring_item);
     drawable = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
     if (force_glz_free) {
         RingItem *glz_item, *next_item;
@@ -3752,7 +3754,7 @@ static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable
     int surface_id;
     Drawable *item = get_drawable(worker, drawable->effect, drawable, group_id);
 
-    ASSERT(item);
+    spice_assert(item);
 
     surface_id = item->surface_id;
 
@@ -3851,7 +3853,7 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
         break;
     }
     case QXL_SURFACE_CMD_DESTROY:
-        PANIC_ON(!red_surface->context.canvas);
+        spice_warn_if(!red_surface->context.canvas);
         set_surface_release_info(worker, surface_id, 0, surface->release_info, group_id);
         red_handle_depends_on_target_surface(worker, surface_id);
         /* note that red_handle_depends_on_target_surface must be called before red_current_clear.
@@ -3862,7 +3864,7 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
         red_destroy_surface(worker, surface_id);
         break;
     default:
-            red_error("unknown surface command");
+            spice_error("unknown surface command");
     };
     red_put_surface_cmd(surface);
     free(surface);
@@ -3921,7 +3923,7 @@ static void image_cache_remove(ImageCache *cache, ImageCacheItem *item)
 
     now = &cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
     for (;;) {
-        ASSERT(*now);
+        spice_assert(*now);
         if (*now == item) {
             *now = item->next;
             break;
@@ -3946,7 +3948,7 @@ static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, pixman_im
 #ifndef IMAGE_CACHE_AGE
     if (cache->num_items == IMAGE_CACHE_MAX_ITEMS) {
         ImageCacheItem *tail = (ImageCacheItem *)ring_get_tail(&cache->lru);
-        ASSERT(tail);
+        spice_assert(tail);
         image_cache_remove(cache, tail);
     }
 #endif
@@ -3973,7 +3975,7 @@ static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id
 
     ImageCacheItem *item = image_cache_find(cache, id);
     if (!item) {
-        red_error("not found");
+        spice_error("not found");
     }
     return pixman_image_ref(item->image);
 }
@@ -4028,8 +4030,8 @@ static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImag
     SpiceImage *image = *image_ptr;
 
     if (image == NULL) {
-        ASSERT(drawable != NULL);
-        ASSERT(drawable->self_bitmap != NULL);
+        spice_assert(drawable != NULL);
+        spice_assert(drawable->self_bitmap != NULL);
         *image_ptr = drawable->self_bitmap;
         return;
     }
@@ -4061,7 +4063,7 @@ static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImag
         /* nothing */
         break;
     default:
-        red_error("invalid image type");
+        spice_error("invalid image type");
     }
 }
 
@@ -4204,7 +4206,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
         break;
     }
     default:
-        red_printf("invalid type");
+        spice_printerr("invalid type");
     }
 }
 
@@ -4242,7 +4244,7 @@ static void validate_area(RedWorker *worker, const SpiceRect *area, uint32_t sur
             return;
         }
 
-        ASSERT(stride < 0);
+        spice_assert(stride < 0);
         uint8_t *dest = line_0 + (area->top * stride) + area->left * sizeof(uint32_t);
         dest += (h - 1) * stride;
         canvas->ops->read_bits(canvas, dest, -stride, area);
@@ -4280,7 +4282,7 @@ static inline void __red_collect_for_update(RedWorker *worker, Ring *ring, RingI
 
                 if ((ring_item = ring_get_head(&container->items))) {
                     ring = &container->items;
-                    ASSERT(((TreeItem *)ring_item)->container);
+                    spice_assert(((TreeItem *)ring_item)->container);
                     continue;
                 }
                 ring_item = &now->siblings_link;
@@ -4353,8 +4355,8 @@ static void red_update_area_till(RedWorker *worker, const SpiceRect *area, int s
     Drawable *now;
     QRegion rgn;
 
-    ASSERT(last);
-    ASSERT(ring_item_is_linked(&last->list_link));
+    spice_assert(last);
+    spice_assert(ring_item_is_linked(&last->list_link));
 
     surface = &worker->surfaces[surface_id];
 
@@ -4471,7 +4473,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
         release_drawable(worker, now);
 #ifdef ACYCLIC_SURFACE_DEBUG
         if (gn != surface->current_gn) {
-            red_error("cyclic surface dependencies");
+            spice_error("cyclic surface dependencies");
         }
 #endif
     } while (now != last);
@@ -4533,7 +4535,7 @@ static inline void free_cursor_item(RedWorker *worker, CursorItem *item)
     worker->free_cursor_items = (_CursorItem *)item;
 #ifdef DEBUG_CURSORS
     ++_cursor_count;
-    ASSERT(_cursor_count <= NUM_CURSORS);
+    spice_assert(_cursor_count <= NUM_CURSORS);
 #endif
 }
 
@@ -4551,7 +4553,7 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
 {
     CursorItem *cursor_item;
 
-    PANIC_ON(!(cursor_item = alloc_cursor_item(worker)));
+    spice_warn_if(!(cursor_item = alloc_cursor_item(worker)));
 
     cursor_item->refs = 1;
     cursor_item->group_id = group_id;
@@ -4562,7 +4564,7 @@ static CursorItem *get_cursor_item(RedWorker *worker, RedCursorCmd *cmd, uint32_
 
 static CursorPipeItem *ref_cursor_pipe_item(CursorPipeItem *item)
 {
-    ASSERT(item);
+    spice_assert(item);
     item->refs++;
     return item;
 }
@@ -4580,13 +4582,13 @@ static PipeItem *new_cursor_pipe_item(RedChannelClient *rcc, void *data, int num
 
 static void put_cursor_pipe_item(CursorChannelClient *ccc, CursorPipeItem *pipe_item)
 {
-    ASSERT(pipe_item);
+    spice_assert(pipe_item);
 
     if (--pipe_item->refs) {
         return;
     }
 
-    ASSERT(!pipe_item_is_linked(&pipe_item->base));
+    spice_assert(!pipe_item_is_linked(&pipe_item->base));
 
     red_release_cursor(ccc->common.worker, pipe_item->cursor_item);
     free(pipe_item);
@@ -4617,7 +4619,7 @@ static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint
         worker->cursor_trail_frequency = cursor_cmd->u.trail.frequency;
         break;
     default:
-        red_error("invalid cursor command %u", cursor_cmd->type);
+        spice_error("invalid cursor command %u", cursor_cmd->type);
     }
 
     if (cursor_is_connected(worker) && (worker->mouse_mode == SPICE_MOUSE_MODE_SERVER ||
@@ -4675,7 +4677,7 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ri
             break;
         }
         default:
-            red_error("bad command type");
+            spice_error("bad command type");
         }
         n++;
     }
@@ -4755,7 +4757,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
                             &message, ext_cmd.cmd.data);
 #ifdef DEBUG
             /* alert: accessing message.data is insecure */
-            red_printf("MESSAGE: %s", message.data);
+            spice_printerr("MESSAGE: %s", message.data);
 #endif
             release_info_ext.group_id = ext_cmd.group_id;
             release_info_ext.info = message.release_info;
@@ -4772,7 +4774,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
             break;
         }
         default:
-            red_error("bad command type");
+            spice_error("bad command type");
         }
         n++;
         if ((worker->display_channel &&
@@ -4793,9 +4795,8 @@ static void red_free_some(RedWorker *worker)
     DisplayChannelClient *dcc;
     RingItem *item;
 
-    red_printf_debug(3, "WORKER",
-                     "#draw=%d, #red_draw=%d, #glz_draw=%d", worker->drawable_count,
-                     worker->red_drawable_count, worker->glz_drawable_count);
+    spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", worker->drawable_count,
+                worker->red_drawable_count, worker->glz_drawable_count);
     WORKER_FOREACH_DCC(worker, item, dcc) {
         GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
 
@@ -4844,7 +4845,7 @@ static ImageItem *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
     int bpp;
     int all_set;
 
-    ASSERT(area);
+    spice_assert(area);
 
     width = area->right - area->left;
     height = area->bottom - area->top;
@@ -4929,7 +4930,7 @@ static void marshaller_add_compressed(SpiceMarshaller *m,
     size_t max = size;
     size_t now;
     do {
-        ASSERT(comp_buf);
+        spice_assert(comp_buf);
         now = MIN(sizeof(comp_buf->buf), max);
         max -= now;
         spice_marshaller_add_ref(m, (uint8_t*)comp_buf->buf, now);
@@ -5020,7 +5021,7 @@ static void red_display_free_compress_buf(DisplayChannelClient *dcc,
     RedCompressBuf **curr_used = &dcc->send_data.used_compress_bufs;
 
     for (;;) {
-        ASSERT(*curr_used);
+        spice_assert(*curr_used);
         if (*curr_used == buf) {
             *curr_used = buf->next;
             break;
@@ -5041,7 +5042,7 @@ static void red_display_reset_compress_buf(DisplayChannelClient *dcc)
 
 static void red_display_destroy_compress_bufs(DisplayChannel *display_channel)
 {
-    ASSERT(!red_channel_is_connected(&display_channel->common.base));
+    spice_assert(!red_channel_is_connected(&display_channel->common.base));
     while (display_channel->free_compress_bufs) {
         RedCompressBuf *buf = display_channel->free_compress_bufs;
         display_channel->free_compress_bufs = buf->next;
@@ -5091,7 +5092,7 @@ static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannelClient *dcc, D
    NOTE - the caller should set the glz_instance returned by the encoder by itself.*/
 static GlzDrawableInstanceItem *red_display_add_glz_drawable_instance(RedGlzDrawable *glz_drawable)
 {
-    ASSERT(glz_drawable->instances_count < MAX_GLZ_DRAWABLE_INSTANCES);
+    spice_assert(glz_drawable->instances_count < MAX_GLZ_DRAWABLE_INSTANCES);
     // NOTE: We assume the additions are performed consecutively, without removals in the middle
     GlzDrawableInstanceItem *ret = glz_drawable->instances_pool + glz_drawable->instances_count;
     glz_drawable->instances_count++;
@@ -5117,13 +5118,13 @@ static void red_display_free_glz_drawable_instance(DisplayChannelClient *dcc,
     RedWorker *worker = display_channel->common.worker;
     RedGlzDrawable *glz_drawable;
 
-    ASSERT(glz_drawable_instance);
-    ASSERT(glz_drawable_instance->red_glz_drawable);
+    spice_assert(glz_drawable_instance);
+    spice_assert(glz_drawable_instance->red_glz_drawable);
 
     glz_drawable = glz_drawable_instance->red_glz_drawable;
 
-    ASSERT(glz_drawable->dcc == dcc);
-    ASSERT(glz_drawable->instances_count);
+    spice_assert(glz_drawable->dcc == dcc);
+    spice_assert(glz_drawable->instances_count);
 
     ring_remove(&glz_drawable_instance->glz_link);
     glz_drawable->instances_count--;
@@ -5134,7 +5135,7 @@ static void red_display_free_glz_drawable_instance(DisplayChannelClient *dcc,
     }
 
     if (ring_is_empty(&glz_drawable->instances)) {
-        ASSERT(!glz_drawable->instances_count);
+        spice_assert(!glz_drawable->instances_count);
 
         Drawable *drawable = glz_drawable->drawable;
 
@@ -5272,7 +5273,7 @@ static void quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
     va_start(ap, fmt);
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
-    red_printf("%s", usr_data->message_buf);
+    spice_printerr("%s", usr_data->message_buf);
 
     longjmp(usr_data->jmp_env, 1);
 }
@@ -5285,7 +5286,7 @@ static void lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
     va_start(ap, fmt);
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
-    red_printf("%s", usr_data->message_buf);
+    spice_printerr("%s", usr_data->message_buf);
 
     longjmp(usr_data->jmp_env, 1);
 }
@@ -5299,7 +5300,7 @@ static void glz_usr_error(GlzEncoderUsrContext *usr, const char *fmt, ...)
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
 
-    PANIC("%s", usr_data->message_buf); // if global lz fails in the middle
+    spice_critical("%s", usr_data->message_buf); // if global lz fails in the middle
                                         // the consequences are not predictable since the window
                                         // can turn to be unsynchronized between the server and
                                         // and the client
@@ -5313,7 +5314,7 @@ static void quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...)
     va_start(ap, fmt);
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
-    red_printf("%s", usr_data->message_buf);
+    spice_printerr("%s", usr_data->message_buf);
 }
 
 static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
@@ -5324,7 +5325,7 @@ static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
     va_start(ap, fmt);
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
-    red_printf("%s", usr_data->message_buf);
+    spice_printerr("%s", usr_data->message_buf);
 }
 
 static void glz_usr_warn(GlzEncoderUsrContext *usr, const char *fmt, ...)
@@ -5335,7 +5336,7 @@ static void glz_usr_warn(GlzEncoderUsrContext *usr, const char *fmt, ...)
     va_start(ap, fmt);
     vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
     va_end(ap);
-    red_printf("%s", usr_data->message_buf);
+    spice_printerr("%s", usr_data->message_buf);
 }
 
 static void *quic_usr_malloc(QuicUsrContext *usr, int size)
@@ -5472,7 +5473,7 @@ static int zlib_usr_more_input(ZlibEncoderUsrContext *usr, uint8_t** input)
     int buf_size;
 
     if (!usr_data->u.compressed_data.next) {
-        ASSERT(usr_data->u.compressed_data.size_left == 0);
+        spice_assert(usr_data->u.compressed_data.size_left == 0);
         return 0;
     }
 
@@ -5521,7 +5522,7 @@ static inline void red_init_quic(RedWorker *worker)
     worker->quic = quic_create(&worker->quic_data.usr);
 
     if (!worker->quic) {
-        PANIC("create quic failed");
+        spice_critical("create quic failed");
     }
 }
 
@@ -5538,7 +5539,7 @@ static inline void red_init_lz(RedWorker *worker)
     worker->lz = lz_create(&worker->lz_data.usr);
 
     if (!worker->lz) {
-        PANIC("create lz failed");
+        spice_critical("create lz failed");
     }
 }
 
@@ -5563,7 +5564,7 @@ static inline void red_init_jpeg(RedWorker *worker)
     worker->jpeg = jpeg_encoder_create(&worker->jpeg_data.usr);
 
     if (!worker->jpeg) {
-        PANIC("create jpeg encoder failed");
+        spice_critical("create jpeg encoder failed");
     }
 }
 
@@ -5575,7 +5576,7 @@ static inline void red_init_zlib(RedWorker *worker)
     worker->zlib = zlib_encoder_create(&worker->zlib_data.usr, ZLIB_DEFAULT_COMPRESSION_LEVEL);
 
     if (!worker->zlib) {
-        PANIC("create zlib encoder failed");
+        spice_critical("create zlib encoder failed");
     }
 }
 
@@ -5655,13 +5656,13 @@ static BitmapGradualType _get_bitmap_graduality_level(RedWorker *worker, SpiceBi
                                               &chunk_score, &chunk_num_samples);
             break;
         default:
-            red_error("invalid bitmap format (not RGB) %u", bitmap->format);
+            spice_error("invalid bitmap format (not RGB) %u", bitmap->format);
         }
         score += chunk_score;
         num_samples += chunk_num_samples;
     }
 
-    ASSERT(num_samples);
+    spice_assert(num_samples);
     score /= num_samples;
 
     if (bitmap->format == SPICE_BITMAP_FMT_16BIT) {
@@ -5683,7 +5684,7 @@ static BitmapGradualType _get_bitmap_graduality_level(RedWorker *worker, SpiceBi
 
 static inline int _stride_is_extra(SpiceBitmap *bitmap)
 {
-    ASSERT(bitmap);
+    spice_assert(bitmap);
     if (BITMAP_FMT_IS_RGB[bitmap->format]) {
         return ((bitmap->x * BITMAP_FMP_BYTES_PER_PIXEL[bitmap->format]) < bitmap->stride);
     } else {
@@ -5701,9 +5702,11 @@ static inline int _stride_is_extra(SpiceBitmap *bitmap)
             return bytes_width < bitmap->stride;
         }
         default:
-            red_error("invalid image type %u", bitmap->format);
+            spice_error("invalid image type %u", bitmap->format);
+            return 0;
         }
     }
+    return 0;
 }
 
 static const LzImageType MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[] = {
@@ -5736,7 +5739,7 @@ static inline int red_glz_compress_image(DisplayChannelClient *dcc,
 #ifdef COMPRESS_STAT
     stat_time_t start_time = stat_now();
 #endif
-    ASSERT(BITMAP_FMT_IS_RGB[src->format]);
+    spice_assert(BITMAP_FMT_IS_RGB[src->format]);
     GlzData *glz_data = &dcc->glz_data;
     ZlibData *zlib_data;
     LzImageType type = MAP_BITMAP_FMT_TO_LZ_IMAGE_TYPE[src->format];
@@ -5785,7 +5788,7 @@ static inline int red_glz_compress_image(DisplayChannelClient *dcc,
     zlib_data->data.bufs_head = zlib_data->data.bufs_tail;
 
     if (!zlib_data->data.bufs_head) {
-        red_printf("failed to allocate zlib compress buffer");
+        spice_printerr("failed to allocate zlib compress buffer");
         goto glz;
     }
 
@@ -5948,7 +5951,7 @@ static int red_jpeg_compress_image(DisplayChannelClient *dcc, SpiceImage *dest,
     jpeg_data->data.bufs_head = jpeg_data->data.bufs_tail;
 
     if (!jpeg_data->data.bufs_head) {
-        red_printf("failed to allocate compress buffer");
+        spice_printerr("failed to allocate compress buffer");
         return FALSE;
     }
 
@@ -6190,7 +6193,7 @@ static inline int red_compress_image(DisplayChannelClient *dcc,
 
     if (quic_compress) {
 #ifdef COMPRESS_DEBUG
-        red_printf("QUIC compress");
+        spice_printerr("QUIC compress");
 #endif
         // if bitmaps is picture-like, compress it using jpeg
         if (can_lossy && display_channel->enable_jpeg &&
@@ -6216,7 +6219,8 @@ static inline int red_compress_image(DisplayChannelClient *dcc,
                    (image_compression == SPICE_IMAGE_COMPRESS_LZ)) {
             glz = FALSE;
         } else {
-            red_error("invalid image compression type %u", image_compression);
+            spice_error("invalid image compression type %u", image_compression);
+            return FALSE;
         }
 
         if (glz) {
@@ -6236,12 +6240,12 @@ static inline int red_compress_image(DisplayChannelClient *dcc,
             ret = red_lz_compress_image(dcc, dest, src, o_comp_data,
                                         drawable->group_id);
 #ifdef COMPRESS_DEBUG
-            red_printf("LZ LOCAL compress");
+            spice_printerr("LZ LOCAL compress");
 #endif
         }
 #ifdef COMPRESS_DEBUG
         else {
-            red_printf("LZ global compress fmt=%d", src->format);
+            spice_printerr("LZ global compress fmt=%d", src->format);
         }
 #endif
         return ret;
@@ -6256,7 +6260,7 @@ static inline void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
 
     if ((image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) {
-        ASSERT(image->descriptor.width * image->descriptor.height > 0);
+        spice_assert(image->descriptor.width * image->descriptor.height > 0);
         if (!(io_image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME)) {
             if (pixmap_cache_add(dcc->pixmap_cache, image->descriptor.id,
                                  image->descriptor.width * image->descriptor.height, is_lossy,
@@ -6296,7 +6300,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
     SpiceMarshaller *bitmap_palette_out, *lzplt_palette_out;
 
     if (simage == NULL) {
-        ASSERT(drawable->self_bitmap);
+        spice_assert(drawable->self_bitmap);
         simage = drawable->self_bitmap;
     }
 
@@ -6319,8 +6323,8 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
                 }
                 spice_marshall_Image(m, &image,
                                      &bitmap_palette_out, &lzplt_palette_out);
-                ASSERT(bitmap_palette_out == NULL);
-                ASSERT(lzplt_palette_out == NULL);
+                spice_assert(bitmap_palette_out == NULL);
+                spice_assert(lzplt_palette_out == NULL);
                 stat_inc_counter(display_channel->cache_hits_counter, 1);
                 return FILL_BITS_TYPE_CACHE;
             } else {
@@ -6348,8 +6352,8 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
         image.u.surface.surface_id = surface_id;
         spice_marshall_Image(m, &image,
                              &bitmap_palette_out, &lzplt_palette_out);
-        ASSERT(bitmap_palette_out == NULL);
-        ASSERT(lzplt_palette_out == NULL);
+        spice_assert(bitmap_palette_out == NULL);
+        spice_assert(lzplt_palette_out == NULL);
         return FILL_BITS_TYPE_SURFACE;
     }
     case SPICE_IMAGE_TYPE_BITMAP: {
@@ -6373,7 +6377,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
             fill_palette(dcc, palette, &bitmap->flags);
             spice_marshall_Image(m, &image,
                                  &bitmap_palette_out, &lzplt_palette_out);
-            ASSERT(lzplt_palette_out == NULL);
+            spice_assert(lzplt_palette_out == NULL);
 
             if (bitmap_palette_out && palette) {
                 spice_marshall_Palette(bitmap_palette_out, palette);
@@ -6387,7 +6391,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
 
             spice_marshall_Image(m, &image,
                                  &bitmap_palette_out, &lzplt_palette_out);
-            ASSERT(bitmap_palette_out == NULL);
+            spice_assert(bitmap_palette_out == NULL);
 
             marshaller_add_compressed(m, comp_send_data.comp_buf,
                                       comp_send_data.comp_buf_size);
@@ -6396,7 +6400,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
                 spice_marshall_Palette(lzplt_palette_out, comp_send_data.lzplt_palette);
             }
 
-            ASSERT(!comp_send_data.is_lossy || can_lossy);
+            spice_assert(!comp_send_data.is_lossy || can_lossy);
             return (comp_send_data.is_lossy ? FILL_BITS_TYPE_COMPRESS_LOSSY :
                                               FILL_BITS_TYPE_COMPRESS_LOSSLESS);
         }
@@ -6407,13 +6411,15 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
         image.u.quic = simage->u.quic;
         spice_marshall_Image(m, &image,
                              &bitmap_palette_out, &lzplt_palette_out);
-        ASSERT(bitmap_palette_out == NULL);
-        ASSERT(lzplt_palette_out == NULL);
+        spice_assert(bitmap_palette_out == NULL);
+        spice_assert(lzplt_palette_out == NULL);
         spice_marshaller_add_ref_chunks(m, image.u.quic.data);
         return FILL_BITS_TYPE_COMPRESS_LOSSLESS;
     default:
-        red_error("invalid image type %u", image.descriptor.type);
+        spice_error("invalid image type %u", image.descriptor.type);
     }
+
+    return 0;
 }
 
 static void fill_mask(RedChannelClient *rcc, SpiceMarshaller *m,
@@ -6706,7 +6712,7 @@ static int pipe_rendered_drawables_intersect_with_areas(RedWorker *worker,
     PipeItem *pipe_item;
     Ring *pipe;
 
-    ASSERT(num_surfaces);
+    spice_assert(num_surfaces);
     pipe = &dcc->common.base.pipe;
 
     for (pipe_item = (PipeItem *)ring_get_head(pipe);
@@ -6780,7 +6786,7 @@ static void red_pipe_replace_rendered_drawables_with_images(RedWorker *worker,
         resent_areas[num_resent] = drawable->red_drawable->bbox;
         num_resent++;
 
-        ASSERT(image);
+        spice_assert(image);
         red_channel_client_pipe_remove_and_release(&dcc->common.base, &dpi->dpi_pipe_item);
         pipe_item = &image->link;
     }
@@ -7722,7 +7728,7 @@ static void red_lossy_marshall_qxl_drawable(RedWorker *worker, RedChannelClient
         red_lossy_marshall_qxl_draw_text(worker, rcc, base_marshaller, dpi);
         break;
     default:
-        red_error("invalid type");
+        spice_error("invalid type");
     }
 }
 
@@ -7773,7 +7779,7 @@ static inline void red_marshall_qxl_drawable(RedWorker *worker, RedChannelClient
         red_marshall_qxl_draw_text(worker, rcc, m, dpi);
         break;
     default:
-        red_error("invalid type");
+        spice_error("invalid type");
     }
 }
 
@@ -7956,7 +7962,7 @@ static inline uint8_t *red_get_image_line(RedWorker *worker, SpiceChunks *chunks
     }
 
     if (chunk->len - *offset < stride) {
-        red_printf("bad chunk alignment");
+        spice_printerr("bad chunk alignment");
         return NULL;
     }
     ret = chunk->data + *offset;
@@ -8011,8 +8017,8 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
     RedWorker *worker = dcc->common.worker;
     int n;
 
-    ASSERT(stream);
-    ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY);
+    spice_assert(stream);
+    spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
 
     worker = display_channel->common.worker;
     image = drawable->red_drawable->u.copy.src_bitmap;
@@ -8062,7 +8068,7 @@ static inline void marshall_qxl_drawable(RedChannelClient *rcc,
     Drawable *item = dpi->drawable;
     DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel, DisplayChannel, common.base);
 
-    ASSERT(display_channel && rcc);
+    spice_assert(display_channel && rcc);
     if (item->stream && red_marshall_stream_data(rcc, m, item)) {
         return;
     }
@@ -8074,7 +8080,7 @@ static inline void marshall_qxl_drawable(RedChannelClient *rcc,
 
 static inline void red_marshall_verb(RedChannelClient *rcc, uint16_t verb)
 {
-    ASSERT(rcc);
+    spice_assert(rcc);
     red_channel_client_init_send_data(rcc, verb, NULL);
 }
 
@@ -8109,9 +8115,9 @@ static void display_channel_marshall_migrate_data(RedChannelClient *rcc,
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, NULL);
 
-    ASSERT(dcc->pixmap_cache);
+    spice_assert(dcc->pixmap_cache);
     display_data.magic = DISPLAY_MIGRATE_DATA_MAGIC;
-    ASSERT(MAX_CACHE_CLIENTS == 4); //MIGRATE_DATA_VERSION dependent
+    spice_assert(MAX_CACHE_CLIENTS == 4); //MIGRATE_DATA_VERSION dependent
     display_data.version = DISPLAY_MIGRATE_DATA_VERSION;
 
     display_data.message_serial = red_channel_client_get_message_serial(rcc);
@@ -8122,7 +8128,7 @@ static void display_channel_marshall_migrate_data(RedChannelClient *rcc,
     memcpy(display_data.pixmap_cache_clients, dcc->pixmap_cache->sync,
            sizeof(display_data.pixmap_cache_clients));
 
-    ASSERT(dcc->glz_dict);
+    spice_assert(dcc->glz_dict);
     red_freeze_glz(dcc);
     display_data.glz_dict_id = dcc->glz_dict->id;
     glz_enc_dictionary_get_restore_data(dcc->glz_dict->dict,
@@ -8187,7 +8193,7 @@ static void red_marshall_image(RedChannelClient *rcc, SpiceMarshaller *m, ImageI
     SpiceMarshaller *src_bitmap_out, *mask_bitmap_out;
     SpiceMarshaller *bitmap_palette_out, *lzplt_palette_out;
 
-    ASSERT(rcc && display_channel && item);
+    spice_assert(rcc && display_channel && item);
     worker = display_channel->common.worker;
 
     QXL_SET_IMAGE_ID(&red_image, QXL_IMAGE_GROUP_RED, ++worker->bits_unique);
@@ -8312,14 +8318,14 @@ static void red_display_marshall_upgrade(RedChannelClient *rcc, SpiceMarshaller
     SpiceMsgDisplayDrawCopy copy;
     SpiceMarshaller *src_bitmap_out, *mask_bitmap_out;
 
-    ASSERT(rcc && rcc->channel && item && item->drawable);
+    spice_assert(rcc && rcc->channel && item && item->drawable);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_DRAW_COPY, &item->base);
 
     red_drawable = item->drawable->red_drawable;
-    ASSERT(red_drawable->type == QXL_DRAW_COPY);
-    ASSERT(red_drawable->u.copy.rop_descriptor == SPICE_ROPD_OP_PUT);
-    ASSERT(red_drawable->u.copy.mask.bitmap == 0);
+    spice_assert(red_drawable->type == QXL_DRAW_COPY);
+    spice_assert(red_drawable->u.copy.rop_descriptor == SPICE_ROPD_OP_PUT);
+    spice_assert(red_drawable->u.copy.mask.bitmap == 0);
 
     copy.base.surface_id = 0;
     copy.base.box = red_drawable->bbox;
@@ -8340,7 +8346,7 @@ static void red_display_marshall_stream_start(RedChannelClient *rcc,
     Stream *stream = agent->stream;
 
     agent->last_send_time = 0;
-    ASSERT(stream);
+    spice_assert(stream);
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_CREATE, &agent->create_item);
     SpiceMsgDisplayStreamCreate stream_create;
     SpiceClipRects clip_rects;
@@ -8377,7 +8383,7 @@ static void red_display_marshall_stream_clip(RedChannelClient *rcc,
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
     StreamAgent *agent = item->stream_agent;
 
-    ASSERT(agent->stream);
+    spice_assert(agent->stream);
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_CLIP, &item->base);
     SpiceMsgDisplayStreamClip stream_clip;
@@ -8404,7 +8410,7 @@ static void red_display_marshall_stream_end(RedChannelClient *rcc,
 static void red_cursor_marshall_inval(RedChannelClient *rcc,
                 SpiceMarshaller *m, CacheItem *cach_item)
 {
-    ASSERT(rcc);
+    spice_assert(rcc);
     red_marshall_inval(rcc, m, cach_item);
 }
 
@@ -8417,7 +8423,7 @@ static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *bas
     SpiceMsgCursorInit msg;
     AddBufInfo info;
 
-    ASSERT(rcc);
+    spice_assert(rcc);
     cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
     worker = cursor_channel->common.worker;
 
@@ -8453,7 +8459,7 @@ static void red_marshall_cursor(RedChannelClient *rcc,
     RedCursorCmd *cmd;
     RedWorker *worker;
 
-    ASSERT(cursor_channel);
+    spice_assert(cursor_channel);
 
     worker = cursor_channel->common.worker;
 
@@ -8495,7 +8501,7 @@ static void red_marshall_cursor(RedChannelClient *rcc,
         }
         break;
     default:
-        red_error("bad cursor command %d", cmd->type);
+        spice_error("bad cursor command %d", cmd->type);
     }
 }
 
@@ -8561,7 +8567,7 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
         red_marshall_verb(rcc, ((VerbItem*)pipe_item)->verb);
         break;
     case PIPE_ITEM_TYPE_MIGRATE:
-        red_printf("PIPE_ITEM_TYPE_MIGRATE");
+        spice_printerr("PIPE_ITEM_TYPE_MIGRATE");
         display_channel_marshall_migrate(rcc, m);
         break;
     case PIPE_ITEM_TYPE_MIGRATE_DATA:
@@ -8593,7 +8599,7 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
         break;
     }
     default:
-        red_error("invalid pipe item type");
+        spice_error("invalid pipe item type");
     }
 
     display_channel_client_release_item_before_push(dcc, pipe_item);
@@ -8620,7 +8626,7 @@ static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item)
         red_marshall_verb(rcc, ((VerbItem*)pipe_item)->verb);
         break;
     case PIPE_ITEM_TYPE_MIGRATE:
-        red_printf("PIPE_ITEM_TYPE_MIGRATE");
+        spice_printerr("PIPE_ITEM_TYPE_MIGRATE");
         cursor_channel_marshall_migrate(rcc, m);
         break;
     case PIPE_ITEM_TYPE_CURSOR_INIT:
@@ -8632,7 +8638,7 @@ static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item)
         red_marshall_verb(rcc, SPICE_MSG_CURSOR_INVAL_ALL);
         break;
     default:
-        red_error("invalid pipe item type");
+        spice_error("invalid pipe item type");
     }
 
     cursor_channel_client_release_item_before_push(ccc, pipe_item);
@@ -8662,7 +8668,7 @@ static void __show_tree_call(TreeItem *item, void *data)
     int i;
 
     while (tree_data->container != item->container) {
-        ASSERT(tree_data->container);
+        spice_assert(tree_data->container);
         tree_data->level--;
         tree_data->container = tree_data->container->base.container;
     }
@@ -8726,11 +8732,11 @@ static void display_channel_client_on_disconnect(RedChannelClient *rcc)
     if (!rcc) {
         return;
     }
-    red_printf("");
+    spice_printerr("");
     common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base);
     worker = common->worker;
     display_channel = (DisplayChannel *)rcc->channel;
-    ASSERT(display_channel == worker->display_channel);
+    spice_assert(display_channel == worker->display_channel);
 #ifdef COMPRESS_STAT
     print_compress_stats(display_channel);
 #endif
@@ -8746,9 +8752,9 @@ static void display_channel_client_on_disconnect(RedChannelClient *rcc)
     if (!red_channel_is_connected(rcc->channel)) {
         red_display_destroy_compress_bufs(display_channel);
     }
-    red_printf_debug(3, "WORKER", "#draw=%d, #red_draw=%d, #glz_draw=%d",
-                     worker->drawable_count, worker->red_drawable_count,
-                     worker->glz_drawable_count);
+    spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d",
+                worker->drawable_count, worker->red_drawable_count,
+                worker->glz_drawable_count);
 }
 
 void red_disconnect_all_display_TODO_remove_me(RedChannel *channel)
@@ -8858,8 +8864,10 @@ static inline void *create_canvas_for_surface(RedWorker *worker, RedSurface *sur
         return canvas;
 #endif
     default:
-        red_error("invalid renderer type");
+        spice_error("invalid renderer type");
     };
+
+    return NULL;
 }
 
 static SurfaceCreateItem *get_surface_create_item(
@@ -8870,7 +8878,7 @@ static SurfaceCreateItem *get_surface_create_item(
     SurfaceCreateItem *create;
 
     create = (SurfaceCreateItem *)malloc(sizeof(SurfaceCreateItem));
-    PANIC_ON(!create);
+    spice_warn_if(!create);
 
     create->surface_create.surface_id = surface_id;
     create->surface_create.width = width;
@@ -8931,9 +8939,9 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
     uint32_t i;
 
     if (stride >= 0) {
-        PANIC("Untested path stride >= 0");
+        spice_critical("Untested path stride >= 0");
     }
-    PANIC_ON(surface->context.canvas);
+    spice_warn_if(surface->context.canvas);
 
     surface->context.canvas_draws_on_surface = FALSE;
     surface->context.width = width;
@@ -8956,7 +8964,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
                                                             width, height, stride,
                                                             surface->context.format, line_0);
         if (!surface->context.canvas) {
-            PANIC("drawing canvas creating failed - can`t create same type canvas");
+            spice_critical("drawing canvas creating failed - can`t create same type canvas");
         }
 
         if (send_client) {
@@ -8984,7 +8992,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
         }
     }
 
-    PANIC("unable to create drawing canvas");
+    spice_critical("unable to create drawing canvas");
 }
 
 static inline void flush_display_commands(RedWorker *worker)
@@ -9021,7 +9029,7 @@ static inline void flush_display_commands(RedWorker *worker)
             // TODO: MC: the whole timeout will break since it takes lowest timeout, should
             // do it client by client.
             if (red_now() >= end_time) {
-                red_printf("update timeout");
+                spice_printerr("update timeout");
                 red_disconnect_all_display_TODO_remove_me(channel);
             } else {
                 sleep_count++;
@@ -9063,7 +9071,7 @@ static inline void flush_cursor_commands(RedWorker *worker)
             red_channel_receive(channel);
             red_channel_send(channel);
             if (red_now() >= end_time) {
-                red_printf("flush cursor timeout");
+                spice_printerr("flush cursor timeout");
                 red_disconnect_cursor(channel);
             } else {
                 sleep_count++;
@@ -9107,15 +9115,15 @@ static int display_channel_client_wait_for_init(DisplayChannelClient *dcc)
         if (dcc->pixmap_cache && dcc->glz_dict) {
             dcc->pixmap_cache_generation = dcc->pixmap_cache->generation;
             /* TODO: move common.id? if it's used for a per client structure.. */
-            red_printf("creating encoder with id == %d", dcc->common.id);
+            spice_printerr("creating encoder with id == %d", dcc->common.id);
             dcc->glz = glz_encoder_create(dcc->common.id, dcc->glz_dict->dict, &dcc->glz_data.usr);
             if (!dcc->glz) {
-                PANIC("create global lz failed");
+                spice_critical("create global lz failed");
             }
             return TRUE;
         }
         if (red_now() > end_time) {
-            red_printf("timeout");
+            spice_printerr("timeout");
             red_channel_client_disconnect(&dcc->common.base);
             break;
         }
@@ -9189,10 +9197,10 @@ static GlzSharedDictionary *red_create_glz_dictionary(DisplayChannelClient *dcc,
                                                             MAX_LZ_ENCODERS,
                                                             &dcc->glz_data.usr);
 #ifdef COMPRESS_DEBUG
-    red_printf("Lz Window %d Size=%d", id, window_size);
+    spice_printerr("Lz Window %d Size=%d", id, window_size);
 #endif
     if (!glz_dict) {
-        PANIC("failed creating lz dictionary");
+        spice_critical("failed creating lz dictionary");
         return NULL;
     }
     return _red_create_glz_dictionary(dcc->common.base.client, id, glz_dict);
@@ -9205,7 +9213,7 @@ static GlzSharedDictionary *red_create_restored_glz_dictionary(DisplayChannelCli
     GlzEncDictContext *glz_dict = glz_enc_dictionary_restore(restore_data,
                                                              &dcc->glz_data.usr);
     if (!glz_dict) {
-        PANIC("failed creating lz dictionary");
+        spice_critical("failed creating lz dictionary");
         return NULL;
     }
     return _red_create_glz_dictionary(dcc->common.base.client, id, glz_dict);
@@ -9342,7 +9350,7 @@ static void red_release_pixmap_cache(DisplayChannelClient *dcc)
 
 static int display_channel_init_cache(DisplayChannelClient *dcc, SpiceMsgcDisplayInit *init_info)
 {
-    ASSERT(!dcc->pixmap_cache);
+    spice_assert(!dcc->pixmap_cache);
     return !!(dcc->pixmap_cache = red_get_pixmap_cache(dcc->common.base.client,
                                                        init_info->pixmap_cache_id,
                                                        init_info->pixmap_cache_size));
@@ -9351,7 +9359,7 @@ static int display_channel_init_cache(DisplayChannelClient *dcc, SpiceMsgcDispla
 static int display_channel_init_glz_dictionary(DisplayChannelClient *dcc,
                                                SpiceMsgcDisplayInit *init_info)
 {
-    ASSERT(!dcc->glz_dict);
+    spice_assert(!dcc->glz_dict);
     ring_init(&dcc->glz_drawables);
     ring_init(&dcc->glz_drawables_inst_to_free);
     pthread_mutex_init(&dcc->glz_drawables_inst_to_free_lock, NULL);
@@ -9369,7 +9377,7 @@ static int display_channel_init(DisplayChannelClient *dcc, SpiceMsgcDisplayInit
 static int display_channel_handle_migrate_glz_dictionary(DisplayChannelClient *dcc,
                                                          DisplayChannelMigrateData *migrate_info)
 {
-    ASSERT(!dcc->glz_dict);
+    spice_assert(!dcc->glz_dict);
     ring_init(&dcc->glz_drawables);
     ring_init(&dcc->glz_drawables_inst_to_free);
     pthread_mutex_init(&dcc->glz_drawables_inst_to_free_lock, NULL);
@@ -9384,7 +9392,7 @@ static int display_channel_handle_migrate_mark(RedChannelClient *rcc)
     RedChannel *channel = &display_channel->common.base;
 
     if (!display_channel->expect_migrate_mark) {
-        red_printf("unexpected");
+        spice_printerr("unexpected");
         return FALSE;
     }
     display_channel->expect_migrate_mark = FALSE;
@@ -9398,12 +9406,12 @@ static uint64_t display_channel_handle_migrate_data_get_serial(
     DisplayChannelMigrateData *migrate_data = message;
 
     if (size < sizeof(*migrate_data)) {
-        red_printf("bad message size");
+        spice_printerr("bad message size");
         return 0;
     }
     if (migrate_data->magic != DISPLAY_MIGRATE_DATA_MAGIC ||
         migrate_data->version != DISPLAY_MIGRATE_DATA_VERSION) {
-        red_printf("invalid content");
+        spice_printerr("invalid content");
         return 0;
     }
     return migrate_data->message_serial;
@@ -9419,17 +9427,17 @@ static uint64_t display_channel_handle_migrate_data(RedChannelClient *rcc, uint3
     int i;
 
     if (size < sizeof(*migrate_data)) {
-        red_printf("bad message size");
+        spice_printerr("bad message size");
         return FALSE;
     }
     migrate_data = (DisplayChannelMigrateData *)message;
     if (migrate_data->magic != DISPLAY_MIGRATE_DATA_MAGIC ||
         migrate_data->version != DISPLAY_MIGRATE_DATA_VERSION) {
-        red_printf("invalid content");
+        spice_printerr("invalid content");
         return FALSE;
     }
     if (!display_channel->expect_migrate_data) {
-        red_printf("unexpected");
+        spice_printerr("unexpected");
         return FALSE;
     }
     display_channel->expect_migrate_data = FALSE;
@@ -9456,10 +9464,10 @@ static uint64_t display_channel_handle_migrate_data(RedChannelClient *rcc, uint3
         dcc->glz = glz_encoder_create(dcc->common.id,
                                       dcc->glz_dict->dict, &dcc->glz_data.usr);
         if (!dcc->glz) {
-            PANIC("create global lz failed");
+            spice_critical("create global lz failed");
         }
     } else {
-        PANIC("restoring global lz dictionary failed");
+        spice_critical("restoring global lz dictionary failed");
     }
 
     red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_INVAL_PALLET_CACHE);
@@ -9474,7 +9482,7 @@ static int display_channel_handle_message(RedChannelClient *rcc, uint32_t size,
     switch (type) {
     case SPICE_MSGC_DISPLAY_INIT:
         if (!dcc->expect_init) {
-            red_printf("unexpected SPICE_MSGC_DISPLAY_INIT");
+            spice_printerr("unexpected SPICE_MSGC_DISPLAY_INIT");
             return FALSE;
         }
         dcc->expect_init = FALSE;
@@ -9493,12 +9501,12 @@ static int common_channel_config_socket(RedChannelClient *rcc)
     int delay_val;
 
     if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         return FALSE;
     }
 
     if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         return FALSE;
     }
 
@@ -9507,7 +9515,7 @@ static int common_channel_config_socket(RedChannelClient *rcc)
     if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
                    sizeof(delay_val)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
     return TRUE;
@@ -9553,7 +9561,7 @@ static SpiceWatch *worker_watch_add(int fd, int event_mask, SpiceWatchFunc func,
         }
     }
     if (i == MAX_EVENT_SOURCES) {
-        red_printf("ERROR could not add a watch for channel type %u id %u",
+        spice_printerr("ERROR could not add a watch for channel type %u id %u",
                    rcc->channel->type, rcc->channel->id);
         return NULL;
     }
@@ -9700,7 +9708,7 @@ error:
 
 static void display_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
 {
-    ASSERT(item);
+    spice_assert(item);
     switch (item->type) {
     case PIPE_ITEM_TYPE_DRAW:
         ref_drawable_pipe_item(SPICE_CONTAINEROF(item, DrawablePipeItem, dpi_pipe_item));
@@ -9722,7 +9730,7 @@ static void display_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item
         ((ImageItem *)item)->refs++;
         break;
     default:
-        PANIC("invalid item type");
+        spice_critical("invalid item type");
     }
 }
 
@@ -9755,7 +9763,7 @@ static void display_channel_client_release_item_after_push(DisplayChannelClient
         free(item);
         break;
     default:
-        PANIC("invalid item type");
+        spice_critical("invalid item type");
     }
 }
 
@@ -9814,7 +9822,7 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
         free(item);
         break;
     default:
-        PANIC("invalid item type");
+        spice_critical("invalid item type");
     }
 }
 
@@ -9822,11 +9830,11 @@ static void display_channel_release_item(RedChannelClient *rcc, PipeItem *item,
 {
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
 
-    ASSERT(item);
+    spice_assert(item);
     if (item_pushed) {
         display_channel_client_release_item_after_push(dcc, item);
     } else {
-        red_printf_once("not pushed (%d)", item->type);
+        spice_debug("not pushed (%d)", item->type);
         display_channel_client_release_item_before_push(dcc, item);
     }
 }
@@ -9839,7 +9847,7 @@ static void display_channel_create(RedWorker *worker, int migrate)
         return;
     }
 
-    red_printf("create display channel");
+    spice_printerr("create display channel");
     if (!(worker->display_channel = (DisplayChannel *)__new_channel(
             worker, sizeof(*display_channel),
             SPICE_CHANNEL_DISPLAY, migrate,
@@ -9852,7 +9860,7 @@ static void display_channel_create(RedWorker *worker, int migrate)
             display_channel_handle_migrate_data,
             display_channel_handle_migrate_data_get_serial
             ))) {
-        red_printf("failed to create display channel");
+        spice_printerr("failed to create display channel");
         return;
     }
     display_channel = worker->display_channel;
@@ -9887,18 +9895,18 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red
     int is_low_bandwidth = main_channel_client_is_low_bandwidth(red_client_get_main(client));
 
     if (!worker->display_channel) {
-        red_printf("Warning: Display channel was not created");
+        spice_printerr("Warning: Display channel was not created");
         return;
     }
     display_channel = worker->display_channel;
-    red_printf("add display channel client");
+    spice_printerr("add display channel client");
     dcc = display_channel_client_create(&display_channel->common, client, stream,
                                         common_caps, num_common_caps,
                                         caps, num_caps);
     if (!dcc) {
         return;
     }
-    red_printf("New display (client %p) dcc %p stream %p", client, dcc, stream);
+    spice_printerr("New display (client %p) dcc %p stream %p", client, dcc, stream);
     stream_buf_size = 32*1024;
     dcc->send_data.stream_outbuf = spice_malloc(stream_buf_size);
     dcc->send_data.stream_outbuf_size = stream_buf_size;
@@ -9925,8 +9933,8 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red
                                                  SPICE_WAN_COMPRESSION_ALWAYS);
     }
 
-    red_printf("jpeg %s", display_channel->enable_jpeg ? "enabled" : "disabled");
-    red_printf("zlib-over-glz %s", display_channel->enable_zlib_glz_wrap ? "enabled" : "disabled");
+    spice_printerr("jpeg %s", display_channel->enable_jpeg ? "enabled" : "disabled");
+    spice_printerr("zlib-over-glz %s", display_channel->enable_zlib_glz_wrap ? "enabled" : "disabled");
 
     // todo: tune level according to bandwidth
     display_channel->zlib_level = ZLIB_DEFAULT_COMPRESSION_LEVEL;
@@ -9950,7 +9958,7 @@ static void red_disconnect_cursor(RedChannel *channel)
         return;
     }
     common = SPICE_CONTAINEROF(channel, CommonChannel, base);
-    ASSERT(channel == (RedChannel *)common->worker->cursor_channel);
+    spice_assert(channel == (RedChannel *)common->worker->cursor_channel);
     common->worker->cursor_channel = NULL;
     red_channel_apply_clients(channel, red_reset_cursor_cache);
     red_channel_disconnect(channel);
@@ -9971,7 +9979,7 @@ static void on_new_cursor_channel(RedWorker *worker, RedChannelClient *rcc)
 {
     CursorChannel *channel = worker->cursor_channel;
 
-    ASSERT(channel);
+    spice_assert(channel);
     red_channel_client_ack_zero_messages_window(rcc);
     red_channel_client_push_set_ack(rcc);
     // TODO: why do we check for context.canvas? defer this to after display cc is connected
@@ -9984,7 +9992,7 @@ static void on_new_cursor_channel(RedWorker *worker, RedChannelClient *rcc)
 static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
 {
     CursorPipeItem *cursor_pipe_item;
-    ASSERT(item);
+    spice_assert(item);
     cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
     ref_cursor_pipe_item(cursor_pipe_item);
 }
@@ -10008,7 +10016,7 @@ static void cursor_channel_client_release_item_before_push(CursorChannelClient *
         free(item);
         break;
     default:
-        red_error("invalid pipe item type");
+        spice_error("invalid pipe item type");
     }
 }
 
@@ -10022,7 +10030,7 @@ static void cursor_channel_client_release_item_after_push(CursorChannelClient *c
             break;
         }
         default:
-            PANIC("invalid item type");
+            spice_critical("invalid item type");
     }
 }
 
@@ -10030,12 +10038,12 @@ static void cursor_channel_release_item(RedChannelClient *rcc, PipeItem *item, i
 {
     CursorChannelClient *ccc = RCC_TO_CCC(rcc);
 
-    ASSERT(item);
+    spice_assert(item);
 
     if (item_pushed) {
         cursor_channel_client_release_item_after_push(ccc, item);
     } else {
-        red_printf_once("not pushed (%d)", item->type);
+        spice_debug("not pushed (%d)", item->type);
         cursor_channel_client_release_item_before_push(ccc, item);
     }
 }
@@ -10045,7 +10053,7 @@ static void cursor_channel_create(RedWorker *worker, int migrate)
     if (worker->cursor_channel != NULL) {
         return;
     }
-    red_printf("create cursor channel");
+    spice_printerr("create cursor channel");
     worker->cursor_channel = (CursorChannel *)__new_channel(
         worker, sizeof(*worker->cursor_channel),
         SPICE_CHANNEL_CURSOR, migrate,
@@ -10068,11 +10076,11 @@ static void red_connect_cursor(RedWorker *worker, RedClient *client, RedsStream
     CursorChannelClient *ccc;
 
     if (worker->cursor_channel == NULL) {
-        red_printf("Warning: cursor channel was not created");
+        spice_printerr("Warning: cursor channel was not created");
         return;
     }
     channel = worker->cursor_channel;
-    red_printf("add cursor channel client");
+    spice_printerr("add cursor channel client");
     ccc = cursor_channel_create_rcc(&channel->common, client, stream,
                                     common_caps, num_common_caps,
                                     caps, num_caps);
@@ -10104,7 +10112,7 @@ static void red_wait_outgoing_item(RedChannelClient *rcc)
         return;
     }
     end_time = red_now() + DETACH_TIMEOUT;
-    red_printf("blocked");
+    spice_printerr("blocked");
 
     do {
         usleep(DETACH_SLEEP_DURATION);
@@ -10113,12 +10121,12 @@ static void red_wait_outgoing_item(RedChannelClient *rcc)
     } while ((blocked = red_channel_client_blocked(rcc)) && red_now() < end_time);
 
     if (blocked) {
-        red_printf("timeout");
+        spice_printerr("timeout");
         // TODO - shutting down the socket but we still need to trigger
         // disconnection. Right now we wait for main channel to error for that.
         red_channel_client_shutdown(rcc);
     } else {
-        ASSERT(red_channel_client_no_item_being_sent(rcc));
+        spice_assert(red_channel_client_no_item_being_sent(rcc));
     }
 }
 
@@ -10127,7 +10135,7 @@ static void rcc_shutdown_if_blocked(RedChannelClient *rcc)
     if (red_channel_client_blocked(rcc)) {
         red_channel_client_shutdown(rcc);
     } else {
-        ASSERT(red_channel_client_no_item_being_sent(rcc));
+        spice_assert(red_channel_client_no_item_being_sent(rcc));
     }
 }
 
@@ -10141,7 +10149,7 @@ static void red_wait_outgoing_items(RedChannel *channel)
     }
 
     end_time = red_now() + DETACH_TIMEOUT;
-    red_printf("blocked");
+    spice_printerr("blocked");
 
     do {
         usleep(DETACH_SLEEP_DURATION);
@@ -10150,10 +10158,10 @@ static void red_wait_outgoing_items(RedChannel *channel)
     } while ((blocked = red_channel_any_blocked(channel)) && red_now() < end_time);
 
     if (blocked) {
-        red_printf("timeout");
+        spice_printerr("timeout");
         red_channel_apply_clients(channel, rcc_shutdown_if_blocked);
     } else {
-        ASSERT(red_channel_no_item_being_sent(channel));
+        spice_assert(red_channel_no_item_being_sent(channel));
     }
 }
 
@@ -10168,7 +10176,7 @@ static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
         return;
     }
 
-    red_printf("");
+    spice_printerr("");
     channel->channel_cbs.hold_item(rcc, item);
 
     end_time = red_now() + CHANNEL_PUSH_TIMEOUT;
@@ -10187,7 +10195,7 @@ static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
     }
 
     if (item_in_pipe) {
-        red_printf("timeout");
+        spice_printerr("timeout");
         red_channel_client_disconnect(rcc);
     } else {
         if (red_channel_client_item_being_sent(rcc, item)) {
@@ -10236,7 +10244,7 @@ void handle_dev_update_async(void *opaque, void *payload)
     red_get_rect_ptr(&rect, &qxl_area);
     flush_display_commands(worker);
 
-    ASSERT(worker->running);
+    spice_assert(worker->running);
 
     validate_surface(worker, surface_id);
     red_update_area(worker, &rect, surface_id);
@@ -10272,7 +10280,7 @@ void handle_dev_update(void *opaque, void *payload)
     red_get_rect_ptr(rect, qxl_area);
     flush_display_commands(worker);
 
-    ASSERT(worker->running);
+    spice_assert(worker->running);
 
     validate_surface(worker, surface_id);
     red_update_area(worker, rect, surface_id);
@@ -10328,7 +10336,7 @@ static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
 
 static void dev_destroy_surface_wait(RedWorker *worker, uint32_t surface_id)
 {
-    ASSERT(surface_id == 0);
+    spice_assert(surface_id == 0);
 
     flush_all_qxl_commands(worker);
 
@@ -10381,10 +10389,10 @@ static inline void dev_destroy_surfaces(RedWorker *worker)
             if (worker->surfaces[i].context.canvas) {
                 red_destroy_surface(worker, i);
             }
-            ASSERT(!worker->surfaces[i].context.canvas);
+            spice_assert(!worker->surfaces[i].context.canvas);
         }
     }
-    ASSERT(ring_is_empty(&worker->streams));
+    spice_assert(ring_is_empty(&worker->streams));
 
     if (display_is_connected(worker)) {
         red_channel_pipes_add_type(&worker->display_channel->common.base,
@@ -10410,9 +10418,9 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
 {
     uint8_t *line_0;
 
-    PANIC_ON(surface_id != 0);
-    PANIC_ON(surface.height == 0);
-    PANIC_ON(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
+    spice_warn_if(surface_id != 0);
+    spice_warn_if(surface.height == 0);
+    spice_warn_if(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
              abs(surface.stride) * surface.height);
 
     line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem,
@@ -10446,19 +10454,19 @@ void handle_dev_create_primary_surface(void *opaque, void *payload)
 
 static void dev_destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
 {
-    PANIC_ON(surface_id != 0);
+    spice_warn_if(surface_id != 0);
 
     if (!worker->surfaces[surface_id].context.canvas) {
-        red_printf("double destroy of primary surface");
+        spice_printerr("double destroy of primary surface");
         return;
     }
 
     flush_all_qxl_commands(worker);
     dev_destroy_surface_wait(worker, 0);
     red_destroy_surface(worker, 0);
-    ASSERT(ring_is_empty(&worker->streams));
+    spice_assert(ring_is_empty(&worker->streams));
 
-    ASSERT(!worker->surfaces[surface_id].context.canvas);
+    spice_assert(!worker->surfaces[surface_id].context.canvas);
 
     red_cursor_reset(worker);
 }
@@ -10518,8 +10526,8 @@ void handle_dev_stop(void *opaque, void *payload)
 {
     RedWorker *worker = opaque;
 
-    red_printf("stop");
-    ASSERT(worker->running);
+    spice_printerr("stop");
+    spice_assert(worker->running);
     worker->running = FALSE;
     red_display_clear_glz_drawables(worker->display_channel);
     flush_all_surfaces(worker);
@@ -10533,7 +10541,7 @@ void handle_dev_start(void *opaque, void *payload)
     RedChannel *cursor_red_channel = &worker->cursor_channel->common.base;
     RedChannel *display_red_channel = &worker->display_channel->common.base;
 
-    ASSERT(!worker->running);
+    spice_assert(!worker->running);
     if (worker->cursor_channel) {
         cursor_red_channel->migrate = FALSE;
     }
@@ -10558,16 +10566,15 @@ void handle_dev_oom(void *opaque, void *payload)
     RedChannel *display_red_channel = &worker->display_channel->common.base;
     int ring_is_empty;
 
-    ASSERT(worker->running);
+    spice_assert(worker->running);
     // streams? but without streams also leak
-    red_printf_debug(1, "WORKER",
-                     "OOM1 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u",
-                     worker->drawable_count,
-                     worker->red_drawable_count,
-                     worker->glz_drawable_count,
-                     worker->current_size,
-                     worker->display_channel ?
-                     red_channel_sum_pipes_size(display_red_channel) : 0);
+    spice_debug("OOM1 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u",
+                worker->drawable_count,
+                worker->red_drawable_count,
+                worker->glz_drawable_count,
+                worker->current_size,
+                worker->display_channel ?
+                red_channel_sum_pipes_size(display_red_channel) : 0);
     while (red_process_commands(worker, MAX_PIPE_SIZE, &ring_is_empty)) {
         red_channel_push(&worker->display_channel->common.base);
     }
@@ -10575,14 +10582,13 @@ void handle_dev_oom(void *opaque, void *payload)
         red_free_some(worker);
         worker->qxl->st->qif->flush_resources(worker->qxl);
     }
-    red_printf_debug(1, "WORKER",
-                     "OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u",
-                     worker->drawable_count,
-                     worker->red_drawable_count,
-                     worker->glz_drawable_count,
-                     worker->current_size,
-                     worker->display_channel ?
-                     red_channel_sum_pipes_size(display_red_channel) : 0);
+    spice_debug("OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u",
+                worker->drawable_count,
+                worker->red_drawable_count,
+                worker->glz_drawable_count,
+                worker->current_size,
+                worker->display_channel ?
+                red_channel_sum_pipes_size(display_red_channel) : 0);
     clear_bit(RED_WORKER_PENDING_OOM, worker->pending);
 }
 
@@ -10644,7 +10650,7 @@ void handle_dev_display_connect(void *opaque, void *payload)
     RedClient *client = msg->client;
     int migration = msg->migration;
 
-    red_printf("connect");
+    spice_printerr("connect");
     handle_new_display_channel(worker, client, stream, migration,
                                msg->common_caps, msg->num_common_caps,
                                msg->caps, msg->num_caps);
@@ -10657,8 +10663,8 @@ void handle_dev_display_disconnect(void *opaque, void *payload)
     RedWorkerMessageDisplayDisconnect *msg = payload;
     RedChannelClient *rcc = msg->rcc;
 
-    red_printf("disconnect display client");
-    ASSERT(rcc);
+    spice_printerr("disconnect display client");
+    spice_assert(rcc);
     red_channel_client_disconnect(rcc);
 }
 
@@ -10668,8 +10674,8 @@ void handle_dev_display_migrate(void *opaque, void *payload)
     RedWorker *worker = opaque;
 
     RedChannelClient *rcc = msg->rcc;
-    red_printf("migrate display client");
-    ASSERT(rcc);
+    spice_printerr("migrate display client");
+    spice_assert(rcc);
     red_migrate_display(worker, rcc);
 }
 
@@ -10693,7 +10699,7 @@ void handle_dev_cursor_connect(void *opaque, void *payload)
     RedClient *client = msg->client;
     int migration = msg->migration;
 
-    red_printf("cursor connect");
+    spice_printerr("cursor connect");
     red_connect_cursor(worker, client, stream, migration,
                        msg->common_caps, msg->num_common_caps,
                        msg->caps, msg->num_caps);
@@ -10706,8 +10712,8 @@ void handle_dev_cursor_disconnect(void *opaque, void *payload)
     RedWorkerMessageCursorDisconnect *msg = payload;
     RedChannelClient *rcc = msg->rcc;
 
-    red_printf("disconnect cursor client");
-    ASSERT(rcc);
+    spice_printerr("disconnect cursor client");
+    spice_assert(rcc);
     red_channel_client_disconnect(rcc);
 }
 
@@ -10717,8 +10723,8 @@ void handle_dev_cursor_migrate(void *opaque, void *payload)
     RedWorker *worker = opaque;
     RedChannelClient *rcc = msg->rcc;
 
-    red_printf("migrate cursor client");
-    ASSERT(rcc);
+    spice_printerr("migrate cursor client");
+    spice_assert(rcc);
     red_migrate_cursor(worker, rcc);
 }
 
@@ -10730,25 +10736,25 @@ void handle_dev_set_compression(void *opaque, void *payload)
     worker->image_compression = msg->image_compression;
     switch (worker->image_compression) {
     case SPICE_IMAGE_COMPRESS_AUTO_LZ:
-        red_printf("ic auto_lz");
+        spice_printerr("ic auto_lz");
         break;
     case SPICE_IMAGE_COMPRESS_AUTO_GLZ:
-        red_printf("ic auto_glz");
+        spice_printerr("ic auto_glz");
         break;
     case SPICE_IMAGE_COMPRESS_QUIC:
-        red_printf("ic quic");
+        spice_printerr("ic quic");
         break;
     case SPICE_IMAGE_COMPRESS_LZ:
-        red_printf("ic lz");
+        spice_printerr("ic lz");
         break;
     case SPICE_IMAGE_COMPRESS_GLZ:
-        red_printf("ic glz");
+        spice_printerr("ic glz");
         break;
     case SPICE_IMAGE_COMPRESS_OFF:
-        red_printf("ic off");
+        spice_printerr("ic off");
         break;
     default:
-        red_printf("ic invalid");
+        spice_printerr("ic invalid");
     }
 #ifdef COMPRESS_STAT
     print_compress_stats(worker->display_channel);
@@ -10769,19 +10775,19 @@ void handle_dev_set_streaming_video(void *opaque, void *payload)
     RedWorker *worker = opaque;
 
     worker->streaming_video = msg->streaming_video;
-    ASSERT(worker->streaming_video != STREAM_VIDEO_INVALID);
+    spice_assert(worker->streaming_video != STREAM_VIDEO_INVALID);
     switch(worker->streaming_video) {
         case STREAM_VIDEO_ALL:
-            red_printf("sv all");
+            spice_printerr("sv all");
             break;
         case STREAM_VIDEO_FILTER:
-            red_printf("sv filter");
+            spice_printerr("sv filter");
             break;
         case STREAM_VIDEO_OFF:
-            red_printf("sv off");
+            spice_printerr("sv off");
             break;
         default:
-            red_printf("sv invalid");
+            spice_printerr("sv invalid");
     }
 }
 
@@ -10791,7 +10797,7 @@ void handle_dev_set_mouse_mode(void *opaque, void *payload)
     RedWorker *worker = opaque;
 
     worker->mouse_mode = msg->mode;
-    red_printf("mouse mode %u", worker->mouse_mode);
+    spice_printerr("mouse mode %u", worker->mouse_mode);
 }
 
 void handle_dev_add_memslot_async(void *opaque, void *payload)
@@ -10819,7 +10825,7 @@ void handle_dev_loadvm_commands(void *opaque, void *payload)
     uint32_t count = msg->count;
     QXLCommandExt *ext = msg->ext;
 
-    red_printf("loadvm_commands");
+    spice_printerr("loadvm_commands");
     for (i = 0 ; i < count ; ++i) {
         switch (ext[i].cmd.type) {
         case QXL_CMD_CURSOR:
@@ -10835,7 +10841,7 @@ void handle_dev_loadvm_commands(void *opaque, void *payload)
             red_process_surface(worker, surface_cmd, ext[i].group_id, TRUE);
             break;
         default:
-            red_printf("unhandled loadvm command type (%d)", ext[i].cmd.type);
+            spice_printerr("unhandled loadvm command type (%d)", ext[i].cmd.type);
             break;
         }
     }
@@ -10848,7 +10854,7 @@ static void worker_handle_dispatcher_async_done(void *opaque,
     RedWorker *worker = opaque;
     RedWorkerMessageAsync *msg_async = payload;
 
-    red_printf_debug(2, "WORKER", "");
+    spice_debug(NULL);
     red_dispatcher_async_complete(worker->red_dispatcher, msg_async->cmd);
 }
 
@@ -11039,7 +11045,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     Dispatcher *dispatcher;
     int i;
 
-    ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
+    spice_assert(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
 
     memset(worker, 0, sizeof(RedWorker));
     dispatcher = red_dispatcher_get_dispatcher(init_data->red_dispatcher);
@@ -11051,7 +11057,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     register_callbacks(dispatcher);
     worker->pending = init_data->pending;
     worker->cursor_visible = TRUE;
-    ASSERT(init_data->num_renderers > 0);
+    spice_assert(init_data->num_renderers > 0);
     worker->num_renderers = init_data->num_renderers;
     memcpy(worker->renderers, init_data->renderers, sizeof(worker->renderers));
     worker->renderer = RED_RENDERER_INVALID;
@@ -11093,7 +11099,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
                           init_data->memslot_id_bits,
                           init_data->internal_groupslot_id);
 
-    PANIC_ON(init_data->n_surfaces > NUM_SURFACES);
+    spice_warn_if(init_data->n_surfaces > NUM_SURFACES);
     worker->n_surfaces = init_data->n_surfaces;
 
     message = RED_WORKER_MESSAGE_READY;
@@ -11111,13 +11117,13 @@ void *red_worker_main(void *arg)
 {
     RedWorker worker;
 
-    red_printf("begin");
-    ASSERT(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW &&
+    spice_printerr("begin");
+    spice_assert(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW &&
            MAX_PIPE_SIZE > NARROW_CLIENT_ACK_WINDOW); //ensure wakeup by ack message
 
 #if  defined(RED_WORKER_STAT) || defined(COMPRESS_STAT)
     if (pthread_getcpuclockid(pthread_self(), &clock_id)) {
-        red_error("pthread_getcpuclockid failed");
+        spice_error("pthread_getcpuclockid failed");
     }
 #endif
 
@@ -11145,7 +11151,7 @@ void *red_worker_main(void *arg)
         worker.event_timeout = INF_EVENT_WAIT;
         if (num_events == -1) {
             if (errno != EINTR) {
-                red_error("poll failed, %s", strerror(errno));
+                spice_error("poll failed, %s", strerror(errno));
             }
         }
 
@@ -11181,7 +11187,7 @@ void *red_worker_main(void *arg)
         }
         red_push(&worker);
     }
-    red_printf("exit");
+    spice_printerr("exit");
     return 0;
 }
 
@@ -11260,7 +11266,7 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
         alpha = 1;
         break;
     default:
-        red_error("invalid bitmap format  %u", bitmap->format);
+        spice_error("invalid bitmap format  %u", bitmap->format);
     }
 
     if (!rgb) {
@@ -11282,7 +11288,7 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
 
     f = fopen(file_str, "wb");
     if (!f) {
-        red_error("Error creating bmp\n");
+        spice_error("Error creating bmp");
         return;
     }
 
diff --git a/server/red_worker.h b/server/red_worker.h
index 1f63d01..fd23ede 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -131,7 +131,7 @@ static inline void send_data(int fd, void *in_buf, int n)
             if (errno == EINTR) {
                 continue;
             }
-            red_error("%s", strerror(errno));
+            spice_error("%s", strerror(errno));
         }
         buf += now;
         n -= now;
@@ -152,7 +152,7 @@ static inline void receive_data(int fd, void *in_buf, int n)
             if (errno == EINTR) {
                 continue;
             }
-            red_error("%s", strerror(errno));
+            spice_error("%s", strerror(errno));
         }
         buf += now;
         n -= now;
diff --git a/server/reds.c b/server/reds.c
index cf493dd..27e7ea2 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -467,7 +467,7 @@ StatNodeRef stat_add_node(StatNodeRef parent, const char *name, int visible)
     StatNodeRef ref;
     SpiceStatNode *node;
 
-    ASSERT(name && strlen(name) > 0);
+    spice_assert(name && strlen(name) > 0);
     if (strlen(name) >= sizeof(node->name)) {
         return INVALID_STAT_REF;
     }
@@ -495,7 +495,7 @@ StatNodeRef stat_add_node(StatNodeRef parent, const char *name, int visible)
             break;
         }
     }
-    ASSERT(!(node->flags & SPICE_STAT_NODE_FLAG_ENABLED));
+    spice_assert(!(node->flags & SPICE_STAT_NODE_FLAG_ENABLED));
     node->value = 0;
     node->flags = SPICE_STAT_NODE_FLAG_ENABLED | (visible ? SPICE_STAT_NODE_FLAG_VISIBLE : 0);
     strncpy(node->name, name, sizeof(node->name));
@@ -552,7 +552,7 @@ void reds_update_stat_value(uint32_t value)
 
 void reds_register_channel(RedChannel *channel)
 {
-    ASSERT(reds);
+    spice_assert(reds);
     ring_add(&reds->channels, &channel->link);
     reds->num_of_channels++;
 }
@@ -563,7 +563,7 @@ void reds_unregister_channel(RedChannel *channel)
         ring_remove(&channel->link);
         reds->num_of_channels--;
     } else {
-        red_printf("not found");
+        spice_printerr("not found");
     }
 }
 
@@ -585,7 +585,7 @@ static void reds_mig_cleanup(void)
     if (reds->mig_inprogress) {
         if (reds->mig_wait_connect) {
             SpiceMigrateInterface *sif;
-            ASSERT(migration_interface);
+            spice_assert(migration_interface);
             sif = SPICE_CONTAINEROF(migration_interface->base.sif, SpiceMigrateInterface, base);
             sif->migrate_connect_complete(migration_interface);
         }
@@ -644,7 +644,7 @@ void reds_client_disconnect(RedClient *client)
         return;
     }
 
-    red_printf("");
+    spice_printerr("");
     /* disconnecting is set to prevent recursion because of the following:
      * main_channel_client_on_disconnect->
      *  reds_client_disconnect->red_client_destroy->main_channel...
@@ -684,7 +684,7 @@ static void reds_disconnect(void)
 {
     RingItem *link, *next;
 
-    red_printf("");
+    spice_printerr("");
     RING_FOREACH_SAFE(link, next, &reds->clients) {
         reds_client_disconnect(SPICE_CONTAINEROF(link, RedClient, link));
     }
@@ -759,7 +759,7 @@ static void reds_agent_remove(void)
 static void reds_push_tokens(void)
 {
     reds->agent_state.num_client_tokens += reds->agent_state.num_tokens;
-    ASSERT(reds->agent_state.num_client_tokens <= REDS_AGENT_WINDOW_SIZE);
+    spice_assert(reds->agent_state.num_client_tokens <= REDS_AGENT_WINDOW_SIZE);
     main_channel_push_tokens(reds->main_channel, reds->agent_state.num_tokens);
     reds->agent_state.num_tokens = 0;
 }
@@ -865,7 +865,7 @@ static void dispatch_vdi_port_data(int port, VDIReadBuf *buf)
         break;
     default:
         ring_add(&state->read_bufs, &buf->link);
-        red_printf("invalid port");
+        spice_printerr("invalid port");
         reds_agent_remove();
     }
 }
@@ -1019,7 +1019,7 @@ int reds_num_of_clients(void)
 
 SPICE_GNUC_VISIBLE int spice_server_get_num_clients(SpiceServer *s)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     return reds_num_of_clients();
 }
 
@@ -1055,7 +1055,7 @@ void reds_fill_channels(SpiceMsgChannels *channels_info)
 
     channels_info->num_of_channels = used_channels;
     if (used_channels != reds->num_of_channels) {
-        red_printf("sent %d out of %d", used_channels, reds->num_of_channels);
+        spice_printerr("sent %d out of %d", used_channels, reds->num_of_channels);
     }
 }
 
@@ -1076,7 +1076,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
     int res;
 
     if (!reds->agent_state.num_client_tokens) {
-        red_printf("token violation");
+        spice_printerr("token violation");
         reds_disconnect();
         return;
     }
@@ -1096,7 +1096,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
     }
 
     if (!(ring_item = ring_get_head(&reds->agent_state.external_bufs))) {
-        red_printf("no agent free bufs");
+        spice_printerr("no agent free bufs");
         reds_disconnect();
         return;
     }
@@ -1124,14 +1124,14 @@ void reds_on_main_mouse_mode_request(void *message, size_t size)
         if (reds->is_client_mouse_allowed) {
             reds_set_mouse_mode(SPICE_MOUSE_MODE_CLIENT);
         } else {
-            red_printf("client mouse is disabled");
+            spice_printerr("client mouse is disabled");
         }
         break;
     case SPICE_MOUSE_MODE_SERVER:
         reds_set_mouse_mode(SPICE_MOUSE_MODE_SERVER);
         break;
     default:
-        red_printf("unsupported mouse mode");
+        spice_printerr("unsupported mouse mode");
     }
 }
 
@@ -1211,7 +1211,7 @@ static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8
     switch (state->read_state) {
     case VDI_PORT_READ_STATE_READ_HADER:
         if (data->read_buf_len) {
-            red_printf("unexpected receive buf");
+            spice_printerr("unexpected receive buf");
             reds_disconnect();
             return FALSE;
         }
@@ -1219,13 +1219,13 @@ static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8
         break;
     case VDI_PORT_READ_STATE_GET_BUFF:
         if (state->message_recive_len > state->vdi_chunk_header.size) {
-            red_printf("invalid message receive len");
+            spice_printerr("invalid message receive len");
             reds_disconnect();
             return FALSE;
         }
 
         if (data->read_buf_len) {
-            red_printf("unexpected receive buf");
+            spice_printerr("unexpected receive buf");
             reds_disconnect();
             return FALSE;
         }
@@ -1235,20 +1235,20 @@ static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8
         uint32_t n;
 
         if (!data->read_buf_len) {
-            red_printf("read state and read_buf_len == 0");
+            spice_printerr("read state and read_buf_len == 0");
             reds_disconnect();
             return FALSE;
         }
 
         if (state->message_recive_len > state->vdi_chunk_header.size) {
-            red_printf("invalid message receive len");
+            spice_printerr("invalid message receive len");
             reds_disconnect();
             return FALSE;
         }
 
 
         if (!(ring_item = ring_get_head(&state->read_bufs))) {
-            red_printf("get read buf failed");
+            spice_printerr("get read buf failed");
             reds_disconnect();
             return FALSE;
         }
@@ -1258,7 +1258,7 @@ static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8
         buff->len = data->read_buf_len;
         n = buff->len - state->recive_len;
         if (buff->len > SPICE_AGENT_MAX_DATA_SIZE || n > SPICE_AGENT_MAX_DATA_SIZE) {
-            red_printf("bad read position");
+            spice_printerr("bad read position");
             reds_disconnect();
             return FALSE;
         }
@@ -1268,7 +1268,7 @@ static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8
         break;
     }
     default:
-        red_printf("invalid read state");
+        spice_printerr("invalid read state");
         reds_disconnect();
         return FALSE;
     }
@@ -1296,14 +1296,14 @@ static int reds_main_channel_restore_vdi_wqueue(MainMigrateData *data, uint8_t *
     inf_end = inf + data->write_queue_size;
     pos = (uint8_t *)inf_end;
     if (pos > end) {
-        red_printf("access violation");
+        spice_printerr("access violation");
         reds_disconnect();
         return FALSE;
     }
 
     for (; inf < inf_end; inf++) {
         if (pos + inf->len > end) {
-            red_printf("access violation");
+            spice_printerr("access violation");
             reds_disconnect();
             return FALSE;
         }
@@ -1311,7 +1311,7 @@ static int reds_main_channel_restore_vdi_wqueue(MainMigrateData *data, uint8_t *
             VDInternalBuf *buf;
 
             if (inf->len > sizeof(*buf) - SPICE_OFFSETOF(VDInternalBuf, header)) {
-                red_printf("bad buffer len");
+                spice_printerr("bad buffer len");
                 reds_disconnect();
                 return FALSE;
             }
@@ -1327,12 +1327,12 @@ static int reds_main_channel_restore_vdi_wqueue(MainMigrateData *data, uint8_t *
 
             state->num_tokens--;
             if (inf->len > sizeof(*buf) - SPICE_OFFSETOF(VDAgentExtBuf, buf)) {
-                red_printf("bad buffer len");
+                spice_printerr("bad buffer len");
                 reds_disconnect();
                 return FALSE;
             }
             if (!(ring_item = ring_get_head(&reds->agent_state.external_bufs))) {
-                red_printf("no external buff");
+                spice_printerr("no external buff");
                 reds_disconnect();
                 return FALSE;
             }
@@ -1343,7 +1343,7 @@ static int reds_main_channel_restore_vdi_wqueue(MainMigrateData *data, uint8_t *
             buf->base.write_len = inf->len;
             ring_add(&reds->agent_state.write_queue, &buf->base.link);
         } else {
-            red_printf("invalid data");
+            spice_printerr("invalid data");
             reds_disconnect();
             return FALSE;
         }
@@ -1358,13 +1358,13 @@ void reds_on_main_receive_migrate_data(MainMigrateData *data, uint8_t *end)
     uint8_t *pos;
 
     if (data->version != MAIN_CHANNEL_MIG_DATA_VERSION) {
-        red_printf("version mismatch");
+        spice_printerr("version mismatch");
         reds_disconnect();
         return;
     }
 
     state->num_client_tokens = data->num_client_tokens;
-    ASSERT(state->num_client_tokens + data->write_queue_size <= REDS_AGENT_WINDOW_SIZE +
+    spice_assert(state->num_client_tokens + data->write_queue_size <= REDS_AGENT_WINDOW_SIZE +
                                                                 REDS_NUM_INTERNAL_AGENT_MESSAGES);
     state->num_tokens = REDS_AGENT_WINDOW_SIZE - state->num_client_tokens;
 
@@ -1395,7 +1395,7 @@ void reds_on_main_receive_migrate_data(MainMigrateData *data, uint8_t *end)
     }
 
     reds_main_channel_restore_vdi_wqueue(data, pos, end);
-    ASSERT(state->num_client_tokens + state->num_tokens == REDS_AGENT_WINDOW_SIZE);
+    spice_assert(state->num_client_tokens + state->num_tokens == REDS_AGENT_WINDOW_SIZE);
 
     while (write_to_vdi_port() || read_from_vdi_port());
 }
@@ -1447,8 +1447,8 @@ static int reds_send_link_ack(RedLinkInfo *link)
 
     channel = reds_find_channel(link->link_mess->channel_type, 0);
     if (!channel) {
-        ASSERT(link->link_mess->channel_type == SPICE_CHANNEL_MAIN);
-        ASSERT(reds->main_channel);
+        spice_assert(link->link_mess->channel_type == SPICE_CHANNEL_MAIN);
+        spice_assert(reds->main_channel);
         channel = &reds->main_channel->base;
     }
 
@@ -1461,12 +1461,12 @@ static int reds_send_link_ack(RedLinkInfo *link)
     ack.caps_offset = sizeof(SpiceLinkReply);
 
     if (!(link->tiTicketing.rsa = RSA_new())) {
-        red_printf("RSA nes failed");
+        spice_printerr("RSA nes failed");
         return FALSE;
     }
 
     if (!(bio = BIO_new(BIO_s_mem()))) {
-        red_printf("BIO new failed");
+        spice_printerr("BIO new failed");
         return FALSE;
     }
 
@@ -1511,7 +1511,7 @@ static int reds_send_link_error(RedLinkInfo *link, uint32_t error)
 
 static void reds_show_new_channel(RedLinkInfo *link, int connection_id)
 {
-    red_printf("channel %d:%d, connected successfully, over %s link",
+    spice_printerr("channel %d:%d, connected successfully, over %s link",
                link->link_mess->channel_type,
                link->link_mess->channel_id,
                link->stream->ssl == NULL ? "Non Secure" : "Secure");
@@ -1532,7 +1532,7 @@ static void reds_send_link_result(RedLinkInfo *link, uint32_t error)
 
 int reds_expects_link_id(uint32_t connection_id)
 {
-    red_printf("TODO: keep a list of connection_id's from migration, compare to them");
+    spice_printerr("TODO: keep a list of connection_id's from migration, compare to them");
     return 1;
 }
 
@@ -1540,8 +1540,8 @@ static void reds_mig_target_client_add(RedClient *client)
 {
     RedsMigTargetClient *mig_client;
 
-    ASSERT(reds);
-    red_printf("");
+    spice_assert(reds);
+    spice_printerr("");
     mig_client = spice_malloc0(sizeof(RedsMigTargetClient));
     mig_client->client = client;
     ring_init(&mig_client->pending_links);
@@ -1571,8 +1571,8 @@ static void reds_mig_target_client_add_pending_link(RedsMigTargetClient *client,
 {
     RedsMigPendingLink *mig_link;
 
-    ASSERT(reds);
-    ASSERT(client);
+    spice_assert(reds);
+    spice_assert(client);
     mig_link = spice_malloc0(sizeof(RedsMigPendingLink));
     mig_link->link_msg = link_msg;
     mig_link->stream = stream;
@@ -1617,8 +1617,8 @@ static void reds_handle_main_link(RedLinkInfo *link)
     MainChannelClient *mcc;
     int mig_target = FALSE;
 
-    red_printf("");
-    ASSERT(reds->main_channel);
+    spice_printerr("");
+    spice_assert(reds->main_channel);
 
     link_mess = link->link_mess;
     if (!reds->allow_multiple_clients) {
@@ -1657,7 +1657,7 @@ static void reds_handle_main_link(RedLinkInfo *link)
                             link_mess->num_common_caps,
                             link_mess->num_common_caps ? caps : NULL, link_mess->num_channel_caps,
                             link_mess->num_channel_caps ? caps + link_mess->num_common_caps : NULL);
-    red_printf("NEW Client %p mcc %p connect-id %d", client, mcc, connection_id);
+    spice_printerr("NEW Client %p mcc %p connect-id %d", client, mcc, connection_id);
     free(link_mess);
     red_client_set_main(client, mcc);
 
@@ -1713,7 +1713,7 @@ static void openssl_init(RedLinkInfo *link)
     link->tiTicketing.bn = BN_new();
 
     if (!link->tiTicketing.bn) {
-        red_error("OpenSSL BIGNUMS alloc failed");
+        spice_error("OpenSSL BIGNUMS alloc failed");
     }
 
     BN_set_word(link->tiTicketing.bn, f4);
@@ -1725,9 +1725,9 @@ static void reds_channel_do_link(RedChannel *channel, RedClient *client,
 {
     uint32_t *caps;
 
-    ASSERT(channel);
-    ASSERT(link_msg);
-    ASSERT(stream);
+    spice_assert(channel);
+    spice_assert(link_msg);
+    spice_assert(stream);
 
     if (link_msg->channel_type == SPICE_CHANNEL_INPUTS && !stream->ssl) {
         char *mess = "keyboard channel is insecure";
@@ -1751,11 +1751,11 @@ void reds_on_client_migrate_complete(RedClient *client)
     MainChannelClient *mcc;
     RingItem *item;
 
-    red_printf("%p", client);
+    spice_printerr("%p", client);
     mcc = red_client_get_main(client);
     mig_client = reds_mig_target_client_find(client);
     if (!mig_client) {
-        red_printf("Error: mig target client was not found");
+        spice_printerr("Error: mig target client was not found");
         return;
     }
 
@@ -1773,7 +1773,7 @@ void reds_on_client_migrate_complete(RedClient *client)
         channel = reds_find_channel(mig_link->link_msg->channel_type,
                                     mig_link->link_msg->channel_id);
         if (!channel) {
-            red_printf("warning: client %p channel (%d, %d) (type, id) wasn't found",
+            spice_printerr("warning: client %p channel (%d, %d) (type, id) wasn't found",
                        client,
                        mig_link->link_msg->channel_type,
                        mig_link->link_msg->channel_id);
@@ -1824,10 +1824,10 @@ static void reds_handle_other_links(RedLinkInfo *link)
 
     mig_client = reds_mig_target_client_find(client);
     if (red_client_during_migrate_at_target(client)) {
-        ASSERT(mig_client);
+        spice_assert(mig_client);
         reds_mig_target_client_add_pending_link(mig_client, link_mess, link->stream);
     } else {
-        ASSERT(!mig_client);
+        spice_assert(!mig_client);
         reds_channel_do_link(channel, client, link_mess, link->stream);
         free(link_mess);
     }
@@ -1862,7 +1862,7 @@ static void reds_handle_ticket(void *opaque)
 
         if (strlen(taTicket.password) == 0) {
             reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED);
-            red_printf("Ticketing is enabled, but no password is set. "
+            spice_printerr("Ticketing is enabled, but no password is set. "
                        "please set a ticket first");
             reds_link_free(link);
             return;
@@ -1870,9 +1870,9 @@ static void reds_handle_ticket(void *opaque)
 
         if (expired || strncmp(password, taTicket.password, SPICE_MAX_PASSWORD_LENGTH) != 0) {
             if (expired) {
-                red_printf("Ticket has expired");
+                spice_printerr("Ticket has expired");
             } else {
-                red_printf("Invalid password");
+                spice_printerr("Invalid password");
             }
             reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED);
             reds_link_free(link);
@@ -1913,7 +1913,7 @@ static ssize_t reds_stream_sasl_write(RedsStream *s, const void *buf, size_t nby
                           (const char **)&s->sasl.encoded,
                           &s->sasl.encodedLength);
         if (err != SASL_OK) {
-            red_printf("sasl_encode error: %d", err);
+            spice_printerr("sasl_encode error: %d", err);
             return -1;
         }
 
@@ -1922,7 +1922,7 @@ static ssize_t reds_stream_sasl_write(RedsStream *s, const void *buf, size_t nby
         }
 
         if (!s->sasl.encoded) {
-            red_printf("sasl_encode didn't return a buffer!");
+            spice_printerr("sasl_encode didn't return a buffer!");
             return 0;
         }
 
@@ -1974,7 +1974,7 @@ static ssize_t reds_stream_sasl_read(RedsStream *s, uint8_t *buf, size_t nbyte)
                       (char *)encoded, n,
                       &decoded, &decodedlen);
     if (err != SASL_OK) {
-        red_printf("sasl_decode error: %d", err);
+        spice_printerr("sasl_decode error: %d", err);
         return -1;
     }
 
@@ -1997,7 +1997,7 @@ static void async_read_handler(int fd, int event, void *data)
     for (;;) {
         int n = obj->end - obj->now;
 
-        ASSERT(n > 0);
+        spice_assert(n > 0);
         n = reds_stream_read(obj->stream, obj->now, n);
         if (n <= 0) {
             if (n < 0) {
@@ -2056,7 +2056,7 @@ static char *addr_to_string(const char *format,
                            host, sizeof(host),
                            serv, sizeof(serv),
                            NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
-        red_printf("Cannot resolve address %d: %s",
+        spice_printerr("Cannot resolve address %d: %s",
                    err, gai_strerror(err));
         return NULL;
     }
@@ -2087,7 +2087,7 @@ static int auth_sasl_check_ssf(RedsSASL *sasl, int *runSSF)
     }
 
     ssf = *(const int *)val;
-    red_printf("negotiated an SSF of %d", ssf);
+    spice_printerr("negotiated an SSF of %d", ssf);
     if (ssf < 56) {
         return 0; /* 56 is good for Kerberos */
     }
@@ -2134,7 +2134,7 @@ static void reds_handle_auth_sasl_step(void *opaque)
         datalen--; /* Don't count NULL byte when passing to _start() */
     }
 
-    red_printf("Step using SASL Data %p (%d bytes)",
+    spice_printerr("Step using SASL Data %p (%d bytes)",
                clientdata, datalen);
     err = sasl_server_step(sasl->conn,
                            clientdata,
@@ -2143,18 +2143,18 @@ static void reds_handle_auth_sasl_step(void *opaque)
                            &serveroutlen);
     if (err != SASL_OK &&
         err != SASL_CONTINUE) {
-        red_printf("sasl step failed %d (%s)",
+        spice_printerr("sasl step failed %d (%s)",
                    err, sasl_errdetail(sasl->conn));
         goto authabort;
     }
 
     if (serveroutlen > SASL_DATA_MAX_LEN) {
-        red_printf("sasl step reply data too long %d",
+        spice_printerr("sasl step reply data too long %d",
                    serveroutlen);
         goto authabort;
     }
 
-    red_printf("SASL return data %d bytes, %p", serveroutlen, serverout);
+    spice_printerr("SASL return data %d bytes, %p", serveroutlen, serverout);
 
     if (serveroutlen) {
         serveroutlen += 1;
@@ -2168,7 +2168,7 @@ static void reds_handle_auth_sasl_step(void *opaque)
     sync_write_u8(link->stream, err == SASL_CONTINUE ? 0 : 1);
 
     if (err == SASL_CONTINUE) {
-        red_printf("%s", "Authentication must continue (step)");
+        spice_printerr("%s", "Authentication must continue (step)");
         /* Wait for step length */
         obj->now = (uint8_t *)&sasl->len;
         obj->end = obj->now + sizeof(uint32_t);
@@ -2178,11 +2178,11 @@ static void reds_handle_auth_sasl_step(void *opaque)
         int ssf;
 
         if (auth_sasl_check_ssf(sasl, &ssf) == 0) {
-            red_printf("Authentication rejected for weak SSF");
+            spice_printerr("Authentication rejected for weak SSF");
             goto authreject;
         }
 
-        red_printf("Authentication successful");
+        spice_printerr("Authentication successful");
         sync_write_u32(link->stream, SPICE_LINK_ERR_OK); /* Accept auth */
 
         /*
@@ -2212,9 +2212,9 @@ static void reds_handle_auth_sasl_steplen(void *opaque)
     AsyncRead *obj = &link->asyc_read;
     RedsSASL *sasl = &link->stream->sasl;
 
-    red_printf("Got steplen %d", sasl->len);
+    spice_printerr("Got steplen %d", sasl->len);
     if (sasl->len > SASL_DATA_MAX_LEN) {
-        red_printf("Too much SASL data %d", sasl->len);
+        spice_printerr("Too much SASL data %d", sasl->len);
         reds_link_free(link);
         return;
     }
@@ -2264,7 +2264,7 @@ static void reds_handle_auth_sasl_start(void *opaque)
         datalen--; /* Don't count NULL byte when passing to _start() */
     }
 
-    red_printf("Start SASL auth with mechanism %s. Data %p (%d bytes)",
+    spice_printerr("Start SASL auth with mechanism %s. Data %p (%d bytes)",
               sasl->mechlist, clientdata, datalen);
     err = sasl_server_start(sasl->conn,
                             sasl->mechlist,
@@ -2274,18 +2274,18 @@ static void reds_handle_auth_sasl_start(void *opaque)
                             &serveroutlen);
     if (err != SASL_OK &&
         err != SASL_CONTINUE) {
-        red_printf("sasl start failed %d (%s)",
+        spice_printerr("sasl start failed %d (%s)",
                    err, sasl_errdetail(sasl->conn));
         goto authabort;
     }
 
     if (serveroutlen > SASL_DATA_MAX_LEN) {
-        red_printf("sasl start reply data too long %d",
+        spice_printerr("sasl start reply data too long %d",
                    serveroutlen);
         goto authabort;
     }
 
-    red_printf("SASL return data %d bytes, %p", serveroutlen, serverout);
+    spice_printerr("SASL return data %d bytes, %p", serveroutlen, serverout);
 
     if (serveroutlen) {
         serveroutlen += 1;
@@ -2299,7 +2299,7 @@ static void reds_handle_auth_sasl_start(void *opaque)
     sync_write_u8(link->stream, err == SASL_CONTINUE ? 0 : 1);
 
     if (err == SASL_CONTINUE) {
-        red_printf("%s", "Authentication must continue (start)");
+        spice_printerr("%s", "Authentication must continue (start)");
         /* Wait for step length */
         obj->now = (uint8_t *)&sasl->len;
         obj->end = obj->now + sizeof(uint32_t);
@@ -2309,11 +2309,11 @@ static void reds_handle_auth_sasl_start(void *opaque)
         int ssf;
 
         if (auth_sasl_check_ssf(sasl, &ssf) == 0) {
-            red_printf("Authentication rejected for weak SSF");
+            spice_printerr("Authentication rejected for weak SSF");
             goto authreject;
         }
 
-        red_printf("Authentication successful");
+        spice_printerr("Authentication successful");
         sync_write_u32(link->stream, SPICE_LINK_ERR_OK); /* Accept auth */
 
         /*
@@ -2343,9 +2343,9 @@ static void reds_handle_auth_startlen(void *opaque)
     AsyncRead *obj = &link->asyc_read;
     RedsSASL *sasl = &link->stream->sasl;
 
-    red_printf("Got client start len %d", sasl->len);
+    spice_printerr("Got client start len %d", sasl->len);
     if (sasl->len > SASL_DATA_MAX_LEN) {
-        red_printf("Too much SASL data %d", sasl->len);
+        spice_printerr("Too much SASL data %d", sasl->len);
         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
         reds_link_free(link);
         return;
@@ -2370,24 +2370,24 @@ static void reds_handle_auth_mechname(void *opaque)
     RedsSASL *sasl = &link->stream->sasl;
 
     sasl->mechname[sasl->len] = '\0';
-    red_printf("Got client mechname '%s' check against '%s'",
+    spice_printerr("Got client mechname '%s' check against '%s'",
                sasl->mechname, sasl->mechlist);
 
     if (strncmp(sasl->mechlist, sasl->mechname, sasl->len) == 0) {
         if (sasl->mechlist[sasl->len] != '\0' &&
             sasl->mechlist[sasl->len] != ',') {
-            red_printf("One %d", sasl->mechlist[sasl->len]);
+            spice_printerr("One %d", sasl->mechlist[sasl->len]);
             reds_link_free(link);
             return;
         }
     } else {
         char *offset = strstr(sasl->mechlist, sasl->mechname);
-        red_printf("Two %p", offset);
+        spice_printerr("Two %p", offset);
         if (!offset) {
             reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
             return;
         }
-        red_printf("Two '%s'", offset);
+        spice_printerr("Two '%s'", offset);
         if (offset[-1] != ',' ||
             (offset[sasl->len] != '\0'&&
              offset[sasl->len] != ',')) {
@@ -2399,7 +2399,7 @@ static void reds_handle_auth_mechname(void *opaque)
     free(sasl->mechlist);
     sasl->mechlist = spice_strdup(sasl->mechname);
 
-    red_printf("Validated mechname '%s'", sasl->mechname);
+    spice_printerr("Validated mechname '%s'", sasl->mechname);
 
     obj->now = (uint8_t *)&sasl->len;
     obj->end = obj->now + sizeof(uint32_t);
@@ -2416,14 +2416,14 @@ static void reds_handle_auth_mechlen(void *opaque)
     RedsSASL *sasl = &link->stream->sasl;
 
     if (sasl->len < 1 || sasl->len > 100) {
-        red_printf("Got bad client mechname len %d", sasl->len);
+        spice_printerr("Got bad client mechname len %d", sasl->len);
         reds_link_free(link);
         return;
     }
 
     sasl->mechname = spice_malloc(sasl->len + 1);
 
-    red_printf("Wait for client mechname");
+    spice_printerr("Wait for client mechname");
     obj->now = (uint8_t *)sasl->mechname;
     obj->end = obj->now + sasl->len;
     obj->done = reds_handle_auth_mechname;
@@ -2465,7 +2465,7 @@ static void reds_start_auth_sasl(RedLinkInfo *link)
     localAddr = remoteAddr = NULL;
 
     if (err != SASL_OK) {
-        red_printf("sasl context setup failed %d (%s)",
+        spice_printerr("sasl context setup failed %d (%s)",
                    err, sasl_errstring(err, NULL, NULL));
         sasl->conn = NULL;
         goto error;
@@ -2478,7 +2478,7 @@ static void reds_start_auth_sasl(RedLinkInfo *link)
         ssf = SSL_get_cipher_bits(link->stream->ssl, NULL);
         err = sasl_setprop(sasl->conn, SASL_SSF_EXTERNAL, &ssf);
         if (err != SASL_OK) {
-            red_printf("cannot set SASL external SSF %d (%s)",
+            spice_printerr("cannot set SASL external SSF %d (%s)",
                        err, sasl_errstring(err, NULL, NULL));
             goto error_dispose;
         }
@@ -2506,7 +2506,7 @@ static void reds_start_auth_sasl(RedLinkInfo *link)
 
     err = sasl_setprop(sasl->conn, SASL_SEC_PROPS, &secprops);
     if (err != SASL_OK) {
-        red_printf("cannot set SASL security props %d (%s)",
+        spice_printerr("cannot set SASL security props %d (%s)",
                    err, sasl_errstring(err, NULL, NULL));
         goto error_dispose;
     }
@@ -2520,23 +2520,23 @@ static void reds_start_auth_sasl(RedLinkInfo *link)
                         NULL,
                         NULL);
     if (err != SASL_OK || mechlist == NULL) {
-        red_printf("cannot list SASL mechanisms %d (%s)",
+        spice_printerr("cannot list SASL mechanisms %d (%s)",
                    err, sasl_errdetail(sasl->conn));
         goto error_dispose;
     }
 
-    red_printf("Available mechanisms for client: '%s'", mechlist);
+    spice_printerr("Available mechanisms for client: '%s'", mechlist);
 
     sasl->mechlist = spice_strdup(mechlist);
 
     mechlistlen = strlen(mechlist);
     if (!sync_write(link->stream, &mechlistlen, sizeof(uint32_t))
         || !sync_write(link->stream, sasl->mechlist, mechlistlen)) {
-        red_printf("SASL mechanisms write error");
+        spice_printerr("SASL mechanisms write error");
         goto error;
     }
 
-    red_printf("Wait for client mechname length");
+    spice_printerr("Wait for client mechname length");
     obj->now = (uint8_t *)&sasl->len;
     obj->end = obj->now + sizeof(uint32_t);
     obj->done = reds_handle_auth_mechlen;
@@ -2557,7 +2557,7 @@ static void reds_handle_auth_mechanism(void *opaque)
 {
     RedLinkInfo *link = (RedLinkInfo *)opaque;
 
-    red_printf("Auth method: %d", link->auth_mechanism.auth_mechanism);
+    spice_printerr("Auth method: %d", link->auth_mechanism.auth_mechanism);
 
     if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SPICE
         && !sasl_enabled
@@ -2565,13 +2565,13 @@ static void reds_handle_auth_mechanism(void *opaque)
         reds_get_spice_ticket(link);
 #if HAVE_SASL
     } else if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SASL) {
-        red_printf("Starting SASL");
+        spice_printerr("Starting SASL");
         reds_start_auth_sasl(link);
 #endif
     } else {
-        red_printf("Unknown auth method, disconnecting");
+        spice_printerr("Unknown auth method, disconnecting");
         if (sasl_enabled) {
-            red_printf("Your client doesn't handle SASL?");
+            spice_printerr("Your client doesn't handle SASL?");
         }
         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
         reds_link_free(link);
@@ -2608,10 +2608,10 @@ static void reds_handle_read_link_done(void *opaque)
 
     if (!reds_security_check(link)) {
         if (link->stream->ssl) {
-            red_printf("spice channels %d should not be encrypted", link_mess->channel_type);
+            spice_printerr("spice channels %d should not be encrypted", link_mess->channel_type);
             reds_send_link_error(link, SPICE_LINK_ERR_NEED_UNSECURED);
         } else {
-            red_printf("spice channels %d should be encrypted", link_mess->channel_type);
+            spice_printerr("spice channels %d should be encrypted", link_mess->channel_type);
             reds_send_link_error(link, SPICE_LINK_ERR_NEED_SECURED);
         }
         reds_link_free(link);
@@ -2625,11 +2625,11 @@ static void reds_handle_read_link_done(void *opaque)
 
     if (!auth_selection) {
         if (sasl_enabled && !link->skip_auth) {
-            red_printf("SASL enabled, but peer supports only spice authentication");
+            spice_printerr("SASL enabled, but peer supports only spice authentication");
             reds_send_link_error(link, SPICE_LINK_ERR_VERSION_MISMATCH);
             return;
         }
-        red_printf("Peer doesn't support AUTH selection");
+        spice_printerr("Peer doesn't support AUTH selection");
         reds_get_spice_ticket(link);
     } else {
         obj->now = (uint8_t *)&link->auth_mechanism;
@@ -2647,7 +2647,7 @@ static void reds_handle_link_error(void *opaque, int err)
     case EPIPE:
         break;
     default:
-        red_printf("%s", strerror(errno));
+        spice_printerr("%s", strerror(errno));
         break;
     }
     reds_link_free(link);
@@ -2670,7 +2670,7 @@ static void reds_handle_read_header_done(void *opaque)
             reds_send_link_error(link, SPICE_LINK_ERR_VERSION_MISMATCH);
         }
 
-        red_printf("version mismatch");
+        spice_printerr("version mismatch");
         reds_link_free(link);
         return;
     }
@@ -2679,7 +2679,7 @@ static void reds_handle_read_header_done(void *opaque)
 
     if (header->size < sizeof(SpiceLinkMess)) {
         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
-        red_printf("bad size %u", header->size);
+        spice_printerr("bad size %u", header->size);
         reds_link_free(link);
         return;
     }
@@ -2712,7 +2712,7 @@ static void reds_handle_ssl_accept(int fd, int event, void *data)
     if ((return_code = SSL_accept(link->stream->ssl)) != 1) {
         int ssl_error = SSL_get_error(link->stream->ssl, return_code);
         if (ssl_error != SSL_ERROR_WANT_READ && ssl_error != SSL_ERROR_WANT_WRITE) {
-            red_printf("SSL_accept failed, error=%d", ssl_error);
+            spice_printerr("SSL_accept failed, error=%d", ssl_error);
             reds_link_free(link);
         } else {
             if (ssl_error == SSL_ERROR_WANT_READ) {
@@ -2735,18 +2735,18 @@ static RedLinkInfo *reds_init_client_connection(int socket)
     int flags;
 
     if ((flags = fcntl(socket, F_GETFL)) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         goto error;
     }
 
     if (fcntl(socket, F_SETFL, flags | O_NONBLOCK) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         goto error;
     }
 
     if (setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
 
@@ -2796,13 +2796,13 @@ static RedLinkInfo *reds_init_client_ssl_connection(int socket)
 
     // Handle SSL handshaking
     if (!(sbio = BIO_new_socket(link->stream->socket, BIO_NOCLOSE))) {
-        red_printf("could not allocate ssl bio socket");
+        spice_printerr("could not allocate ssl bio socket");
         goto error;
     }
 
     link->stream->ssl = SSL_new(reds->ctx);
     if (!link->stream->ssl) {
-        red_printf("could not allocate ssl context");
+        spice_printerr("could not allocate ssl context");
         BIO_free(sbio);
         goto error;
     }
@@ -2830,7 +2830,7 @@ static RedLinkInfo *reds_init_client_ssl_connection(int socket)
     }
 
     ERR_print_errors_fp(stderr);
-    red_printf("SSL_accept failed, error=%d", ssl_error);
+    spice_printerr("SSL_accept failed, error=%d", ssl_error);
     SSL_free(link->stream->ssl);
 
 error:
@@ -2846,7 +2846,7 @@ static void reds_accept_ssl_connection(int fd, int event, void *data)
     int socket;
 
     if ((socket = accept(reds->secure_listen_socket, NULL, 0)) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         return;
     }
 
@@ -2862,7 +2862,7 @@ static void reds_accept(int fd, int event, void *data)
     int socket;
 
     if ((socket = accept(reds->listen_socket, NULL, 0)) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         return;
     }
 
@@ -2876,9 +2876,9 @@ SPICE_GNUC_VISIBLE int spice_server_add_client(SpiceServer *s, int socket, int s
     RedLinkInfo *link;
     RedsStream *stream;
 
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (!(link = reds_init_client_connection(socket))) {
-        red_printf("accept failed");
+        spice_printerr("accept failed");
         return -1;
     }
 
@@ -2898,7 +2898,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_ssl_client(SpiceServer *s, int socket, i
 {
     RedLinkInfo *link;
 
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (!(link = reds_init_client_ssl_connection(socket))) {
         return -1;
     }
@@ -2925,7 +2925,7 @@ static int reds_init_socket(const char *addr, int portnr, int family)
     snprintf(port, sizeof(port), "%d", portnr);
     rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res);
     if (rc != 0) {
-        red_error("getaddrinfo(%s,%s): %s", addr, port,
+        spice_error("getaddrinfo(%s,%s): %s", addr, port,
                   gai_strerror(rc));
     }
 
@@ -2951,7 +2951,7 @@ static int reds_init_socket(const char *addr, int portnr, int family)
         }
         close(slisten);
     }
-    red_printf("%s: binding socket to %s:%d failed", __FUNCTION__,
+    spice_printerr("%s: binding socket to %s:%d failed", __FUNCTION__,
                addr, portnr);
     freeaddrinfo(res);
     return -1;
@@ -2959,7 +2959,7 @@ static int reds_init_socket(const char *addr, int portnr, int family)
 listen:
     freeaddrinfo(res);
     if (listen(slisten,1) != 0) {
-        red_error("%s: listen: %s", __FUNCTION__, strerror(errno));
+        spice_error("listen: %s", strerror(errno));
         close(slisten);
         return -1;
     }
@@ -2977,7 +2977,7 @@ static int reds_init_net(void)
                                              SPICE_WATCH_EVENT_READ,
                                              reds_accept, NULL);
         if (reds->listen_watch == NULL) {
-            red_error("set fd handle failed");
+            spice_error("set fd handle failed");
         }
     }
 
@@ -2991,7 +2991,7 @@ static int reds_init_net(void)
                                                     SPICE_WATCH_EVENT_READ,
                                                     reds_accept_ssl_connection, NULL);
         if (reds->secure_listen_watch == NULL) {
-            red_error("set fd handle failed");
+            spice_error("set fd handle failed");
         }
     }
 
@@ -3001,7 +3001,7 @@ static int reds_init_net(void)
                                              SPICE_WATCH_EVENT_READ,
                                              reds_accept, NULL);
         if (reds->listen_watch == NULL) {
-            red_error("set fd handle failed");
+            spice_error("set fd handle failed");
         }
     }
     return 0;
@@ -3013,18 +3013,18 @@ static void load_dh_params(SSL_CTX *ctx, char *file)
     BIO *bio;
 
     if ((bio = BIO_new_file(file, "r")) == NULL) {
-        red_error("Could not open DH file");
+        spice_error("Could not open DH file");
     }
 
     ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
     if (ret == 0) {
-        red_error("Could not read DH params");
+        spice_error("Could not read DH params");
     }
 
     BIO_free(bio);
 
     if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) {
-        red_error("Could not set DH params");
+        spice_error("Could not set DH params");
     }
 }
 
@@ -3092,7 +3092,7 @@ static void reds_init_ssl(void)
     ssl_method = TLSv1_method();
     reds->ctx = SSL_CTX_new(ssl_method);
     if (!reds->ctx) {
-        red_error("Could not allocate new SSL context");
+        spice_error("Could not allocate new SSL context");
     }
 
     /* Limit connection to TLSv1 only */
@@ -3104,9 +3104,9 @@ static void reds_init_ssl(void)
     /* Load our keys and certificates*/
     return_code = SSL_CTX_use_certificate_chain_file(reds->ctx, ssl_parameters.certs_file);
     if (return_code == 1) {
-        red_printf("Loaded certificates from %s", ssl_parameters.certs_file);
+        spice_printerr("Loaded certificates from %s", ssl_parameters.certs_file);
     } else {
-        red_error("Could not load certificates from %s", ssl_parameters.certs_file);
+        spice_error("Could not load certificates from %s", ssl_parameters.certs_file);
     }
 
     SSL_CTX_set_default_passwd_cb(reds->ctx, ssl_password_cb);
@@ -3114,17 +3114,17 @@ static void reds_init_ssl(void)
     return_code = SSL_CTX_use_PrivateKey_file(reds->ctx, ssl_parameters.private_key_file,
                                               SSL_FILETYPE_PEM);
     if (return_code == 1) {
-        red_printf("Using private key from %s", ssl_parameters.private_key_file);
+        spice_printerr("Using private key from %s", ssl_parameters.private_key_file);
     } else {
-        red_error("Could not use private key file");
+        spice_error("Could not use private key file");
     }
 
     /* Load the CAs we trust*/
     return_code = SSL_CTX_load_verify_locations(reds->ctx, ssl_parameters.ca_certificate_file, 0);
     if (return_code == 1) {
-        red_printf("Loaded CA certificates from %s", ssl_parameters.ca_certificate_file);
+        spice_printerr("Loaded CA certificates from %s", ssl_parameters.ca_certificate_file);
     } else {
-        red_error("Could not use CA file %s", ssl_parameters.ca_certificate_file);
+        spice_error("Could not use CA file %s", ssl_parameters.ca_certificate_file);
     }
 
 #if (OPENSSL_VERSION_NUMBER < 0x00905100L)
@@ -3195,7 +3195,7 @@ enum {
 static inline void on_activating_ticketing(void)
 {
     if (!ticketing_enabled && reds_main_channel_connected()) {
-        red_printf("disconnecting");
+        spice_printerr("disconnecting");
         reds_disconnect();
     }
 }
@@ -3247,8 +3247,8 @@ static void reds_mig_release(void)
 
 static void reds_mig_started(void)
 {
-    red_printf("");
-    ASSERT(reds->mig_spice);
+    spice_printerr("");
+    spice_assert(reds->mig_spice);
 
     reds->mig_inprogress = TRUE;
     reds->mig_wait_connect = TRUE;
@@ -3257,10 +3257,10 @@ static void reds_mig_started(void)
 
 static void reds_mig_finished(int completed)
 {
-    red_printf("");
+    spice_printerr("");
 
     if (!reds_main_channel_connected()) {
-        red_printf("no peer connected");
+        spice_printerr("no peer connected");
         return;
     }
     reds->mig_inprogress = TRUE;
@@ -3277,7 +3277,7 @@ static void reds_mig_finished(int completed)
 static void reds_mig_switch(void)
 {
     if (!reds->mig_spice) {
-        red_printf("warning: reds_mig_switch called without migrate_info set");
+        spice_printerr("warning: reds_mig_switch called without migrate_info set");
         return;
     }
     main_channel_migrate_switch(reds->main_channel, reds->mig_spice);
@@ -3286,8 +3286,8 @@ static void reds_mig_switch(void)
 
 static void migrate_timeout(void *opaque)
 {
-    red_printf("");
-    ASSERT(reds->mig_wait_connect || reds->mig_wait_disconnect);
+    spice_printerr("");
+    spice_assert(reds->mig_wait_connect || reds->mig_wait_disconnect);
     if (reds->mig_wait_connect) {
         /* we will fall back to the switch host scheme when migration completes */
         main_channel_migrate_cancel_wait(reds->main_channel);
@@ -3383,10 +3383,10 @@ static int spice_server_char_device_add_interface(SpiceServer *s,
     SpiceCharDeviceInstance* char_device =
             SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
 
-    red_printf("CHAR_DEVICE %s", char_device->subtype);
+    spice_printerr("CHAR_DEVICE %s", char_device->subtype);
     if (strcmp(char_device->subtype, SUBTYPE_VDAGENT) == 0) {
         if (vdagent) {
-            red_printf("vdagent already attached");
+            spice_printerr("vdagent already attached");
             return -1;
         }
         char_device->st = &vdagent_char_device_state;
@@ -3410,7 +3410,7 @@ static void spice_server_char_device_remove_interface(SpiceBaseInstance *sin)
     SpiceCharDeviceInstance* char_device =
             SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
 
-    red_printf("remove CHAR_DEVICE %s", char_device->subtype);
+    spice_printerr("remove CHAR_DEVICE %s", char_device->subtype);
     if (strcmp(char_device->subtype, SUBTYPE_VDAGENT) == 0) {
         if (vdagent) {
             reds_agent_remove();
@@ -3431,23 +3431,23 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
 {
     const SpiceBaseInterface *interface = sin->sif;
 
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 
     if (strcmp(interface->type, SPICE_INTERFACE_KEYBOARD) == 0) {
-        red_printf("SPICE_INTERFACE_KEYBOARD");
+        spice_printerr("SPICE_INTERFACE_KEYBOARD");
         if (interface->major_version != SPICE_INTERFACE_KEYBOARD_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_KEYBOARD_MINOR) {
-            red_printf("unsupported keyboard interface");
+            spice_printerr("unsupported keyboard interface");
             return -1;
         }
         if (inputs_set_keyboard(SPICE_CONTAINEROF(sin, SpiceKbdInstance, base)) != 0) {
             return -1;
         }
     } else if (strcmp(interface->type, SPICE_INTERFACE_MOUSE) == 0) {
-        red_printf("SPICE_INTERFACE_MOUSE");
+        spice_printerr("SPICE_INTERFACE_MOUSE");
         if (interface->major_version != SPICE_INTERFACE_MOUSE_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_MOUSE_MINOR) {
-            red_printf("unsupported mouse interface");
+            spice_printerr("unsupported mouse interface");
             return -1;
         }
         if (inputs_set_mouse(SPICE_CONTAINEROF(sin, SpiceMouseInstance, base)) != 0) {
@@ -3456,10 +3456,10 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
     } else if (strcmp(interface->type, SPICE_INTERFACE_QXL) == 0) {
         QXLInstance *qxl;
 
-        red_printf("SPICE_INTERFACE_QXL");
+        spice_printerr("SPICE_INTERFACE_QXL");
         if (interface->major_version != SPICE_INTERFACE_QXL_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_QXL_MINOR) {
-            red_printf("unsupported qxl interface");
+            spice_printerr("unsupported qxl interface");
             return -1;
         }
 
@@ -3469,10 +3469,10 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
         qxl->st->dispatcher = red_dispatcher_init(qxl);
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) {
-        red_printf("SPICE_INTERFACE_TABLET");
+        spice_printerr("SPICE_INTERFACE_TABLET");
         if (interface->major_version != SPICE_INTERFACE_TABLET_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_TABLET_MINOR) {
-            red_printf("unsupported tablet interface");
+            spice_printerr("unsupported tablet interface");
             return -1;
         }
         if (inputs_set_tablet(SPICE_CONTAINEROF(sin, SpiceTabletInstance, base)) != 0) {
@@ -3484,19 +3484,19 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
         }
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
-        red_printf("SPICE_INTERFACE_PLAYBACK");
+        spice_printerr("SPICE_INTERFACE_PLAYBACK");
         if (interface->major_version != SPICE_INTERFACE_PLAYBACK_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_PLAYBACK_MINOR) {
-            red_printf("unsupported playback interface");
+            spice_printerr("unsupported playback interface");
             return -1;
         }
         snd_attach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
-        red_printf("SPICE_INTERFACE_RECORD");
+        spice_printerr("SPICE_INTERFACE_RECORD");
         if (interface->major_version != SPICE_INTERFACE_RECORD_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_RECORD_MINOR) {
-            red_printf("unsupported record interface");
+            spice_printerr("unsupported record interface");
             return -1;
         }
         snd_attach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
@@ -3504,7 +3504,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         if (interface->major_version != SPICE_INTERFACE_CHAR_DEVICE_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_CHAR_DEVICE_MINOR) {
-            red_printf("unsupported char device interface");
+            spice_printerr("unsupported char device interface");
             return -1;
         }
         spice_server_char_device_add_interface(s, sin);
@@ -3512,33 +3512,33 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
     } else if (strcmp(interface->type, SPICE_INTERFACE_NET_WIRE) == 0) {
 #ifdef USE_TUNNEL
         SpiceNetWireInstance *net;
-        red_printf("SPICE_INTERFACE_NET_WIRE");
+        spice_printerr("SPICE_INTERFACE_NET_WIRE");
         if (red_tunnel) {
-            red_printf("net wire already attached");
+            spice_printerr("net wire already attached");
             return -1;
         }
         if (interface->major_version != SPICE_INTERFACE_NET_WIRE_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_NET_WIRE_MINOR) {
-            red_printf("unsupported net wire interface");
+            spice_printerr("unsupported net wire interface");
             return -1;
         }
         net = SPICE_CONTAINEROF(sin, SpiceNetWireInstance, base);
         net->st = spice_new0(SpiceNetWireState, 1);
         red_tunnel = red_tunnel_attach(core, net);
 #else
-        red_printf("unsupported net wire interface");
+        spice_printerr("unsupported net wire interface");
         return -1;
 #endif
     } else if (strcmp(interface->type, SPICE_INTERFACE_MIGRATION) == 0) {
-        red_printf("SPICE_INTERFACE_MIGRATION");
+        spice_printerr("SPICE_INTERFACE_MIGRATION");
         if (migration_interface) {
-            red_printf("already have migration");
+            spice_printerr("already have migration");
             return -1;
         }
 
         if (interface->major_version != SPICE_INTERFACE_MIGRATION_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_MIGRATION_MINOR) {
-            red_printf("unsupported migration interface");
+            spice_printerr("unsupported migration interface");
             return -1;
         }
         migration_interface = SPICE_CONTAINEROF(sin, SpiceMigrateInstance, base);
@@ -3553,21 +3553,21 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
     const SpiceBaseInterface *interface = sin->sif;
 
     if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) {
-        red_printf("remove SPICE_INTERFACE_TABLET");
+        spice_printerr("remove SPICE_INTERFACE_TABLET");
         inputs_detach_tablet(SPICE_CONTAINEROF(sin, SpiceTabletInstance, base));
         reds_update_mouse_mode();
     } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
-        red_printf("remove SPICE_INTERFACE_PLAYBACK");
+        spice_printerr("remove SPICE_INTERFACE_PLAYBACK");
         snd_detach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
-        red_printf("remove SPICE_INTERFACE_RECORD");
+        spice_printerr("remove SPICE_INTERFACE_RECORD");
         snd_detach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         spice_server_char_device_remove_interface(sin);
     } else {
-        red_error("VD_INTERFACE_REMOVING unsupported");
+        spice_error("VD_INTERFACE_REMOVING unsupported");
         return -1;
     }
 
@@ -3640,10 +3640,10 @@ const char *version_string = VERSION;
 
 static int do_spice_init(SpiceCoreInterface *core_interface)
 {
-    red_printf("starting %s", version_string);
+    spice_printerr("starting %s", version_string);
 
     if (core_interface->base.major_version != SPICE_INTERFACE_CORE_MAJOR) {
-        red_printf("bad core interface version");
+        spice_printerr("bad core interface version");
         goto err;
     }
     core = core_interface;
@@ -3657,11 +3657,11 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     ring_init(&reds->mig_target_clients);
 
     if (!(reds->mig_timer = core->timer_add(migrate_timeout, NULL))) {
-        red_error("migration timer create failed");
+        spice_error("migration timer create failed");
     }
     if (!(reds->vdi_port_write_timer = core->timer_add(vdi_port_write_retry, NULL)))
     {
-        red_error("vdi port write timer create failed");
+        spice_error("vdi port write timer create failed");
     }
     reds->vdi_port_write_timer_started = FALSE;
 
@@ -3672,26 +3672,26 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     reds->stat_shm_name = (char *)spice_malloc(shm_name_len);
     snprintf(reds->stat_shm_name, shm_name_len, SPICE_STAT_SHM_NAME, getpid());
     if ((fd = shm_open(reds->stat_shm_name, O_CREAT | O_RDWR, 0444)) == -1) {
-        red_error("statistics shm_open failed, %s", strerror(errno));
+        spice_error("statistics shm_open failed, %s", strerror(errno));
     }
     if (ftruncate(fd, REDS_STAT_SHM_SIZE) == -1) {
-        red_error("statistics ftruncate failed, %s", strerror(errno));
+        spice_error("statistics ftruncate failed, %s", strerror(errno));
     }
     reds->stat = (SpiceStat *)mmap(NULL, REDS_STAT_SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     if (reds->stat == (SpiceStat *)MAP_FAILED) {
-        red_error("statistics mmap failed, %s", strerror(errno));
+        spice_error("statistics mmap failed, %s", strerror(errno));
     }
     memset(reds->stat, 0, REDS_STAT_SHM_SIZE);
     reds->stat->magic = SPICE_STAT_MAGIC;
     reds->stat->version = SPICE_STAT_VERSION;
     reds->stat->root_index = INVALID_STAT_REF;
     if (pthread_mutex_init(&reds->stat_lock, NULL)) {
-        red_error("mutex init failed");
+        spice_error("mutex init failed");
     }
 #endif
 
     if (!(reds->mm_timer = core->timer_add(mm_timer_proc, NULL))) {
-        red_error("mm timer create failed");
+        spice_error("mm timer create failed");
     }
     core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
 
@@ -3705,7 +3705,7 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     int saslerr;
     if ((saslerr = sasl_server_init(NULL, sasl_appname ?
                                     sasl_appname : "spice")) != SASL_OK) {
-        red_error("Failed to initialize SASL auth %s",
+        spice_error("Failed to initialize SASL auth %s",
                   sasl_errstring(saslerr, NULL, NULL));
         goto err;
     }
@@ -3717,7 +3717,7 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     reds->mouse_mode = SPICE_MOUSE_MODE_SERVER;
     reds->allow_multiple_clients = getenv(SPICE_DEBUG_ALLOW_MC_ENV) != NULL;
     if (reds->allow_multiple_clients) {
-        red_printf("spice: allowing multiple client connections");
+        spice_printerr("spice: allowing multiple client connections");
     }
     atexit(reds_exit);
     return 0;
@@ -3730,7 +3730,7 @@ err:
 SPICE_GNUC_VISIBLE SpiceServer *spice_server_new(void)
 {
     /* we can't handle multiple instances (yet) */
-    ASSERT(reds == NULL);
+    spice_assert(reds == NULL);
 
     reds = spice_new0(RedsState, 1);
     return reds;
@@ -3740,7 +3740,7 @@ SPICE_GNUC_VISIBLE int spice_server_init(SpiceServer *s, SpiceCoreInterface *cor
 {
     int ret;
 
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     ret = do_spice_init(core);
     if (default_renderer) {
         red_dispatcher_add_renderer(default_renderer);
@@ -3750,7 +3750,7 @@ SPICE_GNUC_VISIBLE int spice_server_init(SpiceServer *s, SpiceCoreInterface *cor
 
 SPICE_GNUC_VISIBLE void spice_server_destroy(SpiceServer *s)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     reds_exit();
 }
 
@@ -3776,7 +3776,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_compat_version(SpiceServer *s,
 
 SPICE_GNUC_VISIBLE int spice_server_set_port(SpiceServer *s, int port)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (port < 0 || port > 0xffff) {
         return -1;
     }
@@ -3786,7 +3786,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_port(SpiceServer *s, int port)
 
 SPICE_GNUC_VISIBLE void spice_server_set_addr(SpiceServer *s, const char *addr, int flags)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     strncpy(spice_addr, addr, sizeof(spice_addr));
     if (flags & SPICE_ADDR_FLAG_IPV4_ONLY) {
         spice_family = PF_INET;
@@ -3798,14 +3798,14 @@ SPICE_GNUC_VISIBLE void spice_server_set_addr(SpiceServer *s, const char *addr,
 
 SPICE_GNUC_VISIBLE int spice_server_set_listen_socket_fd(SpiceServer *s, int listen_fd)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     spice_listen_socket_fd = listen_fd;
     return 0;
 }
 
 SPICE_GNUC_VISIBLE int spice_server_set_noauth(SpiceServer *s)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     memset(taTicket.password, 0, sizeof(taTicket.password));
     ticketing_enabled = 0;
     return 0;
@@ -3813,7 +3813,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_noauth(SpiceServer *s)
 
 SPICE_GNUC_VISIBLE int spice_server_set_sasl(SpiceServer *s, int enabled)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 #if HAVE_SASL
     sasl_enabled = enabled;
     return 0;
@@ -3824,7 +3824,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_sasl(SpiceServer *s, int enabled)
 
 SPICE_GNUC_VISIBLE int spice_server_set_sasl_appname(SpiceServer *s, const char *appname)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 #if HAVE_SASL
     free(sasl_appname);
     sasl_appname = spice_strdup(appname);
@@ -3851,7 +3851,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_ticket(SpiceServer *s,
                                                int fail_if_connected,
                                                int disconnect_if_connected)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 
     if (reds_main_channel_connected()) {
         if (fail_if_connected) {
@@ -3884,7 +3884,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_tls(SpiceServer *s, int port,
                                             const char *private_key_file, const char *key_passwd,
                                             const char *dh_key_file, const char *ciphersuite)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (port == 0 || ca_cert_file == NULL || certs_file == NULL ||
         private_key_file == NULL) {
         return -1;
@@ -3920,22 +3920,22 @@ SPICE_GNUC_VISIBLE int spice_server_set_tls(SpiceServer *s, int port,
 SPICE_GNUC_VISIBLE int spice_server_set_image_compression(SpiceServer *s,
                                                           spice_image_compression_t comp)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     set_image_compression(comp);
     return 0;
 }
 
 SPICE_GNUC_VISIBLE spice_image_compression_t spice_server_get_image_compression(SpiceServer *s)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     return image_compression;
 }
 
 SPICE_GNUC_VISIBLE int spice_server_set_jpeg_compression(SpiceServer *s, spice_wan_compression_t comp)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (comp == SPICE_WAN_COMPRESSION_INVALID) {
-        red_printf("invalid jpeg state");
+        spice_printerr("invalid jpeg state");
         return -1;
     }
     // todo: support dynamically changing the state
@@ -3945,9 +3945,9 @@ SPICE_GNUC_VISIBLE int spice_server_set_jpeg_compression(SpiceServer *s, spice_w
 
 SPICE_GNUC_VISIBLE int spice_server_set_zlib_glz_compression(SpiceServer *s, spice_wan_compression_t comp)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (comp == SPICE_WAN_COMPRESSION_INVALID) {
-        red_printf("invalid zlib_glz state");
+        spice_printerr("invalid zlib_glz state");
         return -1;
     }
     // todo: support dynamically changing the state
@@ -3973,7 +3973,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_channel_security(SpiceServer *s, const c
     };
     int i;
 
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 
     if (channel == NULL) {
         default_channel_security = security;
@@ -3990,7 +3990,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_channel_security(SpiceServer *s, const c
 
 SPICE_GNUC_VISIBLE int spice_server_get_sock_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (main_channel_getsockname(reds->main_channel, sa, salen) < 0) {
         return -1;
     }
@@ -3999,7 +3999,7 @@ SPICE_GNUC_VISIBLE int spice_server_get_sock_info(SpiceServer *s, struct sockadd
 
 SPICE_GNUC_VISIBLE int spice_server_get_peer_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (main_channel_getpeername(reds->main_channel, sa, salen) < 0) {
         return -1;
     }
@@ -4008,7 +4008,7 @@ SPICE_GNUC_VISIBLE int spice_server_get_peer_info(SpiceServer *s, struct sockadd
 
 SPICE_GNUC_VISIBLE int spice_server_add_renderer(SpiceServer *s, const char *name)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (!red_dispatcher_add_renderer(name)) {
         return -1;
     }
@@ -4024,7 +4024,7 @@ SPICE_GNUC_VISIBLE int spice_server_kbd_leds(SpiceKbdInstance *sin, int leds)
 
 SPICE_GNUC_VISIBLE int spice_server_set_streaming_video(SpiceServer *s, int value)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     if (value != SPICE_STREAM_VIDEO_OFF &&
         value != SPICE_STREAM_VIDEO_ALL &&
         value != SPICE_STREAM_VIDEO_FILTER)
@@ -4036,14 +4036,14 @@ SPICE_GNUC_VISIBLE int spice_server_set_streaming_video(SpiceServer *s, int valu
 
 SPICE_GNUC_VISIBLE int spice_server_set_playback_compression(SpiceServer *s, int enable)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     snd_set_playback_compression(enable);
     return 0;
 }
 
 SPICE_GNUC_VISIBLE int spice_server_set_agent_mouse(SpiceServer *s, int enable)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     agent_mouse = enable;
     reds_update_mouse_mode();
     return 0;
@@ -4051,7 +4051,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_agent_mouse(SpiceServer *s, int enable)
 
 SPICE_GNUC_VISIBLE int spice_server_set_agent_copypaste(SpiceServer *s, int enable)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
     agent_copypaste = enable;
     reds->agent_state.write_filter.copy_paste_enabled = agent_copypaste;
     reds->agent_state.read_filter.copy_paste_enabled = agent_copypaste;
@@ -4090,12 +4090,12 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *s, const char*
 {
     SpiceMigrateInterface *sif;
 
-    red_printf("");
-    ASSERT(migration_interface);
-    ASSERT(reds == s);
+    spice_printerr("");
+    spice_assert(migration_interface);
+    spice_assert(reds == s);
 
     if (reds->expect_migrate) {
-        red_printf("warning: consecutive calls without migration. Canceling previous call");
+        spice_printerr("warning: consecutive calls without migration. Canceling previous call");
         main_channel_migrate_complete(reds->main_channel, FALSE);
     }
 
@@ -4114,7 +4114,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *s, const char*
     } else {
         if (reds->num_clients == 0) {
             reds_mig_release();
-            red_printf("no client connected");
+            spice_printerr("no client connected");
         }
         sif->migrate_connect_complete(migration_interface);
     }
@@ -4126,9 +4126,9 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_info(SpiceServer *s, const char* des
                                           int port, int secure_port,
                                           const char* cert_subject)
 {
-    red_printf("");
-    ASSERT(!migration_interface);
-    ASSERT(reds == s);
+    spice_printerr("");
+    spice_assert(!migration_interface);
+    spice_assert(reds == s);
 
     if (!reds_set_migration_dest_info(dest, port, secure_port, cert_subject)) {
         return -1;
@@ -4138,8 +4138,8 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_info(SpiceServer *s, const char* des
 
 SPICE_GNUC_VISIBLE int spice_server_migrate_start(SpiceServer *s)
 {
-    ASSERT(reds == s);
-    red_printf("");
+    spice_assert(reds == s);
+    spice_printerr("");
     if (!reds->mig_spice) {
         return -1;
     }
@@ -4148,7 +4148,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_start(SpiceServer *s)
 
 SPICE_GNUC_VISIBLE int spice_server_migrate_client_state(SpiceServer *s)
 {
-    ASSERT(reds == s);
+    spice_assert(reds == s);
 
     if (!reds_main_channel_connected()) {
         return SPICE_MIGRATE_CLIENT_NONE;
@@ -4165,14 +4165,14 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_end(SpiceServer *s, int completed)
     SpiceMigrateInterface *sif;
     int ret = 0;
 
-    red_printf("");
+    spice_printerr("");
 
-    ASSERT(migration_interface);
-    ASSERT(reds == s);
+    spice_assert(migration_interface);
+    spice_assert(reds == s);
 
     sif = SPICE_CONTAINEROF(migration_interface->base.sif, SpiceMigrateInterface, base);
     if (!reds->expect_migrate && reds->num_clients) {
-        red_printf("spice_server_migrate_info was not called, disconnecting clients");
+        spice_printerr("spice_server_migrate_info was not called, disconnecting clients");
         reds_disconnect();
         ret = -1;
         goto complete;
@@ -4191,8 +4191,8 @@ complete:
 /* interface for switch-host migration */
 SPICE_GNUC_VISIBLE int spice_server_migrate_switch(SpiceServer *s)
 {
-    ASSERT(reds == s);
-    red_printf("");
+    spice_assert(reds == s);
+    spice_printerr("");
     if (!reds->num_clients) {
        return 0;
     }
@@ -4276,7 +4276,7 @@ void reds_stream_free(RedsStream *s)
     }
 
     reds_stream_remove_watch(s);
-    red_printf("close socket fd %d", s->socket);
+    spice_printerr("close socket fd %d", s->socket);
     close(s->socket);
 
     free(s);
diff --git a/server/smartcard.c b/server/smartcard.c
index d023331..894053e 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -101,7 +101,7 @@ void smartcard_char_device_wakeup(SpiceCharDeviceInstance *sin)
         if (actual_length > state->buf_size) {
             state->buf_size = MAX(state->buf_size*2, actual_length + sizeof(VSCMsgHeader));
             state->buf = spice_realloc(state->buf, state->buf_size);
-            ASSERT(state->buf != NULL);
+            spice_assert(state->buf != NULL);
         }
         if (state->buf_used - sizeof(VSCMsgHeader) < actual_length) {
             continue;
@@ -135,7 +135,7 @@ void smartcard_char_device_on_message_from_device(
     }
     /* We pass any VSC_Error right now - might need to ignore some? */
     if (state->reader_id == VSCARD_UNDEFINED_READER_ID && vheader->type != VSC_Init) {
-        red_printf("error: reader_id not assigned for message of type %d", vheader->type);
+        spice_printerr("error: reader_id not assigned for message of type %d", vheader->type);
     }
     if (state->rcc) {
         sent_header = spice_memdup(vheader, sizeof(*vheader) + vheader->length);
@@ -176,7 +176,7 @@ static int smartcard_char_device_add_to_readers(SpiceCharDeviceInstance *char_de
 
 static SpiceCharDeviceInstance *smartcard_readers_get(uint32_t reader_id)
 {
-    ASSERT(reader_id < g_smartcard_readers.num);
+    spice_assert(reader_id < g_smartcard_readers.num);
     return g_smartcard_readers.sin[reader_id];
 }
 
@@ -284,15 +284,15 @@ static void smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc,
                                                   uint32_t size,
                                                   uint8_t *msg)
 {
-    red_printf("freeing %d bytes", size);
+    spice_printerr("freeing %d bytes", size);
     free(msg);
 }
 
 static void smartcard_channel_send_data(RedChannelClient *rcc, SpiceMarshaller *m,
                                         PipeItem *item, VSCMsgHeader *vheader)
 {
-    ASSERT(rcc);
-    ASSERT(vheader);
+    spice_assert(rcc);
+    spice_assert(vheader);
     red_channel_client_init_send_data(rcc, SPICE_MSG_SMARTCARD_DATA, item);
     spice_marshaller_add_ref(m, (uint8_t*)vheader, sizeof(VSCMsgHeader));
     if (vheader->length > 0) {
@@ -428,7 +428,7 @@ static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader)
     uint32_t n;
     uint32_t actual_length = vheader->length;
 
-    ASSERT(vheader->reader_id >= 0 &&
+    spice_assert(vheader->reader_id >= 0 &&
            vheader->reader_id <= g_smartcard_readers.num);
     sin = g_smartcard_readers.sin[vheader->reader_id];
     sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
@@ -439,7 +439,7 @@ static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader)
     n = sif->write(sin, (uint8_t*)vheader,
                    actual_length + sizeof(VSCMsgHeader));
     // TODO - add ring
-    ASSERT(n == actual_length + sizeof(VSCMsgHeader));
+    spice_assert(n == actual_length + sizeof(VSCMsgHeader));
 }
 
 static int smartcard_channel_handle_message(RedChannelClient *rcc,
@@ -454,7 +454,7 @@ static int smartcard_channel_handle_message(RedChannelClient *rcc,
         return red_channel_client_handle_message(rcc, size, type, msg);
     }
 
-    ASSERT(size == vheader->length + sizeof(VSCMsgHeader));
+    spice_assert(size == vheader->length + sizeof(VSCMsgHeader));
     switch (vheader->type) {
         case VSC_ReaderAdd:
             smartcard_add_reader(rcc, msg + sizeof(VSCMsgHeader));
@@ -479,7 +479,7 @@ static int smartcard_channel_handle_message(RedChannelClient *rcc,
     }
 
     if (vheader->reader_id >= g_smartcard_readers.num) {
-        red_printf("ERROR: received message for non existent reader: %d, %d, %d", vheader->reader_id,
+        spice_printerr("ERROR: received message for non existent reader: %d, %d, %d", vheader->reader_id,
             vheader->type, vheader->length);
         return FALSE;
     }
@@ -515,7 +515,7 @@ static void smartcard_init(void)
     ChannelCbs channel_cbs = { NULL, };
     ClientCbs client_cbs = { NULL, };
 
-    ASSERT(!g_smartcard_channel);
+    spice_assert(!g_smartcard_channel);
 
     channel_cbs.config_socket = smartcard_channel_client_config_socket;
     channel_cbs.on_disconnect = smartcard_channel_on_disconnect;
@@ -533,7 +533,7 @@ static void smartcard_init(void)
                                              &channel_cbs);
 
     if (!g_smartcard_channel) {
-        red_error("failed to allocate Inputs Channel");
+        spice_error("failed to allocate Inputs Channel");
     }
 
     client_cbs.connect = smartcard_connect;
diff --git a/server/snd_worker.c b/server/snd_worker.c
index be98094..7bdd399 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -208,7 +208,7 @@ static SndChannel *snd_channel_put(SndChannel *channel)
     if (!--channel->refs) {
         channel->worker->connection = NULL;
         free(channel);
-        red_printf("sound channel freed");
+        spice_printerr("sound channel freed");
         return NULL;
     }
     return channel;
@@ -295,7 +295,7 @@ static int snd_send_data(SndChannel *channel)
                 snd_disconnect_channel(channel);
                 return FALSE;
             default:
-                red_printf("%s", strerror(errno));
+                spice_printerr("%s", strerror(errno));
                 snd_disconnect_channel(channel);
                 return FALSE;
             }
@@ -326,7 +326,7 @@ static int snd_record_handle_write(RecordChannel *record_channel, size_t size, v
         int celt_err = celt051_decode(record_channel->celt_decoder, packet->data, size,
                                       (celt_int16_t *)record_channel->celt_buf);
         if (celt_err != CELT_OK) {
-            red_printf("celt decode failed (%d)", celt_err);
+            spice_printerr("celt decode failed (%d)", celt_err);
             return FALSE;
         }
         data = record_channel->celt_buf;
@@ -366,7 +366,7 @@ static int snd_playback_handle_message(SndChannel *channel, size_t size, uint32_
     case SPICE_MSGC_DISCONNECTING:
         break;
     default:
-        red_printf("invalid message type %u", type);
+        spice_printerr("invalid message type %u", type);
         return FALSE;
     }
     return TRUE;
@@ -388,7 +388,7 @@ static int snd_record_handle_message(SndChannel *channel, size_t size, uint32_t
         record_channel->mode_time = mode->time;
         if (record_channel->mode != SPICE_AUDIO_DATA_MODE_CELT_0_5_1 &&
                                                   record_channel->mode != SPICE_AUDIO_DATA_MODE_RAW) {
-            red_printf("unsupported mode");
+            spice_printerr("unsupported mode");
         }
         break;
     }
@@ -402,7 +402,7 @@ static int snd_record_handle_message(SndChannel *channel, size_t size, uint32_t
     case SPICE_MSGC_MIGRATE_DATA: {
         RecordMigrateData* mig_data = (RecordMigrateData *)message;
         if (mig_data->version != RECORD_MIG_VERSION) {
-            red_printf("invalid mig version");
+            spice_printerr("invalid mig version");
             break;
         }
         record_channel->mode = mig_data->mode;
@@ -411,7 +411,7 @@ static int snd_record_handle_message(SndChannel *channel, size_t size, uint32_t
         break;
     }
     default:
-        red_printf("invalid message type %u", type);
+        spice_printerr("invalid message type %u", type);
         return FALSE;
     }
     return TRUE;
@@ -431,14 +431,14 @@ static void snd_receive(void* data)
     for (;;) {
         ssize_t n;
         n = channel->recive_data.end - channel->recive_data.now;
-        ASSERT(n);
+        spice_assert(n);
         n = reds_stream_read(channel->stream, channel->recive_data.now, n);
         if (n <= 0) {
             if (n == 0) {
                 snd_disconnect_channel(channel);
                 return;
             }
-            ASSERT(n == -1);
+            spice_assert(n == -1);
             switch (errno) {
             case EAGAIN:
                 return;
@@ -448,7 +448,7 @@ static void snd_receive(void* data)
                 snd_disconnect_channel(channel);
                 return;
             default:
-                red_printf("%s", strerror(errno));
+                spice_printerr("%s", strerror(errno));
                 snd_disconnect_channel(channel);
                 return;
             }
@@ -472,7 +472,7 @@ static void snd_receive(void* data)
                                          header->get_msg_type(header),
                                          SPICE_VERSION_MINOR, &parsed_size, &parsed_free);
                 if (parsed == NULL) {
-                    red_printf("failed to parse message type %d", header->get_msg_type(header));
+                    spice_printerr("failed to parse message type %d", header->get_msg_type(header));
                     snd_disconnect_channel(channel);
                     return;
                 }
@@ -629,7 +629,7 @@ static int snd_playback_send_start(PlaybackChannel *playback_channel)
 
     start.channels = SPICE_INTERFACE_PLAYBACK_CHAN;
     start.frequency = SPICE_INTERFACE_PLAYBACK_FREQ;
-    ASSERT(SPICE_INTERFACE_PLAYBACK_FMT == SPICE_INTERFACE_AUDIO_FMT_S16);
+    spice_assert(SPICE_INTERFACE_PLAYBACK_FMT == SPICE_INTERFACE_AUDIO_FMT_S16);
     start.format = SPICE_AUDIO_FMT_S16;
     start.time = reds_get_mm_time();
     spice_marshall_msg_playback_start(channel->send_data.marshaller, &start);
@@ -670,7 +670,7 @@ static int snd_record_send_start(RecordChannel *record_channel)
 
     start.channels = SPICE_INTERFACE_RECORD_CHAN;
     start.frequency = SPICE_INTERFACE_RECORD_FREQ;
-    ASSERT(SPICE_INTERFACE_RECORD_FMT == SPICE_INTERFACE_AUDIO_FMT_S16);
+    spice_assert(SPICE_INTERFACE_RECORD_FMT == SPICE_INTERFACE_AUDIO_FMT_S16);
     start.format = SPICE_AUDIO_FMT_S16;
     spice_marshall_msg_record_start(channel->send_data.marshaller, &start);
 
@@ -783,7 +783,7 @@ static int snd_playback_send_write(PlaybackChannel *playback_channel)
         int n = celt051_encode(playback_channel->celt_encoder, (celt_int16_t *)frame->samples, NULL,
                                playback_channel->send_data.celt_buf, CELT_COMPRESSED_FRAME_BYTES);
         if (n < 0) {
-            red_printf("celt encode failed");
+            spice_printerr("celt encode failed");
             snd_disconnect_channel(channel);
             return FALSE;
         }
@@ -829,12 +829,12 @@ static void snd_playback_send(void* data)
             channel->command &= ~SND_PLAYBACK_MODE_MASK;
         }
         if (channel->command & SND_PLAYBACK_PCM_MASK) {
-            ASSERT(!playback_channel->in_progress && playback_channel->pending_frame);
+            spice_assert(!playback_channel->in_progress && playback_channel->pending_frame);
             playback_channel->in_progress = playback_channel->pending_frame;
             playback_channel->pending_frame = NULL;
             channel->command &= ~SND_PLAYBACK_PCM_MASK;
             if (!snd_playback_send_write(playback_channel)) {
-                red_printf("snd_send_playback_write failed");
+                spice_printerr("snd_send_playback_write failed");
                 return;
             }
         }
@@ -913,7 +913,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
     MainChannelClient *mcc = red_client_get_main(client);
 
     if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         goto error1;
     }
 
@@ -922,7 +922,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
     if (setsockopt(stream->socket, SOL_SOCKET, SO_PRIORITY, (void*)&priority,
                    sizeof(priority)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
 #endif
@@ -930,23 +930,23 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
     tos = IPTOS_LOWDELAY;
     if (setsockopt(stream->socket, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
 
     delay_val = main_channel_client_is_low_bandwidth(mcc) ? 0 : 1;
     if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val, sizeof(delay_val)) == -1) {
         if (errno != ENOTSUP) {
-            red_printf("setsockopt failed, %s", strerror(errno));
+            spice_printerr("setsockopt failed, %s", strerror(errno));
         }
     }
 
     if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
-        red_printf("accept failed, %s", strerror(errno));
+        spice_printerr("accept failed, %s", strerror(errno));
         goto error1;
     }
 
-    ASSERT(size >= sizeof(*channel));
+    spice_assert(size >= sizeof(*channel));
     channel = spice_malloc0(size);
     channel->refs = 1;
     channel->parser = spice_get_client_channel_parser(channel_id, NULL);
@@ -960,7 +960,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
     stream->watch = core->watch_add(stream->socket, SPICE_WATCH_EVENT_READ,
                                   snd_event, channel);
     if (stream->watch == NULL) {
-        red_printf("watch_add failed, %s", strerror(errno));
+        spice_printerr("watch_add failed, %s", strerror(errno));
         goto error2;
     }
 
@@ -989,13 +989,13 @@ static void snd_disconnect_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
 
-    ASSERT(rcc->channel);
-    ASSERT(rcc->channel->data);
+    spice_assert(rcc->channel);
+    spice_assert(rcc->channel->data);
     worker = (SndWorker *)rcc->channel->data;
 
-    ASSERT(worker->connection->channel_client == rcc);
+    spice_assert(worker->connection->channel_client == rcc);
     snd_disconnect_channel(worker->connection);
-    ASSERT(worker->connection == NULL);
+    spice_assert(worker->connection == NULL);
 }
 
 static void snd_set_command(SndChannel *channel, uint32_t command)
@@ -1046,7 +1046,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_start(SpicePlaybackInstance *sin)
     sin->st->worker.active = 1;
     if (!channel)
         return;
-    ASSERT(!playback_channel->base.active);
+    spice_assert(!playback_channel->base.active);
     reds_disable_mm_timer();
     playback_channel->base.active = TRUE;
     if (!playback_channel->base.client_active) {
@@ -1065,7 +1065,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_stop(SpicePlaybackInstance *sin)
     sin->st->worker.active = 0;
     if (!channel)
         return;
-    ASSERT(playback_channel->base.active);
+    spice_assert(playback_channel->base.active);
     reds_enable_mm_timer();
     playback_channel->base.active = FALSE;
     if (playback_channel->base.client_active) {
@@ -1076,7 +1076,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_stop(SpicePlaybackInstance *sin)
         playback_channel->base.command &= ~SND_PLAYBACK_PCM_MASK;
 
         if (playback_channel->pending_frame) {
-            ASSERT(!playback_channel->in_progress);
+            spice_assert(!playback_channel->in_progress);
             snd_playback_free_frame(playback_channel,
                                     playback_channel->pending_frame);
             playback_channel->pending_frame = NULL;
@@ -1095,7 +1095,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_get_buffer(SpicePlaybackInstance *
         *num_samples = 0;
         return;
     }
-    ASSERT(playback_channel->base.active);
+    spice_assert(playback_channel->base.active);
     snd_channel_get(channel);
 
     *frame = playback_channel->free_frames->samples;
@@ -1116,7 +1116,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
         /* lost last reference, channel has been destroyed previously */
         return;
     }
-    ASSERT(playback_channel->base.active);
+    spice_assert(playback_channel->base.active);
 
     if (playback_channel->pending_frame) {
         snd_playback_free_frame(playback_channel, playback_channel->pending_frame);
@@ -1134,7 +1134,7 @@ static void on_new_playback_channel(SndWorker *worker)
     PlaybackChannel *playback_channel =
         SPICE_CONTAINEROF(worker->connection, PlaybackChannel, base);
 
-    ASSERT(playback_channel);
+    spice_assert(playback_channel);
 
     snd_set_command((SndChannel *)playback_channel, SND_PLAYBACK_MODE_MASK);
     if (!playback_channel->base.migrate && playback_channel->base.active) {
@@ -1175,12 +1175,12 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
     if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_PLAYBACK_FREQ,
                                           SPICE_INTERFACE_PLAYBACK_CHAN,
                                           FRAME_SIZE, &celt_error))) {
-        red_printf("create celt mode failed %d", celt_error);
+        spice_printerr("create celt mode failed %d", celt_error);
         return;
     }
 
     if (!(celt_encoder = celt051_encoder_create(celt_mode))) {
-        red_printf("create celt encoder failed");
+        spice_printerr("create celt encoder failed");
         goto error_1;
     }
 
@@ -1228,12 +1228,12 @@ static void snd_record_migrate_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
 
-    ASSERT(rcc->channel);
-    ASSERT(rcc->channel->data);
+    spice_assert(rcc->channel);
+    spice_assert(rcc->channel->data);
     worker = (SndWorker *)rcc->channel->data;
 
     if (worker->connection) {
-        ASSERT(worker->connection->channel_client == rcc);
+        spice_assert(worker->connection->channel_client == rcc);
         snd_set_command(worker->connection, SND_RECORD_MIGRATE_MASK);
         snd_record_send(worker->connection);
     }
@@ -1279,7 +1279,7 @@ SPICE_GNUC_VISIBLE void spice_server_record_start(SpiceRecordInstance *sin)
     sin->st->worker.active = 1;
     if (!channel)
         return;
-    ASSERT(!record_channel->base.active);
+    spice_assert(!record_channel->base.active);
     record_channel->base.active = TRUE;
     record_channel->read_pos = record_channel->write_pos = 0;   //todo: improve by
                                                                 //stream generation
@@ -1299,7 +1299,7 @@ SPICE_GNUC_VISIBLE void spice_server_record_stop(SpiceRecordInstance *sin)
     sin->st->worker.active = 0;
     if (!channel)
         return;
-    ASSERT(record_channel->base.active);
+    spice_assert(record_channel->base.active);
     record_channel->base.active = FALSE;
     if (record_channel->base.client_active) {
         snd_set_command(&record_channel->base, SND_RECORD_CTRL_MASK);
@@ -1320,7 +1320,7 @@ SPICE_GNUC_VISIBLE uint32_t spice_server_record_get_samples(SpiceRecordInstance
 
     if (!channel)
         return 0;
-    ASSERT(record_channel->base.active);
+    spice_assert(record_channel->base.active);
 
     if (record_channel->write_pos < RECORD_SAMPLES_SIZE / 2) {
         return 0;
@@ -1350,7 +1350,7 @@ SPICE_GNUC_VISIBLE uint32_t spice_server_record_get_samples(SpiceRecordInstance
 static void on_new_record_channel(SndWorker *worker)
 {
     RecordChannel *record_channel = (RecordChannel *)worker->connection;
-    ASSERT(record_channel);
+    spice_assert(record_channel);
 
     snd_set_command((SndChannel *)record_channel, SND_RECORD_VOLUME_MASK);
     if (!record_channel->base.migrate) {
@@ -1384,12 +1384,12 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
     if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_RECORD_FREQ,
                                           SPICE_INTERFACE_RECORD_CHAN,
                                           FRAME_SIZE, &celt_error))) {
-        red_printf("create celt mode failed %d", celt_error);
+        spice_printerr("create celt mode failed %d", celt_error);
         return;
     }
 
     if (!(celt_decoder = celt051_decoder_create(celt_mode))) {
-        red_printf("create celt decoder failed");
+        spice_printerr("create celt decoder failed");
         goto error_1;
     }
 
@@ -1431,12 +1431,12 @@ static void snd_playback_migrate_channel_client(RedChannelClient *rcc)
 {
     SndWorker *worker;
 
-    ASSERT(rcc->channel);
-    ASSERT(rcc->channel->data);
+    spice_assert(rcc->channel);
+    spice_assert(rcc->channel->data);
     worker = (SndWorker *)rcc->channel->data;
 
     if (worker->connection) {
-        ASSERT(worker->connection->channel_client == rcc);
+        spice_assert(worker->connection->channel_client == rcc);
         snd_set_command(worker->connection, SND_PLAYBACK_MIGRATE_MASK);
         snd_playback_send(worker->connection);
     }
@@ -1458,7 +1458,7 @@ static void remove_worker(SndWorker *worker)
         }
         now = &(*now)->next;
     }
-    red_printf("not found");
+    spice_printerr("not found");
 }
 
 void snd_attach_playback(SpicePlaybackInstance *sin)
@@ -1561,7 +1561,7 @@ void snd_set_playback_compression(int on)
             PlaybackChannel* playback = (PlaybackChannel*)now->connection;
             if (!red_channel_client_test_remote_cap(sndchannel->channel_client,
                                                     SPICE_PLAYBACK_CAP_CELT_0_5_1)) {
-                ASSERT(playback->mode == SPICE_AUDIO_DATA_MODE_RAW);
+                spice_assert(playback->mode == SPICE_AUDIO_DATA_MODE_RAW);
                 continue;
             }
             if (playback->mode != playback_compression) {
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 18ae627..27123d4 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -93,7 +93,7 @@ static int spicevmc_red_channel_client_config_socket(RedChannelClient *rcc)
         if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY,
                 &delay_val, sizeof(delay_val)) != 0) {
             if (errno != ENOTSUP && errno != ENOPROTOOPT) {
-                red_printf("setsockopt failed, %s", strerror(errno));
+                spice_printerr("setsockopt failed, %s", strerror(errno));
                 return FALSE;
             }
         }
@@ -223,8 +223,8 @@ static void spicevmc_connect(RedChannel *channel, RedClient *client,
     sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
 
     if (state->rcc) {
-        WARN("channel client %d:%d (%p) already connected, refusing second connection\n",
-             channel->type, channel->id, state->rcc);
+        spice_printerr("channel client %d:%d (%p) already connected, refusing second connection",
+                       channel->type, channel->id, state->rcc);
         // TODO: notify client in advance about the in use channel using
         // SPICE_MSG_MAIN_CHANNEL_IN_USE (for example)
         reds_stream_free(stream);
diff --git a/server/zlib_encoder.c b/server/zlib_encoder.c
index c51466b..a3d2aa6 100644
--- a/server/zlib_encoder.c
+++ b/server/zlib_encoder.c
@@ -50,7 +50,7 @@ ZlibEncoder* zlib_encoder_create(ZlibEncoderUsrContext *usr, int level)
     z_ret = deflateInit(&enc->strm, level);
     enc->last_level = level;
     if (z_ret != Z_OK) {
-        red_printf("zlib error");
+        spice_printerr("zlib error");
         free(enc);
         return NULL;
     }
@@ -76,7 +76,7 @@ int zlib_encode(ZlibEncoder *zlib, int level, int input_size,
     z_ret = deflateReset(&zlib->strm);
 
     if (z_ret != Z_OK) {
-        red_error("deflateReset failed");
+        spice_error("deflateReset failed");
     }
 
     zlib->strm.next_out = io_ptr;
@@ -86,12 +86,12 @@ int zlib_encode(ZlibEncoder *zlib, int level, int input_size,
         if (zlib->strm.avail_out == 0) {
             zlib->strm.avail_out = zlib->usr->more_space(zlib->usr, &zlib->strm.next_out);
             if (zlib->strm.avail_out == 0) {
-                red_error("not enough space");
+                spice_error("not enough space");
             }
         }
         z_ret = deflateParams(&zlib->strm, level, Z_DEFAULT_STRATEGY);
         if (z_ret != Z_OK) {
-            red_error("deflateParams failed");
+            spice_error("deflateParams failed");
         }
         zlib->last_level = level;
     }
@@ -100,14 +100,14 @@ int zlib_encode(ZlibEncoder *zlib, int level, int input_size,
     do {
         zlib->strm.avail_in = zlib->usr->more_input(zlib->usr, &zlib->strm.next_in);
         if (zlib->strm.avail_in <= 0) {
-            red_error("more input failed\n");
+            spice_error("more input failed");
         }
         enc_size += zlib->strm.avail_in;
         flush = (enc_size == input_size) ?  Z_FINISH : Z_NO_FLUSH;
         while (1) {
             int deflate_size = zlib->strm.avail_out;
             z_ret = deflate(&zlib->strm, flush);
-            ASSERT(z_ret != Z_STREAM_ERROR);
+            spice_assert(z_ret != Z_STREAM_ERROR);
             out_size += deflate_size - zlib->strm.avail_out;
             if (zlib->strm.avail_out) {
                 break;
@@ -115,11 +115,11 @@ int zlib_encode(ZlibEncoder *zlib, int level, int input_size,
 
             zlib->strm.avail_out = zlib->usr->more_space(zlib->usr, &zlib->strm.next_out);
             if (zlib->strm.avail_out == 0) {
-                red_error("not enough space");
+                spice_error("not enough space");
             }
         }
     } while (flush != Z_FINISH);
 
-    ASSERT(z_ret == Z_STREAM_END);
+    spice_assert(z_ret == Z_STREAM_END);
     return out_size;
 }
commit 359fc1cb5dbbcf32132c3e8ee6f881a23deff684
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Mar 21 14:42:35 2012 +0100

    Use the spice-common submodule
    
    This patch will replace the common/ directory with the spice-common
    project. It is for now a simple project subdirectory shared with
    spice-gtk, but the goal is to make it a proper library later on.
    
    With this change, the spice-server build is broken. The following
    commits fix the build, and have been seperated to ease the review.
    
    v2
    - moves all the generated marshallers to spice-common library
    - don't attempt to fix windows VS build, which should somehow be
      splitted with spice-common (or built from tarball only to avoid
      generation tools/libs deps)
    v3
    - uses libspice-common-client
    - fix a mutex.h inclusion reported by Alon

diff --git a/.gitmodules b/.gitmodules
index f7de75d..0c618ee 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "spice-protocol"]
-	path = spice-protocol
-	url = ../spice-protocol
+[submodule "spice-common"]
+	path = spice-common
+	url = ../spice-common
diff --git a/Makefile.am b/Makefile.am
index 6c27750..6971425 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
+NULL =
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = common server python_modules
-DIST_SUBDIRS = spice-protocol $(SUBDIRS)
+SUBDIRS = spice-common server
 
 if SUPPORT_CLIENT
 SUBDIRS += client
@@ -10,9 +10,11 @@ endif
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = spice-server.pc
 
-DISTCLEANFILES =                                \
-	spice-server.pc
-
-EXTRA_DIST = spice.proto spice1.proto spice_codegen.py
-
-DISTCHECK_CONFIGURE_FLAGS=--enable-opengl --enable-gui --enable-tunnel --enable-smartcard --with-sasl --enable-automated-tests
+DISTCHECK_CONFIGURE_FLAGS =			\
+	--enable-automated-tests		\
+	--enable-gui				\
+	--enable-opengl				\
+	--enable-smartcard			\
+	--enable-tunnel				\
+	--with-sasl				\
+	$(NULL)
diff --git a/autogen.sh b/autogen.sh
index 571549e..b8f4f4a 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -8,8 +8,7 @@ test -z "$srcdir" && srcdir=.
 olddir=`pwd`
 cd "$srcdir"
 
-git submodule init
-git submodule update
+git submodule update --init --recursive
 
 mkdir -p m4
 autoreconf --verbose --force --install
diff --git a/client/Makefile.am b/client/Makefile.am
index c4b5fe1..4913c1e 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -2,27 +2,6 @@ NULL =
 
 bin_PROGRAMS = spicec
 
-BUILT_SOURCES = 			\
-	generated_demarshallers.cpp	\
-	generated_marshallers.cpp	\
-	generated_demarshallers1.cpp	\
-	generated_marshallers1.cpp	\
-	$(NULL)
-
-generated_demarshallers.cpp: $(top_srcdir)/spice.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common.h --include messages.h $(top_srcdir)/spice.proto generated_demarshallers.cpp
-
-generated_demarshallers1.cpp: $(top_srcdir)/spice1.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common.h --include messages.h --prefix 1 --ptrsize 8 $(top_srcdir)/spice1.proto generated_demarshallers1.cpp
-
-generated_marshallers.cpp: $(top_srcdir)/spice.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P  --include "common.h" --include messages.h --include marshallers.h --client $(top_srcdir)/spice.proto generated_marshallers.cpp
-
-generated_marshallers1.cpp: $(top_srcdir)/spice1.proto
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P  --include "common.h" --include messages.h --include marshallers.h --client --prefix 1 --ptrsize 8 $(top_srcdir)/spice1.proto generated_marshallers1.cpp
-
-MAINTAINERCLEANFILES = $(BUILT_SOURCES)
-
 spicec_SOURCES =		\
 	application.cpp		\
 	application.h		\
@@ -43,7 +22,6 @@ spicec_SOURCES =		\
 	cursor_channel.cpp	\
 	cursor_channel.h	\
 	debug.h			\
-	demarshallers.h		\
 	display_channel.cpp	\
 	display_channel.h	\
 	event_sources.h		\
@@ -63,7 +41,6 @@ spicec_SOURCES =		\
 	inputs_handler.h	\
 	jpeg_decoder.cpp	\
 	jpeg_decoder.h		\
-	marshallers.h		\
 	menu.cpp		\
 	menu.h			\
 	mjpeg_decoder.cpp	\
@@ -230,7 +207,7 @@ INCLUDES = \
 	$(GL_CFLAGS)					\
 	$(MISC_X_CFLAGS)				\
 	$(PIXMAN_CFLAGS)				\
-	$(PROTOCOL_CFLAGS)				\
+	$(COMMON_CFLAGS)				\
 	$(SPICE_NONPKGCONFIG_CFLAGS)			\
 	$(SMARTCARD_CFLAGS)				\
 	$(SSL_CFLAGS)					\
@@ -243,24 +220,25 @@ INCLUDES = \
 
 spicec_LDFLAGS = $(SPICEC_STATIC_LINKAGE_BSTATIC)
 
-spicec_LDADD =						\
-	$(top_builddir)/common/libspice-common.la	\
-	$(ALSA_LIBS)					\
-	$(CEGUI_LIBS)					\
-	$(CEGUI06_LIBS)					\
-	$(CELT051_LIBS)					\
-	$(GL_LIBS)					\
-	$(JPEG_LIBS)					\
-	$(MISC_X_LIBS)					\
-	$(PIXMAN_LIBS)					\
-	$(SMARTCARD_LIBS)				\
-	$(SPICE_NONPKGCONFIG_LIBS)			\
-	$(SSL_LIBS)					\
-	$(XFIXES_LIBS)					\
-	$(XRANDR_LIBS)					\
-	$(Z_LIBS)					\
-	$(XINERAMA_LIBS)				\
-	$(spicec_resource_LDADD)			\
+spicec_LDADD =								\
+	$(top_builddir)/spice-common/common/libspice-common.la		\
+	$(top_builddir)/spice-common/common/libspice-common-client.la	\
+	$(ALSA_LIBS)							\
+	$(CEGUI_LIBS)							\
+	$(CEGUI06_LIBS)							\
+	$(CELT051_LIBS)							\
+	$(GL_LIBS)							\
+	$(JPEG_LIBS)							\
+	$(MISC_X_LIBS)							\
+	$(PIXMAN_LIBS)							\
+	$(SMARTCARD_LIBS)						\
+	$(SPICE_NONPKGCONFIG_LIBS)					\
+	$(SSL_LIBS)							\
+	$(XFIXES_LIBS)							\
+	$(XRANDR_LIBS)							\
+	$(Z_LIBS)							\
+	$(XINERAMA_LIBS)						\
+	$(spicec_resource_LDADD)					\
 	$(NULL)
 
 EXTRA_DIST =				\
diff --git a/client/application.cpp b/client/application.cpp
index 34ef729..43fe7fa 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -23,6 +23,10 @@
 #include <io.h>
 #endif
 
+#include "common/quic.h"
+#include "common/mutex.h"
+#include "common/rect.h"
+
 #include "application.h"
 #include "screen.h"
 #include "utils.h"
@@ -38,13 +42,10 @@
 #ifdef USE_OPENGL
 #include "red_gl_canvas.h"
 #endif
-#include "quic.h"
-#include "mutex.h"
 #include "cmd_line_parser.h"
 #ifdef USE_TUNNEL
 #include "tunnel_channel.h"
 #endif
-#include "rect.h"
 #ifdef USE_GUI
 #include "gui/gui.h"
 #endif
diff --git a/client/canvas.h b/client/canvas.h
index 51f2800..cd6a89b 100644
--- a/client/canvas.h
+++ b/client/canvas.h
@@ -19,18 +19,20 @@
 #ifndef _H_CANVAS
 #define _H_CANVAS
 
+#include <map>
+
+#include "common/region.h"
+#include "common/messages.h"
+#include "common/canvas_utils.h"
+
 #include "common.h"
 #include "debug.h"
-#include "region.h"
-#include "messages.h"
 #include "cache.hpp"
 #include "shared_cache.hpp"
-#include "canvas_utils.h"
 #include "glz_decoded_image.h"
 #include "glz_decoder.h"
 #include "jpeg_decoder.h"
 #include "zlib_decoder.h"
-#include <map>
 
 enum CanvasType {
     CANVAS_TYPE_INVALID,
diff --git a/client/cursor.h b/client/cursor.h
index 16b7fc5..3210f1e 100644
--- a/client/cursor.h
+++ b/client/cursor.h
@@ -18,8 +18,8 @@
 #ifndef _H_CURSOR_
 #define _H_CURSOR_
 
+#include "common/messages.h"
 #include "threads.h"
-#include "messages.h"
 #include "red_window_p.h"
 
 class CursorOpaque {
diff --git a/client/cursor_channel.cpp b/client/cursor_channel.cpp
index e317dfa..48786e3 100644
--- a/client/cursor_channel.cpp
+++ b/client/cursor_channel.cpp
@@ -18,6 +18,8 @@
 #include <config.h>
 #endif
 
+#include "common/rect.h"
+
 #include "common.h"
 #include "cursor_channel.h"
 #include "display_channel.h"
@@ -28,7 +30,6 @@
 #include "utils.h"
 #include "screen.h"
 #include "red_pixmap_sw.h"
-#include "rect.h"
 
 static inline uint8_t revers_bits(uint8_t byte)
 {
diff --git a/client/demarshallers.h b/client/demarshallers.h
deleted file mode 100644
index 90084cf..0000000
--- a/client/demarshallers.h
+++ /dev/null
@@ -1,27 +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/client/display_channel.cpp b/client/display_channel.cpp
index 173f012..ebeacd2 100644
--- a/client/display_channel.cpp
+++ b/client/display_channel.cpp
@@ -20,7 +20,6 @@
 #endif
 
 #include "common.h"
-#include "canvas.h"
 #include "red_pixmap.h"
 #ifdef USE_OPENGL
 #include "red_pixmap_gl.h"
diff --git a/client/display_channel.h b/client/display_channel.h
index 7cdd55c..72856f5 100644
--- a/client/display_channel.h
+++ b/client/display_channel.h
@@ -19,9 +19,10 @@
 #ifndef _H_DISPLAY_CHANNEL
 #define _H_DISPLAY_CHANNEL
 
+#include "common/region.h"
+
 #include "common.h"
 #include "canvas.h"
-#include "region.h"
 #include "red_channel.h"
 #include "cache.hpp"
 #include "screen_layer.h"
diff --git a/client/glz_decoder.h b/client/glz_decoder.h
index a0352cc..0d505fd 100644
--- a/client/glz_decoder.h
+++ b/client/glz_decoder.h
@@ -19,7 +19,7 @@
 #ifndef _H_GLZ_DECODER
 #define _H_GLZ_DECODER
 
-#include "lz_common.h"
+#include "common/lz_common.h"
 #include "glz_decoder_config.h"
 #include "glz_decoder_window.h"
 #include "red_canvas_base.h"
diff --git a/client/glz_decoder_config.h b/client/glz_decoder_config.h
index 52fa52d..c15f012 100644
--- a/client/glz_decoder_config.h
+++ b/client/glz_decoder_config.h
@@ -20,13 +20,11 @@
 
 #include <exception>
 #include <sstream>
-
-#include "lz_common.h"
-
 #include <stdio.h>
 
 #include <spice/types.h>
 #include <spice/macros.h>
+#include "common/lz_common.h"
 
 class GlzException: public std::exception {
 public:
diff --git a/client/jpeg_decoder.h b/client/jpeg_decoder.h
index 8f7e1bb..ae76f50 100644
--- a/client/jpeg_decoder.h
+++ b/client/jpeg_decoder.h
@@ -30,6 +30,11 @@
 
 extern "C" {
 #include <jpeglib.h>
+#ifdef HAVE_STDLIB_H
+/* on mingw, there is a hack,
+  and we also include config.h from spice-common, which redefine it */
+#undef HAVE_STDLIB_H
+#endif
 }
 
 class RGBConverter {
diff --git a/client/marshallers.h b/client/marshallers.h
deleted file mode 100644
index 47faeff..0000000
--- a/client/marshallers.h
+++ /dev/null
@@ -1,63 +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
-
-#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);
-} SpiceMessageMarshallers;
-
-SpiceMessageMarshallers *spice_message_marshallers_get(void);
-SpiceMessageMarshallers *spice_message_marshallers_get1(void);
-
-#endif
diff --git a/client/monitor.h b/client/monitor.h
index b8d7c88..bbaaf17 100644
--- a/client/monitor.h
+++ b/client/monitor.h
@@ -18,7 +18,7 @@
 #ifndef _H_MONITOR
 #define _H_MONITOR
 
-#include "draw.h"
+#include "common/draw.h"
 
 class Monitor {
 public:
diff --git a/client/pixels_source.h b/client/pixels_source.h
index 1f4d196..55841a6 100644
--- a/client/pixels_source.h
+++ b/client/pixels_source.h
@@ -18,7 +18,7 @@
 #ifndef _H_PIXELS_SOURCE
 #define _H_PIXELS_SOURCE
 
-#include "draw.h"
+#include "common/draw.h"
 
 #define PIXELES_SOURCE_OPAQUE_SIZE (20 * sizeof(void*))
 
diff --git a/client/red_canvas_base.h b/client/red_canvas_base.h
index bd59109..1506055 100644
--- a/client/red_canvas_base.h
+++ b/client/red_canvas_base.h
@@ -19,7 +19,7 @@
 
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "canvas_base.h"
+#include "common/canvas_base.h"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
diff --git a/client/red_channel.h b/client/red_channel.h
index a839021..3cf5160 100644
--- a/client/red_channel.h
+++ b/client/red_channel.h
@@ -18,14 +18,15 @@
 #ifndef _H_REDCHANNEL
 #define _H_REDCHANNEL
 
+#include "common/client_demarshallers.h"
+#include "common/client_marshallers.h"
+
 #include "common.h"
 #include "utils.h"
 #include "threads.h"
 #include "red_peer.h"
 #include "platform.h"
 #include "process_loop.h"
-#include "demarshallers.h"
-#include "marshallers.h"
 
 enum {
     PASSIVE_STATE,
diff --git a/client/red_client.cpp b/client/red_client.cpp
index 0454408..8f86d3e 100644
--- a/client/red_client.cpp
+++ b/client/red_client.cpp
@@ -18,15 +18,16 @@
 #include <config.h>
 #endif
 
-#include "common.h"
+#include <algorithm>
 #include <math.h>
+#include "common/client_marshallers.h"
+
+#include "common.h"
 #include "red_client.h"
 #include "application.h"
 #include "process_loop.h"
 #include "utils.h"
 #include "debug.h"
-#include "marshallers.h"
-#include <algorithm>
 
 #ifndef INFINITY
 #define INFINITY HUGE
diff --git a/client/red_client.h b/client/red_client.h
index 577ccb7..a2f00c4 100644
--- a/client/red_client.h
+++ b/client/red_client.h
@@ -19,6 +19,7 @@
 #define _H_REDCLIENT
 
 #include <list>
+#include "common/messages.h"
 
 #include "common.h"
 #include "red_peer.h"
@@ -27,7 +28,6 @@
 #include "inputs_channel.h"
 #include "cursor_channel.h"
 #include "audio_channels.h"
-#include "messages.h"
 #include <spice/vd_agent.h>
 #include "process_loop.h"
 
diff --git a/client/red_drawable.h b/client/red_drawable.h
index 660ff4e..8ad3d4c 100644
--- a/client/red_drawable.h
+++ b/client/red_drawable.h
@@ -18,7 +18,7 @@
 #ifndef _H_RED_DRAWABLE
 #define _H_RED_DRAWABLE
 
-#include <pixman_utils.h>
+#include "common/pixman_utils.h"
 #include "pixels_source.h"
 #include "utils.h"
 
diff --git a/client/red_gdi_canvas.cpp b/client/red_gdi_canvas.cpp
index 2e42510..09a1553 100644
--- a/client/red_gdi_canvas.cpp
+++ b/client/red_gdi_canvas.cpp
@@ -21,20 +21,24 @@
 #include <config.h>
 #endif
 
-#include "common.h"
+#ifdef WIN32
+#include <winsock2.h>
+#endif
 #include <stdint.h>
-#include "red_gdi_canvas.h"
-#include "utils.h"
-#include "debug.h"
-#include "region.h"
-#include "red_pixmap_gdi.h"
 
+#include "common/region.h"
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "gdi_canvas.c"
+#include "common/gdi_canvas.c"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
+#include "common.h"
+#include "red_gdi_canvas.h"
+#include "utils.h"
+#include "debug.h"
+#include "red_pixmap_gdi.h"
+
 GDICanvas::GDICanvas(int width, int height, uint32_t format,
 		     PixmapCache& pixmap_cache, PaletteCache& palette_cache,
                      GlzDecoderWindow &glz_decoder_window, SurfacesCache &csurfaces)
diff --git a/client/red_gdi_canvas.h b/client/red_gdi_canvas.h
index 77adcf7..dbebe33 100644
--- a/client/red_gdi_canvas.h
+++ b/client/red_gdi_canvas.h
@@ -21,7 +21,7 @@
 #include "canvas.h"
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "gdi_canvas.h"
+#include "common/gdi_canvas.h"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 #include "red_pixmap_gdi.h"
diff --git a/client/red_gl_canvas.cpp b/client/red_gl_canvas.cpp
index 59c8f06..81203d9 100644
--- a/client/red_gl_canvas.cpp
+++ b/client/red_gl_canvas.cpp
@@ -18,21 +18,22 @@
 #include <config.h>
 #endif
 
-#include "common.h"
 #include <stdint.h>
-#include "red_gl_canvas.h"
-#include "utils.h"
-#include "debug.h"
-#include "region.h"
-#include "red_pixmap_gl.h"
 #include <GL/glx.h>
+#include "common/region.h"
 
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "gl_canvas.c"
+#include "common/gl_canvas.c"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
+#include "common.h"
+#include "red_gl_canvas.h"
+#include "utils.h"
+#include "debug.h"
+#include "red_pixmap_gl.h"
+
 GCanvas::GCanvas(int width, int height, uint32_t format, RedWindow *win,
                  RenderType rendertype,
                  PixmapCache& pixmap_cache, PaletteCache& palette_cache,
diff --git a/client/red_gl_canvas.h b/client/red_gl_canvas.h
index a57ea48..e78b1cc 100644
--- a/client/red_gl_canvas.h
+++ b/client/red_gl_canvas.h
@@ -21,8 +21,8 @@
 #include "canvas.h"
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "sw_canvas.h"
-#include "gl_canvas.h"
+#include "common/sw_canvas.h"
+#include "common/gl_canvas.h"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
diff --git a/client/red_peer.cpp b/client/red_peer.cpp
index 17fcb45..64e43d5 100644
--- a/client/red_peer.cpp
+++ b/client/red_peer.cpp
@@ -19,15 +19,19 @@
 #include <config.h>
 #endif
 
-#include "common.h"
+#ifdef WIN32
+#include <winsock2.h>
+#endif
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <spice/protocol.h>
+#include "common/ssl_verify.h"
+
+#include "common.h"
 #include "red_peer.h"
 #include "utils.h"
 #include "debug.h"
 #include "platform_utils.h"
-#include "ssl_verify.h"
 
 static void ssl_error()
 {
diff --git a/client/red_peer.h b/client/red_peer.h
index 5e2b2b9..b0faa9d 100644
--- a/client/red_peer.h
+++ b/client/red_peer.h
@@ -21,14 +21,15 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
-#include "common.h"
 #include <spice/protocol.h>
+#include "common/marshaller.h"
+#include "common/ssl_verify.h"
+
+#include "common.h"
 #include "process_loop.h"
 #include "threads.h"
 #include "platform_utils.h"
-#include "marshaller.h"
 #include "debug.h"
-#include "ssl_verify.h"
 
 class RedPeer: protected EventSources::Socket {
 public:
diff --git a/client/red_sw_canvas.cpp b/client/red_sw_canvas.cpp
index 5f86dca..d18af0f 100644
--- a/client/red_sw_canvas.cpp
+++ b/client/red_sw_canvas.cpp
@@ -19,21 +19,25 @@
 #include <config.h>
 #endif
 
-#include "common.h"
 #include <stdint.h>
-#include "red_window.h"
-#include "red_sw_canvas.h"
-#include "utils.h"
-#include "debug.h"
-#include "region.h"
-#include "red_pixmap_sw.h"
+#ifdef WIN32
+#include <winsock2.h>
+#endif
 
+#include "common/region.h"
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "sw_canvas.c"
+#include "common/sw_canvas.c"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
+#include "common.h"
+#include "red_window.h"
+#include "red_sw_canvas.h"
+#include "utils.h"
+#include "debug.h"
+#include "red_pixmap_sw.h"
+
 SCanvas::SCanvas(bool onscreen,
                  int width, int height, uint32_t format, RedWindow *win,
                  PixmapCache& pixmap_cache, PaletteCache& palette_cache,
diff --git a/client/red_sw_canvas.h b/client/red_sw_canvas.h
index eb577ac..a192c47 100644
--- a/client/red_sw_canvas.h
+++ b/client/red_sw_canvas.h
@@ -22,7 +22,7 @@
 #include "canvas.h"
 #define SPICE_CANVAS_INTERNAL
 #define SW_CANVAS_CACHE
-#include "sw_canvas.h"
+#include "common/sw_canvas.h"
 #undef SW_CANVAS_CACHE
 #undef SPICE_CANVAS_INTERNAL
 
diff --git a/client/screen.h b/client/screen.h
index d7bb4c2..4093006 100644
--- a/client/screen.h
+++ b/client/screen.h
@@ -18,8 +18,9 @@
 #ifndef _H_SCREEN
 #define _H_SCREEN
 
+#include "common/region.h"
+
 #include "common.h"
-#include "region.h"
 #include "red_key.h"
 #ifdef USE_OPENGL
 #include "GL/gl.h"
diff --git a/client/screen_layer.h b/client/screen_layer.h
index e8ad421..1168b24 100644
--- a/client/screen_layer.h
+++ b/client/screen_layer.h
@@ -18,8 +18,8 @@
 #ifndef _H_SCREEN_LAYER
 #define _H_SCREEN_LAYER
 
+#include "common/region.h"
 #include "threads.h"
-#include "region.h"
 
 class RedScreen;
 class Application;
diff --git a/client/smartcard_channel.cpp b/client/smartcard_channel.cpp
index 09659c2..720b879 100644
--- a/client/smartcard_channel.cpp
+++ b/client/smartcard_channel.cpp
@@ -19,9 +19,9 @@
 #endif
 
 #include <spice/enums.h>
+#include "common/mutex.h"
 
 #include "red_client.h"
-#include "mutex.h"
 
 extern "C" {
 #include <vscard_common.h>
diff --git a/client/x11/pixels_source_p.h b/client/x11/pixels_source_p.h
index 000fe4d..64b0c50 100644
--- a/client/x11/pixels_source_p.h
+++ b/client/x11/pixels_source_p.h
@@ -29,7 +29,8 @@
 #ifdef USE_OPENGL
 #include "red_pixmap_gl.h"
 #endif // USE_OPENGL
-#include "pixman_utils.h"
+
+#include "common/pixman_utils.h"
 
 enum {
     PIXELS_SOURCE_TYPE_INVALID,
diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp
index f535d6d..f35d537 100644
--- a/client/x11/platform.cpp
+++ b/client/x11/platform.cpp
@@ -48,20 +48,21 @@
 #include <sys/time.h>
 #endif
 
+#include <spice/vd_agent.h>
+#include "common/rect.h"
+
 #include "platform.h"
 #include "application.h"
 #include "utils.h"
 #include "x_platform.h"
 #include "debug.h"
 #include "monitor.h"
-#include "rect.h"
 #include "record.h"
 #include "playback.h"
 #include "resource.h"
 #include "res.h"
 #include "cursor.h"
 #include "process_loop.h"
-#include <spice/vd_agent.h>
 
 #define DWORD uint32_t
 #define BOOL bool
diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp
index fd5d4a1..bb8ceb4 100644
--- a/client/x11/red_drawable.cpp
+++ b/client/x11/red_drawable.cpp
@@ -26,7 +26,7 @@
 #include "utils.h"
 
 #ifdef USE_OPENGL
-#include "gl_utils.h"
+#include "common/gl_utils.h"
 #include <GL/gl.h>
 #include <GL/glu.h>
 #include <GL/glext.h>
diff --git a/client/x11/red_pixmap_gl.cpp b/client/x11/red_pixmap_gl.cpp
index 1e1e6e0..8d81c31 100644
--- a/client/x11/red_pixmap_gl.cpp
+++ b/client/x11/red_pixmap_gl.cpp
@@ -22,12 +22,12 @@
 #include <GL/glu.h>
 #include <GL/glext.h>
 #include <X11/Xlib.h>
+#include "common/gl_utils.h"
 
 #include "common.h"
 #include "red_pixmap_gl.h"
 #include "debug.h"
 #include "utils.h"
-#include "gl_utils.h"
 #include "pixels_source_p.h"
 #include "x_platform.h"
 #include "red_window_p.h"
diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp
index fda90d5..83144a5 100644
--- a/client/x11/red_window.cpp
+++ b/client/x11/red_window.cpp
@@ -33,21 +33,22 @@
 #endif // USE_OPENGL
 #include <stdio.h>
 
+#include <spice/protocol.h>
+#include "common/region.h"
+
+#ifdef USE_OPENGL
+#include "common/gl_utils.h"
+#include "red_pixmap_gl.h"
+#endif // USE_OPENGL
+
 #include "red_window.h"
 #include "utils.h"
 #include "debug.h"
 #include "platform.h"
 #include "x_platform.h"
 #include "pixels_source_p.h"
-#include <spice/protocol.h>
-#include "region.h"
-#ifdef USE_OPENGL
-#include "gl_utils.h"
-#include "red_pixmap_gl.h"
-#endif // USE_OPENGL
 #include "x_icon.h"
 
-
 #define X_RETRIES 10
 #define X_RETRY_DELAY_MICRO (1000 * 100)
 #define RAISE_RETRIES X_RETRIES
diff --git a/common/.gitignore b/common/.gitignore
deleted file mode 100644
index d033f47..0000000
--- a/common/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-*.la
-*.lo
-*.loT
-*.o
-.deps
-.dirstamp
-.libs
-Makefile
-Makefile.in
diff --git a/common/Makefile.am b/common/Makefile.am
deleted file mode 100644
index 4189dc1..0000000
--- a/common/Makefile.am
+++ /dev/null
@@ -1,76 +0,0 @@
-if OS_WIN32
-SUBDIRS = win
-endif
-
-NULL =
-
-noinst_LTLIBRARIES = libspice-common.la
-libspice_common_la_SOURCES =		\
-	bitops.h			\
-	canvas_utils.c			\
-	canvas_utils.h			\
-	draw.h				\
-	lines.c				\
-	lines.h				\
-	lz.c				\
-	lz.h				\
-	lz_common.h			\
-	lz_config.h			\
-	marshaller.c			\
-	marshaller.h			\
-	mem.c				\
-	mem.h				\
-	messages.h			\
-	mutex.h				\
-	pixman_utils.c			\
-	pixman_utils.h			\
-	quic.c				\
-	quic.h				\
-	quic_config.h			\
-	rect.h				\
-	region.c			\
-	region.h			\
-	ring.h				\
-	rop3.c				\
-	rop3.h				\
-	spice_common.h			\
-	ssl_verify.c			\
-	ssl_verify.h			\
-	backtrace.c			\
-	backtrace.h			\
-	$(NULL)
-
-if SUPPORT_GL
-libspice_common_la_SOURCES +=		\
-	gl_utils.h			\
-	glc.h				\
-	glc.c				\
-	ogl_ctx.h			\
-	ogl_ctx.c			\
-	$(NULL)
-endif
-
-INCLUDES = \
-	$(GL_CFLAGS)			\
-	$(PIXMAN_CFLAGS)		\
-	$(PROTOCOL_CFLAGS)		\
-	$(VISIBILITY_HIDDEN_CFLAGS)	\
-	$(WARN_CFLAGS)			\
-	-std=gnu99			\
-	$(NULL)
-
-EXTRA_DIST =				\
-	canvas_base.c			\
-	canvas_base.h			\
-	gdi_canvas.c			\
-	gdi_canvas.h			\
-	gl_canvas.c			\
-	gl_canvas.h			\
-	sw_canvas.c			\
-	sw_canvas.h			\
-	lz_compress_tmpl.c		\
-	lz_decompress_tmpl.c		\
-	quic_family_tmpl.c		\
-	quic_rgb_tmpl.c			\
-	quic_tmpl.c			\
-	$(NULL)
diff --git a/common/backtrace.c b/common/backtrace.c
deleted file mode 100644
index c8f4626..0000000
--- a/common/backtrace.c
+++ /dev/null
@@ -1,133 +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/>.
-*/
-
-/*
- * Taken from xserver os/backtrace.c:
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#include <config.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#ifndef __MINGW32__
-#include <sys/wait.h>
-#endif
-
-#include "spice_common.h"
-
-#define GSTACK_PATH "/usr/bin/gstack"
-
-#if HAVE_EXECINFO_H
-#include <execinfo.h>
-
-static void spice_backtrace_backtrace(void)
-{
-    void *array[100];
-    int size;
-
-    size = backtrace(array, sizeof(array)/sizeof(array[0]));
-    backtrace_symbols_fd(array, size, STDERR_FILENO);
-}
-#else
-static void spice_backtrace_backtrace(void)
-{
-}
-#endif
-
-/* XXX perhaps gstack can be available in windows but pipe/waitpid isn't,
- * so until it is ported properly just compile it out, we lose the
- * backtrace only. */
-#ifndef __MINGW32__
-static int spice_backtrace_gstack(void)
-{
-    pid_t kidpid;
-    int pipefd[2];
-
-    if (pipe(pipefd) != 0) {
-        return -1;
-    }
-
-    kidpid = fork();
-
-    if (kidpid == -1) {
-        /* ERROR */
-        return -1;
-    } else if (kidpid == 0) {
-        /* CHILD */
-        char parent[16];
-
-        seteuid(0);
-        close(STDIN_FILENO);
-        close(STDOUT_FILENO);
-        dup2(pipefd[1],STDOUT_FILENO);
-        close(STDERR_FILENO);
-
-        snprintf(parent, sizeof(parent), "%d", getppid());
-        execle(GSTACK_PATH, "gstack", parent, NULL, NULL);
-        exit(1);
-    } else {
-        /* PARENT */
-        char btline[256];
-        int kidstat;
-        int bytesread;
-        int done = 0;
-
-        close(pipefd[1]);
-
-        while (!done) {
-            bytesread = read(pipefd[0], btline, sizeof(btline) - 1);
-
-            if (bytesread > 0) {
-                btline[bytesread] = 0;
-                fprintf(stderr, "%s", btline);
-            }
-            else if ((bytesread == 0) ||
-                     ((errno != EINTR) && (errno != EAGAIN))) {
-                done = 1;
-            }
-        }
-        close(pipefd[0]);
-        waitpid(kidpid, &kidstat, 0);
-        if (kidstat != 0)
-            return -1;
-    }
-    return 0;
-}
-#else
-static int spice_backtrace_gstack(void)
-{
-    /* empty failing implementation */
-    return -1;
-}
-#endif
-
-void spice_backtrace(void)
-{
-    int ret = -1;
-
-    if (!access(GSTACK_PATH, X_OK)) {
-        ret = spice_backtrace_gstack();
-    }
-    if (ret != 0) {
-        spice_backtrace_backtrace();
-    }
-}
diff --git a/common/backtrace.h b/common/backtrace.h
deleted file mode 100644
index 894c027..0000000
--- a/common/backtrace.h
+++ /dev/null
@@ -1,34 +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 BACKTRACE_H
-#define BACKTRACE_H
-
-#include <spice/macros.h>
-
-SPICE_BEGIN_DECLS
-
-#if defined(WIN32) && !defined(__MINGW32__)
-#define spice_backtrace()
-#else
-void spice_backtrace(void);
-#endif
-
-SPICE_END_DECLS
-
-#endif // BACKTRACE_H
diff --git a/common/bitops.h b/common/bitops.h
deleted file mode 100644
index bdd862a..0000000
--- a/common/bitops.h
+++ /dev/null
@@ -1,91 +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 BITOPS_H
-#define BITOPS_H
-
-#include <spice/macros.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-static inline int spice_bit_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;
-}
-
-#elif defined(WIN32) && !defined(_WIN64)
-static INLINE int spice_bit_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 spice_bit_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 spice_bit_next_pow2(unsigned int val)
-{
-    if ((val & (val - 1)) == 0) {
-        return val;
-    }
-    return 1 << spice_bit_find_msb(val);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/canvas_base.c b/common/canvas_base.c
deleted file mode 100644
index c4203dd..0000000
--- a/common/canvas_base.c
+++ /dev/null
@@ -1,3394 +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 SPICE_CANVAS_INTERNAL
-#error "This file shouldn't be compiled directly"
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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 CANVAS_ERROR
-#define CANVAS_ERROR(format, ...) {                             \
-    printf("%s: " format "\n", __FUNCTION__, ## __VA_ARGS__);   \
-    abort();                                                    \
-}
-#endif
-
-#ifndef WARN
-#define WARN(x) printf("warning: %s\n", x)
-#endif
-
-#ifndef DBG
-#define DBG(level, format, ...) printf("%s: debug: " format "\n", __FUNCTION__, ## __VA_ARGS__);
-#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);
-    if (!dc) {
-        CANVAS_ERROR("create compatible DC failed");
-    }
-    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);
-        CANVAS_ERROR("quic error, %s", quic_data->message_buf);
-    }
-
-    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) {
-        CANVAS_ERROR("quic decode begin failed");
-    }
-
-   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:
-        CANVAS_ERROR("unexpected image type");
-    }
-
-    ASSERT((uint32_t)width == image->descriptor.width);
-    ASSERT((uint32_t)height == image->descriptor.height);
-
-    surface = surface_create(
-#ifdef WIN32
-                             canvas->dc,
-#endif
-                             pixman_format,
-                             width, height, FALSE);
-
-    if (surface == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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);
-        CANVAS_ERROR("quic decode failed");
-    }
-
-    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;
-
-    ASSERT(image->u.jpeg.data->num_chunks == 1); /* TODO: Handle chunks */
-    canvas->jpeg->ops->begin_decode(canvas->jpeg, image->u.jpeg.data->chunk[0].data, image->u.jpeg.data->chunk[0].len,
-                                    &width, &height);
-    ASSERT((uint32_t)width == image->descriptor.width);
-    ASSERT((uint32_t)height == image->descriptor.height);
-
-    surface = surface_create(
-#ifdef WIN32
-                             canvas->dc,
-#endif
-                             PIXMAN_x8r8g8b8,
-                             width, height, FALSE);
-    if (surface == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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;
-
-    ASSERT(image->u.jpeg_alpha.data->num_chunks == 1);
-    canvas->jpeg->ops->begin_decode(canvas->jpeg,
-                                    image->u.jpeg_alpha.data->chunk[0].data,
-                                    image->u.jpeg_alpha.jpeg_size,
-                                    &width, &height);
-    ASSERT((uint32_t)width == image->descriptor.width);
-    ASSERT((uint32_t)height == image->descriptor.height);
-
-    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) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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);
-    ASSERT(lz_alpha_type == LZ_IMAGE_TYPE_XXXA);
-    ASSERT(!!lz_alpha_top_down == !!alpha_top_down);
-    ASSERT(lz_alpha_width == width);
-    ASSERT(lz_alpha_height == height);
-    ASSERT(n_comp_pixels == width * height);
-
-    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) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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:
-        PANIC("Unsupported palette depth");
-    }
-    *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)) {
-        free(decomp_buf);
-        CANVAS_ERROR("lz error, %s", lz_data->message_buf);
-    }
-
-    free_palette = FALSE;
-    if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB) {
-        ASSERT(image->u.lz_rgb.data->num_chunks == 1); /* 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) {
-        ASSERT(image->u.lz_plt.data->num_chunks == 1); /* 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 {
-        CANVAS_ERROR("unexpected image type");
-    }
-
-    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:
-        CANVAS_ERROR("unexpected LZ image type");
-    }
-
-    ASSERT((unsigned)width == image->descriptor.width);
-    ASSERT((unsigned)height == image->descriptor.height);
-
-    ASSERT((image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) || (n_comp_pixels == width * height));
-#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)
-{
-    if (canvas->glz_data.decoder == NULL) {
-        CANVAS_ERROR("glz not supported");
-    }
-
-    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)
-{
-    ASSERT(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB);
-#ifdef WIN32
-    canvas->glz_data.decode_data.dc = canvas->dc;
-#endif
-
-    ASSERT(image->u.lz_rgb.data->num_chunks == 1); /* 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;
-
-    if (canvas->zlib == NULL) {
-        CANVAS_ERROR("zlib not supported");
-    }
-
-    ASSERT(image->u.zlib_glz.data->num_chunks == 1); /* 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;
-#ifdef DEBUG_LZ
-    LOG_DEBUG("canvas_get_image image type: " << (int)descriptor->type);
-#endif
-
-    /* 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:
-        CANVAS_ERROR("invalid image type");
-    }
-
-    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)) {
-            CANVAS_ERROR("invalid cache replace request: the image is lossy");
-        }
-        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:
-        CANVAS_ERROR("invalid image type");
-    }
-}
-
-#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);
-    if (surface == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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);
-    if (surface == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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
-        ASSERT(bitmap->y > 0);
-        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;
-            CANVAS_ERROR("invalid bitmap format");
-        }
-    } 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;
-            CANVAS_ERROR("invalid bitmap format");
-        }
-    }
-    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;
-
-    ASSERT(pixman_image_get_depth(src_surf) == 1);
-
-    invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
-    if (invers == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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:
-        CANVAS_ERROR("invalid image type");
-    }
-
-#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)
-{
-    ASSERT(r);
-    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);
-    ASSERT(glyph_box.top >= bounds->top && glyph_box.bottom <= bounds->bottom);
-    ASSERT(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:
-        CANVAS_ERROR("invalid bpp");
-    }
-}
-
-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;
-
-    ASSERT(str->length > 0);
-
-    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);
-    if (str_mask == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-    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);
-    if (surface == NULL) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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);
-    ASSERT(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, 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;
-}
-
-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);
-}
-
-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);
-}
-
-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);
-}
-
-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:
-        CANVAS_ERROR("invalid clip type");
-    }
-}
-
-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);
-            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:
-        CANVAS_ERROR("invalid brush type");
-    }
-}
-
-/* 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);
-        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);
-        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);
-        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);
-
-        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);
-        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:
-        CANVAS_ERROR("invalid brush type");
-    }
-
-    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) {
-            ASSERT((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);
-
-    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) {
-        CANVAS_ERROR("bad src bitmap size");
-    }
-    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)
-{
-    PANIC("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 861171e..0000000
--- a/common/canvas_base.h
+++ /dev/null
@@ -1,327 +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
-
-#ifndef SPICE_CANVAS_INTERNAL
-#error "This header shouldn't be included directly"
-#endif
-
-#include "pixman_utils.h"
-#include "lz.h"
-#include "region.h"
-#include "draw.h"
-#ifdef WIN32
-#include <windows.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#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;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/canvas_utils.c b/common/canvas_utils.c
deleted file mode 100644
index 6632942..0000000
--- a/common/canvas_utils.c
+++ /dev/null
@@ -1,299 +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 HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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 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
-    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 16ada45..0000000
--- a/common/canvas_utils.h
+++ /dev/null
@@ -1,80 +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"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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);
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/draw.h b/common/draw.h
deleted file mode 100644
index 8b1206d..0000000
--- a/common/draw.h
+++ /dev/null
@@ -1,281 +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"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SPICE_GET_ADDRESS(addr) ((void *)(uintptr_t)(addr))
-#define SPICE_SET_ADDRESS(addr, val) ((addr) = (uintptr_t)(val))
-
-typedef int32_t SPICE_FIXED28_4;
-
-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;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _H_SPICE_DRAW */
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
deleted file mode 100644
index d3e9c7f..0000000
--- a/common/gdi_canvas.c
+++ /dev/null
@@ -1,1858 +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 HAVE_CONFIG_H
-#ifdef __MINGW32__
-#undef HAVE_STDLIB_H
-#endif
-#include <config.h>
-#endif
-
-#ifndef SPICE_CANVAS_INTERNAL
-#error "This file shouldn't be compiled directly"
-#endif
-
-#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)) {
-                CANVAS_ERROR("MoveToEx failed");
-                return;
-            }
-            point++;
-        }
-
-        if (seg->flags & SPICE_PATH_BEZIER) {
-            ASSERT((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)) {
-                    CANVAS_ERROR("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))) {
-                    CANVAS_ERROR("LineTo failed");
-                }
-            }
-        }
-
-        if (seg->flags & SPICE_PATH_END) {
-
-            if (seg->flags & SPICE_PATH_CLOSE) {
-                if (!CloseFigure(canvas->dc)) {
-                    CANVAS_ERROR("CloseFigure failed");
-                }
-            }
-
-            if (!EndPath(canvas->dc)) {
-                CANVAS_ERROR("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 {
-        CANVAS_ERROR("Unknown ScaleMode");
-    }
-}
-
-static void set_clip(GdiCanvas *canvas, SpiceClip *clip)
-{
-    switch (clip->type) {
-    case SPICE_CLIP_TYPE_NONE:
-        if (SelectClipRgn(canvas->dc, NULL) == ERROR) {
-            CANVAS_ERROR("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) {
-                    CANVAS_ERROR("Unable to CreateRectRgn");
-                    DeleteObject(main_hrgn);
-                    return;
-                }
-                if (CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR) == ERROR) {
-                    CANVAS_ERROR("Unable to CombineRgn");
-                    DeleteObject(combaine_hrgn);
-                    return;
-                }
-                DeleteObject(combaine_hrgn);
-            }
-            if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
-                CANVAS_ERROR("Unable to SelectClipRgn");
-            }
-            DeleteObject(main_hrgn);
-        }
-        break;
-    }
-    default:
-        CANVAS_ERROR("invalid clip type");
-    }
-}
-
-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;
-
-    ASSERT(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;
-
-    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) {
-        CANVAS_ERROR("create_compatible_dc() failed");
-        return NULL;
-    }
-
-    *bitmap = CreateDIBSection(*dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
-    if (!*bitmap) {
-        CANVAS_ERROR("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:
-        CANVAS_ERROR("invalid bitmap bits size");
-    }
-
-    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)))) {
-            CANVAS_ERROR("CreateSolidBrush failed");
-        }
-        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) {
-                CANVAS_ERROR("GetCurrentObject failed");
-            }
-            *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)) {
-                CANVAS_ERROR("create_bitmap failed");
-                return NULL;
-            }
-        }
-
-        if (!(hbrush = CreatePatternBrush(bitmap))) {
-            CANVAS_ERROR("CreatePatternBrush failed");
-        }
-
-        if (!gdi_surface) {
-            release_bitmap(dc, bitmap, prev_bitmap, 0);
-            pixman_image_unref(surface);
-        }
-        return hbrush;
-    }
-    case SPICE_BRUSH_TYPE_NONE:
-        return NULL;
-    default:
-        CANVAS_ERROR("invalid brush type");
-        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)) {
-            CANVAS_ERROR("SetBrushOrgEx failed");
-        }
-        return prev_hbrush;
-    }
-    default:
-        CANVAS_ERROR("invalid brush type");
-        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) {
-        CANVAS_ERROR("invalid rop3 type");
-    }
-    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) {
-            CANVAS_ERROR ("GetCurrentObject failed");
-        }
-        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)) {
-                CANVAS_ERROR("BitBlt failed");
-            }
-        } 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)) {
-                CANVAS_ERROR("StretchBlt failed");
-            }
-        }
-    } 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)) {
-            CANVAS_ERROR("MaskBlt failed");
-        }
-    }
-}
-
-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))) {
-        CANVAS_ERROR("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:
-        CANVAS_ERROR("unsupported bitmap bits size");
-    }
-    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);
-
-    if (!(brush = get_brush(canvas, &fill->brush, &brush_lock))) {
-        CANVAS_ERROR("no braash");
-        return;
-    }
-
-    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) {
-                    CANVAS_ERROR("CreateRectRgn failed");
-                    DeleteObject(main_hrgn);
-                    return;
-                }
-                if (!CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR)) {
-                    CANVAS_ERROR("CombineRgn failed in put_image");
-                    return;
-                }
-                DeleteObject(combaine_hrgn);
-            }
-            if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
-                CANVAS_ERROR("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)) {
-        CANVAS_ERROR("AlphaBlend failed");
-    }
-}
-
-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) {
-        WARN("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 {
-        WARN("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)
-{
-    uint32_t *local_style;
-    int i;
-
-    if (nseg == 0) {
-        CANVAS_ERROR("bad nseg");
-    }
-    local_style = spice_new(uint32_t , nseg);
-
-    if (start_is_gap) {
-        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
-        //CANVAS_ERROR("untested path stroke brush with pattern");
-#if 0
-        ASSERT(surface)
-        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) {
-                CANVAS_ERROR("GlobalAlloc failed");
-            }
-            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) {
-                CANVAS_ERROR("GlobalAlloc failed");
-            }
-            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
-
-    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;
-
-    if (need_init) {
-        return NULL;
-    }
-    canvas = spice_new0(GdiCanvas, 1);
-    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(void) //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 f92c042..0000000
--- a/common/gdi_canvas.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 _H__GDI_CANVAS
-#define _H__GDI_CANVAS
-
-#ifndef SPICE_CANVAS_INTERNAL
-#error "This header shouldn't be included directly"
-#endif
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
deleted file mode 100644
index ffc6b52..0000000
--- a/common/gl_canvas.c
+++ /dev/null
@@ -1,906 +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 HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef SPICE_CANVAS_INTERNAL
-#error "This file shouldn't be compiled directly"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.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) {
-        CANVAS_ERROR("create surface failed");
-    }
-
-    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) {
-            ASSERT((point - end_point) % 3 == 0);
-            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:
-        CANVAS_ERROR("invalid clip type");
-    }
-}
-
-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);
-
-    ASSERT(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:
-        CANVAS_ERROR("invalid brush type");
-    }
-}
-
-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:
-        WARN("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) {
-        CANVAS_ERROR("create surface failed");
-    }
-    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) {
-        CANVAS_ERROR("bad src bitmap size");
-    }
-
-    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) {
-        WARN("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) {
-        WARN("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 {
-        WARN("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;
-
-    ASSERT(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;
-
-    ASSERT(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);
-    free(canvas->private_data);
-    free(canvas);
-}
-
-void gl_canvas_init(void) //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 400bedb..0000000
--- a/common/gl_canvas.h
+++ /dev/null
@@ -1,53 +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"
-
-#ifndef SPICE_CANVAS_INTERNAL
-#error "This header shouldn't be included directly"
-#endif
-
-#ifndef _H__GL_CANVAS
-#define _H__GL_CANVAS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/gl_utils.h b/common/gl_utils.h
deleted file mode 100644
index c30be16..0000000
--- a/common/gl_utils.h
+++ /dev/null
@@ -1,61 +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 __cplusplus
-extern "C" {
-#endif
-
-#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
-
-#include "bitops.h"
-
-#define find_msb spice_bit_find_msb
-#define gl_get_to_power_two spice_bit_next_pow2
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/glc.c b/common/glc.c
deleted file mode 100644
index 1414bcf..0000000
--- a/common/glc.c
+++ /dev/null
@@ -1,1513 +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
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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"
-#include "spice_common.h"
-
-#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)
-{
-    if (ctx->path_stroke.state == GLC_STROKE_ACTIVE) {
-        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.h b/common/glc.h
deleted file mode 100644
index d77f003..0000000
--- a/common/glc.h
+++ /dev/null
@@ -1,167 +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>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/lines.c b/common/lines.c
deleted file mode 100644
index 797d5d6..0000000
--- a/common/lines.c
+++ /dev/null
@@ -1,3613 +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.
-
-******************************************************************/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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 = xrealloc (spans->points,
-                                                  (spans->count +
-                                                   EXTRA) * sizeof (DDXPointRec));
-                                if (!newPt)
-                                    break;
-                                spansPt = newPt + (spansPt - spans->points);
-                                spans->points = newPt;
-                                newwid = 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 =
-                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)
-{
-    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) {
-            xfree (yspans);
-            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 = xrealloc (newspans->points,
-                                              ysizes[index] * sizeof (DDXPointRec));
-                        newwidths = 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);
-            xfree (points);
-            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)
-        goto out;
-
-    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);
-
-out:
-    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 73eef9b..0000000
--- a/common/lines.h
+++ /dev/null
@@ -1,138 +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"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LINES_H */
diff --git a/common/lz.c b/common/lz.c
deleted file mode 100644
index 5f51794..0000000
--- a/common/lz.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright (C) 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.
-
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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 472e34d..0000000
--- a/common/lz.h
+++ /dev/null
@@ -1,82 +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"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *LzContext;
-
-typedef struct LzUsrContext LzUsrContext;
-struct LzUsrContext {
-    void (*error)(LzUsrContext *usr, const char *fmt, ...);
-    void (*warn)(LzUsrContext *usr, const char *fmt, ...);
-    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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // __LZ_H
diff --git a/common/lz_common.h b/common/lz_common.h
deleted file mode 100644
index 4156cff..0000000
--- a/common/lz_common.h
+++ /dev/null
@@ -1,69 +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
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//#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))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // _LZ_COMMON_H
diff --git a/common/lz_compress_tmpl.c b/common/lz_compress_tmpl.c
deleted file mode 100644
index 6db5387..0000000
--- a/common/lz_compress_tmpl.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright (C) 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.
-
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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 d8675a8..0000000
--- a/common/lz_config.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, 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>
-#else
-#ifdef QXLDD
-#include <windef.h>
-#include "os_dep.h"
-#else
-#include <stddef.h>
-#include <string.h>
-#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 b0cbb2a..0000000
--- a/common/lz_decompress_tmpl.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-
- Copyright (C) 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.
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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/marshaller.c b/common/marshaller.c
deleted file mode 100644
index 9023d08..0000000
--- a/common/marshaller.c
+++ /dev/null
@@ -1,615 +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/>.
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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, 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;
-}
-
-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 = (void *)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 0a61fef..0000000
--- a/common/marshaller.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_MARSHALLER
-#define _H_MARSHALLER
-
-#include <spice/types.h>
-#include "mem.h"
-#ifndef WIN32
-#include <sys/uio.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#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, 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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/mem.c b/common/mem.c
deleted file mode 100644
index 5298e37..0000000
--- a/common/mem.c
+++ /dev/null
@@ -1,297 +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/>.
-*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#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);
-    }
-
-    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;
-    }
-}
-
-void spice_buffer_reserve(SpiceBuffer *buffer, size_t len)
-{
-    if ((buffer->capacity - buffer->offset) < len) {
-        buffer->capacity += (len + 1024);
-        buffer->buffer = (uint8_t*)spice_realloc(buffer->buffer, buffer->capacity);
-    }
-}
-
-int spice_buffer_empty(SpiceBuffer *buffer)
-{
-    return buffer->offset == 0;
-}
-
-uint8_t *spice_buffer_end(SpiceBuffer *buffer)
-{
-    return buffer->buffer + buffer->offset;
-}
-
-void spice_buffer_reset(SpiceBuffer *buffer)
-{
-    buffer->offset = 0;
-}
-
-void spice_buffer_free(SpiceBuffer *buffer)
-{
-    free(buffer->buffer);
-    buffer->offset = 0;
-    buffer->capacity = 0;
-    buffer->buffer = NULL;
-}
-
-void spice_buffer_append(SpiceBuffer *buffer, const void *data, size_t len)
-{
-    spice_buffer_reserve(buffer, len);
-    memcpy(buffer->buffer + buffer->offset, data, len);
-    buffer->offset += len;
-}
-
-size_t spice_buffer_copy(SpiceBuffer *buffer, void *dest, size_t len)
-{
-    len = MIN(buffer->offset, len);
-    memcpy(dest, buffer->buffer, len);
-    return len;
-}
-
-size_t spice_buffer_remove(SpiceBuffer *buffer, size_t len)
-{
-    len = MIN(buffer->offset, len);
-    memmove(buffer->buffer, buffer->buffer + len, buffer->offset - len);
-    buffer->offset -= len;
-    return len;
-}
diff --git a/common/mem.h b/common/mem.h
deleted file mode 100644
index af89ba6..0000000
--- a/common/mem.h
+++ /dev/null
@@ -1,162 +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>
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#elif defined __GNUC__
-#if !defined alloca
-# define alloca __builtin_alloca
-#endif
-#elif defined _AIX
-# define alloca __alloca
-#elif defined _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-#else
-# ifndef HAVE_ALLOCA
-#  ifdef  __cplusplus
-extern "C"
-#  endif
-void *alloca (size_t);
-# endif
-#endif
-
-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;
-
-typedef struct SpiceBuffer
-{
-    size_t capacity;
-    size_t offset;
-    uint8_t *buffer;
-} SpiceBuffer;
-
-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)
-
-/* Buffer management */
-void spice_buffer_reserve(SpiceBuffer *buffer, size_t len);
-int spice_buffer_empty(SpiceBuffer *buffer);
-uint8_t *spice_buffer_end(SpiceBuffer *buffer);
-void spice_buffer_reset(SpiceBuffer *buffer);
-void spice_buffer_free(SpiceBuffer *buffer);
-void spice_buffer_append(SpiceBuffer *buffer, const void *data, size_t len);
-size_t spice_buffer_copy(SpiceBuffer *buffer, void *dest, size_t len);
-size_t spice_buffer_remove(SpiceBuffer *buffer, size_t len);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/common/messages.h b/common/messages.h
deleted file mode 100644
index ec58da5..0000000
--- a/common/messages.h
+++ /dev/null
@@ -1,525 +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
-
-#include <spice/protocol.h>
-#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 __cplusplus
-}
-#endif
-
-#endif /* _H_SPICE_PROTOCOL */
diff --git a/common/mutex.h b/common/mutex.h
deleted file mode 100644
index 6789b8f..0000000
--- a/common/mutex.h
+++ /dev/null
@@ -1,44 +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 __cplusplus
-extern "C" {
-#endif
-
-#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
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _H_MUTEX
diff --git a/common/ogl_ctx.c b/common/ogl_ctx.c
deleted file mode 100644
index 41c0591..0000000
--- a/common/ogl_ctx.c
+++ /dev/null
@@ -1,251 +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 HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <GL/glx.h>
-
-#include "ogl_ctx.h"
-#include "spice_common.h"
-
-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 e7f677a..0000000
--- a/common/ogl_ctx.h
+++ /dev/null
@@ -1,38 +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
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/pixman_utils.c b/common/pixman_utils.c
deleted file mode 100644
index 1136aa7..0000000
--- a/common/pixman_utils.c
+++ /dev/null
@@ -1,1594 +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 HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "pixman_utils.h"
-#include "spice_common.h"
-#include <spice/macros.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "mem.h"
-
-#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 >= 0 && 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 >= 0 && 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;
-
-    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 *)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 *)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 *)src_line;
-
-            transparent_color &= 0xffffff;
-            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 61eaddd..0000000
--- a/common/pixman_utils.h
+++ /dev/null
@@ -1,136 +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"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _H__PIXMAN_UTILS */
diff --git a/common/quic.c b/common/quic.c
deleted file mode 100644
index 707724a..0000000
--- a/common/quic.c
+++ /dev/null
@@ -1,1699 +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
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "quic.h"
-#include <spice/macros.h>
-#include "bitops.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 void encode_run(Encoder *encoder, unsigned int len)
-{
-    int odd = len & 1U;
-    int msb;
-
-    len &= ~1U;
-
-    while ((msb = spice_bit_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_sta