From a39c245900acc7c589ed58404f14753f8bbf08a1 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Feb 25 2009 20:37:02 +0000 Subject: xserver 1.6.0 --- diff --git a/.cvsignore b/.cvsignore index 551b5a4..d453f72 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -xorg-server-1.5.99.903.tar.bz2 +xorg-server-1.6.0.tar.bz2 diff --git a/commitid b/commitid deleted file mode 100644 index 1d2c07c..0000000 --- a/commitid +++ /dev/null @@ -1 +0,0 @@ -02c059ea99a791b9e3643b4fb131af01306b1c23 diff --git a/find-provides b/find-provides new file mode 100755 index 0000000..297b5d0 --- /dev/null +++ b/find-provides @@ -0,0 +1,15 @@ +#!/bin/sh +# +# Extract ABI versions from the .pc file. Filter out xserver modules. +# +# Copyright 2009 Red Hat, Inc. +# License: MIT + +abis=`grep ^abi "$1" | tr '_=.' '-- '` +echo $abis | while read major minor; do + echo "xserver($major) = $minor" +done + +shift + +# exec "$@" | grep -v '\.so$' diff --git a/import.log b/import.log index 937b4f7..be8df06 100644 --- a/import.log +++ b/import.log @@ -2,3 +2,4 @@ xorg-x11-server-1_5_0-1_fc10:HEAD:xorg-x11-server-1.5.0-1.fc10.src.rpm:122048521 xorg-x11-server-1_5_1-1_fc10:HEAD:xorg-x11-server-1.5.1-1.fc10.src.rpm:1222198557 xorg-x11-server-1_5_2-1_fc10:HEAD:xorg-x11-server-1.5.2-1.fc10.src.rpm:1223667007 xorg-x11-server-1_5_3-1_fc10:HEAD:xorg-x11-server-1.5.3-1.fc10.src.rpm:1225918317 +xorg-x11-server-1_6_0-1_fc11:HEAD:xorg-x11-server-1.6.0-1.fc11.src.rpm:1235594175 diff --git a/make-git-snapshot.sh b/make-git-snapshot.sh deleted file mode 100755 index d56bf4f..0000000 --- a/make-git-snapshot.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -DIRNAME=xorg-server-$( date +%Y%m%d ) - -rm -rf $DIRNAME -git clone git://git.freedesktop.org/git/xorg/xserver $DIRNAME -cd $DIRNAME -if [ -z "$1" ]; then - git log | head -1 -else - git checkout $1 -fi -git log | head -1 | awk '{ print $2 }' > ../commitid -git repack -a -d -git-config user.email "x@fedoraproject.org" -git-config user.name "Fedora X Ninjas" -cd .. -tar jcf $DIRNAME.tar.bz2 $DIRNAME -rm -rf $DIRNAME diff --git a/sources b/sources index 96706b8..0ce3d96 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -c80db7b363ea9303243c58e77c464df0 xorg-server-1.5.99.903.tar.bz2 +aafe73f5807ce8bb534727ecb72467c7 xorg-server-1.6.0.tar.bz2 diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 5fad5af..6a65ae6 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -18,8 +18,8 @@ Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.5.99.903 -Release: 3%{?dist} +Version: 1.6.0 +Release: 1%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -45,11 +45,11 @@ Source20: http://svn.exactcode.de/t2/trunk/package/xorg/xorg-server/xvfb-run.sh # ABI version provides. # XXX don't enable any of this yet. for serious. -#Source30: find-provides -#{expand:%%define prev__find_provides %{__find_provides}} -#define pc_path %{buildroot}/%{_libdir}/pkgconfig/xorg-server.pc +Source30: find-provides +%{expand:%%define prev__find_provides %{__find_provides}} +%define pc_path %{buildroot}/%{_libdir}/pkgconfig/xorg-server.pc #define __find_provides %{SOURCE30} %{pc_path} %{prev__find_provides} -#define __find_provides %{nil} +%define __find_provides %{nil} # OpenGL compositing manager feature/optimization patches. Patch100: xorg-x11-server-1.1.0-no-move-damage.patch @@ -82,9 +82,6 @@ Patch6004: xserver-1.5.99.3-dmx-xcalloc.patch # cf. bug 482924 Patch6010: xserver-1.5.99.902-selinux-debugging.patch -# ensure HAL can start after X, upstream soon, not 1.6 yet. -Patch6012: xserver-1.5.99.902-listen-for-hal.patch - # don't try intel on poulsbo Patch6013: xserver-1.5.99.902-sod-off-poulsbo.patch @@ -94,9 +91,6 @@ Patch6015: xserver-1.5.99.902-vnc.patch # Make autoconfiguration chose nouveau driver for NVIDIA GPUs Patch6017: xserver-1.5.99.902-nouveau.patch -Patch6018: xserver-1.5.99.903-glx-visual-score.patch -Patch6019: xserver-1.5.99.903-fontmod.h - %define moduledir %{_libdir}/xorg/modules %define drimoduledir %{_libdir}/dri %define sdkdir %{_includedir}/xorg @@ -513,6 +507,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Feb 25 2009 Adam Jackson 1.6.0-1 +- xserver 1.6.0 + * Wed Feb 18 2009 Adam Jackson 1.5.99.903-3 - xserver-1.5.99.903-fontmod.h: Fix build against new libXfont. diff --git a/xserver-1.4.99-builtin-fonts.patch b/xserver-1.4.99-builtin-fonts.patch deleted file mode 100644 index 50719ad..0000000 --- a/xserver-1.4.99-builtin-fonts.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fe82a1fe634a2e0ceb030de90309d26044c7b75e Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Thu, 1 Nov 2007 15:06:17 -0400 -Subject: [PATCH] Enable builtin font FPE. - ---- - dix/dixfonts.c | 3 --- - 1 files changed, 0 insertions(+), 3 deletions(-) - -diff --git a/dix/dixfonts.c b/dix/dixfonts.c -index c21b3ec..c951b05 100644 ---- a/dix/dixfonts.c -+++ b/dix/dixfonts.c -@@ -1890,11 +1890,8 @@ InitFonts (void) - } else - #endif - { --#ifdef BUILTIN_FONTS - BuiltinRegisterFpeFunctions(); --#else - FontFileRegisterFpeFunctions(); --#endif - #ifndef NOFONTSERVERACCESS - fs_register_fpe_functions(); - #endif --- -1.5.3.4 - diff --git a/xserver-1.5.0-edid-backport.patch b/xserver-1.5.0-edid-backport.patch deleted file mode 100644 index 7c4c081..0000000 --- a/xserver-1.5.0-edid-backport.patch +++ /dev/null @@ -1,976 +0,0 @@ -From 2a0e3188588bce1759d3cef4d190909df2ca07ff Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Mon, 25 Aug 2008 12:55:56 -0400 -Subject: [PATCH] EDID backport from master. - ---- - hw/xfree86/common/Makefile.am | 3 +- - hw/xfree86/common/xf86Mode.c | 14 +-- - hw/xfree86/ddc/ddcProperty.c | 11 ++- - hw/xfree86/ddc/edid.h | 5 +- - hw/xfree86/ddc/interpret_edid.c | 14 +++ - hw/xfree86/ddc/print_edid.c | 28 +++-- - hw/xfree86/ddc/xf86DDC.c | 241 +++++++++++++++++++++++--------------- - hw/xfree86/ddc/xf86DDC.h | 6 + - hw/xfree86/loader/xf86sym.c | 1 + - hw/xfree86/modes/xf86Crtc.c | 11 +- - hw/xfree86/modes/xf86EdidModes.c | 228 +++++++++++++++++++++++++++++++----- - hw/xfree86/modes/xf86Modes.c | 12 ++ - hw/xfree86/modes/xf86Modes.h | 3 + - 13 files changed, 422 insertions(+), 155 deletions(-) - -diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am -index 0f44075..8aa3adc 100644 ---- a/hw/xfree86/common/Makefile.am -+++ b/hw/xfree86/common/Makefile.am -@@ -45,7 +45,8 @@ libinit_a_SOURCES = xf86Build.h xf86Init.c - INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \ - -I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \ - -I$(srcdir)/../vbe -I$(srcdir)/../int10 \ -- -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod -+ -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod \ -+ -I$(srcdir)/../modes - - sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \ - xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \ -diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c -index c1b0a5f..24a431d 100644 ---- a/hw/xfree86/common/xf86Mode.c -+++ b/hw/xfree86/common/xf86Mode.c -@@ -39,6 +39,7 @@ - #endif - - #include -+#include "xf86Modes.h" - #include "os.h" - #include "servermd.h" - #include "mibank.h" -@@ -705,16 +706,9 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) - * -- libv - */ - -- /* Is the horizontal blanking a bit lowish? */ -- if (((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) { -- /* is this a cvt -r mode, and only a cvt -r mode? */ -- if (((mode->HTotal - mode->HDisplay) == 160) && -- ((mode->HSyncEnd - mode->HDisplay) == 80) && -- ((mode->HSyncEnd - mode->HSyncStart) == 32) && -- ((mode->VSyncStart - mode->VDisplay) == 3)) { -- if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER)) -- return MODE_NO_REDUCED; -- } -+ if (xf86ModeIsReduced(mode)) { -+ if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER)) -+ return MODE_NO_REDUCED; - } - - if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock)) -diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c -index 02125df..a4384f1 100644 ---- a/hw/xfree86/ddc/ddcProperty.c -+++ b/hw/xfree86/ddc/ddcProperty.c -@@ -83,13 +83,18 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) - } - - if (makeEDID1prop) { -- if ((EDID1rawdata = xalloc(128*sizeof(CARD8)))==NULL) -+ int size = 128; -+ -+ if (DDC->flags & EDID_COMPLETE_RAWDATA) -+ size += DDC->no_sections * 128; -+ -+ if ((EDID1rawdata = xalloc(size*sizeof(CARD8)))==NULL) - return; - - EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME) - 1, TRUE); -- memcpy(EDID1rawdata, DDC->rawData, 128); -+ memcpy(EDID1rawdata, DDC->rawData, size); - xf86RegisterRootWindowProperty(scrnIndex, EDID1Atom, XA_INTEGER, 8, -- 128, (unsigned char *)EDID1rawdata); -+ size, (unsigned char *)EDID1rawdata); - } - - if (makeEDID2prop) { -diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h -index a4e79da..45caf6e 100644 ---- a/hw/xfree86/ddc/edid.h -+++ b/hw/xfree86/ddc/edid.h -@@ -531,6 +531,9 @@ struct detailed_monitor_section { - } section; /* max: 80 */ - }; - -+/* flags */ -+#define EDID_COMPLETE_RAWDATA 0x1 -+ - typedef struct { - int scrnIndex; - struct vendor vendor; -@@ -539,7 +542,7 @@ typedef struct { - struct established_timings timings1; - struct std_timings timings2[8]; - struct detailed_monitor_section det_mon[4]; -- void *vdif; /* unused */ -+ unsigned long flags; - int no_sections; - Uchar *rawData; - } xf86Monitor, *xf86MonPtr; -diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c -index 21391dd..d293861 100644 ---- a/hw/xfree86/ddc/interpret_edid.c -+++ b/hw/xfree86/ddc/interpret_edid.c -@@ -118,6 +118,20 @@ xf86InterpretEDID(int scrnIndex, Uchar *block) - return NULL; - } - -+xf86MonPtr -+xf86InterpretEEDID(int scrnIndex, Uchar *block) -+{ -+ xf86MonPtr m; -+ -+ m = xf86InterpretEDID(scrnIndex, block); -+ if (!m) -+ return NULL; -+ -+ /* extension parse */ -+ -+ return m; -+} -+ - static void - get_vendor_section(Uchar *c, struct vendor *r) - { -diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c -index f5442ad..5e89b40 100644 ---- a/hw/xfree86/ddc/print_edid.c -+++ b/hw/xfree86/ddc/print_edid.c -@@ -462,22 +462,28 @@ print_number_sections(int scrnIndex, int num) - xf86MonPtr - xf86PrintEDID(xf86MonPtr m) - { -- CARD16 i, j; -+ CARD16 i, j, n; - char buf[EDID_WIDTH * 2 + 1]; - -- if (!(m)) return NULL; -+ if (!m) return NULL; - -- print_vendor(m->scrnIndex,&m->vendor); -- print_version(m->scrnIndex,&m->ver); -- print_display(m->scrnIndex,&m->features, &m->ver); -- print_established_timings(m->scrnIndex,&m->timings1); -- print_std_timings(m->scrnIndex,m->timings2); -- print_detailed_monitor_section(m->scrnIndex,m->det_mon); -- print_number_sections(m->scrnIndex,m->no_sections); -+ print_vendor(m->scrnIndex, &m->vendor); -+ print_version(m->scrnIndex, &m->ver); -+ print_display(m->scrnIndex, &m->features, &m->ver); -+ print_established_timings(m->scrnIndex, &m->timings1); -+ print_std_timings(m->scrnIndex, m->timings2); -+ print_detailed_monitor_section(m->scrnIndex, m->det_mon); -+ print_number_sections(m->scrnIndex, m->no_sections); -+ -+ /* extension block section stuff */ - - xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n"); -- -- for (i = 0; i < 128; i += j) { -+ -+ n = 128; -+ if (m->flags & EDID_COMPLETE_RAWDATA) -+ n += m->no_sections * 128; -+ -+ for (i = 0; i < n; i += j) { - for (j = 0; j < EDID_WIDTH; ++j) { - sprintf(&buf[j * 2], "%02x", m->rawData[i + j]); - } -diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c -index 28e2ead..0d86776 100644 ---- a/hw/xfree86/ddc/xf86DDC.c -+++ b/hw/xfree86/ddc/xf86DDC.c -@@ -2,6 +2,14 @@ - * - * Copyright 1998,1999 by Egbert Eich - */ -+ -+/* -+ * Note that DDC1 does not define any method for returning blocks beyond -+ * the first. DDC2 does, but the original implementation would only ever -+ * read the first block. If you want to read and parse all blocks, use -+ * xf86DoEEDID(). -+ */ -+ - #ifdef HAVE_XORG_CONFIG_H - #include - #endif -@@ -31,18 +39,6 @@ static unsigned int *FetchEDID_DDC1( - register unsigned int (*)(ScrnInfoPtr) - ); - --static unsigned char* EDID1Read_DDC2( -- int scrnIndex, -- I2CBusPtr pBus --); -- --static unsigned char * DDCRead_DDC2( -- int scrnIndex, -- I2CBusPtr pBus, -- int start, -- int len --); -- - typedef enum { - DDCOPT_NODDC1, - DDCOPT_NODDC2, -@@ -107,10 +103,102 @@ xf86DoEDID_DDC1( - return tmp; - } - -+static I2CDevPtr -+DDC2MakeDevice(I2CBusPtr pBus, int address, char *name) -+{ -+ I2CDevPtr dev = NULL; -+ -+ if (!(dev = xf86I2CFindDev(pBus, address))) { -+ dev = xf86CreateI2CDevRec(); -+ dev->DevName = name; -+ dev->SlaveAddr = address; -+ dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ -+ dev->StartTimeout = 550; -+ dev->BitTimeout = 40; -+ dev->AcknTimeout = 40; -+ -+ dev->pI2CBus = pBus; -+ if (!xf86I2CDevInit(dev)) { -+ xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n"); -+ return NULL; -+ } -+ } -+ -+ return dev; -+} -+ -+static I2CDevPtr -+DDC2Init(int scrnIndex, I2CBusPtr pBus) -+{ -+ I2CDevPtr dev = NULL; -+ -+ /* -+ * Slow down the bus so that older monitors don't -+ * miss things. -+ */ -+ pBus->RiseFallTime = 20; -+ -+ DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register"); -+ dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2"); -+ -+ return dev; -+} -+ -+/* Mmmm, smell the hacks */ -+static void -+EEDIDStop(I2CDevPtr d) -+{ -+} -+ -+/* block is the EDID block number. a segment is two blocks. */ -+static Bool -+DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer) -+{ -+ unsigned char W_Buffer[1]; -+ int i, segment; -+ I2CDevPtr seg; -+ void (*stop)(I2CDevPtr); -+ -+ for (i = 0; i < RETRIES; i++) { -+ /* Stop bits reset the segment pointer to 0, so be careful here. */ -+ segment = block >> 1; -+ if (segment) { -+ Bool b; -+ -+ if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060))) -+ return FALSE; -+ -+ W_Buffer[0] = segment; -+ -+ stop = dev->pI2CBus->I2CStop; -+ dev->pI2CBus->I2CStop = EEDIDStop; -+ -+ b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0); -+ -+ dev->pI2CBus->I2CStop = stop; -+ if (!b) { -+ dev->pI2CBus->I2CStop(dev); -+ continue; -+ } -+ } -+ -+ W_Buffer[0] = (block & 0x01) * EDID1_LEN; -+ -+ if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) { -+ if (!DDC_checksum(R_Buffer, EDID1_LEN)) -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ - /** - * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are - * unset. EDID information blocks are interpreted and the results returned in -- * an xf86MonPtr. -+ * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return -+ * the complete EDID data, including all extension blocks, if the 'complete' -+ * parameter is TRUE; - * - * This function does not affect the list of modes used by drivers -- it is up - * to the driver to decide policy on what to do with EDID information. -@@ -119,46 +207,72 @@ xf86DoEDID_DDC1( - * @return NULL if no monitor attached or failure to interpret the EDID. - */ - xf86MonPtr --xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) -+xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool complete) - { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - unsigned char *EDID_block = NULL; - xf86MonPtr tmp = NULL; -+ I2CDevPtr dev = NULL; - /* Default DDC and DDC2 to enabled. */ - Bool noddc = FALSE, noddc2 = FALSE; - OptionInfoPtr options; - -- options = xnfalloc(sizeof(DDCOptions)); -- (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); -+ options = xalloc(sizeof(DDCOptions)); -+ if (!options) -+ return NULL; -+ memcpy(options, DDCOptions, sizeof(DDCOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - - xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); - xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); - xfree(options); -- -+ - if (noddc || noddc2) - return NULL; - -- EDID_block = EDID1Read_DDC2(scrnIndex,pBus); -+ if (!(dev = DDC2Init(scrnIndex, pBus))) -+ return NULL; - -- if (EDID_block){ -- tmp = xf86InterpretEDID(scrnIndex,EDID_block); -- } else { --#ifdef DEBUG -- ErrorF("No EDID block returned\n"); --#endif -+ EDID_block = xcalloc(1, EDID1_LEN); -+ if (!EDID_block) - return NULL; -+ -+ if (DDC2Read(dev, 0, EDID_block)) { -+ int i, n = EDID_block[0x7e]; -+ -+ if (complete && n) { -+ EDID_block = xrealloc(EDID_block, EDID1_LEN * (1+n)); -+ -+ for (i = 0; i < n; i++) -+ DDC2Read(dev, i+1, EDID_block + (EDID1_LEN * (1+i))); -+ } -+ -+ tmp = xf86InterpretEEDID(scrnIndex, EDID_block); - } --#ifdef DEBUG -- if (!tmp) -- ErrorF("Cannot interpret EDID block\n"); -- else -- ErrorF("Sections to follow: %i\n",tmp->no_sections); --#endif -- -+ -+ if (tmp && complete) -+ tmp->flags |= EDID_COMPLETE_RAWDATA; -+ - return tmp; - } - -+/** -+ * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are -+ * unset. EDID information blocks are interpreted and the results returned in -+ * an xf86MonPtr. -+ * -+ * This function does not affect the list of modes used by drivers -- it is up -+ * to the driver to decide policy on what to do with EDID information. -+ * -+ * @return pointer to a new xf86MonPtr containing the EDID information. -+ * @return NULL if no monitor attached or failure to interpret the EDID. -+ */ -+xf86MonPtr -+xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) -+{ -+ return xf86DoEEDID(scrnIndex, pBus, FALSE); -+} -+ - /* - * read EDID record , pass it to callback function to interpret. - * callback function will store it for further use by calling -@@ -225,68 +339,3 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, - } while(--count); - return (ptr); - } -- --static unsigned char* --EDID1Read_DDC2(int scrnIndex, I2CBusPtr pBus) --{ -- return DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); --} -- --static unsigned char * --DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) --{ -- I2CDevPtr dev; -- unsigned char W_Buffer[2]; -- int w_bytes; -- unsigned char *R_Buffer; -- int i; -- -- /* -- * Slow down the bus so that older monitors don't -- * miss things. -- */ -- pBus->RiseFallTime = 20; -- -- if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { -- dev = xf86CreateI2CDevRec(); -- dev->DevName = "ddc2"; -- dev->SlaveAddr = 0xA0; -- dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ -- dev->StartTimeout = 550; -- dev->BitTimeout = 40; -- dev->AcknTimeout = 40; -- -- dev->pI2CBus = pBus; -- if (!xf86I2CDevInit(dev)) { -- xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n"); -- return NULL; -- } -- } -- if (start < 0x100) { -- w_bytes = 1; -- W_Buffer[0] = start; -- } else { -- w_bytes = 2; -- W_Buffer[0] = start & 0xFF; -- W_Buffer[1] = (start & 0xFF00) >> 8; -- } -- R_Buffer = xcalloc(1,sizeof(unsigned char) -- * (len)); -- for (i=0; iver.version == 1) -+ if (edid_mon->ver.version == 1) { - size = 128; -- else if (edid_mon->ver.version == 2) -+ if (edid_mon->flags & EDID_COMPLETE_RAWDATA) -+ size += edid_mon->no_sections * 128; -+ } else if (edid_mon->ver.version == 2) - size = 256; - } - xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size); -@@ -2622,15 +2624,16 @@ xf86OutputGetEDIDModes (xf86OutputPtr output) - return xf86DDCGetModes(scrn->scrnIndex, edid_mon); - } - -+/* maybe we should care about DDC1? meh. */ - _X_EXPORT xf86MonPtr - xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) - { - ScrnInfoPtr scrn = output->scrn; - xf86MonPtr mon; - -- mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); -+ mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE); - if (mon) -- xf86DDCApplyQuirks (scrn->scrnIndex, mon); -+ xf86DDCApplyQuirks(scrn->scrnIndex, mon); - - return mon; - } -diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c -index bf0ea3f..7e80601 100644 ---- a/hw/xfree86/modes/xf86EdidModes.c -+++ b/hw/xfree86/modes/xf86EdidModes.c -@@ -1,5 +1,6 @@ - /* - * Copyright 2006 Luc Verhaegen. -+ * 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"), -@@ -34,16 +35,39 @@ - #endif - #endif - -+#define _PARSE_EDID_ - #include "xf86.h" - #include "xf86DDC.h" - #include - #include "property.h" - #include "propertyst.h" --#include "xf86DDC.h" - #include "xf86Crtc.h" - #include - #include - -+static Bool -+xf86MonitorSupportsReducedBlanking(xf86MonPtr DDC) -+{ -+ /* EDID 1.4 explicitly defines RB support */ -+ if (DDC->ver.revision >= 4) { -+ int i; -+ for (i = 0; i < DET_TIMINGS; i++) { -+ struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; -+ if (det_mon->type == DS_RANGES) -+ if (det_mon->section.ranges.supported_blanking & CVT_REDUCED) -+ return TRUE; -+ } -+ -+ return FALSE; -+ } -+ -+ /* For anything older, assume digital means RB support. Boo. */ -+ if (DDC->features.input_type) -+ return TRUE; -+ -+ return FALSE; -+} -+ - /* - * Quirks to work around broken EDID data from various monitors. - */ -@@ -68,6 +92,8 @@ typedef enum { - DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6, - /* use +hsync +vsync for detailed mode */ - DDC_QUIRK_DETAILED_SYNC_PP = 1 << 7, -+ /* Force single-link DVI bandwidth limit */ -+ DDC_QUIRK_DVI_SINGLE_LINK = 1 << 8, - } ddc_quirk_t; - - static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) -@@ -181,6 +207,16 @@ static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC) - return FALSE; - } - -+/* This should probably be made more generic */ -+static Bool quirk_dvi_single_link(int scrnIndex, xf86MonPtr DDC) -+{ -+ /* Red Hat bug #453106: Apple 23" Cinema Display */ -+ if (memcmp (DDC->vendor.name, "APL", 4) == 0 && -+ DDC->vendor.prod_id == 0x921c) -+ return TRUE; -+ return FALSE; -+} -+ - typedef struct { - Bool (*detect) (int scrnIndex, xf86MonPtr DDC); - ddc_quirk_t quirk; -@@ -220,6 +256,10 @@ static const ddc_quirk_map_t ddc_quirks[] = { - quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP, - "Use +hsync +vsync for detailed timing." - }, -+ { -+ quirk_dvi_single_link, DDC_QUIRK_DVI_SINGLE_LINK, -+ "Forcing maximum pixel clock to single DVI link." -+ }, - { - NULL, DDC_QUIRK_NONE, - "No known quirks" -@@ -227,8 +267,13 @@ static const ddc_quirk_map_t ddc_quirks[] = { - }; - - /* -- * TODO: -- * - for those with access to the VESA DMT standard; review please. -+ * These more or less come from the DMT spec. The 720x400 modes are -+ * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75 -+ * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode -+ * should be 1152x870, again for the Mac, but instead we use the x864 DMT -+ * mode. -+ * -+ * The DMT modes have been fact-checked; the rest are mild guesses. - */ - #define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER - #define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 -@@ -237,16 +282,16 @@ static const DisplayModeRec DDCEstablishedModes[17] = { - { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ - { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ - { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ -- { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ -+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ - { MODEPREFIX, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */ -- { MODEPREFIX, 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ -+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ - { MODEPREFIX, 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */ - { MODEPREFIX, 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */ - { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ -- { MODEPREFIX, 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ -+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ - { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ - { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ -- { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ -+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ - { MODEPREFIX, 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */ - { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ - { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ -@@ -272,6 +317,90 @@ DDCModesFromEstablished(int scrnIndex, struct established_timings *timing, - return Modes; - } - -+/* Autogenerated from the DMT spec */ -+static const DisplayModeRec DMTModes[] = { -+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x350@85Hz */ -+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 640x400@85Hz */ -+ { MODEPREFIX, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@85Hz */ -+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ -+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ -+ { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ -+ { MODEPREFIX, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@85Hz */ -+ { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ -+ { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ -+ { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ -+ { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ -+ { MODEPREFIX, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@85Hz */ -+ { MODEPREFIX, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 800x600@120Hz RB */ -+ { MODEPREFIX, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 848x480@60Hz */ -+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz (interlaced) */ -+ { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ -+ { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ -+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ -+ { MODEPREFIX, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@85Hz */ -+ { MODEPREFIX, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@120Hz RB */ -+ { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */ -+ { MODEPREFIX, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@60Hz RB */ -+ { MODEPREFIX, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@60Hz */ -+ { MODEPREFIX, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@75Hz */ -+ { MODEPREFIX, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@85Hz */ -+ { MODEPREFIX, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@120Hz RB */ -+ { MODEPREFIX, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@60Hz RB */ -+ { MODEPREFIX, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@60Hz */ -+ { MODEPREFIX, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@75Hz */ -+ { MODEPREFIX, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@85Hz */ -+ { MODEPREFIX, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@120Hz RB */ -+ { MODEPREFIX, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@60Hz */ -+ { MODEPREFIX, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@85Hz */ -+ { MODEPREFIX, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x960@120Hz RB */ -+ { MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@60Hz */ -+ { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ -+ { MODEPREFIX, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@85Hz */ -+ { MODEPREFIX, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x1024@120Hz RB */ -+ { MODEPREFIX, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1360x768@60Hz */ -+ { MODEPREFIX, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1360x768@120Hz RB */ -+ { MODEPREFIX, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@60Hz RB */ -+ { MODEPREFIX, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@60Hz */ -+ { MODEPREFIX, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@75Hz */ -+ { MODEPREFIX, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@85Hz */ -+ { MODEPREFIX, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@120Hz RB */ -+ { MODEPREFIX, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@60Hz RB */ -+ { MODEPREFIX, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@60Hz */ -+ { MODEPREFIX, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@75Hz */ -+ { MODEPREFIX, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@85Hz */ -+ { MODEPREFIX, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@120Hz RB */ -+ { MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@60Hz */ -+ { MODEPREFIX, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@65Hz */ -+ { MODEPREFIX, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@70Hz */ -+ { MODEPREFIX, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@75Hz */ -+ { MODEPREFIX, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@85Hz */ -+ { MODEPREFIX, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1600x1200@120Hz RB */ -+ { MODEPREFIX, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@60Hz RB */ -+ { MODEPREFIX, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@60Hz */ -+ { MODEPREFIX, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@75Hz */ -+ { MODEPREFIX, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@85Hz */ -+ { MODEPREFIX, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@120Hz RB */ -+ { MODEPREFIX, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@60Hz */ -+ { MODEPREFIX, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@75Hz */ -+ { MODEPREFIX, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1792x1344@120Hz RB */ -+ { MODEPREFIX, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@60Hz */ -+ { MODEPREFIX, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@75Hz */ -+ { MODEPREFIX, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1856x1392@120Hz RB */ -+ { MODEPREFIX, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@60Hz RB */ -+ { MODEPREFIX, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@60Hz */ -+ { MODEPREFIX, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@75Hz */ -+ { MODEPREFIX, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@85Hz */ -+ { MODEPREFIX, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@120Hz RB */ -+ { MODEPREFIX, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@60Hz */ -+ { MODEPREFIX, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@75Hz */ -+ { MODEPREFIX, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1440@120Hz RB */ -+ { MODEPREFIX, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@60Hz RB */ -+ { MODEPREFIX, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@60Hz */ -+ { MODEPREFIX, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@75Hz */ -+ { MODEPREFIX, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@85Hz */ -+ { MODEPREFIX, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@120Hz RB */ -+}; -+ - #define LEVEL_DMT 0 - #define LEVEL_GTF 1 - #define LEVEL_CVT 2 -@@ -288,12 +417,43 @@ MonitorStandardTimingLevel(xf86MonPtr DDC) - return LEVEL_DMT; - } - -+static int -+ModeRefresh(DisplayModePtr mode) -+{ -+ return (int)(xf86ModeVRefresh(mode) + 0.5); -+} -+ - /* -- * This is not really correct. Appendix B of the EDID 1.4 spec defines -- * the right thing to do here. If the timing given here matches a mode -- * defined in the VESA DMT standard, we _must_ use that. If the device -- * supports CVT modes, then we should generate a CVT timing. If both -- * of the above fail, use GTF. -+ * If rb is not set, then we'll not consider reduced-blanking modes as -+ * part of the DMT pool. For the 'standard' EDID mode descriptor there's -+ * no way to specify whether the mode should be RB or not. -+ */ -+static DisplayModePtr -+FindDMTMode(int hsize, int vsize, int refresh, Bool rb) -+{ -+ int i; -+ DisplayModePtr ret; -+ -+ for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) { -+ ret = &DMTModes[i]; -+ -+ if (!rb && xf86ModeIsReduced(ret)) -+ continue; -+ -+ if (ret->HDisplay == hsize && -+ ret->VDisplay == vsize && -+ refresh == ModeRefresh(ret)) -+ return xf86DuplicateMode(ret); -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Appendix B of the EDID 1.4 spec defines the right thing to do here. -+ * If the timing given here matches a mode defined in the VESA DMT standard, -+ * we _must_ use that. If the device supports CVT modes, then we should -+ * generate a CVT timing. If both of the above fail, use GTF. - * - * There are some wrinkles here. EDID 1.1 and 1.0 sinks can't really - * "support" GTF, since it wasn't a standard yet; so if they ask for a -@@ -308,20 +468,28 @@ MonitorStandardTimingLevel(xf86MonPtr DDC) - */ - static DisplayModePtr - DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks, -- int timing_level) -+ int timing_level, Bool rb) - { - DisplayModePtr Modes = NULL, Mode = NULL; - int i; - - for (i = 0; i < STD_TIMINGS; i++) { - if (timing[i].hsize && timing[i].vsize && timing[i].refresh) { -- /* XXX check for DMT first, else... */ -- if (timing_level == LEVEL_CVT) -- Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, -- timing[i].refresh, FALSE, FALSE); -- else -- Mode = xf86GTFMode(timing[i].hsize, timing[i].vsize, -- timing[i].refresh, FALSE, FALSE); -+ Mode = FindDMTMode(timing[i].hsize, timing[i].vsize, -+ timing[i].refresh, rb); -+ -+ if (!Mode) { -+ if (timing_level == LEVEL_CVT) -+ /* pass rb here too? */ -+ Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, -+ timing[i].refresh, FALSE, FALSE); -+ else if (timing_level == LEVEL_GTF) -+ Mode = xf86GTFMode(timing[i].hsize, timing[i].vsize, -+ timing[i].refresh, FALSE, FALSE); -+ } -+ -+ if (!Mode) -+ continue; - - Mode->type = M_T_DRIVER; - Modes = xf86ModesAdd(Modes, Mode); -@@ -595,7 +763,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) - int i; - DisplayModePtr Modes = NULL, Mode; - ddc_quirk_t quirks; -- Bool preferred; -+ Bool preferred, rb; - int timing_level; - - xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", -@@ -611,6 +779,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) - if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75)) - preferred = FALSE; - -+ rb = xf86MonitorSupportsReducedBlanking(DDC); -+ - timing_level = MonitorStandardTimingLevel(DDC); - - for (i = 0; i < DET_TIMINGS; i++) { -@@ -627,7 +797,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) - break; - case DS_STD_TIMINGS: - Mode = DDCModesFromStandardTiming(det_mon->section.std_t, -- quirks, timing_level); -+ quirks, timing_level, rb); - Modes = xf86ModesAdd(Modes, Mode); - break; - case DS_CVT: -@@ -644,7 +814,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) - Modes = xf86ModesAdd(Modes, Mode); - - /* Add standard timings */ -- Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level); -+ Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb); - Modes = xf86ModesAdd(Modes, Mode); - - if (quirks & DDC_QUIRK_PREFER_LARGE_60) -@@ -665,23 +835,21 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) - DisplayModePtr Modes = NULL, Mode; - int i, clock; - Bool have_hsync = FALSE, have_vrefresh = FALSE, have_maxpixclock = FALSE; -+ ddc_quirk_t quirks; - - if (!Monitor || !DDC) - return; - - Monitor->DDC = DDC; - -+ quirks = xf86DDCDetectQuirks(scrnIndex, DDC, FALSE); -+ - if (Monitor->widthmm <= 0 && Monitor->heightmm <= 0) { - Monitor->widthmm = 10 * DDC->features.hsize; - Monitor->heightmm = 10 * DDC->features.vsize; - } - -- /* -- * If this is a digital display, then we can use reduced blanking. -- * XXX This is a 1.3 heuristic. 1.4 explicitly defines rb support. -- */ -- if (DDC->features.input_type) -- Monitor->reducedblanking = TRUE; -+ Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC); - - Modes = xf86DDCGetModes(scrnIndex, DDC); - -@@ -723,6 +891,8 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) - } - - clock = DDC->det_mon[i].section.ranges.max_clock * 1000; -+ if (quirks & DDC_QUIRK_DVI_SINGLE_LINK) -+ clock = min(clock, 165000); - if (!have_maxpixclock && clock > Monitor->maxPixClock) - Monitor->maxPixClock = clock; - -diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c -index ea398ad..da25273 100644 ---- a/hw/xfree86/modes/xf86Modes.c -+++ b/hw/xfree86/modes/xf86Modes.c -@@ -513,6 +513,18 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList, - } - } - -+Bool -+xf86ModeIsReduced(DisplayModePtr mode) -+{ -+ if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) && -+ ((mode->HTotal - mode->HDisplay) == 160) && -+ ((mode->HSyncEnd - mode->HDisplay) == 80) && -+ ((mode->HSyncEnd - mode->HSyncStart) == 32) && -+ ((mode->VSyncStart - mode->VDisplay) == 3)) -+ return TRUE; -+ return FALSE; -+} -+ - /** - * Marks as bad any reduced-blanking modes. - * -diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h -index acdea65..af5987b 100644 ---- a/hw/xfree86/modes/xf86Modes.h -+++ b/hw/xfree86/modes/xf86Modes.h -@@ -64,6 +64,9 @@ DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, - Bool Reduced, Bool Interlaced); - DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins); - -+Bool -+xf86ModeIsReduced(DisplayModePtr mode); -+ - void - xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags); --- -1.5.6.4 - diff --git a/xserver-1.5.0-exa-master-fix-x11perf-crash.patch b/xserver-1.5.0-exa-master-fix-x11perf-crash.patch deleted file mode 100644 index 80f7e98..0000000 --- a/xserver-1.5.0-exa-master-fix-x11perf-crash.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 99838fad3c826c95736f93fc4f9492fbb93f9205 Mon Sep 17 00:00:00 2001 -From: Dave Airlie -Date: Thu, 25 Sep 2008 15:40:19 +1000 -Subject: [PATCH] exa: make sure pixmap devPrivate.ptr is NULL at create time - ---- - exa/exa.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/exa/exa.c b/exa/exa.c -index 6e769a7..d240126 100644 ---- a/exa/exa.c -+++ b/exa/exa.c -@@ -325,6 +325,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - pExaPixmap->fb_ptr = NULL; - pExaPixmap->pDamage = NULL; -+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; -+ pPixmap->devPrivate.ptr = NULL; -+ - } else { - pExaPixmap->driverPriv = NULL; - /* Scratch pixmaps may have w/h equal to zero, and may not be --- -1.5.5.1 - diff --git a/xserver-1.5.0-force-SwitchCoreKeyboard-for-evdev.patch b/xserver-1.5.0-force-SwitchCoreKeyboard-for-evdev.patch deleted file mode 100644 index 2ac6095..0000000 --- a/xserver-1.5.0-force-SwitchCoreKeyboard-for-evdev.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 638cab7e1dc3711f7fb04155bcdabf4b8895cc5e Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Mon, 4 Aug 2008 17:08:36 +0930 -Subject: [PATCH] xfree86: force SwitchCoreKeyboard for evdev devices (updated). - -If an evdev keyboard device is added through the HAL mechanism, force a -SwitchCoreKeyboard to load the evdev map into the VCK. This way, by the time a -client starts the evdev keymap is already there, leading to less pain lateron. - -Works if: -- all keyboards are hotplugged through HAL, and/or -- the xorg.conf keyboard uses the kbd driver. - -Has no effect (i.e. busted keymaps) if: -- an evdev keyboard device has been specified in the xorg.conf. -- we don't have a device at startup and plug a device in after starting the - desktop environment. -- if the device we use isn't the first one reported by HAL. - -If HAL isn't set up, this patch is a noop. ---- - hw/xfree86/common/xf86Xinput.c | 31 +++++++++++++++++++++++++++++++ - 1 files changed, 31 insertions(+), 0 deletions(-) - -diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c -index 710e787..dacc3dc 100644 ---- a/hw/xfree86/common/xf86Xinput.c -+++ b/hw/xfree86/common/xf86Xinput.c -@@ -423,6 +423,37 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) - (!is_auto || xf86Info.autoEnableDevices)) - EnableDevice(dev); - -+ /* XXX: The VCK always starts with built-in defaults for keymap. These -+ * defaults are different to the evdev ones. When the first key is hit on -+ * an extension device, the keymap is copied into the VCK's and any -+ * changes made at runtime to the VCK map are lost. -+ * -+ * Assumption: if we have at least one evdev keyboard device, we can -+ * ignore kbd devices. Force a SwitchCoreKeyboard so the VCK has the same -+ * keymap as we do. -+ * -+ * Next time we hit a key, we don't change the map over anymore (see -+ * SwitchCoreKeyboard), and live happily ever after. -+ * Until we have 2 physical keyboards. Or the first real keyboard isn't -+ * actually the one we use. Oh well. -+ * -+ */ -+ if (dev->key) -+ { -+ InputInfoPtr info; -+ -+ /* Search if there is one other keyboard that uses evdev. */ -+ for (info = xf86InputDevs; info; info = info->next) -+ { -+ if (info != pInfo && info->dev && info->dev->key && -+ (strcmp(info->drv->driverName, "evdev") == 0)) -+ break; -+ } -+ -+ if (!info) -+ SwitchCoreKeyboard(dev); -+ } -+ - *pdev = dev; - return Success; - --- -1.5.5.1 - diff --git a/xserver-1.5.0-hide-cursor.patch b/xserver-1.5.0-hide-cursor.patch deleted file mode 100644 index da96902..0000000 --- a/xserver-1.5.0-hide-cursor.patch +++ /dev/null @@ -1,94 +0,0 @@ -From e99347a3e82e6db47dd482169b6799968afc3893 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 20 Aug 2008 10:11:07 -0400 -Subject: [PATCH] Hide the cursor until the first XDefineCursor() call. - ---- - xfixes/cursor.c | 28 ++++++++++++++++++++++++++-- - 1 files changed, 26 insertions(+), 2 deletions(-) - -diff --git a/xfixes/cursor.c b/xfixes/cursor.c -index d51251f..c8c4c9f 100755 ---- a/xfixes/cursor.c -+++ b/xfixes/cursor.c -@@ -70,7 +70,7 @@ - return BadCursor; \ - } \ - } -- -+ - /* - * There is a global list of windows selecting for cursor events - */ -@@ -109,6 +109,7 @@ - - typedef struct _CursorScreen { - DisplayCursorProcPtr DisplayCursor; -+ ChangeWindowAttributesProcPtr ChangeWindowAttributes; - CloseScreenProcPtr CloseScreen; - CursorHideCountPtr pCursorHideCounts; - } CursorScreenRec, *CursorScreenPtr; -@@ -119,6 +120,9 @@ - #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) - #define Unwrap(as,s,elt) ((s)->elt = (as)->elt) - -+/* The cursor doesn't show up until the first XDefineCursor() */ -+static Bool CursorVisible = FALSE; -+ - static Bool - CursorDisplayCursor (ScreenPtr pScreen, - CursorPtr pCursor) -@@ -128,7 +132,7 @@ - - Unwrap (cs, pScreen, DisplayCursor); - -- if (cs->pCursorHideCounts != NULL) { -+ if (cs->pCursorHideCounts != NULL || !CursorVisible) { - ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor); - } else { - ret = (*pScreen->DisplayCursor) (pScreen, pCursor); -@@ -161,6 +165,24 @@ - } - - static Bool -+CursorChangeWindowAttributes(WindowPtr pWin, unsigned long mask) -+{ -+ ScreenPtr pScreen = pWin->drawable.pScreen; -+ CursorScreenPtr cs = GetCursorScreen(pScreen); -+ Bool ret; -+ extern char *ConnectionInfo; -+ -+ if ((mask & CWCursor) && ConnectionInfo) -+ CursorVisible = TRUE; -+ -+ Unwrap(cs, pScreen, ChangeWindowAttributes); -+ ret = pScreen->ChangeWindowAttributes(pWin, mask); -+ Wrap(cs, pScreen, ChangeWindowAttributes, CursorChangeWindowAttributes); -+ -+ return ret; -+} -+ -+static Bool - CursorCloseScreen (int index, ScreenPtr pScreen) - { - CursorScreenPtr cs = GetCursorScreen (pScreen); -@@ -168,6 +190,7 @@ - - Unwrap (cs, pScreen, CloseScreen); - Unwrap (cs, pScreen, DisplayCursor); -+ Unwrap (cs, pScreen, ChangeWindowAttributes); - deleteCursorHideCountsForScreen(pScreen); - ret = (*pScreen->CloseScreen) (index, pScreen); - xfree (cs); -@@ -1042,6 +1065,8 @@ - return FALSE; - Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); - Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); -+ Wrap (cs, pScreen, ChangeWindowAttributes, -+ CursorChangeWindowAttributes); - cs->pCursorHideCounts = NULL; - SetCursorScreen (pScreen, cs); - } --- -1.5.6.4 - diff --git a/xserver-1.5.1-exa-fix-glyph-segfault.patch b/xserver-1.5.1-exa-fix-glyph-segfault.patch deleted file mode 100644 index 5f393b5..0000000 --- a/xserver-1.5.1-exa-fix-glyph-segfault.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 5ab230373909541945d373252a3f244b68a6f7af Mon Sep 17 00:00:00 2001 -From: Fedora X Ninjas -Date: Mon, 6 Oct 2008 11:43:05 +1000 -Subject: [PATCH] exa: fix case where glyphs get flushed on last loop of previous cycle. - -we segfault here in exaCompositeRects as we have no source as already -flushed just before the loop finished. ---- - exa/exa_glyphs.c | 12 +++++++----- - 1 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c -index b23e7f6..2efc42d 100644 ---- a/exa/exa_glyphs.c -+++ b/exa/exa_glyphs.c -@@ -872,11 +872,13 @@ exaGlyphs (CARD8 op, - list++; - } - -- if (maskFormat) -- exaGlyphsToMask(pMask, &buffer); -- else -- exaGlyphsToDst(op, pSrc, pDst, &buffer, -- xSrc, ySrc, xDst, yDst); -+ if (buffer.count && buffer.source) { -+ if (maskFormat) -+ exaGlyphsToMask(pMask, &buffer); -+ else -+ exaGlyphsToDst(op, pSrc, pDst, &buffer, -+ xSrc, ySrc, xDst, yDst); -+ } - - if (maskFormat) - { --- -1.5.5.1 - diff --git a/xserver-1.5.1-xgi.patch b/xserver-1.5.1-xgi.patch deleted file mode 100644 index 918f5be..0000000 --- a/xserver-1.5.1-xgi.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3be280e47bf259e5ac43350df52ae0829ca0243f Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Tue, 7 Oct 2008 14:06:21 -0400 -Subject: [PATCH] Shove XGI cards onto the sis driver. - -This is wrong for xgixp but whatever like anyone has one of those. ---- - hw/xfree86/common/xf86AutoConfig.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c -index 7e5fab4..f110fcd 100644 ---- a/hw/xfree86/common/xf86AutoConfig.c -+++ b/hw/xfree86/common/xf86AutoConfig.c -@@ -178,7 +178,7 @@ videoPtrToDriverName(struct pci_device *dev) - default: - return "savage"; - } -- case 0x1039: return "sis"; -+ case 0x1039: case 0x18ca: return "sis"; - case 0x126f: return "siliconmotion"; - case 0x121a: - if (dev->device_id < 0x0003) --- -1.6.0.1 - diff --git a/xserver-1.5.2-exa-master-upgrade.patch b/xserver-1.5.2-exa-master-upgrade.patch deleted file mode 100644 index 37cd709..0000000 --- a/xserver-1.5.2-exa-master-upgrade.patch +++ /dev/null @@ -1,2074 +0,0 @@ -From 3a5a88ec354de45434b9e037d21cc56c3079f4b2 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 5 Nov 2008 14:59:27 -0500 -Subject: [PATCH] Upgrade to master EXA - ---- - exa/Makefile.am | 1 + - exa/exa.c | 95 +++-- - exa/exa.h | 19 +- - exa/exa_accel.c | 144 ++++++-- - exa/exa_glyphs.c | 897 ++++++++++++++++++++++++++++++++++++++++++++ - exa/exa_migration.c | 45 ++- - exa/exa_priv.h | 76 +++- - exa/exa_render.c | 280 +++++++++++++-- - exa/exa_unaccel.c | 30 +- - hw/xfree86/exa/exa.man.pre | 6 - - hw/xfree86/exa/examodule.c | 9 +- - 11 files changed, 1446 insertions(+), 156 deletions(-) - create mode 100644 exa/exa_glyphs.c - -diff --git a/exa/Makefile.am b/exa/Makefile.am -index e2f7ed3..2b3f1e4 100644 ---- a/exa/Makefile.am -+++ b/exa/Makefile.am -@@ -18,6 +18,7 @@ libexa_la_SOURCES = \ - exa.c \ - exa.h \ - exa_accel.c \ -+ exa_glyphs.c \ - exa_migration.c \ - exa_offscreen.c \ - exa_render.c \ -diff --git a/exa/exa.c b/exa/exa.c -index 72539c0..22f3ab9 100644 ---- a/exa/exa.c -+++ b/exa/exa.c -@@ -35,8 +35,6 @@ - #include - - #include "exa_priv.h" --#include --#include "dixfontstr.h" - #include "exa.h" - #include "cw.h" - -@@ -165,7 +163,7 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2) - RegionPtr pDamageReg; - RegionRec region; - -- if (!pExaPixmap) -+ if (!pExaPixmap || !pExaPixmap->pDamage) - return; - - box.x1 = max(x1, 0); -@@ -265,6 +263,21 @@ exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - pExaScr->info->pixmapPitchAlign); - } - -+ -+static void -+ExaDamageReport(DamagePtr pDamage, RegionPtr pReg, void *pClosure) -+{ -+ PixmapPtr pPixmap = pClosure; -+ ExaPixmapPriv(pPixmap); -+ RegionPtr pDamageReg = DamageRegion(pDamage); -+ -+ if (pExaPixmap->pendingDamage) { -+ REGION_UNION(pScreen, pDamageReg, pDamageReg, pReg); -+ pExaPixmap->pendingDamage = FALSE; -+ } -+} -+ -+ - /** - * exaCreatePixmap() creates a new pixmap. - * -@@ -325,6 +338,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - paddedWidth, NULL); - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - pExaPixmap->fb_ptr = NULL; -+ pExaPixmap->pDamage = NULL; - } else { - pExaPixmap->driverPriv = NULL; - /* Scratch pixmaps may have w/h equal to zero, and may not be -@@ -349,21 +363,22 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - fbDestroyPixmap(pPixmap); - return NULL; - } -- } -- -- pExaPixmap->area = NULL; - -- /* Set up damage tracking */ -- pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, -- pScreen, pPixmap); -+ /* Set up damage tracking */ -+ pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL, -+ DamageReportRawRegion, TRUE, -+ pScreen, pPixmap); - -- if (pExaPixmap->pDamage == NULL) { -- fbDestroyPixmap (pPixmap); -- return NULL; -- } -+ if (pExaPixmap->pDamage == NULL) { -+ fbDestroyPixmap (pPixmap); -+ return NULL; -+ } - -- DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); -- DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); -+ DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); -+ DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); -+ } -+ -+ pExaPixmap->area = NULL; - - /* None of the pixmap bits are valid initially */ - REGION_NULL(pScreen, &pExaPixmap->validSys); -@@ -660,34 +675,25 @@ exaCreateGC (GCPtr pGC) - return TRUE; - } - --void --exaPrepareAccessWindow(WindowPtr pWin) -+static Bool -+exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) - { -- if (pWin->backgroundState == BackgroundPixmap) -+ Bool ret; -+ -+ if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) - exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); - -- if (pWin->borderIsPixel == FALSE) -- exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC); --} -+ if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) -+ exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); - --void --exaFinishAccessWindow(WindowPtr pWin) --{ -- if (pWin->backgroundState == BackgroundPixmap) -- exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); -+ ret = fbChangeWindowAttributes(pWin, mask); - -- if (pWin->borderIsPixel == FALSE) -- exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC); --} -+ if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) -+ exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); - --static Bool --exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) --{ -- Bool ret; -+ if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) -+ exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); - -- exaPrepareAccessWindow(pWin); -- ret = fbChangeWindowAttributes(pWin, mask); -- exaFinishAccessWindow(pWin); - return ret; - } - -@@ -741,6 +747,9 @@ exaCloseScreen(int i, ScreenPtr pScreen) - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - #endif - -+ if (ps->Glyphs == exaGlyphs) -+ exaGlyphsFini(pScreen); -+ - pScreen->CreateGC = pExaScr->SavedCreateGC; - pScreen->CloseScreen = pExaScr->SavedCloseScreen; - pScreen->GetImage = pExaScr->SavedGetImage; -@@ -754,8 +763,9 @@ exaCloseScreen(int i, ScreenPtr pScreen) - #ifdef RENDER - if (ps) { - ps->Composite = pExaScr->SavedComposite; -+ ps->Glyphs = pExaScr->SavedGlyphs; - ps->Trapezoids = pExaScr->SavedTrapezoids; -- ps->AddTraps = pExaScr->SavedAddTraps; -+ ps->Triangles = pExaScr->SavedTriangles; - } - #endif - -@@ -917,14 +927,16 @@ exaDriverInit (ScreenPtr pScreen, - pExaScr->SavedComposite = ps->Composite; - ps->Composite = exaComposite; - -+ if (pScreenInfo->PrepareComposite) { -+ pExaScr->SavedGlyphs = ps->Glyphs; -+ ps->Glyphs = exaGlyphs; -+ } -+ - pExaScr->SavedTriangles = ps->Triangles; - ps->Triangles = exaTriangles; - - pExaScr->SavedTrapezoids = ps->Trapezoids; - ps->Trapezoids = exaTrapezoids; -- -- pExaScr->SavedAddTraps = ps->AddTraps; -- ps->AddTraps = ExaCheckAddTraps; - } - #endif - -@@ -978,6 +990,9 @@ exaDriverInit (ScreenPtr pScreen, - } - } - -+ if (ps->Glyphs == exaGlyphs) -+ exaGlyphsInit(pScreen); -+ - LogMessage(X_INFO, "EXA(%d): Driver registered support for the following" - " operations:\n", pScreen->myNum); - assert(pScreenInfo->PrepareSolid != NULL); -diff --git a/exa/exa.h b/exa/exa.h -index a3dad69..6486bd3 100644 ---- a/exa/exa.h -+++ b/exa/exa.h -@@ -744,21 +744,36 @@ typedef struct _ExaDriver { - - /** @} */ - -+/* in exa.c */ - ExaDriverPtr - exaDriverAlloc(void); - - Bool --exaDriverInit(ScreenPtr pScreen, -+exaDriverInit(ScreenPtr pScreen, - ExaDriverPtr pScreenInfo); - - void --exaDriverFini(ScreenPtr pScreen); -+exaDriverFini(ScreenPtr pScreen); - - void - exaMarkSync(ScreenPtr pScreen); - void - exaWaitSync(ScreenPtr pScreen); - -+unsigned long -+exaGetPixmapOffset(PixmapPtr pPix); -+ -+unsigned long -+exaGetPixmapPitch(PixmapPtr pPix); -+ -+unsigned long -+exaGetPixmapSize(PixmapPtr pPix); -+ -+void * -+exaGetPixmapDriverPrivate(PixmapPtr p); -+ -+ -+/* in exa_offscreen.c */ - ExaOffscreenArea * - exaOffscreenAlloc(ScreenPtr pScreen, int size, int align, - Bool locked, -diff --git a/exa/exa_accel.c b/exa/exa_accel.c -index 3ec9625..1c07a0b 100644 ---- a/exa/exa_accel.c -+++ b/exa/exa_accel.c -@@ -144,7 +144,6 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - ExaScreenPriv (pDrawable->pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv(pPix); -- ExaMigrationRec pixmaps[1]; - RegionPtr pClip; - BoxPtr pbox; - int nbox; -@@ -166,11 +165,16 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - if (pExaScr->swappedOut) - return FALSE; - -- pixmaps[0].as_dst = TRUE; -- pixmaps[0].as_src = FALSE; -- pixmaps[0].pPix = pPix; -- pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); -- exaDoMigration (pixmaps, 1, TRUE); -+ if (pExaPixmap->pDamage) { -+ ExaMigrationRec pixmaps[1]; -+ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = FALSE; -+ pixmaps[0].pPix = pPix; -+ pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); -+ -+ exaDoMigration (pixmaps, 1, TRUE); -+ } - - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - -@@ -441,16 +445,36 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, - pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); - - /* Check whether the accelerator can use this pixmap. -- * FIXME: If it cannot, use temporary pixmaps so that the drawing -- * happens within limits. -+ * If the pitch of the pixmaps is out of range, there's nothing -+ * we can do but fall back to software rendering. - */ -- if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) -- { -+ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || -+ pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) - goto fallback; -- } else { -- exaDoMigration (pixmaps, 2, TRUE); -+ -+ /* If the width or the height of either of the pixmaps -+ * is out of range, check whether the boxes are actually out of the -+ * addressable range as well. If they aren't, we can still do -+ * the copying in hardware. -+ */ -+ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { -+ int i; -+ -+ for (i = 0; i < nbox; i++) { -+ /* src */ -+ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || -+ (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) -+ goto fallback; -+ -+ /* dst */ -+ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || -+ (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) -+ goto fallback; -+ } - } - -+ exaDoMigration (pixmaps, 2, TRUE); -+ - /* Mixed directions must be handled specially if the card is lame */ - if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && - reverse != upsidedown) { -@@ -860,16 +884,23 @@ exaImageGlyphBlt (DrawablePtr pDrawable, - FbBits depthMask; - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - ExaPixmapPriv(pPixmap); -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- BoxRec extents = *REGION_EXTENTS(pScreen, pending_damage); -+ RegionPtr pending_damage = NULL; -+ BoxRec extents; - int xoff, yoff; - -- if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2) -- return; -+ if (pExaPixmap->pDamage) -+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ -+ if (pending_damage) { -+ extents = *REGION_EXTENTS(pScreen, pending_damage); -+ -+ if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2) -+ return; - -- depthMask = FbFullMask(pDrawable->depth); -+ depthMask = FbFullMask(pDrawable->depth); -+ } - -- if ((pGC->planemask & depthMask) != depthMask) -+ if (!pending_damage || (pGC->planemask & depthMask) != depthMask) - { - ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); - return; -@@ -1103,6 +1134,7 @@ exaFillRegionTiled (DrawablePtr pDrawable, - int nbox = REGION_NUM_RECTS (pRegion); - BoxPtr pBox = REGION_RECTS (pRegion); - Bool ret = FALSE; -+ int i; - - tileWidth = pTile->drawable.width; - tileHeight = pTile->drawable.height; -@@ -1125,14 +1157,11 @@ exaFillRegionTiled (DrawablePtr pDrawable, - pixmaps[1].pPix = pTile; - pixmaps[1].pReg = NULL; - -- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); -- REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); -- - pExaPixmap = ExaGetPixmapPriv (pPixmap); - - if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) - { -- goto out; -+ return FALSE; - } else { - exaDoMigration (pixmaps, 2, TRUE); - } -@@ -1140,24 +1169,33 @@ exaFillRegionTiled (DrawablePtr pDrawable, - pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - - if (!pPixmap || !exaPixmapIsOffscreen(pTile)) -- goto out; -+ return FALSE; - - if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) - { -- while (nbox--) -+ if (xoff || yoff) -+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); -+ -+ for (i = 0; i < nbox; i++) - { -- int height = pBox->y2 - pBox->y1; -- int dstY = pBox->y1; -+ int height = pBox[i].y2 - pBox[i].y1; -+ int dstY = pBox[i].y1; - int tileY; - -+ if (alu == GXcopy) -+ height = min(height, tileHeight); -+ - modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); - - while (height > 0) { -- int width = pBox->x2 - pBox->x1; -- int dstX = pBox->x1; -+ int width = pBox[i].x2 - pBox[i].x1; -+ int dstX = pBox[i].x1; - int tileX; - int h = tileHeight - tileY; - -+ if (alu == GXcopy) -+ width = min(width, tileWidth); -+ - if (h > height) - h = height; - height -= h; -@@ -1179,17 +1217,57 @@ exaFillRegionTiled (DrawablePtr pDrawable, - dstY += h; - tileY = 0; - } -- pBox++; - } - (*pExaScr->info->DoneCopy) (pPixmap); -+ -+ /* With GXcopy, we only need to do the basic algorithm up to the tile -+ * size; then, we can just keep doubling the destination in each -+ * direction until it fills the box. This way, the number of copy -+ * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where -+ * rx/ry is the ratio between box and tile width/height. This can make -+ * a big difference if each driver copy incurs a significant constant -+ * overhead. -+ */ -+ if (alu != GXcopy) -+ ret = TRUE; -+ else if ((*pExaScr->info->PrepareCopy) (pPixmap, pPixmap, 1, 1, alu, -+ planemask)) { -+ for (i = 0; i < nbox; i++) -+ { -+ int dstX = pBox[i].x1 + tileWidth; -+ int dstY = pBox[i].y1 + tileHeight; -+ int width = min(pBox[i].x2 - dstX, tileWidth); -+ int height = min(pBox[i].y2 - pBox[i].y1, tileHeight); -+ -+ while (dstX < pBox[i].x2) { -+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, -+ dstX, pBox[i].y1, width, height); -+ dstX += width; -+ width = min(pBox[i].x2 - dstX, width * 2); -+ } -+ -+ width = pBox[i].x2 - pBox[i].x1; -+ height = min(pBox[i].y2 - dstY, tileHeight); -+ -+ while (dstY < pBox[i].y2) { -+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, -+ pBox[i].x1, dstY, width, height); -+ dstY += height; -+ height = min(pBox[i].y2 - dstY, height * 2); -+ } -+ } -+ -+ (*pExaScr->info->DoneCopy) (pPixmap); -+ -+ ret = TRUE; -+ } -+ - exaMarkSync(pDrawable->pScreen); - -- ret = TRUE; -+ if (xoff || yoff) -+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); - } - --out: -- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); -- - return ret; - } - -diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c -new file mode 100644 -index 0000000..b23e7f6 ---- /dev/null -+++ b/exa/exa_glyphs.c -@@ -0,0 +1,897 @@ -+/* -+ * Copyright © 2008 Red Hat, Inc. -+ * Partly based on code Copyright © 2000 SuSE, Inc. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of Red Hat not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. Red Hat makes no representations about the -+ * suitability of this software for any purpose. It is provided "as is" -+ * without express or implied warranty. -+ * -+ * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat -+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of SuSE not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. SuSE makes no representations about the -+ * suitability of this software for any purpose. It is provided "as is" -+ * without express or implied warranty. -+ * -+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE -+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ * Author: Owen Taylor -+ * Based on code by: Keith Packard -+ */ -+ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+ -+#include "exa_priv.h" -+ -+#include "mipict.h" -+ -+#if DEBUG_GLYPH_CACHE -+#define DBG_GLYPH_CACHE(a) ErrorF a -+#else -+#define DBG_GLYPH_CACHE(a) -+#endif -+ -+/* Width of the pixmaps we use for the caches; this should be less than -+ * max texture size of the driver; this may need to actually come from -+ * the driver. -+ */ -+#define CACHE_PICTURE_WIDTH 1024 -+ -+/* Maximum number of glyphs we buffer on the stack before flushing -+ * rendering to the mask or destination surface. -+ */ -+#define GLYPH_BUFFER_SIZE 256 -+ -+typedef struct { -+ PicturePtr source; -+ ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE]; -+ int count; -+} ExaGlyphBuffer, *ExaGlyphBufferPtr; -+ -+typedef enum { -+ ExaGlyphSuccess, /* Glyph added to render buffer */ -+ ExaGlyphFail, /* out of memory, etc */ -+ ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */ -+} ExaGlyphCacheResult; -+ -+void -+exaGlyphsInit(ScreenPtr pScreen) -+{ -+ ExaScreenPriv(pScreen); -+ int i = 0; -+ -+ memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches)); -+ -+ pExaScr->glyphCaches[i].format = PICT_a8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; -+ i++; -+ -+ assert(i == EXA_NUM_GLYPH_CACHES); -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ pExaScr->glyphCaches[i].columns = CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth; -+ pExaScr->glyphCaches[i].size = 256; -+ pExaScr->glyphCaches[i].hashSize = 557; -+ } -+} -+ -+static void -+exaUnrealizeGlyphCaches(ScreenPtr pScreen, -+ unsigned int format) -+{ -+ ExaScreenPriv(pScreen); -+ int i; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (cache->format != format) -+ continue; -+ -+ if (cache->picture) { -+ FreePicture ((pointer) cache->picture, (XID) 0); -+ cache->picture = NULL; -+ } -+ -+ if (cache->hashEntries) { -+ xfree(cache->hashEntries); -+ cache->hashEntries = NULL; -+ } -+ -+ if (cache->glyphs) { -+ xfree(cache->glyphs); -+ cache->glyphs = NULL; -+ } -+ cache->glyphCount = 0; -+ } -+} -+ -+/* All caches for a single format share a single pixmap for glyph storage, -+ * allowing mixing glyphs of different sizes without paying a penalty -+ * for switching between source pixmaps. (Note that for a size of font -+ * right at the border between two sizes, we might be switching for almost -+ * every glyph.) -+ * -+ * This function allocates the storage pixmap, and then fills in the -+ * rest of the allocated structures for all caches with the given format. -+ */ -+static Bool -+exaRealizeGlyphCaches(ScreenPtr pScreen, -+ unsigned int format) -+{ -+ ExaScreenPriv(pScreen); -+ -+ int depth = PIXMAN_FORMAT_DEPTH(format); -+ PictFormatPtr pPictFormat; -+ PixmapPtr pPixmap; -+ PicturePtr pPicture; -+ int height; -+ int i; -+ int error; -+ -+ pPictFormat = PictureMatchFormat(pScreen, depth, format); -+ if (!pPictFormat) -+ return FALSE; -+ -+ /* Compute the total vertical size needed for the format */ -+ -+ height = 0; -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ int rows; -+ -+ if (cache->format != format) -+ continue; -+ -+ cache->yOffset = height; -+ -+ rows = (cache->size + cache->columns - 1) / cache->columns; -+ height += rows * cache->glyphHeight; -+ } -+ -+ /* Now allocate the pixmap and picture */ -+ -+ pPixmap = (*pScreen->CreatePixmap) (pScreen, -+ CACHE_PICTURE_WIDTH, -+ height, depth, 0); -+ if (!pPixmap) -+ return FALSE; -+ -+ pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, -+ 0, 0, serverClient, &error); -+ -+ (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */ -+ -+ if (!pPicture) -+ return FALSE; -+ -+ /* And store the picture in all the caches for the format */ -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ int j; -+ -+ if (cache->format != format) -+ continue; -+ -+ cache->picture = pPicture; -+ cache->picture->refcnt++; -+ cache->hashEntries = xalloc(sizeof(int) * cache->hashSize); -+ cache->glyphs = xalloc(sizeof(ExaCachedGlyphRec) * cache->size); -+ cache->glyphCount = 0; -+ -+ if (!cache->hashEntries || !cache->glyphs) -+ goto bail; -+ -+ for (j = 0; j < cache->hashSize; j++) -+ cache->hashEntries[j] = -1; -+ -+ cache->evictionPosition = rand() % cache->size; -+ } -+ -+ /* Each cache references the picture individually */ -+ FreePicture ((pointer) pPicture, (XID) 0); -+ return TRUE; -+ -+bail: -+ exaUnrealizeGlyphCaches(pScreen, format); -+ return FALSE; -+} -+ -+void -+exaGlyphsFini (ScreenPtr pScreen) -+{ -+ ExaScreenPriv(pScreen); -+ int i; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (cache->picture) -+ exaUnrealizeGlyphCaches(pScreen, cache->format); -+ } -+} -+ -+static int -+exaGlyphCacheHashLookup(ExaGlyphCachePtr cache, -+ GlyphPtr pGlyph) -+{ -+ int slot; -+ -+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ int entryPos = cache->hashEntries[slot]; -+ if (entryPos == -1) -+ return -1; -+ -+ if (memcmp(pGlyph->sha1, cache->glyphs[entryPos].sha1, sizeof(pGlyph->sha1)) == 0){ -+ return entryPos; -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+static void -+exaGlyphCacheHashInsert(ExaGlyphCachePtr cache, -+ GlyphPtr pGlyph, -+ int pos) -+{ -+ int slot; -+ -+ memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1)); -+ -+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ if (cache->hashEntries[slot] == -1) { -+ cache->hashEntries[slot] = pos; -+ return; -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+static void -+exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, -+ int pos) -+{ -+ int slot; -+ int emptiedSlot = -1; -+ -+ slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ int entryPos = cache->hashEntries[slot]; -+ -+ if (entryPos == -1) -+ return; -+ -+ if (entryPos == pos) { -+ cache->hashEntries[slot] = -1; -+ emptiedSlot = slot; -+ } else if (emptiedSlot != -1) { -+ /* See if we can move this entry into the emptied slot, we can't -+ * do that if if entry would have hashed between the current position -+ * and the emptied slot. (taking wrapping into account). Bad positions -+ * are: -+ * -+ * | XXXXXXXXXX | -+ * i j -+ * -+ * |XXX XXXX| -+ * j i -+ * -+ * i - slot, j - emptiedSlot -+ * -+ * (Knuth 6.4R) -+ */ -+ -+ int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize; -+ -+ if (!((entrySlot >= slot && entrySlot < emptiedSlot) || -+ (emptiedSlot < slot && (entrySlot < emptiedSlot || entrySlot >= slot)))) -+ { -+ cache->hashEntries[emptiedSlot] = entryPos; -+ cache->hashEntries[slot] = -1; -+ emptiedSlot = slot; -+ } -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth) -+#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight) -+ -+/* The most efficient thing to way to upload the glyph to the screen -+ * is to use the UploadToScreen() driver hook; this allows us to -+ * pipeline glyph uploads and to avoid creating offscreen pixmaps for -+ * glyphs that we'll never use again. -+ */ -+static Bool -+exaGlyphCacheUploadGlyph(ScreenPtr pScreen, -+ ExaGlyphCachePtr cache, -+ int pos, -+ GlyphPtr pGlyph) -+{ -+ ExaScreenPriv(pScreen); -+ PicturePtr pGlyphPicture = GlyphPicture(pGlyph)[pScreen->myNum]; -+ PixmapPtr pGlyphPixmap = (PixmapPtr)pGlyphPicture->pDrawable; -+ ExaPixmapPriv(pGlyphPixmap); -+ PixmapPtr pCachePixmap = (PixmapPtr)cache->picture->pDrawable; -+ ExaMigrationRec pixmaps[1]; -+ -+ if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaPixmap->accel_blocked) -+ return FALSE; -+ -+ /* If the glyph pixmap is already uploaded, no point in doing -+ * things this way */ -+ if (exaPixmapIsOffscreen(pGlyphPixmap)) -+ return FALSE; -+ -+ /* UploadToScreen only works if bpp match */ -+ if (pGlyphPixmap->drawable.bitsPerPixel != pCachePixmap->drawable.bitsPerPixel) -+ return FALSE; -+ -+ /* cache pixmap must be offscreen. */ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = FALSE; -+ pixmaps[0].pPix = pCachePixmap; -+ pixmaps[0].pReg = NULL; -+ exaDoMigration (pixmaps, 1, TRUE); -+ -+ if (!exaPixmapIsOffscreen(pCachePixmap)) -+ return FALSE; -+ -+ /* CACHE_{X,Y} are in pixmap coordinates, no need for cache{X,Y}off */ -+ if (!pExaScr->info->UploadToScreen(pCachePixmap, -+ CACHE_X(pos), -+ CACHE_Y(pos), -+ pGlyph->info.width, -+ pGlyph->info.height, -+ (char *)pExaPixmap->sys_ptr, -+ pExaPixmap->sys_pitch)) -+ return FALSE; -+ -+ /* This pixmap should never be bound to a window, so no need to offset coordinates. */ -+ exaPixmapDirty (pCachePixmap, -+ CACHE_X(pos), -+ CACHE_Y(pos), -+ CACHE_X(pos) + pGlyph->info.width, -+ CACHE_Y(pos) + pGlyph->info.height); -+ -+ return TRUE; -+} -+ -+static ExaGlyphCacheResult -+exaGlyphCacheBufferGlyph(ScreenPtr pScreen, -+ ExaGlyphCachePtr cache, -+ ExaGlyphBufferPtr buffer, -+ GlyphPtr pGlyph, -+ int xGlyph, -+ int yGlyph) -+{ -+ ExaCompositeRectPtr rect; -+ int pos; -+ -+ if (buffer->source && buffer->source != cache->picture) -+ return ExaGlyphNeedFlush; -+ -+ if (!cache->picture) { -+ if (!exaRealizeGlyphCaches(pScreen, cache->format)) -+ return ExaGlyphFail; -+ } -+ -+ DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n", -+ cache->glyphWidth, cache->glyphHeight, cache->format == PICT_a8 ? "A" : "ARGB", -+ (long)*(CARD32 *) pGlyph->sha1)); -+ -+ pos = exaGlyphCacheHashLookup(cache, pGlyph); -+ if (pos != -1) { -+ DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); -+ } else { -+ if (cache->glyphCount < cache->size) { -+ /* Space remaining; we fill from the start */ -+ pos = cache->glyphCount; -+ cache->glyphCount++; -+ DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); -+ -+ exaGlyphCacheHashInsert(cache, pGlyph, pos); -+ -+ } else { -+ /* Need to evict an entry. We have to see if any glyphs -+ * already in the output buffer were at this position in -+ * the cache -+ */ -+ -+ pos = cache->evictionPosition; -+ DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); -+ if (buffer->count) { -+ int x, y; -+ int i; -+ -+ x = CACHE_X(pos); -+ y = CACHE_Y(pos); -+ -+ for (i = 0; i < buffer->count; i++) { -+ if (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y) { -+ DBG_GLYPH_CACHE((" must flush buffer\n")); -+ return ExaGlyphNeedFlush; -+ } -+ } -+ } -+ -+ /* OK, we're all set, swap in the new glyph */ -+ exaGlyphCacheHashRemove(cache, pos); -+ exaGlyphCacheHashInsert(cache, pGlyph, pos); -+ -+ /* And pick a new eviction position */ -+ cache->evictionPosition = rand() % cache->size; -+ } -+ -+ /* Now actually upload the glyph into the cache picture; if -+ * we can't do it with UploadToScreen (because the glyph is -+ * offscreen, etc), we fall back to CompositePicture. -+ */ -+ if (!exaGlyphCacheUploadGlyph(pScreen, cache, pos, pGlyph)) { -+ CompositePicture (PictOpSrc, -+ GlyphPicture(pGlyph)[pScreen->myNum], -+ None, -+ cache->picture, -+ 0, 0, -+ 0, 0, -+ CACHE_X(pos), -+ CACHE_Y(pos), -+ pGlyph->info.width, -+ pGlyph->info.height); -+ } -+ -+ } -+ -+ -+ buffer->source = cache->picture; -+ -+ rect = &buffer->rects[buffer->count]; -+ rect->xSrc = CACHE_X(pos); -+ rect->ySrc = CACHE_Y(pos); -+ rect->xDst = xGlyph - pGlyph->info.x; -+ rect->yDst = yGlyph - pGlyph->info.y; -+ rect->width = pGlyph->info.width; -+ rect->height = pGlyph->info.height; -+ -+ buffer->count++; -+ -+ return ExaGlyphSuccess; -+} -+ -+#undef CACHE_X -+#undef CACHE_Y -+ -+static ExaGlyphCacheResult -+exaBufferGlyph(ScreenPtr pScreen, -+ ExaGlyphBufferPtr buffer, -+ GlyphPtr pGlyph, -+ int xGlyph, -+ int yGlyph) -+{ -+ ExaScreenPriv(pScreen); -+ unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format; -+ int width = pGlyph->info.width; -+ int height = pGlyph->info.height; -+ ExaCompositeRectPtr rect; -+ PicturePtr source; -+ int i; -+ -+ if (buffer->count == GLYPH_BUFFER_SIZE) -+ return ExaGlyphNeedFlush; -+ -+ if (PICT_FORMAT_BPP(format) == 1) -+ format = PICT_a8; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (format == cache->format && -+ width <= cache->glyphWidth && -+ height <= cache->glyphHeight) { -+ ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr->glyphCaches[i], -+ buffer, -+ pGlyph, xGlyph, yGlyph); -+ switch (result) { -+ case ExaGlyphFail: -+ break; -+ case ExaGlyphSuccess: -+ case ExaGlyphNeedFlush: -+ return result; -+ } -+ } -+ } -+ -+ /* Couldn't find the glyph in the cache, use the glyph picture directly */ -+ -+ source = GlyphPicture(pGlyph)[pScreen->myNum]; -+ if (buffer->source && buffer->source != source) -+ return ExaGlyphNeedFlush; -+ -+ buffer->source = source; -+ -+ rect = &buffer->rects[buffer->count]; -+ rect->xSrc = 0; -+ rect->ySrc = 0; -+ rect->xDst = xGlyph - pGlyph->info.x; -+ rect->yDst = yGlyph - pGlyph->info.y; -+ rect->width = pGlyph->info.width; -+ rect->height = pGlyph->info.height; -+ -+ buffer->count++; -+ -+ return ExaGlyphSuccess; -+} -+ -+static void -+exaGlyphsToMask(PicturePtr pMask, -+ ExaGlyphBufferPtr buffer) -+{ -+ exaCompositeRects(PictOpAdd, buffer->source, pMask, -+ buffer->count, buffer->rects); -+ -+ buffer->count = 0; -+ buffer->source = NULL; -+} -+ -+static void -+exaGlyphsToDst(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ ExaGlyphBufferPtr buffer, -+ INT16 xSrc, -+ INT16 ySrc, -+ INT16 xDst, -+ INT16 yDst) -+{ -+ int i; -+ -+ for (i = 0; i < buffer->count; i++) { -+ ExaCompositeRectPtr rect = &buffer->rects[i]; -+ -+ CompositePicture (op, -+ pSrc, -+ buffer->source, -+ pDst, -+ xSrc + rect->xDst - xDst, -+ ySrc + rect->yDst - yDst, -+ rect->xSrc, -+ rect->ySrc, -+ rect->xDst, -+ rect->yDst, -+ rect->width, -+ rect->height); -+ } -+ -+ buffer->count = 0; -+ buffer->source = NULL; -+} -+ -+/* Cut and paste from render/glyph.c - probably should export it instead */ -+static void -+GlyphExtents (int nlist, -+ GlyphListPtr list, -+ GlyphPtr *glyphs, -+ BoxPtr extents) -+{ -+ int x1, x2, y1, y2; -+ int n; -+ GlyphPtr glyph; -+ int x, y; -+ -+ x = 0; -+ y = 0; -+ extents->x1 = MAXSHORT; -+ extents->x2 = MINSHORT; -+ extents->y1 = MAXSHORT; -+ extents->y2 = MINSHORT; -+ while (nlist--) -+ { -+ x += list->xOff; -+ y += list->yOff; -+ n = list->len; -+ list++; -+ while (n--) -+ { -+ glyph = *glyphs++; -+ x1 = x - glyph->info.x; -+ if (x1 < MINSHORT) -+ x1 = MINSHORT; -+ y1 = y - glyph->info.y; -+ if (y1 < MINSHORT) -+ y1 = MINSHORT; -+ x2 = x1 + glyph->info.width; -+ if (x2 > MAXSHORT) -+ x2 = MAXSHORT; -+ y2 = y1 + glyph->info.height; -+ if (y2 > MAXSHORT) -+ y2 = MAXSHORT; -+ if (x1 < extents->x1) -+ extents->x1 = x1; -+ if (x2 > extents->x2) -+ extents->x2 = x2; -+ if (y1 < extents->y1) -+ extents->y1 = y1; -+ if (y2 > extents->y2) -+ extents->y2 = y2; -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ } -+ } -+} -+ -+/** -+ * Returns TRUE if the glyphs in the lists intersect. Only checks based on -+ * bounding box, which appears to be good enough to catch most cases at least. -+ */ -+static Bool -+exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) -+{ -+ int x1, x2, y1, y2; -+ int n; -+ GlyphPtr glyph; -+ int x, y; -+ BoxRec extents; -+ Bool first = TRUE; -+ -+ x = 0; -+ y = 0; -+ while (nlist--) { -+ x += list->xOff; -+ y += list->yOff; -+ n = list->len; -+ list++; -+ while (n--) { -+ glyph = *glyphs++; -+ -+ if (glyph->info.width == 0 || glyph->info.height == 0) { -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ continue; -+ } -+ -+ x1 = x - glyph->info.x; -+ if (x1 < MINSHORT) -+ x1 = MINSHORT; -+ y1 = y - glyph->info.y; -+ if (y1 < MINSHORT) -+ y1 = MINSHORT; -+ x2 = x1 + glyph->info.width; -+ if (x2 > MAXSHORT) -+ x2 = MAXSHORT; -+ y2 = y1 + glyph->info.height; -+ if (y2 > MAXSHORT) -+ y2 = MAXSHORT; -+ -+ if (first) { -+ extents.x1 = x1; -+ extents.y1 = y1; -+ extents.x2 = x2; -+ extents.y2 = y2; -+ first = FALSE; -+ } else { -+ if (x1 < extents.x2 && x2 > extents.x1 && -+ y1 < extents.y2 && y2 > extents.y1) -+ { -+ return TRUE; -+ } -+ -+ if (x1 < extents.x1) -+ extents.x1 = x1; -+ if (x2 > extents.x2) -+ extents.x2 = x2; -+ if (y1 < extents.y1) -+ extents.y1 = y1; -+ if (y2 > extents.y2) -+ extents.y2 = y2; -+ } -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ } -+ } -+ -+ return FALSE; -+} -+ -+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) -+ -+void -+exaGlyphs (CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ PictFormatPtr maskFormat, -+ INT16 xSrc, -+ INT16 ySrc, -+ int nlist, -+ GlyphListPtr list, -+ GlyphPtr *glyphs) -+{ -+ PicturePtr pPicture; -+ PixmapPtr pMaskPixmap = 0; -+ PicturePtr pMask; -+ ScreenPtr pScreen = pDst->pDrawable->pScreen; -+ int width = 0, height = 0; -+ int x, y; -+ int xDst = list->xOff, yDst = list->yOff; -+ int n; -+ GlyphPtr glyph; -+ int error; -+ BoxRec extents = {0, 0, 0, 0}; -+ CARD32 component_alpha; -+ ExaGlyphBuffer buffer; -+ -+ /* If we don't have a mask format but all the glyphs have the same format -+ * and don't intersect, use the glyph format as mask format for the full -+ * benefits of the glyph cache. -+ */ -+ if (!maskFormat) { -+ Bool sameFormat = TRUE; -+ int i; -+ -+ maskFormat = list[0].format; -+ -+ for (i = 0; i < nlist; i++) { -+ if (maskFormat->format != list[i].format->format) { -+ sameFormat = FALSE; -+ break; -+ } -+ } -+ -+ if (!sameFormat || (maskFormat->depth != 1 && -+ exaGlyphsIntersect(nlist, list, glyphs))) { -+ maskFormat = NULL; -+ } -+ } -+ -+ if (maskFormat) -+ { -+ GCPtr pGC; -+ xRectangle rect; -+ -+ GlyphExtents (nlist, list, glyphs, &extents); -+ -+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) -+ return; -+ width = extents.x2 - extents.x1; -+ height = extents.y2 - extents.y1; -+ -+ if (maskFormat->depth == 1) { -+ PictFormatPtr a8Format = PictureMatchFormat (pScreen, 8, PICT_a8); -+ -+ if (a8Format) -+ maskFormat = a8Format; -+ } -+ -+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, -+ maskFormat->depth, -+ CREATE_PIXMAP_USAGE_SCRATCH); -+ if (!pMaskPixmap) -+ return; -+ component_alpha = NeedsComponent(maskFormat->format); -+ pMask = CreatePicture (0, &pMaskPixmap->drawable, -+ maskFormat, CPComponentAlpha, &component_alpha, -+ serverClient, &error); -+ if (!pMask) -+ { -+ (*pScreen->DestroyPixmap) (pMaskPixmap); -+ return; -+ } -+ pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); -+ ValidateGC (&pMaskPixmap->drawable, pGC); -+ rect.x = 0; -+ rect.y = 0; -+ rect.width = width; -+ rect.height = height; -+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); -+ FreeScratchGC (pGC); -+ x = -extents.x1; -+ y = -extents.y1; -+ } -+ else -+ { -+ pMask = pDst; -+ x = 0; -+ y = 0; -+ } -+ buffer.count = 0; -+ buffer.source = NULL; -+ while (nlist--) -+ { -+ x += list->xOff; -+ y += list->yOff; -+ n = list->len; -+ while (n--) -+ { -+ glyph = *glyphs++; -+ pPicture = GlyphPicture (glyph)[pScreen->myNum]; -+ -+ if (glyph->info.width > 0 && glyph->info.height > 0 && -+ exaBufferGlyph(pScreen, &buffer, glyph, x, y) == ExaGlyphNeedFlush) -+ { -+ if (maskFormat) -+ exaGlyphsToMask(pMask, &buffer); -+ else -+ exaGlyphsToDst(op, pSrc, pDst, &buffer, -+ xSrc, ySrc, xDst, yDst); -+ -+ exaBufferGlyph(pScreen, &buffer, glyph, x, y); -+ } -+ -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ } -+ list++; -+ } -+ -+ if (maskFormat) -+ exaGlyphsToMask(pMask, &buffer); -+ else -+ exaGlyphsToDst(op, pSrc, pDst, &buffer, -+ xSrc, ySrc, xDst, yDst); -+ -+ if (maskFormat) -+ { -+ x = extents.x1; -+ y = extents.y1; -+ CompositePicture (op, -+ pSrc, -+ pMask, -+ pDst, -+ xSrc + x - xDst, -+ ySrc + y - yDst, -+ 0, 0, -+ x, y, -+ width, height); -+ FreePicture ((pointer) pMask, (XID) 0); -+ (*pScreen->DestroyPixmap) (pMaskPixmap); -+ } -+} -diff --git a/exa/exa_migration.c b/exa/exa_migration.c -index b7cc062..8f000e9 100644 ---- a/exa/exa_migration.c -+++ b/exa/exa_migration.c -@@ -33,8 +33,6 @@ - #include - - #include "exa_priv.h" --#include --#include "dixfontstr.h" - #include "exa.h" - #include "cw.h" - -@@ -45,6 +43,39 @@ - #endif - - /** -+ * Returns TRUE if the pixmap has damage. -+ * EXA only migrates the parts of a destination -+ * that are affected by rendering. -+ * It uses the current damage as indication. -+ * So anything that does not need to be updated won't be. -+ * For clarity this seperate function was made. -+ * Note that some situations don't use this, -+ * because their calls are wrapped by the damage layer. -+ */ -+Bool -+exaDamageDestForMigration(DrawablePtr pDrawable, PixmapPtr pPix, RegionPtr region) -+{ -+ ScreenPtr pScreen = pDrawable->pScreen; -+ (void) pScreen; /* the macros don't use pScreen currently */ -+ ExaPixmapPriv (pPix); -+ int x_offset, y_offset; -+ RegionPtr pending_damage; -+ -+ if (!pExaPixmap->pDamage) -+ return FALSE; -+ -+ exaGetDrawableDeltas(pDrawable, pPix, &x_offset, &y_offset); -+ -+ REGION_TRANSLATE(pScreen, region, x_offset, y_offset); -+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ REGION_UNION(pScreen, pending_damage, pending_damage, region); -+ /* Restore region as we got it. */ -+ REGION_TRANSLATE(pScreen, region, -x_offset, -y_offset); -+ -+ return TRUE; -+} -+ -+/** - * Returns TRUE if the pixmap is not movable. This is the case where it's a - * fake pixmap for the frontbuffer (no pixmap private) or it's a scratch - * pixmap created by some other X Server internals (the score says it's -@@ -212,9 +243,9 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, - pBox->x1, pBox->y1, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1, -- pExaPixmap->sys_ptr -+ (char *) (pExaPixmap->sys_ptr - + pBox->y1 * pExaPixmap->sys_pitch -- + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8, -+ + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8), - pExaPixmap->sys_pitch)) - { - if (!access_prepared) { -@@ -303,6 +334,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) - ExaScreenPriv (pScreen); - ExaPixmapPriv (pPixmap); - -+ if (migrate->as_dst) -+ pExaPixmap->pendingDamage = TRUE; -+ - /* If we're VT-switched away, no touching card memory allowed. */ - if (pExaScr->swappedOut) - return; -@@ -371,6 +405,9 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate) - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - -+ if (migrate->as_dst) -+ pExaPixmap->pendingDamage = TRUE; -+ - if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap)) - return; - -diff --git a/exa/exa_priv.h b/exa/exa_priv.h -index 387e751..f0696b0 100644 ---- a/exa/exa_priv.h -+++ b/exa/exa_priv.h -@@ -61,6 +61,7 @@ - #define DEBUG_MIGRATE 0 - #define DEBUG_PIXMAP 0 - #define DEBUG_OFFSCREEN 0 -+#define DEBUG_GLYPH_CACHE 0 - - #if DEBUG_TRACE_FALL - #define EXA_FALLBACK(x) \ -@@ -95,6 +96,38 @@ enum ExaMigrationHeuristic { - ExaMigrationSmart - }; - -+typedef struct { -+ unsigned char sha1[20]; -+} ExaCachedGlyphRec, *ExaCachedGlyphPtr; -+ -+typedef struct { -+ /* The identity of the cache, statically configured at initialization */ -+ unsigned int format; -+ int glyphWidth; -+ int glyphHeight; -+ -+ int size; /* Size of cache; eventually this should be dynamically determined */ -+ -+ /* Hash table mapping from glyph sha1 to position in the glyph; we use -+ * open addressing with a hash table size determined based on size and large -+ * enough so that we always have a good amount of free space, so we can -+ * use linear probing. (Linear probing is preferrable to double hashing -+ * here because it allows us to easily remove entries.) -+ */ -+ int *hashEntries; -+ int hashSize; -+ -+ ExaCachedGlyphPtr glyphs; -+ int glyphCount; /* Current number of glyphs */ -+ -+ PicturePtr picture; /* Where the glyphs of the cache are stored */ -+ int yOffset; /* y location within the picture where the cache starts */ -+ int columns; /* Number of columns the glyphs are layed out in */ -+ int evictionPosition; /* Next random position to evict a glyph */ -+} ExaGlyphCacheRec, *ExaGlyphCachePtr; -+ -+#define EXA_NUM_GLYPH_CACHES 4 -+ - typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); - typedef struct { - ExaDriverPtr info; -@@ -114,7 +147,6 @@ typedef struct { - TrianglesProcPtr SavedTriangles; - GlyphsProcPtr SavedGlyphs; - TrapezoidsProcPtr SavedTrapezoids; -- AddTrapsProcPtr SavedAddTraps; - #endif - - Bool swappedOut; -@@ -123,6 +155,8 @@ typedef struct { - unsigned disableFbCount; - Bool optimize_migration; - unsigned offScreenCounter; -+ -+ ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; - } ExaScreenPrivRec, *ExaScreenPrivPtr; - - /* -@@ -192,6 +226,7 @@ typedef struct { - * location. - */ - DamagePtr pDamage; -+ Bool pendingDamage; - /** - * The valid regions mark the valid bits (at least, as they're derived from - * damage, which may be overreported) of a pixmap's system and FB copies. -@@ -210,18 +245,21 @@ typedef struct _ExaMigrationRec { - RegionPtr pReg; - } ExaMigrationRec, *ExaMigrationPtr; - -+typedef struct { -+ INT16 xSrc; -+ INT16 ySrc; -+ INT16 xDst; -+ INT16 yDst; -+ INT16 width; -+ INT16 height; -+} ExaCompositeRectRec, *ExaCompositeRectPtr; -+ - /** - * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place - * to set EXA options or hook in screen functions to handle using EXA as the AA. - */ - void exaDDXDriverInit (ScreenPtr pScreen); - --void --exaPrepareAccessWindow(WindowPtr pWin); -- --void --exaFinishAccessWindow(WindowPtr pWin); -- - /* exa_unaccel.c */ - void - exaPrepareAccessGC(GCPtr pGC); -@@ -294,13 +332,6 @@ ExaCheckGetSpans (DrawablePtr pDrawable, - int nspans, - char *pdstStart); - --void --ExaCheckAddTraps (PicturePtr pPicture, -- INT16 x_off, -- INT16 y_off, -- int ntrap, -- xTrap *traps); -- - /* exa_accel.c */ - - static _X_INLINE Bool -@@ -419,6 +450,13 @@ exaComposite(CARD8 op, - CARD16 height); - - void -+exaCompositeRects(CARD8 op, -+ PicturePtr Src, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects); -+ -+void - exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntrap, xTrapezoid *traps); -@@ -428,6 +466,13 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntri, xTriangle *tris); - -+/* exa_glyph.c */ -+void -+exaGlyphsInit(ScreenPtr pScreen); -+ -+void -+exaGlyphsFini (ScreenPtr pScreen); -+ - void - exaGlyphs (CARD8 op, - PicturePtr pSrc, -@@ -446,4 +491,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - void - exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area); - -+Bool -+exaDamageDestForMigration(DrawablePtr pDrawable, PixmapPtr pPix, RegionPtr region); -+ - #endif /* EXAPRIV_H */ -diff --git a/exa/exa_render.c b/exa/exa_render.c -index 1d7b897..bafa309 100644 ---- a/exa/exa_render.c -+++ b/exa/exa_render.c -@@ -332,6 +332,228 @@ exaTryDriverSolidFill(PicturePtr pSrc, - } - - static int -+exaTryDriverCompositeRects(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects) -+{ -+ ExaScreenPriv (pDst->pDrawable->pScreen); -+ int src_off_x, src_off_y, dst_off_x, dst_off_y; -+ PixmapPtr pSrcPix, pDstPix; -+ ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; -+ struct _Pixmap scratch; -+ ExaMigrationRec pixmaps[2]; -+ -+ if (!pExaScr->info->PrepareComposite) -+ return -1; -+ -+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); -+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix); -+ -+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable); -+ pDstExaPix = ExaGetPixmapPriv(pDstPix); -+ -+ /* Check whether the accelerator can use these pixmaps. -+ * FIXME: If it cannot, use temporary pixmaps so that the drawing -+ * happens within limits. -+ */ -+ if (pSrcExaPix->accel_blocked || -+ pDstExaPix->accel_blocked) -+ { -+ return -1; -+ } -+ -+ if (pExaScr->info->CheckComposite && -+ !(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst)) -+ { -+ return -1; -+ } -+ -+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); -+ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = exaOpReadsDestination(op); -+ pixmaps[0].pPix = pDstPix; -+ pixmaps[0].pReg = NULL; -+ pixmaps[1].as_dst = FALSE; -+ pixmaps[1].as_src = TRUE; -+ pixmaps[1].pPix = pSrcPix; -+ pixmaps[1].pReg = NULL; -+ exaDoMigration(pixmaps, 2, TRUE); -+ -+ pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); -+ if (!exaPixmapIsOffscreen(pDstPix)) -+ return 0; -+ -+ if (!pSrcPix && pExaScr->info->UploadToScratch) -+ { -+ pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); -+ if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch)) -+ pSrcPix = &scratch; -+ } -+ -+ if (!pSrcPix) -+ return 0; -+ -+ if (!(*pExaScr->info->PrepareComposite) (op, pSrc, NULL, pDst, pSrcPix, -+ NULL, pDstPix)) -+ return -1; -+ -+ while (nrect--) -+ { -+ INT16 xDst = rects->xDst + pDst->pDrawable->x; -+ INT16 yDst = rects->yDst + pDst->pDrawable->y; -+ INT16 xSrc = rects->xSrc + pSrc->pDrawable->x; -+ INT16 ySrc = rects->ySrc + pSrc->pDrawable->y; -+ -+ RegionRec region; -+ BoxPtr pbox; -+ int nbox; -+ -+ if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, -+ xSrc, ySrc, 0, 0, xDst, yDst, -+ rects->width, rects->height)) -+ goto next_rect; -+ -+ REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); -+ -+ nbox = REGION_NUM_RECTS(®ion); -+ pbox = REGION_RECTS(®ion); -+ -+ xSrc = xSrc + src_off_x - xDst - dst_off_x; -+ ySrc = ySrc + src_off_y - yDst - dst_off_y; -+ -+ while (nbox--) -+ { -+ (*pExaScr->info->Composite) (pDstPix, -+ pbox->x1 + xSrc, -+ pbox->y1 + ySrc, -+ 0, 0, -+ pbox->x1, -+ pbox->y1, -+ pbox->x2 - pbox->x1, -+ pbox->y2 - pbox->y1); -+ pbox++; -+ } -+ -+ next_rect: -+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); -+ -+ rects++; -+ } -+ -+ (*pExaScr->info->DoneComposite) (pDstPix); -+ exaMarkSync(pDst->pDrawable->pScreen); -+ -+ return 1; -+} -+ -+/** -+ * Copy a number of rectangles from source to destination in a single -+ * operation. This is specialized for building a glyph mask: we don'y -+ * have a mask argument because we don't need it for that, and we -+ * don't have he special-case fallbacks found in exaComposite() - if the -+ * driver can support it, we use the driver functionality, otherwise we -+ * fallback straight to software. -+ */ -+void -+exaCompositeRects(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects) -+{ -+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable); -+ ExaPixmapPriv(pPixmap); -+ RegionRec region; -+ int n; -+ ExaCompositeRectPtr r; -+ -+ if (pExaPixmap->pDamage) { -+ int x1 = MAXSHORT; -+ int y1 = MAXSHORT; -+ int x2 = MINSHORT; -+ int y2 = MINSHORT; -+ BoxRec box; -+ -+ /* We have to manage the damage ourselves, since CompositeRects isn't -+ * something in the screen that can be managed by the damage extension, -+ * and EXA depends on damage to track what needs to be migrated between -+ * offscreen and onscreen. -+ */ -+ -+ /* Compute the overall extents of the composited region - we're making -+ * the assumption here that we are compositing a bunch of glyphs that -+ * cluster closely together and damaging each glyph individually would -+ * be a loss compared to damaging the bounding box. -+ */ -+ n = nrect; -+ r = rects; -+ while (n--) { -+ int rect_x2 = r->xDst + r->width; -+ int rect_y2 = r->yDst + r->width; -+ -+ if (r->xDst < x1) x1 = r->xDst; -+ if (r->xDst < y1) y1 = r->xDst; -+ if (rect_x2 > x2) x2 = rect_x2; -+ if (rect_y2 > y2) y2 = rect_y2; -+ -+ r++; -+ } -+ -+ if (x2 <= x1 && y2 <= y1) -+ return; -+ -+ box.x1 = x1; -+ box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT; -+ box.y1 = y1; -+ box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT; -+ -+ /* The pixmap migration code relies on pendingDamage indicating -+ * the bounds of the current rendering, so we need to force -+ * the actual damage into that region before we do anything, and -+ * (see use of DamagePendingRegion in exaCopyDirty) -+ */ -+ -+ REGION_INIT(pScreen, ®ion, &box, 1); -+ -+ exaDamageDestForMigration(pDst->pDrawable, pPixmap, ®ion); -+ } -+ -+ /************************************************************/ -+ -+ ValidatePicture (pSrc); -+ ValidatePicture (pDst); -+ -+ if (exaTryDriverCompositeRects(op, pSrc, pDst, nrect, rects) != 1) { -+ n = nrect; -+ r = rects; -+ while (n--) { -+ ExaCheckComposite (op, pSrc, NULL, pDst, -+ r->xSrc, r->ySrc, -+ 0, 0, -+ r->xDst, r->yDst, -+ r->width, r->height); -+ r++; -+ } -+ } -+ -+ /************************************************************/ -+ -+ if (pExaPixmap->pDamage) { -+ /* Now we have to flush the damage out from pendingDamage => damage -+ * Calling DamageDamageRegion has that effect. (We could pass -+ * in an empty region here, but we pass in the same region we -+ * use above; the effect is the same.) -+ */ -+ -+ DamageDamageRegion(pDst->pDrawable, ®ion); -+ REGION_UNINIT(pScreen, ®ion); -+ } -+} -+ -+static int - exaTryDriverComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, -@@ -843,22 +1065,16 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PixmapPtr pixmap = exaGetDrawablePixmap (pDraw); - ExaPixmapPriv (pixmap); - RegionRec migration; -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- int xoff, yoff; -- -- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); - -- xoff += pDraw->x; -- yoff += pDraw->y; -+ if (pExaPixmap->pDamage) { -+ bounds.x1 += pDraw->x; -+ bounds.y1 += pDraw->y; -+ bounds.x2 += pDraw->x; -+ bounds.y2 += pDraw->y; - -- bounds.x1 += xoff; -- bounds.y1 += yoff; -- bounds.x2 += xoff; -- bounds.y2 += yoff; -- -- REGION_INIT(pScreen, &migration, &bounds, 1); -- REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -- REGION_UNINIT(pScreen, &migration); -+ REGION_INIT(pScreen, &migration, &bounds, 1); -+ exaDamageDestForMigration(pDraw, pixmap, &migration); -+ } - - exaPrepareAccess(pDraw, EXA_PREPARE_DEST); - -@@ -866,6 +1082,13 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0); - - exaFinishAccess(pDraw, EXA_PREPARE_DEST); -+ -+ /* Damage manually, because Trapezoids expects to hit Composite normally. */ -+ /* Composite is wrapped by damage, but Trapezoids isn't. */ -+ if (pExaPixmap->pDamage) { -+ DamageDamageRegion(pDraw, &migration); -+ REGION_UNINIT(pScreen, &migration); -+ } - } - else if (maskFormat) - { -@@ -946,26 +1169,27 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PixmapPtr pixmap = exaGetDrawablePixmap (pDraw); - ExaPixmapPriv (pixmap); - RegionRec migration; -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- int xoff, yoff; -- -- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); -- -- xoff += pDraw->x; -- yoff += pDraw->y; - -- bounds.x1 += xoff; -- bounds.y1 += yoff; -- bounds.x2 += xoff; -- bounds.y2 += yoff; -+ if (pExaPixmap->pDamage) { -+ bounds.x1 += pDraw->x; -+ bounds.y1 += pDraw->y; -+ bounds.x2 += pDraw->x; -+ bounds.y2 += pDraw->y; - -- REGION_INIT(pScreen, &migration, &bounds, 1); -- REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -- REGION_UNINIT(pScreen, &migration); -+ REGION_INIT(pScreen, &migration, &bounds, 1); -+ exaDamageDestForMigration(pDraw, pixmap, &migration); -+ } - - exaPrepareAccess(pDraw, EXA_PREPARE_DEST); - (*ps->AddTriangles) (pDst, 0, 0, ntri, tris); - exaFinishAccess(pDraw, EXA_PREPARE_DEST); -+ -+ /* Damage manually, because Triangles expects to hit Composite normally. */ -+ /* Composite is wrapped by damage, but Triangles isn't. */ -+ if (pExaPixmap->pDamage) { -+ DamageDamageRegion(pDraw, &migration); -+ REGION_UNINIT(pScreen, &migration); -+ } - } - else if (maskFormat) - { -diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c -index d7bd06c..d5d6a30 100644 ---- a/exa/exa_unaccel.c -+++ b/exa/exa_unaccel.c -@@ -97,12 +97,15 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits) - { -+ ExaPixmapPriv(exaGetDrawablePixmap(pDrawable)); -+ - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, - pGC->alu)) - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - else -- ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST); -+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ? -+ DamagePendingRegion(pExaPixmap->pDamage) : NULL); - fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - } -@@ -350,20 +353,6 @@ ExaCheckComposite (CARD8 op, - REGION_UNINIT(pScreen, ®ion); - } - --void --ExaCheckAddTraps (PicturePtr pPicture, -- INT16 x_off, -- INT16 y_off, -- int ntrap, -- xTrap *traps) --{ -- EXA_FALLBACK(("to pict %p (%c)\n", -- exaDrawableLocation(pPicture->pDrawable))); -- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); -- fbAddTraps (pPicture, x_off, y_off, ntrap, traps); -- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); --} -- - /** - * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps - * that happen to be 1x1. Pixmap must be at least 8bpp. -@@ -373,23 +362,22 @@ ExaCheckAddTraps (PicturePtr pPicture, - CARD32 - exaGetPixmapFirstPixel (PixmapPtr pPixmap) - { -- ExaScreenPriv(pPixmap->drawable.pScreen); - CARD32 pixel; - void *fb; - Bool need_finish = FALSE; - BoxRec box; - RegionRec migration; - ExaPixmapPriv (pPixmap); -- Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box); -- Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, -- &box); -+ Bool sys_valid = pExaPixmap->pDamage && -+ !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box); -+ Bool damaged = pExaPixmap->pDamage && -+ miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box); - Bool offscreen = exaPixmapIsOffscreen(pPixmap); - - fb = pExaPixmap->sys_ptr; - - /* Try to avoid framebuffer readbacks */ -- if (pExaScr->info->CreatePixmap || -- (!offscreen && !sys_valid && !damaged) || -+ if ((!offscreen && !sys_valid && !damaged) || - (offscreen && (!sys_valid || damaged))) - { - box.x1 = 0; -diff --git a/hw/xfree86/exa/exa.man.pre b/hw/xfree86/exa/exa.man.pre -index 14859bc..31e1cfe 100644 ---- a/hw/xfree86/exa/exa.man.pre -+++ b/hw/xfree86/exa/exa.man.pre -@@ -31,12 +31,6 @@ Disables acceleration of downloading of pixmap data from the framebuffer. - Not usable with drivers which rely on DownloadFromScreen succeeding. - Default: No. - .TP --.BI "Option \*qEXAOptimizeMigration\*q \*q" boolean \*q --Enables an additional optimization for migration of destination pixmaps. This --may improve performance in some cases (e.g. when switching virtual desktops with --no compositing manager) but causes corruption in others (e.g. when starting --compiz). Default: No. --.TP - .BI "Option \*qMigrationHeuristic\*q \*q" anystr \*q - Chooses an alternate pixmap migration heuristic, for debugging purposes. The - default is intended to be the best performing one for general use, though others -diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c -index e18da0a..4a8d8f2 100644 ---- a/hw/xfree86/exa/examodule.c -+++ b/hw/xfree86/exa/examodule.c -@@ -145,7 +145,7 @@ exaDDXDriverInit(ScreenPtr pScreen) - pExaScr->optimize_migration = - xf86ReturnOptValBool(pScreenPriv->options, - EXAOPT_OPTIMIZE_MIGRATION, -- FALSE); -+ TRUE); - } - - if (xf86ReturnOptValBool(pScreenPriv->options, -@@ -179,13 +179,6 @@ exaDDXDriverInit(ScreenPtr pScreen) - - } - --/*ARGSUSED*/ --static const OptionInfoRec * --EXAAvailableOptions(void *unused) --{ -- return (EXAOptions); --} -- - static XF86ModuleVersionInfo exaVersRec = - { - "exa", --- -1.6.0.3 - diff --git a/xserver-1.5.2-more-sanity-checks.patch b/xserver-1.5.2-more-sanity-checks.patch deleted file mode 100644 index f9fda89..0000000 --- a/xserver-1.5.2-more-sanity-checks.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 30c077f228f563e4e1f4115b345577d9fd393b68 Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Fri, 24 Oct 2008 15:06:49 +1030 -Subject: [PATCH] dix: extra sanity-checks against potential NULL-dereferences. #434807 - -Two minor code paths could potentially crash the server: -- if scr is NULL, we shouldn't try to dereference it. -- if GPE is called with buttons != 0 but the event is not a - ButtonPress or ButtonRelease, the button mapping may dereference a NULL - pointer. - -Admittedly the second should never happen, but better to guard against it. ---- - dix/getevents.c | 6 ++++++ - 1 files changed, 6 insertions(+), 0 deletions(-) - -diff --git a/dix/getevents.c b/dix/getevents.c -index 1e0edbf..923744d 100644 ---- a/dix/getevents.c -+++ b/dix/getevents.c -@@ -537,6 +537,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, - ScreenPtr scr = miPointerGetScreen(pDev); - - /* Sanity checks. */ -+ if (!scr) -+ return 0; -+ - if (type != MotionNotify && type != ButtonPress && type != ButtonRelease) - return 0; - -@@ -548,6 +551,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, - if (!pDev->valuator) - return 0; - -+ if (buttons && !pDev->button) -+ return 0; -+ - if (!coreOnly && pDev->coreEvents) - num_events = 2; - else --- -1.6.0.3 - diff --git a/xserver-1.5.99.3-ddx-rules.patch b/xserver-1.5.99.3-ddx-rules.patch deleted file mode 100644 index 0f88503..0000000 --- a/xserver-1.5.99.3-ddx-rules.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 9c5dd7337fa93fb1650cc017e523b939dcbf482a Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Wed, 03 Dec 2008 04:24:25 +0000 -Subject: Let the DDX decide on the XkbRulesDefaults. - -Rather than assuming rules in the CoreKeyboardProc, init the default rules in -InitCoreDevices, then re-use them later. - -In the xfree86 DDX, set the rules to "base" or "evdev", depending on whether -we'll load kbd or evdev. - -If we create a new MD, use pc105,us as default and re-use the rules file used -previously. - -Signed-off-by: Peter Hutterer ---- -diff --git a/dix/devices.c b/dix/devices.c -index 6b8cecb..9feca90 100644 ---- a/dix/devices.c -+++ b/dix/devices.c -@@ -526,7 +526,6 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what) - #ifdef XKB - if (!noXkbExtension) { - bzero(&names, sizeof(names)); -- XkbSetRulesDflts("base", "pc105", "us", NULL, NULL); - XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap, - CoreKeyboardBell, CoreKeyboardCtl); - } -diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c -index 1210a8f..9bf18b5 100644 ---- a/hw/xfree86/common/xf86Config.c -+++ b/hw/xfree86/common/xf86Config.c -@@ -1008,6 +1008,12 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) - xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices); - xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput); - -+ /* AEI on? Then we're not using kbd, so use the evdev rules set. */ -+#ifdef XKB -+ XkbSetRulesDflts(((xf86Info.allowEmptyInput) ? "evdev" : "base"), -+ "pc105", "us", NULL, NULL); -+#endif -+ - xf86Info.useDefaultFontPath = TRUE; - xf86Info.useDefaultFontPathFrom = X_DEFAULT; - if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) { --- -cgit v0.8.1-24-ge5fb diff --git a/xserver-1.5.99.3-offscreen-pixmaps.patch b/xserver-1.5.99.3-offscreen-pixmaps.patch deleted file mode 100644 index 9ce9913..0000000 --- a/xserver-1.5.99.3-offscreen-pixmaps.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 70e14e1dd95ba965ffd3264af1f2d4b207c67f73 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 7 Jan 2009 17:14:34 -0500 -Subject: [PATCH] XAA: turn off offscreen pixmaps by default. again. - ---- - hw/xfree86/xaa/xaaInitAccel.c | 9 ++++++--- - 1 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/hw/xfree86/xaa/xaaInitAccel.c b/hw/xfree86/xaa/xaaInitAccel.c -index 4087142..3b397dc 100644 ---- a/hw/xfree86/xaa/xaaInitAccel.c -+++ b/hw/xfree86/xaa/xaaInitAccel.c -@@ -41,7 +41,8 @@ typedef enum { - XAAOPT_WRITE_BITMAP, - XAAOPT_WRITE_PIXMAP, - XAAOPT_PIXMAP_CACHE, -- XAAOPT_OFFSCREEN_PIXMAPS -+ XAAOPT_OFFSCREEN_PIXMAPS, -+ XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE - } XAAOpts; - - static const OptionInfoRec XAAOptions[] = { -@@ -87,6 +88,8 @@ static const OptionInfoRec XAAOptions[] = { - OPTV_BOOLEAN, {0}, FALSE }, - {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps", - OPTV_BOOLEAN, {0}, FALSE }, -+ {XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE, "XaaOffscreenPixmaps", -+ OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, - OPTV_NONE, {0}, FALSE } - }; -@@ -525,8 +528,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) - #define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0) - - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy && -- !xf86ReturnOptValBool(options, XAAOPT_OFFSCREEN_PIXMAPS, -- FALSE)) { -+ xf86IsOptionSet(options, XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE)) -+ { - XAAMSG("\tOffscreen Pixmaps\n"); - } else { - infoRec->Flags &= ~OFFSCREEN_PIXMAPS; --- -1.6.0.3 - diff --git a/xserver-1.5.99.902-listen-for-hal.patch b/xserver-1.5.99.902-listen-for-hal.patch deleted file mode 100644 index 7d3cf80..0000000 --- a/xserver-1.5.99.902-listen-for-hal.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 9bd9e83179e863c8bd25da423d6c69f57c3317ba Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Wed, 4 Feb 2009 11:50:18 +1000 -Subject: [PATCH] config: if we can't connect to HAL, listen for a startup notification. - -If HAL isn't available when we try to connect, the registered NameOwnerChanged -signal handler waits until HAL is available. Once we connected to HAL, we -unregister the signal handler again. -This allows HAL to be started in parallel or after the server has started. - -Signed-off-by: Peter Hutterer ---- - config/hal.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 files changed, 105 insertions(+), 6 deletions(-) - -diff --git a/config/hal.c b/config/hal.c -index 8dfbb07..36fa839 100644 ---- a/config/hal.c -+++ b/config/hal.c -@@ -467,11 +467,10 @@ disconnect_hook(void *data) - info->system_bus = NULL; - } - --static void --connect_hook(DBusConnection *connection, void *data) -+static BOOL -+connect_and_register(DBusConnection *connection, struct config_hal_info *info) - { - DBusError error; -- struct config_hal_info *info = data; - char **devices; - int num_devices, i; - -@@ -479,8 +478,10 @@ connect_hook(DBusConnection *connection, void *data) - - dbus_error_init(&error); - -- if (!info->hal_ctx) -- info->hal_ctx = libhal_ctx_new(); -+ if (info->hal_ctx) -+ return TRUE; /* already registered, pretend we did something */ -+ -+ info->hal_ctx = libhal_ctx_new(); - if (!info->hal_ctx) { - LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n"); - goto out_err; -@@ -512,7 +513,7 @@ connect_hook(DBusConnection *connection, void *data) - - dbus_error_free(&error); - -- return; -+ return TRUE; - - out_ctx2: - if (!libhal_ctx_shutdown(info->hal_ctx, &error)) -@@ -526,6 +527,104 @@ out_err: - info->hal_ctx = NULL; - info->system_bus = NULL; - -+ return FALSE; -+} -+ -+ -+/** -+ * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime. -+ * -+ * NewOwnerChanged is send once when HAL shuts down, and once again when it -+ * comes back up. Message has three arguments, first is the name -+ * (org.freedesktop.Hal), the second one is the old owner, third one is new -+ * owner. -+ */ -+static DBusHandlerResult -+ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data) -+{ -+ int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -+ -+ if (dbus_message_is_signal(message, -+ "org.freedesktop.DBus", -+ "NameOwnerChanged")) { -+ DBusError error; -+ char *name, *old_owner, *new_owner; -+ -+ dbus_error_init(&error); -+ dbus_message_get_args(message, &error, -+ DBUS_TYPE_STRING, &name, -+ DBUS_TYPE_STRING, &old_owner, -+ DBUS_TYPE_STRING, &new_owner, -+ DBUS_TYPE_INVALID); -+ -+ if (dbus_error_is_set(&error)) { -+ ErrorF("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n", -+ error.name, error.message); -+ } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) { -+ -+ if (!old_owner || !strlen(old_owner)) { -+ DebugF("[config/hal] HAL startup detected.\n"); -+ if (connect_and_register(connection, (struct config_hal_info*)data)) -+ dbus_connection_unregister_object_path(connection, -+ "/org/freedesktop/DBus"); -+ else -+ ErrorF("[config/hal] Failed to connect to HAL bus.\n"); -+ } -+ -+ ret = DBUS_HANDLER_RESULT_HANDLED; -+ } -+ dbus_error_free(&error); -+ } -+ -+ return ret; -+} -+ -+/** -+ * Register a handler for the NameOwnerChanged signal. -+ */ -+static BOOL -+listen_for_startup(DBusConnection *connection, void *data) -+{ -+ DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, }; -+ DBusError error; -+ const char MATCH_RULE[] = "sender='org.freedesktop.DBus'," -+ "interface='org.freedesktop.DBus'," -+ "type='signal'," -+ "path='/org/freedesktop/DBus'," -+ "member='NameOwnerChanged'"; -+ int rc = FALSE; -+ -+ dbus_error_init(&error); -+ dbus_bus_add_match(connection, MATCH_RULE, &error); -+ if (!dbus_error_is_set(&error)) { -+ if (dbus_connection_register_object_path(connection, -+ "/org/freedesktop/DBus", -+ &vtable, -+ data)) -+ rc = TRUE; -+ else -+ ErrorF("[config/hal] cannot register object path.\n"); -+ } else { -+ ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name, -+ error.message); -+ ErrorF("[config/hal] cannot detect a HAL startup.\n"); -+ } -+ -+ dbus_error_free(&error); -+ -+ return rc; -+} -+ -+static void -+connect_hook(DBusConnection *connection, void *data) -+{ -+ struct config_hal_info *info = data; -+ -+ if (listen_for_startup(connection, data) && -+ connect_and_register(connection, info)) -+ dbus_connection_unregister_object_path(connection, -+ "/org/freedesktop/DBus"); -+ - return; - } - --- -1.6.0.6 - diff --git a/xserver-1.5.99.903-fontmod.h b/xserver-1.5.99.903-fontmod.h deleted file mode 100644 index 89adb0a..0000000 --- a/xserver-1.5.99.903-fontmod.h +++ /dev/null @@ -1,24 +0,0 @@ -From 24a1f522d52d9cf5720dad28107bea33e623fd7b Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 18 Feb 2009 15:33:14 -0500 -Subject: [PATCH] uninclude fontmod.h - ---- - hw/xfree86/loader/loaderProcs.h | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) - -diff --git a/hw/xfree86/loader/loaderProcs.h b/hw/xfree86/loader/loaderProcs.h -index 827f3a9..a10f0b3 100644 ---- a/hw/xfree86/loader/loaderProcs.h -+++ b/hw/xfree86/loader/loaderProcs.h -@@ -56,7 +56,6 @@ - #undef IN_LOADER - #define IN_LOADER - #include "xf86Module.h" --#include - - typedef struct module_desc { - struct module_desc *child; --- -1.6.1.3 - diff --git a/xserver-1.5.99.903-glx-visual-score.patch b/xserver-1.5.99.903-glx-visual-score.patch deleted file mode 100644 index 9b9169a..0000000 --- a/xserver-1.5.99.903-glx-visual-score.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4039603413f9f46d7f725463a70b4a51838e0049 Mon Sep 17 00:00:00 2001 -From: Ian Romanick -Date: Tue, 17 Feb 2009 08:27:32 -0800 -Subject: [PATCH 01/10] glx: Inialize best_score before calculating visual scores -MIME-Version: 1.0 -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: 8bit - -This bug was pointed out by Peter Åstrand. - -Signed-off-by: Ian Romanick ---- - glx/glxscreens.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/glx/glxscreens.c b/glx/glxscreens.c -index 87119fb..6f68b06 100644 ---- a/glx/glxscreens.c -+++ b/glx/glxscreens.c -@@ -354,7 +354,7 @@ static __GLXconfig * - pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual) - { - __GLXconfig *best = NULL, *config; -- int best_score; -+ int best_score = 0; - - for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { - int score = 0; --- -1.6.1.3 -