From 28add0c08d2497d2484c72f8d7c368dd0dd8506e Mon Sep 17 00:00:00 2001 From: CentOS Buildsys Date: Nov 08 2013 05:09:52 +0000 Subject: import xorg-x11-drv-qxl-0.1.1-5.el7.src.rpm --- diff --git a/.xorg-x11-drv-qxl.metadata b/.xorg-x11-drv-qxl.metadata new file mode 100644 index 0000000..96ba2e2 --- /dev/null +++ b/.xorg-x11-drv-qxl.metadata @@ -0,0 +1 @@ +6ec6b58369ffed4e112f7697d884e50df28fe3a2 SOURCES/xf86-video-qxl-0.1.1.tar.bz2 diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0002-Add-old-driver-in-as-a-compatibility-layer.patch b/SOURCES/0002-Add-old-driver-in-as-a-compatibility-layer.patch new file mode 100644 index 0000000..64930bb --- /dev/null +++ b/SOURCES/0002-Add-old-driver-in-as-a-compatibility-layer.patch @@ -0,0 +1,3828 @@ +diff -up xf86-video-qxl-20130514/configure.ac.compat xf86-video-qxl-20130514/configure.ac +--- xf86-video-qxl-20130514/configure.ac.compat 2013-07-03 14:18:40.381914397 +1000 ++++ xf86-video-qxl-20130514/configure.ac 2013-07-03 14:18:57.093319209 +1000 +@@ -155,6 +155,7 @@ AC_CONFIG_FILES([ + Makefile + src/Makefile + src/uxa/Makefile ++ src/compat/Makefile + scripts/Makefile + examples/Makefile + ]) +diff -up xf86-video-qxl-20130514/src/compat/compat-lookup3.c.compat xf86-video-qxl-20130514/src/compat/compat-lookup3.c +--- xf86-video-qxl-20130514/src/compat/compat-lookup3.c.compat 2013-07-03 14:18:57.094319233 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-lookup3.c 2013-07-03 14:18:57.094319233 +1000 +@@ -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 /* defines printf for tests */ ++#include /* defines time_t for timings in the test */ ++#include "compat-lookup3.h" ++#ifdef linux ++# include /* 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 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 -up xf86-video-qxl-20130514/src/compat/compat-lookup3.h.compat xf86-video-qxl-20130514/src/compat/compat-lookup3.h +--- xf86-video-qxl-20130514/src/compat/compat-lookup3.h.compat 2013-07-03 14:18:57.094319233 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-lookup3.h 2013-07-03 14:18:57.094319233 +1000 +@@ -0,0 +1,26 @@ ++#ifndef __LOOKUP3_H ++#define __LOOKUP3_H ++ ++#if defined(__GNUC__) || defined(__sun) ++ ++#include ++ ++#else ++ ++#ifdef QXLDD ++#include ++#include "os_dep.h" ++#else ++#include ++#include ++#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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_cursor.c.compat xf86-video-qxl-20130514/src/compat/compat-qxl_cursor.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_cursor.c.compat 2013-07-03 14:18:57.094319233 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_cursor.c 2013-07-03 14:18:57.094319233 +1000 +@@ -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 ++#include "compat-qxl.h" ++#include ++ ++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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c.compat xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c.compat 2013-07-03 14:18:57.095319258 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c 2013-07-03 14:18:57.095319258 +1000 +@@ -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 ++ * ++ * This is qxl, a driver for the Qumranet paravirtualized graphics device ++ * in qemu. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#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 -up xf86-video-qxl-20130514/src/compat/compat-qxl.h.compat xf86-video-qxl-20130514/src/compat/compat-qxl.h +--- xf86-video-qxl-20130514/src/compat/compat-qxl.h.compat 2013-07-03 14:18:57.094319233 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl.h 2013-07-03 14:18:57.094319233 +1000 +@@ -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 ++ ++#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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_image.c.compat xf86-video-qxl-20130514/src/compat/compat-qxl_image.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_image.c.compat 2013-07-03 14:18:57.096319282 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_image.c 2013-07-03 14:18:57.096319282 +1000 +@@ -0,0 +1,255 @@ ++#include ++#include ++#include ++#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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c.compat xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c.compat 2013-07-03 14:18:57.096319282 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c 2013-07-03 14:18:57.096319282 +1000 +@@ -0,0 +1,321 @@ ++#include ++#include ++#include ++ ++#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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c.compat xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c.compat 2013-07-03 14:18:57.096319282 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c 2013-07-03 14:18:57.096319282 +1000 +@@ -0,0 +1,97 @@ ++#include ++#include ++#include ++#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(); ++ } ++} +diff -up xf86-video-qxl-20130514/src/compat/Makefile.am.compat xf86-video-qxl-20130514/src/compat/Makefile.am +--- xf86-video-qxl-20130514/src/compat/Makefile.am.compat 2013-07-03 14:18:57.093319209 +1000 ++++ xf86-video-qxl-20130514/src/compat/Makefile.am 2013-07-03 14:18:57.093319209 +1000 +@@ -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 -up xf86-video-qxl-20130514/src/Makefile.am.compat xf86-video-qxl-20130514/src/Makefile.am +--- xf86-video-qxl-20130514/src/Makefile.am.compat 2013-07-03 14:18:40.381914397 +1000 ++++ xf86-video-qxl-20130514/src/Makefile.am 2013-07-03 14:18:57.093319209 +1000 +@@ -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) $(DRM_CFLAGS) @LIBUDEV_CFLAGS@ + diff --git a/SOURCES/0003-Link-in-the-compat-driver-various-renamings.patch b/SOURCES/0003-Link-in-the-compat-driver-various-renamings.patch new file mode 100644 index 0000000..ab16375 --- /dev/null +++ b/SOURCES/0003-Link-in-the-compat-driver-various-renamings.patch @@ -0,0 +1,2674 @@ +diff -up xf86-video-qxl-20130514/src/compat/compat-lookup3.c.compat2 xf86-video-qxl-20130514/src/compat/compat-lookup3.c +--- xf86-video-qxl-20130514/src/compat/compat-lookup3.c.compat2 2013-07-03 14:19:39.007334520 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-lookup3.c 2013-07-03 14:19:56.102748510 +1000 +@@ -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, exac + 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: + + /* + ------------------------------------------------------------------------------- +-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 + 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 + + 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, + } + #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, Curs + } + + 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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c.compat2 xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c.compat2 2013-07-03 14:19:39.009334569 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_driver.c 2013-07-03 14:19:56.103748552 +1000 +@@ -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 + * +- * 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 + 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 + } + + 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]; +- +- 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])); ++ 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]; ++ ++ 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])); ++ ++ 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, DisplayMo + 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, DisplayMo + 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, DisplayMo + } + + 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 + * 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_ + 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 s + 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 st + 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 st + 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 st + 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, Region + } + + 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, + * 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 + } + + 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 pDrawabl + + 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 pDrawabl + } + + 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 pSrcDraw + { + 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 pSrcDraw + 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 pSrcDraw + * 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 pSrcDraw + /* 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 pSrcDraw + } + + 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, + + 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, + } + + 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 pDraw + + 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 pDraw + } + + 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, DDXPoin + + 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, DDXPoin + } + + 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 + /* 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 + + 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); ++ 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); + +- 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->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 scrn + } + + 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_ + 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, + } + + 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 + 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 pSc + } + + 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 flag + } + + 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 flag + } + + /* 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 flag + 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 flag + 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_dev + }; + #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 -up xf86-video-qxl-20130514/src/compat/compat-qxl.h.compat2 xf86-video-qxl-20130514/src/compat/compat-qxl.h +--- xf86-video-qxl-20130514/src/compat/compat-qxl.h.compat2 2013-07-03 14:19:39.009334569 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl.h 2013-07-03 14:19:56.102748510 +1000 +@@ -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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_image.c.compat2 xf86-video-qxl-20130514/src/compat/compat-qxl_image.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_image.c.compat2 2013-07-03 14:19:39.010334593 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_image.c 2013-07-03 14:19:56.103748552 +1000 +@@ -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 s + 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, con + + 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, con + } + 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, con + /* 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, con + + 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, con + 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, con + 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, con + } + + 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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c.compat2 xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c.compat2 2013-07-03 14:19:39.010334593 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_mem.c 2013-07-03 14:19:56.104748592 +1000 +@@ -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, + } + + 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 + /* 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 + * 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, vo + } + + 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 -up xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c.compat2 xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c +--- xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c.compat2 2013-07-03 14:19:39.010334593 +1000 ++++ xf86-video-qxl-20130514/src/compat/compat-qxl_ring.c 2013-07-03 14:19:56.104748592 +1000 +@@ -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 + } + + 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 -up xf86-video-qxl-20130514/src/compat/Makefile.am.compat2 xf86-video-qxl-20130514/src/compat/Makefile.am +--- xf86-video-qxl-20130514/src/compat/Makefile.am.compat2 2013-07-03 14:19:39.010334593 +1000 ++++ xf86-video-qxl-20130514/src/compat/Makefile.am 2013-07-03 14:19:56.102748510 +1000 +@@ -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 -up xf86-video-qxl-20130514/src/Makefile.am.compat2 xf86-video-qxl-20130514/src/Makefile.am +--- xf86-video-qxl-20130514/src/Makefile.am.compat2 2013-07-03 14:19:56.102748510 +1000 ++++ xf86-video-qxl-20130514/src/Makefile.am 2013-07-03 14:20:10.365094118 +1000 +@@ -34,7 +34,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 + if LIBUDEV + qxl_drv_la_LIBADD += $(LIBUDEV_LIBS) + endif +diff -up xf86-video-qxl-20130514/src/qxl_driver.c.compat2 xf86-video-qxl-20130514/src/qxl_driver.c +--- xf86-video-qxl-20130514/src/qxl_driver.c.compat2 2013-05-14 11:13:00.000000000 +1000 ++++ xf86-video-qxl-20130514/src/qxl_driver.c 2013-07-03 14:19:56.104748592 +1000 +@@ -1365,7 +1365,11 @@ qxl_pci_probe (DriverPtr drv, int entity + qxl = pScrn->driverPrivate; + qxl->pci = dev; + +- qxl_init_scrn (pScrn, kms); ++ if (!kms && qxl->pci->revision == 0x01) ++ { ++ compat_init_scrn (pScrn); ++ } else ++ qxl_init_scrn (pScrn, kms); + + return TRUE; + } diff --git a/SOURCES/0004-compat-bump-to-new-server-API-changes.patch b/SOURCES/0004-compat-bump-to-new-server-API-changes.patch new file mode 100644 index 0000000..f177769 --- /dev/null +++ b/SOURCES/0004-compat-bump-to-new-server-API-changes.patch @@ -0,0 +1,191 @@ +From de69b14deb4109dce884cf88d0a13ba294562822 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 19 Jul 2012 06:53:59 +1000 +Subject: [PATCH 4/4] compat: bump to new server API changes + +--- + src/compat/compat-qxl.h | 1 + + src/compat/compat-qxl_driver.c | 51 +++++++++++++++++++++--------------------- + 2 files changed, 27 insertions(+), 25 deletions(-) + +diff --git a/src/compat/compat-qxl.h b/src/compat/compat-qxl.h +index 2c61699..eed3a2f 100644 +--- a/src/compat/compat-qxl.h ++++ b/src/compat/compat-qxl.h +@@ -41,6 +41,7 @@ + #include "fb.h" + #include "vgaHW.h" + ++#include "../compat-api.h" + #define hidden _X_HIDDEN + + #define QXL_NAME "compat_qxl" +diff --git a/src/compat/compat-qxl_driver.c b/src/compat/compat-qxl_driver.c +index 758ee24..0047382 100644 +--- a/src/compat/compat-qxl_driver.c ++++ b/src/compat/compat-qxl_driver.c +@@ -260,14 +260,14 @@ compat_qxl_restore_state(ScrnInfoPtr pScrn) + } + + static Bool +-compat_qxl_close_screen(int scrnIndex, ScreenPtr pScreen) ++compat_qxl_close_screen(CLOSE_SCREEN_ARGS_DECL) + { +- ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + + if (pScrn->vtSema) { + compat_qxl_restore_state(pScrn); +- compat_qxl_unmap_memory(compat_qxl, scrnIndex); ++ compat_qxl_unmap_memory(compat_qxl, pScrn->scrnIndex); + } + pScrn->vtSema = FALSE; + +@@ -276,14 +276,15 @@ compat_qxl_close_screen(int scrnIndex, ScreenPtr pScreen) + pScreen->CreateScreenResources = compat_qxl->create_screen_resources; + pScreen->CloseScreen = compat_qxl->close_screen; + +- return pScreen->CloseScreen(scrnIndex, pScreen); ++ return pScreen->CloseScreen(CLOSE_SCREEN_ARGS); + } + + static Bool +-compat_qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags) ++compat_qxl_switch_mode(SWITCH_MODE_ARGS_DECL) + { +- compat_qxl_screen_t *compat_qxl = xf86Screens[scrnIndex]->driverPrivate; +- int mode_index = (int)(unsigned long)p->Private; ++ SCRN_INFO_PTR(arg); ++ compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; ++ int mode_index = (int)(unsigned long)mode->Private; + struct compat_qxl_mode *m = compat_qxl->modes + mode_index; + ScreenPtr pScreen = compat_qxl->pScrn->pScreen; + +@@ -291,8 +292,8 @@ compat_qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags) + 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); ++ xf86DrvMsg (pScrn->scrnIndex, X_INFO, "Setting mode %d (%d x %d) (%d x %d) %p\n", ++ m->id, m->x_res, m->y_res, mode->HDisplay, mode->VDisplay, mode); + + outb(compat_qxl->io_base + QXL_IO_RESET, 0); + +@@ -571,7 +572,7 @@ compat_qxl_sanity_check (compat_qxl_screen_t *compat_qxl) + if (compat_qxl->rom->mode == ~0) + { + ErrorF("QXL device jumped back to VGA mode - resetting mode\n"); +- compat_qxl_switch_mode(compat_qxl->pScrn->scrnIndex, compat_qxl->pScrn->currentMode, 0); ++ compat_qxl_switch_mode(SWITCH_MODE_ARGS(compat_qxl->pScrn, compat_qxl->pScrn->currentMode)); + } + } + +@@ -638,7 +639,7 @@ compat_qxl_on_damage (DamagePtr pDamage, RegionPtr pRegion, pointer closure) + static Bool + compat_qxl_create_screen_resources(ScreenPtr pScreen) + { +- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + Bool ret; + PixmapPtr pPixmap; +@@ -691,7 +692,7 @@ compat_qxl_poly_fill_rect (DrawablePtr pDrawable, + int nrect, + xRectangle *prect) + { +- ScrnInfoPtr pScrn = xf86Screens[pDrawable->pScreen->myNum]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pDrawable->pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + PixmapPtr pPixmap; + int xoff, yoff; +@@ -746,7 +747,7 @@ compat_qxl_copy_n_to_n (DrawablePtr pSrcDrawable, + void *closure) + { + ScreenPtr pScreen = pSrcDrawable->pScreen; +- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + int src_xoff, src_yoff; + int dst_xoff, dst_yoff; +@@ -859,7 +860,7 @@ static void + compat_qxl_fill_region_solid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel) + { + ScreenPtr pScreen = pDrawable->pScreen; +- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + PixmapPtr pPixmap; + int xoff, yoff; +@@ -937,9 +938,9 @@ compat_qxl_create_gc (GCPtr pGC) + } + + static Bool +-compat_qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ++compat_qxl_screen_init(SCREEN_INIT_ARGS_DECL) + { +- ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ++ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + struct compat_qxl_rom *rom; + struct compat_qxl_ram_header *ram_header; +@@ -949,7 +950,7 @@ compat_qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) + + compat_qxl->pScrn = pScrn; + +- if (!compat_qxl_map_memory(compat_qxl, scrnIndex)) ++ if (!compat_qxl_map_memory(compat_qxl, pScrn->scrnIndex)) + return FALSE; + + rom = compat_qxl->rom; +@@ -1053,7 +1054,7 @@ compat_qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) + + CHECK_POINT(); + +- compat_qxl_switch_mode(scrnIndex, pScrn->currentMode, 0); ++ compat_qxl_switch_mode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); + + CHECK_POINT(); + +@@ -1064,20 +1065,20 @@ out: + } + + static Bool +-compat_qxl_enter_vt(int scrnIndex, int flags) ++compat_qxl_enter_vt(VT_FUNC_ARGS_DECL) + { +- ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ++ SCRN_INFO_PTR(arg); + + compat_qxl_save_state(pScrn); +- compat_qxl_switch_mode(scrnIndex, pScrn->currentMode, 0); ++ compat_qxl_switch_mode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); + + return TRUE; + } + + static void +-compat_qxl_leave_vt(int scrnIndex, int flags) ++compat_qxl_leave_vt(VT_FUNC_ARGS_DECL) + { +- ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ++ SCRN_INFO_PTR(arg); + + compat_qxl_restore_state(pScrn); + } +@@ -1212,9 +1213,9 @@ compat_qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p) + } + + static ModeStatus +-compat_qxl_valid_mode(int scrn, DisplayModePtr p, Bool flag, int pass) ++compat_qxl_valid_mode(SCRN_ARG_TYPE arg, DisplayModePtr p, Bool flag, int pass) + { +- ScrnInfoPtr pScrn = xf86Screens[scrn]; ++ SCRN_INFO_PTR(arg); + compat_qxl_screen_t *compat_qxl = pScrn->driverPrivate; + int bpp = pScrn->bitsPerPixel; + int mode_idx; +-- +1.8.2.1 + diff --git a/SOURCES/0005-spiceqxl_display-only-use-qxl-interface-after-it-is-.patch b/SOURCES/0005-spiceqxl_display-only-use-qxl-interface-after-it-is-.patch new file mode 100644 index 0000000..e8f797b --- /dev/null +++ b/SOURCES/0005-spiceqxl_display-only-use-qxl-interface-after-it-is-.patch @@ -0,0 +1,36 @@ +From c3dd01524bfbd2554fff219112bd8a312b4d8f9e Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 14:08:18 +0300 +Subject: [PATCH] spiceqxl_display: only use qxl interface after it is added - + spice server + +before 1d18b7e98ab268c755933061d77ccc7a981815e2 we get a segfault from +using the st->dispatcher before it is set since during the attach_worker +callback st->dispatcher is still not set. +--- + src/spiceqxl_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/spiceqxl_display.c b/src/spiceqxl_display.c +index a3a8978..066b1a1 100644 +--- a/src/spiceqxl_display.c ++++ b/src/spiceqxl_display.c +@@ -95,7 +95,6 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker) + return; + } + dprint(qxl, 1, "%s:\n", __FUNCTION__); +- spice_qxl_add_memslot(sin, &slot); + qxl->worker = qxl_worker; + } + +@@ -346,6 +345,7 @@ void qxl_add_spice_display_interface(qxl_screen_t *qxl) + qxl->display_sin.id = 0; + qxl->display_sin.st = (struct QXLState*)qxl; + spice_server_add_interface(qxl->spice_server, &qxl->display_sin.base); ++ spice_qxl_add_memslot(&qxl->display_sin.base, &slot); + } + + void spiceqxl_display_monitors_config(qxl_screen_t *qxl) +-- +1.8.3.1 + diff --git a/SOURCES/0006-spiceqxl_spice_server-no-need-to-call-spice_server_s.patch b/SOURCES/0006-spiceqxl_spice_server-no-need-to-call-spice_server_s.patch new file mode 100644 index 0000000..7e5c017 --- /dev/null +++ b/SOURCES/0006-spiceqxl_spice_server-no-need-to-call-spice_server_s.patch @@ -0,0 +1,27 @@ +From 5f23159d86e94d599301581f25a6e13fe3a050b9 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 11:57:43 +0300 +Subject: [PATCH 06/10] spiceqxl_spice_server: no need to call + spice_server_set_noauth twice + +--- + src/spiceqxl_spice_server.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/spiceqxl_spice_server.c b/src/spiceqxl_spice_server.c +index 63a3179..14ee752 100644 +--- a/src/spiceqxl_spice_server.c ++++ b/src/spiceqxl_spice_server.c +@@ -254,9 +254,6 @@ void xspice_set_spice_server_options(OptionInfoPtr options) + exit(1); + #endif + } +- if (disable_ticketing) { +- spice_server_set_noauth(spice_server); +- } + + #if SPICE_SERVER_VERSION >= 0x000801 + /* we still don't actually support agent in xspice, but this +-- +1.8.3.1 + diff --git a/SOURCES/0007-xspice-chown-both-files-used-by-vdagent-for-suid-Xor.patch b/SOURCES/0007-xspice-chown-both-files-used-by-vdagent-for-suid-Xor.patch new file mode 100644 index 0000000..388f03b --- /dev/null +++ b/SOURCES/0007-xspice-chown-both-files-used-by-vdagent-for-suid-Xor.patch @@ -0,0 +1,176 @@ +From e1b4022a0d2c598e5d5dead8d770f5e7d0de5a0c Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 18:22:15 +0300 +Subject: [PATCH 07/10] xspice: chown both files used by vdagent for suid Xorg + case + +When running a suid Xorg mkfifo and bind produce files owned by root. +Change the ownership so that the user launched vdagent & vdagentd can +write to them. This also makes it easier to cleanup the files from the +Xspice process that is not running as root (and is launching both +vdagent & vdagentd, hence they are not running as root either). + +The patch adds two new parameters, uid and gid of the agent used files, +namely the virtio unix domain socket and the uinput fifo. +--- + scripts/Xspice | 5 ++++- + src/Makefile.am | 2 ++ + src/qxl.h | 2 ++ + src/qxl_driver.c | 4 ++++ + src/spiceqxl_uinput.c | 2 ++ + src/spiceqxl_util.c | 22 ++++++++++++++++++++++ + src/spiceqxl_util.h | 8 ++++++++ + src/spiceqxl_vdagent.c | 2 ++ + 8 files changed, 46 insertions(+), 1 deletion(-) + create mode 100644 src/spiceqxl_util.c + create mode 100644 src/spiceqxl_util.h + +diff --git a/scripts/Xspice b/scripts/Xspice +index 17439a1..34a5fcc 100755 +--- a/scripts/Xspice ++++ b/scripts/Xspice +@@ -91,6 +91,8 @@ parser.add_argument('--vdagent-uinput-path', default='/tmp/xspice-uinput', help= + parser.add_argument('--vdagentd-exec', default='spice-vdagentd') + parser.add_argument('--vdagent-exec', default='spice-vdagent') + parser.add_argument('--vdagent-no-launch', default=True, action='store_false', dest='vdagent_launch') ++parser.add_argument('--vdagent-uid', default=str(os.getuid())) ++parser.add_argument('--vdagent-gid', default=str(os.getgid())) + parser.add_argument('--audio-fifo-dir', default='') + + #TODO +@@ -231,7 +233,8 @@ var_args = ['port', 'tls_port', 'disable_ticketing', + 'tls_ciphers', 'dh_file', 'password', 'image_compression', + 'jpeg_wan_compression', 'zlib_glz_wan_compression', + 'streaming_video', 'deferred_fps', 'exit_on_disconnect', +- 'vdagent_enabled', 'vdagent_virtio_path', 'vdagent_uinput_path'] ++ 'vdagent_enabled', 'vdagent_virtio_path', 'vdagent_uinput_path', ++ 'vdagent_uid', 'vdagent_gid'] + + for arg in var_args: + if getattr(args, arg): +diff --git a/src/Makefile.am b/src/Makefile.am +index 4c4ae40..bf50ae1 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -79,6 +79,8 @@ spiceqxl_drv_la_SOURCES = \ + qxl.h \ + qxl_option_helpers.c \ + qxl_option_helpers.h \ ++ spiceqxl_util.h \ ++ spiceqxl_util.c \ + spiceqxl_spice_server.c \ + spiceqxl_spice_server.h \ + spiceqxl_io_port.c \ +diff --git a/src/qxl.h b/src/qxl.h +index c699c58..a44875b 100644 +--- a/src/qxl.h ++++ b/src/qxl.h +@@ -147,6 +147,8 @@ enum { + OPTION_SPICE_VDAGENT_ENABLED, + OPTION_SPICE_VDAGENT_VIRTIO_PATH, + OPTION_SPICE_VDAGENT_UINPUT_PATH, ++ OPTION_SPICE_VDAGENT_UID, ++ OPTION_SPICE_VDAGENT_GID, + #endif + OPTION_COUNT, + }; +diff --git a/src/qxl_driver.c b/src/qxl_driver.c +index 91ba6c2..29b1551 100644 +--- a/src/qxl_driver.c ++++ b/src/qxl_driver.c +@@ -142,6 +142,10 @@ const OptionInfoRec DefaultOptions[] = + "SpiceVdagentVirtioPath", OPTV_STRING, {.str = spice_vdagent_virtio_path_default}, FALSE}, + { OPTION_SPICE_VDAGENT_UINPUT_PATH, + "SpiceVdagentUinputPath", OPTV_STRING, {.str = spice_vdagent_uinput_path_default}, FALSE}, ++ { OPTION_SPICE_VDAGENT_UID, ++ "SpiceVdagentUid", OPTV_INTEGER, {0}, FALSE}, ++ { OPTION_SPICE_VDAGENT_GID, ++ "SpiceVdagentGid", OPTV_INTEGER, {0}, FALSE}, + #endif + + { -1, NULL, OPTV_NONE, {0}, FALSE } +diff --git a/src/spiceqxl_uinput.c b/src/spiceqxl_uinput.c +index 443f931..1e61907 100644 +--- a/src/spiceqxl_uinput.c ++++ b/src/spiceqxl_uinput.c +@@ -13,6 +13,7 @@ + #include + + #include "qxl_option_helpers.h" ++#include "spiceqxl_util.h" + #include "spiceqxl_inputs.h" + + #include "spiceqxl_uinput.h" +@@ -113,6 +114,7 @@ void spiceqxl_uinput_init(qxl_screen_t *qxl) + uinput_filename, strerror(errno)); + return; + } ++ spiceqxl_chown_agent_file(qxl, uinput_filename); + uinput_fd = open(uinput_filename, O_RDONLY | O_NONBLOCK, 0666); + if (uinput_fd == -1) { + fprintf(stderr, "spice: failed creating uinput file %s: %s\n", +diff --git a/src/spiceqxl_util.c b/src/spiceqxl_util.c +new file mode 100644 +index 0000000..49cd5ab +--- /dev/null ++++ b/src/spiceqxl_util.c +@@ -0,0 +1,22 @@ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "qxl_option_helpers.h" ++#include "spiceqxl_util.h" ++ ++void spiceqxl_chown_agent_file(qxl_screen_t *qxl, const char *filename) ++{ ++ int uid, gid; ++ ++ uid = get_int_option(qxl->options, OPTION_SPICE_VDAGENT_UID, "XSPICE_VDAGENT_UID"); ++ gid = get_int_option(qxl->options, OPTION_SPICE_VDAGENT_GID, "XSPICE_VDAGENT_GID"); ++ if (uid && gid) { ++ if (chown(filename, uid, gid) != 0) { ++ fprintf(stderr, "spice: failed to chain ownership of '%s' to %d/%d: %s\n", ++ filename, uid, gid, strerror(errno)); ++ } ++ } ++} +diff --git a/src/spiceqxl_util.h b/src/spiceqxl_util.h +new file mode 100644 +index 0000000..4726bc1 +--- /dev/null ++++ b/src/spiceqxl_util.h +@@ -0,0 +1,8 @@ ++#ifndef SPICEQXL_UTIL_H ++#define SPICEQXL_UTIL_H ++ ++#include "qxl.h" ++ ++void spiceqxl_chown_agent_file(qxl_screen_t *qxl, const char *filename); ++ ++#endif +diff --git a/src/spiceqxl_vdagent.c b/src/spiceqxl_vdagent.c +index fdeddd3..ba04cb8 100644 +--- a/src/spiceqxl_vdagent.c ++++ b/src/spiceqxl_vdagent.c +@@ -10,6 +10,7 @@ + + #include "qxl_option_helpers.h" + ++#include "spiceqxl_util.h" + #include "spiceqxl_uinput.h" + #include "spiceqxl_vdagent.h" + +@@ -156,6 +157,7 @@ void spiceqxl_vdagent_init(qxl_screen_t *qxl) + vdagent_virtio_filename, strerror(errno)); + return; + } ++ spiceqxl_chown_agent_file(qxl, vdagent_virtio_filename); + c = listen(virtio_fd, 1); + if (c != 0) { + fprintf(stderr, "error listening to unix domain socket: %s\n", strerror(errno)); +-- +1.8.3.1 + diff --git a/SOURCES/0008-Xspice-cleanup-non-regular-files-too.patch b/SOURCES/0008-Xspice-cleanup-non-regular-files-too.patch new file mode 100644 index 0000000..6062dc5 --- /dev/null +++ b/SOURCES/0008-Xspice-cleanup-non-regular-files-too.patch @@ -0,0 +1,25 @@ +From a778d9da649b16098ab3721f135bd7508bc32167 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 18:25:47 +0300 +Subject: [PATCH 08/10] Xspice: cleanup non regular files too + +--- + scripts/Xspice | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Xspice b/scripts/Xspice +index 34a5fcc..be87c08 100755 +--- a/scripts/Xspice ++++ b/scripts/Xspice +@@ -159,7 +159,7 @@ cleanup_processes = [] + + def cleanup(*args): + for f in cleanup_files: +- if os.path.isfile(f): ++ if os.path.exists(f): + os.remove(f) + for p in cleanup_processes: + p.kill() +-- +1.8.3.1 + diff --git a/SOURCES/0009-Xspice-fix-cleanup-when-some-processes-are-already-d.patch b/SOURCES/0009-Xspice-fix-cleanup-when-some-processes-are-already-d.patch new file mode 100644 index 0000000..6908d5c --- /dev/null +++ b/SOURCES/0009-Xspice-fix-cleanup-when-some-processes-are-already-d.patch @@ -0,0 +1,35 @@ +From eb437149e26c995aac780dc8bb67ea41275d0429 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 18:26:02 +0300 +Subject: [PATCH 09/10] Xspice: fix cleanup when some processes are already + dead + +--- + scripts/Xspice | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/scripts/Xspice b/scripts/Xspice +index be87c08..9b82bfe 100755 +--- a/scripts/Xspice ++++ b/scripts/Xspice +@@ -162,9 +162,15 @@ def cleanup(*args): + if os.path.exists(f): + os.remove(f) + for p in cleanup_processes: +- p.kill() ++ try: ++ p.kill() ++ except OSError: ++ pass + for p in cleanup_processes: +- p.wait() ++ try: ++ p.wait() ++ except OSError: ++ pass + del cleanup_processes[:] + + def launch(*args, **kw): +-- +1.8.3.1 + diff --git a/SOURCES/0010-Xspice-cleanup-vdagent-files.patch b/SOURCES/0010-Xspice-cleanup-vdagent-files.patch new file mode 100644 index 0000000..42603f4 --- /dev/null +++ b/SOURCES/0010-Xspice-cleanup-vdagent-files.patch @@ -0,0 +1,24 @@ +From c1b698baf3a5d653854c69a12f2d3cb76991b406 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Mon, 21 Oct 2013 18:26:12 +0300 +Subject: [PATCH 10/10] Xspice: cleanup vdagent files + +--- + scripts/Xspice | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/scripts/Xspice b/scripts/Xspice +index 9b82bfe..b1528f9 100755 +--- a/scripts/Xspice ++++ b/scripts/Xspice +@@ -278,6 +278,7 @@ if args.vdagent_enabled: + for f in [vdagentd_uds, args.vdagent_virtio_path, args.vdagent_uinput_path]: + if os.path.exists(f): + os.unlink(f) ++ cleanup_files.extend([args.vdagent_virtio_path, args.vdagent_uinput_path]) + xorg = launch(executable=args.xorg, args=exec_args + xorg_args) + time.sleep(2) + +-- +1.8.3.1 + diff --git a/SOURCES/no-surfaces-kms.patch b/SOURCES/no-surfaces-kms.patch new file mode 100644 index 0000000..21c53ab --- /dev/null +++ b/SOURCES/no-surfaces-kms.patch @@ -0,0 +1,12 @@ +diff -up xf86-video-qxl-0.1.1/src/qxl_uxa.c.dma xf86-video-qxl-0.1.1/src/qxl_uxa.c +--- xf86-video-qxl-0.1.1/src/qxl_uxa.c.dma 2013-11-08 13:37:49.898702515 +1000 ++++ xf86-video-qxl-0.1.1/src/qxl_uxa.c 2013-11-08 13:38:10.185702515 +1000 +@@ -422,6 +422,8 @@ qxl_create_pixmap (ScreenPtr screen, int + ErrorF ("Create pixmap: %d %d @ %d (usage: %d)\n", w, h, depth, usage); + #endif + ++ if (qxl->kms_enabled) ++ goto fallback; + if (uxa_swapped_out (screen)) + goto fallback; + diff --git a/SOURCES/qxl-kms-disable-composite.patch b/SOURCES/qxl-kms-disable-composite.patch new file mode 100644 index 0000000..aa1a83f --- /dev/null +++ b/SOURCES/qxl-kms-disable-composite.patch @@ -0,0 +1,37 @@ +diff -up xf86-video-qxl-20130514/src/qxl_kms.c.da xf86-video-qxl-20130514/src/qxl_kms.c +diff -up xf86-video-qxl-20130514/src/qxl_uxa.c.da xf86-video-qxl-20130514/src/qxl_uxa.c +--- xf86-video-qxl-20130514/src/qxl_uxa.c.da 2013-06-18 10:08:56.113709355 +1000 ++++ xf86-video-qxl-20130514/src/qxl_uxa.c 2013-06-18 10:10:08.775610941 +1000 +@@ -222,11 +222,15 @@ qxl_has_composite (qxl_screen_t *qxl) + #ifdef XF86DRM_MODE + if (qxl->kms_enabled) { + static Bool result, checked; ++#if 0 /* KMS Composite support seems broken - needs better hw support */ + if (!checked) { + result = qxl_kms_check_cap(qxl, SPICE_DISPLAY_CAP_COMPOSITE); + checked = TRUE; + } + return result; ++#else ++ return FALSE; ++#endif + } + #endif + #ifndef XSPICE +@@ -244,12 +248,16 @@ qxl_has_a8_surfaces (qxl_screen_t *qxl) + { + #ifdef XF86DRM_MODE + if (qxl->kms_enabled) { ++#if 0 /* KMS Composite support seems broken - needs better hw support */ + static Bool result, checked; + if (!checked) { + result = qxl_kms_check_cap(qxl, SPICE_DISPLAY_CAP_A8_SURFACE); + checked = TRUE; + } + return result; ++#else ++ return FALSE; ++#endif + } + #endif + #ifndef XSPICE diff --git a/SPECS/xorg-x11-drv-qxl.spec b/SPECS/xorg-x11-drv-qxl.spec new file mode 100644 index 0000000..ef9eb92 --- /dev/null +++ b/SPECS/xorg-x11-drv-qxl.spec @@ -0,0 +1,344 @@ +%global tarball xf86-video-qxl +%global moduledir %(pkg-config xorg-server --variable=moduledir ) +%global driverdir %{moduledir}/drivers + +# Xspice is x86_64 only since spice-server is x86_64 only +%ifarch x86_64 +%define with_xspice (0%{?fedora} || 0%{?rhel} > 6) +%else +%define with_xspice 0 +%endif + +#% global gitdate 20130703 +%global gitversion 8b03ec16 + +%if 0%{?gitdate} + +%define gver .%{gitdate}git%{gitversion} +%endif + +Summary: Xorg X11 qxl video driver +Name: xorg-x11-drv-qxl + +Version: 0.1.1 + +Release: 5%{?gver}%{?dist} +URL: http://www.x.org +Source0: http://xorg.freedesktop.org/releases/individual/driver/%{tarball}-%{version}.tar.bz2 + +#Source0: %{tarball}-%{gitdate}.tar.bz2 +Patch1: qxl-kms-disable-composite.patch + +# This should go away with a spice server containing 1d18b7e98ab268c755933061d77ccc7a981815e2 +Patch2: 0005-spiceqxl_display-only-use-qxl-interface-after-it-is-.patch + +# Avoid oops in the kernel +Patch3: no-surfaces-kms.patch + +# Fixes for running with Xorg suid, which is the only way we ship in fedora +Patch6: 0006-spiceqxl_spice_server-no-need-to-call-spice_server_s.patch +Patch7: 0007-xspice-chown-both-files-used-by-vdagent-for-suid-Xor.patch +Patch8: 0008-Xspice-cleanup-non-regular-files-too.patch +Patch9: 0009-Xspice-fix-cleanup-when-some-processes-are-already-d.patch +Patch10: 0010-Xspice-cleanup-vdagent-files.patch + +# Support for old revision 1 qxl device (which won't go upstream) +# These aren't currently being applied, because they're not compatible with +# xserver 1.15. They could be if someone wanted, but it's been 2.5 years, +# probably nobody's running that old of a RHEV anymore... +Patch20: 0002-Add-old-driver-in-as-a-compatibility-layer.patch +Patch21: 0003-Link-in-the-compat-driver-various-renamings.patch +Patch22: 0004-compat-bump-to-new-server-API-changes.patch + +License: MIT +Group: User Interface/X Hardware Support + +ExcludeArch: s390 s390x + +BuildRequires: pkgconfig +BuildRequires: xorg-x11-server-devel >= 1.1.0-1 +BuildRequires: spice-protocol >= 0.12.1 +BuildRequires: libdrm-devel >= 2.4.46-1 + +%ifarch x86_64 +BuildRequires: spice-server-devel >= 0.8.0 +%endif +BuildRequires: glib2-devel +BuildRequires: libtool +BuildRequires: libudev-devel + +Requires: Xorg %(xserver-sdk-abi-requires ansic) +Requires: Xorg %(xserver-sdk-abi-requires videodrv) + +%description +X.Org X11 qxl video driver. + +%if %{with_xspice} +%package -n xorg-x11-server-Xspice +Summary: XSpice is an X server that can be accessed by a Spice client +Requires: Xorg %(xserver-sdk-abi-requires ansic) +Requires: Xorg %(xserver-sdk-abi-requires videodrv) +Requires: xorg-x11-server-Xorg +Requires: python >= 2.6 + +%description -n xorg-x11-server-Xspice +XSpice is both an X and a Spice server. +%endif + +%prep +%setup -q -n %{tarball}-%{?gitdate:%{gitdate}}%{!?gitdate:%{version}} + +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 + +%build +autoreconf -f -i +%if %{with_xspice} +%define enable_xspice --enable-xspice +%endif +%configure --disable-static %{?enable_xspice} +make %{?_smp_mflags} + + +%install +make install DESTDIR=$RPM_BUILD_ROOT INSTALL='install -p' + +# FIXME: Remove all libtool archives (*.la) from modules directory. This +# should be fixed in upstream Makefile.am or whatever. +find $RPM_BUILD_ROOT -regex ".*\.la$" | xargs rm -f -- + +%ifarch x86_64 +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/X11 +install -p -m 644 examples/spiceqxl.xorg.conf.example \ + $RPM_BUILD_ROOT%{_sysconfdir}/X11/spiceqxl.xorg.conf +# FIXME: upstream installs this file by default, we install it elsewhere. +# upstream should just not install it and let dist package deal with +# doc/examples. +rm -f $RPM_BUILD_ROOT/usr/share/doc/xf86-video-qxl/spiceqxl.xorg.conf.example +%if !%{with_xspice} +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/X11/spiceqxl.xorg.conf +%endif +%endif + + +%files +%defattr(-,root,root,-) +%doc COPYING README +%{driverdir}/qxl_drv.so + +%if %{with_xspice} +%files -n xorg-x11-server-Xspice +%defattr(-,root,root,-) +%doc COPYING README.xspice README examples/spiceqxl.xorg.conf.example +%config(noreplace) %{_sysconfdir}/X11/spiceqxl.xorg.conf +%{_bindir}/Xspice +%{driverdir}/spiceqxl_drv.so +%endif + + +%changelog +* Fri Nov 08 2013 Dave Airlie 0.1.1-5 +- avoid kernel oops problem (#1028273) + +* Wed Nov 06 2013 Adam Jackson - 0.1.1-4 +- 1.15RC1 ABI rebuild + +* Fri Oct 25 2013 Adam Jackson - 0.1.1-3 +- ABI rebuild + +* Thu Oct 24 2013 Adam Jackson 0.1.1-2 +- Drop qxl rev 1 patches + +* Mon Oct 21 2013 Alon Levy - 0.1.1-1 +- New upstream release +- Fixes to said release to work with suid issues (upstream) + +* Sun Aug 04 2013 Fedora Release Engineering - 0.1.1-0.14.20130514git77a1594 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 03 2013 Dave Airlie 0.1.1-0.13 +- resnapshot upstream to pick up a few patches +- add userspace patch to use new kernel hotspot interface (#974662) + +* Wed Jul 03 2013 Dave Airlie 0.1.1-0.12 +- add support for udev event catching - for dynamic resize from kernel + +* Tue Jul 02 2013 Dave Airlie 0.1.1-0.11 +- helps if you apply the patch (#978612) + +* Sat Jun 29 2013 Dave Airlie 0.1.1-0.10 +- fix another resize issue due (#978612) + +* Tue Jun 18 2013 Dave Airlie 0.1.1-0.9 +- disable composite/a8 surfaces for KMS (#974198) + +* Tue May 28 2013 Dave Airlie 0.1.1-0.8 +- fix 32-bit (#965101) + +* Tue May 14 2013 Dave Airlie 0.1.1-0.7 +- resnapshot - fixes randr under KMS + +* Sat May 14 2013 Daniel Mach - 0.1.1-0.6 +- Fix with_xspice macro definition (airlied - cherrypick) + +* Tue May 7 2013 Alon Levy 0.1.1-0.5 +- Add Xspice fixes and dfps (upstream a474a71..77a1594) + +* Tue Mar 19 2013 Adam Jackson 0.1.1-0.4 +- Less RHEL customization + +* Tue Mar 12 2013 Dave Airlie 0.1.1-0.3.20130312gita474a71 +- add KMS support to userspace driver + +* Thu Mar 07 2013 Peter Hutterer - 0.1.1-0.2.20130306git9d45cc5 +- ABI rebuild + +* Wed Mar 06 2013 Dave Airlie 0.1.1-0.1 +- bump to get UMS bo abstraction in - kms coming soon + +* Fri Feb 15 2013 Peter Hutterer - 0.1.0-4 +- ABI rebuild + +* Fri Feb 15 2013 Peter Hutterer - 0.1.0-3 +- ABI rebuild + +* Thu Jan 10 2013 Adam Jackson - 0.1.0-2 +- ABI rebuild + +* Sat Sep 22 2012 Soren Sandmann 0.1.0-1 +- Upstream 0.1.0 + +* Wed Aug 29 2012 Adam Jackson 0.0.22-6 +- Exclude Xspice from RHEL6 builds + +* Thu Aug 26 2012 Alon Levy +- fix uxa_xorg_enable_disable_fb_access - 0.0.22-5.20120718gitde6620788 (#844463) + +* Thu Aug 23 2012 Alon Levy +- fix break from introduction of screen privates - 0.0.22-4.20120718gitde6620788 (#844463) + +* Sun Jul 22 2012 Fedora Release Engineering - 0.0.22-3.20120718gitde6620788 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 18 2012 Dave Airlie 0.0.22-2.20120718gitde6620788 +- git snapshot for new server API + +* Thu Apr 05 2012 Adam Jackson - 0.0.22-1 +- RHEL arch exclude updates + +* Thu Mar 15 2012 Soren Sandmann - 0.22.0 +- Upstream 0.0.17 + +* Sat Feb 11 2012 Peter Hutterer - 0.0.21-16 +- ABI rebuild + +* Fri Feb 10 2012 Peter Hutterer - 0.0.21-15 +- ABI rebuild + +* Tue Jan 24 2012 Peter Hutterer - 0.0.21-14 +- ABI rebuild + +* Fri Jan 13 2012 Marc-AndrĂ© Lureau 0.0.21-13 +- Add 0011-support-_ASYNC-io-calls-and-interrupt-handling-busy-.patch + to use async calls + +* Wed Jan 04 2012 Adam Jackson 0.0.21-12 +- qxl-0.0.16-ftbfs.patch: Fix some FTBFS. + +* Wed Nov 16 2011 Adam Jackson 0.0.21-11 +- qxl-0.0.16-vgahw.patch: API compat for xserver 1.12 (#753928) + +* Mon Nov 14 2011 Adam Jackson - 0.0.21-10 +- ABI rebuild + +* Wed Nov 09 2011 Adam Jackson - 0.0.21-9 +- ABI rebuild + +* Wed Oct 28 2011 Soren Sandmann - 0.0.21-8 +- Bump release + +* Wed Oct 28 2011 Soren Sandmann - 0.0.21-7 +- Add patch to translate access regions according to drawable offset + Bug 731245. + +* Thu Oct 27 2011 Fedora Release Engineering - 0.0.21-7 +- Rebuilt for glibc bug#747377 + +* Wed Oct 26 2011 Soren Sandmann - 0.0.21-6 +- Add patch to confine access regions to the bounds of the drawable. + Bug 731245. + +* Mon Sep 12 2011 Hans de Goede - 0.0.21-5 +- Rebase to latest upstream release +- Enable building of the Xspice X-server and put it in its own + xorg-x11-server-Xspice package + +* Thu Aug 18 2011 Adam Jackson - 0.0.21-4 +- Rebuild for xserver 1.11 ABI + +* Wed Apr 20 2011 Hans de Goede 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 0.0.21-2 +- Bump to for abi rebuild + +* Sat Feb 12 2011 Soren Sandmann 0.0.21-1 +- New version number to make sure upgrading works + +* Tue Feb 08 2011 Fedora Release Engineering - 0.0.13-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jan 26 2011 Soren Sandmann 0.0.13-1 +- Update to 0.0.13 with surfaces + +* Mon Dec 06 2010 Adam Jackson 0.0.20.f14b-10 +- Rebuild for new server ABI. + +* Wed Oct 27 2010 Adam Jackson 0.0.20.f14b-8 +- Add ABI requires magic (#542742) + +* Sun Oct 17 2010 Hans de Goede 0.0.20.f14b-7 +- Fix notification bubbles under gnome not showing (backport from the + surface-fixes branch) + +* Sun Oct 17 2010 Hans de Goede 0.0.20.f14b-6 +- Fix a pointer casting bug which causes the qxl driver to trigger an + assertion in the qxl device terminating the entire virtual machine + +* Mon Oct 11 2010 Hans de Goede 0.0.20.f14b-5 +- Don't access the qxl device when our vt is not focussed, this fixes + Xorg crashing when switching to a text vc + +* Sun Oct 10 2010 Hans de Goede 0.0.20.f14b-4 +- Fix the driver not working on qxl devices with a framebuffer of 8MB + +* Sat Oct 9 2010 Hans de Goede 0.0.20.f14b-3 +- Add support for using resolutions > 1024x768 without needing an xorg.conf +- Restore textmode font when switching back to a textmode virtual console + +* Fri Oct 08 2010 Jesse Keating - 0.0.20.f14b-2.1 +- Rebuild for gcc bug 634757 + +* Tue Sep 14 2010 Soren Sandmann 0.0.20.f14b-2 +- Patch to fix it up for the new privates ABI (I had apparently been + testing with a too old X server). + +* Tue Sep 14 2010 Soren Sandmann 0.0.20.f14b-1 +- Add support for new device + +* Sat Mar 13 2010 Dave Airlie 0.0.12-2 +- fix bug in qxl with asserts + +* Sat Mar 13 2010 Dave Airlie 0.0.12-1 +- rebase to 0.0.12 release - fix some 16-bit bugs + +* Mon Jan 11 2010 Dave Airlie 0.0.9-0.1 +- Initial public release 0.0.9