[xorg-x11-drv-qxl] Add various bugfixes from upstream git Fixes VT-switching (rhbz#696711) Add support for old qxl devi
Hans de Goede
jwrdegoede at fedoraproject.org
Thu Apr 21 14:53:22 UTC 2011
commit bb11dc3754b3ec7f26db1fc419028fa1739a12b4
Author: Hans de Goede <hdegoede at redhat.com>
Date: Thu Apr 21 16:53:12 2011 +0200
Add various bugfixes from upstream git
Fixes VT-switching (rhbz#696711)
Add support for old qxl device (from rhel6 branch) (rhbz#642153)
0001-Make-non-default-qxl-modes-available.patch | 98 -
0001-Update-to-the-new-dixPrivate-ABI.patch | 425 ---
...6.0-fix-cast-unmatching-function-pointers.patch | 35 +
...l-resolution-match-actual-resolution-on-s.patch | 34 -
...remove-unused-variable-found-by-gcc-4.6.0.patch | 33 +
...ult-virtual-size-to-match-the-highest-ava.patch | 114 -
0003-build-add-spice-protocol-dep.patch | 39 +
...tion-of-text-mode-font-when-leaving-the-v.patch | 136 -
0004-use-spice-protocol-qxl_dev.h-enums.patch | 215 ++
...eak-the-vfresh-range-of-the-default-monit.patch | 26 -
...use-structs-from-spice-protocol-qxl_dev.h.patch | 1112 ++++++
...lated-virtual-size-to-fit-within-the-fram.patch | 40 -
0006-s-qxl_ram_header-QXLRam.patch | 161 +
...s-the-qxl-device-when-our-vt-is-not-focus.patch | 49 -
...load-read-only-surfaces-after-a-software-.patch | 107 +
0008-Fix-the-driver-crashing-qemu-on-32-bits.patch | 62 -
...-upload-of-images-after-software-fallback.patch | 60 +
...-Generate-tighter-damage-for-PolyFillRect.patch | 61 +
0010-Fix-VT-switching.patch | 133 +
...dd-old-driver-in-as-a-compatibility-layer.patch | 3878 ++++++++++++++++++++
...nk-in-the-compat-driver-various-renamings.patch | 2711 ++++++++++++++
...init-is-called-without-a-confScreen-just-.patch | 31 +
qxl-fixes-from-surface-fixes-branch.patch | 77 -
qxl-remove-assert.patch | 30 -
sources | 2 -
xorg-x11-drv-qxl.spec | 37 +-
26 files changed, 8612 insertions(+), 1094 deletions(-)
---
diff --git a/0001-gcc-4.6.0-fix-cast-unmatching-function-pointers.patch b/0001-gcc-4.6.0-fix-cast-unmatching-function-pointers.patch
new file mode 100644
index 0000000..9534309
--- /dev/null
+++ b/0001-gcc-4.6.0-fix-cast-unmatching-function-pointers.patch
@@ -0,0 +1,35 @@
+From 260ee7001a4c0f3bf5e93e355b23ee8417c7c63a Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 16:03:52 +0200
+Subject: [PATCH 01/13] gcc-4.6.0 fix: cast unmatching function pointers
+
+---
+ src/qxl_driver.c | 12 ++++++------
+ 1 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index 4240c8a..6399d31 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -781,12 +781,12 @@ setup_uxa (qxl_screen_t *qxl, ScreenPtr screen)
+ qxl->uxa->done_copy = qxl_done_copy;
+
+ /* Composite */
+- qxl->uxa->check_composite = unaccel;
+- qxl->uxa->check_composite_target = unaccel;
+- qxl->uxa->check_composite_texture = unaccel;
+- qxl->uxa->prepare_composite = unaccel;
+- qxl->uxa->composite = unaccel;
+- qxl->uxa->done_composite = unaccel;
++ qxl->uxa->check_composite = (typeof(qxl->uxa->check_composite))unaccel;
++ qxl->uxa->check_composite_target = (typeof(qxl->uxa->check_composite_target))unaccel;
++ qxl->uxa->check_composite_texture = (typeof(qxl->uxa->check_composite_texture))unaccel;
++ qxl->uxa->prepare_composite = (typeof(qxl->uxa->prepare_composite))unaccel;
++ qxl->uxa->composite = (typeof(qxl->uxa->composite))unaccel;
++ qxl->uxa->done_composite = (typeof(qxl->uxa->done_composite))unaccel;
+
+ /* PutImage */
+ qxl->uxa->put_image = qxl_put_image;
+--
+1.7.4.4
+
diff --git a/0002-qxl_driver-remove-unused-variable-found-by-gcc-4.6.0.patch b/0002-qxl_driver-remove-unused-variable-found-by-gcc-4.6.0.patch
new file mode 100644
index 0000000..9122150
--- /dev/null
+++ b/0002-qxl_driver-remove-unused-variable-found-by-gcc-4.6.0.patch
@@ -0,0 +1,33 @@
+From 688d7679cb7dbcd57ec07cbaee9b115efbd639c1 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 16:04:14 +0200
+Subject: [PATCH 02/13] qxl_driver: remove unused variable (found by gcc
+ 4.6.0)
+
+---
+ src/qxl_driver.c | 2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index 6399d31..d1ad499 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -826,7 +826,6 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_rom *rom;
+ struct qxl_ram_header *ram_header;
+ VisualPtr visual;
+
+@@ -837,7 +836,6 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ if (!qxl_map_memory(qxl, scrnIndex))
+ return FALSE;
+
+- rom = qxl->rom;
+ ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
+
+ printf ("ram_header at %d\n", qxl->rom->ram_header_offset);
+--
+1.7.4.4
+
diff --git a/0003-build-add-spice-protocol-dep.patch b/0003-build-add-spice-protocol-dep.patch
new file mode 100644
index 0000000..804cf12
--- /dev/null
+++ b/0003-build-add-spice-protocol-dep.patch
@@ -0,0 +1,39 @@
+From e18ea01e672e08e46f63292a5cd5a55be8b8f434 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 12:47:54 +0200
+Subject: [PATCH 03/13] build: add spice-protocol dep
+
+---
+ configure.ac | 2 ++
+ src/Makefile.am | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 2ccd659..ce67b41 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -76,6 +76,8 @@ AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes)
+
+ # Checks for libraries.
+
++PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 0.7.0])
++
+ DRIVER_NAME=qxl
+ AC_SUBST([DRIVER_NAME])
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 1c185fc..ff4fa14 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -27,7 +27,7 @@
+
+ SUBDIRS=uxa
+
+-AM_CFLAGS = $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS)
++AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS)
+
+ qxl_drv_la_LTLIBRARIES = qxl_drv.la
+ qxl_drv_la_LDFLAGS = -module -avoid-version
+--
+1.7.4.4
+
diff --git a/0004-use-spice-protocol-qxl_dev.h-enums.patch b/0004-use-spice-protocol-qxl_dev.h-enums.patch
new file mode 100644
index 0000000..476e89e
--- /dev/null
+++ b/0004-use-spice-protocol-qxl_dev.h-enums.patch
@@ -0,0 +1,215 @@
+From 9fd9bf3676f343ef3e124874c45add88ce2a084f Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 15:47:54 +0200
+Subject: [PATCH 04/13] use spice-protocol qxl_dev.h enums
+
+---
+ src/qxl.h | 95 +---------------------------------------------------
+ src/qxl_surface.c | 10 +++---
+ 2 files changed, 7 insertions(+), 98 deletions(-)
+
+diff --git a/src/qxl.h b/src/qxl.h
+index 801fe77..8a04522 100644
+--- a/src/qxl.h
++++ b/src/qxl.h
+@@ -42,6 +42,8 @@
+ #include "uxa/uxa.h"
+ #include "vgaHW.h"
+
++#include <spice/qxl_dev.h>
++
+ #define hidden _X_HIDDEN
+
+ #define QXL_NAME "qxl"
+@@ -54,27 +56,6 @@
+ #pragma pack(push,1)
+
+ /* I/O port definitions */
+-enum {
+- QXL_IO_NOTIFY_CMD,
+- QXL_IO_NOTIFY_CURSOR,
+- QXL_IO_UPDATE_AREA,
+- QXL_IO_UPDATE_IRQ,
+- QXL_IO_NOTIFY_OOM,
+- QXL_IO_RESET,
+- QXL_IO_SET_MODE, /* qxl 1 */
+- QXL_IO_LOG,
+- /* Appended in qxl 2 */
+- QXL_IO_MEMSLOT_ADD,
+- QXL_IO_MEMSLOT_DEL,
+- QXL_IO_DETACH_PRIMARY,
+- QXL_IO_ATTACH_PRIMARY,
+- QXL_IO_CREATE_PRIMARY,
+- QXL_IO_DESTROY_PRIMARY,
+- QXL_IO_DESTROY_SURFACE_WAIT,
+- QXL_IO_DESTROY_ALL_SURFACES,
+-
+- QXL_IO_RANGE_SIZE
+-};
+
+ struct qxl_mode {
+ uint32_t id;
+@@ -87,16 +68,6 @@ struct qxl_mode {
+ uint32_t orientation;
+ };
+
+-typedef enum
+-{
+- QXL_CMD_NOP,
+- QXL_CMD_DRAW,
+- QXL_CMD_UPDATE,
+- QXL_CMD_CURSOR,
+- QXL_CMD_MESSAGE,
+- QXL_CMD_SURFACE
+-} qxl_command_type;
+-
+ struct qxl_command {
+ uint64_t data;
+ uint32_t type;
+@@ -176,10 +147,6 @@ typedef enum {
+ QXL_IMAGE_TYPE_JPEG_ALPHA
+ } qxl_image_type;
+
+-typedef enum {
+- QXL_IMAGE_CACHE = (1 << 0)
+-} qxl_image_flags;
+-
+ struct qxl_image_descriptor
+ {
+ uint64_t id;
+@@ -210,24 +177,6 @@ typedef enum
+ QXL_BITMAP_FMT_RGBA,
+ } qxl_bitmap_format;
+
+-typedef enum {
+- QXL_BITMAP_PAL_CACHE_ME = (1 << 0),
+- QXL_BITMAP_PAL_FROM_CACHE = (1 << 1),
+- QXL_BITMAP_TOP_DOWN = (1 << 2),
+-} qxl_bitmap_flags;
+-
+-typedef enum {
+- QXL_SURFACE_FMT_INVALID,
+- QXL_SURFACE_FMT_1_A,
+- QXL_SURFACE_FMT_8_A = 8,
+- QXL_SURFACE_FMT_16_555 = 16,
+- QXL_SURFACE_FMT_32_xRGB = 32,
+- QXL_SURFACE_FMT_16_565 = 80,
+- QXL_SURFACE_FMT_32_ARGB = 96,
+-
+- SPICE_SURFACE_FMT_ENUM_END
+-} qxl_surface_fmt;
+-
+ struct qxl_bitmap {
+ uint8_t format;
+ uint8_t flags;
+@@ -344,17 +293,6 @@ struct qxl_whiteness {
+ };
+
+ /* Effects */
+-typedef enum
+-{
+- QXL_EFFECT_BLEND,
+- QXL_EFFECT_OPAQUE,
+- QXL_EFFECT_REVERT_ON_DUP,
+- QXL_EFFECT_BLACKNESS_ON_DUP,
+- QXL_EFFECT_WHITENESS_ON_DUP,
+- QXL_EFFECT_NOP_ON_DUP,
+- QXL_EFFECT_NOP,
+- QXL_EFFECT_OPAQUE_BRUSH
+-} qxl_effect_type;
+
+ typedef enum
+ {
+@@ -363,23 +301,6 @@ typedef enum
+ QXL_CLIP_TYPE_PATH,
+ } qxl_clip_type;
+
+-typedef enum {
+- QXL_DRAW_NOP,
+- QXL_DRAW_FILL,
+- QXL_DRAW_OPAQUE,
+- QXL_DRAW_COPY,
+- QXL_COPY_BITS,
+- QXL_DRAW_BLEND,
+- QXL_DRAW_BLACKNESS,
+- QXL_DRAW_WHITENESS,
+- QXL_DRAW_INVERS,
+- QXL_DRAW_ROP3,
+- QXL_DRAW_STROKE,
+- QXL_DRAW_TEXT,
+- QXL_DRAW_TRANSPARENT,
+- QXL_DRAW_ALPHA_BLEND,
+-} qxl_draw_type;
+-
+ /* QXL 1 */
+ struct qxl_compat_drawable {
+ union qxl_release_info release_info;
+@@ -437,11 +358,6 @@ struct qxl_drawable {
+ } u;
+ };
+
+-typedef enum {
+- QXL_SURFACE_CMD_CREATE,
+- QXL_SURFACE_CMD_DESTROY
+-} qxl_surface_cmd_type;
+-
+ struct qxl_surface_info
+ {
+ uint32_t format;
+@@ -481,13 +397,6 @@ struct qxl_point16 {
+ int16_t y;
+ };
+
+-enum {
+- QXL_CURSOR_SET,
+- QXL_CURSOR_MOVE,
+- QXL_CURSOR_HIDE,
+- QXL_CURSOR_TRAIL,
+-};
+-
+ #define QXL_CURSOR_DEVICE_DATA_SIZE 128
+
+ enum {
+diff --git a/src/qxl_surface.c b/src/qxl_surface.c
+index 0d5a766..f03922a 100644
+--- a/src/qxl_surface.c
++++ b/src/qxl_surface.c
+@@ -232,22 +232,22 @@ get_formats (int bpp, qxl_bitmap_format *format, pixman_format_code_t *pformat)
+ switch (bpp)
+ {
+ case 8:
+- *format = QXL_SURFACE_FMT_8_A;
++ *format = SPICE_SURFACE_FMT_8_A;
+ *pformat = PIXMAN_a8;
+ break;
+
+ case 16:
+- *format = QXL_SURFACE_FMT_16_565;
++ *format = SPICE_SURFACE_FMT_16_565;
+ *pformat = PIXMAN_r5g6b5;
+ break;
+
+ case 24:
+- *format = QXL_SURFACE_FMT_32_xRGB;
++ *format = SPICE_SURFACE_FMT_32_xRGB;
+ *pformat = PIXMAN_a8r8g8b8;
+ break;
+
+ case 32:
+- *format = QXL_SURFACE_FMT_32_ARGB;
++ *format = SPICE_SURFACE_FMT_32_ARGB;
+ *pformat = PIXMAN_a8r8g8b8;
+ break;
+
+@@ -406,7 +406,7 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
+ }
+
+ static struct qxl_surface_cmd *
+-make_surface_cmd (surface_cache_t *cache, uint32_t id, qxl_surface_cmd_type type)
++make_surface_cmd (surface_cache_t *cache, uint32_t id, QXLSurfaceCmdType type)
+ {
+ struct qxl_surface_cmd *cmd;
+ qxl_screen_t *qxl = cache->qxl;
+--
+1.7.4.4
+
diff --git a/0005-use-structs-from-spice-protocol-qxl_dev.h.patch b/0005-use-structs-from-spice-protocol-qxl_dev.h.patch
new file mode 100644
index 0000000..926e9c6
--- /dev/null
+++ b/0005-use-structs-from-spice-protocol-qxl_dev.h.patch
@@ -0,0 +1,1112 @@
+From b25d9a5c425aad88da704df6a7551d12b4f140f1 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 15:55:25 +0200
+Subject: [PATCH 05/13] use structs from spice-protocol qxl_dev.h
+
+A bunch of renames and just plain removal (where the
+struct was never used):
+ * s/qxl_cursor_cmd/QXLCursorCmd/
+ * s/qxl_mode/QXLMode/
+ * s/qxl_command/QXLCommand/
+ * remove qxl_command_ext
+ * s/qxl_rect/QXLRect/
+ * s/qxl_release_info/QXLReleaseInfo/
+ * remove QXLReleaseInfo_ext (prev qxl_release_info_ext)
+ * s/qxl_clip/QXLClip/
+ * s/qxl_point/QXLPoint/
+ * s/qxl_pattern/QXLPattern/
+ * s/qxl_point16/QXLPoint16/
+ * s/qxl_brush/QXLBrush/
+ * s/qxl_mask/QXLQMask/
+ * s/QXL_BRUSH/SPICE_BRUSH/
+ * s/QXL_IMAGE/SPICE_IMAGE/
+ * s/qxl_image_descriptor/QXLImageDescriptor/
+ * s/qxl_data_chunk/QXLDataChunk/
+ * s/qxl_bitmap_format/SpiceBitmapFmt/
+ * s/qxl_bitmap/QXLBitmap/
+ * s/qxl_image/QXLImage/
+ * s/qxl_fill/QXLFill/
+ * s/qxl_opaque/QXLOpaque/
+ * s/qxl_copy/QXLCopy/
+ * s/qxl_transparent/QXLTransparent/
+ * s/qxl_alpha_blend/QXLAlphaBlend/
+ * s/qxl_copy_bits/QXLCopyBits/
+ * s/qxl_blend/QXLBlend/
+ * s/qxl_rop3/QXLRop3/
+ * s/qxl_line_attr/QXLLineAttr/
+ * s/qxl_stroke/QXLStroke/
+ * s/qxl_text/QXLText/
+ * use QXLBlackness,QXLInvers (typo needs fixing later), QXLWhiteness
+ * s/QXL_CLIP_TYPE/SPICE_CLIP_TYPE/
+ * s/qxl_compat_drawable/QXLCompatDrawable/
+ * s/qxl_drawable/QXLDrawable/
+ * s/qxl_surface_cmd/QXLSurfaceCmd/
+ * remove qxl_compat_update_cmd
+ * remove qxl_update_cmd
+ * remove QXL_CURSOR_DEVICE_DATA_SIZE
+ * s/CURSOR_TYPE/SPICE_CURSOR_TYPE/
+ * s/qxl_cursor/QXLCursor/
+ * s/qxl_rom/QXLRom/
+ * remove QXL_SURF_TYPE_PRIMARY
+ * s/qxl_surface_create/QXLSurfaceCreate/
+---
+ src/qxl.h | 447 ++---------------------------------------------------
+ src/qxl_cursor.c | 24 ++--
+ src/qxl_driver.c | 30 ++--
+ src/qxl_image.c | 44 +++---
+ src/qxl_surface.c | 68 ++++----
+ 5 files changed, 93 insertions(+), 520 deletions(-)
+
+diff --git a/src/qxl.h b/src/qxl.h
+index 8a04522..526f145 100644
+--- a/src/qxl.h
++++ b/src/qxl.h
+@@ -55,419 +55,6 @@
+
+ #pragma pack(push,1)
+
+-/* I/O port definitions */
+-
+-struct qxl_mode {
+- uint32_t id;
+- uint32_t x_res;
+- uint32_t y_res;
+- uint32_t bits;
+- uint32_t stride;
+- uint32_t x_mili;
+- uint32_t y_mili;
+- uint32_t orientation;
+-};
+-
+-struct qxl_command {
+- uint64_t data;
+- uint32_t type;
+- uint32_t pad;
+-};
+-
+-struct qxl_command_ext {
+- struct qxl_command cmd;
+- uint32_t group_id;
+- uint32_t flags;
+-};
+-
+-struct qxl_rect {
+- uint32_t top;
+- uint32_t left;
+- uint32_t bottom;
+- uint32_t right;
+-};
+-
+-union qxl_release_info {
+- uint64_t id;
+- uint64_t next;
+-};
+-
+-struct qxl_release_info_ext {
+- union qxl_release_info * info;
+- uint32_t group_id;
+-};
+-
+-struct qxl_clip {
+- uint32_t type;
+- uint64_t address;
+-};
+-
+-struct qxl_point {
+- int x;
+- int y;
+-};
+-
+-struct qxl_pattern {
+- uint64_t pat;
+- struct qxl_point pos;
+-};
+-
+-typedef enum
+-{
+- QXL_BRUSH_TYPE_NONE,
+- QXL_BRUSH_TYPE_SOLID,
+- QXL_BRUSH_TYPE_PATTERN
+-} qxl_brush_type;
+-
+-struct qxl_brush {
+- uint32_t type;
+- union {
+- uint32_t color;
+- struct qxl_pattern pattern;
+- } u;
+-};
+-
+-struct qxl_mask {
+- unsigned char flags;
+- struct qxl_point pos;
+- uint64_t bitmap;
+-};
+-
+-typedef enum {
+- QXL_IMAGE_TYPE_BITMAP,
+- QXL_IMAGE_TYPE_QUIC,
+- QXL_IMAGE_TYPE_PNG,
+- QXL_IMAGE_TYPE_LZ_PLT = 100,
+- QXL_IMAGE_TYPE_LZ_RGB,
+- QXL_IMAGE_TYPE_GLZ_RGB,
+- QXL_IMAGE_TYPE_FROM_CACHE,
+- QXL_IMAGE_TYPE_SURFACE,
+- QXL_IMAGE_TYPE_JPEG,
+- QXL_IMAGE_TYPE_FROM_CACHE_LOSSLESS,
+- QXL_IMAGE_TYPE_JPEG_ALPHA
+-} qxl_image_type;
+-
+-struct qxl_image_descriptor
+-{
+- uint64_t id;
+- uint8_t type;
+- uint8_t flags;
+- uint32_t width;
+- uint32_t height;
+-};
+-
+-struct qxl_data_chunk {
+- uint32_t data_size;
+- uint64_t prev_chunk;
+- uint64_t next_chunk;
+- uint8_t data[0];
+-};
+-
+-typedef enum
+-{
+- QXL_BITMAP_FMT_INVALID,
+- QXL_BITMAP_FMT_1BIT_LE,
+- QXL_BITMAP_FMT_1BIT_BE,
+- QXL_BITMAP_FMT_4BIT_LE,
+- QXL_BITMAP_FMT_4BIT_BE,
+- QXL_BITMAP_FMT_8BIT,
+- QXL_BITMAP_FMT_16BIT,
+- QXL_BITMAP_FMT_24BIT,
+- QXL_BITMAP_FMT_32BIT,
+- QXL_BITMAP_FMT_RGBA,
+-} qxl_bitmap_format;
+-
+-struct qxl_bitmap {
+- uint8_t format;
+- uint8_t flags;
+- uint32_t x; /* actually width */
+- uint32_t y; /* actually height */
+- uint32_t stride; /* in bytes */
+- uint64_t palette; /* Can be NULL */
+- uint64_t data; /* A qxl_data_chunk that actually contains the data */
+-};
+-
+-struct qxl_image {
+- struct qxl_image_descriptor descriptor;
+- union
+- {
+- struct qxl_bitmap bitmap;
+- uint32_t surface_id;
+- } u;
+-};
+-
+-struct qxl_fill {
+- struct qxl_brush brush;
+- unsigned short rop_descriptor;
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_opaque {
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- struct qxl_brush brush;
+- unsigned short rop_descriptor;
+- unsigned char scale_mode;
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_copy {
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- unsigned short rop_descriptor;
+- unsigned char scale_mode;
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_transparent {
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- uint32_t src_color;
+- uint32_t true_color;
+-};
+-
+-struct qxl_alpha_blend {
+- unsigned char alpha;
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+-};
+-
+-struct qxl_copy_bits {
+- struct qxl_point src_pos;
+-};
+-
+-struct qxl_blend { /* same as copy */
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- unsigned short rop_descriptor;
+- unsigned char scale_mode;
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_rop3 {
+- uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- struct qxl_brush brush;
+- unsigned char rop3;
+- unsigned char scale_mode;
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_line_attr {
+- unsigned char flags;
+- unsigned char join_style;
+- unsigned char end_style;
+- unsigned char style_nseg;
+- int width;
+- int miter_limit;
+- uint64_t style;
+-};
+-
+-struct qxl_stroke {
+- uint64_t path;
+- struct qxl_line_attr attr;
+- struct qxl_brush brush;
+- unsigned short fore_mode;
+- unsigned short back_mode;
+-};
+-
+-struct qxl_text {
+- uint64_t str;
+- struct qxl_rect back_area;
+- struct qxl_brush fore_brush;
+- struct qxl_brush back_brush;
+- unsigned short fore_mode;
+- unsigned short back_mode;
+-};
+-
+-struct qxl_blackness {
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_inverse {
+- struct qxl_mask mask;
+-};
+-
+-struct qxl_whiteness {
+- struct qxl_mask mask;
+-};
+-
+-/* Effects */
+-
+-typedef enum
+-{
+- QXL_CLIP_TYPE_NONE,
+- QXL_CLIP_TYPE_RECTS,
+- QXL_CLIP_TYPE_PATH,
+-} qxl_clip_type;
+-
+-/* QXL 1 */
+-struct qxl_compat_drawable {
+- union qxl_release_info release_info;
+- uint8_t effect;
+- uint8_t type;
+- uint8_t self_bitmap;
+- struct qxl_rect bitmap_area;
+- struct qxl_rect bbox;
+- struct qxl_clip clip;
+- uint32_t mm_time;
+- union {
+- struct qxl_fill fill;
+- struct qxl_opaque opaque;
+- struct qxl_copy copy;
+- struct qxl_transparent transparent;
+- struct qxl_alpha_blend alpha_blend;
+- struct qxl_copy_bits copy_bits;
+- struct qxl_blend blend;
+- struct qxl_rop3 rop3;
+- struct qxl_stroke stroke;
+- struct qxl_text text;
+- struct qxl_blackness blackness;
+- struct qxl_inverse inverse;
+- struct qxl_whiteness whiteness;
+- } u;
+-};
+-
+-/* QXL 2 */
+-struct qxl_drawable {
+- union qxl_release_info release_info;
+- uint32_t surface_id;
+- uint8_t effect;
+- uint8_t type;
+- uint8_t self_bitmap;
+- struct qxl_rect self_bitmap_area;
+- struct qxl_rect bbox;
+- struct qxl_clip clip;
+- uint32_t mm_time;
+- int32_t surfaces_dest[3];
+- struct qxl_rect surfaces_rects[3];
+- union {
+- struct qxl_fill fill;
+- struct qxl_opaque opaque;
+- struct qxl_copy copy;
+- struct qxl_transparent transparent;
+- struct qxl_alpha_blend alpha_blend;
+- struct qxl_copy_bits copy_bits;
+- struct qxl_blend blend;
+- struct qxl_rop3 rop3;
+- struct qxl_stroke stroke;
+- struct qxl_text text;
+- struct qxl_blackness blackness;
+- struct qxl_inverse inverse;
+- struct qxl_whiteness whiteness;
+- } u;
+-};
+-
+-struct qxl_surface_info
+-{
+- uint32_t format;
+- uint32_t width;
+- uint32_t height;
+- int32_t stride;
+- uint64_t physical;
+-};
+-
+-struct qxl_surface_cmd {
+- union qxl_release_info release_info;
+- uint32_t surface_id;
+- uint8_t type;
+- uint32_t flags;
+- union
+- {
+- struct qxl_surface_info surface_create;
+- } u;
+-};
+-
+-
+-struct qxl_compat_update_cmd {
+- union qxl_release_info release_info;
+- struct qxl_rect area;
+- uint32_t update_id;
+-};
+-
+-struct qxl_update_cmd {
+- union qxl_release_info release_info;
+- struct qxl_rect area;
+- uint32_t update_id;
+- uint32_t surface_id;
+-};
+-
+-struct qxl_point16 {
+- int16_t x;
+- int16_t y;
+-};
+-
+-#define QXL_CURSOR_DEVICE_DATA_SIZE 128
+-
+-enum {
+- CURSOR_TYPE_ALPHA,
+- CURSOR_TYPE_MONO,
+- CURSOR_TYPE_COLOR4,
+- CURSOR_TYPE_COLOR8,
+- CURSOR_TYPE_COLOR16,
+- CURSOR_TYPE_COLOR24,
+- CURSOR_TYPE_COLOR32,
+-};
+-
+-struct qxl_cursor_header {
+- uint64_t unique;
+- uint16_t type;
+- uint16_t width;
+- uint16_t height;
+- uint16_t hot_spot_x;
+- uint16_t hot_spot_y;
+-};
+-
+-struct qxl_cursor
+-{
+- struct qxl_cursor_header header;
+- uint32_t data_size;
+- struct qxl_data_chunk chunk;
+-};
+-
+-struct qxl_cursor_cmd {
+- union qxl_release_info release_info;
+- uint8_t type;
+- union {
+- struct {
+- struct qxl_point16 position;
+- unsigned char visible;
+- uint64_t shape;
+- } set;
+- struct {
+- uint16_t length;
+- uint16_t frequency;
+- } trail;
+- struct qxl_point16 position;
+- } u;
+- uint8_t device_data[QXL_CURSOR_DEVICE_DATA_SIZE];
+-};
+-
+-struct qxl_rom {
+- uint32_t magic;
+- uint32_t id;
+- uint32_t update_id;
+- uint32_t compression_level;
+- uint32_t log_level;
+- uint32_t mode; /* qxl 1 */
+- uint32_t modes_offset;
+- uint32_t num_pages;
+- uint32_t pages_offset; /* qxl 1 */
+- uint32_t draw_area_offset; /* qxl 1 */
+- uint32_t surface0_area_size; /* qxl 1 name: draw_area_size */
+- uint32_t ram_header_offset;
+- uint32_t mm_clock;
+- /* Appended for qxl-2 */
+- uint32_t n_surfaces;
+- uint64_t flags;
+- uint8_t slots_start;
+- uint8_t slots_end;
+- uint8_t slot_gen_bits;
+- uint8_t slot_id_bits;
+- uint8_t slot_generation;
+- uint8_t padding[3];
+-};
+-
+ struct qxl_ring_header {
+ uint32_t num_items;
+ uint32_t prod;
+@@ -476,20 +63,6 @@ struct qxl_ring_header {
+ uint32_t notify_on_cons;
+ };
+
+-#define QXL_SURF_TYPE_PRIMARY 0
+-
+-struct qxl_surface_create {
+- uint32_t width;
+- uint32_t height;
+- int32_t stride;
+- uint32_t depth;
+- uint32_t position;
+- uint32_t mouse_mode;
+- uint32_t flags;
+- uint32_t type;
+- uint64_t mem;
+-};
+-
+ #define QXL_LOG_BUF_SIZE 4096
+
+ struct qxl_ram_header {
+@@ -498,17 +71,17 @@ struct qxl_ram_header {
+ uint32_t int_mask;
+ unsigned char log_buf[QXL_LOG_BUF_SIZE];
+ struct qxl_ring_header cmd_ring_hdr;
+- struct qxl_command cmd_ring[32];
++ struct QXLCommand cmd_ring[32];
+ struct qxl_ring_header cursor_ring_hdr;
+- struct qxl_command cursor_ring[32];
++ struct QXLCommand cursor_ring[32];
+ struct qxl_ring_header release_ring_hdr;
+ uint64_t release_ring[8];
+- struct qxl_rect update_area;
++ struct QXLRect update_area;
+ /* appended for qxl-2 */
+ uint32_t update_surface;
+ uint64_t mem_slot_start;
+ uint64_t mem_slot_end;
+- struct qxl_surface_create create_surface;
++ struct QXLSurfaceCreate create_surface;
+ uint64_t flags;
+ };
+
+@@ -536,14 +109,14 @@ struct _qxl_screen_t
+ void * ram_physical;
+ void * vram; /* Surface RAM */
+ void * vram_physical;
+- struct qxl_rom * rom; /* Parameter RAM */
++ struct QXLRom * rom; /* Parameter RAM */
+
+ struct qxl_ring * command_ring;
+ struct qxl_ring * cursor_ring;
+ struct qxl_ring * release_ring;
+
+ int num_modes;
+- struct qxl_mode * modes;
++ struct QXLMode * modes;
+ int io_base;
+ void * surface0_area;
+ long surface0_size;
+@@ -553,7 +126,7 @@ struct _qxl_screen_t
+ int virtual_y;
+ void * fb;
+ int stride;
+- struct qxl_mode * current_mode;
++ struct QXLMode * current_mode;
+ qxl_surface_t * primary;
+
+ int bytes_per_pixel;
+@@ -664,7 +237,7 @@ void qxl_ring_wait_idle (struct qxl_ring *ring);
+ */
+ surface_cache_t * qxl_surface_cache_create (qxl_screen_t *qxl);
+ qxl_surface_t * qxl_surface_cache_create_primary (surface_cache_t *qxl,
+- struct qxl_mode *mode);
++ struct QXLMode *mode);
+ qxl_surface_t * qxl_surface_create (surface_cache_t *qxl,
+ int width,
+ int height,
+@@ -748,7 +321,7 @@ get_ram_header (qxl_screen_t *qxl)
+ /*
+ * Images
+ */
+-struct qxl_image *qxl_image_create (qxl_screen_t *qxl,
++struct QXLImage *qxl_image_create (qxl_screen_t *qxl,
+ const uint8_t *data,
+ int x,
+ int y,
+@@ -757,7 +330,7 @@ struct qxl_image *qxl_image_create (qxl_screen_t *qxl,
+ int stride,
+ int Bpp);
+ void qxl_image_destroy (qxl_screen_t *qxl,
+- struct qxl_image *image);
++ struct QXLImage *image);
+ void qxl_drop_image_cache (qxl_screen_t *qxl);
+
+
+diff --git a/src/qxl_cursor.c b/src/qxl_cursor.c
+index 836a3f3..c42e8fa 100644
+--- a/src/qxl_cursor.c
++++ b/src/qxl_cursor.c
+@@ -20,7 +20,7 @@
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+-/** \file qxl_image.c
++/** \file qxl_cursor.c
+ * \author Søren Sandmann <sandmann at redhat.com>
+ */
+
+@@ -29,9 +29,9 @@
+ #include <cursorstr.h>
+
+ static void
+-push_cursor (qxl_screen_t *qxl, struct qxl_cursor_cmd *cursor)
++push_cursor (qxl_screen_t *qxl, struct QXLCursorCmd *cursor)
+ {
+- struct qxl_command cmd;
++ struct QXLCommand cmd;
+
+ /* See comment on push_command() in qxl_driver.c */
+ if (qxl->pScrn->vtSema)
+@@ -43,11 +43,11 @@ push_cursor (qxl_screen_t *qxl, struct qxl_cursor_cmd *cursor)
+ }
+ }
+
+-static struct qxl_cursor_cmd *
++static struct QXLCursorCmd *
+ qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
+ {
+- struct qxl_cursor_cmd *cmd =
+- qxl_allocnf (qxl, sizeof(struct qxl_cursor_cmd));
++ struct QXLCursorCmd *cmd =
++ qxl_allocnf (qxl, sizeof(struct QXLCursorCmd));
+
+ cmd->release_info.id = pointer_to_u64 (cmd) | 1;
+
+@@ -58,7 +58,7 @@ static void
+ qxl_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
+ {
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd(qxl);
++ struct QXLCursorCmd *cmd = qxl_alloc_cursor_cmd(qxl);
+
+ qxl->cur_x = x;
+ qxl->cur_y = y;
+@@ -89,12 +89,12 @@ qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
+ int h = pCurs->bits->height;
+ int size = w * h * sizeof (CARD32);
+
+- struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd (qxl);
+- struct qxl_cursor *cursor =
+- qxl_allocnf(qxl, sizeof(struct qxl_cursor) + size);
++ struct QXLCursorCmd *cmd = qxl_alloc_cursor_cmd (qxl);
++ struct QXLCursor *cursor =
++ qxl_allocnf(qxl, sizeof(struct QXLCursor) + size);
+
+ cursor->header.unique = 0;
+- cursor->header.type = CURSOR_TYPE_ALPHA;
++ cursor->header.type = SPICE_CURSOR_TYPE_ALPHA;
+ cursor->header.width = w;
+ cursor->header.height = h;
+ /* I wonder if we can just tell the client that the hotspot is 0, 0
+@@ -156,7 +156,7 @@ static void
+ qxl_hide_cursor(ScrnInfoPtr pScrn)
+ {
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_cursor_cmd *cursor = qxl_alloc_cursor_cmd(qxl);
++ struct QXLCursorCmd *cursor = qxl_alloc_cursor_cmd(qxl);
+
+ cursor->type = QXL_CURSOR_HIDE;
+
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index d1ad499..b6a5e4e 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -58,10 +58,10 @@ qxl_garbage_collect (qxl_screen_t *qxl)
+ */
+ #define POINTER_MASK ((1 << 2) - 1)
+
+- union qxl_release_info *info = u64_to_pointer (id & ~POINTER_MASK);
+- struct qxl_cursor_cmd *cmd = (struct qxl_cursor_cmd *)info;
+- struct qxl_drawable *drawable = (struct qxl_drawable *)info;
+- struct qxl_surface_cmd *surface_cmd = (struct qxl_surface_cmd *)info;
++ union QXLReleaseInfo *info = u64_to_pointer (id & ~POINTER_MASK);
++ struct QXLCursorCmd *cmd = (struct QXLCursorCmd *)info;
++ struct QXLDrawable *drawable = (struct qxl_drawable *)info;
++ struct QXLSurfaceCmd *surface_cmd = (struct QXLSurfaceCmd *)info;
+ int is_cursor = FALSE;
+ int is_surface = FALSE;
+ int is_drawable = FALSE;
+@@ -75,19 +75,19 @@ qxl_garbage_collect (qxl_screen_t *qxl)
+
+ if (is_cursor && cmd->type == QXL_CURSOR_SET)
+ {
+- struct qxl_cursor *cursor = (void *)virtual_address (
++ struct QXLCursor *cursor = (void *)virtual_address (
+ qxl, u64_to_pointer (cmd->u.set.shape), qxl->main_mem_slot);
+
+ qxl_free (qxl->mem, cursor);
+ }
+ else if (is_drawable && drawable->type == QXL_DRAW_COPY)
+ {
+- struct qxl_image *image = virtual_address (
++ struct QXLImage *image = virtual_address (
+ qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot);
+
+- if (image->descriptor.type == QXL_IMAGE_TYPE_SURFACE)
++ if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
+ {
+- qxl_surface_unref (qxl->surface_cache, image->u.surface_id);
++ qxl_surface_unref (qxl->surface_cache, image->surface_image.surface_id);
+ qxl_surface_cache_sanity_check (qxl->surface_cache);
+ qxl_free (qxl->mem, image);
+ }
+@@ -281,7 +281,7 @@ qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
+ xf86DrvMsg(scrnIndex, X_INFO, "rom at %p\n", qxl->rom);
+
+ qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
+- qxl->modes = (struct qxl_mode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
++ qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
+ qxl->surface0_area = qxl->ram;
+ qxl->surface0_size = qxl->rom->surface0_area_size;
+
+@@ -429,7 +429,7 @@ qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
+ {
+ qxl_screen_t *qxl = xf86Screens[scrnIndex]->driverPrivate;
+ int mode_index = (int)(unsigned long)p->Private;
+- struct qxl_mode *m = qxl->modes + mode_index;
++ struct QXLMode *m = qxl->modes + mode_index;
+ ScreenPtr pScreen;
+ void *evacuated;
+
+@@ -904,10 +904,10 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
+
+ qxl->command_ring = qxl_ring_create (&(ram_header->cmd_ring_hdr),
+- sizeof (struct qxl_command),
++ sizeof (struct QXLCommand),
+ 32, qxl->io_base + QXL_IO_NOTIFY_CMD);
+ qxl->cursor_ring = qxl_ring_create (&(ram_header->cursor_ring_hdr),
+- sizeof (struct qxl_command),
++ sizeof (struct QXLCommand),
+ 32, qxl->io_base + QXL_IO_NOTIFY_CURSOR);
+ qxl->release_ring = qxl_ring_create (&(ram_header->release_ring_hdr),
+ sizeof (uint64_t),
+@@ -1013,7 +1013,7 @@ print_modes (qxl_screen_t *qxl, int scrnIndex)
+
+ for (i = 0; i < qxl->num_modes; ++i)
+ {
+- struct qxl_mode *m = qxl->modes + i;
++ struct QXLMode *m = qxl->modes + i;
+
+ xf86DrvMsg (scrnIndex, X_INFO,
+ "%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n",
+@@ -1026,7 +1026,7 @@ static Bool
+ qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
+ {
+ int scrnIndex = pScrn->scrnIndex;
+- struct qxl_rom *rom = qxl->rom;
++ struct QXLRom *rom = qxl->rom;
+ struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
+
+ CHECK_POINT();
+@@ -1077,7 +1077,7 @@ qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
+
+ for (i = 0; i < qxl->num_modes; i++)
+ {
+- struct qxl_mode *m = qxl->modes + i;
++ struct QXLMode *m = qxl->modes + i;
+
+ if (m->x_res == p->HDisplay &&
+ m->y_res == p->VDisplay &&
+diff --git a/src/qxl_image.c b/src/qxl_image.c
+index 2e1a70b..04074d0 100644
+--- a/src/qxl_image.c
++++ b/src/qxl_image.c
+@@ -20,7 +20,7 @@
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+-/** \file qxl_image.c
++/** \file QXLImage.c
+ * \author Søren Sandmann <sandmann at redhat.com>
+ */
+
+@@ -34,7 +34,7 @@ typedef struct image_info_t image_info_t;
+
+ struct image_info_t
+ {
+- struct qxl_image *image;
++ struct QXLImage *image;
+ int ref_count;
+ image_info_t *next;
+ };
+@@ -74,7 +74,7 @@ lookup_image_info (unsigned int hash,
+
+ while (info)
+ {
+- struct qxl_image *image = info->image;
++ struct QXLImage *image = info->image;
+
+ if (image->descriptor.id == hash &&
+ image->descriptor.width == width &&
+@@ -121,7 +121,7 @@ remove_image_info (image_info_t *info)
+ free (info);
+ }
+
+-struct qxl_image *
++struct QXLImage *
+ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ int x, int y, int width, int height,
+ int stride, int Bpp)
+@@ -146,11 +146,11 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+
+ for (i = 0; i < height; ++i)
+ {
+- struct qxl_data_chunk *chunk;
++ struct QXLDataChunk *chunk;
+ const uint8_t *src_line = data + i * stride;
+ uint32_t *dest_line;
+
+- chunk = virtual_address (qxl, u64_to_pointer (info->image->u.bitmap.data), qxl->main_mem_slot);
++ chunk = virtual_address (qxl, u64_to_pointer (info->image->bitmap.data), qxl->main_mem_slot);
+
+ dest_line = (uint32_t *)chunk->data + width * i;
+
+@@ -173,8 +173,8 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ }
+ else
+ {
+- struct qxl_image *image;
+- struct qxl_data_chunk *chunk;
++ struct QXLImage *image;
++ struct QXLDataChunk *chunk;
+ int dest_stride = width * Bpp;
+
+ #if 0
+@@ -198,7 +198,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ image = qxl_allocnf (qxl, sizeof *image);
+
+ image->descriptor.id = 0;
+- image->descriptor.type = QXL_IMAGE_TYPE_BITMAP;
++ image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
+
+ image->descriptor.flags = 0;
+ image->descriptor.width = width;
+@@ -206,25 +206,25 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+
+ if (Bpp == 2)
+ {
+- image->u.bitmap.format = QXL_BITMAP_FMT_16BIT;
++ image->bitmap.format = SPICE_BITMAP_FMT_16BIT;
+ }
+ else if (Bpp == 1)
+ {
+- image->u.bitmap.format = QXL_BITMAP_FMT_8BIT;
++ image->bitmap.format = SPICE_BITMAP_FMT_8BIT;
+ }
+ else if (Bpp == 4)
+ {
+- image->u.bitmap.format = QXL_BITMAP_FMT_32BIT;
++ image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
+ }
+ else
+ abort();
+
+- image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
+- image->u.bitmap.x = width;
+- image->u.bitmap.y = height;
+- image->u.bitmap.stride = width * Bpp;
+- image->u.bitmap.palette = 0;
+- image->u.bitmap.data = physical_address (qxl, chunk, qxl->main_mem_slot);
++ image->bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
++ image->bitmap.x = width;
++ image->bitmap.y = height;
++ image->bitmap.stride = width * Bpp;
++ image->bitmap.palette = 0;
++ image->bitmap.data = physical_address (qxl, chunk, qxl->main_mem_slot);
+
+ #if 0
+ ErrorF ("%p has size %d %d\n", image, width, height);
+@@ -238,7 +238,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ info->ref_count = 1;
+
+ image->descriptor.id = hash;
+- image->descriptor.flags = QXL_IMAGE_CACHE;
++ image->descriptor.flags = SPICE_IMAGE_CACHE;
+
+ #if 0
+ ErrorF ("added with hash %u\n", hash);
+@@ -252,12 +252,12 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+
+ void
+ qxl_image_destroy (qxl_screen_t *qxl,
+- struct qxl_image *image)
++ struct QXLImage *image)
+ {
+- struct qxl_data_chunk *chunk;
++ struct QXLDataChunk *chunk;
+ image_info_t *info;
+
+- chunk = virtual_address (qxl, u64_to_pointer (image->u.bitmap.data), qxl->main_mem_slot);
++ chunk = virtual_address (qxl, u64_to_pointer (image->bitmap.data), qxl->main_mem_slot);
+
+ info = lookup_image_info (image->descriptor.id,
+ image->descriptor.width,
+diff --git a/src/qxl_surface.c b/src/qxl_surface.c
+index f03922a..0ada697 100644
+--- a/src/qxl_surface.c
++++ b/src/qxl_surface.c
+@@ -227,7 +227,7 @@ print_cache_info (surface_cache_t *cache)
+ }
+
+ static void
+-get_formats (int bpp, qxl_bitmap_format *format, pixman_format_code_t *pformat)
++get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat)
+ {
+ switch (bpp)
+ {
+@@ -341,11 +341,11 @@ qxl_surface_recycle (surface_cache_t *cache, uint32_t id)
+
+ qxl_surface_t *
+ qxl_surface_cache_create_primary (surface_cache_t *cache,
+- struct qxl_mode *mode)
++ struct QXLMode *mode)
+ {
+ struct qxl_ram_header *ram_header =
+ (void *)((unsigned long)cache->qxl->ram + cache->qxl->rom->ram_header_offset);
+- struct qxl_surface_create *create = &(ram_header->create_surface);
++ struct QXLSurfaceCreate *create = &(ram_header->create_surface);
+ pixman_format_code_t format;
+ uint8_t *dev_addr;
+ pixman_image_t *dev_image, *host_image;
+@@ -370,7 +370,7 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
+ create->width = mode->x_res;
+ create->height = mode->y_res;
+ create->stride = - mode->stride;
+- create->depth = mode->bits;
++ create->format = mode->bits;
+ create->position = 0; /* What is this? The Windows driver doesn't use it */
+ create->flags = 0;
+ create->type = QXL_SURF_TYPE_PRIMARY;
+@@ -405,10 +405,10 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
+ return surface;
+ }
+
+-static struct qxl_surface_cmd *
++static struct QXLSurfaceCmd *
+ make_surface_cmd (surface_cache_t *cache, uint32_t id, QXLSurfaceCmdType type)
+ {
+- struct qxl_surface_cmd *cmd;
++ struct QXLSurfaceCmd *cmd;
+ qxl_screen_t *qxl = cache->qxl;
+
+ qxl_garbage_collect (qxl);
+@@ -424,9 +424,9 @@ make_surface_cmd (surface_cache_t *cache, uint32_t id, QXLSurfaceCmdType type)
+ }
+
+ static void
+-push_surface_cmd (surface_cache_t *cache, struct qxl_surface_cmd *cmd)
++push_surface_cmd (surface_cache_t *cache, struct QXLSurfaceCmd *cmd)
+ {
+- struct qxl_command command;
++ struct QXLCommand command;
+ qxl_screen_t *qxl = cache->qxl;
+
+ command.type = QXL_CMD_SURFACE;
+@@ -450,12 +450,12 @@ enum ROPDescriptor
+ ROPD_INVERS_RES = (1 <<10),
+ };
+
+-static struct qxl_drawable *
++static struct QXLDrawable *
+ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
+- const struct qxl_rect *rect
++ const struct QXLRect *rect
+ /* , pRegion clip */)
+ {
+- struct qxl_drawable *drawable;
++ struct QXLDrawable *drawable;
+ int i;
+
+ drawable = qxl_allocnf (qxl, sizeof *drawable);
+@@ -472,7 +472,7 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
+ drawable->self_bitmap_area.bottom = 0;
+ drawable->self_bitmap_area.right = 0;
+ /* FIXME: add clipping */
+- drawable->clip.type = QXL_CLIP_TYPE_NONE;
++ drawable->clip.type = SPICE_CLIP_TYPE_NONE;
+
+ /*
+ * surfaces_dest[i] should apparently be filled out with the
+@@ -492,9 +492,9 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
+ }
+
+ static void
+-push_drawable (qxl_screen_t *qxl, struct qxl_drawable *drawable)
++push_drawable (qxl_screen_t *qxl, struct QXLDrawable *drawable)
+ {
+- struct qxl_command cmd;
++ struct QXLCommand cmd;
+
+ /* When someone runs "init 3", the device will be
+ * switched into VGA mode and there is nothing we
+@@ -516,13 +516,13 @@ push_drawable (qxl_screen_t *qxl, struct qxl_drawable *drawable)
+
+ static void
+ submit_fill (qxl_screen_t *qxl, int id,
+- const struct qxl_rect *rect, uint32_t color)
++ const struct QXLRect *rect, uint32_t color)
+ {
+- struct qxl_drawable *drawable;
++ struct QXLDrawable *drawable;
+
+ drawable = make_drawable (qxl, id, QXL_DRAW_FILL, rect);
+
+- drawable->u.fill.brush.type = QXL_BRUSH_TYPE_SOLID;
++ drawable->u.fill.brush.type = SPICE_BRUSH_TYPE_SOLID;
+ drawable->u.fill.brush.u.color = color;
+ drawable->u.fill.rop_descriptor = ROPD_OP_PUT;
+ drawable->u.fill.mask.flags = 0;
+@@ -578,9 +578,9 @@ surface_send_create (surface_cache_t *cache,
+ int height,
+ int bpp)
+ {
+- qxl_bitmap_format format;
++ SpiceBitmapFmt format;
+ pixman_format_code_t pformat;
+- struct qxl_surface_cmd *cmd;
++ struct QXLSurfaceCmd *cmd;
+ int stride;
+ uint32_t *dev_addr;
+ int n_attempts = 0;
+@@ -653,7 +653,7 @@ retry2:
+ cmd->u.surface_create.height = height;
+ cmd->u.surface_create.stride = - stride;
+
+- cmd->u.surface_create.physical =
++ cmd->u.surface_create.data =
+ physical_address (qxl, surface->address, qxl->vram_mem_slot);
+
+ push_surface_cmd (cache, cmd);
+@@ -754,7 +754,7 @@ unlink_surface (qxl_surface_t *surface)
+ static void
+ send_destroy (qxl_surface_t *surface)
+ {
+- struct qxl_surface_cmd *cmd;
++ struct QXLSurfaceCmd *cmd;
+
+ if (surface->dev_image)
+ pixman_image_unref (surface->dev_image);
+@@ -1010,7 +1010,7 @@ qxl_surface_prepare_access (qxl_surface_t *surface,
+ }
+
+ static void
+-translate_rect (struct qxl_rect *rect)
++translate_rect (struct QXLRect *rect)
+ {
+ rect->right -= rect->left;
+ rect->bottom -= rect->top;
+@@ -1020,9 +1020,9 @@ translate_rect (struct qxl_rect *rect)
+ static void
+ upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+ {
+- struct qxl_rect rect;
+- struct qxl_drawable *drawable;
+- struct qxl_image *image;
++ struct QXLRect rect;
++ struct QXLDrawable *drawable;
++ struct QXLImage *image;
+ qxl_screen_t *qxl = surface->cache->qxl;
+ uint32_t *data;
+ int stride;
+@@ -1255,7 +1255,7 @@ qxl_surface_solid (qxl_surface_t *destination,
+ int y2)
+ {
+ qxl_screen_t *qxl = destination->cache->qxl;
+- struct qxl_rect qrect;
++ struct QXLRect qrect;
+ uint32_t p;
+
+ qrect.top = y1;
+@@ -1310,8 +1310,8 @@ qxl_surface_copy (qxl_surface_t *dest,
+ int width, int height)
+ {
+ qxl_screen_t *qxl = dest->cache->qxl;
+- struct qxl_drawable *drawable;
+- struct qxl_rect qrect;
++ struct QXLDrawable *drawable;
++ struct QXLRect qrect;
+
+ #if 0
+ print_region (" copy src", &(dest->u.copy_src->access_region));
+@@ -1336,15 +1336,15 @@ qxl_surface_copy (qxl_surface_t *dest,
+ }
+ else
+ {
+- struct qxl_image *image = qxl_allocnf (qxl, sizeof *image);
++ struct QXLImage *image = qxl_allocnf (qxl, sizeof *image);
+
+ dest->u.copy_src->ref_count++;
+
+ image->descriptor.id = 0;
+- image->descriptor.type = QXL_IMAGE_TYPE_SURFACE;
++ image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
+ image->descriptor.width = 0;
+ image->descriptor.height = 0;
+- image->u.surface_id = dest->u.copy_src->id;
++ image->surface_image.surface_id = dest->u.copy_src->id;
+
+ drawable = make_drawable (qxl, dest->id, QXL_DRAW_COPY, &qrect);
+
+@@ -1397,10 +1397,10 @@ qxl_surface_put_image (qxl_surface_t *dest,
+ int x, int y, int width, int height,
+ const char *src, int src_pitch)
+ {
+- struct qxl_drawable *drawable;
++ struct QXLDrawable *drawable;
+ qxl_screen_t *qxl = dest->cache->qxl;
+- struct qxl_rect rect;
+- struct qxl_image *image;
++ struct QXLRect rect;
++ struct QXLImage *image;
+
+ rect.left = x;
+ rect.right = x + width;
+--
+1.7.4.4
+
diff --git a/0006-s-qxl_ram_header-QXLRam.patch b/0006-s-qxl_ram_header-QXLRam.patch
new file mode 100644
index 0000000..25794ab
--- /dev/null
+++ b/0006-s-qxl_ram_header-QXLRam.patch
@@ -0,0 +1,161 @@
+From 3657800a64af34d04a18bbf342a648ab4e28c294 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 10 Feb 2011 20:08:24 +0200
+Subject: [PATCH 06/13] s/qxl_ram_header/QXLRam/
+
+---
+ src/qxl.h | 26 ++------------------------
+ src/qxl_driver.c | 22 +++++++++++-----------
+ src/qxl_surface.c | 4 ++--
+ 3 files changed, 15 insertions(+), 37 deletions(-)
+
+diff --git a/src/qxl.h b/src/qxl.h
+index 526f145..1c79ec8 100644
+--- a/src/qxl.h
++++ b/src/qxl.h
+@@ -63,28 +63,6 @@ struct qxl_ring_header {
+ uint32_t notify_on_cons;
+ };
+
+-#define QXL_LOG_BUF_SIZE 4096
+-
+-struct qxl_ram_header {
+- uint32_t magic;
+- uint32_t int_pending;
+- uint32_t int_mask;
+- unsigned char log_buf[QXL_LOG_BUF_SIZE];
+- struct qxl_ring_header cmd_ring_hdr;
+- struct QXLCommand cmd_ring[32];
+- struct qxl_ring_header cursor_ring_hdr;
+- struct QXLCommand cursor_ring[32];
+- struct qxl_ring_header release_ring_hdr;
+- uint64_t release_ring[8];
+- struct QXLRect update_area;
+- /* appended for qxl-2 */
+- uint32_t update_surface;
+- uint64_t mem_slot_start;
+- uint64_t mem_slot_end;
+- struct QXLSurfaceCreate create_surface;
+- uint64_t flags;
+-};
+-
+ #pragma pack(pop)
+ typedef struct surface_cache_t surface_cache_t;
+
+@@ -311,10 +289,10 @@ static inline void set_surface (PixmapPtr pixmap, qxl_surface_t *surface)
+ dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, surface);
+ }
+
+-static inline struct qxl_ram_header *
++static inline struct QXLRam *
+ get_ram_header (qxl_screen_t *qxl)
+ {
+- return (struct qxl_ram_header *)
++ return (struct QXLRam *)
+ ((uint8_t *)qxl->ram + qxl->rom->ram_header_offset);
+ }
+
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index b6a5e4e..d174d05 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -156,7 +156,7 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
+
+ while (!(result = qxl_alloc (qxl->mem, size)))
+ {
+- struct qxl_ram_header *ram_header = (void *)(
++ struct QXLRam *ram_header = (void *)(
+ (unsigned long)qxl->ram + qxl->rom->ram_header_offset);
+
+ /* Rather than go out of memory, we simply tell the
+@@ -340,7 +340,7 @@ qxl_reset (qxl_screen_t *qxl)
+ {
+ qxl_memslot_t *slot;
+ uint64_t high_bits;
+- struct qxl_ram_header *ram_header;
++ struct QXLRam *ram_header;
+
+ outb(qxl->io_base + QXL_IO_RESET, 0);
+
+@@ -367,8 +367,8 @@ qxl_reset (qxl_screen_t *qxl)
+ slot->start_virt_addr = (uint64_t)(uintptr_t)qxl->ram;
+ slot->end_virt_addr = slot->start_virt_addr + (unsigned long)qxl->rom->num_pages * getpagesize();
+
+- ram_header->mem_slot_start = slot->start_phys_addr;
+- ram_header->mem_slot_end = slot->end_phys_addr;
++ ram_header->mem_slot.mem_start = slot->start_phys_addr;
++ ram_header->mem_slot.mem_end = slot->end_phys_addr;
+
+ outb (qxl->io_base + QXL_IO_MEMSLOT_ADD, qxl->main_mem_slot);
+
+@@ -387,8 +387,8 @@ qxl_reset (qxl_screen_t *qxl)
+ slot->start_virt_addr = (uint64_t)(uintptr_t)qxl->vram;
+ slot->end_virt_addr = (uint64_t)(uintptr_t)qxl->vram + (uint64_t)qxl->vram_size;
+
+- ram_header->mem_slot_start = slot->start_phys_addr;
+- ram_header->mem_slot_end = slot->end_phys_addr;
++ ram_header->mem_slot.mem_start = slot->start_phys_addr;
++ ram_header->mem_slot.mem_end = slot->end_phys_addr;
+
+ outb (qxl->io_base + QXL_IO_MEMSLOT_ADD, qxl->vram_mem_slot);
+
+@@ -826,7 +826,7 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_ram_header *ram_header;
++ struct QXLRam *ram_header;
+ VisualPtr visual;
+
+ CHECK_POINT();
+@@ -903,13 +903,13 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ qxl->io_pages = (void *)((unsigned long)qxl->ram);
+ qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
+
+- qxl->command_ring = qxl_ring_create (&(ram_header->cmd_ring_hdr),
++ qxl->command_ring = qxl_ring_create (&(ram_header->cmd_ring),
+ sizeof (struct QXLCommand),
+ 32, qxl->io_base + QXL_IO_NOTIFY_CMD);
+- qxl->cursor_ring = qxl_ring_create (&(ram_header->cursor_ring_hdr),
++ qxl->cursor_ring = qxl_ring_create (&(ram_header->cursor_ring),
+ sizeof (struct QXLCommand),
+ 32, qxl->io_base + QXL_IO_NOTIFY_CURSOR);
+- qxl->release_ring = qxl_ring_create (&(ram_header->release_ring_hdr),
++ qxl->release_ring = qxl_ring_create (&(ram_header->release_ring),
+ sizeof (uint64_t),
+ 8, 0);
+
+@@ -1027,7 +1027,7 @@ qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
+ {
+ int scrnIndex = pScrn->scrnIndex;
+ struct QXLRom *rom = qxl->rom;
+- struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
++ struct QXLRam *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
+
+ CHECK_POINT();
+
+diff --git a/src/qxl_surface.c b/src/qxl_surface.c
+index 0ada697..993c271 100644
+--- a/src/qxl_surface.c
++++ b/src/qxl_surface.c
+@@ -343,7 +343,7 @@ qxl_surface_t *
+ qxl_surface_cache_create_primary (surface_cache_t *cache,
+ struct QXLMode *mode)
+ {
+- struct qxl_ram_header *ram_header =
++ struct QXLRam *ram_header =
+ (void *)((unsigned long)cache->qxl->ram + cache->qxl->rom->ram_header_offset);
+ struct QXLSurfaceCreate *create = &(ram_header->create_surface);
+ pixman_format_code_t format;
+@@ -904,7 +904,7 @@ qxl_surface_flush (qxl_surface_t *surface)
+ static void
+ download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+ {
+- struct qxl_ram_header *ram_header = get_ram_header (surface->cache->qxl);
++ struct QXLRam *ram_header = get_ram_header (surface->cache->qxl);
+
+ ram_header->update_area.top = y1;
+ ram_header->update_area.bottom = y2;
+--
+1.7.4.4
+
diff --git a/0007-Don-t-re-upload-read-only-surfaces-after-a-software-.patch b/0007-Don-t-re-upload-read-only-surfaces-after-a-software-.patch
new file mode 100644
index 0000000..1ef2679
--- /dev/null
+++ b/0007-Don-t-re-upload-read-only-surfaces-after-a-software-.patch
@@ -0,0 +1,107 @@
+From 81e3d5c118bbe75688be61d7739a48452f1a9415 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Sat, 19 Mar 2011 11:56:00 -0400
+Subject: [PATCH 07/13] Don't re-upload read-only surfaces after a software
+ fallback.
+
+Surfaces that were used in a read-only way don't need to be uploaded
+again since they didn't change. This is a particularly important
+optimization for Composite since sources and masks there don't have
+tight damage tracking regions.
+---
+ src/qxl_surface.c | 38 ++++++++++++++++++++++++--------------
+ 1 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/src/qxl_surface.c b/src/qxl_surface.c
+index 993c271..88b3ebb 100644
+--- a/src/qxl_surface.c
++++ b/src/qxl_surface.c
+@@ -56,6 +56,7 @@ struct qxl_surface_t
+ pixman_image_t * dev_image;
+ pixman_image_t * host_image;
+
++ uxa_access_t access_type;
+ RegionRec access_region;
+
+ void * address;
+@@ -139,6 +140,7 @@ surface_cache_init (surface_cache_t *cache, qxl_screen_t *qxl)
+
+ REGION_INIT (
+ NULL, &(cache->all_surfaces[i].access_region), (BoxPtr)NULL, 0);
++ cache->all_surfaces[i].access_type = UXA_ACCESS_RO;
+
+ if (i) /* surface 0 is the primary surface */
+ {
+@@ -309,7 +311,7 @@ surface_get_from_cache (surface_cache_t *cache, int width, int height, int bpp)
+ return NULL;
+ }
+
+-static n_live;
++static int n_live;
+
+ void
+ qxl_surface_recycle (surface_cache_t *cache, uint32_t id)
+@@ -401,6 +403,7 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
+ #endif
+
+ REGION_INIT (NULL, &(surface->access_region), (BoxPtr)NULL, 0);
++ surface->access_type = UXA_ACCESS_RO;
+
+ return surface;
+ }
+@@ -945,6 +948,9 @@ qxl_surface_prepare_access (qxl_surface_t *surface,
+ REGION_INIT (NULL, &new, (BoxPtr)NULL, 0);
+ REGION_SUBTRACT (NULL, &new, region, &surface->access_region);
+
++ if (access == UXA_ACCESS_RW)
++ surface->access_type = UXA_ACCESS_RW;
++
+ region = &new;
+
+ n_boxes = REGION_NUM_RECTS (region);
+@@ -1066,25 +1072,29 @@ qxl_surface_finish_access (qxl_surface_t *surface, PixmapPtr pixmap)
+ n_boxes = REGION_NUM_RECTS (&surface->access_region);
+ boxes = REGION_RECTS (&surface->access_region);
+
+- if (n_boxes < 25)
++ if (surface->access_type == UXA_ACCESS_RW)
+ {
+- while (n_boxes--)
++ if (n_boxes < 25)
+ {
+- upload_box (surface, boxes->x1, boxes->y1, boxes->x2, boxes->y2);
+-
+- boxes++;
++ while (n_boxes--)
++ {
++ upload_box (surface, boxes->x1, boxes->y1, boxes->x2, boxes->y2);
++
++ boxes++;
++ }
++ }
++ else
++ {
++ upload_box (surface,
++ surface->access_region.extents.x1,
++ surface->access_region.extents.y1,
++ surface->access_region.extents.x2,
++ surface->access_region.extents.y2);
+ }
+- }
+- else
+- {
+- upload_box (surface,
+- surface->access_region.extents.x1,
+- surface->access_region.extents.y1,
+- surface->access_region.extents.x2,
+- surface->access_region.extents.y2);
+ }
+
+ REGION_EMPTY (pScreen, &surface->access_region);
++ surface->access_type = UXA_ACCESS_RO;
+
+ pScreen->ModifyPixmapHeader(pixmap, w, h, -1, -1, 0, NULL);
+ }
+--
+1.7.4.4
+
diff --git a/0008-Tiled-upload-of-images-after-software-fallback.patch b/0008-Tiled-upload-of-images-after-software-fallback.patch
new file mode 100644
index 0000000..f442fd4
--- /dev/null
+++ b/0008-Tiled-upload-of-images-after-software-fallback.patch
@@ -0,0 +1,60 @@
+From ab8fd100430f7a142799960ce371b36f4c673cda Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at localhost.localdomain>
+Date: Sat, 19 Mar 2011 15:19:13 -0400
+Subject: [PATCH 08/13] Tiled upload of images after software fallback.
+
+Instead of uploading the full software image in one go, upload it in
+512x512 tiles to avoid having to find huge huge blocks of memory and
+potentially running out.
+---
+ src/qxl_surface.c | 27 ++++++++++++++++++++++++++-
+ 1 files changed, 26 insertions(+), 1 deletions(-)
+
+diff --git a/src/qxl_surface.c b/src/qxl_surface.c
+index 88b3ebb..bf91483 100644
+--- a/src/qxl_surface.c
++++ b/src/qxl_surface.c
+@@ -1024,7 +1024,7 @@ translate_rect (struct QXLRect *rect)
+ }
+
+ static void
+-upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
++real_upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+ {
+ struct QXLRect rect;
+ struct QXLDrawable *drawable;
+@@ -1060,6 +1060,31 @@ upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
+ push_drawable (qxl, drawable);
+ }
+
++#define TILE_WIDTH 512
++#define TILE_HEIGHT 512
++
++static void
++upload_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
++{
++ int tile_x1, tile_y1;
++
++ for (tile_y1 = y1; tile_y1 < y2; tile_y1 += TILE_HEIGHT)
++ {
++ for (tile_x1 = x1; tile_x1 < x2; tile_x1 += TILE_WIDTH)
++ {
++ int tile_x2 = tile_x1 + TILE_WIDTH;
++ int tile_y2 = tile_y1 + TILE_HEIGHT;
++
++ if (tile_x2 > x2)
++ tile_x2 = x2;
++ if (tile_y2 > y2)
++ tile_y2 = y2;
++
++ real_upload_box (surface, tile_x1, tile_y1, tile_x2, tile_y2);
++ }
++ }
++}
++
+ void
+ qxl_surface_finish_access (qxl_surface_t *surface, PixmapPtr pixmap)
+ {
+--
+1.7.4.4
+
diff --git a/0009-Generate-tighter-damage-for-PolyFillRect.patch b/0009-Generate-tighter-damage-for-PolyFillRect.patch
new file mode 100644
index 0000000..53db29a
--- /dev/null
+++ b/0009-Generate-tighter-damage-for-PolyFillRect.patch
@@ -0,0 +1,61 @@
+From ae165af1ad3fed9d6443f5733afecfb3b577a1aa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Sat, 19 Mar 2011 13:38:06 -0400
+Subject: [PATCH 09/13] Generate tighter damage for PolyFillRect
+
+https://bugzilla.redhat.com/show_bug.cgi?id=552000
+---
+ src/uxa/uxa-damage.c | 35 ++++++++++++++---------------------
+ 1 files changed, 14 insertions(+), 21 deletions(-)
+
+diff --git a/src/uxa/uxa-damage.c b/src/uxa/uxa-damage.c
+index 2259a43..586c466 100644
+--- a/src/uxa/uxa-damage.c
++++ b/src/uxa/uxa-damage.c
+@@ -869,29 +869,22 @@ uxa_damage_poly_fill_rect (RegionPtr region,
+ {
+ if (nRects && checkGCDamage (pGC))
+ {
+- BoxRec box;
+- xRectangle *pRectsTmp = pRects;
+- int nRectsTmp = nRects;
+-
+- box.x1 = pRectsTmp->x;
+- box.x2 = box.x1 + pRectsTmp->width;
+- box.y1 = pRectsTmp->y;
+- box.y2 = box.y1 + pRectsTmp->height;
+-
+- while(--nRectsTmp)
++ int i;
++
++ for (i = 0; i < nRects; ++i)
+ {
+- pRectsTmp++;
+- if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+- if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+- box.x2 = pRectsTmp->x + pRectsTmp->width;
+- if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+- if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+- box.y2 = pRectsTmp->y + pRectsTmp->height;
++ xRectangle *rect = &(pRects[i]);
++ BoxRec box;
++
++ box.x1 = rect->x;
++ box.x2 = rect->x + rect->width;
++ box.y1 = rect->y;
++ box.y2 = rect->y + rect->height;
++
++ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
++ if(BOX_NOT_EMPTY(box))
++ add_box (region, &box, pDrawable, pGC->subWindowMode);
+ }
+-
+- TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+- if(BOX_NOT_EMPTY(box))
+- add_box (region, &box, pDrawable, pGC->subWindowMode);
+ }
+ }
+
+--
+1.7.4.4
+
diff --git a/0010-Fix-VT-switching.patch b/0010-Fix-VT-switching.patch
new file mode 100644
index 0000000..ad2146c
--- /dev/null
+++ b/0010-Fix-VT-switching.patch
@@ -0,0 +1,133 @@
+From b8b8754421f98cc6edc7993e5b65b9228102bcd1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Sun, 20 Mar 2011 14:15:07 -0400
+Subject: [PATCH 10/13] Fix VT switching
+
+- Surfaces need to be evacuated before switching VT
+
+- The device must be reset
+
+- Framebuffer access must be turned off
+
+- Pixmaps created while switched away must be created in host memory.
+---
+ src/qxl.h | 3 +++
+ src/qxl_driver.c | 26 +++++++++++++++++++++++---
+ src/uxa/uxa.c | 7 +++++++
+ src/uxa/uxa.h | 1 +
+ 4 files changed, 34 insertions(+), 3 deletions(-)
+
+diff --git a/src/qxl.h b/src/qxl.h
+index 1c79ec8..60a1046 100644
+--- a/src/qxl.h
++++ b/src/qxl.h
+@@ -153,6 +153,9 @@ struct _qxl_screen_t
+ uint8_t vram_mem_slot;
+
+ surface_cache_t * surface_cache;
++
++ /* Evacuated surfaces are stored here during VT switches */
++ void * vt_surfaces;
+ };
+
+ static inline uint64_t
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index d174d05..b8f2812 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -678,6 +678,9 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
+ #if 0
+ ErrorF ("Create pixmap: %d %d @ %d (usage: %d)\n", w, h, depth, usage);
+ #endif
++
++ if (uxa_swapped_out (screen))
++ goto fallback;
+
+ surface = qxl_surface_create (qxl->surface_cache, w, h, depth);
+
+@@ -705,13 +708,13 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
+ ErrorF (" Couldn't allocate %d x %d @ %d surface in video memory\n",
+ w, h, depth);
+ #endif
+-
++ fallback:
+ pixmap = fbCreatePixmap (screen, w, h, depth, usage);
+
+ #if 0
+ ErrorF ("Create pixmap %p without surface\n", pixmap);
+ #endif
+-}
++ }
+
+ return pixmap;
+ }
+@@ -961,10 +964,20 @@ static Bool
+ qxl_enter_vt(int scrnIndex, int flags)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+-
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
+ qxl_save_state(pScrn);
+ qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
+
++ if (qxl->vt_surfaces)
++ {
++ qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);
++
++ qxl->vt_surfaces = NULL;
++ }
++
++ pScrn->EnableDisableFBAccess (scrnIndex, TRUE);
++
+ return TRUE;
+ }
+
+@@ -972,7 +985,14 @@ static void
+ qxl_leave_vt(int scrnIndex, int flags)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
+
++ pScrn->EnableDisableFBAccess (scrnIndex, FALSE);
++
++ qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
++
++ outb(qxl->io_base + QXL_IO_RESET, 0);
++
+ qxl_restore_state(pScrn);
+ }
+
+diff --git a/src/uxa/uxa.c b/src/uxa/uxa.c
+index 71609fa..83e06cc 100644
+--- a/src/uxa/uxa.c
++++ b/src/uxa/uxa.c
+@@ -391,6 +391,13 @@ void uxa_set_force_fallback(ScreenPtr screen, Bool value)
+ uxa_screen->force_fallback = value;
+ }
+
++Bool uxa_swapped_out(ScreenPtr screen)
++{
++ uxa_screen_t *uxa_screen = uxa_get_screen (screen);
++
++ return uxa_screen->swappedOut;
++}
++
+ /**
+ * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's
+ * screen private, before calling down to the next CloseSccreen.
+diff --git a/src/uxa/uxa.h b/src/uxa/uxa.h
+index 379d384..2eb4041 100644
+--- a/src/uxa/uxa.h
++++ b/src/uxa/uxa.h
+@@ -572,6 +572,7 @@ uxa_get_color_for_pixmap (PixmapPtr pixmap,
+
+ void uxa_set_fallback_debug(ScreenPtr screen, Bool enable);
+ void uxa_set_force_fallback(ScreenPtr screen, Bool enable);
++Bool uxa_swapped_out (ScreenPtr screen);
+
+ /**
+ * Returns TRUE if the given planemask covers all the significant bits in the
+--
+1.7.4.4
+
diff --git a/0011-Add-old-driver-in-as-a-compatibility-layer.patch b/0011-Add-old-driver-in-as-a-compatibility-layer.patch
new file mode 100644
index 0000000..74f67d6
--- /dev/null
+++ b/0011-Add-old-driver-in-as-a-compatibility-layer.patch
@@ -0,0 +1,3878 @@
+From 60ac65a18e9cc7cf9cf78013dffd2005682f32aa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Thu, 3 Feb 2011 05:53:01 -0500
+Subject: [PATCH 11/13] Add old driver in as a compatibility layer
+
+---
+ configure.ac | 1 +
+ src/Makefile.am | 2 +-
+ src/compat/Makefile.am | 41 ++
+ src/compat/compat-lookup3.c | 769 +++++++++++++++++++++
+ src/compat/compat-lookup3.h | 26 +
+ src/compat/compat-qxl.h | 610 +++++++++++++++++
+ src/compat/compat-qxl_cursor.c | 196 ++++++
+ src/compat/compat-qxl_driver.c | 1454 ++++++++++++++++++++++++++++++++++++++++
+ src/compat/compat-qxl_image.c | 255 +++++++
+ src/compat/compat-qxl_mem.c | 321 +++++++++
+ src/compat/compat-qxl_ring.c | 97 +++
+ 11 files changed, 3771 insertions(+), 1 deletions(-)
+ create mode 100644 src/compat/Makefile.am
+ create mode 100644 src/compat/compat-lookup3.c
+ create mode 100644 src/compat/compat-lookup3.h
+ create mode 100644 src/compat/compat-qxl.h
+ create mode 100644 src/compat/compat-qxl_cursor.c
+ create mode 100644 src/compat/compat-qxl_driver.c
+ create mode 100644 src/compat/compat-qxl_image.c
+ create mode 100644 src/compat/compat-qxl_mem.c
+ create mode 100644 src/compat/compat-qxl_ring.c
+
+diff --git a/configure.ac b/configure.ac
+index ce67b41..c865439 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -85,5 +85,6 @@ AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+ src/uxa/Makefile
++ src/compat/Makefile
+ ])
+ AC_OUTPUT
+diff --git a/src/Makefile.am b/src/Makefile.am
+index ff4fa14..f3a65bf 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -25,7 +25,7 @@
+ # _ladir passes a dummy rpath to libtool so the thing will actually link
+ # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+-SUBDIRS=uxa
++SUBDIRS=uxa compat
+
+ AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS)
+
+diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
+new file mode 100644
+index 0000000..84a30f2
+--- /dev/null
++++ b/src/compat/Makefile.am
+@@ -0,0 +1,41 @@
++# Copyright 2008 Red Hat, Inc.
++#
++# 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
++# on the rights to use, copy, modify, merge, publish, distribute, sub
++# license, 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 (including the next
++# paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
++# THE AUTHORS 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.
++
++
++# this is obnoxious:
++# -module lets us name the module exactly how we want
++# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
++# _ladir passes a dummy rpath to libtool so the thing will actually link
++# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
++qxl_drv_la_LTLIBRARIES = qxl_drv.la
++qxl_drv_la_LDFLAGS = -module -avoid-version
++qxl_drv_ladir = @moduledir@/drivers
++AM_CFLAGS = -g
++AM_CFLAGS = $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS)
++
++qxl_drv_la_SOURCES = \
++ compat-qxl.h \
++ compat-qxl_driver.c \
++ compat-qxl_image.c \
++ compat-qxl_ring.c \
++ compat-qxl_mem.c \
++ compat-lookup3.c \
++ compat-lookup3.h \
++ compat-qxl_cursor.c
+diff --git a/src/compat/compat-lookup3.c b/src/compat/compat-lookup3.c
+new file mode 100644
+index 0000000..c301d85
+--- /dev/null
++++ b/src/compat/compat-lookup3.c
+@@ -0,0 +1,769 @@
++/*
++-------------------------------------------------------------------------------
++lookup3.c, by Bob Jenkins, May 2006, Public Domain.
++
++These are functions for producing 32-bit hashes for hash table lookup.
++hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
++are externally useful functions. Routines to test the hash are included
++if SELF_TEST is defined. You can use this free for any purpose. It's in
++the public domain. It has no warranty.
++
++You probably want to use hashlittle(). hashlittle() and hashbig()
++hash byte arrays. hashlittle() is is faster than hashbig() on
++little-endian machines. Intel and AMD are little-endian machines.
++On second thought, you probably want hashlittle2(), which is identical to
++hashlittle() except it returns two 32-bit hashes for the price of one.
++You could implement hashbig2() if you wanted but I haven't bothered here.
++
++If you want to find a hash of, say, exactly 7 integers, do
++ a = i1; b = i2; c = i3;
++ mix(a,b,c);
++ a += i4; b += i5; c += i6;
++ mix(a,b,c);
++ a += i7;
++ final(a,b,c);
++then use c as the hash value. If you have a variable length array of
++4-byte integers to hash, use hashword(). If you have a byte array (like
++a character string), use hashlittle(). If you have several byte arrays, or
++a mix of things, see the comments above hashlittle().
++
++Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
++then mix those integers. This is fast (you can do a lot more thorough
++mixing with 12*3 instructions on 3 integers than you can with 3 instructions
++on 1 byte), but shoehorning those bytes into integers efficiently is messy.
++-------------------------------------------------------------------------------
++*/
++
++#include <stdio.h> /* defines printf for tests */
++#include <time.h> /* defines time_t for timings in the test */
++#include "compat-lookup3.h"
++#ifdef linux
++# include <endian.h> /* attempt to define endianness */
++#endif
++
++/*
++ * My best guess at if you are big-endian or little-endian. This may
++ * need adjustment.
++ */
++#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
++ __BYTE_ORDER == __LITTLE_ENDIAN) || \
++ (defined(i386) || defined(__i386__) || defined(__i486__) || \
++ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
++# define HASH_LITTLE_ENDIAN 1
++# define HASH_BIG_ENDIAN 0
++#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
++ __BYTE_ORDER == __BIG_ENDIAN) || \
++ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
++# define HASH_LITTLE_ENDIAN 0
++# define HASH_BIG_ENDIAN 1
++#else
++# define HASH_LITTLE_ENDIAN 0
++# define HASH_BIG_ENDIAN 0
++#endif
++
++#define hashsize(n) ((uint32_t)1<<(n))
++#define hashmask(n) (hashsize(n)-1)
++#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
++
++/*
++-------------------------------------------------------------------------------
++mix -- mix 3 32-bit values reversibly.
++
++This is reversible, so any information in (a,b,c) before mix() is
++still in (a,b,c) after mix().
++
++If four pairs of (a,b,c) inputs are run through mix(), or through
++mix() in reverse, there are at least 32 bits of the output that
++are sometimes the same for one pair and different for another pair.
++This was tested for:
++* pairs that differed by one bit, by two bits, in any combination
++ of top bits of (a,b,c), or in any combination of bottom bits of
++ (a,b,c).
++* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
++ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
++ is commonly produced by subtraction) look like a single 1-bit
++ difference.
++* the base values were pseudorandom, all zero but one bit set, or
++ all zero plus a counter that starts at zero.
++
++Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
++satisfy this are
++ 4 6 8 16 19 4
++ 9 15 3 18 27 15
++ 14 9 3 7 17 3
++Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
++for "differ" defined as + with a one-bit base and a two-bit delta. I
++used http://burtleburtle.net/bob/hash/avalanche.html to choose
++the operations, constants, and arrangements of the variables.
++
++This does not achieve avalanche. There are input bits of (a,b,c)
++that fail to affect some output bits of (a,b,c), especially of a. The
++most thoroughly mixed value is c, but it doesn't really even achieve
++avalanche in c.
++
++This allows some parallelism. Read-after-writes are good at doubling
++the number of bits affected, so the goal of mixing pulls in the opposite
++direction as the goal of parallelism. I did what I could. Rotates
++seem to cost as much as shifts on every machine I could lay my hands
++on, and rotates are much kinder to the top and bottom bits, so I used
++rotates.
++-------------------------------------------------------------------------------
++*/
++#define mix(a,b,c) \
++{ \
++ a -= c; a ^= rot(c, 4); c += b; \
++ b -= a; b ^= rot(a, 6); a += c; \
++ c -= b; c ^= rot(b, 8); b += a; \
++ a -= c; a ^= rot(c,16); c += b; \
++ b -= a; b ^= rot(a,19); a += c; \
++ c -= b; c ^= rot(b, 4); b += a; \
++}
++
++/*
++-------------------------------------------------------------------------------
++final -- final mixing of 3 32-bit values (a,b,c) into c
++
++Pairs of (a,b,c) values differing in only a few bits will usually
++produce values of c that look totally different. This was tested for
++* pairs that differed by one bit, by two bits, in any combination
++ of top bits of (a,b,c), or in any combination of bottom bits of
++ (a,b,c).
++* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
++ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
++ is commonly produced by subtraction) look like a single 1-bit
++ difference.
++* the base values were pseudorandom, all zero but one bit set, or
++ all zero plus a counter that starts at zero.
++
++These constants passed:
++ 14 11 25 16 4 14 24
++ 12 14 25 16 4 14 24
++and these came close:
++ 4 8 15 26 3 22 24
++ 10 8 15 26 3 22 24
++ 11 8 15 26 3 22 24
++-------------------------------------------------------------------------------
++*/
++#define final(a,b,c) \
++{ \
++ c ^= b; c -= rot(b,14); \
++ a ^= c; a -= rot(c,11); \
++ b ^= a; b -= rot(a,25); \
++ c ^= b; c -= rot(b,16); \
++ a ^= c; a -= rot(c,4); \
++ b ^= a; b -= rot(a,14); \
++ c ^= b; c -= rot(b,24); \
++}
++
++/*
++--------------------------------------------------------------------
++ This works on all machines. To be useful, it requires
++ -- that the key be an array of uint32_t's, and
++ -- that the length be the number of uint32_t's in the key
++
++ The function hashword() is identical to hashlittle() on little-endian
++ machines, and identical to hashbig() on big-endian machines,
++ except that the length has to be measured in uint32_ts rather than in
++ bytes. hashlittle() is more complicated than hashword() only because
++ hashlittle() has to dance around fitting the key bytes into registers.
++--------------------------------------------------------------------
++*/
++uint32_t hashword(
++ const uint32_t *k, /* the key, an array of uint32_t values */
++ size_t length, /* the length of the key, in uint32_ts */
++ uint32_t initval) /* the previous hash, or an arbitrary value */
++{
++ uint32_t a,b,c;
++
++ /* Set up the internal state */
++ a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval;
++
++ /*------------------------------------------------- handle most of the key */
++ while (length > 3)
++ {
++ a += k[0];
++ b += k[1];
++ c += k[2];
++ mix(a,b,c);
++ length -= 3;
++ k += 3;
++ }
++
++ /*------------------------------------------- handle the last 3 uint32_t's */
++ switch(length) /* all the case statements fall through */
++ {
++ case 3 : c+=k[2];
++ case 2 : b+=k[1];
++ case 1 : a+=k[0];
++ final(a,b,c);
++ case 0: /* case 0: nothing left to add */
++ break;
++ }
++ /*------------------------------------------------------ report the result */
++ return c;
++}
++
++
++/*
++--------------------------------------------------------------------
++hashword2() -- same as hashword(), but take two seeds and return two
++32-bit values. pc and pb must both be nonnull, and *pc and *pb must
++both be initialized with seeds. If you pass in (*pb)==0, the output
++(*pc) will be the same as the return value from hashword().
++--------------------------------------------------------------------
++*/
++void hashword2 (
++const uint32_t *k, /* the key, an array of uint32_t values */
++size_t length, /* the length of the key, in uint32_ts */
++uint32_t *pc, /* IN: seed OUT: primary hash value */
++uint32_t *pb) /* IN: more seed OUT: secondary hash value */
++{
++ uint32_t a,b,c;
++
++ /* Set up the internal state */
++ a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc;
++ c += *pb;
++
++ /*------------------------------------------------- handle most of the key */
++ while (length > 3)
++ {
++ a += k[0];
++ b += k[1];
++ c += k[2];
++ mix(a,b,c);
++ length -= 3;
++ k += 3;
++ }
++
++ /*------------------------------------------- handle the last 3 uint32_t's */
++ switch(length) /* all the case statements fall through */
++ {
++ case 3 : c+=k[2];
++ case 2 : b+=k[1];
++ case 1 : a+=k[0];
++ final(a,b,c);
++ case 0: /* case 0: nothing left to add */
++ break;
++ }
++ /*------------------------------------------------------ report the result */
++ *pc=c; *pb=b;
++}
++
++
++/*
++-------------------------------------------------------------------------------
++hashlittle() -- hash a variable-length key into a 32-bit value
++ k : the key (the unaligned variable-length array of bytes)
++ length : the length of the key, counting by bytes
++ initval : can be any 4-byte value
++Returns a 32-bit value. Every bit of the key affects every bit of
++the return value. Two keys differing by one or two bits will have
++totally different hash values.
++
++The best hash table sizes are powers of 2. There is no need to do
++mod a prime (mod is sooo slow!). If you need less than 32 bits,
++use a bitmask. For example, if you need only 10 bits, do
++ h = (h & hashmask(10));
++In which case, the hash table should have hashsize(10) elements.
++
++If you are hashing n strings (uint8_t **)k, do it like this:
++ for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
++
++By Bob Jenkins, 2006. bob_jenkins at burtleburtle.net. You may use this
++code any way you wish, private, educational, or commercial. It's free.
++
++Use for hash table lookup, or anything where one collision in 2^^32 is
++acceptable. Do NOT use for cryptographic purposes.
++-------------------------------------------------------------------------------
++*/
++
++uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
++{
++ uint32_t a,b,c; /* internal state */
++ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
++
++ /* Set up the internal state */
++ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
++
++ u.ptr = key;
++ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
++ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
++#ifdef VALGRIND
++ const uint8_t *k8;
++#endif
++
++ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += k[0];
++ b += k[1];
++ c += k[2];
++ mix(a,b,c);
++ length -= 12;
++ k += 3;
++ }
++
++ /*----------------------------- handle the last (probably partial) block */
++ /*
++ * "k[2]&0xffffff" actually reads beyond the end of the string, but
++ * then masks off the part it's not allowed to read. Because the
++ * string is aligned, the masked-off tail is in the same word as the
++ * rest of the string. Every machine with memory protection I've seen
++ * does it on word boundaries, so is OK with this. But VALGRIND will
++ * still catch it and complain. The masking trick does make the hash
++ * noticably faster for short strings (like English words).
++ */
++#ifndef VALGRIND
++
++ switch(length)
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
++ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
++ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
++ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
++ case 5 : b+=k[1]&0xff; a+=k[0]; break;
++ case 4 : a+=k[0]; break;
++ case 3 : a+=k[0]&0xffffff; break;
++ case 2 : a+=k[0]&0xffff; break;
++ case 1 : a+=k[0]&0xff; break;
++ case 0 : return c; /* zero length strings require no mixing */
++ }
++
++#else /* make valgrind happy */
++
++ k8 = (const uint8_t *)k;
++ switch(length)
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
++ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
++ case 9 : c+=k8[8]; /* fall through */
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
++ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
++ case 5 : b+=k8[4]; /* fall through */
++ case 4 : a+=k[0]; break;
++ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
++ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
++ case 1 : a+=k8[0]; break;
++ case 0 : return c;
++ }
++
++#endif /* !valgrind */
++
++ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
++ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
++ const uint8_t *k8;
++
++ /*--------------- all but last block: aligned reads and different mixing */
++ while (length > 12)
++ {
++ a += k[0] + (((uint32_t)k[1])<<16);
++ b += k[2] + (((uint32_t)k[3])<<16);
++ c += k[4] + (((uint32_t)k[5])<<16);
++ mix(a,b,c);
++ length -= 12;
++ k += 6;
++ }
++
++ /*----------------------------- handle the last (probably partial) block */
++ k8 = (const uint8_t *)k;
++ switch(length)
++ {
++ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
++ b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
++ case 10: c+=k[4];
++ b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 9 : c+=k8[8]; /* fall through */
++ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
++ case 6 : b+=k[2];
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 5 : b+=k8[4]; /* fall through */
++ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
++ case 2 : a+=k[0];
++ break;
++ case 1 : a+=k8[0];
++ break;
++ case 0 : return c; /* zero length requires no mixing */
++ }
++
++ } else { /* need to read the key one byte at a time */
++ const uint8_t *k = (const uint8_t *)key;
++
++ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += k[0];
++ a += ((uint32_t)k[1])<<8;
++ a += ((uint32_t)k[2])<<16;
++ a += ((uint32_t)k[3])<<24;
++ b += k[4];
++ b += ((uint32_t)k[5])<<8;
++ b += ((uint32_t)k[6])<<16;
++ b += ((uint32_t)k[7])<<24;
++ c += k[8];
++ c += ((uint32_t)k[9])<<8;
++ c += ((uint32_t)k[10])<<16;
++ c += ((uint32_t)k[11])<<24;
++ mix(a,b,c);
++ length -= 12;
++ k += 12;
++ }
++
++ /*-------------------------------- last block: affect all 32 bits of (c) */
++ switch(length) /* all the case statements fall through */
++ {
++ case 12: c+=((uint32_t)k[11])<<24;
++ case 11: c+=((uint32_t)k[10])<<16;
++ case 10: c+=((uint32_t)k[9])<<8;
++ case 9 : c+=k[8];
++ case 8 : b+=((uint32_t)k[7])<<24;
++ case 7 : b+=((uint32_t)k[6])<<16;
++ case 6 : b+=((uint32_t)k[5])<<8;
++ case 5 : b+=k[4];
++ case 4 : a+=((uint32_t)k[3])<<24;
++ case 3 : a+=((uint32_t)k[2])<<16;
++ case 2 : a+=((uint32_t)k[1])<<8;
++ case 1 : a+=k[0];
++ break;
++ case 0 : return c;
++ }
++ }
++
++ final(a,b,c);
++ return c;
++}
++
++
++/*
++ * hashlittle2: return 2 32-bit hash values
++ *
++ * This is identical to hashlittle(), except it returns two 32-bit hash
++ * values instead of just one. This is good enough for hash table
++ * lookup with 2^^64 buckets, or if you want a second hash if you're not
++ * happy with the first, or if you want a probably-unique 64-bit ID for
++ * the key. *pc is better mixed than *pb, so use *pc first. If you want
++ * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
++ */
++void hashlittle2(
++ const void *key, /* the key to hash */
++ size_t length, /* length of the key */
++ uint32_t *pc, /* IN: primary initval, OUT: primary hash */
++ uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */
++{
++ uint32_t a,b,c; /* internal state */
++ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
++
++ /* Set up the internal state */
++ a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc;
++ c += *pb;
++
++ u.ptr = key;
++ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
++ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
++#ifdef VALGRIND
++ const uint8_t *k8;
++#endif
++
++ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += k[0];
++ b += k[1];
++ c += k[2];
++ mix(a,b,c);
++ length -= 12;
++ k += 3;
++ }
++
++ /*----------------------------- handle the last (probably partial) block */
++ /*
++ * "k[2]&0xffffff" actually reads beyond the end of the string, but
++ * then masks off the part it's not allowed to read. Because the
++ * string is aligned, the masked-off tail is in the same word as the
++ * rest of the string. Every machine with memory protection I've seen
++ * does it on word boundaries, so is OK with this. But VALGRIND will
++ * still catch it and complain. The masking trick does make the hash
++ * noticably faster for short strings (like English words).
++ */
++#ifndef VALGRIND
++
++ switch(length)
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
++ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
++ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
++ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
++ case 5 : b+=k[1]&0xff; a+=k[0]; break;
++ case 4 : a+=k[0]; break;
++ case 3 : a+=k[0]&0xffffff; break;
++ case 2 : a+=k[0]&0xffff; break;
++ case 1 : a+=k[0]&0xff; break;
++ case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
++ }
++
++#else /* make valgrind happy */
++
++ k8 = (const uint8_t *)k;
++ switch(length)
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
++ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
++ case 9 : c+=k8[8]; /* fall through */
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
++ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
++ case 5 : b+=k8[4]; /* fall through */
++ case 4 : a+=k[0]; break;
++ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
++ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
++ case 1 : a+=k8[0]; break;
++ case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
++ }
++
++#endif /* !valgrind */
++
++ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
++ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
++ const uint8_t *k8;
++
++ /*--------------- all but last block: aligned reads and different mixing */
++ while (length > 12)
++ {
++ a += k[0] + (((uint32_t)k[1])<<16);
++ b += k[2] + (((uint32_t)k[3])<<16);
++ c += k[4] + (((uint32_t)k[5])<<16);
++ mix(a,b,c);
++ length -= 12;
++ k += 6;
++ }
++
++ /*----------------------------- handle the last (probably partial) block */
++ k8 = (const uint8_t *)k;
++ switch(length)
++ {
++ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
++ b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
++ case 10: c+=k[4];
++ b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 9 : c+=k8[8]; /* fall through */
++ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
++ case 6 : b+=k[2];
++ a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 5 : b+=k8[4]; /* fall through */
++ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
++ break;
++ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
++ case 2 : a+=k[0];
++ break;
++ case 1 : a+=k8[0];
++ break;
++ case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
++ }
++
++ } else { /* need to read the key one byte at a time */
++ const uint8_t *k = (const uint8_t *)key;
++
++ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += k[0];
++ a += ((uint32_t)k[1])<<8;
++ a += ((uint32_t)k[2])<<16;
++ a += ((uint32_t)k[3])<<24;
++ b += k[4];
++ b += ((uint32_t)k[5])<<8;
++ b += ((uint32_t)k[6])<<16;
++ b += ((uint32_t)k[7])<<24;
++ c += k[8];
++ c += ((uint32_t)k[9])<<8;
++ c += ((uint32_t)k[10])<<16;
++ c += ((uint32_t)k[11])<<24;
++ mix(a,b,c);
++ length -= 12;
++ k += 12;
++ }
++
++ /*-------------------------------- last block: affect all 32 bits of (c) */
++ switch(length) /* all the case statements fall through */
++ {
++ case 12: c+=((uint32_t)k[11])<<24;
++ case 11: c+=((uint32_t)k[10])<<16;
++ case 10: c+=((uint32_t)k[9])<<8;
++ case 9 : c+=k[8];
++ case 8 : b+=((uint32_t)k[7])<<24;
++ case 7 : b+=((uint32_t)k[6])<<16;
++ case 6 : b+=((uint32_t)k[5])<<8;
++ case 5 : b+=k[4];
++ case 4 : a+=((uint32_t)k[3])<<24;
++ case 3 : a+=((uint32_t)k[2])<<16;
++ case 2 : a+=((uint32_t)k[1])<<8;
++ case 1 : a+=k[0];
++ break;
++ case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
++ }
++ }
++
++ final(a,b,c);
++ *pc=c; *pb=b;
++}
++
++
++
++/*
++ * hashbig():
++ * This is the same as hashword() on big-endian machines. It is different
++ * from hashlittle() on all machines. hashbig() takes advantage of
++ * big-endian byte ordering.
++ */
++uint32_t hashbig( const void *key, size_t length, uint32_t initval)
++{
++ uint32_t a,b,c;
++ union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
++
++ /* Set up the internal state */
++ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
++
++ u.ptr = key;
++ if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
++ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
++#ifdef VALGRIND
++ const uint8_t *k8;
++#endif
++
++ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += k[0];
++ b += k[1];
++ c += k[2];
++ mix(a,b,c);
++ length -= 12;
++ k += 3;
++ }
++
++ /*----------------------------- handle the last (probably partial) block */
++ /*
++ * "k[2]<<8" actually reads beyond the end of the string, but
++ * then shifts out the part it's not allowed to read. Because the
++ * string is aligned, the illegal read is in the same word as the
++ * rest of the string. Every machine with memory protection I've seen
++ * does it on word boundaries, so is OK with this. But VALGRIND will
++ * still catch it and complain. The masking trick does make the hash
++ * noticably faster for short strings (like English words).
++ */
++#ifndef VALGRIND
++
++ switch(length)
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
++ case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
++ case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;
++ case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;
++ case 5 : b+=k[1]&0xff000000; a+=k[0]; break;
++ case 4 : a+=k[0]; break;
++ case 3 : a+=k[0]&0xffffff00; break;
++ case 2 : a+=k[0]&0xffff0000; break;
++ case 1 : a+=k[0]&0xff000000; break;
++ case 0 : return c; /* zero length strings require no mixing */
++ }
++
++#else /* make valgrind happy */
++
++ k8 = (const uint8_t *)k;
++ switch(length) /* all the case statements fall through */
++ {
++ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
++ case 11: c+=((uint32_t)k8[10])<<8; /* fall through */
++ case 10: c+=((uint32_t)k8[9])<<16; /* fall through */
++ case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */
++ case 8 : b+=k[1]; a+=k[0]; break;
++ case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */
++ case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */
++ case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */
++ case 4 : a+=k[0]; break;
++ case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */
++ case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */
++ case 1 : a+=((uint32_t)k8[0])<<24; break;
++ case 0 : return c;
++ }
++
++#endif /* !VALGRIND */
++
++ } else { /* need to read the key one byte at a time */
++ const uint8_t *k = (const uint8_t *)key;
++
++ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
++ while (length > 12)
++ {
++ a += ((uint32_t)k[0])<<24;
++ a += ((uint32_t)k[1])<<16;
++ a += ((uint32_t)k[2])<<8;
++ a += ((uint32_t)k[3]);
++ b += ((uint32_t)k[4])<<24;
++ b += ((uint32_t)k[5])<<16;
++ b += ((uint32_t)k[6])<<8;
++ b += ((uint32_t)k[7]);
++ c += ((uint32_t)k[8])<<24;
++ c += ((uint32_t)k[9])<<16;
++ c += ((uint32_t)k[10])<<8;
++ c += ((uint32_t)k[11]);
++ mix(a,b,c);
++ length -= 12;
++ k += 12;
++ }
++
++ /*-------------------------------- last block: affect all 32 bits of (c) */
++ switch(length) /* all the case statements fall through */
++ {
++ case 12: c+=k[11];
++ case 11: c+=((uint32_t)k[10])<<8;
++ case 10: c+=((uint32_t)k[9])<<16;
++ case 9 : c+=((uint32_t)k[8])<<24;
++ case 8 : b+=k[7];
++ case 7 : b+=((uint32_t)k[6])<<8;
++ case 6 : b+=((uint32_t)k[5])<<16;
++ case 5 : b+=((uint32_t)k[4])<<24;
++ case 4 : a+=k[3];
++ case 3 : a+=((uint32_t)k[2])<<8;
++ case 2 : a+=((uint32_t)k[1])<<16;
++ case 1 : a+=((uint32_t)k[0])<<24;
++ break;
++ case 0 : return c;
++ }
++ }
++
++ final(a,b,c);
++ return c;
++}
++
+diff --git a/src/compat/compat-lookup3.h b/src/compat/compat-lookup3.h
+new file mode 100644
+index 0000000..50c1cf4
+--- /dev/null
++++ b/src/compat/compat-lookup3.h
+@@ -0,0 +1,26 @@
++#ifndef __LOOKUP3_H
++#define __LOOKUP3_H
++
++#if defined(__GNUC__) || defined(__sun)
++
++#include <stdint.h>
++
++#else
++
++#ifdef QXLDD
++#include <windef.h>
++#include "os_dep.h"
++#else
++#include <stddef.h>
++#include <basetsd.h>
++#endif
++
++typedef UINT32 uint32_t;
++typedef UINT16 uint16_t;
++typedef UINT8 uint8_t;
++
++#endif
++
++uint32_t hashlittle( const void *key, size_t length, uint32_t initval);
++
++#endif
+diff --git a/src/compat/compat-qxl.h b/src/compat/compat-qxl.h
+new file mode 100644
+index 0000000..bec43b3
+--- /dev/null
++++ b/src/compat/compat-qxl.h
+@@ -0,0 +1,610 @@
++/*
++ * Copyright 2008 Red Hat, Inc.
++ *
++ * 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
++ * on the rights to use, copy, modify, merge, publish, distribute, sub
++ * license, 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 (including the next
++ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS 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 "config.h"
++
++#include <stdint.h>
++
++#include "compiler.h"
++#include "xf86.h"
++#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
++#include "xf86Resources.h"
++#endif
++#include "xf86PciInfo.h"
++#include "xf86Cursor.h"
++#include "xf86_OSproc.h"
++#include "xf86xv.h"
++#include "shadow.h"
++#include "micmap.h"
++#ifdef XSERVER_PCIACCESS
++#include "pciaccess.h"
++#endif
++#include "fb.h"
++#include "vgaHW.h"
++
++#define hidden _X_HIDDEN
++
++#define QXL_NAME "qxl"
++#define QXL_DRIVER_NAME "qxl"
++#define PCI_VENDOR_RED_HAT 0x1b36
++
++#define PCI_CHIP_QXL_0100 0x0100
++
++#pragma pack(push,1)
++
++/* I/O port definitions */
++enum {
++ QXL_IO_NOTIFY_CMD,
++ QXL_IO_NOTIFY_CURSOR,
++ QXL_IO_UPDATE_AREA,
++ QXL_IO_UPDATE_IRQ,
++ QXL_IO_NOTIFY_OOM,
++ QXL_IO_RESET,
++ QXL_IO_SET_MODE,
++ QXL_IO_LOG,
++};
++
++struct qxl_mode {
++ uint32_t id;
++ uint32_t x_res;
++ uint32_t y_res;
++ uint32_t bits;
++ uint32_t stride;
++ uint32_t x_mili;
++ uint32_t y_mili;
++ uint32_t orientation;
++};
++
++typedef enum
++{
++ QXL_CMD_NOP,
++ QXL_CMD_DRAW,
++ QXL_CMD_UPDATE,
++ QXL_CMD_CURSOR,
++ QXL_CMD_MESSAGE
++} qxl_command_type;
++
++struct qxl_command {
++ uint64_t data;
++ uint32_t type;
++ uint32_t pad;
++};
++
++struct qxl_rect {
++ uint32_t top;
++ uint32_t left;
++ uint32_t bottom;
++ uint32_t right;
++};
++
++union qxl_release_info {
++ uint64_t id;
++ uint64_t next;
++};
++
++struct qxl_clip {
++ uint32_t type;
++ uint64_t address;
++};
++
++struct qxl_point {
++ int x;
++ int y;
++};
++
++struct qxl_pattern {
++ uint64_t pat;
++ struct qxl_point pos;
++};
++
++typedef enum
++{
++ QXL_BRUSH_TYPE_NONE,
++ QXL_BRUSH_TYPE_SOLID,
++ QXL_BRUSH_TYPE_PATTERN
++} qxl_brush_type;
++
++struct qxl_brush {
++ uint32_t type;
++ union {
++ uint32_t color;
++ struct qxl_pattern pattern;
++ } u;
++};
++
++struct qxl_mask {
++ unsigned char flags;
++ struct qxl_point pos;
++ uint64_t bitmap;
++};
++
++typedef enum {
++ QXL_IMAGE_TYPE_BITMAP,
++ QXL_IMAGE_TYPE_QUIC,
++ QXL_IMAGE_TYPE_PNG,
++ QXL_IMAGE_TYPE_LZ_PLT = 100,
++ QXL_IMAGE_TYPE_LZ_RGB,
++ QXL_IMAGE_TYPE_GLZ_RGB,
++ QXL_IMAGE_TYPE_FROM_CACHE,
++} qxl_image_type;
++
++typedef enum {
++ QXL_IMAGE_CACHE = (1 << 0)
++} qxl_image_flags;
++
++struct qxl_image_descriptor
++{
++ uint64_t id;
++ uint8_t type;
++ uint8_t flags;
++ uint32_t width;
++ uint32_t height;
++};
++
++struct qxl_data_chunk {
++ uint32_t data_size;
++ uint64_t prev_chunk;
++ uint64_t next_chunk;
++ uint8_t data[0];
++};
++
++typedef enum
++{
++ QXL_BITMAP_FMT_INVALID,
++ QXL_BITMAP_FMT_1BIT_LE,
++ QXL_BITMAP_FMT_1BIT_BE,
++ QXL_BITMAP_FMT_4BIT_LE,
++ QXL_BITMAP_FMT_4BIT_BE,
++ QXL_BITMAP_FMT_8BIT,
++ QXL_BITMAP_FMT_16BIT,
++ QXL_BITMAP_FMT_24BIT,
++ QXL_BITMAP_FMT_32BIT,
++ QXL_BITMAP_FMT_RGBA,
++} qxl_bitmap_format;
++
++typedef enum {
++ QXL_BITMAP_PAL_CACHE_ME = (1 << 0),
++ QXL_BITMAP_PAL_FROM_CACHE = (1 << 1),
++ QXL_BITMAP_TOP_DOWN = (1 << 2),
++} qxl_bitmap_flags;
++
++struct qxl_bitmap {
++ uint8_t format;
++ uint8_t flags;
++ uint32_t x; /* actually width */
++ uint32_t y; /* actually height */
++ uint32_t stride; /* in bytes */
++ uint64_t palette; /* Can be NULL */
++ uint64_t data; /* A qxl_data_chunk that actually contains the data */
++};
++
++struct qxl_image {
++ struct qxl_image_descriptor descriptor;
++ union
++ {
++ struct qxl_bitmap bitmap;
++ } u;
++};
++
++struct qxl_fill {
++ struct qxl_brush brush;
++ unsigned short rop_descriptor;
++ struct qxl_mask mask;
++};
++
++struct qxl_opaque {
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++ struct qxl_brush brush;
++ unsigned short rop_descriptor;
++ unsigned char scale_mode;
++ struct qxl_mask mask;
++};
++
++struct qxl_copy {
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++ unsigned short rop_descriptor;
++ unsigned char scale_mode;
++ struct qxl_mask mask;
++};
++
++struct qxl_transparent {
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++ uint32_t src_color;
++ uint32_t true_color;
++};
++
++struct qxl_alpha_blend {
++ unsigned char alpha;
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++};
++
++struct qxl_copy_bits {
++ struct qxl_point src_pos;
++};
++
++struct qxl_blend { /* same as copy */
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++ unsigned short rop_descriptor;
++ unsigned char scale_mode;
++ struct qxl_mask mask;
++};
++
++struct qxl_rop3 {
++ uint64_t src_bitmap;
++ struct qxl_rect src_area;
++ struct qxl_brush brush;
++ unsigned char rop3;
++ unsigned char scale_mode;
++ struct qxl_mask mask;
++};
++
++struct qxl_line_attr {
++ unsigned char flags;
++ unsigned char join_style;
++ unsigned char end_style;
++ unsigned char style_nseg;
++ int width;
++ int miter_limit;
++ uint64_t style;
++};
++
++struct qxl_stroke {
++ uint64_t path;
++ struct qxl_line_attr attr;
++ struct qxl_brush brush;
++ unsigned short fore_mode;
++ unsigned short back_mode;
++};
++
++struct qxl_text {
++ uint64_t str;
++ struct qxl_rect back_area;
++ struct qxl_brush fore_brush;
++ struct qxl_brush back_brush;
++ unsigned short fore_mode;
++ unsigned short back_mode;
++};
++
++struct qxl_blackness {
++ struct qxl_mask mask;
++};
++
++struct qxl_inverse {
++ struct qxl_mask mask;
++};
++
++struct qxl_whiteness {
++ struct qxl_mask mask;
++};
++
++/* Effects */
++typedef enum
++{
++ QXL_EFFECT_BLEND,
++ QXL_EFFECT_OPAQUE,
++ QXL_EFFECT_REVERT_ON_DUP,
++ QXL_EFFECT_BLACKNESS_ON_DUP,
++ QXL_EFFECT_WHITENESS_ON_DUP,
++ QXL_EFFECT_NOP_ON_DUP,
++ QXL_EFFECT_NOP,
++ QXL_EFFECT_OPAQUE_BRUSH
++} qxl_effect_type;
++
++typedef enum
++{
++ QXL_CLIP_TYPE_NONE,
++ QXL_CLIP_TYPE_RECTS,
++ QXL_CLIP_TYPE_PATH,
++} qxl_clip_type;
++
++typedef enum {
++ QXL_DRAW_NOP,
++ QXL_DRAW_FILL,
++ QXL_DRAW_OPAQUE,
++ QXL_DRAW_COPY,
++ QXL_COPY_BITS,
++ QXL_DRAW_BLEND,
++ QXL_DRAW_BLACKNESS,
++ QXL_DRAW_WHITENESS,
++ QXL_DRAW_INVERS,
++ QXL_DRAW_ROP3,
++ QXL_DRAW_STROKE,
++ QXL_DRAW_TEXT,
++ QXL_DRAW_TRANSPARENT,
++ QXL_DRAW_ALPHA_BLEND,
++} qxl_draw_type;
++
++struct qxl_drawable {
++ union qxl_release_info release_info;
++ unsigned char effect;
++ unsigned char type;
++ unsigned short bitmap_offset;
++ struct qxl_rect bitmap_area;
++ struct qxl_rect bbox;
++ struct qxl_clip clip;
++ uint32_t mm_time;
++ union {
++ struct qxl_fill fill;
++ struct qxl_opaque opaque;
++ struct qxl_copy copy;
++ struct qxl_transparent transparent;
++ struct qxl_alpha_blend alpha_blend;
++ struct qxl_copy_bits copy_bits;
++ struct qxl_blend blend;
++ struct qxl_rop3 rop3;
++ struct qxl_stroke stroke;
++ struct qxl_text text;
++ struct qxl_blackness blackness;
++ struct qxl_inverse inverse;
++ struct qxl_whiteness whiteness;
++ } u;
++};
++
++struct qxl_update_cmd {
++ union qxl_release_info release_info;
++ struct qxl_rect area;
++ uint32_t update_id;
++};
++
++struct qxl_point16 {
++ int16_t x;
++ int16_t y;
++};
++
++enum {
++ QXL_CURSOR_SET,
++ QXL_CURSOR_MOVE,
++ QXL_CURSOR_HIDE,
++ QXL_CURSOR_TRAIL,
++};
++
++#define QXL_CURSOR_DEVICE_DATA_SIZE 128
++
++enum {
++ CURSOR_TYPE_ALPHA,
++ CURSOR_TYPE_MONO,
++ CURSOR_TYPE_COLOR4,
++ CURSOR_TYPE_COLOR8,
++ CURSOR_TYPE_COLOR16,
++ CURSOR_TYPE_COLOR24,
++ CURSOR_TYPE_COLOR32,
++};
++
++struct qxl_cursor_header {
++ uint64_t unique;
++ uint16_t type;
++ uint16_t width;
++ uint16_t height;
++ uint16_t hot_spot_x;
++ uint16_t hot_spot_y;
++};
++
++struct qxl_cursor
++{
++ struct qxl_cursor_header header;
++ uint32_t data_size;
++ struct qxl_data_chunk chunk;
++};
++
++struct qxl_cursor_cmd {
++ union qxl_release_info release_info;
++ uint8_t type;
++ union {
++ struct {
++ struct qxl_point16 position;
++ unsigned char visible;
++ uint64_t shape;
++ } set;
++ struct {
++ uint16_t length;
++ uint16_t frequency;
++ } trail;
++ struct qxl_point16 position;
++ } u;
++ uint8_t device_data[QXL_CURSOR_DEVICE_DATA_SIZE];
++};
++
++struct qxl_rom {
++ uint32_t magic;
++ uint32_t id;
++ uint32_t update_id;
++ uint32_t compression_level;
++ uint32_t log_level;
++ uint32_t mode;
++ uint32_t modes_offset;
++ uint32_t num_io_pages;
++ uint32_t pages_offset;
++ uint32_t draw_area_offset;
++ uint32_t draw_area_size;
++ uint32_t ram_header_offset;
++ uint32_t mm_clock;
++};
++
++struct qxl_ring_header {
++ uint32_t num_items;
++ uint32_t prod;
++ uint32_t notify_on_prod;
++ uint32_t cons;
++ uint32_t notify_on_cons;
++};
++
++#define QXL_LOG_BUF_SIZE 4096
++
++struct qxl_ram_header {
++ uint32_t magic;
++ uint32_t int_pending;
++ uint32_t int_mask;
++ unsigned char log_buf[QXL_LOG_BUF_SIZE];
++ struct qxl_ring_header cmd_ring_hdr;
++ struct qxl_command cmd_ring[32];
++ struct qxl_ring_header cursor_ring_hdr;
++ struct qxl_command cursor_ring[32];
++ struct qxl_ring_header release_ring_hdr;
++ uint64_t release_ring[8];
++ struct qxl_rect update_area;
++};
++
++#pragma pack(pop)
++
++typedef struct _qxl_screen_t qxl_screen_t;
++
++struct _qxl_screen_t
++{
++ /* These are the names QXL uses */
++ void * ram; /* Video RAM */
++ void * ram_physical;
++ void * vram; /* Command RAM */
++ struct qxl_rom * rom; /* Parameter RAM */
++
++ struct qxl_ring * command_ring;
++ struct qxl_ring * cursor_ring;
++ struct qxl_ring * release_ring;
++
++ int num_modes;
++ struct qxl_mode * modes;
++ int io_base;
++ int draw_area_offset;
++ int draw_area_size;
++
++ void * fb;
++ int bytes_per_pixel;
++
++ struct qxl_mem * mem; /* Context for qxl_alloc/free */
++
++ EntityInfoPtr entity;
++
++ void * io_pages;
++ void * io_pages_physical;
++
++#ifdef XSERVER_LIBPCIACCESS
++ struct pci_device * pci;
++#else
++ pciVideoPtr pci;
++ PCITAG pci_tag;
++#endif
++ vgaRegRec vgaRegs;
++
++ CreateScreenResourcesProcPtr create_screen_resources;
++ CloseScreenProcPtr close_screen;
++ CreateGCProcPtr create_gc;
++#if 0
++ PaintWindowProcPtr paint_window_background;
++ PaintWindowProcPtr paint_window_border;
++#endif
++ CopyWindowProcPtr copy_window;
++
++ DamagePtr damage;
++ RegionRec pending_copy;
++ RegionRec to_be_sent;
++
++ int16_t cur_x;
++ int16_t cur_y;
++ int16_t hot_x;
++ int16_t hot_y;
++
++ ScrnInfoPtr pScrn;
++};
++
++static inline uint64_t
++physical_address (qxl_screen_t *qxl, void *virtual)
++{
++ return (uint64_t) ((unsigned long)virtual + (((unsigned long)qxl->ram_physical - (unsigned long)qxl->ram)));
++}
++
++static inline void *
++virtual_address (qxl_screen_t *qxl, void *physical)
++{
++ return (void *) ((unsigned long)physical + ((unsigned long)qxl->ram - (unsigned long)qxl->ram_physical));
++}
++
++static inline void *
++u64_to_pointer (uint64_t u)
++{
++ return (void *)(unsigned long)u;
++}
++
++static inline uint64_t
++pointer_to_u64 (void *p)
++{
++ return (uint64_t)(unsigned long)p;
++}
++
++struct qxl_ring;
++
++/*
++ * HW cursor
++ */
++void qxl_cursor_init (ScreenPtr pScreen);
++
++
++
++/*
++ * Rings
++ */
++struct qxl_ring * qxl_ring_create (struct qxl_ring_header *header,
++ int element_size,
++ int n_elements,
++ int prod_notify);
++void qxl_ring_push (struct qxl_ring *ring,
++ const void *element);
++Bool qxl_ring_pop (struct qxl_ring *ring,
++ void *element);
++void qxl_ring_wait_idle (struct qxl_ring *ring);
++
++
++
++/*
++ * Images
++ */
++struct qxl_image *qxl_image_create (qxl_screen_t *qxl,
++ const uint8_t *data,
++ int x,
++ int y,
++ int width,
++ int height,
++ int stride);
++void qxl_image_destroy (qxl_screen_t *qxl,
++ struct qxl_image *image);
++void qxl_drop_image_cache (qxl_screen_t *qxl);
++
++
++/*
++ * Malloc
++ */
++struct qxl_mem * qxl_mem_create (void *base,
++ unsigned long n_bytes);
++void qxl_mem_dump_stats (struct qxl_mem *mem,
++ const char *header);
++void * qxl_alloc (struct qxl_mem *mem,
++ unsigned long n_bytes);
++void qxl_free (struct qxl_mem *mem,
++ void *d);
++void qxl_mem_free_all (struct qxl_mem *mem);
++void * qxl_allocnf (qxl_screen_t *qxl,
++ unsigned long size);
++
++
+diff --git a/src/compat/compat-qxl_cursor.c b/src/compat/compat-qxl_cursor.c
+new file mode 100644
+index 0000000..bb5387e
+--- /dev/null
++++ b/src/compat/compat-qxl_cursor.c
+@@ -0,0 +1,196 @@
++/*
++ * Copyright 2009 Red Hat, Inc.
++ *
++ * 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
++ * on the rights to use, copy, modify, merge, publish, distribute, sub
++ * license, 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 (including the next
++ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS 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 <string.h>
++#include "compat-qxl.h"
++#include <cursorstr.h>
++
++static void
++push_cursor (qxl_screen_t *qxl, struct qxl_cursor_cmd *cursor)
++{
++ struct qxl_command cmd;
++
++ /* See comment on push_command() in qxl_driver.c */
++ if (qxl->rom->mode != ~0)
++ {
++ cmd.type = QXL_CMD_CURSOR;
++ cmd.data = physical_address (qxl, cursor);
++
++ qxl_ring_push (qxl->cursor_ring, &cmd);
++ }
++}
++
++static struct qxl_cursor_cmd *
++qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
++{
++ struct qxl_cursor_cmd *cmd =
++ qxl_allocnf (qxl, sizeof(struct qxl_cursor_cmd));
++
++ cmd->release_info.id = pointer_to_u64 (cmd) | 1;
++
++ return cmd;
++}
++
++static void
++qxl_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
++{
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd(qxl);
++
++ qxl->cur_x = x;
++ qxl->cur_y = y;
++
++ cmd->type = QXL_CURSOR_MOVE;
++ cmd->u.position.x = qxl->cur_x + qxl->hot_x;
++ cmd->u.position.y = qxl->cur_y + qxl->hot_y;
++
++ push_cursor(qxl, cmd);
++}
++
++static void
++qxl_load_cursor_image(ScrnInfoPtr pScrn, unsigned char *bits)
++{
++}
++
++static void
++qxl_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
++{
++ /* Should not be called since UseHWCursor returned FALSE */
++}
++
++static void
++qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
++{
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ int w = pCurs->bits->width;
++ int h = pCurs->bits->height;
++ int size = w * h * sizeof (CARD32);
++
++ struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd (qxl);
++ struct qxl_cursor *cursor =
++ qxl_allocnf(qxl, sizeof(struct qxl_cursor) + size);
++
++ cursor->header.unique = 0;
++ cursor->header.type = CURSOR_TYPE_ALPHA;
++ cursor->header.width = w;
++ cursor->header.height = h;
++ /* I wonder if we can just tell the client that the hotspot is 0, 0
++ * always? The coordinates we are getting from X are for 0, 0 anyway,
++ * so the question is if the client uses the hotspot for anything else?
++ */
++ cursor->header.hot_spot_x = pCurs->bits->xhot;
++ cursor->header.hot_spot_y = pCurs->bits->yhot;
++
++ cursor->data_size = size;
++
++ cursor->chunk.next_chunk = 0;
++ cursor->chunk.prev_chunk = 0;
++ cursor->chunk.data_size = size;
++
++ memcpy (cursor->chunk.data, pCurs->bits->argb, size);
++
++#if 0
++ int i, j;
++ for (j = 0; j < h; ++j)
++ {
++ for (i = 0; i < w; ++i)
++ {
++ ErrorF ("%c", (pCurs->bits->argb[j * w + i] & 0xff000000) == 0xff000000? '#' : '.');
++ }
++
++ ErrorF ("\n");
++ }
++#endif
++
++ qxl->hot_x = pCurs->bits->xhot;
++ qxl->hot_y = pCurs->bits->yhot;
++
++ cmd->type = QXL_CURSOR_SET;
++ cmd->u.set.position.x = qxl->cur_x + qxl->hot_x;
++ cmd->u.set.position.y = qxl->cur_y + qxl->hot_y;
++ cmd->u.set.shape = physical_address (qxl, cursor);
++ cmd->u.set.visible = TRUE;
++
++ push_cursor(qxl, cmd);
++}
++
++static Bool
++qxl_use_hw_cursor (ScreenPtr pScrn, CursorPtr pCurs)
++{
++ /* Old-school bitmap cursors are not
++ * hardware accelerated for now.
++ */
++ return FALSE;
++}
++
++static Bool
++qxl_use_hw_cursorARGB (ScreenPtr pScrn, CursorPtr pCurs)
++{
++ return TRUE;
++}
++
++static void
++qxl_hide_cursor(ScrnInfoPtr pScrn)
++{
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ struct qxl_cursor_cmd *cursor = qxl_alloc_cursor_cmd(qxl);
++
++ cursor->type = QXL_CURSOR_HIDE;
++
++ push_cursor(qxl, cursor);
++}
++
++static void
++qxl_show_cursor(ScrnInfoPtr pScrn)
++{
++ /*
++ * slightly hacky, but there's no QXL_CURSOR_SHOW. Could maybe do
++ * QXL_CURSOR_SET?
++ */
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
++ qxl_set_cursor_position(pScrn, qxl->cur_x, qxl->cur_y);
++}
++
++hidden void
++qxl_cursor_init(ScreenPtr pScreen)
++{
++ xf86CursorInfoPtr cursor;
++
++ cursor = xcalloc(1, sizeof(xf86CursorInfoRec));
++ if (!cursor)
++ return;
++
++ cursor->MaxWidth = cursor->MaxHeight = 64;
++ /* cursor->Flags; */
++ cursor->SetCursorPosition = qxl_set_cursor_position;
++ cursor->LoadCursorARGB = qxl_load_cursor_argb;
++ cursor->UseHWCursor = qxl_use_hw_cursor;
++ cursor->UseHWCursorARGB = qxl_use_hw_cursorARGB;
++ cursor->LoadCursorImage = qxl_load_cursor_image;
++ cursor->SetCursorColors = qxl_set_cursor_colors;
++ cursor->HideCursor = qxl_hide_cursor;
++ cursor->ShowCursor = qxl_show_cursor;
++
++ if (!xf86InitCursor(pScreen, cursor))
++ xfree(cursor);
++}
+diff --git a/src/compat/compat-qxl_driver.c b/src/compat/compat-qxl_driver.c
+new file mode 100644
+index 0000000..7cd5f40
+--- /dev/null
++++ b/src/compat/compat-qxl_driver.c
+@@ -0,0 +1,1454 @@
++/*
++ * Copyright 2008 Red Hat, Inc.
++ *
++ * 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
++ * on the rights to use, copy, modify, merge, publish, distribute, sub
++ * license, 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 (including the next
++ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS 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.
++ */
++
++/** \file qxl_driver.c
++ * \author Adam Jackson <ajax at redhat.com>
++ *
++ * This is qxl, a driver for the Qumranet paravirtualized graphics device
++ * in qemu.
++ */
++
++#include <unistd.h>
++#include <string.h>
++#include <stdio.h>
++#include <errno.h>
++#include <time.h>
++#include <stdlib.h>
++#include "compat-qxl.h"
++#include "assert.h"
++
++#define CHECK_POINT()
++
++static int
++garbage_collect (qxl_screen_t *qxl)
++{
++ uint64_t id;
++ int i = 0;
++
++ while (qxl_ring_pop (qxl->release_ring, &id))
++ {
++ while (id)
++ {
++ /* We assume that there the two low bits of a pointer are
++ * available. If the low one is set, then the command in
++ * question is a cursor command
++ */
++#define POINTER_MASK ((1 << 2) - 1)
++
++ union qxl_release_info *info = u64_to_pointer (id & ~POINTER_MASK);
++ struct qxl_cursor_cmd *cmd = (struct qxl_cursor_cmd *)info;
++ struct qxl_drawable *drawable = (struct qxl_drawable *)info;
++ int is_cursor = FALSE;
++
++ if ((id & POINTER_MASK) == 1)
++ is_cursor = TRUE;
++
++ if (is_cursor && cmd->type == QXL_CURSOR_SET)
++ {
++ struct qxl_cursor *cursor = (void *)virtual_address (
++ qxl, u64_to_pointer (cmd->u.set.shape));
++
++ qxl_free (qxl->mem, cursor);
++ }
++ else if (!is_cursor && drawable->type == QXL_DRAW_COPY)
++ {
++ struct qxl_image *image = virtual_address (
++ qxl, u64_to_pointer (drawable->u.copy.src_bitmap));
++
++ qxl_image_destroy (qxl, image);
++ }
++
++ id = info->next;
++
++ qxl_free (qxl->mem, info);
++ }
++ }
++
++ return i > 0;
++}
++
++static void
++qxl_usleep (int useconds)
++{
++ struct timespec t;
++
++ t.tv_sec = useconds / 1000000;
++ t.tv_nsec = (useconds - (t.tv_sec * 1000000)) * 1000;
++
++ errno = 0;
++ while (nanosleep (&t, &t) == -1 && errno == EINTR)
++ ;
++
++}
++
++#if 0
++static void
++push_update_area (qxl_screen_t *qxl, const struct qxl_rect *area)
++{
++ struct qxl_update_cmd *update = qxl_allocnf (qxl, sizeof *update);
++ struct qxl_command cmd;
++
++ update->release_info.id = (uint64_t)update;
++ update->area = *area;
++ update->update_id = 0;
++
++ cmd.type = QXL_CMD_UDPATE;
++ cmd.data = physical_address (qxl, update);
++
++ qxl_ring_push (qxl->command_ring, &cmd);
++}
++#endif
++
++void *
++qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
++{
++ void *result;
++ int n_attempts = 0;
++ static int nth_oom = 1;
++
++ garbage_collect (qxl);
++
++ while (!(result = qxl_alloc (qxl->mem, size)))
++ {
++ struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram +
++ qxl->rom->ram_header_offset);
++
++ /* Rather than go out of memory, we simply tell the
++ * device to dump everything
++ */
++ ram_header->update_area.top = 0;
++ ram_header->update_area.bottom = 1280;
++ ram_header->update_area.left = 0;
++ ram_header->update_area.right = 800;
++
++ outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
++
++ ErrorF ("eliminated memory (%d)\n", nth_oom++);
++
++ outb (qxl->io_base + QXL_IO_NOTIFY_OOM, 0);
++
++ qxl_usleep (10000);
++
++ if (garbage_collect (qxl))
++ {
++ n_attempts = 0;
++ }
++ else if (++n_attempts == 1000)
++ {
++ qxl_mem_dump_stats (qxl->mem, "Out of mem - stats\n");
++
++ fprintf (stderr, "Out of memory\n");
++ exit (1);
++ }
++ }
++
++ return result;
++}
++
++static Bool
++qxl_blank_screen(ScreenPtr pScreen, int mode)
++{
++ return TRUE;
++}
++
++static void
++qxl_unmap_memory(qxl_screen_t *qxl, int scrnIndex)
++{
++#ifdef XSERVER_LIBPCIACCESS
++ if (qxl->ram)
++ pci_device_unmap_range(qxl->pci, qxl->ram, qxl->pci->regions[0].size);
++ if (qxl->vram)
++ pci_device_unmap_range(qxl->pci, qxl->vram, qxl->pci->regions[1].size);
++ if (qxl->rom)
++ pci_device_unmap_range(qxl->pci, qxl->rom, qxl->pci->regions[2].size);
++#else
++ if (qxl->ram)
++ xf86UnMapVidMem(scrnIndex, qxl->ram, (1 << qxl->pci->size[0]));
++ if (qxl->vram)
++ xf86UnMapVidMem(scrnIndex, qxl->vram, (1 << qxl->pci->size[1]));
++ if (qxl->rom)
++ xf86UnMapVidMem(scrnIndex, qxl->rom, (1 << qxl->pci->size[2]));
++#endif
++
++ qxl->ram = qxl->ram_physical = qxl->vram = qxl->rom = NULL;
++
++ qxl->num_modes = 0;
++ qxl->modes = NULL;
++}
++
++static Bool
++qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
++{
++#ifdef XSERVER_LIBPCIACCESS
++ pci_device_map_range(qxl->pci, qxl->pci->regions[0].base_addr,
++ qxl->pci->regions[0].size,
++ PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
++ &qxl->ram);
++ qxl->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr);
++
++ pci_device_map_range(qxl->pci, qxl->pci->regions[1].base_addr,
++ qxl->pci->regions[1].size,
++ PCI_DEV_MAP_FLAG_WRITABLE,
++ &qxl->vram);
++
++ pci_device_map_range(qxl->pci, qxl->pci->regions[2].base_addr,
++ qxl->pci->regions[2].size, 0,
++ (void **)&qxl->rom);
++
++ qxl->io_base = qxl->pci->regions[3].base_addr;
++#else
++ qxl->ram = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
++ qxl->pci_tag, qxl->pci->memBase[0],
++ (1 << qxl->pci->size[0]));
++ qxl->ram_physical = (void *)qxl->pci->memBase[0];
++
++ qxl->vram = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
++ qxl->pci_tag, qxl->pci->memBase[1],
++ (1 << qxl->pci->size[1]));
++
++ qxl->rom = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
++ qxl->pci_tag, qxl->pci->memBase[2],
++ (1 << qxl->pci->size[2]));
++
++ qxl->io_base = qxl->pci->ioBase[3];
++#endif
++ if (!qxl->ram || !qxl->vram || !qxl->rom)
++ return FALSE;
++
++ xf86DrvMsg(scrnIndex, X_INFO, "ram at %p; vram at %p; rom at %p\n",
++ qxl->ram, qxl->vram, qxl->rom);
++
++ qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
++ qxl->modes = (struct qxl_mode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
++
++ return TRUE;
++}
++
++static void
++qxl_save_state(ScrnInfoPtr pScrn)
++{
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
++ vgaHWSaveFonts(pScrn, &qxl->vgaRegs);
++}
++
++static void
++qxl_restore_state(ScrnInfoPtr pScrn)
++{
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
++ vgaHWRestoreFonts(pScrn, &qxl->vgaRegs);
++}
++
++static Bool
++qxl_close_screen(int scrnIndex, ScreenPtr pScreen)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
++ if (pScrn->vtSema) {
++ qxl_restore_state(pScrn);
++ qxl_unmap_memory(qxl, scrnIndex);
++ }
++ pScrn->vtSema = FALSE;
++
++ xfree(qxl->fb);
++
++ pScreen->CreateScreenResources = qxl->create_screen_resources;
++ pScreen->CloseScreen = qxl->close_screen;
++
++ return pScreen->CloseScreen(scrnIndex, pScreen);
++}
++
++static Bool
++qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
++{
++ qxl_screen_t *qxl = xf86Screens[scrnIndex]->driverPrivate;
++ int mode_index = (int)(unsigned long)p->Private;
++ struct qxl_mode *m = qxl->modes + mode_index;
++ ScreenPtr pScreen = qxl->pScrn->pScreen;
++
++ if (!m)
++ return FALSE;
++
++ /* if (debug) */
++ xf86DrvMsg (scrnIndex, X_INFO, "Setting mode %d (%d x %d) (%d x %d) %p\n",
++ m->id, m->x_res, m->y_res, p->HDisplay, p->VDisplay, p);
++
++ outb(qxl->io_base + QXL_IO_RESET, 0);
++
++ outb(qxl->io_base + QXL_IO_SET_MODE, m->id);
++
++ qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8;
++
++ /* If this happens out of ScreenInit, we won't have a screen yet. In that
++ * case createScreenResources will make things right.
++ */
++ if (pScreen)
++ {
++ PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
++
++ if (pPixmap)
++ {
++ pScreen->ModifyPixmapHeader(
++ pPixmap,
++ m->x_res, m->y_res,
++ -1, -1,
++ qxl->pScrn->displayWidth * qxl->bytes_per_pixel,
++ NULL);
++ }
++ }
++
++ if (qxl->mem)
++ {
++ qxl_mem_free_all (qxl->mem);
++ qxl_drop_image_cache (qxl);
++ }
++
++
++ return TRUE;
++}
++
++static void
++push_drawable (qxl_screen_t *qxl, struct qxl_drawable *drawable)
++{
++ struct qxl_command cmd;
++
++ /* When someone runs "init 3", the device will be
++ * switched into VGA mode and there is nothing we
++ * can do about it. We get no notification.
++ *
++ * However, if commands are submitted when the device
++ * is in VGA mode, they will be queued up, and then
++ * the next time a mode set set, an assertion in the
++ * device will take down the entire virtual machine.
++ *
++ * The author of the QXL device is opposed to this
++ * for reasons I don't understand.
++ */
++ if (qxl->rom->mode != ~0)
++ {
++ cmd.type = QXL_CMD_DRAW;
++ cmd.data = physical_address (qxl, drawable);
++
++ qxl_ring_push (qxl->command_ring, &cmd);
++ }
++}
++
++static struct qxl_drawable *
++make_drawable (qxl_screen_t *qxl, uint8_t type,
++ const struct qxl_rect *rect
++ /* , pRegion clip */)
++{
++ struct qxl_drawable *drawable;
++
++ CHECK_POINT();
++
++ drawable = qxl_allocnf (qxl, sizeof *drawable);
++
++ CHECK_POINT();
++
++ drawable->release_info.id = pointer_to_u64 (drawable);
++
++ drawable->type = type;
++
++ drawable->effect = QXL_EFFECT_OPAQUE;
++ drawable->bitmap_offset = 0;
++ drawable->bitmap_area.top = 0;
++ drawable->bitmap_area.left = 0;
++ drawable->bitmap_area.bottom = 0;
++ drawable->bitmap_area.right = 0;
++ /* FIXME: add clipping */
++ drawable->clip.type = QXL_CLIP_TYPE_NONE;
++
++ if (rect)
++ drawable->bbox = *rect;
++
++ drawable->mm_time = qxl->rom->mm_clock;
++
++ CHECK_POINT();
++
++ return drawable;
++}
++
++enum ROPDescriptor {
++ ROPD_INVERS_SRC = (1 << 0),
++ ROPD_INVERS_BRUSH = (1 << 1),
++ ROPD_INVERS_DEST = (1 << 2),
++ ROPD_OP_PUT = (1 << 3),
++ ROPD_OP_OR = (1 << 4),
++ ROPD_OP_AND = (1 << 5),
++ ROPD_OP_XOR = (1 << 6),
++ ROPD_OP_BLACKNESS = (1 << 7),
++ ROPD_OP_WHITENESS = (1 << 8),
++ ROPD_OP_INVERS = (1 << 9),
++ ROPD_INVERS_RES = (1 <<10),
++};
++
++static void
++undamage_box (qxl_screen_t *qxl, const struct qxl_rect *rect)
++{
++ RegionRec region;
++ BoxRec box;
++
++ box.x1 = rect->left;
++ box.y1 = rect->top;
++ box.x2 = rect->right;
++ box.y2 = rect->bottom;
++
++ REGION_INIT (qxl->pScrn->pScreen, ®ion, &box, 0);
++
++ REGION_SUBTRACT (qxl->pScrn->pScreen, &(qxl->pending_copy), &(qxl->pending_copy), ®ion);
++
++ REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++}
++
++static void
++clear_pending_damage (qxl_screen_t *qxl)
++{
++ REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++}
++
++static void
++submit_fill (qxl_screen_t *qxl, const struct qxl_rect *rect, uint32_t color)
++{
++ struct qxl_drawable *drawable;
++
++ CHECK_POINT();
++
++ drawable = make_drawable (qxl, QXL_DRAW_FILL, rect);
++
++ CHECK_POINT();
++
++ drawable->u.fill.brush.type = QXL_BRUSH_TYPE_SOLID;
++ drawable->u.fill.brush.u.color = color;
++ drawable->u.fill.rop_descriptor = ROPD_OP_PUT;
++ drawable->u.fill.mask.flags = 0;
++ drawable->u.fill.mask.pos.x = 0;
++ drawable->u.fill.mask.pos.y = 0;
++ drawable->u.fill.mask.bitmap = 0;
++
++ push_drawable (qxl, drawable);
++
++ undamage_box (qxl, rect);
++}
++
++static void
++translate_rect (struct qxl_rect *rect)
++{
++ rect->right -= rect->left;
++ rect->bottom -= rect->top;
++ rect->left = rect->top = 0;
++}
++
++static void
++submit_copy (qxl_screen_t *qxl, const struct qxl_rect *rect)
++{
++ struct qxl_drawable *drawable;
++ ScrnInfoPtr pScrn = qxl->pScrn;
++
++ if (rect->left == rect->right ||
++ rect->top == rect->bottom)
++ {
++ /* Empty rectangle */
++ return ;
++ }
++
++ drawable = make_drawable (qxl, QXL_DRAW_COPY, rect);
++
++ drawable->u.copy.src_bitmap = physical_address (
++ qxl, qxl_image_create (qxl, qxl->fb, rect->left, rect->top,
++ rect->right - rect->left,
++ rect->bottom - rect->top,
++ pScrn->displayWidth * qxl->bytes_per_pixel));
++ drawable->u.copy.src_area = *rect;
++ translate_rect (&drawable->u.copy.src_area);
++ drawable->u.copy.rop_descriptor = ROPD_OP_PUT;
++ drawable->u.copy.scale_mode = 0;
++ drawable->u.copy.mask.flags = 0;
++ drawable->u.copy.mask.pos.x = 0;
++ drawable->u.copy.mask.pos.y = 0;
++ drawable->u.copy.mask.bitmap = 0;
++
++ push_drawable (qxl, drawable);
++}
++
++static void
++print_region (const char *header, RegionPtr pRegion)
++{
++ int nbox = REGION_NUM_RECTS (pRegion);
++ BoxPtr pbox = REGION_RECTS (pRegion);
++
++ ErrorF ("%s \n", header);
++
++ while (nbox--)
++ {
++ ErrorF (" %d %d %d %d (size: %d %d)\n",
++ pbox->x1, pbox->y1, pbox->x2, pbox->y2,
++ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
++
++ pbox++;
++ }
++}
++
++static void
++accept_damage (qxl_screen_t *qxl)
++{
++ REGION_UNION (qxl->pScrn->pScreen, &(qxl->to_be_sent), &(qxl->to_be_sent),
++ &(qxl->pending_copy));
++
++ REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++}
++
++static void
++qxl_send_copies (qxl_screen_t *qxl)
++{
++ BoxPtr pBox;
++ int nbox;
++
++ nbox = REGION_NUM_RECTS (&qxl->to_be_sent);
++ pBox = REGION_RECTS (&qxl->to_be_sent);
++
++/* if (REGION_NUM_RECTS (&qxl->to_be_sent) > 0) */
++/* print_region ("send bits", &qxl->to_be_sent); */
++
++ while (nbox--)
++ {
++ struct qxl_rect qrect;
++
++ qrect.top = pBox->y1;
++ qrect.left = pBox->x1;
++ qrect.bottom = pBox->y2;
++ qrect.right = pBox->x2;
++
++ submit_copy (qxl, &qrect);
++
++ pBox++;
++ }
++
++ REGION_EMPTY(qxl->pScrn->pScreen, &qxl->to_be_sent);
++}
++
++static void
++paint_shadow (qxl_screen_t *qxl)
++{
++ struct qxl_rect qrect;
++
++ qrect.top = 0;
++ qrect.bottom = 1200;
++ qrect.left = 0;
++ qrect.right = 1600;
++
++ submit_copy (qxl, &qrect);
++}
++
++static void
++qxl_sanity_check (qxl_screen_t *qxl)
++{
++ /* read the mode back from the rom */
++ if (!qxl->rom || !qxl->pScrn)
++ return;
++
++ if (qxl->rom->mode == ~0)
++ {
++ ErrorF("QXL device jumped back to VGA mode - resetting mode\n");
++ qxl_switch_mode(qxl->pScrn->scrnIndex, qxl->pScrn->currentMode, 0);
++ }
++}
++
++static void
++qxl_block_handler (pointer data, OSTimePtr pTimeout, pointer pRead)
++{
++ qxl_screen_t *qxl = (qxl_screen_t *) data;
++
++ if (!qxl->pScrn->vtSema)
++ return;
++
++ qxl_sanity_check(qxl);
++
++ accept_damage (qxl);
++
++ qxl_send_copies (qxl);
++}
++
++static void
++qxl_wakeup_handler (pointer data, int i, pointer LastSelectMask)
++{
++}
++
++/* Damage Handling
++ *
++ * When something is drawn, X first generates a damage callback, then
++ * it calls the GC function to actually draw it. In most cases, we want
++ * to simply draw into the shadow framebuffer, then submit a copy to the
++ * device, but when the operation is hardware accelerated, we don't want
++ * to submit the copy. So, damage is first accumulated into 'pending_copy',
++ * then if we accelerated the operation, that damage is deleted.
++ *
++ * If we _didn't_ accelerate, we need to union the pending_copy damage
++ * onto the to_be_sent damage, and then submit a copy command in the block
++ * handler.
++ *
++ * This means that when new damage happens, if there is already pending
++ * damage, that must first be unioned onto to_be_sent, and then the new
++ * damage must be stored in pending_copy.
++ *
++ * The qxl_screen_t struct contains two regions, "pending_copy" and
++ * "to_be_sent".
++ *
++ * Pending copy is
++ *
++ */
++static void
++qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure)
++{
++ qxl_screen_t *qxl = closure;
++
++/* print_region ("damage", pRegion); */
++
++/* print_region ("on_damage ", pRegion); */
++
++ accept_damage (qxl);
++
++/* print_region ("accepting, qxl->to_be_sent is now", &qxl->to_be_sent); */
++
++ REGION_COPY (qxl->pScrn->pScreen, &(qxl->pending_copy), pRegion);
++}
++
++
++static Bool
++qxl_create_screen_resources(ScreenPtr pScreen)
++{
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ Bool ret;
++ PixmapPtr pPixmap;
++
++ pScreen->CreateScreenResources = qxl->create_screen_resources;
++ ret = pScreen->CreateScreenResources (pScreen);
++ pScreen->CreateScreenResources = qxl_create_screen_resources;
++
++ if (!ret)
++ return FALSE;
++
++ qxl->damage = DamageCreate (qxl_on_damage, NULL,
++ DamageReportRawRegion,
++ TRUE, pScreen, qxl);
++
++
++ pPixmap = pScreen->GetScreenPixmap(pScreen);
++
++ if (!RegisterBlockAndWakeupHandlers(qxl_block_handler, qxl_wakeup_handler, qxl))
++ return FALSE;
++
++ REGION_INIT (pScreen, &(qxl->pending_copy), NullBox, 0);
++
++ REGION_INIT (pScreen, &(qxl->to_be_sent), NullBox, 0);
++
++ DamageRegister (&pPixmap->drawable, qxl->damage);
++ return TRUE;
++}
++
++static PixmapPtr
++get_window_pixmap (DrawablePtr pDrawable, int *xoff, int *yoff)
++{
++ ScreenPtr pScreen = pDrawable->pScreen;
++ PixmapPtr result;
++
++ if (pDrawable->type != DRAWABLE_WINDOW)
++ return NULL;
++
++ result = pScreen->GetWindowPixmap ((WindowPtr)pDrawable);
++
++ *xoff = pDrawable->x;
++ *yoff = pDrawable->y;
++
++ return result;
++}
++
++static void
++qxl_poly_fill_rect (DrawablePtr pDrawable,
++ GCPtr pGC,
++ int nrect,
++ xRectangle *prect)
++{
++ ScrnInfoPtr pScrn = xf86Screens[pDrawable->pScreen->myNum];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ PixmapPtr pPixmap;
++ int xoff, yoff;
++
++ if ((pPixmap = get_window_pixmap (pDrawable, &xoff, &yoff)) &&
++ pGC->fillStyle == FillSolid &&
++ pGC->alu == GXcopy &&
++ (unsigned int)pGC->planemask == FB_ALLONES)
++ {
++ RegionPtr pReg = RECTS_TO_REGION (pScreen, nrect, prect, CT_UNSORTED);
++ RegionPtr pClip = fbGetCompositeClip (pGC);
++ BoxPtr pBox;
++ int nbox;
++
++ REGION_TRANSLATE(pScreen, pReg, xoff, yoff);
++ REGION_INTERSECT(pScreen, pReg, pClip, pReg);
++
++ pBox = REGION_RECTS (pReg);
++ nbox = REGION_NUM_RECTS (pReg);
++
++ while (nbox--)
++ {
++ struct qxl_rect qrect;
++
++ qrect.left = pBox->x1;
++ qrect.right = pBox->x2;
++ qrect.top = pBox->y1;
++ qrect.bottom = pBox->y2;
++
++ submit_fill (qxl, &qrect, pGC->fgPixel);
++
++ pBox++;
++ }
++
++ REGION_DESTROY (pScreen, pReg);
++ }
++
++ fbPolyFillRect (pDrawable, pGC, nrect, prect);
++}
++
++static void
++qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
++ DrawablePtr pDstDrawable,
++ GCPtr pGC,
++ BoxPtr pbox,
++ int nbox,
++ int dx,
++ int dy,
++ Bool reverse,
++ Bool upsidedown,
++ Pixel bitplane,
++ void *closure)
++{
++ ScreenPtr pScreen = pSrcDrawable->pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ int src_xoff, src_yoff;
++ int dst_xoff, dst_yoff;
++ PixmapPtr pSrcPixmap, pDstPixmap;
++
++ if ((pSrcPixmap = get_window_pixmap (pSrcDrawable, &src_xoff, &src_yoff)) &&
++ (pDstPixmap = get_window_pixmap (pDstDrawable, &dst_xoff, &dst_yoff)))
++ {
++ int n = nbox;
++ BoxPtr b = pbox;
++
++ assert (pSrcPixmap == pDstPixmap);
++
++/* ErrorF ("Accelerated copy: %d boxes\n", n); */
++
++ /* At this point we know that any pending damage must
++ * have been caused by whatever copy operation triggered us.
++ *
++ * Therefore we can clear it.
++ *
++ * We couldn't clear it at the toplevel function because
++ * the copy might end up being empty, in which case no
++ * damage would have been generated. Which means the
++ * pending damage would have been caused by some
++ * earlier operation.
++ */
++ if (n)
++ {
++/* ErrorF ("Clearing pending damage\n"); */
++ clear_pending_damage (qxl);
++
++ /* We have to do this because the copy will cause the damage
++ * to be sent to move.
++ *
++ * Instead of just sending the bits, we could also move
++ * the existing damage around; however that's a bit more
++ * complex, and the performance win is unlikely to be
++ * very big.
++ */
++ qxl_send_copies (qxl);
++ }
++
++ while (n--)
++ {
++ struct qxl_drawable *drawable;
++ struct qxl_rect qrect;
++
++ qrect.top = b->y1;
++ qrect.bottom = b->y2;
++ qrect.left = b->x1;
++ qrect.right = b->x2;
++
++/* ErrorF (" Translate %d %d %d %d by %d %d (offsets %d %d)\n", */
++/* b->x1, b->y1, b->x2, b->y2, */
++/* dx, dy, dst_xoff, dst_yoff); */
++
++ drawable = make_drawable (qxl, QXL_COPY_BITS, &qrect);
++ drawable->u.copy_bits.src_pos.x = b->x1 + dx;
++ drawable->u.copy_bits.src_pos.y = b->y1 + dy;
++
++ push_drawable (qxl, drawable);
++
++#if 0
++ if (closure)
++ qxl_usleep (1000000);
++#endif
++
++#if 0
++ submit_fill (qxl, &qrect, rand());
++#endif
++
++ b++;
++ }
++ }
++/* else */
++/* ErrorF ("Unaccelerated copy\n"); */
++
++ fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
++}
++
++static RegionPtr
++qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
++ int srcx, int srcy, int width, int height, int dstx, int dsty)
++{
++ if (pSrcDrawable->type == DRAWABLE_WINDOW &&
++ pDstDrawable->type == DRAWABLE_WINDOW)
++ {
++ RegionPtr res;
++
++/* ErrorF ("accelerated copy %d %d %d %d %d %d\n", */
++/* srcx, srcy, width, height, dstx, dsty); */
++
++ res = fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
++ srcx, srcy, width, height, dstx, dsty,
++ qxl_copy_n_to_n, 0, NULL);
++
++ return res;
++ }
++ else
++ {
++/* ErrorF ("Falling back %d %d %d %d %d %d\n", */
++/* srcx, srcy, width, height, dstx, dsty); */
++
++ return fbCopyArea (pSrcDrawable, pDstDrawable, pGC,
++ srcx, srcy, width, height, dstx, dsty);
++ }
++}
++
++static void
++qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel)
++{
++ ScreenPtr pScreen = pDrawable->pScreen;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ PixmapPtr pPixmap;
++ int xoff, yoff;
++
++ if ((pPixmap = get_window_pixmap (pDrawable, &xoff, &yoff)))
++ {
++ int nbox = REGION_NUM_RECTS (pRegion);
++ BoxPtr pBox = REGION_RECTS (pRegion);
++
++ while (nbox--)
++ {
++ struct qxl_rect qrect;
++
++ qrect.left = pBox->x1;
++ qrect.right = pBox->x2;
++ qrect.top = pBox->y1;
++ qrect.bottom = pBox->y2;
++
++ submit_fill (qxl, &qrect, pixel);
++
++ pBox++;
++ }
++ }
++
++ fbFillRegionSolid (pDrawable, pRegion, 0,
++ fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
++}
++
++static void
++qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
++{
++ RegionRec rgnDst;
++ int dx, dy;
++
++ dx = ptOldOrg.x - pWin->drawable.x;
++ dy = ptOldOrg.y - pWin->drawable.y;
++
++ REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
++
++ REGION_INIT (pScreen, &rgnDst, NullBox, 0);
++
++ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
++
++ fbCopyRegion (&pWin->drawable, &pWin->drawable,
++ NULL,
++ &rgnDst, dx, dy, qxl_copy_n_to_n, 0, NULL);
++
++ REGION_UNINIT (pScreen, &rgnDst);
++
++/* REGION_TRANSLATE (pScreen, prgnSrc, dx, dy); */
++
++/* fbCopyWindow (pWin, ptOldOrg, prgnSrc); */
++}
++
++static int
++qxl_create_gc (GCPtr pGC)
++{
++ static GCOps ops;
++ static int initialized;
++
++ if (!fbCreateGC (pGC))
++ return FALSE;
++
++ if (!initialized)
++ {
++ ops = *pGC->ops;
++ ops.PolyFillRect = qxl_poly_fill_rect;
++ ops.CopyArea = qxl_copy_area;
++
++ initialized = TRUE;
++ }
++
++ pGC->ops = &ops;
++ return TRUE;
++}
++
++static Bool
++qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ struct qxl_rom *rom;
++ struct qxl_ram_header *ram_header;
++ VisualPtr visual;
++
++ CHECK_POINT();
++
++ qxl->pScrn = pScrn;
++
++ if (!qxl_map_memory(qxl, scrnIndex))
++ return FALSE;
++
++ rom = qxl->rom;
++ ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
++
++ qxl_save_state(pScrn);
++ qxl_blank_screen(pScreen, SCREEN_SAVER_ON);
++
++ miClearVisualTypes();
++ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
++ pScrn->rgbBits, pScrn->defaultVisual))
++ goto out;
++ if (!miSetPixmapDepths())
++ goto out;
++
++ /* Note we do this before setting pScrn->virtualY to match our current
++ mode, so as to allocate a buffer large enough for the largest mode.
++ FIXME: add support for resizing the framebuffer on modeset. */
++ qxl->fb = xcalloc(pScrn->virtualY * pScrn->displayWidth, 4);
++ if (!qxl->fb)
++ goto out;
++
++ pScrn->virtualX = pScrn->currentMode->HDisplay;
++ pScrn->virtualY = pScrn->currentMode->VDisplay;
++
++ if (!fbScreenInit(pScreen, qxl->fb,
++ pScrn->currentMode->HDisplay,
++ pScrn->currentMode->VDisplay,
++ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
++ pScrn->bitsPerPixel))
++ {
++ goto out;
++ }
++
++ visual = pScreen->visuals + pScreen->numVisuals;
++ while (--visual >= pScreen->visuals)
++ {
++ if ((visual->class | DynamicClass) == DirectColor)
++ {
++ visual->offsetRed = pScrn->offset.red;
++ visual->offsetGreen = pScrn->offset.green;
++ visual->offsetBlue = pScrn->offset.blue;
++ visual->redMask = pScrn->mask.red;
++ visual->greenMask = pScrn->mask.green;
++ visual->blueMask = pScrn->mask.blue;
++ }
++ }
++
++
++ fbPictureInit(pScreen, 0, 0);
++
++ qxl->create_screen_resources = pScreen->CreateScreenResources;
++ pScreen->CreateScreenResources = qxl_create_screen_resources;
++
++ /* Set up resources */
++ qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->ram + (unsigned long)rom->pages_offset),
++ rom->num_io_pages * getpagesize());
++ qxl->io_pages = (void *)((unsigned long)qxl->ram + (unsigned long)rom->pages_offset);
++ qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical + (unsigned long)rom->pages_offset);
++
++ qxl->command_ring = qxl_ring_create (&(ram_header->cmd_ring_hdr),
++ sizeof (struct qxl_command),
++ 32, qxl->io_base + QXL_IO_NOTIFY_CMD);
++ qxl->cursor_ring = qxl_ring_create (&(ram_header->cursor_ring_hdr),
++ sizeof (struct qxl_command),
++ 32, qxl->io_base + QXL_IO_NOTIFY_CURSOR);
++ qxl->release_ring = qxl_ring_create (&(ram_header->release_ring_hdr),
++ sizeof (uint64_t),
++ 8, 0);
++
++ /* xf86DPMSInit(pScreen, xf86DPMSSet, 0); */
++
++#if 0 /* XV accel */
++ qxlInitVideo(pScreen);
++#endif
++
++ pScreen->SaveScreen = qxl_blank_screen;
++ qxl->close_screen = pScreen->CloseScreen;
++ pScreen->CloseScreen = qxl_close_screen;
++
++ qxl->create_gc = pScreen->CreateGC;
++ pScreen->CreateGC = qxl_create_gc;
++
++#if 0
++ qxl->paint_window_background = pScreen->PaintWindowBackground;
++ qxl->paint_window_border = pScreen->PaintWindowBorder;
++#endif
++ qxl->copy_window = pScreen->CopyWindow;
++#if 0
++ pScreen->PaintWindowBackground = qxl_paint_window;
++ pScreen->PaintWindowBorder = qxl_paint_window;
++#endif
++ pScreen->CopyWindow = qxl_copy_window;
++
++ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
++
++ if (!miCreateDefColormap(pScreen))
++ goto out;
++
++ qxl_cursor_init (pScreen);
++
++ CHECK_POINT();
++
++ qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
++
++ CHECK_POINT();
++
++ return TRUE;
++
++out:
++ return FALSE;
++}
++
++static Bool
++qxl_enter_vt(int scrnIndex, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++
++ qxl_save_state(pScrn);
++ qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
++
++ return TRUE;
++}
++
++static void
++qxl_leave_vt(int scrnIndex, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++
++ qxl_restore_state(pScrn);
++}
++
++static Bool
++qxl_color_setup(ScrnInfoPtr pScrn)
++{
++ int scrnIndex = pScrn->scrnIndex;
++ Gamma gzeros = { 0.0, 0.0, 0.0 };
++ rgb rzeros = { 0, 0, 0 };
++
++ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb))
++ return FALSE;
++
++ if (pScrn->depth != 15 && pScrn->depth != 24)
++ {
++ xf86DrvMsg(scrnIndex, X_ERROR, "Depth %d is not supported\n",
++ pScrn->depth);
++ return FALSE;
++ }
++ xf86PrintDepthBpp(pScrn);
++
++ if (!xf86SetWeight(pScrn, rzeros, rzeros))
++ return FALSE;
++
++ if (!xf86SetDefaultVisual(pScrn, -1))
++ return FALSE;
++
++ if (!xf86SetGamma(pScrn, gzeros))
++ return FALSE;
++
++ return TRUE;
++}
++
++static void
++print_modes (qxl_screen_t *qxl, int scrnIndex)
++{
++ int i;
++
++ for (i = 0; i < qxl->num_modes; ++i)
++ {
++ struct qxl_mode *m = qxl->modes + i;
++
++ xf86DrvMsg (scrnIndex, X_INFO,
++ "%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n",
++ m->id, m->x_res, m->y_res, m->bits, m->stride, m->x_mili,
++ m->y_mili, m->orientation);
++ }
++}
++
++static Bool
++qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
++{
++ int scrnIndex = pScrn->scrnIndex;
++ struct qxl_rom *rom = qxl->rom;
++ struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
++
++ CHECK_POINT();
++
++ if (rom->magic != 0x4f525851) { /* "QXRO" little-endian */
++ xf86DrvMsg(scrnIndex, X_ERROR, "Bad ROM signature %x\n", rom->magic);
++ return FALSE;
++ }
++
++ xf86DrvMsg(scrnIndex, X_INFO, "Device version %d.%d\n",
++ rom->id, rom->update_id);
++
++ xf86DrvMsg(scrnIndex, X_INFO, "Compression level %d, log level %d\n",
++ rom->compression_level,
++ rom->log_level);
++
++ xf86DrvMsg(scrnIndex, X_INFO, "Currently using mode #%d, list at 0x%x\n",
++ rom->mode, rom->modes_offset);
++
++ xf86DrvMsg(scrnIndex, X_INFO, "%d io pages at 0x%x\n",
++ rom->num_io_pages, rom->pages_offset);
++
++ xf86DrvMsg(scrnIndex, X_INFO, "%d byte draw area at 0x%x\n",
++ rom->draw_area_size, rom->draw_area_offset);
++
++ xf86DrvMsg(scrnIndex, X_INFO, "RAM header offset: 0x%x\n", rom->ram_header_offset);
++
++ if (ram_header->magic != 0x41525851) { /* "QXRA" little-endian */
++ xf86DrvMsg(scrnIndex, X_ERROR, "Bad RAM signature %x at %p\n",
++ ram_header->magic,
++ &ram_header->magic);
++ return FALSE;
++ }
++
++ xf86DrvMsg(scrnIndex, X_INFO, "Correct RAM signature %x\n",
++ ram_header->magic);
++
++ qxl->draw_area_offset = rom->draw_area_offset;
++ qxl->draw_area_size = rom->draw_area_size;
++ pScrn->videoRam = rom->draw_area_size / 1024;
++
++ return TRUE;
++}
++
++static int
++qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
++{
++ int i;
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++
++ CHECK_POINT();
++
++ for (i = 0; i < qxl->num_modes; i++)
++ {
++ struct qxl_mode *m = qxl->modes + i;
++
++ if (m->x_res == p->HDisplay &&
++ m->y_res == p->VDisplay &&
++ m->bits == pScrn->bitsPerPixel)
++ {
++ if (m->bits == 16)
++ {
++ /* What QXL calls 16 bit is actually x1r5g5b515 */
++ if (pScrn->depth == 15)
++ return i;
++ }
++ else if (m->bits == 32)
++ {
++ /* What QXL calls 32 bit is actually x8r8g8b8 */
++ if (pScrn->depth == 24)
++ return i;
++ }
++ }
++ }
++
++ return -1;
++}
++
++static ModeStatus
++qxl_valid_mode(int scrn, DisplayModePtr p, Bool flag, int pass)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrn];
++ qxl_screen_t *qxl = pScrn->driverPrivate;
++ int bpp = pScrn->bitsPerPixel;
++ int mode_idx;
++
++ /* FIXME: I don't think this is necessary now that we report the
++ * correct amount of video ram?
++ */
++ if (p->HDisplay * p->VDisplay * (bpp/8) > qxl->draw_area_size)
++ return MODE_MEM;
++
++ mode_idx = qxl_find_native_mode (pScrn, p);
++ if (mode_idx == -1)
++ return MODE_NOMODE;
++
++ p->Private = (void *)(unsigned long)mode_idx;
++
++ return MODE_OK;
++}
++
++static void qxl_add_mode(ScrnInfoPtr pScrn, int width, int height, int type)
++{
++ DisplayModePtr mode;
++
++ /* Skip already present modes */
++ for (mode = pScrn->monitor->Modes; mode; mode = mode->next)
++ if (mode->HDisplay == width && mode->VDisplay == height)
++ return;
++
++ mode = xnfcalloc(1, sizeof(DisplayModeRec));
++
++ mode->status = MODE_OK;
++ mode->type = type;
++ mode->HDisplay = width;
++ mode->HSyncStart = (width * 105 / 100 + 7) & ~7;
++ mode->HSyncEnd = (width * 115 / 100 + 7) & ~7;
++ mode->HTotal = (width * 130 / 100 + 7) & ~7;
++ mode->VDisplay = height;
++ mode->VSyncStart = height + 1;
++ mode->VSyncEnd = height + 4;
++ mode->VTotal = height * 1035 / 1000;
++ mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000;
++ mode->Flags = V_NHSYNC | V_PVSYNC;
++
++ xf86SetModeDefaultName(mode);
++ xf86ModesAdd(pScrn->monitor->Modes, mode);
++}
++
++static Bool
++qxl_pre_init(ScrnInfoPtr pScrn, int flags)
++{
++ int i, scrnIndex = pScrn->scrnIndex;
++ qxl_screen_t *qxl = NULL;
++ ClockRangePtr clockRanges = NULL;
++ int *linePitches = NULL;
++ DisplayModePtr mode;
++ unsigned int max_x = 0, max_y = 0;
++
++ CHECK_POINT();
++
++ /* zaphod mode is for suckers and i choose not to implement it */
++ if (xf86IsEntityShared(pScrn->entityList[0])) {
++ xf86DrvMsg(scrnIndex, X_ERROR, "No Zaphod mode for you\n");
++ return FALSE;
++ }
++
++ if (!pScrn->driverPrivate)
++ pScrn->driverPrivate = xnfcalloc(sizeof(qxl_screen_t), 1);
++ qxl = pScrn->driverPrivate;
++
++ qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
++ qxl->pci = xf86GetPciInfoForEntity(qxl->entity->index);
++#ifndef XSERVER_LIBPCIACCESS
++ qxl->pci_tag = pciTag(qxl->pci->bus, qxl->pci->device, qxl->pci->func);
++#endif
++
++ pScrn->monitor = pScrn->confScreen->monitor;
++
++ if (!qxl_color_setup(pScrn))
++ goto out;
++
++ /* option parsing and card differentiation */
++ xf86CollectOptions(pScrn, NULL);
++
++ if (!qxl_map_memory(qxl, scrnIndex))
++ goto out;
++
++ if (!qxl_check_device(pScrn, qxl))
++ goto out;
++
++ /* ddc stuff here */
++
++ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
++ clockRanges->next = NULL;
++ clockRanges->minClock = 10000;
++ clockRanges->maxClock = 400000;
++ clockRanges->clockIndex = -1;
++ clockRanges->interlaceAllowed = clockRanges->doubleScanAllowed = 0;
++ clockRanges->ClockMulFactor = clockRanges->ClockDivFactor = 1;
++ pScrn->progClock = TRUE;
++
++ /* override QXL monitor stuff */
++ if (pScrn->monitor->nHsync <= 0) {
++ pScrn->monitor->hsync[0].lo = 29.0;
++ pScrn->monitor->hsync[0].hi = 160.0;
++ pScrn->monitor->nHsync = 1;
++ }
++ if (pScrn->monitor->nVrefresh <= 0) {
++ pScrn->monitor->vrefresh[0].lo = 50;
++ pScrn->monitor->vrefresh[0].hi = 75;
++ pScrn->monitor->nVrefresh = 1;
++ }
++
++ /* Add any modes not in xorg's default mode list */
++ for (i = 0; i < qxl->num_modes; i++)
++ if (qxl->modes[i].orientation == 0) {
++ qxl_add_mode(pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
++ M_T_DRIVER);
++ if (qxl->modes[i].x_res > max_x)
++ max_x = qxl->modes[i].x_res;
++ if (qxl->modes[i].y_res > max_y)
++ max_y = qxl->modes[i].y_res;
++ }
++
++ if (pScrn->display->virtualX == 0 && pScrn->display->virtualY == 0) {
++ /* It is possible for the largest x + largest y size combined leading
++ to a virtual size which will not fit into the framebuffer when this
++ happens we prefer max width and make height as large as possible */
++ if (max_x * max_y * (pScrn->bitsPerPixel / 8) > qxl->draw_area_size)
++ pScrn->display->virtualY = qxl->draw_area_size /
++ (max_x * (pScrn->bitsPerPixel / 8));
++ else
++ pScrn->display->virtualY = max_y;
++
++ pScrn->display->virtualX = max_x;
++ }
++
++ if (0 >= xf86ValidateModes(pScrn, pScrn->monitor->Modes,
++ pScrn->display->modes, clockRanges, linePitches,
++ 128, max_x, 128 * 4, 128, max_y,
++ pScrn->display->virtualX,
++ pScrn->display->virtualY,
++ 128 * 1024 * 1024, LOOKUP_BEST_REFRESH))
++ goto out;
++
++ CHECK_POINT();
++
++ xf86PruneDriverModes(pScrn);
++ pScrn->currentMode = pScrn->modes;
++ /* If no modes are specified in xorg.conf, default to 1024x768 */
++ if (pScrn->display->modes == NULL || pScrn->display->modes[0] == NULL)
++ for (mode = pScrn->modes; mode; mode = mode->next)
++ if (mode->HDisplay == 1024 && mode->VDisplay == 768) {
++ pScrn->currentMode = mode;
++ break;
++ }
++
++ xf86PrintModes(pScrn);
++ xf86SetDpi(pScrn, 0, 0);
++
++ if (!xf86LoadSubModule(pScrn, "fb") ||
++ !xf86LoadSubModule(pScrn, "ramdac") ||
++ !xf86LoadSubModule(pScrn, "vgahw"))
++ {
++ goto out;
++ }
++
++ print_modes (qxl, scrnIndex);
++
++ /* VGA hardware initialisation */
++ if (!vgaHWGetHWRec(pScrn))
++ return FALSE;
++
++ /* hate */
++ qxl_unmap_memory(qxl, scrnIndex);
++
++ CHECK_POINT();
++
++ xf86DrvMsg(scrnIndex, X_INFO, "PreInit complete\n");
++ return TRUE;
++
++out:
++ if (clockRanges)
++ xfree(clockRanges);
++ if (qxl)
++ xfree(qxl);
++
++ return FALSE;
++}
++
++#ifdef XSERVER_LIBPCIACCESS
++enum qxl_class
++{
++ CHIP_QXL_1,
++};
++
++static const struct pci_id_match qxl_device_match[] = {
++ {
++ PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_0100, PCI_MATCH_ANY, PCI_MATCH_ANY,
++ 0x00030000, 0x00ffffff, CHIP_QXL_1
++ },
++
++ { 0 },
++};
++#endif
++
++static SymTabRec qxlChips[] =
++{
++ { PCI_CHIP_QXL_0100, "QXL 1", },
++ { -1, NULL }
++};
++
++#ifndef XSERVER_LIBPCIACCESS
++static PciChipsets qxlPciChips[] =
++{
++ { PCI_CHIP_QXL_0100, PCI_CHIP_QXL_0100, RES_SHARED_VGA },
++ { -1, -1, RES_UNDEFINED }
++};
++#endif
++
++static void
++qxl_identify(int flags)
++{
++ xf86PrintChipsets("qxl", "Driver for QXL virtual graphics", qxlChips);
++}
++
++static void
++qxl_init_scrn(ScrnInfoPtr pScrn)
++{
++ pScrn->driverVersion = 0;
++ pScrn->driverName = pScrn->name = "qxl";
++ pScrn->PreInit = qxl_pre_init;
++ pScrn->ScreenInit = qxl_screen_init;
++ pScrn->SwitchMode = qxl_switch_mode;
++ pScrn->ValidMode = qxl_valid_mode;
++ pScrn->EnterVT = qxl_enter_vt;
++ pScrn->LeaveVT = qxl_leave_vt;
++}
+diff --git a/src/compat/compat-qxl_image.c b/src/compat/compat-qxl_image.c
+new file mode 100644
+index 0000000..d2ac12d
+--- /dev/null
++++ b/src/compat/compat-qxl_image.c
+@@ -0,0 +1,255 @@
++#include <string.h>
++#include <assert.h>
++#include <stdlib.h>
++#include "compat-qxl.h"
++#include "compat-lookup3.h"
++
++typedef struct image_info_t image_info_t;
++
++struct image_info_t
++{
++ struct qxl_image *image;
++ int ref_count;
++ image_info_t *next;
++};
++
++#define HASH_SIZE 4096
++static image_info_t *image_table[HASH_SIZE];
++
++static unsigned int
++hash_and_copy (const uint8_t *src, int src_stride,
++ uint8_t *dest, int dest_stride,
++ int bytes_per_pixel, int width, int height)
++{
++ unsigned int hash = 0;
++ int i;
++
++ for (i = 0; i < height; ++i)
++ {
++ const uint8_t *src_line = src + i * src_stride;
++ uint8_t *dest_line = dest + i * dest_stride;
++ int n_bytes = width * bytes_per_pixel;
++
++ if (dest)
++ memcpy (dest_line, src_line, n_bytes);
++
++ hash = hashlittle (src_line, n_bytes, hash);
++ }
++
++ return hash;
++}
++
++static image_info_t *
++lookup_image_info (unsigned int hash,
++ int width,
++ int height)
++{
++ struct image_info_t *info = image_table[hash % HASH_SIZE];
++
++ while (info)
++ {
++ struct qxl_image *image = info->image;
++
++ if (image->descriptor.id == hash &&
++ image->descriptor.width == width &&
++ image->descriptor.height == height)
++ {
++ return info;
++ }
++
++ info = info->next;
++ }
++
++#if 0
++ ErrorF ("lookup of %u failed\n", hash);
++#endif
++
++ return NULL;
++}
++
++static image_info_t *
++insert_image_info (unsigned int hash)
++{
++ struct image_info_t *info = malloc (sizeof (image_info_t));
++
++ if (!info)
++ return NULL;
++
++ info->next = image_table[hash % HASH_SIZE];
++ image_table[hash % HASH_SIZE] = info;
++
++ return info;
++}
++
++static void
++remove_image_info (image_info_t *info)
++{
++ struct image_info_t **location = &image_table[info->image->descriptor.id % HASH_SIZE];
++
++ while (*location && (*location) != info)
++ location = &((*location)->next);
++
++ if (*location)
++ *location = info->next;
++
++ free (info);
++}
++
++struct qxl_image *
++qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
++ int x, int y, int width, int height,
++ int stride)
++{
++ unsigned int hash;
++ image_info_t *info;
++
++ data += y * stride + x * qxl->bytes_per_pixel;
++
++ hash = hash_and_copy (data, stride, NULL, -1, qxl->bytes_per_pixel, width, height);
++
++ info = lookup_image_info (hash, width, height);
++ if (info)
++ {
++ int i, j;
++
++#if 0
++ ErrorF ("reusing image %p with hash %u (%d x %d)\n", info->image, hash, width, height);
++#endif
++
++ info->ref_count++;
++
++ for (i = 0; i < height; ++i)
++ {
++ struct qxl_data_chunk *chunk;
++ const uint8_t *src_line = data + i * stride;
++ uint32_t *dest_line;
++
++ chunk = virtual_address (qxl, u64_to_pointer (info->image->u.bitmap.data));
++
++ dest_line = (uint32_t *)chunk->data + width * i;
++
++ for (j = 0; j < width; ++j)
++ {
++ uint32_t *s = (uint32_t *)src_line;
++ uint32_t *d = (uint32_t *)dest_line;
++
++ if (d[j] != s[j])
++ {
++#if 0
++ ErrorF ("bad collision at (%d, %d)! %d != %d\n", j, i, s[j], d[j]);
++#endif
++ goto out;
++ }
++ }
++ }
++ out:
++ return info->image;
++ }
++ else
++ {
++ struct qxl_image *image;
++ struct qxl_data_chunk *chunk;
++ int dest_stride = width * qxl->bytes_per_pixel;
++ image_info_t *info;
++
++#if 0
++ ErrorF ("Must create new image of size %d %d\n", width, height);
++#endif
++
++ /* Chunk */
++
++ /* FIXME: Check integer overflow */
++ chunk = qxl_allocnf (qxl, sizeof *chunk + height * dest_stride);
++
++ chunk->data_size = height * dest_stride;
++ chunk->prev_chunk = 0;
++ chunk->next_chunk = 0;
++
++ hash_and_copy (data, stride,
++ chunk->data, dest_stride,
++ qxl->bytes_per_pixel, width, height);
++
++ /* Image */
++ image = qxl_allocnf (qxl, sizeof *image);
++
++ image->descriptor.id = 0;
++ image->descriptor.type = QXL_IMAGE_TYPE_BITMAP;
++
++ image->descriptor.flags = 0;
++ image->descriptor.width = width;
++ image->descriptor.height = height;
++
++ if (qxl->bytes_per_pixel == 2)
++ {
++ image->u.bitmap.format = QXL_BITMAP_FMT_16BIT;
++ }
++ else
++ {
++ image->u.bitmap.format = QXL_BITMAP_FMT_32BIT;
++ }
++
++ image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
++ image->u.bitmap.x = width;
++ image->u.bitmap.y = height;
++ image->u.bitmap.stride = width * qxl->bytes_per_pixel;
++ image->u.bitmap.palette = 0;
++ image->u.bitmap.data = physical_address (qxl, chunk);
++
++#if 0
++ ErrorF ("%p has size %d %d\n", image, width, height);
++#endif
++
++ /* Add to hash table */
++ if ((info = insert_image_info (hash)))
++ {
++ info->image = image;
++ info->ref_count = 1;
++
++ image->descriptor.id = hash;
++ image->descriptor.flags = QXL_IMAGE_CACHE;
++
++#if 0
++ ErrorF ("added with hash %u\n", hash);
++#endif
++ }
++
++ return image;
++ }
++}
++
++void
++qxl_image_destroy (qxl_screen_t *qxl,
++ struct qxl_image *image)
++{
++ struct qxl_data_chunk *chunk;
++ image_info_t *info;
++
++ chunk = virtual_address (qxl, u64_to_pointer (image->u.bitmap.data));
++
++ info = lookup_image_info (image->descriptor.id,
++ image->descriptor.width,
++ image->descriptor.height);
++
++ if (info && info->image == image)
++ {
++ --info->ref_count;
++
++ if (info->ref_count != 0)
++ return;
++
++#if 0
++ ErrorF ("removed %p from hash table\n", info->image);
++#endif
++
++ remove_image_info (info);
++ }
++
++ qxl_free (qxl->mem, chunk);
++ qxl_free (qxl->mem, image);
++}
++
++void
++qxl_drop_image_cache (qxl_screen_t *qxl)
++{
++ memset (image_table, 0, HASH_SIZE * sizeof (image_info_t *));
++}
+diff --git a/src/compat/compat-qxl_mem.c b/src/compat/compat-qxl_mem.c
+new file mode 100644
+index 0000000..2f6fa6a
+--- /dev/null
++++ b/src/compat/compat-qxl_mem.c
+@@ -0,0 +1,321 @@
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++#include "compat-qxl.h"
++
++struct block
++{
++ unsigned long n_bytes;
++
++ union
++ {
++ struct
++ {
++ struct block *next;
++ } unused;
++
++ struct
++ {
++ uint8_t data[0];
++ } used;
++ } u;
++};
++
++struct qxl_mem
++{
++ void * base;
++ unsigned long n_bytes;
++
++ struct block *unused;
++ unsigned long total_allocated;
++ unsigned long total_freed;
++ unsigned long n_allocated_blocks;
++ unsigned long n_freed_blocks;
++};
++
++static void
++initialize (struct qxl_mem *mem)
++{
++ mem->unused = (struct block *)mem->base;
++ mem->unused->n_bytes = mem->n_bytes;
++ mem->unused->u.unused.next = NULL;
++
++ mem->total_allocated = 0;
++ mem->total_freed = 0;
++ mem->n_allocated_blocks = 0;
++ mem->n_freed_blocks = 0;
++}
++
++struct qxl_mem *
++qxl_mem_create (void *base, unsigned long n_bytes)
++{
++ struct qxl_mem *mem = NULL;
++
++ mem = calloc (sizeof (*mem), 1);
++ if (!mem)
++ goto out;
++
++ mem->base = base;
++ mem->n_bytes = n_bytes;
++
++ initialize (mem);
++
++out:
++ return mem;
++}
++
++void
++qxl_mem_free_all (struct qxl_mem *mem)
++{
++ initialize (mem);
++}
++
++void
++qxl_mem_dump_stats (struct qxl_mem *mem, const char *header)
++{
++ struct block *b;
++ int n_blocks;
++ unsigned long max_block = 0;
++ unsigned long min_block = 0xffffffffffffffffUL;
++
++ fprintf (stderr, "%s\n", header);
++
++ n_blocks = 0;
++ for (b = mem->unused; b != NULL; b = b->u.unused.next)
++ {
++ fprintf (stderr, "block: %p (%lu bytes)\n", b, b->n_bytes);
++
++ if (b->u.unused.next && b >= b->u.unused.next)
++ {
++ fprintf (stderr, "b: %p b->next: %p\n",
++ b, b->u.unused.next);
++ assert (0);
++ }
++
++ if (b->u.unused.next && (void *)b + b->n_bytes >= b->u.unused.next)
++ {
++ fprintf (stderr, "OVERLAPPING BLOCKS b: %p b->next: %p\n",
++ b, b->u.unused.next);
++ assert (0);
++ }
++
++ if (b->n_bytes > max_block)
++ max_block = b->n_bytes;
++
++ if (b->n_bytes < min_block)
++ min_block = b->n_bytes;
++
++ ++n_blocks;
++ }
++
++ fprintf (stderr, "=========\n");
++
++ fprintf (stderr, "%d blocks\n", n_blocks);
++ fprintf (stderr, "min block: %lu bytes\n", min_block);
++ fprintf (stderr, "max block: %lu bytes\n", max_block);
++ fprintf (stderr, "total freed: %lu bytres\n", mem->total_freed);
++ fprintf (stderr, "total allocated: %lu bytes\n",
++ mem->total_allocated - mem->total_freed);
++ fprintf (stderr, "total free: %lu bytes\n",
++ mem->n_bytes - (mem->total_allocated - mem->total_freed));
++}
++
++void *
++qxl_alloc (struct qxl_mem *mem, unsigned long n_bytes)
++{
++ struct block *b, *prev;
++
++ mem->n_allocated_blocks++;
++
++ /* Simply pretend the user asked to allocate the header as well. Then
++ * we can mostly ignore the difference between blocks and allocations
++ */
++ n_bytes += sizeof (unsigned long);
++
++ n_bytes = (n_bytes + 7) & ~((1 << 3) - 1);
++
++ if (n_bytes < sizeof (struct block))
++ n_bytes = sizeof (struct block);
++
++ assert (mem->unused);
++
++ prev = NULL;
++ for (b = mem->unused; b != NULL; prev = b, b = b->u.unused.next)
++ {
++ if (b->n_bytes >= n_bytes)
++ {
++ struct block *new_block;
++
++ if (b->n_bytes - n_bytes >= sizeof (struct block))
++ {
++ new_block = (void *)b + n_bytes;
++
++ new_block->n_bytes = b->n_bytes - n_bytes;
++
++ if (prev)
++ {
++ assert (prev < b);
++ assert (prev->u.unused.next == NULL || prev < prev->u.unused.next);
++
++ new_block->u.unused.next = b->u.unused.next;
++ prev->u.unused.next = new_block;
++ }
++ else
++ {
++ assert (mem->unused == b);
++
++ new_block->u.unused.next = mem->unused->u.unused.next;
++ mem->unused = new_block;
++ }
++
++ b->n_bytes = n_bytes;
++ }
++ else
++ {
++#if 0
++ printf ("Exact match\n");
++#endif
++
++ if (prev)
++ {
++ prev->u.unused.next = b->u.unused.next;
++ }
++ else
++ {
++ mem->unused = b->u.unused.next;
++ }
++ }
++
++ mem->total_allocated += n_bytes;
++
++ return (void *)b->u.used.data;
++ }
++ else
++ {
++#if 0
++ printf ("Skipping small block %d\n", b->n_bytes);
++#endif
++ }
++ }
++
++ /* If we get here, we are out of memory, so print some stats */
++#if 0
++ fprintf (stderr, "Failing to allocate %lu bytes\n", n_bytes);
++ qxl_mem_dump_stats (mem, "out of memory");
++#endif
++
++ return NULL;
++}
++
++/* Finds the unused block before and the unused block after @data. Both
++ * before and after can be NULL if data is before the first or after the
++ * last unused block.
++ */
++static void
++find_neighbours (struct qxl_mem *mem, void *data,
++ struct block **before, struct block **after)
++{
++ struct block *b;
++ *before = NULL;
++ *after = NULL;
++
++ for (b = mem->unused; b != NULL; b = b->u.unused.next)
++ {
++ if ((void *)b < data)
++ *before = b;
++
++ if ((void *)b > data)
++ {
++ *after = b;
++ break;
++ }
++ }
++
++ if (*before)
++ assert ((*before)->u.unused.next == *after);
++}
++
++void
++qxl_free (struct qxl_mem *mem, void *d)
++{
++ struct block *b = d - sizeof (unsigned long);
++ struct block *before, *after;
++
++ mem->total_freed += b->n_bytes;
++ mem->n_freed_blocks++;
++
++#if 0
++ printf ("freeing %p (%d bytes)\n", b, b->n_bytes);
++
++ qxl_mem_dump_stats (mem, "before free");
++#endif
++
++ find_neighbours (mem, (void *)b, &before, &after);
++
++ if (before)
++ {
++#if 0
++ printf (" free: merge before: %p\n", before->u.used.data);
++#endif
++
++ if ((void *)before + before->n_bytes == b)
++ {
++#if 0
++ printf (" free: merge with before (adding %d bytes)\n", b->n_bytes);
++#endif
++
++ /* Merge before and b */
++ before->n_bytes += b->n_bytes;
++ b = before;
++ }
++ else
++ {
++#if 0
++ printf (" free: no merge with before\n");
++#endif
++
++ before->u.unused.next = b;
++ }
++ }
++ else
++ {
++#if 0
++ printf (" free: no before\n");
++#endif
++ mem->unused = b;
++ }
++
++ if (after)
++ {
++#if 0
++ printf (" free: after: %p\n", after->u.used.data);
++#endif
++ if ((void *)b + b->n_bytes == after)
++ {
++#if 0
++ printf (" merge with after\n");
++#endif
++ b->n_bytes += after->n_bytes;
++ b->u.unused.next = after->u.unused.next;
++ }
++ else
++ {
++#if 0
++ printf (" no merge with after\n");
++#endif
++ b->u.unused.next = after;
++ }
++ }
++ else
++ {
++#if 0
++ printf (" free: no after\n");
++#endif
++ b->u.unused.next = NULL;
++ }
++
++#if 0
++ qxl_mem_dump_stats (mem, "after free");
++#endif
++}
+diff --git a/src/compat/compat-qxl_ring.c b/src/compat/compat-qxl_ring.c
+new file mode 100644
+index 0000000..9a34583
+--- /dev/null
++++ b/src/compat/compat-qxl_ring.c
+@@ -0,0 +1,97 @@
++#include <string.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include "compat-qxl.h"
++
++struct ring
++{
++ struct qxl_ring_header header;
++ uint8_t elements[0];
++};
++
++struct qxl_ring
++{
++ volatile struct ring *ring;
++ int element_size;
++ int n_elements;
++ int prod_notify;
++};
++
++struct qxl_ring *
++qxl_ring_create (struct qxl_ring_header *header,
++ int element_size,
++ int n_elements,
++ int prod_notify)
++{
++ struct qxl_ring *ring;
++
++ ring = malloc (sizeof *ring);
++ if (!ring)
++ return NULL;
++
++ ring->ring = (volatile struct ring *)header;
++ ring->element_size = element_size;
++ ring->n_elements = n_elements;
++ ring->prod_notify = prod_notify;
++
++ return ring;
++}
++
++void
++qxl_ring_push (struct qxl_ring *ring,
++ const void *new_elt)
++{
++ volatile struct qxl_ring_header *header = &(ring->ring->header);
++ volatile uint8_t *elt;
++ int idx;
++
++ while (header->prod - header->cons == header->num_items)
++ {
++ header->notify_on_cons = header->cons + 1;
++
++ mem_barrier();
++ }
++
++ idx = header->prod & (ring->n_elements - 1);
++ elt = ring->ring->elements + idx * ring->element_size;
++
++ memcpy((void *)elt, new_elt, ring->element_size);
++
++ header->prod++;
++
++ mem_barrier();
++
++ if (header->prod == header->notify_on_prod)
++ outb (ring->prod_notify, 0);
++}
++
++Bool
++qxl_ring_pop (struct qxl_ring *ring,
++ void *element)
++{
++ volatile struct qxl_ring_header *header = &(ring->ring->header);
++ volatile uint8_t *ring_elt;
++ int idx;
++
++ if (header->cons == header->prod)
++ return FALSE;
++
++ idx = header->cons & (ring->n_elements - 1);
++ ring_elt = ring->ring->elements + idx * ring->element_size;
++
++ memcpy (element, (void *)ring_elt, ring->element_size);
++
++ header->cons++;
++
++ return TRUE;
++}
++
++void
++qxl_ring_wait_idle (struct qxl_ring *ring)
++{
++ while (ring->ring->header.cons != ring->ring->header.prod)
++ {
++ usleep (1000);
++ mem_barrier();
++ }
++}
+--
+1.7.4.4
+
diff --git a/0012-Link-in-the-compat-driver-various-renamings.patch b/0012-Link-in-the-compat-driver-various-renamings.patch
new file mode 100644
index 0000000..da9f03d
--- /dev/null
+++ b/0012-Link-in-the-compat-driver-various-renamings.patch
@@ -0,0 +1,2711 @@
+From 5ff4ed6f80706a8df863e1b72b4051551c850609 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Thu, 3 Feb 2011 06:40:29 -0500
+Subject: [PATCH 12/13] Link in the compat driver; various renamings
+
+---
+ src/Makefile.am | 2 +-
+ src/compat/Makefile.am | 10 +-
+ src/compat/compat-lookup3.c | 54 ++--
+ src/compat/compat-lookup3.h | 2 +-
+ src/compat/compat-qxl.h | 268 +++++++++---------
+ src/compat/compat-qxl_cursor.c | 98 ++++----
+ src/compat/compat-qxl_driver.c | 592 ++++++++++++++++++++--------------------
+ src/compat/compat-qxl_image.c | 50 ++--
+ src/compat/compat-qxl_mem.c | 26 +-
+ src/compat/compat-qxl_ring.c | 20 +-
+ src/qxl_driver.c | 11 +-
+ 11 files changed, 570 insertions(+), 563 deletions(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index f3a65bf..179d217 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -33,7 +33,7 @@ qxl_drv_la_LTLIBRARIES = qxl_drv.la
+ qxl_drv_la_LDFLAGS = -module -avoid-version
+ qxl_drv_ladir = @moduledir@/drivers
+
+-qxl_drv_la_LIBADD = uxa/libuxa.la
++qxl_drv_la_LIBADD = uxa/libuxa.la compat/compatdriver.la
+
+ qxl_drv_la_SOURCES = \
+ qxl.h \
+diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
+index 84a30f2..64de89d 100644
+--- a/src/compat/Makefile.am
++++ b/src/compat/Makefile.am
+@@ -24,13 +24,13 @@
+ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+ # _ladir passes a dummy rpath to libtool so the thing will actually link
+ # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+-qxl_drv_la_LTLIBRARIES = qxl_drv.la
+-qxl_drv_la_LDFLAGS = -module -avoid-version
+-qxl_drv_ladir = @moduledir@/drivers
+-AM_CFLAGS = -g
++
++noinst_LTLIBRARIES = compatdriver.la
++compatdriver_la_LDFLAGS = -module -avoid-version
++
+ AM_CFLAGS = $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS)
+
+-qxl_drv_la_SOURCES = \
++compatdriver_la_SOURCES = \
+ compat-qxl.h \
+ compat-qxl_driver.c \
+ compat-qxl_image.c \
+diff --git a/src/compat/compat-lookup3.c b/src/compat/compat-lookup3.c
+index c301d85..a0608a9 100644
+--- a/src/compat/compat-lookup3.c
++++ b/src/compat/compat-lookup3.c
+@@ -3,17 +3,17 @@
+ lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+ These are functions for producing 32-bit hashes for hash table lookup.
+-hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
++compat_hashword(), compat_hashlittle(), compat_hashlittle2(), compat_hashbig(), mix(), and final()
+ are externally useful functions. Routines to test the hash are included
+ if SELF_TEST is defined. You can use this free for any purpose. It's in
+ the public domain. It has no warranty.
+
+-You probably want to use hashlittle(). hashlittle() and hashbig()
+-hash byte arrays. hashlittle() is is faster than hashbig() on
++You probably want to use compat_hashlittle(). compat_hashlittle() and compat_hashbig()
++hash byte arrays. compat_hashlittle() is is faster than compat_hashbig() on
+ little-endian machines. Intel and AMD are little-endian machines.
+-On second thought, you probably want hashlittle2(), which is identical to
+-hashlittle() except it returns two 32-bit hashes for the price of one.
+-You could implement hashbig2() if you wanted but I haven't bothered here.
++On second thought, you probably want compat_hashlittle2(), which is identical to
++compat_hashlittle() except it returns two 32-bit hashes for the price of one.
++You could implement compat_hashbig2() if you wanted but I haven't bothered here.
+
+ If you want to find a hash of, say, exactly 7 integers, do
+ a = i1; b = i2; c = i3;
+@@ -23,9 +23,9 @@ If you want to find a hash of, say, exactly 7 integers, do
+ a += i7;
+ final(a,b,c);
+ then use c as the hash value. If you have a variable length array of
+-4-byte integers to hash, use hashword(). If you have a byte array (like
+-a character string), use hashlittle(). If you have several byte arrays, or
+-a mix of things, see the comments above hashlittle().
++4-byte integers to hash, use compat_hashword(). If you have a byte array (like
++a character string), use compat_hashlittle(). If you have several byte arrays, or
++a mix of things, see the comments above compat_hashlittle().
+
+ Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
+ then mix those integers. This is fast (you can do a lot more thorough
+@@ -161,14 +161,14 @@ and these came close:
+ -- that the key be an array of uint32_t's, and
+ -- that the length be the number of uint32_t's in the key
+
+- The function hashword() is identical to hashlittle() on little-endian
+- machines, and identical to hashbig() on big-endian machines,
++ The function compat_hashword() is identical to compat_hashlittle() on little-endian
++ machines, and identical to compat_hashbig() on big-endian machines,
+ except that the length has to be measured in uint32_ts rather than in
+- bytes. hashlittle() is more complicated than hashword() only because
+- hashlittle() has to dance around fitting the key bytes into registers.
++ bytes. compat_hashlittle() is more complicated than compat_hashword() only because
++ compat_hashlittle() has to dance around fitting the key bytes into registers.
+ --------------------------------------------------------------------
+ */
+-uint32_t hashword(
++uint32_t compat_hashword(
+ const uint32_t *k, /* the key, an array of uint32_t values */
+ size_t length, /* the length of the key, in uint32_ts */
+ uint32_t initval) /* the previous hash, or an arbitrary value */
+@@ -206,13 +206,13 @@ uint32_t hashword(
+
+ /*
+ --------------------------------------------------------------------
+-hashword2() -- same as hashword(), but take two seeds and return two
++compat_hashword2() -- same as compat_hashword(), but take two seeds and return two
+ 32-bit values. pc and pb must both be nonnull, and *pc and *pb must
+ both be initialized with seeds. If you pass in (*pb)==0, the output
+-(*pc) will be the same as the return value from hashword().
++(*pc) will be the same as the return value from compat_hashword().
+ --------------------------------------------------------------------
+ */
+-void hashword2 (
++void compat_hashword2 (
+ const uint32_t *k, /* the key, an array of uint32_t values */
+ size_t length, /* the length of the key, in uint32_ts */
+ uint32_t *pc, /* IN: seed OUT: primary hash value */
+@@ -252,7 +252,7 @@ uint32_t *pb) /* IN: more seed OUT: secondary hash value */
+
+ /*
+ -------------------------------------------------------------------------------
+-hashlittle() -- hash a variable-length key into a 32-bit value
++compat_hashlittle() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ length : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+@@ -267,7 +267,7 @@ use a bitmask. For example, if you need only 10 bits, do
+ In which case, the hash table should have hashsize(10) elements.
+
+ If you are hashing n strings (uint8_t **)k, do it like this:
+- for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
++ for (i=0, h=0; i<n; ++i) h = compat_hashlittle( k[i], len[i], h);
+
+ By Bob Jenkins, 2006. bob_jenkins at burtleburtle.net. You may use this
+ code any way you wish, private, educational, or commercial. It's free.
+@@ -277,7 +277,7 @@ acceptable. Do NOT use for cryptographic purposes.
+ -------------------------------------------------------------------------------
+ */
+
+-uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
++uint32_t compat_hashlittle( const void *key, size_t length, uint32_t initval)
+ {
+ uint32_t a,b,c; /* internal state */
+ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
+@@ -450,16 +450,16 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
+
+
+ /*
+- * hashlittle2: return 2 32-bit hash values
++ * compat_hashlittle2: return 2 32-bit hash values
+ *
+- * This is identical to hashlittle(), except it returns two 32-bit hash
++ * This is identical to compat_hashlittle(), except it returns two 32-bit hash
+ * values instead of just one. This is good enough for hash table
+ * lookup with 2^^64 buckets, or if you want a second hash if you're not
+ * happy with the first, or if you want a probably-unique 64-bit ID for
+ * the key. *pc is better mixed than *pb, so use *pc first. If you want
+ * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
+ */
+-void hashlittle2(
++void compat_hashlittle2(
+ const void *key, /* the key to hash */
+ size_t length, /* length of the key */
+ uint32_t *pc, /* IN: primary initval, OUT: primary hash */
+@@ -638,12 +638,12 @@ void hashlittle2(
+
+
+ /*
+- * hashbig():
+- * This is the same as hashword() on big-endian machines. It is different
+- * from hashlittle() on all machines. hashbig() takes advantage of
++ * compat_hashbig():
++ * This is the same as compat_hashword() on big-endian machines. It is different
++ * from compat_hashlittle() on all machines. compat_hashbig() takes advantage of
+ * big-endian byte ordering.
+ */
+-uint32_t hashbig( const void *key, size_t length, uint32_t initval)
++uint32_t compat_hashbig( const void *key, size_t length, uint32_t initval)
+ {
+ uint32_t a,b,c;
+ union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
+diff --git a/src/compat/compat-lookup3.h b/src/compat/compat-lookup3.h
+index 50c1cf4..67658ad 100644
+--- a/src/compat/compat-lookup3.h
++++ b/src/compat/compat-lookup3.h
+@@ -21,6 +21,6 @@ typedef UINT8 uint8_t;
+
+ #endif
+
+-uint32_t hashlittle( const void *key, size_t length, uint32_t initval);
++uint32_t compat_hashlittle( const void *key, size_t length, uint32_t initval);
+
+ #endif
+diff --git a/src/compat/compat-qxl.h b/src/compat/compat-qxl.h
+index bec43b3..2c61699 100644
+--- a/src/compat/compat-qxl.h
++++ b/src/compat/compat-qxl.h
+@@ -43,8 +43,8 @@
+
+ #define hidden _X_HIDDEN
+
+-#define QXL_NAME "qxl"
+-#define QXL_DRIVER_NAME "qxl"
++#define QXL_NAME "compat_qxl"
++#define QXL_DRIVER_NAME "compat_qxl"
+ #define PCI_VENDOR_RED_HAT 0x1b36
+
+ #define PCI_CHIP_QXL_0100 0x0100
+@@ -63,7 +63,7 @@ enum {
+ QXL_IO_LOG,
+ };
+
+-struct qxl_mode {
++struct compat_qxl_mode {
+ uint32_t id;
+ uint32_t x_res;
+ uint32_t y_res;
+@@ -81,39 +81,39 @@ typedef enum
+ QXL_CMD_UPDATE,
+ QXL_CMD_CURSOR,
+ QXL_CMD_MESSAGE
+-} qxl_command_type;
++} compat_qxl_command_type;
+
+-struct qxl_command {
++struct compat_qxl_command {
+ uint64_t data;
+ uint32_t type;
+ uint32_t pad;
+ };
+
+-struct qxl_rect {
++struct compat_qxl_rect {
+ uint32_t top;
+ uint32_t left;
+ uint32_t bottom;
+ uint32_t right;
+ };
+
+-union qxl_release_info {
++union compat_qxl_release_info {
+ uint64_t id;
+ uint64_t next;
+ };
+
+-struct qxl_clip {
++struct compat_qxl_clip {
+ uint32_t type;
+ uint64_t address;
+ };
+
+-struct qxl_point {
++struct compat_qxl_point {
+ int x;
+ int y;
+ };
+
+-struct qxl_pattern {
++struct compat_qxl_pattern {
+ uint64_t pat;
+- struct qxl_point pos;
++ struct compat_qxl_point pos;
+ };
+
+ typedef enum
+@@ -121,19 +121,19 @@ typedef enum
+ QXL_BRUSH_TYPE_NONE,
+ QXL_BRUSH_TYPE_SOLID,
+ QXL_BRUSH_TYPE_PATTERN
+-} qxl_brush_type;
++} compat_qxl_brush_type;
+
+-struct qxl_brush {
++struct compat_qxl_brush {
+ uint32_t type;
+ union {
+ uint32_t color;
+- struct qxl_pattern pattern;
++ struct compat_qxl_pattern pattern;
+ } u;
+ };
+
+-struct qxl_mask {
++struct compat_qxl_mask {
+ unsigned char flags;
+- struct qxl_point pos;
++ struct compat_qxl_point pos;
+ uint64_t bitmap;
+ };
+
+@@ -145,13 +145,13 @@ typedef enum {
+ QXL_IMAGE_TYPE_LZ_RGB,
+ QXL_IMAGE_TYPE_GLZ_RGB,
+ QXL_IMAGE_TYPE_FROM_CACHE,
+-} qxl_image_type;
++} compat_qxl_image_type;
+
+ typedef enum {
+ QXL_IMAGE_CACHE = (1 << 0)
+-} qxl_image_flags;
++} compat_qxl_image_flags;
+
+-struct qxl_image_descriptor
++struct compat_qxl_image_descriptor
+ {
+ uint64_t id;
+ uint8_t type;
+@@ -160,7 +160,7 @@ struct qxl_image_descriptor
+ uint32_t height;
+ };
+
+-struct qxl_data_chunk {
++struct compat_qxl_data_chunk {
+ uint32_t data_size;
+ uint64_t prev_chunk;
+ uint64_t next_chunk;
+@@ -179,90 +179,90 @@ typedef enum
+ QXL_BITMAP_FMT_24BIT,
+ QXL_BITMAP_FMT_32BIT,
+ QXL_BITMAP_FMT_RGBA,
+-} qxl_bitmap_format;
++} compat_qxl_bitmap_format;
+
+ typedef enum {
+ QXL_BITMAP_PAL_CACHE_ME = (1 << 0),
+ QXL_BITMAP_PAL_FROM_CACHE = (1 << 1),
+ QXL_BITMAP_TOP_DOWN = (1 << 2),
+-} qxl_bitmap_flags;
++} compat_qxl_bitmap_flags;
+
+-struct qxl_bitmap {
++struct compat_qxl_bitmap {
+ uint8_t format;
+ uint8_t flags;
+ uint32_t x; /* actually width */
+ uint32_t y; /* actually height */
+ uint32_t stride; /* in bytes */
+ uint64_t palette; /* Can be NULL */
+- uint64_t data; /* A qxl_data_chunk that actually contains the data */
++ uint64_t data; /* A compat_qxl_data_chunk that actually contains the data */
+ };
+
+-struct qxl_image {
+- struct qxl_image_descriptor descriptor;
++struct compat_qxl_image {
++ struct compat_qxl_image_descriptor descriptor;
+ union
+ {
+- struct qxl_bitmap bitmap;
++ struct compat_qxl_bitmap bitmap;
+ } u;
+ };
+
+-struct qxl_fill {
+- struct qxl_brush brush;
++struct compat_qxl_fill {
++ struct compat_qxl_brush brush;
+ unsigned short rop_descriptor;
+- struct qxl_mask mask;
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_opaque {
++struct compat_qxl_opaque {
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- struct qxl_brush brush;
++ struct compat_qxl_rect src_area;
++ struct compat_qxl_brush brush;
+ unsigned short rop_descriptor;
+ unsigned char scale_mode;
+- struct qxl_mask mask;
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_copy {
++struct compat_qxl_copy {
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
++ struct compat_qxl_rect src_area;
+ unsigned short rop_descriptor;
+ unsigned char scale_mode;
+- struct qxl_mask mask;
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_transparent {
++struct compat_qxl_transparent {
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
++ struct compat_qxl_rect src_area;
+ uint32_t src_color;
+ uint32_t true_color;
+ };
+
+-struct qxl_alpha_blend {
++struct compat_qxl_alpha_blend {
+ unsigned char alpha;
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
++ struct compat_qxl_rect src_area;
+ };
+
+-struct qxl_copy_bits {
+- struct qxl_point src_pos;
++struct compat_qxl_copy_bits {
++ struct compat_qxl_point src_pos;
+ };
+
+-struct qxl_blend { /* same as copy */
++struct compat_qxl_blend { /* same as copy */
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
++ struct compat_qxl_rect src_area;
+ unsigned short rop_descriptor;
+ unsigned char scale_mode;
+- struct qxl_mask mask;
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_rop3 {
++struct compat_qxl_rop3 {
+ uint64_t src_bitmap;
+- struct qxl_rect src_area;
+- struct qxl_brush brush;
++ struct compat_qxl_rect src_area;
++ struct compat_qxl_brush brush;
+ unsigned char rop3;
+ unsigned char scale_mode;
+- struct qxl_mask mask;
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_line_attr {
++struct compat_qxl_line_attr {
+ unsigned char flags;
+ unsigned char join_style;
+ unsigned char end_style;
+@@ -272,33 +272,33 @@ struct qxl_line_attr {
+ uint64_t style;
+ };
+
+-struct qxl_stroke {
++struct compat_qxl_stroke {
+ uint64_t path;
+- struct qxl_line_attr attr;
+- struct qxl_brush brush;
++ struct compat_qxl_line_attr attr;
++ struct compat_qxl_brush brush;
+ unsigned short fore_mode;
+ unsigned short back_mode;
+ };
+
+-struct qxl_text {
++struct compat_qxl_text {
+ uint64_t str;
+- struct qxl_rect back_area;
+- struct qxl_brush fore_brush;
+- struct qxl_brush back_brush;
++ struct compat_qxl_rect back_area;
++ struct compat_qxl_brush fore_brush;
++ struct compat_qxl_brush back_brush;
+ unsigned short fore_mode;
+ unsigned short back_mode;
+ };
+
+-struct qxl_blackness {
+- struct qxl_mask mask;
++struct compat_qxl_blackness {
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_inverse {
+- struct qxl_mask mask;
++struct compat_qxl_inverse {
++ struct compat_qxl_mask mask;
+ };
+
+-struct qxl_whiteness {
+- struct qxl_mask mask;
++struct compat_qxl_whiteness {
++ struct compat_qxl_mask mask;
+ };
+
+ /* Effects */
+@@ -312,14 +312,14 @@ typedef enum
+ QXL_EFFECT_NOP_ON_DUP,
+ QXL_EFFECT_NOP,
+ QXL_EFFECT_OPAQUE_BRUSH
+-} qxl_effect_type;
++} compat_qxl_effect_type;
+
+ typedef enum
+ {
+ QXL_CLIP_TYPE_NONE,
+ QXL_CLIP_TYPE_RECTS,
+ QXL_CLIP_TYPE_PATH,
+-} qxl_clip_type;
++} compat_qxl_clip_type;
+
+ typedef enum {
+ QXL_DRAW_NOP,
+@@ -336,41 +336,41 @@ typedef enum {
+ QXL_DRAW_TEXT,
+ QXL_DRAW_TRANSPARENT,
+ QXL_DRAW_ALPHA_BLEND,
+-} qxl_draw_type;
++} compat_qxl_draw_type;
+
+-struct qxl_drawable {
+- union qxl_release_info release_info;
++struct compat_qxl_drawable {
++ union compat_qxl_release_info release_info;
+ unsigned char effect;
+ unsigned char type;
+ unsigned short bitmap_offset;
+- struct qxl_rect bitmap_area;
+- struct qxl_rect bbox;
+- struct qxl_clip clip;
++ struct compat_qxl_rect bitmap_area;
++ struct compat_qxl_rect bbox;
++ struct compat_qxl_clip clip;
+ uint32_t mm_time;
+ union {
+- struct qxl_fill fill;
+- struct qxl_opaque opaque;
+- struct qxl_copy copy;
+- struct qxl_transparent transparent;
+- struct qxl_alpha_blend alpha_blend;
+- struct qxl_copy_bits copy_bits;
+- struct qxl_blend blend;
+- struct qxl_rop3 rop3;
+- struct qxl_stroke stroke;
+- struct qxl_text text;
+- struct qxl_blackness blackness;
+- struct qxl_inverse inverse;
+- struct qxl_whiteness whiteness;
++ struct compat_qxl_fill fill;
++ struct compat_qxl_opaque opaque;
++ struct compat_qxl_copy copy;
++ struct compat_qxl_transparent transparent;
++ struct compat_qxl_alpha_blend alpha_blend;
++ struct compat_qxl_copy_bits copy_bits;
++ struct compat_qxl_blend blend;
++ struct compat_qxl_rop3 rop3;
++ struct compat_qxl_stroke stroke;
++ struct compat_qxl_text text;
++ struct compat_qxl_blackness blackness;
++ struct compat_qxl_inverse inverse;
++ struct compat_qxl_whiteness whiteness;
+ } u;
+ };
+
+-struct qxl_update_cmd {
+- union qxl_release_info release_info;
+- struct qxl_rect area;
++struct compat_qxl_update_cmd {
++ union compat_qxl_release_info release_info;
++ struct compat_qxl_rect area;
+ uint32_t update_id;
+ };
+
+-struct qxl_point16 {
++struct compat_qxl_point16 {
+ int16_t x;
+ int16_t y;
+ };
+@@ -394,7 +394,7 @@ enum {
+ CURSOR_TYPE_COLOR32,
+ };
+
+-struct qxl_cursor_header {
++struct compat_qxl_cursor_header {
+ uint64_t unique;
+ uint16_t type;
+ uint16_t width;
+@@ -403,19 +403,19 @@ struct qxl_cursor_header {
+ uint16_t hot_spot_y;
+ };
+
+-struct qxl_cursor
++struct compat_qxl_cursor
+ {
+- struct qxl_cursor_header header;
++ struct compat_qxl_cursor_header header;
+ uint32_t data_size;
+- struct qxl_data_chunk chunk;
++ struct compat_qxl_data_chunk chunk;
+ };
+
+-struct qxl_cursor_cmd {
+- union qxl_release_info release_info;
++struct compat_qxl_cursor_cmd {
++ union compat_qxl_release_info release_info;
+ uint8_t type;
+ union {
+ struct {
+- struct qxl_point16 position;
++ struct compat_qxl_point16 position;
+ unsigned char visible;
+ uint64_t shape;
+ } set;
+@@ -423,12 +423,12 @@ struct qxl_cursor_cmd {
+ uint16_t length;
+ uint16_t frequency;
+ } trail;
+- struct qxl_point16 position;
++ struct compat_qxl_point16 position;
+ } u;
+ uint8_t device_data[QXL_CURSOR_DEVICE_DATA_SIZE];
+ };
+
+-struct qxl_rom {
++struct compat_qxl_rom {
+ uint32_t magic;
+ uint32_t id;
+ uint32_t update_id;
+@@ -444,7 +444,7 @@ struct qxl_rom {
+ uint32_t mm_clock;
+ };
+
+-struct qxl_ring_header {
++struct compat_qxl_ring_header {
+ uint32_t num_items;
+ uint32_t prod;
+ uint32_t notify_on_prod;
+@@ -454,38 +454,38 @@ struct qxl_ring_header {
+
+ #define QXL_LOG_BUF_SIZE 4096
+
+-struct qxl_ram_header {
++struct compat_qxl_ram_header {
+ uint32_t magic;
+ uint32_t int_pending;
+ uint32_t int_mask;
+ unsigned char log_buf[QXL_LOG_BUF_SIZE];
+- struct qxl_ring_header cmd_ring_hdr;
+- struct qxl_command cmd_ring[32];
+- struct qxl_ring_header cursor_ring_hdr;
+- struct qxl_command cursor_ring[32];
+- struct qxl_ring_header release_ring_hdr;
++ struct compat_qxl_ring_header cmd_ring_hdr;
++ struct compat_qxl_command cmd_ring[32];
++ struct compat_qxl_ring_header cursor_ring_hdr;
++ struct compat_qxl_command cursor_ring[32];
++ struct compat_qxl_ring_header release_ring_hdr;
+ uint64_t release_ring[8];
+- struct qxl_rect update_area;
++ struct compat_qxl_rect update_area;
+ };
+
+ #pragma pack(pop)
+
+-typedef struct _qxl_screen_t qxl_screen_t;
++typedef struct _compat_qxl_screen_t compat_qxl_screen_t;
+
+-struct _qxl_screen_t
++struct _compat_qxl_screen_t
+ {
+ /* These are the names QXL uses */
+ void * ram; /* Video RAM */
+ void * ram_physical;
+ void * vram; /* Command RAM */
+- struct qxl_rom * rom; /* Parameter RAM */
++ struct compat_qxl_rom * rom; /* Parameter RAM */
+
+- struct qxl_ring * command_ring;
+- struct qxl_ring * cursor_ring;
+- struct qxl_ring * release_ring;
++ struct compat_qxl_ring * command_ring;
++ struct compat_qxl_ring * cursor_ring;
++ struct compat_qxl_ring * release_ring;
+
+ int num_modes;
+- struct qxl_mode * modes;
++ struct compat_qxl_mode * modes;
+ int io_base;
+ int draw_area_offset;
+ int draw_area_size;
+@@ -493,7 +493,7 @@ struct _qxl_screen_t
+ void * fb;
+ int bytes_per_pixel;
+
+- struct qxl_mem * mem; /* Context for qxl_alloc/free */
++ struct compat_qxl_mem * mem; /* Context for compat_qxl_alloc/free */
+
+ EntityInfoPtr entity;
+
+@@ -530,15 +530,15 @@ struct _qxl_screen_t
+ };
+
+ static inline uint64_t
+-physical_address (qxl_screen_t *qxl, void *virtual)
++physical_address (compat_qxl_screen_t *compat_qxl, void *virtual)
+ {
+- return (uint64_t) ((unsigned long)virtual + (((unsigned long)qxl->ram_physical - (unsigned long)qxl->ram)));
++ return (uint64_t) ((unsigned long)virtual + (((unsigned long)compat_qxl->ram_physical - (unsigned long)compat_qxl->ram)));
+ }
+
+ static inline void *
+-virtual_address (qxl_screen_t *qxl, void *physical)
++virtual_address (compat_qxl_screen_t *compat_qxl, void *physical)
+ {
+- return (void *) ((unsigned long)physical + ((unsigned long)qxl->ram - (unsigned long)qxl->ram_physical));
++ return (void *) ((unsigned long)physical + ((unsigned long)compat_qxl->ram - (unsigned long)compat_qxl->ram_physical));
+ }
+
+ static inline void *
+@@ -553,58 +553,58 @@ pointer_to_u64 (void *p)
+ return (uint64_t)(unsigned long)p;
+ }
+
+-struct qxl_ring;
++struct compat_qxl_ring;
+
+ /*
+ * HW cursor
+ */
+-void qxl_cursor_init (ScreenPtr pScreen);
++void compat_qxl_cursor_init (ScreenPtr pScreen);
+
+
+
+ /*
+ * Rings
+ */
+-struct qxl_ring * qxl_ring_create (struct qxl_ring_header *header,
++struct compat_qxl_ring * compat_qxl_ring_create (struct compat_qxl_ring_header *header,
+ int element_size,
+ int n_elements,
+ int prod_notify);
+-void qxl_ring_push (struct qxl_ring *ring,
++void compat_qxl_ring_push (struct compat_qxl_ring *ring,
+ const void *element);
+-Bool qxl_ring_pop (struct qxl_ring *ring,
++Bool compat_qxl_ring_pop (struct compat_qxl_ring *ring,
+ void *element);
+-void qxl_ring_wait_idle (struct qxl_ring *ring);
++void compat_qxl_ring_wait_idle (struct compat_qxl_ring *ring);
+
+
+
+ /*
+ * Images
+ */
+-struct qxl_image *qxl_image_create (qxl_screen_t *qxl,
++struct compat_qxl_image *compat_qxl_image_create (compat_qxl_screen_t *compat_qxl,
+ const uint8_t *data,
+ int x,
+ int y,
+ int width,
+ int height,
+ int stride);
+-void qxl_image_destroy (qxl_screen_t *qxl,
+- struct qxl_image *image);
+-void qxl_drop_image_cache (qxl_screen_t *qxl);
++void compat_qxl_image_destroy (compat_qxl_screen_t *compat_qxl,
++ struct compat_qxl_image *image);
++void compat_qxl_drop_image_cache (compat_qxl_screen_t *compat_qxl);
+
+
+ /*
+ * Malloc
+ */
+-struct qxl_mem * qxl_mem_create (void *base,
++struct compat_qxl_mem * compat_qxl_mem_create (void *base,
+ unsigned long n_bytes);
+-void qxl_mem_dump_stats (struct qxl_mem *mem,
++void compat_qxl_mem_dump_stats (struct compat_qxl_mem *mem,
+ const char *header);
+-void * qxl_alloc (struct qxl_mem *mem,
++void * compat_qxl_alloc (struct compat_qxl_mem *mem,
+ unsigned long n_bytes);
+-void qxl_free (struct qxl_mem *mem,
++void compat_qxl_free (struct compat_qxl_mem *mem,
+ void *d);
+-void qxl_mem_free_all (struct qxl_mem *mem);
+-void * qxl_allocnf (qxl_screen_t *qxl,
++void compat_qxl_mem_free_all (struct compat_qxl_mem *mem);
++void * compat_qxl_allocnf (compat_qxl_screen_t *compat_qxl,
+ unsigned long size);
+
+
+diff --git a/src/compat/compat-qxl_cursor.c b/src/compat/compat-qxl_cursor.c
+index bb5387e..e94eb6a 100644
+--- a/src/compat/compat-qxl_cursor.c
++++ b/src/compat/compat-qxl_cursor.c
+@@ -25,25 +25,25 @@
+ #include <cursorstr.h>
+
+ static void
+-push_cursor (qxl_screen_t *qxl, struct qxl_cursor_cmd *cursor)
++push_cursor (compat_qxl_screen_t *compat_qxl, struct compat_qxl_cursor_cmd *cursor)
+ {
+- struct qxl_command cmd;
++ struct compat_qxl_command cmd;
+
+- /* See comment on push_command() in qxl_driver.c */
+- if (qxl->rom->mode != ~0)
++ /* See comment on push_command() in compat_qxl_driver.c */
++ if (compat_qxl->rom->mode != ~0)
+ {
+ cmd.type = QXL_CMD_CURSOR;
+- cmd.data = physical_address (qxl, cursor);
++ cmd.data = physical_address (compat_qxl, cursor);
+
+- qxl_ring_push (qxl->cursor_ring, &cmd);
++ compat_qxl_ring_push (compat_qxl->cursor_ring, &cmd);
+ }
+ }
+
+-static struct qxl_cursor_cmd *
+-qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
++static struct compat_qxl_cursor_cmd *
++compat_qxl_alloc_cursor_cmd(compat_qxl_screen_t *compat_qxl)
+ {
+- struct qxl_cursor_cmd *cmd =
+- qxl_allocnf (qxl, sizeof(struct qxl_cursor_cmd));
++ struct compat_qxl_cursor_cmd *cmd =
++ compat_qxl_allocnf (compat_qxl, sizeof(struct compat_qxl_cursor_cmd));
+
+ cmd->release_info.id = pointer_to_u64 (cmd) | 1;
+
+@@ -51,43 +51,43 @@ qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
+ }
+
+ static void
+-qxl_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
++compat_qxl_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
+ {
+- qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd(qxl);
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
++ struct compat_qxl_cursor_cmd *cmd = compat_qxl_alloc_cursor_cmd(compat_qxl);
+
+- qxl->cur_x = x;
+- qxl->cur_y = y;
++ compat_qxl->cur_x = x;
++ compat_qxl->cur_y = y;
+
+ cmd->type = QXL_CURSOR_MOVE;
+- cmd->u.position.x = qxl->cur_x + qxl->hot_x;
+- cmd->u.position.y = qxl->cur_y + qxl->hot_y;
++ cmd->u.position.x = compat_qxl->cur_x + compat_qxl->hot_x;
++ cmd->u.position.y = compat_qxl->cur_y + compat_qxl->hot_y;
+
+- push_cursor(qxl, cmd);
++ push_cursor(compat_qxl, cmd);
+ }
+
+ static void
+-qxl_load_cursor_image(ScrnInfoPtr pScrn, unsigned char *bits)
++compat_qxl_load_cursor_image(ScrnInfoPtr pScrn, unsigned char *bits)
+ {
+ }
+
+ static void
+-qxl_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
++compat_qxl_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
+ {
+ /* Should not be called since UseHWCursor returned FALSE */
+ }
+
+ static void
+-qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
++compat_qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
+ {
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ int w = pCurs->bits->width;
+ int h = pCurs->bits->height;
+ int size = w * h * sizeof (CARD32);
+
+- struct qxl_cursor_cmd *cmd = qxl_alloc_cursor_cmd (qxl);
+- struct qxl_cursor *cursor =
+- qxl_allocnf(qxl, sizeof(struct qxl_cursor) + size);
++ struct compat_qxl_cursor_cmd *cmd = compat_qxl_alloc_cursor_cmd (compat_qxl);
++ struct compat_qxl_cursor *cursor =
++ compat_qxl_allocnf(compat_qxl, sizeof(struct compat_qxl_cursor) + size);
+
+ cursor->header.unique = 0;
+ cursor->header.type = CURSOR_TYPE_ALPHA;
+@@ -121,20 +121,20 @@ qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
+ }
+ #endif
+
+- qxl->hot_x = pCurs->bits->xhot;
+- qxl->hot_y = pCurs->bits->yhot;
++ compat_qxl->hot_x = pCurs->bits->xhot;
++ compat_qxl->hot_y = pCurs->bits->yhot;
+
+ cmd->type = QXL_CURSOR_SET;
+- cmd->u.set.position.x = qxl->cur_x + qxl->hot_x;
+- cmd->u.set.position.y = qxl->cur_y + qxl->hot_y;
+- cmd->u.set.shape = physical_address (qxl, cursor);
++ cmd->u.set.position.x = compat_qxl->cur_x + compat_qxl->hot_x;
++ cmd->u.set.position.y = compat_qxl->cur_y + compat_qxl->hot_y;
++ cmd->u.set.shape = physical_address (compat_qxl, cursor);
+ cmd->u.set.visible = TRUE;
+
+- push_cursor(qxl, cmd);
++ push_cursor(compat_qxl, cmd);
+ }
+
+ static Bool
+-qxl_use_hw_cursor (ScreenPtr pScrn, CursorPtr pCurs)
++compat_qxl_use_hw_cursor (ScreenPtr pScrn, CursorPtr pCurs)
+ {
+ /* Old-school bitmap cursors are not
+ * hardware accelerated for now.
+@@ -143,36 +143,36 @@ qxl_use_hw_cursor (ScreenPtr pScrn, CursorPtr pCurs)
+ }
+
+ static Bool
+-qxl_use_hw_cursorARGB (ScreenPtr pScrn, CursorPtr pCurs)
++compat_qxl_use_hw_cursorARGB (ScreenPtr pScrn, CursorPtr pCurs)
+ {
+ return TRUE;
+ }
+
+ static void
+-qxl_hide_cursor(ScrnInfoPtr pScrn)
++compat_qxl_hide_cursor(ScrnInfoPtr pScrn)
+ {
+- qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_cursor_cmd *cursor = qxl_alloc_cursor_cmd(qxl);
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
++ struct compat_qxl_cursor_cmd *cursor = compat_qxl_alloc_cursor_cmd(compat_qxl);
+
+ cursor->type = QXL_CURSOR_HIDE;
+
+- push_cursor(qxl, cursor);
++ push_cursor(compat_qxl, cursor);
+ }
+
+ static void
+-qxl_show_cursor(ScrnInfoPtr pScrn)
++compat_qxl_show_cursor(ScrnInfoPtr pScrn)
+ {
+ /*
+ * slightly hacky, but there's no QXL_CURSOR_SHOW. Could maybe do
+ * QXL_CURSOR_SET?
+ */
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+
+- qxl_set_cursor_position(pScrn, qxl->cur_x, qxl->cur_y);
++ compat_qxl_set_cursor_position(pScrn, compat_qxl->cur_x, compat_qxl->cur_y);
+ }
+
+ hidden void
+-qxl_cursor_init(ScreenPtr pScreen)
++compat_qxl_cursor_init(ScreenPtr pScreen)
+ {
+ xf86CursorInfoPtr cursor;
+
+@@ -182,14 +182,14 @@ qxl_cursor_init(ScreenPtr pScreen)
+
+ cursor->MaxWidth = cursor->MaxHeight = 64;
+ /* cursor->Flags; */
+- cursor->SetCursorPosition = qxl_set_cursor_position;
+- cursor->LoadCursorARGB = qxl_load_cursor_argb;
+- cursor->UseHWCursor = qxl_use_hw_cursor;
+- cursor->UseHWCursorARGB = qxl_use_hw_cursorARGB;
+- cursor->LoadCursorImage = qxl_load_cursor_image;
+- cursor->SetCursorColors = qxl_set_cursor_colors;
+- cursor->HideCursor = qxl_hide_cursor;
+- cursor->ShowCursor = qxl_show_cursor;
++ cursor->SetCursorPosition = compat_qxl_set_cursor_position;
++ cursor->LoadCursorARGB = compat_qxl_load_cursor_argb;
++ cursor->UseHWCursor = compat_qxl_use_hw_cursor;
++ cursor->UseHWCursorARGB = compat_qxl_use_hw_cursorARGB;
++ cursor->LoadCursorImage = compat_qxl_load_cursor_image;
++ cursor->SetCursorColors = compat_qxl_set_cursor_colors;
++ cursor->HideCursor = compat_qxl_hide_cursor;
++ cursor->ShowCursor = compat_qxl_show_cursor;
+
+ if (!xf86InitCursor(pScreen, cursor))
+ xfree(cursor);
+diff --git a/src/compat/compat-qxl_driver.c b/src/compat/compat-qxl_driver.c
+index 7cd5f40..758ee24 100644
+--- a/src/compat/compat-qxl_driver.c
++++ b/src/compat/compat-qxl_driver.c
+@@ -20,10 +20,10 @@
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+-/** \file qxl_driver.c
++/** \file compat_qxl_driver.c
+ * \author Adam Jackson <ajax at redhat.com>
+ *
+- * This is qxl, a driver for the Qumranet paravirtualized graphics device
++ * This is compat_qxl, a driver for the Qumranet paravirtualized graphics device
+ * in qemu.
+ */
+
+@@ -39,12 +39,12 @@
+ #define CHECK_POINT()
+
+ static int
+-garbage_collect (qxl_screen_t *qxl)
++garbage_collect (compat_qxl_screen_t *compat_qxl)
+ {
+ uint64_t id;
+ int i = 0;
+
+- while (qxl_ring_pop (qxl->release_ring, &id))
++ while (compat_qxl_ring_pop (compat_qxl->release_ring, &id))
+ {
+ while (id)
+ {
+@@ -54,9 +54,9 @@ garbage_collect (qxl_screen_t *qxl)
+ */
+ #define POINTER_MASK ((1 << 2) - 1)
+
+- union qxl_release_info *info = u64_to_pointer (id & ~POINTER_MASK);
+- struct qxl_cursor_cmd *cmd = (struct qxl_cursor_cmd *)info;
+- struct qxl_drawable *drawable = (struct qxl_drawable *)info;
++ union compat_qxl_release_info *info = u64_to_pointer (id & ~POINTER_MASK);
++ struct compat_qxl_cursor_cmd *cmd = (struct compat_qxl_cursor_cmd *)info;
++ struct compat_qxl_drawable *drawable = (struct compat_qxl_drawable *)info;
+ int is_cursor = FALSE;
+
+ if ((id & POINTER_MASK) == 1)
+@@ -64,22 +64,22 @@ garbage_collect (qxl_screen_t *qxl)
+
+ if (is_cursor && cmd->type == QXL_CURSOR_SET)
+ {
+- struct qxl_cursor *cursor = (void *)virtual_address (
+- qxl, u64_to_pointer (cmd->u.set.shape));
++ struct compat_qxl_cursor *cursor = (void *)virtual_address (
++ compat_qxl, u64_to_pointer (cmd->u.set.shape));
+
+- qxl_free (qxl->mem, cursor);
++ compat_qxl_free (compat_qxl->mem, cursor);
+ }
+ else if (!is_cursor && drawable->type == QXL_DRAW_COPY)
+ {
+- struct qxl_image *image = virtual_address (
+- qxl, u64_to_pointer (drawable->u.copy.src_bitmap));
++ struct compat_qxl_image *image = virtual_address (
++ compat_qxl, u64_to_pointer (drawable->u.copy.src_bitmap));
+
+- qxl_image_destroy (qxl, image);
++ compat_qxl_image_destroy (compat_qxl, image);
+ }
+
+ id = info->next;
+
+- qxl_free (qxl->mem, info);
++ compat_qxl_free (compat_qxl->mem, info);
+ }
+ }
+
+@@ -87,7 +87,7 @@ garbage_collect (qxl_screen_t *qxl)
+ }
+
+ static void
+-qxl_usleep (int useconds)
++compat_qxl_usleep (int useconds)
+ {
+ struct timespec t;
+
+@@ -102,35 +102,35 @@ qxl_usleep (int useconds)
+
+ #if 0
+ static void
+-push_update_area (qxl_screen_t *qxl, const struct qxl_rect *area)
++push_update_area (compat_qxl_screen_t *compat_qxl, const struct compat_qxl_rect *area)
+ {
+- struct qxl_update_cmd *update = qxl_allocnf (qxl, sizeof *update);
+- struct qxl_command cmd;
++ struct compat_qxl_update_cmd *update = compat_qxl_allocnf (compat_qxl, sizeof *update);
++ struct compat_qxl_command cmd;
+
+ update->release_info.id = (uint64_t)update;
+ update->area = *area;
+ update->update_id = 0;
+
+ cmd.type = QXL_CMD_UDPATE;
+- cmd.data = physical_address (qxl, update);
++ cmd.data = physical_address (compat_qxl, update);
+
+- qxl_ring_push (qxl->command_ring, &cmd);
++ compat_qxl_ring_push (compat_qxl->command_ring, &cmd);
+ }
+ #endif
+
+ void *
+-qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
++compat_qxl_allocnf (compat_qxl_screen_t *compat_qxl, unsigned long size)
+ {
+ void *result;
+ int n_attempts = 0;
+ static int nth_oom = 1;
+
+- garbage_collect (qxl);
++ garbage_collect (compat_qxl);
+
+- while (!(result = qxl_alloc (qxl->mem, size)))
++ while (!(result = compat_qxl_alloc (compat_qxl->mem, size)))
+ {
+- struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram +
+- qxl->rom->ram_header_offset);
++ struct compat_qxl_ram_header *ram_header = (void *)((unsigned long)compat_qxl->ram +
++ compat_qxl->rom->ram_header_offset);
+
+ /* Rather than go out of memory, we simply tell the
+ * device to dump everything
+@@ -140,21 +140,21 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
+ ram_header->update_area.left = 0;
+ ram_header->update_area.right = 800;
+
+- outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
++ outb (compat_qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+
+ ErrorF ("eliminated memory (%d)\n", nth_oom++);
+
+- outb (qxl->io_base + QXL_IO_NOTIFY_OOM, 0);
++ outb (compat_qxl->io_base + QXL_IO_NOTIFY_OOM, 0);
+
+- qxl_usleep (10000);
++ compat_qxl_usleep (10000);
+
+- if (garbage_collect (qxl))
++ if (garbage_collect (compat_qxl))
+ {
+ n_attempts = 0;
+ }
+ else if (++n_attempts == 1000)
+ {
+- qxl_mem_dump_stats (qxl->mem, "Out of mem - stats\n");
++ compat_qxl_mem_dump_stats (compat_qxl->mem, "Out of mem - stats\n");
+
+ fprintf (stderr, "Out of memory\n");
+ exit (1);
+@@ -165,127 +165,127 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
+ }
+
+ static Bool
+-qxl_blank_screen(ScreenPtr pScreen, int mode)
++compat_qxl_blank_screen(ScreenPtr pScreen, int mode)
+ {
+ return TRUE;
+ }
+
+ static void
+-qxl_unmap_memory(qxl_screen_t *qxl, int scrnIndex)
++compat_qxl_unmap_memory(compat_qxl_screen_t *compat_qxl, int scrnIndex)
+ {
+ #ifdef XSERVER_LIBPCIACCESS
+- if (qxl->ram)
+- pci_device_unmap_range(qxl->pci, qxl->ram, qxl->pci->regions[0].size);
+- if (qxl->vram)
+- pci_device_unmap_range(qxl->pci, qxl->vram, qxl->pci->regions[1].size);
+- if (qxl->rom)
+- pci_device_unmap_range(qxl->pci, qxl->rom, qxl->pci->regions[2].size);
++ if (compat_qxl->ram)
++ pci_device_unmap_range(compat_qxl->pci, compat_qxl->ram, compat_qxl->pci->regions[0].size);
++ if (compat_qxl->vram)
++ pci_device_unmap_range(compat_qxl->pci, compat_qxl->vram, compat_qxl->pci->regions[1].size);
++ if (compat_qxl->rom)
++ pci_device_unmap_range(compat_qxl->pci, compat_qxl->rom, compat_qxl->pci->regions[2].size);
+ #else
+- if (qxl->ram)
+- xf86UnMapVidMem(scrnIndex, qxl->ram, (1 << qxl->pci->size[0]));
+- if (qxl->vram)
+- xf86UnMapVidMem(scrnIndex, qxl->vram, (1 << qxl->pci->size[1]));
+- if (qxl->rom)
+- xf86UnMapVidMem(scrnIndex, qxl->rom, (1 << qxl->pci->size[2]));
++ if (compat_qxl->ram)
++ xf86UnMapVidMem(scrnIndex, compat_qxl->ram, (1 << compat_qxl->pci->size[0]));
++ if (compat_qxl->vram)
++ xf86UnMapVidMem(scrnIndex, compat_qxl->vram, (1 << compat_qxl->pci->size[1]));
++ if (compat_qxl->rom)
++ xf86UnMapVidMem(scrnIndex, compat_qxl->rom, (1 << compat_qxl->pci->size[2]));
+ #endif
+
+- qxl->ram = qxl->ram_physical = qxl->vram = qxl->rom = NULL;
++ compat_qxl->ram = compat_qxl->ram_physical = compat_qxl->vram = compat_qxl->rom = NULL;
+
+- qxl->num_modes = 0;
+- qxl->modes = NULL;
++ compat_qxl->num_modes = 0;
++ compat_qxl->modes = NULL;
+ }
+
+ static Bool
+-qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
++compat_qxl_map_memory(compat_qxl_screen_t *compat_qxl, int scrnIndex)
+ {
+ #ifdef XSERVER_LIBPCIACCESS
+- pci_device_map_range(qxl->pci, qxl->pci->regions[0].base_addr,
+- qxl->pci->regions[0].size,
++ pci_device_map_range(compat_qxl->pci, compat_qxl->pci->regions[0].base_addr,
++ compat_qxl->pci->regions[0].size,
+ PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+- &qxl->ram);
+- qxl->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr);
++ &compat_qxl->ram);
++ compat_qxl->ram_physical = u64_to_pointer (compat_qxl->pci->regions[0].base_addr);
+
+- pci_device_map_range(qxl->pci, qxl->pci->regions[1].base_addr,
+- qxl->pci->regions[1].size,
++ pci_device_map_range(compat_qxl->pci, compat_qxl->pci->regions[1].base_addr,
++ compat_qxl->pci->regions[1].size,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+- &qxl->vram);
++ &compat_qxl->vram);
+
+- pci_device_map_range(qxl->pci, qxl->pci->regions[2].base_addr,
+- qxl->pci->regions[2].size, 0,
+- (void **)&qxl->rom);
++ pci_device_map_range(compat_qxl->pci, compat_qxl->pci->regions[2].base_addr,
++ compat_qxl->pci->regions[2].size, 0,
++ (void **)&compat_qxl->rom);
+
+- qxl->io_base = qxl->pci->regions[3].base_addr;
++ compat_qxl->io_base = compat_qxl->pci->regions[3].base_addr;
+ #else
+- qxl->ram = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
+- qxl->pci_tag, qxl->pci->memBase[0],
+- (1 << qxl->pci->size[0]));
+- qxl->ram_physical = (void *)qxl->pci->memBase[0];
++ compat_qxl->ram = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
++ compat_qxl->pci_tag, compat_qxl->pci->memBase[0],
++ (1 << compat_qxl->pci->size[0]));
++ compat_qxl->ram_physical = (void *)compat_qxl->pci->memBase[0];
+
+- qxl->vram = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
+- qxl->pci_tag, qxl->pci->memBase[1],
+- (1 << qxl->pci->size[1]));
++ compat_qxl->vram = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
++ compat_qxl->pci_tag, compat_qxl->pci->memBase[1],
++ (1 << compat_qxl->pci->size[1]));
+
+- qxl->rom = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
+- qxl->pci_tag, qxl->pci->memBase[2],
+- (1 << qxl->pci->size[2]));
++ compat_qxl->rom = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
++ compat_qxl->pci_tag, compat_qxl->pci->memBase[2],
++ (1 << compat_qxl->pci->size[2]));
+
+- qxl->io_base = qxl->pci->ioBase[3];
++ compat_qxl->io_base = compat_qxl->pci->ioBase[3];
+ #endif
+- if (!qxl->ram || !qxl->vram || !qxl->rom)
++ if (!compat_qxl->ram || !compat_qxl->vram || !compat_qxl->rom)
+ return FALSE;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "ram at %p; vram at %p; rom at %p\n",
+- qxl->ram, qxl->vram, qxl->rom);
++ compat_qxl->ram, compat_qxl->vram, compat_qxl->rom);
+
+- qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
+- qxl->modes = (struct qxl_mode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
++ compat_qxl->num_modes = *(uint32_t *)((uint8_t *)compat_qxl->rom + compat_qxl->rom->modes_offset);
++ compat_qxl->modes = (struct compat_qxl_mode *)(((uint8_t *)compat_qxl->rom) + compat_qxl->rom->modes_offset + 4);
+
+ return TRUE;
+ }
+
+ static void
+-qxl_save_state(ScrnInfoPtr pScrn)
++compat_qxl_save_state(ScrnInfoPtr pScrn)
+ {
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+
+- vgaHWSaveFonts(pScrn, &qxl->vgaRegs);
++ vgaHWSaveFonts(pScrn, &compat_qxl->vgaRegs);
+ }
+
+ static void
+-qxl_restore_state(ScrnInfoPtr pScrn)
++compat_qxl_restore_state(ScrnInfoPtr pScrn)
+ {
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+
+- vgaHWRestoreFonts(pScrn, &qxl->vgaRegs);
++ vgaHWRestoreFonts(pScrn, &compat_qxl->vgaRegs);
+ }
+
+ static Bool
+-qxl_close_screen(int scrnIndex, ScreenPtr pScreen)
++compat_qxl_close_screen(int scrnIndex, ScreenPtr pScreen)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+
+ if (pScrn->vtSema) {
+- qxl_restore_state(pScrn);
+- qxl_unmap_memory(qxl, scrnIndex);
++ compat_qxl_restore_state(pScrn);
++ compat_qxl_unmap_memory(compat_qxl, scrnIndex);
+ }
+ pScrn->vtSema = FALSE;
+
+- xfree(qxl->fb);
++ xfree(compat_qxl->fb);
+
+- pScreen->CreateScreenResources = qxl->create_screen_resources;
+- pScreen->CloseScreen = qxl->close_screen;
++ pScreen->CreateScreenResources = compat_qxl->create_screen_resources;
++ pScreen->CloseScreen = compat_qxl->close_screen;
+
+ return pScreen->CloseScreen(scrnIndex, pScreen);
+ }
+
+ static Bool
+-qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
++compat_qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
+ {
+- qxl_screen_t *qxl = xf86Screens[scrnIndex]->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = xf86Screens[scrnIndex]->driverPrivate;
+ int mode_index = (int)(unsigned long)p->Private;
+- struct qxl_mode *m = qxl->modes + mode_index;
+- ScreenPtr pScreen = qxl->pScrn->pScreen;
++ struct compat_qxl_mode *m = compat_qxl->modes + mode_index;
++ ScreenPtr pScreen = compat_qxl->pScrn->pScreen;
+
+ if (!m)
+ return FALSE;
+@@ -294,11 +294,11 @@ qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
+ xf86DrvMsg (scrnIndex, X_INFO, "Setting mode %d (%d x %d) (%d x %d) %p\n",
+ m->id, m->x_res, m->y_res, p->HDisplay, p->VDisplay, p);
+
+- outb(qxl->io_base + QXL_IO_RESET, 0);
++ outb(compat_qxl->io_base + QXL_IO_RESET, 0);
+
+- outb(qxl->io_base + QXL_IO_SET_MODE, m->id);
++ outb(compat_qxl->io_base + QXL_IO_SET_MODE, m->id);
+
+- qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8;
++ compat_qxl->bytes_per_pixel = (compat_qxl->pScrn->bitsPerPixel + 7) / 8;
+
+ /* If this happens out of ScreenInit, we won't have a screen yet. In that
+ * case createScreenResources will make things right.
+@@ -313,15 +313,15 @@ qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
+ pPixmap,
+ m->x_res, m->y_res,
+ -1, -1,
+- qxl->pScrn->displayWidth * qxl->bytes_per_pixel,
++ compat_qxl->pScrn->displayWidth * compat_qxl->bytes_per_pixel,
+ NULL);
+ }
+ }
+
+- if (qxl->mem)
++ if (compat_qxl->mem)
+ {
+- qxl_mem_free_all (qxl->mem);
+- qxl_drop_image_cache (qxl);
++ compat_qxl_mem_free_all (compat_qxl->mem);
++ compat_qxl_drop_image_cache (compat_qxl);
+ }
+
+
+@@ -329,9 +329,9 @@ qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
+ }
+
+ static void
+-push_drawable (qxl_screen_t *qxl, struct qxl_drawable *drawable)
++push_drawable (compat_qxl_screen_t *compat_qxl, struct compat_qxl_drawable *drawable)
+ {
+- struct qxl_command cmd;
++ struct compat_qxl_command cmd;
+
+ /* When someone runs "init 3", the device will be
+ * switched into VGA mode and there is nothing we
+@@ -345,25 +345,25 @@ push_drawable (qxl_screen_t *qxl, struct qxl_drawable *drawable)
+ * The author of the QXL device is opposed to this
+ * for reasons I don't understand.
+ */
+- if (qxl->rom->mode != ~0)
++ if (compat_qxl->rom->mode != ~0)
+ {
+ cmd.type = QXL_CMD_DRAW;
+- cmd.data = physical_address (qxl, drawable);
++ cmd.data = physical_address (compat_qxl, drawable);
+
+- qxl_ring_push (qxl->command_ring, &cmd);
++ compat_qxl_ring_push (compat_qxl->command_ring, &cmd);
+ }
+ }
+
+-static struct qxl_drawable *
+-make_drawable (qxl_screen_t *qxl, uint8_t type,
+- const struct qxl_rect *rect
++static struct compat_qxl_drawable *
++make_drawable (compat_qxl_screen_t *compat_qxl, uint8_t type,
++ const struct compat_qxl_rect *rect
+ /* , pRegion clip */)
+ {
+- struct qxl_drawable *drawable;
++ struct compat_qxl_drawable *drawable;
+
+ CHECK_POINT();
+
+- drawable = qxl_allocnf (qxl, sizeof *drawable);
++ drawable = compat_qxl_allocnf (compat_qxl, sizeof *drawable);
+
+ CHECK_POINT();
+
+@@ -383,7 +383,7 @@ make_drawable (qxl_screen_t *qxl, uint8_t type,
+ if (rect)
+ drawable->bbox = *rect;
+
+- drawable->mm_time = qxl->rom->mm_clock;
++ drawable->mm_time = compat_qxl->rom->mm_clock;
+
+ CHECK_POINT();
+
+@@ -405,7 +405,7 @@ enum ROPDescriptor {
+ };
+
+ static void
+-undamage_box (qxl_screen_t *qxl, const struct qxl_rect *rect)
++undamage_box (compat_qxl_screen_t *compat_qxl, const struct compat_qxl_rect *rect)
+ {
+ RegionRec region;
+ BoxRec box;
+@@ -415,27 +415,27 @@ undamage_box (qxl_screen_t *qxl, const struct qxl_rect *rect)
+ box.x2 = rect->right;
+ box.y2 = rect->bottom;
+
+- REGION_INIT (qxl->pScrn->pScreen, ®ion, &box, 0);
++ REGION_INIT (compat_qxl->pScrn->pScreen, ®ion, &box, 0);
+
+- REGION_SUBTRACT (qxl->pScrn->pScreen, &(qxl->pending_copy), &(qxl->pending_copy), ®ion);
++ REGION_SUBTRACT (compat_qxl->pScrn->pScreen, &(compat_qxl->pending_copy), &(compat_qxl->pending_copy), ®ion);
+
+- REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++ REGION_EMPTY (compat_qxl->pScrn->pScreen, &(compat_qxl->pending_copy));
+ }
+
+ static void
+-clear_pending_damage (qxl_screen_t *qxl)
++clear_pending_damage (compat_qxl_screen_t *compat_qxl)
+ {
+- REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++ REGION_EMPTY (compat_qxl->pScrn->pScreen, &(compat_qxl->pending_copy));
+ }
+
+ static void
+-submit_fill (qxl_screen_t *qxl, const struct qxl_rect *rect, uint32_t color)
++submit_fill (compat_qxl_screen_t *compat_qxl, const struct compat_qxl_rect *rect, uint32_t color)
+ {
+- struct qxl_drawable *drawable;
++ struct compat_qxl_drawable *drawable;
+
+ CHECK_POINT();
+
+- drawable = make_drawable (qxl, QXL_DRAW_FILL, rect);
++ drawable = make_drawable (compat_qxl, QXL_DRAW_FILL, rect);
+
+ CHECK_POINT();
+
+@@ -447,13 +447,13 @@ submit_fill (qxl_screen_t *qxl, const struct qxl_rect *rect, uint32_t color)
+ drawable->u.fill.mask.pos.y = 0;
+ drawable->u.fill.mask.bitmap = 0;
+
+- push_drawable (qxl, drawable);
++ push_drawable (compat_qxl, drawable);
+
+- undamage_box (qxl, rect);
++ undamage_box (compat_qxl, rect);
+ }
+
+ static void
+-translate_rect (struct qxl_rect *rect)
++translate_rect (struct compat_qxl_rect *rect)
+ {
+ rect->right -= rect->left;
+ rect->bottom -= rect->top;
+@@ -461,10 +461,10 @@ translate_rect (struct qxl_rect *rect)
+ }
+
+ static void
+-submit_copy (qxl_screen_t *qxl, const struct qxl_rect *rect)
++submit_copy (compat_qxl_screen_t *compat_qxl, const struct compat_qxl_rect *rect)
+ {
+- struct qxl_drawable *drawable;
+- ScrnInfoPtr pScrn = qxl->pScrn;
++ struct compat_qxl_drawable *drawable;
++ ScrnInfoPtr pScrn = compat_qxl->pScrn;
+
+ if (rect->left == rect->right ||
+ rect->top == rect->bottom)
+@@ -473,13 +473,13 @@ submit_copy (qxl_screen_t *qxl, const struct qxl_rect *rect)
+ return ;
+ }
+
+- drawable = make_drawable (qxl, QXL_DRAW_COPY, rect);
++ drawable = make_drawable (compat_qxl, QXL_DRAW_COPY, rect);
+
+ drawable->u.copy.src_bitmap = physical_address (
+- qxl, qxl_image_create (qxl, qxl->fb, rect->left, rect->top,
++ compat_qxl, compat_qxl_image_create (compat_qxl, compat_qxl->fb, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top,
+- pScrn->displayWidth * qxl->bytes_per_pixel));
++ pScrn->displayWidth * compat_qxl->bytes_per_pixel));
+ drawable->u.copy.src_area = *rect;
+ translate_rect (&drawable->u.copy.src_area);
+ drawable->u.copy.rop_descriptor = ROPD_OP_PUT;
+@@ -489,7 +489,7 @@ submit_copy (qxl_screen_t *qxl, const struct qxl_rect *rect)
+ drawable->u.copy.mask.pos.y = 0;
+ drawable->u.copy.mask.bitmap = 0;
+
+- push_drawable (qxl, drawable);
++ push_drawable (compat_qxl, drawable);
+ }
+
+ static void
+@@ -511,87 +511,87 @@ print_region (const char *header, RegionPtr pRegion)
+ }
+
+ static void
+-accept_damage (qxl_screen_t *qxl)
++accept_damage (compat_qxl_screen_t *compat_qxl)
+ {
+- REGION_UNION (qxl->pScrn->pScreen, &(qxl->to_be_sent), &(qxl->to_be_sent),
+- &(qxl->pending_copy));
++ REGION_UNION (compat_qxl->pScrn->pScreen, &(compat_qxl->to_be_sent), &(compat_qxl->to_be_sent),
++ &(compat_qxl->pending_copy));
+
+- REGION_EMPTY (qxl->pScrn->pScreen, &(qxl->pending_copy));
++ REGION_EMPTY (compat_qxl->pScrn->pScreen, &(compat_qxl->pending_copy));
+ }
+
+ static void
+-qxl_send_copies (qxl_screen_t *qxl)
++compat_qxl_send_copies (compat_qxl_screen_t *compat_qxl)
+ {
+ BoxPtr pBox;
+ int nbox;
+
+- nbox = REGION_NUM_RECTS (&qxl->to_be_sent);
+- pBox = REGION_RECTS (&qxl->to_be_sent);
++ nbox = REGION_NUM_RECTS (&compat_qxl->to_be_sent);
++ pBox = REGION_RECTS (&compat_qxl->to_be_sent);
+
+-/* if (REGION_NUM_RECTS (&qxl->to_be_sent) > 0) */
+-/* print_region ("send bits", &qxl->to_be_sent); */
++/* if (REGION_NUM_RECTS (&compat_qxl->to_be_sent) > 0) */
++/* print_region ("send bits", &compat_qxl->to_be_sent); */
+
+ while (nbox--)
+ {
+- struct qxl_rect qrect;
++ struct compat_qxl_rect qrect;
+
+ qrect.top = pBox->y1;
+ qrect.left = pBox->x1;
+ qrect.bottom = pBox->y2;
+ qrect.right = pBox->x2;
+
+- submit_copy (qxl, &qrect);
++ submit_copy (compat_qxl, &qrect);
+
+ pBox++;
+ }
+
+- REGION_EMPTY(qxl->pScrn->pScreen, &qxl->to_be_sent);
++ REGION_EMPTY(compat_qxl->pScrn->pScreen, &compat_qxl->to_be_sent);
+ }
+
+ static void
+-paint_shadow (qxl_screen_t *qxl)
++paint_shadow (compat_qxl_screen_t *compat_qxl)
+ {
+- struct qxl_rect qrect;
++ struct compat_qxl_rect qrect;
+
+ qrect.top = 0;
+ qrect.bottom = 1200;
+ qrect.left = 0;
+ qrect.right = 1600;
+
+- submit_copy (qxl, &qrect);
++ submit_copy (compat_qxl, &qrect);
+ }
+
+ static void
+-qxl_sanity_check (qxl_screen_t *qxl)
++compat_qxl_sanity_check (compat_qxl_screen_t *compat_qxl)
+ {
+ /* read the mode back from the rom */
+- if (!qxl->rom || !qxl->pScrn)
++ if (!compat_qxl->rom || !compat_qxl->pScrn)
+ return;
+
+- if (qxl->rom->mode == ~0)
++ if (compat_qxl->rom->mode == ~0)
+ {
+ ErrorF("QXL device jumped back to VGA mode - resetting mode\n");
+- qxl_switch_mode(qxl->pScrn->scrnIndex, qxl->pScrn->currentMode, 0);
++ compat_qxl_switch_mode(compat_qxl->pScrn->scrnIndex, compat_qxl->pScrn->currentMode, 0);
+ }
+ }
+
+ static void
+-qxl_block_handler (pointer data, OSTimePtr pTimeout, pointer pRead)
++compat_qxl_block_handler (pointer data, OSTimePtr pTimeout, pointer pRead)
+ {
+- qxl_screen_t *qxl = (qxl_screen_t *) data;
++ compat_qxl_screen_t *compat_qxl = (compat_qxl_screen_t *) data;
+
+- if (!qxl->pScrn->vtSema)
++ if (!compat_qxl->pScrn->vtSema)
+ return;
+
+- qxl_sanity_check(qxl);
++ compat_qxl_sanity_check(compat_qxl);
+
+- accept_damage (qxl);
++ accept_damage (compat_qxl);
+
+- qxl_send_copies (qxl);
++ compat_qxl_send_copies (compat_qxl);
+ }
+
+ static void
+-qxl_wakeup_handler (pointer data, int i, pointer LastSelectMask)
++compat_qxl_wakeup_handler (pointer data, int i, pointer LastSelectMask)
+ {
+ }
+
+@@ -612,59 +612,59 @@ qxl_wakeup_handler (pointer data, int i, pointer LastSelectMask)
+ * damage, that must first be unioned onto to_be_sent, and then the new
+ * damage must be stored in pending_copy.
+ *
+- * The qxl_screen_t struct contains two regions, "pending_copy" and
++ * The compat_qxl_screen_t struct contains two regions, "pending_copy" and
+ * "to_be_sent".
+ *
+ * Pending copy is
+ *
+ */
+ static void
+-qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure)
++compat_qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure)
+ {
+- qxl_screen_t *qxl = closure;
++ compat_qxl_screen_t *compat_qxl = closure;
+
+ /* print_region ("damage", pRegion); */
+
+ /* print_region ("on_damage ", pRegion); */
+
+- accept_damage (qxl);
++ accept_damage (compat_qxl);
+
+-/* print_region ("accepting, qxl->to_be_sent is now", &qxl->to_be_sent); */
++/* print_region ("accepting, compat_qxl->to_be_sent is now", &compat_qxl->to_be_sent); */
+
+- REGION_COPY (qxl->pScrn->pScreen, &(qxl->pending_copy), pRegion);
++ REGION_COPY (compat_qxl->pScrn->pScreen, &(compat_qxl->pending_copy), pRegion);
+ }
+
+
+ static Bool
+-qxl_create_screen_resources(ScreenPtr pScreen)
++compat_qxl_create_screen_resources(ScreenPtr pScreen)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ Bool ret;
+ PixmapPtr pPixmap;
+
+- pScreen->CreateScreenResources = qxl->create_screen_resources;
++ pScreen->CreateScreenResources = compat_qxl->create_screen_resources;
+ ret = pScreen->CreateScreenResources (pScreen);
+- pScreen->CreateScreenResources = qxl_create_screen_resources;
++ pScreen->CreateScreenResources = compat_qxl_create_screen_resources;
+
+ if (!ret)
+ return FALSE;
+
+- qxl->damage = DamageCreate (qxl_on_damage, NULL,
++ compat_qxl->damage = DamageCreate (compat_qxl_on_damage, NULL,
+ DamageReportRawRegion,
+- TRUE, pScreen, qxl);
++ TRUE, pScreen, compat_qxl);
+
+
+ pPixmap = pScreen->GetScreenPixmap(pScreen);
+
+- if (!RegisterBlockAndWakeupHandlers(qxl_block_handler, qxl_wakeup_handler, qxl))
++ if (!RegisterBlockAndWakeupHandlers(compat_qxl_block_handler, compat_qxl_wakeup_handler, compat_qxl))
+ return FALSE;
+
+- REGION_INIT (pScreen, &(qxl->pending_copy), NullBox, 0);
++ REGION_INIT (pScreen, &(compat_qxl->pending_copy), NullBox, 0);
+
+- REGION_INIT (pScreen, &(qxl->to_be_sent), NullBox, 0);
++ REGION_INIT (pScreen, &(compat_qxl->to_be_sent), NullBox, 0);
+
+- DamageRegister (&pPixmap->drawable, qxl->damage);
++ DamageRegister (&pPixmap->drawable, compat_qxl->damage);
+ return TRUE;
+ }
+
+@@ -686,13 +686,13 @@ get_window_pixmap (DrawablePtr pDrawable, int *xoff, int *yoff)
+ }
+
+ static void
+-qxl_poly_fill_rect (DrawablePtr pDrawable,
++compat_qxl_poly_fill_rect (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prect)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[pDrawable->pScreen->myNum];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ PixmapPtr pPixmap;
+ int xoff, yoff;
+
+@@ -714,14 +714,14 @@ qxl_poly_fill_rect (DrawablePtr pDrawable,
+
+ while (nbox--)
+ {
+- struct qxl_rect qrect;
++ struct compat_qxl_rect qrect;
+
+ qrect.left = pBox->x1;
+ qrect.right = pBox->x2;
+ qrect.top = pBox->y1;
+ qrect.bottom = pBox->y2;
+
+- submit_fill (qxl, &qrect, pGC->fgPixel);
++ submit_fill (compat_qxl, &qrect, pGC->fgPixel);
+
+ pBox++;
+ }
+@@ -733,7 +733,7 @@ qxl_poly_fill_rect (DrawablePtr pDrawable,
+ }
+
+ static void
+-qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
++compat_qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+@@ -747,7 +747,7 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ {
+ ScreenPtr pScreen = pSrcDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ int src_xoff, src_yoff;
+ int dst_xoff, dst_yoff;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+@@ -776,7 +776,7 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ if (n)
+ {
+ /* ErrorF ("Clearing pending damage\n"); */
+- clear_pending_damage (qxl);
++ clear_pending_damage (compat_qxl);
+
+ /* We have to do this because the copy will cause the damage
+ * to be sent to move.
+@@ -786,13 +786,13 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ * complex, and the performance win is unlikely to be
+ * very big.
+ */
+- qxl_send_copies (qxl);
++ compat_qxl_send_copies (compat_qxl);
+ }
+
+ while (n--)
+ {
+- struct qxl_drawable *drawable;
+- struct qxl_rect qrect;
++ struct compat_qxl_drawable *drawable;
++ struct compat_qxl_rect qrect;
+
+ qrect.top = b->y1;
+ qrect.bottom = b->y2;
+@@ -803,19 +803,19 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ /* b->x1, b->y1, b->x2, b->y2, */
+ /* dx, dy, dst_xoff, dst_yoff); */
+
+- drawable = make_drawable (qxl, QXL_COPY_BITS, &qrect);
++ drawable = make_drawable (compat_qxl, QXL_COPY_BITS, &qrect);
+ drawable->u.copy_bits.src_pos.x = b->x1 + dx;
+ drawable->u.copy_bits.src_pos.y = b->y1 + dy;
+
+- push_drawable (qxl, drawable);
++ push_drawable (compat_qxl, drawable);
+
+ #if 0
+ if (closure)
+- qxl_usleep (1000000);
++ compat_qxl_usleep (1000000);
+ #endif
+
+ #if 0
+- submit_fill (qxl, &qrect, rand());
++ submit_fill (compat_qxl, &qrect, rand());
+ #endif
+
+ b++;
+@@ -828,7 +828,7 @@ qxl_copy_n_to_n (DrawablePtr pSrcDrawable,
+ }
+
+ static RegionPtr
+-qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
++compat_qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+ {
+ if (pSrcDrawable->type == DRAWABLE_WINDOW &&
+@@ -841,7 +841,7 @@ qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+
+ res = fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+- qxl_copy_n_to_n, 0, NULL);
++ compat_qxl_copy_n_to_n, 0, NULL);
+
+ return res;
+ }
+@@ -856,11 +856,11 @@ qxl_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ }
+
+ static void
+-qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel)
++compat_qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ PixmapPtr pPixmap;
+ int xoff, yoff;
+
+@@ -871,14 +871,14 @@ qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel)
+
+ while (nbox--)
+ {
+- struct qxl_rect qrect;
++ struct compat_qxl_rect qrect;
+
+ qrect.left = pBox->x1;
+ qrect.right = pBox->x2;
+ qrect.top = pBox->y1;
+ qrect.bottom = pBox->y2;
+
+- submit_fill (qxl, &qrect, pixel);
++ submit_fill (compat_qxl, &qrect, pixel);
+
+ pBox++;
+ }
+@@ -889,7 +889,7 @@ qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel)
+ }
+
+ static void
+-qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
++compat_qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+ {
+ RegionRec rgnDst;
+ int dx, dy;
+@@ -905,7 +905,7 @@ qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+
+ fbCopyRegion (&pWin->drawable, &pWin->drawable,
+ NULL,
+- &rgnDst, dx, dy, qxl_copy_n_to_n, 0, NULL);
++ &rgnDst, dx, dy, compat_qxl_copy_n_to_n, 0, NULL);
+
+ REGION_UNINIT (pScreen, &rgnDst);
+
+@@ -915,7 +915,7 @@ qxl_copy_window (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+ }
+
+ static int
+-qxl_create_gc (GCPtr pGC)
++compat_qxl_create_gc (GCPtr pGC)
+ {
+ static GCOps ops;
+ static int initialized;
+@@ -926,8 +926,8 @@ qxl_create_gc (GCPtr pGC)
+ if (!initialized)
+ {
+ ops = *pGC->ops;
+- ops.PolyFillRect = qxl_poly_fill_rect;
+- ops.CopyArea = qxl_copy_area;
++ ops.PolyFillRect = compat_qxl_poly_fill_rect;
++ ops.CopyArea = compat_qxl_copy_area;
+
+ initialized = TRUE;
+ }
+@@ -937,26 +937,26 @@ qxl_create_gc (GCPtr pGC)
+ }
+
+ static Bool
+-qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
++compat_qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
+- struct qxl_rom *rom;
+- struct qxl_ram_header *ram_header;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
++ struct compat_qxl_rom *rom;
++ struct compat_qxl_ram_header *ram_header;
+ VisualPtr visual;
+
+ CHECK_POINT();
+
+- qxl->pScrn = pScrn;
++ compat_qxl->pScrn = pScrn;
+
+- if (!qxl_map_memory(qxl, scrnIndex))
++ if (!compat_qxl_map_memory(compat_qxl, scrnIndex))
+ return FALSE;
+
+- rom = qxl->rom;
+- ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
++ rom = compat_qxl->rom;
++ ram_header = (void *)((unsigned long)compat_qxl->ram + (unsigned long)compat_qxl->rom->ram_header_offset);
+
+- qxl_save_state(pScrn);
+- qxl_blank_screen(pScreen, SCREEN_SAVER_ON);
++ compat_qxl_save_state(pScrn);
++ compat_qxl_blank_screen(pScreen, SCREEN_SAVER_ON);
+
+ miClearVisualTypes();
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
+@@ -968,14 +968,14 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+ /* Note we do this before setting pScrn->virtualY to match our current
+ mode, so as to allocate a buffer large enough for the largest mode.
+ FIXME: add support for resizing the framebuffer on modeset. */
+- qxl->fb = xcalloc(pScrn->virtualY * pScrn->displayWidth, 4);
+- if (!qxl->fb)
++ compat_qxl->fb = xcalloc(pScrn->virtualY * pScrn->displayWidth, 4);
++ if (!compat_qxl->fb)
+ goto out;
+
+ pScrn->virtualX = pScrn->currentMode->HDisplay;
+ pScrn->virtualY = pScrn->currentMode->VDisplay;
+
+- if (!fbScreenInit(pScreen, qxl->fb,
++ if (!fbScreenInit(pScreen, compat_qxl->fb,
+ pScrn->currentMode->HDisplay,
+ pScrn->currentMode->VDisplay,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+@@ -1001,59 +1001,59 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+
+ fbPictureInit(pScreen, 0, 0);
+
+- qxl->create_screen_resources = pScreen->CreateScreenResources;
+- pScreen->CreateScreenResources = qxl_create_screen_resources;
++ compat_qxl->create_screen_resources = pScreen->CreateScreenResources;
++ pScreen->CreateScreenResources = compat_qxl_create_screen_resources;
+
+ /* Set up resources */
+- qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->ram + (unsigned long)rom->pages_offset),
++ compat_qxl->mem = compat_qxl_mem_create ((void *)((unsigned long)compat_qxl->ram + (unsigned long)rom->pages_offset),
+ rom->num_io_pages * getpagesize());
+- qxl->io_pages = (void *)((unsigned long)qxl->ram + (unsigned long)rom->pages_offset);
+- qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical + (unsigned long)rom->pages_offset);
+-
+- qxl->command_ring = qxl_ring_create (&(ram_header->cmd_ring_hdr),
+- sizeof (struct qxl_command),
+- 32, qxl->io_base + QXL_IO_NOTIFY_CMD);
+- qxl->cursor_ring = qxl_ring_create (&(ram_header->cursor_ring_hdr),
+- sizeof (struct qxl_command),
+- 32, qxl->io_base + QXL_IO_NOTIFY_CURSOR);
+- qxl->release_ring = qxl_ring_create (&(ram_header->release_ring_hdr),
++ compat_qxl->io_pages = (void *)((unsigned long)compat_qxl->ram + (unsigned long)rom->pages_offset);
++ compat_qxl->io_pages_physical = (void *)((unsigned long)compat_qxl->ram_physical + (unsigned long)rom->pages_offset);
++
++ compat_qxl->command_ring = compat_qxl_ring_create (&(ram_header->cmd_ring_hdr),
++ sizeof (struct compat_qxl_command),
++ 32, compat_qxl->io_base + QXL_IO_NOTIFY_CMD);
++ compat_qxl->cursor_ring = compat_qxl_ring_create (&(ram_header->cursor_ring_hdr),
++ sizeof (struct compat_qxl_command),
++ 32, compat_qxl->io_base + QXL_IO_NOTIFY_CURSOR);
++ compat_qxl->release_ring = compat_qxl_ring_create (&(ram_header->release_ring_hdr),
+ sizeof (uint64_t),
+ 8, 0);
+
+ /* xf86DPMSInit(pScreen, xf86DPMSSet, 0); */
+
+ #if 0 /* XV accel */
+- qxlInitVideo(pScreen);
++ compat_qxlInitVideo(pScreen);
+ #endif
+
+- pScreen->SaveScreen = qxl_blank_screen;
+- qxl->close_screen = pScreen->CloseScreen;
+- pScreen->CloseScreen = qxl_close_screen;
++ pScreen->SaveScreen = compat_qxl_blank_screen;
++ compat_qxl->close_screen = pScreen->CloseScreen;
++ pScreen->CloseScreen = compat_qxl_close_screen;
+
+- qxl->create_gc = pScreen->CreateGC;
+- pScreen->CreateGC = qxl_create_gc;
++ compat_qxl->create_gc = pScreen->CreateGC;
++ pScreen->CreateGC = compat_qxl_create_gc;
+
+ #if 0
+- qxl->paint_window_background = pScreen->PaintWindowBackground;
+- qxl->paint_window_border = pScreen->PaintWindowBorder;
++ compat_qxl->paint_window_background = pScreen->PaintWindowBackground;
++ compat_qxl->paint_window_border = pScreen->PaintWindowBorder;
+ #endif
+- qxl->copy_window = pScreen->CopyWindow;
++ compat_qxl->copy_window = pScreen->CopyWindow;
+ #if 0
+- pScreen->PaintWindowBackground = qxl_paint_window;
+- pScreen->PaintWindowBorder = qxl_paint_window;
++ pScreen->PaintWindowBackground = compat_qxl_paint_window;
++ pScreen->PaintWindowBorder = compat_qxl_paint_window;
+ #endif
+- pScreen->CopyWindow = qxl_copy_window;
++ pScreen->CopyWindow = compat_qxl_copy_window;
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (!miCreateDefColormap(pScreen))
+ goto out;
+
+- qxl_cursor_init (pScreen);
++ compat_qxl_cursor_init (pScreen);
+
+ CHECK_POINT();
+
+- qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
++ compat_qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
+
+ CHECK_POINT();
+
+@@ -1064,26 +1064,26 @@ out:
+ }
+
+ static Bool
+-qxl_enter_vt(int scrnIndex, int flags)
++compat_qxl_enter_vt(int scrnIndex, int flags)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+- qxl_save_state(pScrn);
+- qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
++ compat_qxl_save_state(pScrn);
++ compat_qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
+
+ return TRUE;
+ }
+
+ static void
+-qxl_leave_vt(int scrnIndex, int flags)
++compat_qxl_leave_vt(int scrnIndex, int flags)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+- qxl_restore_state(pScrn);
++ compat_qxl_restore_state(pScrn);
+ }
+
+ static Bool
+-qxl_color_setup(ScrnInfoPtr pScrn)
++compat_qxl_color_setup(ScrnInfoPtr pScrn)
+ {
+ int scrnIndex = pScrn->scrnIndex;
+ Gamma gzeros = { 0.0, 0.0, 0.0 };
+@@ -1113,13 +1113,13 @@ qxl_color_setup(ScrnInfoPtr pScrn)
+ }
+
+ static void
+-print_modes (qxl_screen_t *qxl, int scrnIndex)
++print_modes (compat_qxl_screen_t *compat_qxl, int scrnIndex)
+ {
+ int i;
+
+- for (i = 0; i < qxl->num_modes; ++i)
++ for (i = 0; i < compat_qxl->num_modes; ++i)
+ {
+- struct qxl_mode *m = qxl->modes + i;
++ struct compat_qxl_mode *m = compat_qxl->modes + i;
+
+ xf86DrvMsg (scrnIndex, X_INFO,
+ "%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n",
+@@ -1129,11 +1129,11 @@ print_modes (qxl_screen_t *qxl, int scrnIndex)
+ }
+
+ static Bool
+-qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
++compat_qxl_check_device(ScrnInfoPtr pScrn, compat_qxl_screen_t *compat_qxl)
+ {
+ int scrnIndex = pScrn->scrnIndex;
+- struct qxl_rom *rom = qxl->rom;
+- struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
++ struct compat_qxl_rom *rom = compat_qxl->rom;
++ struct compat_qxl_ram_header *ram_header = (void *)((unsigned long)compat_qxl->ram + rom->ram_header_offset);
+
+ CHECK_POINT();
+
+@@ -1170,24 +1170,24 @@ qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
+ xf86DrvMsg(scrnIndex, X_INFO, "Correct RAM signature %x\n",
+ ram_header->magic);
+
+- qxl->draw_area_offset = rom->draw_area_offset;
+- qxl->draw_area_size = rom->draw_area_size;
++ compat_qxl->draw_area_offset = rom->draw_area_offset;
++ compat_qxl->draw_area_size = rom->draw_area_size;
+ pScrn->videoRam = rom->draw_area_size / 1024;
+
+ return TRUE;
+ }
+
+ static int
+-qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
++compat_qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
+ {
+ int i;
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+
+ CHECK_POINT();
+
+- for (i = 0; i < qxl->num_modes; i++)
++ for (i = 0; i < compat_qxl->num_modes; i++)
+ {
+- struct qxl_mode *m = qxl->modes + i;
++ struct compat_qxl_mode *m = compat_qxl->modes + i;
+
+ if (m->x_res == p->HDisplay &&
+ m->y_res == p->VDisplay &&
+@@ -1212,20 +1212,20 @@ qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
+ }
+
+ static ModeStatus
+-qxl_valid_mode(int scrn, DisplayModePtr p, Bool flag, int pass)
++compat_qxl_valid_mode(int scrn, DisplayModePtr p, Bool flag, int pass)
+ {
+ ScrnInfoPtr pScrn = xf86Screens[scrn];
+- qxl_screen_t *qxl = pScrn->driverPrivate;
++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate;
+ int bpp = pScrn->bitsPerPixel;
+ int mode_idx;
+
+ /* FIXME: I don't think this is necessary now that we report the
+ * correct amount of video ram?
+ */
+- if (p->HDisplay * p->VDisplay * (bpp/8) > qxl->draw_area_size)
++ if (p->HDisplay * p->VDisplay * (bpp/8) > compat_qxl->draw_area_size)
+ return MODE_MEM;
+
+- mode_idx = qxl_find_native_mode (pScrn, p);
++ mode_idx = compat_qxl_find_native_mode (pScrn, p);
+ if (mode_idx == -1)
+ return MODE_NOMODE;
+
+@@ -1234,7 +1234,7 @@ qxl_valid_mode(int scrn, DisplayModePtr p, Bool flag, int pass)
+ return MODE_OK;
+ }
+
+-static void qxl_add_mode(ScrnInfoPtr pScrn, int width, int height, int type)
++static void compat_qxl_add_mode(ScrnInfoPtr pScrn, int width, int height, int type)
+ {
+ DisplayModePtr mode;
+
+@@ -1263,10 +1263,10 @@ static void qxl_add_mode(ScrnInfoPtr pScrn, int width, int height, int type)
+ }
+
+ static Bool
+-qxl_pre_init(ScrnInfoPtr pScrn, int flags)
++compat_qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ {
+ int i, scrnIndex = pScrn->scrnIndex;
+- qxl_screen_t *qxl = NULL;
++ compat_qxl_screen_t *compat_qxl = NULL;
+ ClockRangePtr clockRanges = NULL;
+ int *linePitches = NULL;
+ DisplayModePtr mode;
+@@ -1281,27 +1281,27 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ }
+
+ if (!pScrn->driverPrivate)
+- pScrn->driverPrivate = xnfcalloc(sizeof(qxl_screen_t), 1);
+- qxl = pScrn->driverPrivate;
++ pScrn->driverPrivate = xnfcalloc(sizeof(compat_qxl_screen_t), 1);
++ compat_qxl = pScrn->driverPrivate;
+
+- qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
+- qxl->pci = xf86GetPciInfoForEntity(qxl->entity->index);
++ compat_qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
++ compat_qxl->pci = xf86GetPciInfoForEntity(compat_qxl->entity->index);
+ #ifndef XSERVER_LIBPCIACCESS
+- qxl->pci_tag = pciTag(qxl->pci->bus, qxl->pci->device, qxl->pci->func);
++ compat_qxl->pci_tag = pciTag(compat_qxl->pci->bus, compat_qxl->pci->device, compat_qxl->pci->func);
+ #endif
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+- if (!qxl_color_setup(pScrn))
++ if (!compat_qxl_color_setup(pScrn))
+ goto out;
+
+ /* option parsing and card differentiation */
+ xf86CollectOptions(pScrn, NULL);
+
+- if (!qxl_map_memory(qxl, scrnIndex))
++ if (!compat_qxl_map_memory(compat_qxl, scrnIndex))
+ goto out;
+
+- if (!qxl_check_device(pScrn, qxl))
++ if (!compat_qxl_check_device(pScrn, compat_qxl))
+ goto out;
+
+ /* ddc stuff here */
+@@ -1328,22 +1328,22 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ }
+
+ /* Add any modes not in xorg's default mode list */
+- for (i = 0; i < qxl->num_modes; i++)
+- if (qxl->modes[i].orientation == 0) {
+- qxl_add_mode(pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
++ for (i = 0; i < compat_qxl->num_modes; i++)
++ if (compat_qxl->modes[i].orientation == 0) {
++ compat_qxl_add_mode(pScrn, compat_qxl->modes[i].x_res, compat_qxl->modes[i].y_res,
+ M_T_DRIVER);
+- if (qxl->modes[i].x_res > max_x)
+- max_x = qxl->modes[i].x_res;
+- if (qxl->modes[i].y_res > max_y)
+- max_y = qxl->modes[i].y_res;
++ if (compat_qxl->modes[i].x_res > max_x)
++ max_x = compat_qxl->modes[i].x_res;
++ if (compat_qxl->modes[i].y_res > max_y)
++ max_y = compat_qxl->modes[i].y_res;
+ }
+
+ if (pScrn->display->virtualX == 0 && pScrn->display->virtualY == 0) {
+ /* It is possible for the largest x + largest y size combined leading
+ to a virtual size which will not fit into the framebuffer when this
+ happens we prefer max width and make height as large as possible */
+- if (max_x * max_y * (pScrn->bitsPerPixel / 8) > qxl->draw_area_size)
+- pScrn->display->virtualY = qxl->draw_area_size /
++ if (max_x * max_y * (pScrn->bitsPerPixel / 8) > compat_qxl->draw_area_size)
++ pScrn->display->virtualY = compat_qxl->draw_area_size /
+ (max_x * (pScrn->bitsPerPixel / 8));
+ else
+ pScrn->display->virtualY = max_y;
+@@ -1381,14 +1381,14 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ goto out;
+ }
+
+- print_modes (qxl, scrnIndex);
++ print_modes (compat_qxl, scrnIndex);
+
+ /* VGA hardware initialisation */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ /* hate */
+- qxl_unmap_memory(qxl, scrnIndex);
++ compat_qxl_unmap_memory(compat_qxl, scrnIndex);
+
+ CHECK_POINT();
+
+@@ -1398,19 +1398,19 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ out:
+ if (clockRanges)
+ xfree(clockRanges);
+- if (qxl)
+- xfree(qxl);
++ if (compat_qxl)
++ xfree(compat_qxl);
+
+ return FALSE;
+ }
+
+ #ifdef XSERVER_LIBPCIACCESS
+-enum qxl_class
++enum compat_qxl_class
+ {
+ CHIP_QXL_1,
+ };
+
+-static const struct pci_id_match qxl_device_match[] = {
++static const struct pci_id_match compat_qxl_device_match[] = {
+ {
+ PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_0100, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ 0x00030000, 0x00ffffff, CHIP_QXL_1
+@@ -1420,14 +1420,14 @@ static const struct pci_id_match qxl_device_match[] = {
+ };
+ #endif
+
+-static SymTabRec qxlChips[] =
++static SymTabRec compat_qxlChips[] =
+ {
+ { PCI_CHIP_QXL_0100, "QXL 1", },
+ { -1, NULL }
+ };
+
+ #ifndef XSERVER_LIBPCIACCESS
+-static PciChipsets qxlPciChips[] =
++static PciChipsets compat_qxlPciChips[] =
+ {
+ { PCI_CHIP_QXL_0100, PCI_CHIP_QXL_0100, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+@@ -1435,20 +1435,20 @@ static PciChipsets qxlPciChips[] =
+ #endif
+
+ static void
+-qxl_identify(int flags)
++compat_qxl_identify(int flags)
+ {
+- xf86PrintChipsets("qxl", "Driver for QXL virtual graphics", qxlChips);
++ xf86PrintChipsets("compat_qxl", "Driver for QXL virtual graphics", compat_qxlChips);
+ }
+
+-static void
+-qxl_init_scrn(ScrnInfoPtr pScrn)
++void
++compat_init_scrn(ScrnInfoPtr pScrn)
+ {
+ pScrn->driverVersion = 0;
+- pScrn->driverName = pScrn->name = "qxl";
+- pScrn->PreInit = qxl_pre_init;
+- pScrn->ScreenInit = qxl_screen_init;
+- pScrn->SwitchMode = qxl_switch_mode;
+- pScrn->ValidMode = qxl_valid_mode;
+- pScrn->EnterVT = qxl_enter_vt;
+- pScrn->LeaveVT = qxl_leave_vt;
++ pScrn->driverName = pScrn->name = "compat_qxl";
++ pScrn->PreInit = compat_qxl_pre_init;
++ pScrn->ScreenInit = compat_qxl_screen_init;
++ pScrn->SwitchMode = compat_qxl_switch_mode;
++ pScrn->ValidMode = compat_qxl_valid_mode;
++ pScrn->EnterVT = compat_qxl_enter_vt;
++ pScrn->LeaveVT = compat_qxl_leave_vt;
+ }
+diff --git a/src/compat/compat-qxl_image.c b/src/compat/compat-qxl_image.c
+index d2ac12d..2307138 100644
+--- a/src/compat/compat-qxl_image.c
++++ b/src/compat/compat-qxl_image.c
+@@ -8,7 +8,7 @@ typedef struct image_info_t image_info_t;
+
+ struct image_info_t
+ {
+- struct qxl_image *image;
++ struct compat_qxl_image *image;
+ int ref_count;
+ image_info_t *next;
+ };
+@@ -33,7 +33,7 @@ hash_and_copy (const uint8_t *src, int src_stride,
+ if (dest)
+ memcpy (dest_line, src_line, n_bytes);
+
+- hash = hashlittle (src_line, n_bytes, hash);
++ hash = compat_hashlittle (src_line, n_bytes, hash);
+ }
+
+ return hash;
+@@ -48,7 +48,7 @@ lookup_image_info (unsigned int hash,
+
+ while (info)
+ {
+- struct qxl_image *image = info->image;
++ struct compat_qxl_image *image = info->image;
+
+ if (image->descriptor.id == hash &&
+ image->descriptor.width == width &&
+@@ -95,17 +95,17 @@ remove_image_info (image_info_t *info)
+ free (info);
+ }
+
+-struct qxl_image *
+-qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
++struct compat_qxl_image *
++compat_qxl_image_create (compat_qxl_screen_t *compat_qxl, const uint8_t *data,
+ int x, int y, int width, int height,
+ int stride)
+ {
+ unsigned int hash;
+ image_info_t *info;
+
+- data += y * stride + x * qxl->bytes_per_pixel;
++ data += y * stride + x * compat_qxl->bytes_per_pixel;
+
+- hash = hash_and_copy (data, stride, NULL, -1, qxl->bytes_per_pixel, width, height);
++ hash = hash_and_copy (data, stride, NULL, -1, compat_qxl->bytes_per_pixel, width, height);
+
+ info = lookup_image_info (hash, width, height);
+ if (info)
+@@ -120,11 +120,11 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+
+ for (i = 0; i < height; ++i)
+ {
+- struct qxl_data_chunk *chunk;
++ struct compat_qxl_data_chunk *chunk;
+ const uint8_t *src_line = data + i * stride;
+ uint32_t *dest_line;
+
+- chunk = virtual_address (qxl, u64_to_pointer (info->image->u.bitmap.data));
++ chunk = virtual_address (compat_qxl, u64_to_pointer (info->image->u.bitmap.data));
+
+ dest_line = (uint32_t *)chunk->data + width * i;
+
+@@ -147,9 +147,9 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ }
+ else
+ {
+- struct qxl_image *image;
+- struct qxl_data_chunk *chunk;
+- int dest_stride = width * qxl->bytes_per_pixel;
++ struct compat_qxl_image *image;
++ struct compat_qxl_data_chunk *chunk;
++ int dest_stride = width * compat_qxl->bytes_per_pixel;
+ image_info_t *info;
+
+ #if 0
+@@ -159,7 +159,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ /* Chunk */
+
+ /* FIXME: Check integer overflow */
+- chunk = qxl_allocnf (qxl, sizeof *chunk + height * dest_stride);
++ chunk = compat_qxl_allocnf (compat_qxl, sizeof *chunk + height * dest_stride);
+
+ chunk->data_size = height * dest_stride;
+ chunk->prev_chunk = 0;
+@@ -167,10 +167,10 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+
+ hash_and_copy (data, stride,
+ chunk->data, dest_stride,
+- qxl->bytes_per_pixel, width, height);
++ compat_qxl->bytes_per_pixel, width, height);
+
+ /* Image */
+- image = qxl_allocnf (qxl, sizeof *image);
++ image = compat_qxl_allocnf (compat_qxl, sizeof *image);
+
+ image->descriptor.id = 0;
+ image->descriptor.type = QXL_IMAGE_TYPE_BITMAP;
+@@ -179,7 +179,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ image->descriptor.width = width;
+ image->descriptor.height = height;
+
+- if (qxl->bytes_per_pixel == 2)
++ if (compat_qxl->bytes_per_pixel == 2)
+ {
+ image->u.bitmap.format = QXL_BITMAP_FMT_16BIT;
+ }
+@@ -191,9 +191,9 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
+ image->u.bitmap.x = width;
+ image->u.bitmap.y = height;
+- image->u.bitmap.stride = width * qxl->bytes_per_pixel;
++ image->u.bitmap.stride = width * compat_qxl->bytes_per_pixel;
+ image->u.bitmap.palette = 0;
+- image->u.bitmap.data = physical_address (qxl, chunk);
++ image->u.bitmap.data = physical_address (compat_qxl, chunk);
+
+ #if 0
+ ErrorF ("%p has size %d %d\n", image, width, height);
+@@ -218,13 +218,13 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
+ }
+
+ void
+-qxl_image_destroy (qxl_screen_t *qxl,
+- struct qxl_image *image)
++compat_qxl_image_destroy (compat_qxl_screen_t *compat_qxl,
++ struct compat_qxl_image *image)
+ {
+- struct qxl_data_chunk *chunk;
++ struct compat_qxl_data_chunk *chunk;
+ image_info_t *info;
+
+- chunk = virtual_address (qxl, u64_to_pointer (image->u.bitmap.data));
++ chunk = virtual_address (compat_qxl, u64_to_pointer (image->u.bitmap.data));
+
+ info = lookup_image_info (image->descriptor.id,
+ image->descriptor.width,
+@@ -244,12 +244,12 @@ qxl_image_destroy (qxl_screen_t *qxl,
+ remove_image_info (info);
+ }
+
+- qxl_free (qxl->mem, chunk);
+- qxl_free (qxl->mem, image);
++ compat_qxl_free (compat_qxl->mem, chunk);
++ compat_qxl_free (compat_qxl->mem, image);
+ }
+
+ void
+-qxl_drop_image_cache (qxl_screen_t *qxl)
++compat_qxl_drop_image_cache (compat_qxl_screen_t *compat_qxl)
+ {
+ memset (image_table, 0, HASH_SIZE * sizeof (image_info_t *));
+ }
+diff --git a/src/compat/compat-qxl_mem.c b/src/compat/compat-qxl_mem.c
+index 2f6fa6a..26e85f9 100644
+--- a/src/compat/compat-qxl_mem.c
++++ b/src/compat/compat-qxl_mem.c
+@@ -22,7 +22,7 @@ struct block
+ } u;
+ };
+
+-struct qxl_mem
++struct compat_qxl_mem
+ {
+ void * base;
+ unsigned long n_bytes;
+@@ -35,7 +35,7 @@ struct qxl_mem
+ };
+
+ static void
+-initialize (struct qxl_mem *mem)
++initialize (struct compat_qxl_mem *mem)
+ {
+ mem->unused = (struct block *)mem->base;
+ mem->unused->n_bytes = mem->n_bytes;
+@@ -47,10 +47,10 @@ initialize (struct qxl_mem *mem)
+ mem->n_freed_blocks = 0;
+ }
+
+-struct qxl_mem *
+-qxl_mem_create (void *base, unsigned long n_bytes)
++struct compat_qxl_mem *
++compat_qxl_mem_create (void *base, unsigned long n_bytes)
+ {
+- struct qxl_mem *mem = NULL;
++ struct compat_qxl_mem *mem = NULL;
+
+ mem = calloc (sizeof (*mem), 1);
+ if (!mem)
+@@ -66,13 +66,13 @@ out:
+ }
+
+ void
+-qxl_mem_free_all (struct qxl_mem *mem)
++compat_qxl_mem_free_all (struct compat_qxl_mem *mem)
+ {
+ initialize (mem);
+ }
+
+ void
+-qxl_mem_dump_stats (struct qxl_mem *mem, const char *header)
++compat_qxl_mem_dump_stats (struct compat_qxl_mem *mem, const char *header)
+ {
+ struct block *b;
+ int n_blocks;
+@@ -122,7 +122,7 @@ qxl_mem_dump_stats (struct qxl_mem *mem, const char *header)
+ }
+
+ void *
+-qxl_alloc (struct qxl_mem *mem, unsigned long n_bytes)
++compat_qxl_alloc (struct compat_qxl_mem *mem, unsigned long n_bytes)
+ {
+ struct block *b, *prev;
+
+@@ -202,7 +202,7 @@ qxl_alloc (struct qxl_mem *mem, unsigned long n_bytes)
+ /* If we get here, we are out of memory, so print some stats */
+ #if 0
+ fprintf (stderr, "Failing to allocate %lu bytes\n", n_bytes);
+- qxl_mem_dump_stats (mem, "out of memory");
++ compat_qxl_mem_dump_stats (mem, "out of memory");
+ #endif
+
+ return NULL;
+@@ -213,7 +213,7 @@ qxl_alloc (struct qxl_mem *mem, unsigned long n_bytes)
+ * last unused block.
+ */
+ static void
+-find_neighbours (struct qxl_mem *mem, void *data,
++find_neighbours (struct compat_qxl_mem *mem, void *data,
+ struct block **before, struct block **after)
+ {
+ struct block *b;
+@@ -237,7 +237,7 @@ find_neighbours (struct qxl_mem *mem, void *data,
+ }
+
+ void
+-qxl_free (struct qxl_mem *mem, void *d)
++compat_qxl_free (struct compat_qxl_mem *mem, void *d)
+ {
+ struct block *b = d - sizeof (unsigned long);
+ struct block *before, *after;
+@@ -248,7 +248,7 @@ qxl_free (struct qxl_mem *mem, void *d)
+ #if 0
+ printf ("freeing %p (%d bytes)\n", b, b->n_bytes);
+
+- qxl_mem_dump_stats (mem, "before free");
++ compat_qxl_mem_dump_stats (mem, "before free");
+ #endif
+
+ find_neighbours (mem, (void *)b, &before, &after);
+@@ -316,6 +316,6 @@ qxl_free (struct qxl_mem *mem, void *d)
+ }
+
+ #if 0
+- qxl_mem_dump_stats (mem, "after free");
++ compat_qxl_mem_dump_stats (mem, "after free");
+ #endif
+ }
+diff --git a/src/compat/compat-qxl_ring.c b/src/compat/compat-qxl_ring.c
+index 9a34583..d875357 100644
+--- a/src/compat/compat-qxl_ring.c
++++ b/src/compat/compat-qxl_ring.c
+@@ -5,11 +5,11 @@
+
+ struct ring
+ {
+- struct qxl_ring_header header;
++ struct compat_qxl_ring_header header;
+ uint8_t elements[0];
+ };
+
+-struct qxl_ring
++struct compat_qxl_ring
+ {
+ volatile struct ring *ring;
+ int element_size;
+@@ -17,13 +17,13 @@ struct qxl_ring
+ int prod_notify;
+ };
+
+-struct qxl_ring *
+-qxl_ring_create (struct qxl_ring_header *header,
++struct compat_qxl_ring *
++compat_qxl_ring_create (struct compat_qxl_ring_header *header,
+ int element_size,
+ int n_elements,
+ int prod_notify)
+ {
+- struct qxl_ring *ring;
++ struct compat_qxl_ring *ring;
+
+ ring = malloc (sizeof *ring);
+ if (!ring)
+@@ -38,10 +38,10 @@ qxl_ring_create (struct qxl_ring_header *header,
+ }
+
+ void
+-qxl_ring_push (struct qxl_ring *ring,
++compat_qxl_ring_push (struct compat_qxl_ring *ring,
+ const void *new_elt)
+ {
+- volatile struct qxl_ring_header *header = &(ring->ring->header);
++ volatile struct compat_qxl_ring_header *header = &(ring->ring->header);
+ volatile uint8_t *elt;
+ int idx;
+
+@@ -66,10 +66,10 @@ qxl_ring_push (struct qxl_ring *ring,
+ }
+
+ Bool
+-qxl_ring_pop (struct qxl_ring *ring,
++compat_qxl_ring_pop (struct compat_qxl_ring *ring,
+ void *element)
+ {
+- volatile struct qxl_ring_header *header = &(ring->ring->header);
++ volatile struct compat_qxl_ring_header *header = &(ring->ring->header);
+ volatile uint8_t *ring_elt;
+ int idx;
+
+@@ -87,7 +87,7 @@ qxl_ring_pop (struct qxl_ring *ring,
+ }
+
+ void
+-qxl_ring_wait_idle (struct qxl_ring *ring)
++compat_qxl_ring_wait_idle (struct compat_qxl_ring *ring)
+ {
+ while (ring->ring->header.cons != ring->ring->header.prod)
+ {
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index b8f2812..670c7e6 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -1435,8 +1435,15 @@ qxl_pci_probe(DriverPtr drv, int entity, struct pci_device *dev, intptr_t match)
+ pScrn->driverPrivate = xnfcalloc(sizeof(qxl_screen_t), 1);
+ qxl = pScrn->driverPrivate;
+ qxl->pci = dev;
+-
+- qxl_init_scrn(pScrn);
++
++ if (qxl->pci->revision == 0x01)
++ {
++ compat_init_scrn (pScrn);
++ }
++ else
++ {
++ qxl_init_scrn(pScrn);
++ }
+
+ return TRUE;
+ }
+--
+1.7.4.4
+
diff --git a/0013-If-qxl_pre_init-is-called-without-a-confScreen-just-.patch b/0013-If-qxl_pre_init-is-called-without-a-confScreen-just-.patch
new file mode 100644
index 0000000..ef92bd9
--- /dev/null
+++ b/0013-If-qxl_pre_init-is-called-without-a-confScreen-just-.patch
@@ -0,0 +1,31 @@
+From 9ac8dd49e8633601f44dcf1b854ade97c481698c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
+Date: Sat, 19 Mar 2011 12:47:52 -0400
+Subject: [PATCH 13/13] If qxl_pre_init() is called without a confScreen, just
+ return FALSE.
+
+Otherwise, the driver crashes when called from Xorg -configure.
+---
+ src/qxl_driver.c | 6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/src/qxl_driver.c b/src/qxl_driver.c
+index 670c7e6..fc6d2a2 100644
+--- a/src/qxl_driver.c
++++ b/src/qxl_driver.c
+@@ -1189,6 +1189,12 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
+ int *linePitches = NULL;
+ DisplayModePtr mode;
+ unsigned int max_x = 0, max_y = 0;
++
++ /* In X server 1.7.5, Xorg -configure will cause this
++ * function to get called without a confScreen.
++ */
++ if (!pScrn->confScreen)
++ return FALSE;
+
+ CHECK_POINT();
+
+--
+1.7.4.4
+
diff --git a/sources b/sources
index 481fdfd..7fd7a13 100644
--- a/sources
+++ b/sources
@@ -1,3 +1 @@
-ebe8fcf4d62bff7964c0c8b2f18bbc11 xf86-video-qxl-0.0.20.f14b.tar.bz2
-1c649e4672b1c860d0ae8b0a004f771d xf86-video-qxl-0.0.13.tar.gz
c1f177a26ed32f48f68158bf92439ede xf86-video-qxl-0.0.13.tar.bz2
diff --git a/xorg-x11-drv-qxl.spec b/xorg-x11-drv-qxl.spec
index 5e739f6..7687eff 100644
--- a/xorg-x11-drv-qxl.spec
+++ b/xorg-x11-drv-qxl.spec
@@ -10,9 +10,23 @@ Name: xorg-x11-drv-qxl
Version: 0.0.21
%define tarversion 0.0.13
-Release: 2%{?dist}
+Release: 3%{?dist}
URL: http://www.x.org
Source0: http://xorg.freedesktop.org/releases/individual/driver/%{tarball}-%{tarversion}.tar.bz2
+# Patches from upstream git, bugfixes + support for old qxl device
+Patch1: 0001-gcc-4.6.0-fix-cast-unmatching-function-pointers.patch
+Patch2: 0002-qxl_driver-remove-unused-variable-found-by-gcc-4.6.0.patch
+Patch3: 0003-build-add-spice-protocol-dep.patch
+Patch4: 0004-use-spice-protocol-qxl_dev.h-enums.patch
+Patch5: 0005-use-structs-from-spice-protocol-qxl_dev.h.patch
+Patch6: 0006-s-qxl_ram_header-QXLRam.patch
+Patch7: 0007-Don-t-re-upload-read-only-surfaces-after-a-software-.patch
+Patch8: 0008-Tiled-upload-of-images-after-software-fallback.patch
+Patch9: 0009-Generate-tighter-damage-for-PolyFillRect.patch
+Patch10: 0010-Fix-VT-switching.patch
+Patch11: 0011-Add-old-driver-in-as-a-compatibility-layer.patch
+Patch12: 0012-Link-in-the-compat-driver-various-renamings.patch
+Patch13: 0013-If-qxl_pre_init-is-called-without-a-confScreen-just-.patch
License: MIT
Group: User Interface/X Hardware Support
@@ -20,7 +34,9 @@ ExcludeArch: s390 s390x
BuildRequires: pkgconfig
BuildRequires: xorg-x11-server-devel >= 1.1.0-1
+BuildRequires: spice-protocol >= 0.8.0
BuildRequires: glib2-devel
+BuildRequires: libtool
Requires: Xorg %(xserver-sdk-abi-requires ansic)
Requires: Xorg %(xserver-sdk-abi-requires videodrv)
@@ -30,6 +46,20 @@ X.Org X11 qxl video driver.
%prep
%setup -q -n %{tarball}-%{tarversion}
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+autoreconf -f -i
%build
%configure --disable-static
@@ -53,6 +83,11 @@ rm -rf $RPM_BUILD_ROOT
%{driverdir}/qxl_drv.so
%changelog
+* Wed Apr 20 2011 Hans de Goede <hdegoede at redhat.com> 0.0.21-3
+- Add various bugfixes from upstream git
+- Fixes VT-switching (rhbz#696711)
+- Add support for old qxl device (from rhel6 branch) (rhbz#642153)
+
* Mon Mar 07 2011 Dave Airlie <airlied at redhat.com> 0.0.21-2
- Bump to for abi rebuild
More information about the scm-commits
mailing list