xserver: Branch 'XACE-SELINUX' - 119 commits

Eamon Walsh ewalsh at kemper.freedesktop.org
Thu May 24 07:44:55 PDT 2007


 GL/glx/glxcmds.c                            |   34 
 GL/glx/glxdrawable.h                        |    9 
 GL/glx/glxdri.c                             |  251 +
 GL/glx/glxext.c                             |   33 
 GL/glx/glxglcore.c                          |   16 
 GL/glx/glxserver.h                          |    8 
 GL/glx/indirect_dispatch.h                  |   14 
 GL/glx/indirect_size_get.c                  |    2 
 GL/glx/indirect_table.c                     |   19 
 GL/mesa/main/Makefile.am                    |    2 
 GL/mesa/shader/slang/Makefile.am            |    1 
 Xext/sync.c                                 |  119 
 config/config.c                             |   36 
 config/dbus-api                             |   22 
 configure.ac                                |   30 
 dix/devices.c                               |   35 
 dix/main.c                                  |    1 
 exa/exa.c                                   |   25 
 exa/exa.h                                   |    5 
 exa/exa_accel.c                             |  465 +--
 exa/exa_migration.c                         |   21 
 exa/exa_offscreen.c                         |    8 
 exa/exa_priv.h                              |   11 
 exa/exa_render.c                            |  178 -
 exa/exa_unaccel.c                           |   36 
 fb/Makefile.am                              |    1 
 fb/fbcompose.c                              | 3687 ----------------------------
 fb/fbmmx.c                                  | 1124 ++++++--
 fb/fbmmx.h                                  |   62 
 fb/fbpict.c                                 | 1588 ++----------
 fb/fbpict.h                                 |  236 -
 fb/fbtrap.c                                 |    3 
 hw/dmx/dmx-config.h                         |    2 
 hw/dmx/glxProxy/glxext.h                    |    2 
 hw/kdrive/Makefile.am                       |   12 
 hw/kdrive/ati/Makefile.am                   |    3 
 hw/kdrive/chips/Makefile.am                 |    3 
 hw/kdrive/ephyr/Makefile.am                 |    3 
 hw/kdrive/epson/Makefile.am                 |    3 
 hw/kdrive/fake/Makefile.am                  |    3 
 hw/kdrive/fbdev/Makefile.am                 |    3 
 hw/kdrive/i810/Makefile.am                  |    3 
 hw/kdrive/mach64/Makefile.am                |    3 
 hw/kdrive/mga/Makefile.am                   |    3 
 hw/kdrive/neomagic/Makefile.am              |    3 
 hw/kdrive/nvidia/Makefile.am                |    3 
 hw/kdrive/pm2/Makefile.am                   |    3 
 hw/kdrive/r128/Makefile.am                  |    3 
 hw/kdrive/sdl/Makefile.am                   |    3 
 hw/kdrive/sis300/Makefile.am                |    3 
 hw/kdrive/smi/Makefile.am                   |    3 
 hw/kdrive/vesa/Makefile.am                  |    3 
 hw/kdrive/via/Makefile.am                   |    3 
 hw/xfree86/common/xf86Config.c              |  140 -
 hw/xfree86/common/xf86Config.h              |   19 
 hw/xfree86/common/xf86Privstr.h             |    2 
 hw/xfree86/common/xf86Xinput.c              |   44 
 hw/xfree86/common/xf86Xinput.h              |    3 
 hw/xfree86/ddc/edid_modes.c                 |  361 --
 hw/xfree86/dixmods/Makefile.am              |    3 
 hw/xfree86/dixmods/afbmodule.c              |    1 
 hw/xfree86/dixmods/cfb32module.c            |    3 
 hw/xfree86/dixmods/cfbmodule.c              |    3 
 hw/xfree86/doc/man/xorg.conf.man.pre        |   19 
 hw/xfree86/dri/dri.c                        |   16 
 hw/xfree86/dri/dri.h                        |   13 
 hw/xfree86/modes/xf86Crtc.c                 |   22 
 hw/xfree86/modes/xf86Crtc.h                 |    4 
 hw/xfree86/modes/xf86EdidModes.c            |    5 
 hw/xfree86/modes/xf86RandR12.c              |    5 
 hw/xfree86/modes/xf86RandR12.h              |    3 
 hw/xfree86/modes/xf86Rename.h               |    9 
 hw/xfree86/modes/xf86Rotate.c               |   64 
 hw/xfree86/os-support/bus/Pci.c             |   14 
 hw/xfree86/os-support/bus/Pci.h             |    2 
 hw/xfree86/parser/Module.c                  |   17 
 hw/xfree86/parser/xf86Parser.h              |    2 
 hw/xfree86/parser/xf86tokens.h              |    1 
 hw/xfree86/xaa/xaaWideLine.c                |    4 
 hw/xgl/xglcompose.c                         |    2 
 hw/xwin/winmouse.c                          |    5 
 hw/xwin/winmultiwindowwm.c                  |    5 
 hw/xwin/winmultiwindowwndproc.c             |    9 
 hw/xwin/winwin32rootlesswndproc.c           |    5 
 hw/xwin/winwndproc.c                        |    5 
 include/dix-config.h.in                     |    3 
 include/misc.h                              |    2 
 include/miscstruct.h                        |    5 
 include/regionstr.h                         |   15 
 mi/Makefile.am                              |   10 
 mi/cbrt.c                                   |   46 
 mi/miarc.c                                  |   44 
 mi/mifpoly.h                                |   13 
 mi/mifpolycon.c                             |    4 
 mi/miregion.c                               |  747 -----
 mi/miwideline.c                             |    4 
 miext/cw/cw_ops.c                           |   37 
 miext/rootless/safeAlpha/safeAlphaPicture.c |  526 ---
 randr/rrxinerama.c                          |    8 
 render/picture.c                            |  140 -
 render/picture.h                            |  172 -
 render/picturestr.h                         |   58 
 render/renderedge.c                         |    1 
 103 files changed, 2875 insertions(+), 7922 deletions(-)

New commits:
diff-tree 2a4aa63a23ddd816b647b851a01865861827a7eb (from parents)
Merge: 9cee4ec5e6e06d23aafb302494b082c77ade4623 cc648e609d472472bac4a2e568eb3598b3690ba3
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Tue May 22 14:50:26 2007 -0400

    Merge branch 'master' into XACE-SELINUX
    
    Conflicts:
    
    	include/miscstruct.h

diff --cc include/miscstruct.h
index f784587,4f5b1d5..81f699a
@@@ -50,6 -50,8 +50,7 @@@
  
  #include "misc.h"
  #include <X11/Xprotostr.h>
 -#include "gc.h"
+ #include <pixman/pixman.h>
  
  typedef xPoint DDXPointRec;
  
diff-tree cc648e609d472472bac4a2e568eb3598b3690ba3 (from e6a7198e7cd96f1fe0654cc6811a977821579258)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue May 22 10:51:56 2007 +0200

    EXA: Export ExaOffscreenMarkUsed.
    
    Can be used to inform EXA that an offscreen area is used outside of EXA.

diff --git a/exa/exa.h b/exa/exa.h
index cd90bbc..9ea5933 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -721,6 +721,9 @@ exaOffscreenAlloc(ScreenPtr pScreen, int
 ExaOffscreenArea *
 exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);
 
+void
+ExaOffscreenMarkUsed (PixmapPtr pPixmap);
+
 unsigned long
 exaGetPixmapOffset(PixmapPtr pPix);
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index ece5898..a6d98cd 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -323,9 +323,6 @@ ExaCheckComposite (CARD8      op,
 
 /* exa_offscreen.c */
 void
-ExaOffscreenMarkUsed (PixmapPtr pPixmap);
-
-void
 ExaOffscreenSwapOut (ScreenPtr pScreen);
 
 void
diff-tree e6a7198e7cd96f1fe0654cc6811a977821579258 (from 6324bfc468f7a645d2fee59f1c921a4328a4639f)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Tue May 22 10:51:55 2007 +0200

    Bug #8991: Add glXGetDrawableAttributes dispatch; fix texture format therein.
    
    Adapted to master branch by Michel Dänzer <michel at tungstengraphics.com>.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 932878f..ed5c138 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1679,6 +1679,7 @@ DoGetDrawableAttributes(__GLXclientState
     xGLXGetDrawableAttributesReply reply;
     CARD32 attributes[4];
     int numAttribs;
+    PixmapPtr	pixmap;
 
     glxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
     if (!glxPixmap) {
@@ -1693,10 +1694,19 @@ DoGetDrawableAttributes(__GLXclientState
     reply.numAttribs = numAttribs;
 
     attributes[0] = GLX_TEXTURE_TARGET_EXT;
-    attributes[1] = GLX_TEXTURE_RECTANGLE_EXT;
     attributes[2] = GLX_Y_INVERTED_EXT;
     attributes[3] = GL_FALSE;
 
+    /* XXX this is merely less wrong, see fdo bug #8991 */
+    pixmap = (PixmapPtr) glxPixmap->pDraw;
+    if ((pixmap->drawable.width & (pixmap->drawable.width - 1)) ||
+	(pixmap->drawable.height & (pixmap->drawable.height - 1))
+	/* || strstr(CALL_GetString(GL_EXTENSIONS,
+	             "GL_ARB_texture_non_power_of_two")) */)
+	attributes[1] = GLX_TEXTURE_RECTANGLE_EXT;
+    else
+	attributes[1] = GLX_TEXTURE_2D_EXT;
+
     if (client->swapped) {
 	__glXSwapGetDrawableAttributesReply(client, &reply, attributes);
     } else {
diff --git a/GL/glx/indirect_dispatch.h b/GL/glx/indirect_dispatch.h
index 17a372f..24f4bed 100644
--- a/GL/glx/indirect_dispatch.h
+++ b/GL/glx/indirect_dispatch.h
@@ -211,8 +211,6 @@ extern HIDDEN int __glXDisp_ReadPixels(s
 extern HIDDEN int __glXDispSwap_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_EdgeFlagv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_EdgeFlagv(GLbyte * pc);
-extern HIDDEN void __glXDisp_Rotatef(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_Rotatef(GLbyte * pc);
 extern HIDDEN void __glXDisp_TexParameterf(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_TexParameterf(GLbyte * pc);
 extern HIDDEN void __glXDisp_TexParameteri(GLbyte * pc);
@@ -519,6 +517,8 @@ extern HIDDEN void __glXDisp_SecondaryCo
 extern HIDDEN void __glXDispSwap_SecondaryColor3ivEXT(GLbyte * pc);
 extern HIDDEN void __glXDisp_TexCoord4iv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_TexCoord4iv(GLbyte * pc);
+extern HIDDEN int __glXDisp_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_SampleMaskSGIS(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_SampleMaskSGIS(GLbyte * pc);
 extern HIDDEN void __glXDisp_ColorTableParameteriv(GLbyte * pc);
@@ -849,10 +849,8 @@ extern HIDDEN int __glXDisp_GetHistogram
 extern HIDDEN int __glXDispSwap_GetHistogramParameteriv(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDisp_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
-extern HIDDEN int __glXDisp_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
-extern HIDDEN int __glXDispSwap_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
-extern HIDDEN int __glXDisp_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
-extern HIDDEN int __glXDispSwap_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN void __glXDisp_Rotatef(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_Rotatef(GLbyte * pc);
 extern HIDDEN int __glXDisp_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_BlendFuncSeparateEXT(GLbyte * pc);
@@ -877,6 +875,10 @@ extern HIDDEN void __glXDisp_Map2f(GLbyt
 extern HIDDEN void __glXDispSwap_Map2f(GLbyte * pc);
 extern HIDDEN void __glXDisp_ProgramStringARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_ProgramStringARB(GLbyte * pc);
+extern HIDDEN int __glXDisp_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDisp_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDisp_GetCompressedTexImageARB(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_GetCompressedTexImageARB(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDisp_GetTexGenfv(struct __GLXclientStateRec *, GLbyte *);
diff --git a/GL/glx/indirect_table.c b/GL/glx/indirect_table.c
index 60d6760..9d0383c 100644
--- a/GL/glx/indirect_table.c
+++ b/GL/glx/indirect_table.c
@@ -1231,8 +1231,8 @@ const struct __glXDispatchInfo Render_di
 };
 
 /*****************************************************************/
-/* tree depth = 13 */
-static const int_fast16_t VendorPriv_dispatch_tree[155] = {
+/* tree depth = 12 */
+static const int_fast16_t VendorPriv_dispatch_tree[152] = {
     /* [0] -> opcode range [0, 131072], node depth 1 */
     2,
     5,
@@ -1474,17 +1474,12 @@ static const int_fast16_t VendorPriv_dis
 
     /* [149] -> opcode range [65536, 65568], node depth 12 */
     1,
-    152,
-    EMPTY_LEAF,
-
-    /* [152] -> opcode range [65536, 65552], node depth 13 */
-    1,
     LEAF(88),
     EMPTY_LEAF,
 
 };
 
-static const void *VendorPriv_function_table[96][2] = {
+static const void *VendorPriv_function_table[104][2] = {
     /* [  0] =     0 */ {NULL, NULL},
     /* [  1] =     1 */ {__glXDisp_GetConvolutionFilterEXT, __glXDispSwap_GetConvolutionFilterEXT},
     /* [  2] =     2 */ {__glXDisp_GetConvolutionParameterfvEXT, __glXDispSwap_GetConvolutionParameterfvEXT},
@@ -1581,6 +1576,14 @@ static const void *VendorPriv_function_t
     /* [ 93] = 65541 */ {__glXDisp_CreateContextWithConfigSGIX, __glXDispSwap_CreateContextWithConfigSGIX},
     /* [ 94] = 65542 */ {__glXDisp_CreateGLXPixmapWithConfigSGIX, __glXDispSwap_CreateGLXPixmapWithConfigSGIX},
     /* [ 95] = 65543 */ {NULL, NULL},
+    /* [ 96] = 65544 */ {NULL, NULL},
+    /* [ 97] = 65545 */ {NULL, NULL},
+    /* [ 98] = 65546 */ {__glXDisp_GetDrawableAttributesSGIX, __glXDispSwap_GetDrawableAttributesSGIX},
+    /* [ 99] = 65547 */ {NULL, NULL},
+    /* [ 100] = 65548 */ {NULL, NULL},
+    /* [ 101] = 65549 */ {NULL, NULL},
+    /* [ 102] = 65550 */ {NULL, NULL},
+    /* [ 103] = 65551 */ {NULL, NULL},
 };
 
 const struct __glXDispatchInfo VendorPriv_dispatch_info = {
diff-tree 6324bfc468f7a645d2fee59f1c921a4328a4639f (from 5006d08d7fc56d3d380cc6b75297f94e8594eb54)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue May 22 10:51:53 2007 +0200

    AIGLX: Zero-copy texture-from-pixmap.
    
    When available, use the 2D driver texOffsetStart hook and the 3D driver
    setTexOffset hook to save the overhead of passing the pixmap data to
    glTex(Sub)Image.
    
    The basic idea is to update the driver specific 'offset' for bound pixmaps
    before dispatching a GLX render request and to flush immediately afterwards
    if there are any pixmaps bound. This should ensure that the 3D driver can
    use pixmaps for texturing directly regardless of the X server moving them
    around.

diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 20e9b43..6500cc7 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -42,6 +42,10 @@
 
 #include <damage.h>
 
+#ifdef XF86DRI
+#include <GL/internal/dri_interface.h>
+#endif
+
 typedef struct {
 
     DrawablePtr pDraw;
@@ -50,7 +54,12 @@ typedef struct {
     ScreenPtr pScreen;
     Bool idExists;
     int refcnt;
+#ifdef XF86DRI
     DamagePtr pDamage;
+    __DRIcontext *pDRICtx;
+    GLint texname;
+    unsigned long offset;
+#endif
 } __GLXpixmap;
 
 struct __GLXdrawable {
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index c30f372..d93d460 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -76,6 +76,11 @@ struct __GLXDRIscreen {
     xf86EnterVTProc *enterVT;
     xf86LeaveVTProc *leaveVT;
 
+    DRITexOffsetStartProcPtr texOffsetStart;
+    DRITexOffsetFinishProcPtr texOffsetFinish;
+    __GLXpixmap* texOffsetOverride[16];
+    GLuint lastTexOffsetOverride;
+
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 };
 
@@ -125,30 +130,75 @@ struct __GLXDRIdrawable {
 static const char CREATE_NEW_SCREEN_FUNC[] =
     "__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
 
-/* The DRI driver entry point version wasn't bumped when the
- * copySubBuffer functionality was added to the DRI drivers, but the
- * functionality is still conditional on the value of the
- * internal_api_version passed to __driCreateNewScreen.  However, the
- * screen constructor doesn't fail for a DRI driver that's older than
- * the passed in version number, so there's no way we can know for
- * sure that we can actually use the copySubBuffer functionality.  But
- * since the earliest (and at this point only) released mesa version
- * (6.5) that uses the 20050727 entry point does have copySubBuffer,
- * we'll just settle for that.  We still have to pass in a higher to
- * the screen constructor to enable the functionality.
- */
-#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
 
 static void
-__glXDRIleaveServer(void)
+__glXDRIleaveServer(GLboolean rendering)
 {
-  DRIBlockHandler(NULL, NULL, NULL);
+    int i;
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+	GLuint lastOverride = screen->lastTexOffsetOverride;
+
+	if (lastOverride) {
+	    __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	    int j;
+
+	    for (j = 0; j < lastOverride; j++) {
+		__GLXpixmap *pGlxPix = texOffsetOverride[j];
+
+		if (pGlxPix && pGlxPix->texname) {
+		    pGlxPix->offset =
+			screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
+		}
+	    }
+	}
+    }
+
+    DRIBlockHandler(NULL, NULL, NULL);
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+	GLuint lastOverride = screen->lastTexOffsetOverride;
+
+	if (lastOverride) {
+	    __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	    int j;
+
+	    for (j = 0; j < lastOverride; j++) {
+		__GLXpixmap *pGlxPix = texOffsetOverride[j];
+
+		if (pGlxPix && pGlxPix->texname) {
+		    screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
+						   pGlxPix->texname,
+						   pGlxPix->offset,
+						   pGlxPix->pDraw->depth,
+						   ((PixmapPtr)pGlxPix->pDraw)->
+						   devKind);
+		}
+	    }
+	}
+    }
 }
     
 static void
-__glXDRIenterServer(void)
+__glXDRIenterServer(GLboolean rendering)
 {
-  DRIWakeupHandler(NULL, 0, NULL);
+    int i;
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+
+	if (screen->lastTexOffsetOverride) {
+	    CALL_Flush(GET_DISPATCH(), ());
+	    break;
+	}
+    }
+
+    DRIWakeupHandler(NULL, 0, NULL);
 }
 
 /**
@@ -289,19 +339,6 @@ __glXDRIcontextForceCurrent(__GLXcontext
 					      &context->driContext);
 }
 
-static int
-glxCountBits(int word)
-{
-    int ret = 0;
-
-    while (word) {
-        ret += (word & 1);
-        word >>= 1;
-    }
-
-    return ret;
-}
-
 static void
 glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
 {
@@ -335,19 +372,75 @@ __glXDRIbindTexImage(__GLXcontext *baseC
 		     int buffer,
 		     __GLXpixmap *glxPixmap)
 {
-    RegionPtr	pRegion;
+    RegionPtr	pRegion = NULL;
     PixmapPtr	pixmap;
-    int		bpp;
+    int		w, h, bpp, override = 0;
     GLenum	target, format, type;
+    ScreenPtr pScreen = glxPixmap->pScreen;
+    __GLXDRIscreen * const screen =
+	(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
 
     pixmap = (PixmapPtr) glxPixmap->pDraw;
+    w = pixmap->drawable.width;
+    h = pixmap->drawable.height;
+
+    if (h & (h - 1) || w & (w - 1))
+	target = GL_TEXTURE_RECTANGLE_ARB;
+    else
+	target = GL_TEXTURE_2D;
+
+    if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
+	__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	int i, firstEmpty = 16, texname;
+
+	for (i = 0; i < 16; i++) {
+	    if (texOffsetOverride[i] == glxPixmap)
+		goto alreadyin; 
+
+	    if (firstEmpty == 16 && !texOffsetOverride[i])
+		firstEmpty = i;
+	}
+
+	if (firstEmpty == 16) {
+	    ErrorF("%s: Failed to register texture offset override\n", __func__);
+	    goto nooverride;
+	}
+
+	if (firstEmpty >= screen->lastTexOffsetOverride)
+	    screen->lastTexOffsetOverride = firstEmpty + 1;
+
+	texOffsetOverride[firstEmpty] = glxPixmap;
+
+alreadyin:
+	override = 1;
+
+	glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
+
+	CALL_GetIntegerv(GET_DISPATCH(), (target == GL_TEXTURE_2D ?
+					  GL_TEXTURE_BINDING_2D :
+					  GL_TEXTURE_BINDING_RECTANGLE_NV,
+					  &texname));
+
+	if (texname == glxPixmap->texname)
+	    return Success;
+
+	glxPixmap->texname = texname;
+
+	screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
+				       pixmap->drawable.depth, pixmap->devKind);
+    }
+nooverride:
+
     if (!glxPixmap->pDamage) {
-        glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
-					  TRUE, glxPixmap->pScreen, NULL);
-	if (!glxPixmap->pDamage)
-            return BadAlloc;
+	if (!override) {
+	    glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+					      TRUE, pScreen, NULL);
+	    if (!glxPixmap->pDamage)
+		return BadAlloc;
+
+	    DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
+	}
 
-	DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
 	pRegion = NULL;
     } else {
 	pRegion = DamageRegion(glxPixmap->pDamage);
@@ -360,30 +453,22 @@ __glXDRIbindTexImage(__GLXcontext *baseC
 	bpp = 4;
 	format = GL_BGRA;
 	type =
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
-	    GL_UNSIGNED_BYTE;
-#else
-	    GL_UNSIGNED_INT_8_8_8_8_REV;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	    !override ? GL_UNSIGNED_INT_8_8_8_8_REV :
 #endif
+	    GL_UNSIGNED_BYTE;
     } else {
 	bpp = 2;
 	format = GL_RGB;
 	type = GL_UNSIGNED_SHORT_5_6_5;
     }
 
-    if (!(glxCountBits(pixmap->drawable.width) == 1 &&
-	  glxCountBits(pixmap->drawable.height) == 1)
-	/* || strstr(CALL_GetString(GL_EXTENSIONS,
-	             "GL_ARB_texture_non_power_of_two")) */)
-	target = GL_TEXTURE_RECTANGLE_ARB;
-    else
-	target = GL_TEXTURE_2D;
-
     CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
 				       pixmap->devKind / bpp) );
+
     if (pRegion == NULL)
     {
-	if (pixmap->drawable.depth == 24)
+	if (!override && pixmap->drawable.depth == 24)
 	    glxFillAlphaChannel(pixmap,
 				pixmap->drawable.x,
 				pixmap->drawable.y,
@@ -404,8 +489,8 @@ __glXDRIbindTexImage(__GLXcontext *baseC
 			  0,
 			  format,
 			  type,
-			  pixmap->devPrivate.ptr) );
-    } else {
+			  override ? NULL : pixmap->devPrivate.ptr) );
+    } else if (!override) {
         int i, numRects;
 	BoxPtr p;
 
@@ -436,7 +521,8 @@ __glXDRIbindTexImage(__GLXcontext *baseC
 	}
     }
 
-    DamageEmpty(glxPixmap->pDamage);
+    if (!override)
+	DamageEmpty(glxPixmap->pDamage);
 
     return Success;
 }
@@ -446,6 +532,40 @@ __glXDRIreleaseTexImage(__GLXcontext *ba
 			int buffer,
 			__GLXpixmap *pixmap)
 {
+    ScreenPtr pScreen = pixmap->pScreen;
+    __GLXDRIscreen * const screen =
+	(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+    GLuint lastOverride = screen->lastTexOffsetOverride;
+
+    if (lastOverride) {
+	__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	int i;
+
+	for (i = 0; i < lastOverride; i++) {
+	    if (texOffsetOverride[i] == pixmap) {
+		if (screen->texOffsetFinish)
+		    screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
+
+		texOffsetOverride[i] = NULL;
+
+		if (i + 1 == lastOverride) {
+		    lastOverride = 0;
+
+		    while (i--) {
+			if (texOffsetOverride[i]) {
+			    lastOverride = i + 1;
+			    break;
+			}
+		    }
+
+		    screen->lastTexOffsetOverride = lastOverride;
+
+		    break;
+		}
+	    }
+	}
+    }
+
     return Success;
 }
 
@@ -666,9 +786,9 @@ static GLboolean createContext(__DRInati
     fakeID = FakeClientID(0);
     *(XID *) contextID = fakeID;
 
-    __glXDRIenterServer();
+    __glXDRIenterServer(GL_FALSE);
     retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
-    __glXDRIleaveServer();
+    __glXDRIleaveServer(GL_FALSE);
     return retval;
 }
 
@@ -677,9 +797,9 @@ static GLboolean destroyContext(__DRInat
 {
     GLboolean retval;
 
-    __glXDRIenterServer();
+    __glXDRIenterServer(GL_FALSE);
     retval = DRIDestroyContext(screenInfo.screens[screen], context);
-    __glXDRIleaveServer();
+    __glXDRIleaveServer(GL_FALSE);
     return retval;
 }
 
@@ -694,12 +814,12 @@ createDrawable(__DRInativeDisplay *dpy, 
     if (!pDrawable)
 	return GL_FALSE;
 
-    __glXDRIenterServer();
+    __glXDRIenterServer(GL_FALSE);
     retval = DRICreateDrawable(screenInfo.screens[screen],
 			    drawable,
 			    pDrawable,
 			    hHWDrawable);
-    __glXDRIleaveServer();
+    __glXDRIleaveServer(GL_FALSE);
     return retval;
 }
 
@@ -713,11 +833,11 @@ destroyDrawable(__DRInativeDisplay *dpy,
     if (!pDrawable)
 	return GL_FALSE;
 
-    __glXDRIenterServer();
+    __glXDRIenterServer(GL_FALSE);
     retval = DRIDestroyDrawable(screenInfo.screens[screen],
 			     drawable,
 			     pDrawable);
-    __glXDRIleaveServer();
+    __glXDRIleaveServer(GL_FALSE);
     return retval;
 }
 
@@ -754,14 +874,14 @@ getDrawableInfo(__DRInativeDisplay *dpy,
 	return GL_FALSE;
     }
 
-    __glXDRIenterServer();
+    __glXDRIenterServer(GL_FALSE);
     retval = DRIGetDrawableInfo(screenInfo.screens[screen],
 				pDrawable, index, stamp,
 				x, y, width, height,
 				numClipRects, &pClipRects,
 				backX, backY,
 				numBackClipRects, &pBackClipRects);
-    __glXDRIleaveServer();
+    __glXDRIleaveServer(GL_FALSE);
 
     if (*numClipRects > 0) {
 	size = sizeof (drm_clip_rect_t) * *numClipRects;
@@ -866,7 +986,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     __DRIframebuffer  framebuffer;
     int   fd = -1;
     int   status;
-    int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION;
+    int api_ver = 20070121;
     drm_magic_t magic;
     drmVersionPtr version;
     int newlyopened;
@@ -1048,6 +1168,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
 
+    DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
+			 &screen->texOffsetFinish);
+
     __glXScreenInit(&screen->base, pScreen);
 
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index ca874e3..c09120c 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -238,9 +238,9 @@ GLboolean __glXFreeContext(__GLXcontext 
      * the latter case we need to lift the DRI lock manually. */
 
     if (!glxBlockClients) {
-	__glXleaveServer();
+	__glXleaveServer(GL_FALSE);
 	cx->destroy(cx);
-	__glXenterServer();
+	__glXenterServer(GL_FALSE);
     } else {
 	cx->next = glxPendingDestroyContexts;
 	glxPendingDestroyContexts = cx;
@@ -439,49 +439,49 @@ void glxResumeClients(void)
 	AttendClient(__glXClients[i]->client);
     }
 
-    __glXleaveServer();
+    __glXleaveServer(GL_FALSE);
     for (cx = glxPendingDestroyContexts; cx != NULL; cx = next) {
 	next = cx->next;
 
 	cx->destroy(cx);
     }
     glxPendingDestroyContexts = NULL;
-    __glXenterServer();
+    __glXenterServer(GL_FALSE);
 }
 
 static void
-__glXnopEnterServer(void)
+__glXnopEnterServer(GLboolean rendering)
 {
 }
     
 static void
-__glXnopLeaveServer(void)
+__glXnopLeaveServer(GLboolean rendering)
 {
 }
 
-static void (*__glXenterServerFunc)(void) = __glXnopEnterServer;
-static void (*__glXleaveServerFunc)(void)  = __glXnopLeaveServer;
+static void (*__glXenterServerFunc)(GLboolean) = __glXnopEnterServer;
+static void (*__glXleaveServerFunc)(GLboolean)  = __glXnopLeaveServer;
 
-void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
-				   void (*leave)(void))
+void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
+				   void (*leave)(GLboolean))
 {
   __glXenterServerFunc = enter;
   __glXleaveServerFunc = leave;
 }
 
 
-void __glXenterServer(void)
+void __glXenterServer(GLboolean rendering)
 {
   glxServerLeaveCount--;
 
   if (glxServerLeaveCount == 0)
-    (*__glXenterServerFunc)();
+    (*__glXenterServerFunc)(rendering);
 }
 
-void __glXleaveServer(void)
+void __glXleaveServer(GLboolean rendering)
 {
   if (glxServerLeaveCount == 0)
-    (*__glXleaveServerFunc)();
+    (*__glXleaveServerFunc)(rendering);
 
   glxServerLeaveCount++;
 }
@@ -546,11 +546,12 @@ static int __glXDispatch(ClientPtr clien
 								       opcode,
 								       client->swapped);
     if (proc != NULL) {
-	__glXleaveServer();
+	GLboolean rendering = opcode <= X_GLXRenderLarge;
+	__glXleaveServer(rendering);
 
 	retval = (*proc)(cl, (GLbyte *) stuff);
 
-	__glXenterServer();
+	__glXenterServer(rendering);
     }
     else {
 	retval = BadRequest;
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index b50740c..df9be07 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -106,11 +106,11 @@ __glXMesaDrawableSwapBuffers(__GLXdrawab
      * why we need to re-take the lock and swap in the server context
      * before calling XMesaSwapBuffers() here.  /me shakes head. */
 
-    __glXenterServer();
+    __glXenterServer(GL_FALSE);
 
     XMesaSwapBuffers(glxPriv->xm_buf);
 
-    __glXleaveServer();
+    __glXleaveServer(GL_FALSE);
 
     return GL_TRUE;
 }
diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h
index 49cad73..fa09c15 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -131,10 +131,10 @@ struct __GLXprovider {
 
 void GlxPushProvider(__GLXprovider *provider);
 
-void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
-				   void (*leave)(void));
-void __glXenterServer(void);
-void __glXleaveServer(void);
+void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
+				   void (*leave)(GLboolean));
+void __glXenterServer(GLboolean rendering);
+void __glXleaveServer(GLboolean rendering);
 
 void glxSuspendClients(void);
 void glxResumeClients(void);
diff-tree 5006d08d7fc56d3d380cc6b75297f94e8594eb54 (from ff2eae86b6a8760befbbc5d605debebe7b024c05)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue May 22 10:51:52 2007 +0200

    DRI: Add TexOffset driver hooks.
    
    To be used by AIGLX for GLX_EXT_texture_from_pixmap without several data copies.
    
    The texOffsetStart hook must make sure that the given pixmap is accessible by
    the GPU for texturing and return an 'offset' that can be used by the 3D
    driver for that purpose.
    
    The texOffsetFinish hook is called when the pixmap is no longer being used for
    texturing.

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 355d281..fae0b43 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -2210,6 +2210,19 @@ DRIGetContext(ScreenPtr pScreen)
     return pDRIPriv->myContext;
 }
 
+void
+DRIGetTexOffsetFuncs(ScreenPtr pScreen,
+		     DRITexOffsetStartProcPtr *texOffsetStartFunc,
+		     DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
+{
+    DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+    if (!pDRIPriv) return;
+
+    *texOffsetStartFunc  = pDRIPriv->pDriverInfo->texOffsetStart;
+    *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
+}
+
 /* This lets get at the unwrapped functions so that they can correctly
  * call the lowerlevel functions, and choose whether they will be
  * called at every level of recursion (eg in validatetree).
diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h
index a21338a..e49bb6f 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -107,9 +107,12 @@ typedef struct {
  */
 
 #define DRIINFO_MAJOR_VERSION   5
-#define DRIINFO_MINOR_VERSION   2
+#define DRIINFO_MINOR_VERSION   3
 #define DRIINFO_PATCH_VERSION   0
 
+typedef unsigned long long (*DRITexOffsetStartProcPtr)(PixmapPtr pPix);
+typedef void (*DRITexOffsetFinishProcPtr)(PixmapPtr pPix);
+
 typedef struct {
     /* driver call back functions
      *
@@ -180,6 +183,10 @@ typedef struct {
     /* New with DRI version 5.2.0 */
     Bool                allocSarea;
     Bool                keepFDOpen;
+
+    /* New with DRI version 5.3.0 */
+    DRITexOffsetStartProcPtr  texOffsetStart;
+    DRITexOffsetFinishProcPtr texOffsetFinish;
 } DRIInfoRec, *DRIInfoPtr;
 
 
@@ -358,7 +365,9 @@ extern void *DRIMasterSareaPointer(ScrnI
 
 extern drm_handle_t DRIMasterSareaHandle(ScrnInfoPtr pScrn);
 
-
+extern void DRIGetTexOffsetFuncs(ScreenPtr pScreen,
+				 DRITexOffsetStartProcPtr *texOffsetStartFunc,
+				 DRITexOffsetFinishProcPtr *texOffsetFinishFunc);
 
 #define _DRI_H_
 
diff-tree ff2eae86b6a8760befbbc5d605debebe7b024c05 (from 56fd92715567cd32e4b725b3791de9ac4e3879aa)
Author: David Nusinow <dnusinow at debian.org>
Date:   Mon May 21 19:50:04 2007 -0400

    Fix boolean thinko that prevented working without a server layout

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 7f1105f..67e8af4 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1809,7 +1809,7 @@ configImpliedLayout(serverLayoutPtr serv
     indp = xnfalloc(sizeof(IDevRec));
     indp->identifier = NULL;
     servlayoutp->inputs = indp;
-    if (!xf86Info.allowEmptyInput && checkCoreInputDevices(servlayoutp, TRUE))
+    if (!xf86Info.allowEmptyInput && !checkCoreInputDevices(servlayoutp, TRUE))
 	return FALSE;
     
     return TRUE;
diff-tree 56fd92715567cd32e4b725b3791de9ac4e3879aa (from 7e2c935920cafadbd87c351f1a3239932864fb90)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Mon May 21 20:00:25 2007 -0400

    Remove fast path code from fbpict.c
    
    Remove the various fast path functions from fbpict, and instead use
    pixman_image_composite().

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 84d19ac..eb78ced 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -39,898 +39,6 @@
 #include "fbpict.h"
 #include "fbmmx.h"
 
-CARD32
-fbOver (CARD32 x, CARD32 y)
-{
-    CARD16  a = ~x >> 24;
-    CARD16  t;
-    CARD32  m,n,o,p;
-
-    m = FbOverU(x,y,0,a,t);
-    n = FbOverU(x,y,8,a,t);
-    o = FbOverU(x,y,16,a,t);
-    p = FbOverU(x,y,24,a,t);
-    return m|n|o|p;
-}
-
-CARD32
-fbOver24 (CARD32 x, CARD32 y)
-{
-    CARD16  a = ~x >> 24;
-    CARD16  t;
-    CARD32  m,n,o;
-
-    m = FbOverU(x,y,0,a,t);
-    n = FbOverU(x,y,8,a,t);
-    o = FbOverU(x,y,16,a,t);
-    return m|n|o;
-}
-
-CARD32
-fbIn (CARD32 x, CARD8 y)
-{
-    CARD16  a = y;
-    CARD16  t;
-    CARD32  m,n,o,p;
-
-    m = FbInU(x,0,a,t);
-    n = FbInU(x,8,a,t);
-    o = FbInU(x,16,a,t);
-    p = FbInU(x,24,a,t);
-    return m|n|o|p;
-}
-
-/*
- * Naming convention:
- *
- *  opSRCxMASKxDST
- */
-
-void
-fbCompositeSolidMask_nx8x8888 (CARD8      op,
-			       PicturePtr pSrc,
-			       PicturePtr pMask,
-			       PicturePtr pDst,
-			       INT16      xSrc,
-			       INT16      ySrc,
-			       INT16      xMask,
-			       INT16      yMask,
-			       INT16      xDst,
-			       INT16      yDst,
-			       CARD16     width,
-			       CARD16     height)
-{
-    CARD32	src, srca;
-    CARD32	*dstLine, *dst, d, dstMask;
-    CARD8	*maskLine, *mask, m;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    dstMask = FbFullMask (pDst->pDrawable->depth);
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    WRITE(dst, src & dstMask);
-		else
-		    WRITE(dst, fbOver (src, READ(dst)) & dstMask);
-	    }
-	    else if (m)
-	    {
-		d = fbIn (src, m);
-		WRITE(dst, fbOver (d, READ(dst)) & dstMask);
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSolidMask_nx8888x8888C (CARD8      op,
-				   PicturePtr pSrc,
-				   PicturePtr pMask,
-				   PicturePtr pDst,
-				   INT16      xSrc,
-				   INT16      ySrc,
-				   INT16      xMask,
-				   INT16      yMask,
-				   INT16      xDst,
-				   INT16      yDst,
-				   CARD16     width,
-				   CARD16     height)
-{
-    CARD32	src, srca;
-    CARD32	*dstLine, *dst, d, dstMask;
-    CARD32	*maskLine, *mask, ma;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-    CARD32	m, n, o, p;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    dstMask = FbFullMask (pDst->pDrawable->depth);
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    ma = READ(mask++);
-	    if (ma == 0xffffffff)
-	    {
-		if (srca == 0xff)
-		    WRITE(dst, src & dstMask);
-		else
-		    WRITE(dst, fbOver (src, READ(dst)) & dstMask);
-	    }
-	    else if (ma)
-	    {
-		d = READ(dst);
-#define FbInOverC(src,srca,msk,dst,i,result) { \
-    CARD16  __a = FbGet8(msk,i); \
-    CARD32  __t, __ta; \
-    CARD32  __i; \
-    __t = FbIntMult (FbGet8(src,i), __a,__i); \
-    __ta = (CARD8) ~FbIntMult (srca, __a,__i); \
-    __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
-    __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
-    result = __t << (i); \
-}
-		FbInOverC (src, srca, ma, d, 0, m);
-		FbInOverC (src, srca, ma, d, 8, n);
-		FbInOverC (src, srca, ma, d, 16, o);
-		FbInOverC (src, srca, ma, d, 24, p);
-		WRITE(dst, m|n|o|p);
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSolidMask_nx8x0888 (CARD8      op,
-			       PicturePtr pSrc,
-			       PicturePtr pMask,
-			       PicturePtr pDst,
-			       INT16      xSrc,
-			       INT16      ySrc,
-			       INT16      xMask,
-			       INT16      yMask,
-			       INT16      xDst,
-			       INT16      yDst,
-			       CARD16     width,
-			       CARD16     height)
-{
-    CARD32	src, srca;
-    CARD8	*dstLine, *dst;
-    CARD32	d;
-    CARD8	*maskLine, *mask, m;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = Fetch24(dst);
-		    d = fbOver24 (src, d);
-		}
-		Store24(dst,d);
-	    }
-	    else if (m)
-	    {
-		d = fbOver24 (fbIn(src,m), Fetch24(dst));
-		Store24(dst,d);
-	    }
-	    dst += 3;
-	}
-    }
-
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSolidMask_nx8x0565 (CARD8      op,
-				  PicturePtr pSrc,
-				  PicturePtr pMask,
-				  PicturePtr pDst,
-				  INT16      xSrc,
-				  INT16      ySrc,
-				  INT16      xMask,
-				  INT16      yMask,
-				  INT16      xDst,
-				  INT16      yDst,
-				  CARD16     width,
-				  CARD16     height)
-{
-    CARD32	src, srca;
-    CARD16	*dstLine, *dst;
-    CARD32	d;
-    CARD8	*maskLine, *mask, m;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = READ(dst);
-		    d = fbOver24 (src, cvt0565to0888(d));
-		}
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    else if (m)
-	    {
-		d = READ(dst);
-		d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSolidMask_nx8888x0565C (CARD8      op,
-				   PicturePtr pSrc,
-				   PicturePtr pMask,
-				   PicturePtr pDst,
-				   INT16      xSrc,
-				   INT16      ySrc,
-				   INT16      xMask,
-				   INT16      yMask,
-				   INT16      xDst,
-				   INT16      yDst,
-				   CARD16     width,
-				   CARD16     height)
-{
-    CARD32	src, srca;
-    CARD16	src16;
-    CARD16	*dstLine, *dst;
-    CARD32	d;
-    CARD32	*maskLine, *mask, ma;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-    CARD32	m, n, o;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    src16 = cvt8888to0565(src);
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    ma = READ(mask++);
-	    if (ma == 0xffffffff)
-	    {
-		if (srca == 0xff)
-		{
-		    WRITE(dst, src16);
-		}
-		else
-		{
-		    d = READ(dst);
-		    d = fbOver24 (src, cvt0565to0888(d));
-		    WRITE(dst, cvt8888to0565(d));
-		}
-	    }
-	    else if (ma)
-	    {
-		d = READ(dst);
-		d = cvt0565to0888(d);
-		FbInOverC (src, srca, ma, d, 0, m);
-		FbInOverC (src, srca, ma, d, 8, n);
-		FbInOverC (src, srca, ma, d, 16, o);
-		d = m|n|o;
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSrc_8888x8888 (CARD8      op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height)
-{
-    CARD32	*dstLine, *dst, dstMask;
-    CARD32	*srcLine, *src, s;
-    FbStride	dstStride, srcStride;
-    CARD8	a;
-    CARD16	w;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
-
-    dstMask = FbFullMask (pDst->pDrawable->depth);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(src++);
-	    a = s >> 24;
-	    if (a == 0xff)
-		WRITE(dst, s & dstMask);
-	    else if (a)
-		WRITE(dst, fbOver (s, READ(dst)) & dstMask);
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pSrc->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSrc_8888x0888 (CARD8      op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height)
-{
-    CARD8	*dstLine, *dst;
-    CARD32	d;
-    CARD32	*srcLine, *src, s;
-    CARD8	a;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(src++);
-	    a = s >> 24;
-	    if (a)
-	    {
-		if (a == 0xff)
-		    d = s;
-		else
-		    d = fbOver24 (s, Fetch24(dst));
-		Store24(dst,d);
-	    }
-	    dst += 3;
-	}
-    }
-
-    fbFinishAccess (pSrc->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-void
-fbCompositeSrc_8888x0565 (CARD8      op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height)
-{
-    CARD16	*dstLine, *dst;
-    CARD32	d;
-    CARD32	*srcLine, *src, s;
-    CARD8	a;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(src++);
-	    a = s >> 24;
-	    if (a)
-	    {
-		if (a == 0xff)
-		    d = s;
-		else
-		{
-		    d = READ(dst);
-		    d = fbOver24 (s, cvt0565to0888(d));
-		}
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pDst->pDrawable);
-    fbFinishAccess (pSrc->pDrawable);
-}
-
-void
-fbCompositeSrcAdd_8000x8000 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height)
-{
-    CARD8	*dstLine, *dst;
-    CARD8	*srcLine, *src;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-    CARD8	s, d;
-    CARD16	t;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(src++);
-	    if (s)
-	    {
-		if (s != 0xff)
-		{
-		    d = READ(dst);
-		    t = d + s;
-		    s = t | (0 - (t >> 8));
-		}
-		WRITE(dst, s);
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pDst->pDrawable);
-    fbFinishAccess (pSrc->pDrawable);
-}
-
-void
-fbCompositeSrcAdd_8888x8888 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height)
-{
-    CARD32	*dstLine, *dst;
-    CARD32	*srcLine, *src;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-    CARD32	s, d;
-    CARD16	t;
-    CARD32	m,n,o,p;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(src++);
-	    if (s)
-	    {
-		if (s != 0xffffffff)
-		{
-		    d = READ(dst);
-		    if (d)
-		    {
-			m = FbAdd(s,d,0,t);
-			n = FbAdd(s,d,8,t);
-			o = FbAdd(s,d,16,t);
-			p = FbAdd(s,d,24,t);
-			s = m|n|o|p;
-		    }
-		}
-		WRITE(dst, s);
-	    }
-	    dst++;
-	}
-    }
-
-    fbFinishAccess (pDst->pDrawable);
-    fbFinishAccess (pSrc->pDrawable);
-}
-
-static void
-fbCompositeSrcAdd_8888x8x8 (CARD8      op,
-			    PicturePtr pSrc,
-			    PicturePtr pMask,
-			    PicturePtr pDst,
-			    INT16      xSrc,
-			    INT16      ySrc,
-			    INT16      xMask,
-			    INT16      yMask,
-			    INT16      xDst,
-			    INT16      yDst,
-			    CARD16     width,
-			    CARD16     height)
-{
-    CARD8	*dstLine, *dst;
-    CARD8	*maskLine, *mask;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-    CARD32	src;
-    CARD8	sa;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-    fbComposeGetSolid (pSrc, src, pDst->format);
-    sa = (src >> 24);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    CARD16	tmp;
-	    CARD16	a;
-	    CARD32	m, d;
-	    CARD32	r;
-
-	    a = READ(mask++);
-	    d = READ(dst);
-
-	    m = FbInU (sa, 0, a, tmp);
-	    r = FbAdd (m, d, 0, tmp);
-
-	    WRITE(dst++, r);
-	}
-    }
-    
-    fbFinishAccess(pDst->pDrawable);
-    fbFinishAccess(pMask->pDrawable);
-}
-
-void
-fbCompositeSrcAdd_1000x1000 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height)
-{
-    FbBits	*dstBits, *srcBits;
-    FbStride	dstStride, srcStride;
-    int		dstBpp, srcBpp;
-    int		dstXoff, dstYoff;
-    int		srcXoff, srcYoff;
-
-    fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
-
-    fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
-
-    fbBlt (srcBits + srcStride * (ySrc + srcYoff),
-	   srcStride,
-	   xSrc + srcXoff,
-
-	   dstBits + dstStride * (yDst + dstYoff),
-	   dstStride,
-	   xDst + dstXoff,
-
-	   width,
-	   height,
-
-	   GXor,
-	   FB_ALLONES,
-	   srcBpp,
-
-	   FALSE,
-	   FALSE);
-
-    fbFinishAccess(pDst->pDrawable);
-    fbFinishAccess(pSrc->pDrawable);
-}
-
-void
-fbCompositeSolidMask_nx1xn (CARD8      op,
-			    PicturePtr pSrc,
-			    PicturePtr pMask,
-			    PicturePtr pDst,
-			    INT16      xSrc,
-			    INT16      ySrc,
-			    INT16      xMask,
-			    INT16      yMask,
-			    INT16      xDst,
-			    INT16      yDst,
-			    CARD16     width,
-			    CARD16     height)
-{
-    FbBits	*dstBits;
-    FbStip	*maskBits;
-    FbStride	dstStride, maskStride;
-    int		dstBpp, maskBpp;
-    int		dstXoff, dstYoff;
-    int		maskXoff, maskYoff;
-    FbBits	src;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-    fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
-    fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
-
-    switch (dstBpp) {
-    case 32:
-	break;
-    case 24:
-	break;
-    case 16:
-	src = cvt8888to0565(src);
-	break;
-    }
-
-    src = fbReplicatePixel (src, dstBpp);
-
-    fbBltOne (maskBits + maskStride * (yMask + maskYoff),
-	      maskStride,
-	      xMask + maskXoff,
-
-	      dstBits + dstStride * (yDst + dstYoff),
-	      dstStride,
-	      (xDst + dstXoff) * dstBpp,
-	      dstBpp,
-
-	      width * dstBpp,
-	      height,
-
-	      0x0,
-	      src,
-	      FB_ALLONES,
-	      0x0);
-
-    fbFinishAccess (pDst->pDrawable);
-    fbFinishAccess (pMask->pDrawable);
-}
-
-# define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
-
-/*
- * Apply a constant alpha value in an over computation
- */
-static void
-fbCompositeSrcSrc_nxn  (CARD8	   op,
-			PicturePtr pSrc,
-			PicturePtr pMask,
-			PicturePtr pDst,
-			INT16      xSrc,
-			INT16      ySrc,
-			INT16      xMask,
-			INT16      yMask,
-			INT16      xDst,
-			INT16      yDst,
-			CARD16     width,
-			CARD16     height);
-
-/*
- * Simple bitblt
- */
-
-static void
-fbCompositeSrcSrc_nxn  (CARD8	   op,
-			PicturePtr pSrc,
-			PicturePtr pMask,
-			PicturePtr pDst,
-			INT16      xSrc,
-			INT16      ySrc,
-			INT16      xMask,
-			INT16      yMask,
-			INT16      xDst,
-			INT16      yDst,
-			CARD16     width,
-			CARD16     height)
-{
-    FbBits	*dst;
-    FbBits	*src;
-    FbStride	dstStride, srcStride;
-    int		srcXoff, srcYoff;
-    int		dstXoff, dstYoff;
-    int		srcBpp;
-    int		dstBpp;
-    Bool	reverse = FALSE;
-    Bool	upsidedown = FALSE;
-    
-    fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
-    fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
-	
-    fbBlt (src + (ySrc + srcYoff) * srcStride,
-	   srcStride,
-	   (xSrc + srcXoff) * srcBpp,
- 
-	   dst + (yDst + dstYoff) * dstStride,
-	   dstStride,
-	   (xDst + dstXoff) * dstBpp,
-
-	   (width) * dstBpp,
-	   (height),
-
-	   GXcopy,
-	   FB_ALLONES,
-	   dstBpp,
-
-	   reverse,
-	   upsidedown);
-    
-    fbFinishAccess(pSrc->pDrawable);
-    fbFinishAccess(pDst->pDrawable);
-}
-
 static pixman_image_t *
 create_solid_fill_image (PicturePtr pict)
 {
@@ -1153,39 +261,7 @@ image_from_pict (PicturePtr pict)
     return image;
 }
 
-static void
-fbCompositeRectWrapper  (CARD8	   op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height)
-{
-    pixman_image_t *src = image_from_pict (pSrc);
-    pixman_image_t *dest = image_from_pict (pDst);
-    pixman_image_t *mask = image_from_pict (pMask);
-
-    if (!src || !dest || (pMask && !mask))
-	goto out;
-
-    pixman_image_composite_rect (op, src, mask, dest,
-				 xSrc, ySrc, xMask, yMask, xDst, yDst,
-				 width, height);
-    
-out:
-    if (src)
-	pixman_image_unref (src);
-    if (mask)
-	pixman_image_unref (mask);
-    if (dest)
-	pixman_image_unref (dest);
-}    
+#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
 
 void
 fbWalkCompositeRegion (CARD8 op,
@@ -1305,591 +381,32 @@ fbComposite (CARD8      op,
 	     CARD16     width,
 	     CARD16     height)
 {
-    Bool	    srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
-    Bool	    maskRepeat = FALSE;
-    Bool	    srcTransform = pSrc->transform != 0;
-    Bool	    maskTransform = FALSE;
-    Bool	    srcAlphaMap = pSrc->alphaMap != 0;
-    Bool	    maskAlphaMap = FALSE;
-    Bool	    dstAlphaMap = pDst->alphaMap != 0;
-    CompositeFunc   func = NULL;
-
-#ifdef USE_MMX
-    static Bool mmx_setup = FALSE;
-    if (!mmx_setup) {
-        fbComposeSetupMMX();
-        mmx_setup = TRUE;
-    }
-#endif
-
-    if (srcRepeat && srcTransform &&
-	pSrc->pDrawable->width == 1 &&
-	pSrc->pDrawable->height == 1)
-	srcTransform = FALSE;
+    pixman_region16_t region;
+    pixman_image_t *src, *mask, *dest;
     
-    if (pMask && pMask->pDrawable)
-    {
-	maskRepeat = pMask->repeatType == RepeatNormal;
-
-	if (pMask->filter == PictFilterConvolution)
-	    maskTransform = TRUE;
-
-	maskAlphaMap = pMask->alphaMap != 0;
+    if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
+				   xMask, yMask, xDst, yDst, width, height))
+        return;
 
-	if (maskRepeat && maskTransform &&
-	    pMask->pDrawable->width == 1 &&
-	    pMask->pDrawable->height == 1)
-	    maskTransform = FALSE;
-    }
+    src = image_from_pict (pSrc);
+    mask = image_from_pict (pMask);
+    dest = image_from_pict (pDst);
 
-    if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
-        && !srcTransform && !maskTransform
-        && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
-        && (pSrc->filter != PictFilterConvolution)
-        && (!pMask || pMask->filter != PictFilterConvolution))
-    switch (op) {
-    case PictOpOver:
-	if (pMask)
-	{
-	    if (fbCanGetSolid(pSrc) &&
-		!maskRepeat)
-	    {
-		if (PICT_FORMAT_COLOR(pSrc->format)) {
-		    switch (pMask->format) {
-		    case PICT_a8:
-			switch (pDst->format) {
-			case PICT_r5g6b5:
-			case PICT_b5g6r5:
-#ifdef USE_MMX
-			    if (fbHaveMMX())
-				func = fbCompositeSolidMask_nx8x0565mmx;
-			    else
-#endif
-				func = fbCompositeSolidMask_nx8x0565;
-			    break;
-			case PICT_r8g8b8:
-			case PICT_b8g8r8:
-			    func = fbCompositeSolidMask_nx8x0888;
-			    break;
-			case PICT_a8r8g8b8:
-			case PICT_x8r8g8b8:
-			case PICT_a8b8g8r8:
-			case PICT_x8b8g8r8:
-#ifdef USE_MMX
-			    if (fbHaveMMX())
-				func = fbCompositeSolidMask_nx8x8888mmx;
-			    else
-#endif
-				func = fbCompositeSolidMask_nx8x8888;
-			    break;
-			default:
-			    break;
-			}
-			break;
-		    case PICT_a8r8g8b8:
-			if (pMask->componentAlpha) {
-			    switch (pDst->format) {
-			    case PICT_a8r8g8b8:
-			    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x8888Cmmx;
-				else
-#endif
-				    func = fbCompositeSolidMask_nx8888x8888C;
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x0565Cmmx;
-				else
-#endif
-				    func = fbCompositeSolidMask_nx8888x0565C;
-				break;
-			    default:
-				break;
-			    }
-			}
-#if 0
-			else
-			{
-			    switch (pDst->format) {
-                            case PICT_r5g6b5:
-                                func = fbCompositeSolidMask_nx8888x0565;
-                                break;
-			    default:
-				break;
-                            }
-			}
-#endif
-			break;
-		    case PICT_a8b8g8r8:
-			if (pMask->componentAlpha) {
-			    switch (pDst->format) {
-			    case PICT_a8b8g8r8:
-			    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x8888Cmmx;
-				else
-#endif
-				    func = fbCompositeSolidMask_nx8888x8888C;
-				break;
-			    case PICT_b5g6r5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x0565Cmmx;
-				else
-#endif
-				    func = fbCompositeSolidMask_nx8888x0565C;
-				break;
-			    default:
-				break;
-			    }
-			}
-#if 0
-			else
-			{
-			    switch (pDst->format) {
-                            case PICT_b5g6r5:
-                                func = fbCompositeSolidMask_nx8888x0565;
-                                break;
-			    default:
-				break;
-                            }
-			}
-#endif
-			break;
-		    case PICT_a1:
-			switch (pDst->format) {
-			case PICT_r5g6b5:
-			case PICT_b5g6r5:
-			case PICT_r8g8b8:
-			case PICT_b8g8r8:
-			case PICT_a8r8g8b8:
-			case PICT_x8r8g8b8:
-			case PICT_a8b8g8r8:
-			case PICT_x8b8g8r8:
-			{
-			    FbBits src;
-
-			    fbComposeGetSolid(pSrc, src, pDst->format);
-			    if ((src & 0xff000000) == 0xff000000)
-				func = fbCompositeSolidMask_nx1xn;
-			    break;
-			}
-			default:
-			    break;
-			}
-			break;
-		    default:
-			break;
-		    }
-		}
-		if (func)
-		    srcRepeat = FALSE;
-	    }
-	    else if (!srcRepeat) /* has mask and non-repeating source */
-	    {
-		if (pSrc->pDrawable == pMask->pDrawable &&
-		    xSrc + pSrc->pDrawable->x == xMask + pMask->pDrawable->x &&
-		    ySrc + pSrc->pDrawable->y == yMask + pMask->pDrawable->y &&
-		    !pMask->componentAlpha && !maskRepeat)
-		{
-		    /* source == mask: non-premultiplied data */
-		    switch (pSrc->format) {
-		    case PICT_x8b8g8r8:
-			switch (pMask->format) {
-			case PICT_a8r8g8b8:
-			case PICT_a8b8g8r8:
-			    switch (pDst->format) {
-			    case PICT_a8r8g8b8:
-			    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx8888mmx;
-#endif
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx0565mmx;
-#endif
-				break;
-			    default:
-				break;
-			    }
-			    break;
-			default:
-			    break;
-			}
-			break;
-		    case PICT_x8r8g8b8:
-			switch (pMask->format) {
-			case PICT_a8r8g8b8:
-			case PICT_a8b8g8r8:
-			    switch (pDst->format) {
-			    case PICT_a8b8g8r8:
-			    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx8888mmx;
-#endif
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx0565mmx;
-#endif
-				break;
-			    default:
-				break;
-			    }
-			    break;
-			default:
-			    break;
-			}
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		}
-		else if (maskRepeat &&
-			 pMask->pDrawable->width == 1 &&
-			 pMask->pDrawable->height == 1)
-		{
-		    switch (pSrc->format) {
-#ifdef USE_MMX
-		    case PICT_x8r8g8b8:
-			if ((pDst->format == PICT_a8r8g8b8 ||
-			     pDst->format == PICT_x8r8g8b8) &&
-			    pMask->format == PICT_a8 && fbHaveMMX())
-			    func = fbCompositeSrc_x888x8x8888mmx;
-			break;
-		    case PICT_x8b8g8r8:
-			if ((pDst->format == PICT_a8b8g8r8 ||
-			     pDst->format == PICT_x8b8g8r8) &&
-			    pMask->format == PICT_a8 && fbHaveMMX())
-			    func = fbCompositeSrc_x888x8x8888mmx;
-			break;
-		    case PICT_a8r8g8b8:
-			if ((pDst->format == PICT_a8r8g8b8 ||
-			     pDst->format == PICT_x8r8g8b8) &&
-			    pMask->format == PICT_a8 && fbHaveMMX())
-			    func = fbCompositeSrc_8888x8x8888mmx;
-			break;
-		    case PICT_a8b8g8r8:
-			if ((pDst->format == PICT_a8b8g8r8 ||
-			     pDst->format == PICT_x8b8g8r8) &&
-			    pMask->format == PICT_a8 && fbHaveMMX())
-			    func = fbCompositeSrc_8888x8x8888mmx;
-			break;
-#endif
-		    default:
-			break;
-		    }
-		    
-		    if (func)
-			maskRepeat = FALSE;
-		}
-	    }
-	}
-	else /* no mask */
-	{
-	    if (fbCanGetSolid(pSrc))
-	    {
-		/* no mask and repeating source */
-		switch (pSrc->format) {
-		case PICT_a8r8g8b8:
-		    switch (pDst->format) {
-		    case PICT_a8r8g8b8:
-		    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			{
-			    srcRepeat = FALSE;
-			    func = fbCompositeSolid_nx8888mmx;
-			}
-#endif
-			break;
-		    case PICT_r5g6b5:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			{
-			    srcRepeat = FALSE;
-			    func = fbCompositeSolid_nx0565mmx;
-			}
-#endif
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		default:
-		    break;
-		}
-	    }
-	    else if (! srcRepeat)
-	    {
-		/*
-		 * Formats without alpha bits are just Copy with Over
-		 */
-		if (pSrc->format == pDst->format && !PICT_FORMAT_A(pSrc->format))
-		{
-#ifdef USE_MMX
-		    if (fbHaveMMX() &&
-			(pSrc->format == PICT_x8r8g8b8 || pSrc->format == PICT_x8b8g8r8))
-			func = fbCompositeCopyAreammx;
-		    else
-#endif
-			func = fbCompositeSrcSrc_nxn;
-		}
-		else switch (pSrc->format) {
-		case PICT_a8r8g8b8:
-		    switch (pDst->format) {
-		    case PICT_a8r8g8b8:
-		    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x8888mmx;
-			else
-#endif
-			    func = fbCompositeSrc_8888x8888;
-			break;
-		    case PICT_r8g8b8:
-			func = fbCompositeSrc_8888x0888;
-			break;
-		    case PICT_r5g6b5:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x0565mmx;
-			else
-#endif
-			    func = fbCompositeSrc_8888x0565;
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		case PICT_x8r8g8b8:
-		    switch (pDst->format) {
-		    case PICT_a8r8g8b8:
-		    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeCopyAreammx;
-#endif
-			break;
-		    default:
-			break;
-		    }
-		case PICT_x8b8g8r8:
-		    switch (pDst->format) {
-		    case PICT_a8b8g8r8:
-		    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeCopyAreammx;
-#endif
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		case PICT_a8b8g8r8:
-		    switch (pDst->format) {
-		    case PICT_a8b8g8r8:
-		    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x8888mmx;
-			else
-#endif
-			    func = fbCompositeSrc_8888x8888;
-			break;
-		    case PICT_b8g8r8:
-			func = fbCompositeSrc_8888x0888;
-			break;
-		    case PICT_b5g6r5:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x0565mmx;
-			else
-#endif
-			    func = fbCompositeSrc_8888x0565;
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		default:
-		    break;
-		}
-	    }
-	}
-	break;
-    case PictOpAdd:
-	if (pMask == 0)
-	{
-	    switch (pSrc->format) {
-	    case PICT_a8r8g8b8:
-		switch (pDst->format) {
-		case PICT_a8r8g8b8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8888x8888mmx;
-		    else
-#endif
-			func = fbCompositeSrcAdd_8888x8888;
-		    break;
-		default:
-		    break;
-		}
-		break;
-	    case PICT_a8b8g8r8:
-		switch (pDst->format) {
-		case PICT_a8b8g8r8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8888x8888mmx;
-		    else
-#endif
-			func = fbCompositeSrcAdd_8888x8888;
-		    break;
-		default:
-		    break;
-		}
-		break;
-	    case PICT_a8:
-		switch (pDst->format) {
-		case PICT_a8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8000x8000mmx;
-		    else
-#endif
-			func = fbCompositeSrcAdd_8000x8000;
-		    break;
-		default:
-		    break;
-		}
-		break;
-	    case PICT_a1:
-		switch (pDst->format) {
-		case PICT_a1:
-		    func = fbCompositeSrcAdd_1000x1000;
-		    break;
-		default:
-		    break;
-		}
-		break;
-	    default:
-		break;
-	    }
-	}
-	else
-	{
-	    if ((pSrc->format == PICT_a8r8g8b8	||
-		 pSrc->format == PICT_a8b8g8r8) &&
-		fbCanGetSolid (pSrc)		&&
-		pMask->format == PICT_a8	&&
-		pDst->format == PICT_a8)
-	    {
-		srcRepeat = FALSE;
-#ifdef USE_MMX
-		if (fbHaveMMX())
-		    func = fbCompositeSrcAdd_8888x8x8mmx;
-		else
-#endif
-		    func = fbCompositeSrcAdd_8888x8x8;
-	    }
-	}
-	break;
-    case PictOpSrc:
-	if (pMask)
-	{
-#ifdef USE_MMX
-	    if (fbCanGetSolid (pSrc))
-	    {
-		if (pMask->format == PICT_a8)
-		{
-		    switch (pDst->format)
-		    {
-		    case PICT_a8r8g8b8:
-		    case PICT_x8r8g8b8:
-		    case PICT_a8b8g8r8:
-		    case PICT_x8b8g8r8:
-			if (fbHaveMMX())
-			{
-			    srcRepeat = FALSE;
-			    func = fbCompositeSolidMaskSrc_nx8x8888mmx;
-			}
-			break;
-		    default:
-			break;
-		    }
-		}
-	    }
-#endif
-	}
-	else
-	{
-	    if (pSrc->format == pDst->format)
-	    {
-#ifdef USE_MMX
-		if (pSrc->pDrawable != pDst->pDrawable && fbHaveMMX() &&
-		    (PICT_FORMAT_BPP (pSrc->format) == 16 ||
-		     PICT_FORMAT_BPP (pSrc->format) == 32))
-		    func = fbCompositeCopyAreammx;
-		else
-#endif
-		    func = fbCompositeSrcSrc_nxn;
-	    }
-	}
-	break;
-    case PictOpIn:
-#ifdef USE_MMX
-	if (pSrc->format == PICT_a8 &&
-	    pDst->format == PICT_a8 &&
-	    !pMask)
-	{
-	    if (fbHaveMMX())
-		func = fbCompositeIn_8x8mmx;
-	}
-	else if (srcRepeat && pMask && !pMask->componentAlpha &&
-		 (pSrc->format == PICT_a8r8g8b8 ||
-		  pSrc->format == PICT_a8b8g8r8)   &&
-		 (pMask->format == PICT_a8)        &&
-		 pDst->format == PICT_a8)
-	{
-	    if (fbHaveMMX())
-	    {
-		srcRepeat = FALSE;
-		func = fbCompositeIn_nx8x8mmx;
-	    }
-	}
-#else
-	func = NULL;
-#endif
-       break;
-    default:
-	break;
-    }
-
-    if (!func) {
-	func = fbCompositeRectWrapper;
+    if (src && dest && !(pMask && !mask))
+    {
+	pixman_image_composite (op, src, mask, dest,
+				xSrc, ySrc, xMask, yMask, xDst, yDst,
+				width, height, &region);
     }
-
-    /* if we are transforming, we handle repeats in fbFetchTransformed */
-    if (srcTransform)
-	srcRepeat = FALSE;
-    if (maskTransform)
-	maskRepeat = FALSE;
-
-    fbWalkCompositeRegion (op, pSrc, pMask, pDst, xSrc, ySrc,
-			   xMask, yMask, xDst, yDst, width, height,
-			   srcRepeat, maskRepeat, func);
+    
+    pixman_region_fini (&region);
+    
+    if (src)
+	pixman_image_unref (src);
+    if (mask)
+	pixman_image_unref (mask);
+    if (dest)
+	pixman_image_unref (dest);
 }
 
 void
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 11cab3d..3bd0a78 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -425,197 +425,6 @@ fbRasterizeEdges (FbBits	*buf,
 		  xFixed	b);
 
 /* fbpict.c */
-CARD32
-fbOver (CARD32 x, CARD32 y);
-
-CARD32
-fbOver24 (CARD32 x, CARD32 y);
-
-CARD32
-fbIn (CARD32 x, CARD8 y);
-
-void
-fbCompositeSolidMask_nx8x8888 (CARD8      op,
-			       PicturePtr pSrc,
-			       PicturePtr pMask,
-			       PicturePtr pDst,
-			       INT16      xSrc,
-			       INT16      ySrc,
-			       INT16      xMask,
-			       INT16      yMask,
-			       INT16      xDst,
-			       INT16      yDst,
-			       CARD16     width,
-			       CARD16     height);
-
-void
-fbCompositeSolidMask_nx8x0888 (CARD8      op,
-			       PicturePtr pSrc,
-			       PicturePtr pMask,
-			       PicturePtr pDst,
-			       INT16      xSrc,
-			       INT16      ySrc,
-			       INT16      xMask,
-			       INT16      yMask,
-			       INT16      xDst,
-			       INT16      yDst,
-			       CARD16     width,
-			       CARD16     height);
-
-void
-fbCompositeSolidMask_nx8888x8888C (CARD8      op,
-				   PicturePtr pSrc,
-				   PicturePtr pMask,
-				   PicturePtr pDst,
-				   INT16      xSrc,
-				   INT16      ySrc,
-				   INT16      xMask,
-				   INT16      yMask,
-				   INT16      xDst,
-				   INT16      yDst,
-				   CARD16     width,
-				   CARD16     height);
-
-void
-fbCompositeSolidMask_nx8x0565 (CARD8      op,
-			       PicturePtr pSrc,
-			       PicturePtr pMask,
-			       PicturePtr pDst,
-			       INT16      xSrc,
-			       INT16      ySrc,
-			       INT16      xMask,
-			       INT16      yMask,
-			       INT16      xDst,
-			       INT16      yDst,
-			       CARD16     width,
-			       CARD16     height);
-
-void
-fbCompositeSolidMask_nx8888x0565C (CARD8      op,
-				   PicturePtr pSrc,
-				   PicturePtr pMask,
-				   PicturePtr pDst,
-				   INT16      xSrc,
-				   INT16      ySrc,
-				   INT16      xMask,
-				   INT16      yMask,
-				   INT16      xDst,
-				   INT16      yDst,
-				   CARD16     width,
-				   CARD16     height);
-
-void
-fbCompositeSrc_8888x8888 (CARD8      op,
-			  PicturePtr pSrc,
-			  PicturePtr pMask,
-			  PicturePtr pDst,
-			  INT16      xSrc,
-			  INT16      ySrc,
-			  INT16      xMask,
-			  INT16      yMask,
-			  INT16      xDst,
-			  INT16      yDst,
-			  CARD16     width,
-			  CARD16     height);
-
-void
-fbCompositeSrc_8888x0888 (CARD8      op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height);
-
-void
-fbCompositeSrc_8888x0565 (CARD8      op,
-			  PicturePtr pSrc,
-			  PicturePtr pMask,
-			  PicturePtr pDst,
-			  INT16      xSrc,
-			  INT16      ySrc,
-			  INT16      xMask,
-			  INT16      yMask,
-			  INT16      xDst,
-			  INT16      yDst,
-			  CARD16     width,
-			  CARD16     height);
-
-void
-fbCompositeSrc_0565x0565 (CARD8      op,
-			  PicturePtr pSrc,
-			  PicturePtr pMask,
-			  PicturePtr pDst,
-			  INT16      xSrc,
-			  INT16      ySrc,
-			  INT16      xMask,
-			  INT16      yMask,
-			  INT16      xDst,
-			  INT16      yDst,
-			  CARD16     width,
-			  CARD16     height);
-
-void
-fbCompositeSrcAdd_8000x8000 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height);
-
-void
-fbCompositeSrcAdd_8888x8888 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height);
-
-void
-fbCompositeSrcAdd_1000x1000 (CARD8	op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height);
-
-void
-fbCompositeSolidMask_nx1xn (CARD8      op,
-			    PicturePtr pSrc,
-			    PicturePtr pMask,
-			    PicturePtr pDst,
-			    INT16      xSrc,
-			    INT16      ySrc,
-			    INT16      xMask,
-			    INT16      yMask,
-			    INT16      xDst,
-			    INT16      yDst,
-			    CARD16     width,
-			    CARD16     height);
-
 void
 fbComposite (CARD8      op,
 	     PicturePtr pSrc,
diff-tree 7e2c935920cafadbd87c351f1a3239932864fb90 (from 756acea23a0cc56c470bcd77c6f5638d923ab3d1)
Author: Fredrik Höglund <fredrik at kde.org>
Date:   Fri May 18 20:06:14 2007 +0200

    Add a new IDLETIME system sync counter.
    
    This counter exposes the time in milliseconds since the last
    input event. Clients such as screen savers and power managers
    can set an alarm on this counter to find out when the idle time
    reaches a certain value, without having to poll the server.

diff --git a/Xext/sync.c b/Xext/sync.c
index c5441a1..6fc2dcc 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -243,6 +243,11 @@ SyncInitServerTime(
     void
 );
 
+static void
+SyncInitIdleTime(
+    void
+);
+
 static void 
 SyncResetProc(
     ExtensionEntry * /* extEntry */
@@ -2400,6 +2405,7 @@ SyncExtensionInit(INITARGS)
      * because there is always a servertime counter.
      */
     SyncInitServerTime();
+    SyncInitIdleTime();
 
 #ifdef DEBUG
     fprintf(stderr, "Sync Extension %d.%d\n",
@@ -2520,3 +2526,116 @@ SyncInitServerTime(void)
 			    ServertimeQueryValue, ServertimeBracketValues);
     pnext_time = NULL;
 }
+
+
+
+/*
+ * IDLETIME implementation
+ */
+
+static pointer IdleTimeCounter;
+static XSyncValue *pIdleTimeValueLess;
+static XSyncValue *pIdleTimeValueGreater;
+
+static void
+IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
+{
+    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
+    XSyncIntsToValue (pValue_return, idle, 0);
+}
+
+static void
+IdleTimeBlockHandler (pointer env,
+                      struct timeval **wt,
+                      pointer LastSelectMask)
+{
+    XSyncValue idle;
+
+    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
+	return;
+
+    IdleTimeQueryValue (NULL, &idle);
+
+    if (pIdleTimeValueLess &&
+        XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
+    {
+	AdjustWaitForDelay (wt, 0);
+    }
+    else if (pIdleTimeValueGreater)
+    {
+	unsigned long timeout = 0;
+
+	if (XSyncValueLessThan (idle, *pIdleTimeValueGreater))
+	{
+	    XSyncValue value;
+	    Bool overflow;
+
+	    XSyncValueSubtract (&value, *pIdleTimeValueGreater,
+	                        idle, &overflow);
+	    timeout = XSyncValueLow32 (value);
+	}
+
+	AdjustWaitForDelay (wt, timeout);
+    }
+}
+
+static void
+IdleTimeWakeupHandler (pointer env,
+                       int rc,
+                       pointer LastSelectMask)
+{
+    XSyncValue idle;
+
+    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
+	return;
+
+    IdleTimeQueryValue (NULL, &idle);
+
+    if ((pIdleTimeValueGreater &&
+         XSyncValueGreaterThan (idle, *pIdleTimeValueGreater)) ||
+        (pIdleTimeValueLess && XSyncValueLessThan (idle, *pIdleTimeValueLess)))
+    {
+	SyncChangeCounter (IdleTimeCounter, idle);
+    }
+}
+
+static void
+IdleTimeBracketValues (pointer pCounter,
+                       CARD64 *pbracket_less,
+                       CARD64 *pbracket_greater)
+{
+    Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
+
+    if (registered && !pbracket_less && !pbracket_greater)
+    {
+	RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
+	                             IdleTimeWakeupHandler,
+	                             NULL);
+    }
+    else if (!registered && (pbracket_less || pbracket_greater))
+    {
+	RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
+	                               IdleTimeWakeupHandler,
+	                               NULL);
+    }
+
+    pIdleTimeValueGreater = pbracket_greater;
+    pIdleTimeValueLess    = pbracket_less;
+}
+
+static void
+SyncInitIdleTime (void)
+{
+    CARD64 resolution;
+    XSyncValue idle;
+
+    IdleTimeQueryValue (NULL, &idle);
+    XSyncIntToValue (&resolution, 4);
+
+    IdleTimeCounter = SyncCreateSystemCounter ("IDLETIME", idle, resolution,
+                                               XSyncCounterUnrestricted,
+                                               IdleTimeQueryValue,
+                                               IdleTimeBracketValues);
+
+    pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
+}
diff-tree 756acea23a0cc56c470bcd77c6f5638d923ab3d1 (from 7916419a0092b8bf9713c0840f9e969950d7aa85)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri May 18 13:39:12 2007 -0400

    Use pixman_image_set_indexed() to make 8 bit work

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 324d9b2..84d19ac 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1036,6 +1036,10 @@ create_bits_picture (PicturePtr pict)
      */
     pixman_image_set_clip_region (image, pict->pCompositeClip);
     
+    /* Indexed table */
+    if (pict->pFormat->index.devPrivate)
+	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
+    
     fbFinishAccess (pict->pDrawable);
 
     return image;
diff-tree 7916419a0092b8bf9713c0840f9e969950d7aa85 (from 998164bac648756e5b5254aa36e075ae360d3972)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri May 18 11:58:24 2007 -0400

    Comment out setup of general MMX code

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 8a132f6..53459a0 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -878,10 +878,15 @@ mmxCombineAddC (CARD32 *dest, CARD32 *sr
     _mm_empty();
 }
 
+#if 0
+/* FIXME: this should be reinstated after adding fbmmx to pixman */
 extern FbComposeFunctions composeFunctions;
+#endif
 
 void fbComposeSetupMMX(void)
 {
+#if 0
+/* FIXME: this should be reinstated after adding fbmmx to pixman */
     /* check if we have MMX support and initialize accordingly */
     if (fbHaveMMX()) {
         composeFunctions.combineU[PictOpOver] = mmxCombineOverU;
@@ -910,6 +915,7 @@ void fbComposeSetupMMX(void)
 
         composeFunctions.combineMaskU = mmxCombineMaskU;
     } 
+#endif
 }
 
 
diff-tree 998164bac648756e5b5254aa36e075ae360d3972 (from a2e3614eb8f0fa198615df492b03ff36bc9c1121)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri May 18 11:36:20 2007 -0400

    Move fbCompositeGeneral() to fbpict.c and remove fbcompose.c

diff --git a/fb/Makefile.am b/fb/Makefile.am
index ab135c9..01e81da 100644
--- a/fb/Makefile.am
+++ b/fb/Makefile.am
@@ -42,7 +42,6 @@ libfb_la_SOURCES = 	\
 	fbblt.c		\
 	fbbltone.c	\
 	fbbstore.c	\
-	fbcompose.c	\
 	fbcopy.c	\
 	fbfill.c	\
 	fbfillrect.c	\
diff --git a/fb/fbcompose.c b/fb/fbcompose.c
deleted file mode 100644
index 0e64de0..0000000
--- a/fb/fbcompose.c
+++ /dev/null
@@ -1,4318 +0,0 @@
-/*
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- *             2005 Lars Knoll & Zack Rusin, Trolltech
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "fb.h"
-
-#ifdef RENDER
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-
-#include "picturestr.h"
-#include "mipict.h"
-#include "fbpict.h"
-
-static unsigned int
-SourcePictureClassify (PicturePtr pict,
-		       int	  x,
-		       int	  y,
-		       int	  width,
-		       int	  height)
-{
-    if (pict->pSourcePict->type == SourcePictTypeSolidFill)
-    {
-	pict->pSourcePict->solidFill.class = SourcePictClassHorizontal;
-    }
-    else if (pict->pSourcePict->type == SourcePictTypeLinear)
-    {
-	PictVector   v;
-	xFixed_32_32 l;
-	xFixed_48_16 dx, dy, a, b, off;
-	xFixed_48_16 factors[4];
-	int	     i;
-
-	dx = pict->pSourcePict->linear.p2.x - pict->pSourcePict->linear.p1.x;
-	dy = pict->pSourcePict->linear.p2.y - pict->pSourcePict->linear.p1.y;
-	l = dx * dx + dy * dy;
-	if (l)
-	{
-	    a = (dx << 32) / l;
-	    b = (dy << 32) / l;
-	}
-	else
-	{
-	    a = b = 0;
-	}
-
-	off = (-a * pict->pSourcePict->linear.p1.x
-	       -b * pict->pSourcePict->linear.p1.y) >> 16;
-
-	for (i = 0; i < 3; i++)
-	{
-	    v.vector[0] = IntToxFixed ((i % 2) * (width  - 1) + x);
-	    v.vector[1] = IntToxFixed ((i / 2) * (height - 1) + y);
-	    v.vector[2] = xFixed1;
-
-	    if (pict->transform)
-	    {
-		if (!PictureTransformPoint3d (pict->transform, &v))
-		    return SourcePictClassUnknown;
-	    }
-
-	    factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
-	}
-
-	if (factors[2] == factors[0])
-	    pict->pSourcePict->linear.class = SourcePictClassHorizontal;
-	else if (factors[1] == factors[0])
-	    pict->pSourcePict->linear.class = SourcePictClassVertical;
-    }
-
-    return pict->pSourcePict->solidFill.class;
-}
-
-#define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
-
-#define SCANLINE_BUFFER_LENGTH 2048
-
-typedef FASTCALL void (*fetchProc)(const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed);
-
-/*
- * All of the fetch functions
- */
-
-static FASTCALL void
-fbFetch_a8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    MEMCPY_WRAPPED(buffer, (const CARD32 *)bits + x, width*sizeof(CARD32));
-}
-
-static FASTCALL void
-fbFetch_x8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD32 *pixel = (const CARD32 *)bits + x;
-    const CARD32 *end = pixel + width;
-    while (pixel < end) {
-        WRITE(buffer++, READ(pixel++) | 0xff000000);
-    }
-}
-
-static FASTCALL void
-fbFetch_a8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD32 *pixel = (CARD32 *)bits + x;
-    const CARD32 *end = pixel + width;
-    while (pixel < end) {
-        WRITE(buffer++, ((READ(pixel) & 0xff00ff00) |
-                         ((READ(pixel) >> 16) & 0xff) |
-                         ((READ(pixel) & 0xff) << 16)));
-        ++pixel;
-    }
-}
-
-static FASTCALL void
-fbFetch_x8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD32 *pixel = (CARD32 *)bits + x;
-    const CARD32 *end = pixel + width;
-    while (pixel < end) {
-        WRITE(buffer++, 0xff000000 |
-	      ((READ(pixel) & 0x0000ff00) |
-	       ((READ(pixel) >> 16) & 0xff) |
-	       ((READ(pixel) & 0xff) << 16)));
-        ++pixel;
-    }
-}
-
-static FASTCALL void
-fbFetch_r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + 3*x;
-    const CARD8 *end = pixel + 3*width;
-    while (pixel < end) {
-        CARD32 b = Fetch24(pixel) | 0xff000000;
-        pixel += 3;
-        WRITE(buffer++, b);
-    }
-}
-
-static FASTCALL void
-fbFetch_b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + 3*x;
-    const CARD8 *end = pixel + 3*width;
-    while (pixel < end) {
-        CARD32 b = 0xff000000;
-#if IMAGE_BYTE_ORDER == MSBFirst
-        b |= (READ(pixel++));
-        b |= (READ(pixel++) << 8);
-        b |= (READ(pixel++) << 16);
-#else
-        b |= (READ(pixel++) << 16);
-        b |= (READ(pixel++) << 8);
-        b |= (READ(pixel++));
-#endif
-	WRITE(buffer++, b);
-    }
-}
-
-static FASTCALL void
-fbFetch_r5g6b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32 r = (((p) << 3) & 0xf8) | 
-	    (((p) << 5) & 0xfc00) |
-	    (((p) << 8) & 0xf80000);
-        r |= (r >> 5) & 0x70007;
-        r |= (r >> 6) & 0x300;
-        WRITE(buffer++, 0xff000000 | r);
-    }
-}
-
-static FASTCALL void
-fbFetch_b5g6r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
-        g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
-        r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b, a;
-
-        a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
-        r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
-        g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
-        b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-        WRITE(buffer++, (a | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_x1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
-        g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
-        b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b, a;
-
-        a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
-        b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
-        g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
-        r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-        WRITE(buffer++, (a | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_x1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
-        g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
-        r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b, a;
-
-        a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
-        r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
-        g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
-        b = ((p & 0x000f) | ((p & 0x000f) << 4));
-        WRITE(buffer++, (a | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_x4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
-        g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
-        b = ((p & 0x000f) | ((p & 0x000f) << 4));
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b, a;
-
-        a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
-        b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
-        g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
-        r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-        WRITE(buffer++, (a | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_x4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD16 *pixel = (const CARD16 *)bits + x;
-    const CARD16 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
-        g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
-        r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        WRITE(buffer++, READ(pixel++) << 24);
-    }
-}
-
-static FASTCALL void
-fbFetch_r3g3b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
-        g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
-        b = (((p & 0x03)     ) |
-             ((p & 0x03) << 2) |
-             ((p & 0x03) << 4) |
-             ((p & 0x03) << 6));
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_b2g3r3 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32  r,g,b;
-
-        b = (((p & 0xc0)     ) |
-             ((p & 0xc0) >> 2) |
-             ((p & 0xc0) >> 4) |
-             ((p & 0xc0) >> 6));
-        g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
-        r = (((p & 0x07)     ) |
-             ((p & 0x07) << 3) |
-             ((p & 0x06) << 6)) << 16;
-        WRITE(buffer++, (0xff000000 | r | g | b));
-    }
-}
-
-static FASTCALL void
-fbFetch_a2r2g2b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32   a,r,g,b;
-
-        a = ((p & 0xc0) * 0x55) << 18;
-        r = ((p & 0x30) * 0x55) << 12;
-        g = ((p & 0x0c) * 0x55) << 6;
-        b = ((p & 0x03) * 0x55);
-        WRITE(buffer++, a|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_a2b2g2r2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        CARD32   a,r,g,b;
-
-        a = ((p & 0xc0) * 0x55) << 18;
-        b = ((p & 0x30) * 0x55) >> 6;
-        g = ((p & 0x0c) * 0x55) << 6;
-        r = ((p & 0x03) * 0x55) << 16;
-        WRITE(buffer++, a|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_c8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-        CARD32  p = READ(pixel++);
-        WRITE(buffer++, indexed->rgba[p]);
-    }
-}
-
-static FASTCALL void
-fbFetch_x4a4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    const CARD8 *pixel = (const CARD8 *)bits + x;
-    const CARD8 *end = pixel + width;
-    while (pixel < end) {
-	CARD8 p = READ(pixel++) & 0xf;
-        WRITE(buffer++, (p | (p << 4)) << 24);
-    }
-}
-
-#define Fetch8(l,o)    (((CARD8 *) (l))[(o) >> 2])
-#if IMAGE_BYTE_ORDER == MSBFirst
-#define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
-#else
-#define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
-#endif
-
-static FASTCALL void
-fbFetch_a4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-
-        p |= p << 4;
-        WRITE(buffer++, p << 24);
-    }
-}
-
-static FASTCALL void
-fbFetch_r1g2b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-        CARD32  r,g,b;
-
-        r = ((p & 0x8) * 0xff) << 13;
-        g = ((p & 0x6) * 0x55) << 7;
-        b = ((p & 0x1) * 0xff);
-        WRITE(buffer++, 0xff000000|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_b1g2r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-        CARD32  r,g,b;
-
-        b = ((p & 0x8) * 0xff) >> 3;
-        g = ((p & 0x6) * 0x55) << 7;
-        r = ((p & 0x1) * 0xff) << 16;
-        WRITE(buffer++, 0xff000000|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_a1r1g1b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-        CARD32  a,r,g,b;
-
-        a = ((p & 0x8) * 0xff) << 21;
-        r = ((p & 0x4) * 0xff) << 14;
-        g = ((p & 0x2) * 0xff) << 7;
-        b = ((p & 0x1) * 0xff);
-        WRITE(buffer++, a|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_a1b1g1r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-        CARD32  a,r,g,b;
-
-        a = ((p & 0x8) * 0xff) << 21;
-        r = ((p & 0x4) * 0xff) >> 3;
-        g = ((p & 0x2) * 0xff) << 7;
-        b = ((p & 0x1) * 0xff) << 16;
-        WRITE(buffer++, a|r|g|b);
-    }
-}
-
-static FASTCALL void
-fbFetch_c4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = Fetch4(bits, i + x);
-
-        WRITE(buffer++, indexed->rgba[p]);
-    }
-}
-
-
-static FASTCALL void
-fbFetch_a1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = ((CARD32 *)bits)[(i + x) >> 5];
-        CARD32  a;
-#if BITMAP_BIT_ORDER == MSBFirst
-        a = p >> (0x1f - ((i+x) & 0x1f));
-#else
-        a = p >> ((i+x) & 0x1f);
-#endif
-        a = a & 1;
-        a |= a << 1;
-        a |= a << 2;
-        a |= a << 4;
-        WRITE(buffer++, a << 24);
-    }
-}
-
-static FASTCALL void
-fbFetch_g1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  p = ((CARD32 *)bits)[(i+x) >> 5];
-        CARD32 a;
-#if BITMAP_BIT_ORDER == MSBFirst
-        a = p >> (0x1f - ((i+x) & 0x1f));
-#else
-        a = p >> ((i+x) & 0x1f);
-#endif
-        a = a & 1;
-        WRITE(buffer++, indexed->rgba[a]);
-    }
-}
-
-static fetchProc fetchProcForPicture (PicturePtr pict)
-{
-    switch(pict->format) {
-    case PICT_a8r8g8b8: return fbFetch_a8r8g8b8;
-    case PICT_x8r8g8b8: return fbFetch_x8r8g8b8;
-    case PICT_a8b8g8r8: return fbFetch_a8b8g8r8;
-    case PICT_x8b8g8r8: return fbFetch_x8b8g8r8;
-
-        /* 24bpp formats */
-    case PICT_r8g8b8: return fbFetch_r8g8b8;
-    case PICT_b8g8r8: return fbFetch_b8g8r8;
-
-        /* 16bpp formats */
-    case PICT_r5g6b5: return fbFetch_r5g6b5;
-    case PICT_b5g6r5: return fbFetch_b5g6r5;
-
-    case PICT_a1r5g5b5: return fbFetch_a1r5g5b5;
-    case PICT_x1r5g5b5: return fbFetch_x1r5g5b5;
-    case PICT_a1b5g5r5: return fbFetch_a1b5g5r5;
-    case PICT_x1b5g5r5: return fbFetch_x1b5g5r5;
-    case PICT_a4r4g4b4: return fbFetch_a4r4g4b4;
-    case PICT_x4r4g4b4: return fbFetch_x4r4g4b4;
-    case PICT_a4b4g4r4: return fbFetch_a4b4g4r4;
-    case PICT_x4b4g4r4: return fbFetch_x4b4g4r4;
-
-        /* 8bpp formats */
-    case PICT_a8: return  fbFetch_a8;
-    case PICT_r3g3b2: return fbFetch_r3g3b2;
-    case PICT_b2g3r3: return fbFetch_b2g3r3;
-    case PICT_a2r2g2b2: return fbFetch_a2r2g2b2;
-    case PICT_a2b2g2r2: return fbFetch_a2b2g2r2;
-    case PICT_c8: return  fbFetch_c8;
-    case PICT_g8: return  fbFetch_c8;
-    case PICT_x4a4: return fbFetch_x4a4;
-
-        /* 4bpp formats */
-    case PICT_a4: return  fbFetch_a4;
-    case PICT_r1g2b1: return fbFetch_r1g2b1;
-    case PICT_b1g2r1: return fbFetch_b1g2r1;
-    case PICT_a1r1g1b1: return fbFetch_a1r1g1b1;
-    case PICT_a1b1g1r1: return fbFetch_a1b1g1r1;
-    case PICT_c4: return  fbFetch_c4;
-    case PICT_g4: return  fbFetch_c4;
-
-        /* 1bpp formats */
-    case PICT_a1: return  fbFetch_a1;
-    case PICT_g1: return  fbFetch_g1;
-    }
-
-    return NULL;
-}
-
-/*
- * Pixel wise fetching
- */
-
-typedef FASTCALL CARD32 (*fetchPixelProc)(const FbBits *bits, int offset, miIndexedPtr indexed);
-
-static FASTCALL CARD32
-fbFetchPixel_a8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    return READ((CARD32 *)bits + offset);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    return READ((CARD32 *)bits + offset) | 0xff000000;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD32 *)bits + offset);
-
-    return ((pixel & 0xff000000) |
-	    ((pixel >> 16) & 0xff) |
-	    (pixel & 0x0000ff00) |
-	    ((pixel & 0xff) << 16));
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD32 *)bits + offset);
-
-    return ((0xff000000) |
-	    ((pixel >> 16) & 0xff) |
-	    (pixel & 0x0000ff00) |
-	    ((pixel & 0xff) << 16));
-}
-
-static FASTCALL CARD32
-fbFetchPixel_r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD8   *pixel = ((CARD8 *) bits) + (offset*3);
-#if IMAGE_BYTE_ORDER == MSBFirst
-    return (0xff000000 |
-	    (READ(pixel + 0) << 16) |
-	    (READ(pixel + 1) << 8) |
-	    (READ(pixel + 2)));
-#else
-    return (0xff000000 |
-            (READ(pixel + 2) << 16) |
-            (READ(pixel + 1) << 8) |
-            (READ(pixel + 0)));
-#endif
-}
-
-static FASTCALL CARD32
-fbFetchPixel_b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD8   *pixel = ((CARD8 *) bits) + (offset*3);
-#if IMAGE_BYTE_ORDER == MSBFirst
-    return (0xff000000 |
-	    (READ(pixel + 2) << 16) |
-	    (READ(pixel + 1) << 8) |
-	    (READ(pixel + 0)));
-#else
-    return (0xff000000 |
-	    (READ(pixel + 0) << 16) |
-	    (READ(pixel + 1) << 8) |
-	    (READ(pixel + 2)));
-#endif
-}
-
-static FASTCALL CARD32
-fbFetchPixel_r5g6b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
-    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
-    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_b5g6r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
-    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
-    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  a,r,g,b;
-
-    a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
-    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
-    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-    return (a | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
-    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  a,r,g,b;
-
-    a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
-    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
-    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-    return (a | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
-    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  a,r,g,b;
-
-    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
-    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
-    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-    return (a | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
-    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  a,r,g,b;
-
-    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
-    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
-    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-    return (a | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = READ((CARD16 *) bits + offset);
-    CARD32  r,g,b;
-
-    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
-    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-
-    return pixel << 24;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_r3g3b2 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-    CARD32  r,g,b;
-
-    r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
-    g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
-    b = (((pixel & 0x03)     ) |
-	 ((pixel & 0x03) << 2) |
-	 ((pixel & 0x03) << 4) |
-	 ((pixel & 0x03) << 6));
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_b2g3r3 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-    CARD32  r,g,b;
-
-    b = (((pixel & 0xc0)     ) |
-	 ((pixel & 0xc0) >> 2) |
-	 ((pixel & 0xc0) >> 4) |
-	 ((pixel & 0xc0) >> 6));
-    g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
-    r = (((pixel & 0x07)     ) |
-	 ((pixel & 0x07) << 3) |
-	 ((pixel & 0x06) << 6)) << 16;
-    return (0xff000000 | r | g | b);
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a2r2g2b2 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-    CARD32   a,r,g,b;
-
-    a = ((pixel & 0xc0) * 0x55) << 18;
-    r = ((pixel & 0x30) * 0x55) << 12;
-    g = ((pixel & 0x0c) * 0x55) << 6;
-    b = ((pixel & 0x03) * 0x55);
-    return a|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a2b2g2r2 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-    CARD32   a,r,g,b;
-
-    a = ((pixel & 0xc0) * 0x55) << 18;
-    b = ((pixel & 0x30) * 0x55) >> 6;
-    g = ((pixel & 0x0c) * 0x55) << 6;
-    r = ((pixel & 0x03) * 0x55) << 16;
-    return a|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_c8 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-    return indexed->rgba[pixel];
-}
-
-static FASTCALL CARD32
-fbFetchPixel_x4a4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32   pixel = READ((CARD8 *) bits + offset);
-
-    return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
-}
-
-#define Fetch8(l,o)    (((CARD8 *) (l))[(o) >> 2])
-#if IMAGE_BYTE_ORDER == MSBFirst
-#define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
-#else
-#define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
-#endif
-
-static FASTCALL CARD32
-fbFetchPixel_a4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-
-    pixel |= pixel << 4;
-    return pixel << 24;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_r1g2b1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-    CARD32  r,g,b;
-
-    r = ((pixel & 0x8) * 0xff) << 13;
-    g = ((pixel & 0x6) * 0x55) << 7;
-    b = ((pixel & 0x1) * 0xff);
-    return 0xff000000|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_b1g2r1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-    CARD32  r,g,b;
-
-    b = ((pixel & 0x8) * 0xff) >> 3;
-    g = ((pixel & 0x6) * 0x55) << 7;
-    r = ((pixel & 0x1) * 0xff) << 16;
-    return 0xff000000|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a1r1g1b1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-    CARD32  a,r,g,b;
-
-    a = ((pixel & 0x8) * 0xff) << 21;
-    r = ((pixel & 0x4) * 0xff) << 14;
-    g = ((pixel & 0x2) * 0xff) << 7;
-    b = ((pixel & 0x1) * 0xff);
-    return a|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_a1b1g1r1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-    CARD32  a,r,g,b;
-
-    a = ((pixel & 0x8) * 0xff) << 21;
-    r = ((pixel & 0x4) * 0xff) >> 3;
-    g = ((pixel & 0x2) * 0xff) << 7;
-    b = ((pixel & 0x1) * 0xff) << 16;
-    return a|r|g|b;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_c4 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = Fetch4(bits, offset);
-
-    return indexed->rgba[pixel];
-}
-
-
-static FASTCALL CARD32
-fbFetchPixel_a1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32  pixel = ((CARD32 *)bits)[offset >> 5];
-    CARD32  a;
-#if BITMAP_BIT_ORDER == MSBFirst
-    a = pixel >> (0x1f - (offset & 0x1f));
-#else
-    a = pixel >> (offset & 0x1f);
-#endif
-    a = a & 1;
-    a |= a << 1;
-    a |= a << 2;
-    a |= a << 4;
-    return a << 24;
-}
-
-static FASTCALL CARD32
-fbFetchPixel_g1 (const FbBits *bits, int offset, miIndexedPtr indexed)
-{
-    CARD32 pixel = ((CARD32 *)bits)[offset >> 5];
-    CARD32 a;
-#if BITMAP_BIT_ORDER == MSBFirst
-    a = pixel >> (0x1f - (offset & 0x1f));
-#else
-    a = pixel >> (offset & 0x1f);
-#endif
-    a = a & 1;
-    return indexed->rgba[a];
-}
-
-static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict)
-{
-    switch(pict->format) {
-    case PICT_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
-    case PICT_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
-    case PICT_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
-    case PICT_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
-
-        /* 24bpp formats */
-    case PICT_r8g8b8: return fbFetchPixel_r8g8b8;
-    case PICT_b8g8r8: return fbFetchPixel_b8g8r8;
-
-        /* 16bpp formats */
-    case PICT_r5g6b5: return fbFetchPixel_r5g6b5;
-    case PICT_b5g6r5: return fbFetchPixel_b5g6r5;
-
-    case PICT_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
-    case PICT_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
-    case PICT_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
-    case PICT_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
-    case PICT_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
-    case PICT_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
-    case PICT_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
-    case PICT_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
-
-        /* 8bpp formats */
-    case PICT_a8: return  fbFetchPixel_a8;
-    case PICT_r3g3b2: return fbFetchPixel_r3g3b2;
-    case PICT_b2g3r3: return fbFetchPixel_b2g3r3;
-    case PICT_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
-    case PICT_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
-    case PICT_c8: return  fbFetchPixel_c8;
-    case PICT_g8: return  fbFetchPixel_c8;
-    case PICT_x4a4: return fbFetchPixel_x4a4;
-
-        /* 4bpp formats */
-    case PICT_a4: return  fbFetchPixel_a4;
-    case PICT_r1g2b1: return fbFetchPixel_r1g2b1;
-    case PICT_b1g2r1: return fbFetchPixel_b1g2r1;
-    case PICT_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
-    case PICT_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
-    case PICT_c4: return  fbFetchPixel_c4;
-    case PICT_g4: return  fbFetchPixel_c4;
-
-        /* 1bpp formats */
-    case PICT_a1: return  fbFetchPixel_a1;
-    case PICT_g1: return  fbFetchPixel_g1;
-    }
-
-    return NULL;
-}
-
-
-
-/*
- * All the store functions
- */
-
-typedef FASTCALL void (*storeProc) (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed);
-
-#define Splita(v)	CARD32	a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
-#define Split(v)	CARD32	r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
-
-static FASTCALL void
-fbStore_a8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    MEMCPY_WRAPPED(((CARD32 *)bits) + x, values, width*sizeof(CARD32));
-}
-
-static FASTCALL void
-fbStore_x8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD32 *pixel = (CARD32 *)bits + x;
-    for (i = 0; i < width; ++i)
-        WRITE(pixel++, READ(values + i) & 0xffffff);
-}
-
-static FASTCALL void
-fbStore_a8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD32 *pixel = (CARD32 *)bits + x;
-    for (i = 0; i < width; ++i)
-        WRITE(pixel++, (READ(values + i) & 0xff00ff00) | ((READ(values + i) >> 16) & 0xff) | ((READ(values + i) & 0xff) << 16));
-}
-
-static FASTCALL void
-fbStore_x8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD32 *pixel = (CARD32 *)bits + x;
-    for (i = 0; i < width; ++i)
-        WRITE(pixel++, (READ(values + i) & 0x0000ff00) | ((READ(values + i) >> 16) & 0xff) | ((READ(values + i) & 0xff) << 16));
-}
-
-static FASTCALL void
-fbStore_r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8 *pixel = ((CARD8 *) bits) + 3*x;
-    for (i = 0; i < width; ++i) {
-        Store24(pixel, READ(values + i));
-        pixel += 3;
-    }
-}
-
-static FASTCALL void
-fbStore_b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8 *pixel = ((CARD8 *) bits) + 3*x;
-    for (i = 0; i < width; ++i) {
-        CARD32 val = READ(values + i);
-#if IMAGE_BYTE_ORDER == MSBFirst
-        WRITE(pixel++, Blue(val));
-        WRITE(pixel++, Green(val));
-        WRITE(pixel++, Red(val));
-#else
-        WRITE(pixel++, Red(val));
-        WRITE(pixel++, Green(val));
-        WRITE(pixel++, Blue(val));
-#endif
-    }
-}
-
-static FASTCALL void
-fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16 *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(values + i);
-        WRITE(pixel++, ((s >> 3) & 0x001f) |
-	      ((s >> 5) & 0x07e0) |
-	      ((s >> 8) & 0xf800));
-    }
-}
-
-static FASTCALL void
-fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((b << 8) & 0xf800) |
-	      ((g << 3) & 0x07e0) |
-	      ((r >> 3)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_a1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Splita(READ(values + i));
-        WRITE(pixel++, ((a << 8) & 0x8000) |
-	      ((r << 7) & 0x7c00) |
-	      ((g << 2) & 0x03e0) |
-	      ((b >> 3)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_x1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((r << 7) & 0x7c00) |
-	      ((g << 2) & 0x03e0) |
-	      ((b >> 3)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_a1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Splita(READ(values + i));
-        WRITE(pixel++, ((a << 8) & 0x8000) |
-	      ((b << 7) & 0x7c00) |
-	      ((g << 2) & 0x03e0) |
-	      ((r >> 3)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_x1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((b << 7) & 0x7c00) |
-	      ((g << 2) & 0x03e0) |
-	      ((r >> 3)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_a4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Splita(READ(values + i));
-        WRITE(pixel++, ((a << 8) & 0xf000) |
-	      ((r << 4) & 0x0f00) |
-	      ((g     ) & 0x00f0) |
-	      ((b >> 4)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_x4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((r << 4) & 0x0f00) |
-	      ((g     ) & 0x00f0) |
-	      ((b >> 4)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_a4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Splita(READ(values + i));
-        WRITE(pixel++, ((a << 8) & 0xf000) |
-	      ((b << 4) & 0x0f00) |
-	      ((g     ) & 0x00f0) |
-	      ((r >> 4)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_x4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD16  *pixel = ((CARD16 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((b << 4) & 0x0f00) |
-	      ((g     ) & 0x00f0) |
-	      ((r >> 4)         ));
-    }
-}
-
-static FASTCALL void
-fbStore_a8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        WRITE(pixel++, READ(values + i) >> 24);
-    }
-}
-
-static FASTCALL void
-fbStore_r3g3b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((r     ) & 0xe0) |
-	      ((g >> 3) & 0x1c) |
-	      ((b >> 6)       ));
-    }
-}
-
-static FASTCALL void
-fbStore_b2g3r3 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Split(READ(values + i));
-        WRITE(pixel++, ((b     ) & 0xe0) |
-	      ((g >> 3) & 0x1c) |
-	      ((r >> 6)       ));
-    }
-}
-
-static FASTCALL void
-fbStore_a2r2g2b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        Splita(READ(values + i));
-        WRITE(pixel++, ((a     ) & 0xc0) |
-	      ((r >> 2) & 0x30) |
-	      ((g >> 4) & 0x0c) |
-	      ((b >> 6)       ));
-    }
-}
-
-static FASTCALL void
-fbStore_c8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        WRITE(pixel++, miIndexToEnt24(indexed,READ(values + i)));
-    }
-}
-
-static FASTCALL void
-fbStore_x4a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    CARD8   *pixel = ((CARD8 *) bits) + x;
-    for (i = 0; i < width; ++i) {
-        WRITE(pixel++, READ(values + i) >> 28);
-    }
-}
-
-#define Store8(l,o,v)  (((CARD8 *) l)[(o) >> 3] = (v))
-#if IMAGE_BYTE_ORDER == MSBFirst
-#define Store4(l,o,v)  Store8(l,o,((o) & 4 ?			\
-				   (Fetch8(l,o) & 0xf0) | (v) :		\
-				   (Fetch8(l,o) & 0x0f) | ((v) << 4)))
-#else
-#define Store4(l,o,v)  Store8(l,o,((o) & 4 ?			       \
-				   (Fetch8(l,o) & 0x0f) | ((v) << 4) : \
-				   (Fetch8(l,o) & 0xf0) | (v)))
-#endif
-
-static FASTCALL void
-fbStore_a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        Store4(bits, i + x, READ(values + i)>>28);
-    }
-}
-
-static FASTCALL void
-fbStore_r1g2b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  pixel;
-
-        Split(READ(values + i));
-        pixel = (((r >> 4) & 0x8) |
-                 ((g >> 5) & 0x6) |
-                 ((b >> 7)      ));
-        Store4(bits, i + x, pixel);
-    }
-}
-
-static FASTCALL void
-fbStore_b1g2r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  pixel;
-
-        Split(READ(values + i));
-        pixel = (((b >> 4) & 0x8) |
-                 ((g >> 5) & 0x6) |
-                 ((r >> 7)      ));
-        Store4(bits, i + x, pixel);
-    }
-}
-
-static FASTCALL void
-fbStore_a1r1g1b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  pixel;
-        Splita(READ(values + i));
-        pixel = (((a >> 4) & 0x8) |
-                 ((r >> 5) & 0x4) |
-                 ((g >> 6) & 0x2) |
-                 ((b >> 7)      ));
-        Store4(bits, i + x, pixel);
-    }
-}
-
-static FASTCALL void
-fbStore_a1b1g1r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  pixel;
-        Splita(READ(values + i));
-        pixel = (((a >> 4) & 0x8) |
-                 ((b >> 5) & 0x4) |
-                 ((g >> 6) & 0x2) |
-                 ((r >> 7)      ));
-        Store4(bits, i + x, pixel);
-    }
-}
-
-static FASTCALL void
-fbStore_c4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  pixel;
-
-        pixel = miIndexToEnt24(indexed, READ(values + i));
-        Store4(bits, i + x, pixel);
-    }
-}
-
-static FASTCALL void
-fbStore_a1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  *pixel = ((CARD32 *) bits) + ((i+x) >> 5);
-        CARD32  mask = FbStipMask((i+x) & 0x1f, 1);
-
-        CARD32 v = READ(values + i) & 0x80000000 ? mask : 0;
-        WRITE(pixel, (READ(pixel) & ~mask) | v);
-    }
-}
-
-static FASTCALL void
-fbStore_g1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  *pixel = ((CARD32 *) bits) + ((i+x) >> 5);
-        CARD32  mask = FbStipMask((i+x) & 0x1f, 1);
-
-        CARD32 v = miIndexToEntY24(indexed,READ(values + i)) ? mask : 0;
-        WRITE(pixel, (READ(pixel) & ~mask) | v);
-    }
-}
-
-
-static storeProc storeProcForPicture (PicturePtr pict)
-{
-    switch(pict->format) {
-    case PICT_a8r8g8b8: return fbStore_a8r8g8b8;
-    case PICT_x8r8g8b8: return fbStore_x8r8g8b8;
-    case PICT_a8b8g8r8: return fbStore_a8b8g8r8;
-    case PICT_x8b8g8r8: return fbStore_x8b8g8r8;
-
-        /* 24bpp formats */
-    case PICT_r8g8b8: return fbStore_r8g8b8;
-    case PICT_b8g8r8: return fbStore_b8g8r8;
-
-        /* 16bpp formats */
-    case PICT_r5g6b5: return fbStore_r5g6b5;
-    case PICT_b5g6r5: return fbStore_b5g6r5;
-
-    case PICT_a1r5g5b5: return fbStore_a1r5g5b5;
-    case PICT_x1r5g5b5: return fbStore_x1r5g5b5;
-    case PICT_a1b5g5r5: return fbStore_a1b5g5r5;
-    case PICT_x1b5g5r5: return fbStore_x1b5g5r5;
-    case PICT_a4r4g4b4: return fbStore_a4r4g4b4;
-    case PICT_x4r4g4b4: return fbStore_x4r4g4b4;
-    case PICT_a4b4g4r4: return fbStore_a4b4g4r4;
-    case PICT_x4b4g4r4: return fbStore_x4b4g4r4;
-
-        /* 8bpp formats */
-    case PICT_a8: return  fbStore_a8;
-    case PICT_r3g3b2: return fbStore_r3g3b2;
-    case PICT_b2g3r3: return fbStore_b2g3r3;
-    case PICT_a2r2g2b2: return fbStore_a2r2g2b2;
-    case PICT_c8: return  fbStore_c8;
-    case PICT_g8: return  fbStore_c8;
-    case PICT_x4a4: return fbStore_x4a4;
-
-        /* 4bpp formats */
-    case PICT_a4: return  fbStore_a4;
-    case PICT_r1g2b1: return fbStore_r1g2b1;
-    case PICT_b1g2r1: return fbStore_b1g2r1;
-    case PICT_a1r1g1b1: return fbStore_a1r1g1b1;
-    case PICT_a1b1g1r1: return fbStore_a1b1g1r1;
-    case PICT_c4: return  fbStore_c4;
-    case PICT_g4: return  fbStore_c4;
-
-        /* 1bpp formats */
-    case PICT_a1: return  fbStore_a1;
-    case PICT_g1: return  fbStore_g1;
-    default:
-        return NULL;
-    }
-}
-
-
-/*
- * Combine src and mask
- */
-static FASTCALL void
-fbCombineMaskU (CARD32 *src, const CARD32 *mask, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 a = READ(mask + i) >> 24;
-        CARD32 s = READ(src + i);
-        FbByteMul(s, a);
-        WRITE(src + i, s);
-    }
-}
-
-/*
- * All of the composing functions
- */
-
-static FASTCALL void
-fbCombineClear (CARD32 *dest, const CARD32 *src, int width)
-{
-    MEMSET_WRAPPED(dest, 0, width*sizeof(CARD32));
-}
-
-static FASTCALL void
-fbCombineSrcU (CARD32 *dest, const CARD32 *src, int width)
-{
-    MEMCPY_WRAPPED(dest, src, width*sizeof(CARD32));
-}
-
-static FASTCALL void
-fbCombineOverU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 ia = Alpha(~s);
-
-        FbByteMulAdd(d, ia, s);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineOverReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 ia = Alpha(~READ(dest + i));
-        FbByteMulAdd(s, ia, d);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineInU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 a = Alpha(READ(dest + i));
-        FbByteMul(s, a);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineInReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD32 a = Alpha(READ(src + i));
-        FbByteMul(d, a);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineOutU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 a = Alpha(~READ(dest + i));
-        FbByteMul(s, a);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineOutReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD32 a = Alpha(~READ(src + i));
-        FbByteMul(d, a);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineAtopU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 dest_a = Alpha(d);
-        CARD32 src_ia = Alpha(~s);
-
-        FbByteAddMul(s, dest_a, d, src_ia);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 src_a = Alpha(s);
-        CARD32 dest_ia = Alpha(~d);
-
-        FbByteAddMul(s, dest_ia, d, src_a);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineXorU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 src_ia = Alpha(~s);
-        CARD32 dest_ia = Alpha(~d);
-
-        FbByteAddMul(s, dest_ia, d, src_ia);
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineAddU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        FbByteAdd(d, s);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineSaturateU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD16  sa, da;
-
-        sa = s >> 24;
-        da = ~d >> 24;
-        if (sa > da)
-        {
-            sa = FbIntDiv(da, sa);
-            FbByteMul(s, sa);
-        }
-        FbByteAdd(d, s);
-        WRITE(dest + i, d);
-    }
-}
-
-/*
- * All of the disjoint composing functions
-
- The four entries in the first column indicate what source contributions
- come from each of the four areas of the picture -- areas covered by neither
- A nor B, areas covered only by A, areas covered only by B and finally
- areas covered by both A and B.
-
- Disjoint			Conjoint
- Fa		Fb		Fa		Fb
- (0,0,0,0)	0		0		0		0
- (0,A,0,A)	1		0		1		0
- (0,0,B,B)	0		1		0		1
- (0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
- (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
- (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
- (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
- (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
- (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
- (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
- (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
- (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
-
-*/
-
-#define CombineAOut 1
-#define CombineAIn  2
-#define CombineBOut 4
-#define CombineBIn  8
-
-#define CombineClear	0
-#define CombineA	(CombineAOut|CombineAIn)
-#define CombineB	(CombineBOut|CombineBIn)
-#define CombineAOver	(CombineAOut|CombineBOut|CombineAIn)
-#define CombineBOver	(CombineAOut|CombineBOut|CombineBIn)
-#define CombineAAtop	(CombineBOut|CombineAIn)
-#define CombineBAtop	(CombineAOut|CombineBIn)
-#define CombineXor	(CombineAOut|CombineBOut)
-
-/* portion covered by a but not b */
-static INLINE CARD8
-fbCombineDisjointOutPart (CARD8 a, CARD8 b)
-{
-    /* min (1, (1-b) / a) */
-
-    b = ~b;		    /* 1 - b */
-    if (b >= a)		    /* 1 - b >= a -> (1-b)/a >= 1 */
-	return 0xff;	    /* 1 */
-    return FbIntDiv(b,a);   /* (1-b) / a */
-}
-
-/* portion covered by both a and b */
-static INLINE CARD8
-fbCombineDisjointInPart (CARD8 a, CARD8 b)
-{
-    /* max (1-(1-b)/a,0) */
-    /*  = - min ((1-b)/a - 1, 0) */
-    /*  = 1 - min (1, (1-b)/a) */
-
-    b = ~b;		    /* 1 - b */
-    if (b >= a)		    /* 1 - b >= a -> (1-b)/a >= 1 */
-	return 0;	    /* 1 - 1 */
-    return ~FbIntDiv(b,a);  /* 1 - (1-b) / a */
-}
-
-static FASTCALL void
-fbCombineDisjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32 m,n,o,p;
-        CARD16 Fa, Fb, t, u, v;
-        CARD8 sa = s >> 24;
-        CARD8 da = d >> 24;
-
-        switch (combine & CombineA) {
-        default:
-            Fa = 0;
-            break;
-        case CombineAOut:
-            Fa = fbCombineDisjointOutPart (sa, da);
-            break;
-        case CombineAIn:
-            Fa = fbCombineDisjointInPart (sa, da);
-            break;
-        case CombineA:
-            Fa = 0xff;
-            break;
-        }
-
-        switch (combine & CombineB) {
-        default:
-            Fb = 0;
-            break;
-        case CombineBOut:
-            Fb = fbCombineDisjointOutPart (da, sa);
-            break;
-        case CombineBIn:
-            Fb = fbCombineDisjointInPart (da, sa);
-            break;
-        case CombineB:
-            Fb = 0xff;
-            break;
-        }
-        m = FbGen (s,d,0,Fa,Fb,t, u, v);
-        n = FbGen (s,d,8,Fa,Fb,t, u, v);
-        o = FbGen (s,d,16,Fa,Fb,t, u, v);
-        p = FbGen (s,d,24,Fa,Fb,t, u, v);
-        s = m|n|o|p;
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineDisjointOverU (CARD32 *dest, const CARD32 *src, int width)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  s = READ(src + i);
-        CARD16  a = s >> 24;
-
-        if (a != 0x00)
-        {
-            if (a != 0xff)
-            {
-                CARD32 d = READ(dest + i);
-                a = fbCombineDisjointOutPart (d >> 24, a);
-                FbByteMulAdd(d, a, s);
-                s = d;
-            }
-            WRITE(dest + i, s);
-        }
-    }
-}
-
-static FASTCALL void
-fbCombineDisjointInU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineAIn);
-}
-
-static FASTCALL void
-fbCombineDisjointInReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineBIn);
-}
-
-static FASTCALL void
-fbCombineDisjointOutU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineAOut);
-}
-
-static FASTCALL void
-fbCombineDisjointOutReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineBOut);
-}
-
-static FASTCALL void
-fbCombineDisjointAtopU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineAAtop);
-}
-
-static FASTCALL void
-fbCombineDisjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineBAtop);
-}
-
-static FASTCALL void
-fbCombineDisjointXorU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineDisjointGeneralU (dest, src, width, CombineXor);
-}
-
-/* portion covered by a but not b */
-static INLINE CARD8
-fbCombineConjointOutPart (CARD8 a, CARD8 b)
-{
-    /* max (1-b/a,0) */
-    /* = 1-min(b/a,1) */
-
-    /* min (1, (1-b) / a) */
-
-    if (b >= a)		    /* b >= a -> b/a >= 1 */
-	return 0x00;	    /* 0 */
-    return ~FbIntDiv(b,a);   /* 1 - b/a */
-}
-
-/* portion covered by both a and b */
-static INLINE CARD8
-fbCombineConjointInPart (CARD8 a, CARD8 b)
-{
-    /* min (1,b/a) */
-
-    if (b >= a)		    /* b >= a -> b/a >= 1 */
-	return 0xff;	    /* 1 */
-    return FbIntDiv(b,a);   /* b/a */
-}
-
-static FASTCALL void
-fbCombineConjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine)
-{
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32  s = READ(src + i);
-        CARD32 d = READ(dest + i);
-        CARD32  m,n,o,p;
-        CARD16  Fa, Fb, t, u, v;
-        CARD8 sa = s >> 24;
-        CARD8 da = d >> 24;
-
-        switch (combine & CombineA) {
-        default:
-            Fa = 0;
-            break;
-        case CombineAOut:
-            Fa = fbCombineConjointOutPart (sa, da);
-            break;
-        case CombineAIn:
-            Fa = fbCombineConjointInPart (sa, da);
-            break;
-        case CombineA:
-            Fa = 0xff;
-            break;
-        }
-
-        switch (combine & CombineB) {
-        default:
-            Fb = 0;
-            break;
-        case CombineBOut:
-            Fb = fbCombineConjointOutPart (da, sa);
-            break;
-        case CombineBIn:
-            Fb = fbCombineConjointInPart (da, sa);
-            break;
-        case CombineB:
-            Fb = 0xff;
-            break;
-        }
-        m = FbGen (s,d,0,Fa,Fb,t, u, v);
-        n = FbGen (s,d,8,Fa,Fb,t, u, v);
-        o = FbGen (s,d,16,Fa,Fb,t, u, v);
-        p = FbGen (s,d,24,Fa,Fb,t, u, v);
-        s = m|n|o|p;
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineConjointOverU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineAOver);
-}
-
-
-static FASTCALL void
-fbCombineConjointOverReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineBOver);
-}
-
-
-static FASTCALL void
-fbCombineConjointInU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineAIn);
-}
-
-
-static FASTCALL void
-fbCombineConjointInReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineBIn);
-}
-
-static FASTCALL void
-fbCombineConjointOutU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineAOut);
-}
-
-static FASTCALL void
-fbCombineConjointOutReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineBOut);
-}
-
-static FASTCALL void
-fbCombineConjointAtopU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineAAtop);
-}
-
-static FASTCALL void
-fbCombineConjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineBAtop);
-}
-
-static FASTCALL void
-fbCombineConjointXorU (CARD32 *dest, const CARD32 *src, int width)
-{
-    fbCombineConjointGeneralU (dest, src, width, CombineXor);
-}
-
-static CombineFuncU fbCombineFuncU[] = {
-    fbCombineClear,
-    fbCombineSrcU,
-    NULL, /* CombineDst */
-    fbCombineOverU,
-    fbCombineOverReverseU,
-    fbCombineInU,
-    fbCombineInReverseU,
-    fbCombineOutU,
-    fbCombineOutReverseU,
-    fbCombineAtopU,
-    fbCombineAtopReverseU,
-    fbCombineXorU,
-    fbCombineAddU,
-    fbCombineSaturateU,
-    NULL,
-    NULL,
-    fbCombineClear,
-    fbCombineSrcU,
-    NULL, /* CombineDst */
-    fbCombineDisjointOverU,
-    fbCombineSaturateU, /* DisjointOverReverse */
-    fbCombineDisjointInU,
-    fbCombineDisjointInReverseU,
-    fbCombineDisjointOutU,
-    fbCombineDisjointOutReverseU,
-    fbCombineDisjointAtopU,
-    fbCombineDisjointAtopReverseU,
-    fbCombineDisjointXorU,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    fbCombineClear,
-    fbCombineSrcU,
-    NULL, /* CombineDst */
-    fbCombineConjointOverU,
-    fbCombineConjointOverReverseU,
-    fbCombineConjointInU,
-    fbCombineConjointInReverseU,
-    fbCombineConjointOutU,
-    fbCombineConjointOutReverseU,
-    fbCombineConjointAtopU,
-    fbCombineConjointAtopReverseU,
-    fbCombineConjointXorU,
-};
-
-static INLINE void
-fbCombineMaskC (CARD32 *src, CARD32 *mask)
-{
-    CARD32 a = *mask;
-
-    CARD32	x;
-    CARD16	xa;
-
-    if (!a)
-    {
-	WRITE(src, 0);
-	return;
-    }
-
-    x = READ(src);
-    if (a == 0xffffffff)
-    {
-	x = x >> 24;
-	x |= x << 8;
-	x |= x << 16;
-	WRITE(mask, x);
-	return;
-    }
-
-    xa = x >> 24;
-    FbByteMulC(x, a);
-    WRITE(src, x);
-    FbByteMul(a, xa);
-    WRITE(mask, a);
-}
-
-static INLINE void
-fbCombineMaskValueC (CARD32 *src, const CARD32 *mask)
-{
-    CARD32 a = READ(mask);
-    CARD32	x;
-
-    if (!a)
-    {
-	WRITE(src, 0);
-	return;
-    }
-
-    if (a == 0xffffffff)
-	return;
-
-    x = READ(src);
-    FbByteMulC(x, a);
-    WRITE(src,x);
-}
-
-static INLINE void
-fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask)
-{
-    CARD32 a = READ(mask);
-    CARD32	x;
-
-    if (!a)
-	return;
-
-    x = READ(src) >> 24;
-    if (x == 0xff)
-	return;
-    if (a == 0xffffffff)
-    {
-	x = x >> 24;
-	x |= x << 8;
-	x |= x << 16;
-	WRITE(mask, x);
-	return;
-    }
-
-    FbByteMul(a, x);
-    WRITE(mask, a);
-}
-
-static FASTCALL void
-fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    MEMSET_WRAPPED(dest, 0, width*sizeof(CARD32));
-}
-
-static FASTCALL void
-fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-	CARD32 s = READ(src + i);
-	CARD32 m = READ(mask + i);
-
-	fbCombineMaskValueC (&s, &m);
-
-	WRITE(dest, s);
-    }
-}
-
-static FASTCALL void
-fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-	CARD32 s = READ(src + i);
-	CARD32 m = READ(mask + i);
-	CARD32 a;
-
-	fbCombineMaskC (&s, &m);
-
-	a = ~m;
-        if (a != 0xffffffff)
-        {
-            if (a)
-            {
-                CARD32 d = READ(dest + i);
-                FbByteMulAddC(d, a, s);
-                s = d;
-            }
-            WRITE(dest + i, s);
-        }
-    }
-}
-
-static FASTCALL void
-fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD32 a = ~d >> 24;
-
-        if (a)
-        {
-            CARD32 s = READ(src + i);
-	    CARD32 m = READ(mask + i);
-
-	    fbCombineMaskValueC (&s, &m);
-
-            if (a != 0xff)
-            {
-                FbByteMulAdd(s, a, d);
-            }
-            WRITE(dest + i, s);
-        }
-    }
-}
-
-static FASTCALL void
-fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD16 a = d >> 24;
-        CARD32 s = 0;
-        if (a)
-        {
-	    CARD32 m = READ(mask + i);
-
-	    s = READ(src + i);
-	    fbCombineMaskValueC (&s, &m);
-            if (a != 0xff)
-            {
-                FbByteMul(s, a);
-            }
-        }
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 m = READ(mask + i);
-        CARD32 a;
-
-	fbCombineMaskAlphaC (&s, &m);
-
-	a = m;
-        if (a != 0xffffffff)
-        {
-            CARD32 d = 0;
-            if (a)
-            {
-                d = READ(dest + i);
-                FbByteMulC(d, a);
-            }
-            WRITE(dest + i, d); 
-        }
-    }
-}
-
-static FASTCALL void
-fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD16 a = ~d >> 24;
-        CARD32 s = 0;
-        if (a)
-        {
-	    CARD32 m = READ(mask + i);
-
-	    s = READ(src + i);
-	    fbCombineMaskValueC (&s, &m);
-
-            if (a != 0xff)
-            {
-                FbByteMul(s, a);
-            }
-        }
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-	CARD32 s = READ(src + i);
-	CARD32 m = READ(mask + i);
-	CARD32 a;
-
-	fbCombineMaskAlphaC (&s, &m);
-
-        a = ~m;
-        if (a != 0xffffffff)
-        {
-            CARD32 d = 0;
-            if (a)
-            {
-                d = READ(dest + i);
-                FbByteMulC(d, a);
-            }
-            WRITE(dest + i, d);
-        }
-    }
-}
-
-static FASTCALL void
-fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD32 s = READ(src + i);
-        CARD32 m = READ(mask + i);
-        CARD32 ad;
-        CARD16 as = d >> 24;
-
-	fbCombineMaskC (&s, &m);
-
-        ad = ~m;
-
-        FbByteAddMulC(d, ad, s, as);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-
-        CARD32 d = READ(dest + i);
-        CARD32 s = READ(src + i);
-        CARD32 m = READ(mask + i);
-        CARD32 ad;
-        CARD16 as = ~d >> 24;
-
-	fbCombineMaskC (&s, &m);
-
-	ad = m;
-
-        FbByteAddMulC(d, ad, s, as);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 d = READ(dest + i);
-        CARD32 s = READ(src + i);
-        CARD32 m = READ(mask + i);
-        CARD32 ad;
-        CARD16 as = ~d >> 24;
-
-	fbCombineMaskC (&s, &m);
-
-	ad = ~m;
-
-        FbByteAddMulC(d, ad, s, as);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32 s = READ(src + i);
-        CARD32 m = READ(mask + i);
-        CARD32 d = READ(dest + i);
-
-	fbCombineMaskValueC (&s, &m);
-
-        FbByteAdd(d, s);
-        WRITE(dest + i, d);
-    }
-}
-
-static FASTCALL void
-fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32  s, d;
-        CARD16  sa, sr, sg, sb, da;
-        CARD16  t, u, v;
-        CARD32  m,n,o,p;
-
-        d = READ(dest + i);
-        s = READ(src + i);
-	m = READ(mask + i);
-
-	fbCombineMaskC (&s, &m);
-
-        sa = (m >> 24);
-        sr = (m >> 16) & 0xff;
-        sg = (m >>  8) & 0xff;
-        sb = (m      ) & 0xff;
-        da = ~d >> 24;
-
-        if (sb <= da)
-            m = FbAdd(s,d,0,t);
-        else
-            m = FbGen (s, d, 0, (da << 8) / sb, 0xff, t, u, v);
-
-        if (sg <= da)
-            n = FbAdd(s,d,8,t);
-        else
-            n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v);
-
-        if (sr <= da)
-            o = FbAdd(s,d,16,t);
-        else
-            o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v);
-
-        if (sa <= da)
-            p = FbAdd(s,d,24,t);
-        else
-            p = FbGen (s, d, 24, (da << 8) / sa, 0xff, t, u, v);
-
-        WRITE(dest + i, m|n|o|p);
-    }
-}
-
-static FASTCALL void
-fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32  s, d;
-        CARD32  m,n,o,p;
-        CARD32  Fa, Fb;
-        CARD16  t, u, v;
-        CARD32  sa;
-        CARD8   da;
-
-        s = READ(src + i);
-        m = READ(mask + i);
-        d = READ(dest + i);
-        da = d >> 24;
-
-	fbCombineMaskC (&s, &m);
-
-	sa = m;
-
-        switch (combine & CombineA) {
-        default:
-            Fa = 0;
-            break;
-        case CombineAOut:
-            m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da);
-            n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8;
-            o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16;
-            p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24;
-            Fa = m|n|o|p;
-            break;
-        case CombineAIn:
-            m = fbCombineDisjointInPart ((CARD8) (sa >> 0), da);
-            n = fbCombineDisjointInPart ((CARD8) (sa >> 8), da) << 8;
-            o = fbCombineDisjointInPart ((CARD8) (sa >> 16), da) << 16;
-            p = fbCombineDisjointInPart ((CARD8) (sa >> 24), da) << 24;
-            Fa = m|n|o|p;
-            break;
-        case CombineA:
-            Fa = 0xffffffff;
-            break;
-        }
-
-        switch (combine & CombineB) {
-        default:
-            Fb = 0;
-            break;
-        case CombineBOut:
-            m = fbCombineDisjointOutPart (da, (CARD8) (sa >> 0));
-            n = fbCombineDisjointOutPart (da, (CARD8) (sa >> 8)) << 8;
-            o = fbCombineDisjointOutPart (da, (CARD8) (sa >> 16)) << 16;
-            p = fbCombineDisjointOutPart (da, (CARD8) (sa >> 24)) << 24;
-            Fb = m|n|o|p;
-            break;
-        case CombineBIn:
-            m = fbCombineDisjointInPart (da, (CARD8) (sa >> 0));
-            n = fbCombineDisjointInPart (da, (CARD8) (sa >> 8)) << 8;
-            o = fbCombineDisjointInPart (da, (CARD8) (sa >> 16)) << 16;
-            p = fbCombineDisjointInPart (da, (CARD8) (sa >> 24)) << 24;
-            Fb = m|n|o|p;
-            break;
-        case CombineB:
-            Fb = 0xffffffff;
-            break;
-        }
-        m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v);
-        n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v);
-        o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v);
-        p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v);
-        s = m|n|o|p;
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineDisjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOver);
-}
-
-static FASTCALL void
-fbCombineDisjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineAIn);
-}
-
-static FASTCALL void
-fbCombineDisjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineBIn);
-}
-
-static FASTCALL void
-fbCombineDisjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut);
-}
-
-static FASTCALL void
-fbCombineDisjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineBOut);
-}
-
-static FASTCALL void
-fbCombineDisjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineAAtop);
-}
-
-static FASTCALL void
-fbCombineDisjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineBAtop);
-}
-
-static FASTCALL void
-fbCombineDisjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineDisjointGeneralC (dest, src, mask, width, CombineXor);
-}
-
-static FASTCALL void
-fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
-{
-    int i;
-
-    for (i = 0; i < width; ++i) {
-        CARD32  s, d;
-        CARD32  m,n,o,p;
-        CARD32  Fa, Fb;
-        CARD16  t, u, v;
-        CARD32  sa;
-        CARD8   da;
-
-        s = READ(src + i);
-        m = READ(mask + i);
-        d = READ(dest + i);
-        da = d >> 24;
-
-	fbCombineMaskC (&s, &m);
-
-        sa = m;
-
-        switch (combine & CombineA) {
-        default:
-            Fa = 0;
-            break;
-        case CombineAOut:
-            m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da);
-            n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8;
-            o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16;
-            p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24;
-            Fa = m|n|o|p;
-            break;
-        case CombineAIn:
-            m = fbCombineConjointInPart ((CARD8) (sa >> 0), da);
-            n = fbCombineConjointInPart ((CARD8) (sa >> 8), da) << 8;
-            o = fbCombineConjointInPart ((CARD8) (sa >> 16), da) << 16;
-            p = fbCombineConjointInPart ((CARD8) (sa >> 24), da) << 24;
-            Fa = m|n|o|p;
-            break;
-        case CombineA:
-            Fa = 0xffffffff;
-            break;
-        }
-
-        switch (combine & CombineB) {
-        default:
-            Fb = 0;
-            break;
-        case CombineBOut:
-            m = fbCombineConjointOutPart (da, (CARD8) (sa >> 0));
-            n = fbCombineConjointOutPart (da, (CARD8) (sa >> 8)) << 8;
-            o = fbCombineConjointOutPart (da, (CARD8) (sa >> 16)) << 16;
-            p = fbCombineConjointOutPart (da, (CARD8) (sa >> 24)) << 24;
-            Fb = m|n|o|p;
-            break;
-        case CombineBIn:
-            m = fbCombineConjointInPart (da, (CARD8) (sa >> 0));
-            n = fbCombineConjointInPart (da, (CARD8) (sa >> 8)) << 8;
-            o = fbCombineConjointInPart (da, (CARD8) (sa >> 16)) << 16;
-            p = fbCombineConjointInPart (da, (CARD8) (sa >> 24)) << 24;
-            Fb = m|n|o|p;
-            break;
-        case CombineB:
-            Fb = 0xffffffff;
-            break;
-        }
-        m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v);
-        n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v);
-        o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v);
-        p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v);
-        s = m|n|o|p;
-        WRITE(dest + i, s);
-    }
-}
-
-static FASTCALL void
-fbCombineConjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineAOver);
-}
-
-static FASTCALL void
-fbCombineConjointOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver);
-}
-
-static FASTCALL void
-fbCombineConjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineAIn);
-}
-
-static FASTCALL void
-fbCombineConjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineBIn);
-}
-
-static FASTCALL void
-fbCombineConjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineAOut);
-}
-
-static FASTCALL void
-fbCombineConjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineBOut);
-}
-
-static FASTCALL void
-fbCombineConjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineAAtop);
-}
-
-static FASTCALL void
-fbCombineConjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineBAtop);
-}
-
-static FASTCALL void
-fbCombineConjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
-{
-    fbCombineConjointGeneralC (dest, src, mask, width, CombineXor);
-}
-
-static CombineFuncC fbCombineFuncC[] = {
-    fbCombineClearC,
-    fbCombineSrcC,
-    NULL, /* Dest */
-    fbCombineOverC,
-    fbCombineOverReverseC,
-    fbCombineInC,
-    fbCombineInReverseC,
-    fbCombineOutC,
-    fbCombineOutReverseC,
-    fbCombineAtopC,
-    fbCombineAtopReverseC,
-    fbCombineXorC,
-    fbCombineAddC,
-    fbCombineSaturateC,
-    NULL,
-    NULL,
-    fbCombineClearC,	    /* 0x10 */
-    fbCombineSrcC,
-    NULL, /* Dest */
-    fbCombineDisjointOverC,
-    fbCombineSaturateC, /* DisjointOverReverse */
-    fbCombineDisjointInC,
-    fbCombineDisjointInReverseC,
-    fbCombineDisjointOutC,
-    fbCombineDisjointOutReverseC,
-    fbCombineDisjointAtopC,
-    fbCombineDisjointAtopReverseC,
-    fbCombineDisjointXorC,  /* 0x1b */
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    fbCombineClearC,
-    fbCombineSrcC,
-    NULL, /* Dest */
-    fbCombineConjointOverC,
-    fbCombineConjointOverReverseC,
-    fbCombineConjointInC,
-    fbCombineConjointInReverseC,
-    fbCombineConjointOutC,
-    fbCombineConjointOutReverseC,
-    fbCombineConjointAtopC,
-    fbCombineConjointAtopReverseC,
-    fbCombineConjointXorC,
-};
-
-
-FbComposeFunctions composeFunctions = {
-    fbCombineFuncU,
-    fbCombineFuncC,
-    fbCombineMaskU
-};
-
-
-static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
-{
-    FbBits *bits;
-    FbStride stride;
-    int bpp;
-    int xoff, yoff;
-    CARD32 color;
-    CARD32 *end;
-    fetchPixelProc fetch = fetchPixelProcForPicture(pict);
-    miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
-
-    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-    bits += yoff*stride + (xoff*bpp >> FB_SHIFT);
-
-    color = fetch(bits, 0, indexed);
-
-    end = buffer + width;
-    while (buffer < end)
-        WRITE(buffer++, color);
-    fbFinishAccess (pict->pDrawable);
-}
-
-static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
-{
-    FbBits *bits;
-    FbStride stride;
-    int bpp;
-    int xoff, yoff;
-    fetchProc fetch = fetchProcForPicture(pict);
-    miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
-
-    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-    x += xoff;
-    y += yoff;
-
-    bits += y*stride;
-
-    fetch(bits, x, width, buffer, indexed);
-    fbFinishAccess (pict->pDrawable);
-}
-
-#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
-#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :		\
-		  ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
-
-typedef struct
-{
-    CARD32        left_ag;
-    CARD32        left_rb;
-    CARD32        right_ag;
-    CARD32        right_rb;
-    int32_t       left_x;
-    int32_t       right_x;
-    int32_t       stepper;
-    
-    PictGradientStopPtr      stops;
-    int                      num_stops;
-    unsigned int             spread;
-
-    int		  need_reset;
-} GradientWalker;
-
-static void
-_gradient_walker_init (GradientWalker  *walker,
-		       SourcePictPtr    pGradient,
-		       unsigned int     spread)
-{
-    walker->num_stops = pGradient->gradient.nstops;
-    walker->stops     = pGradient->gradient.stops;
-    walker->left_x    = 0;
-    walker->right_x   = 0x10000;
-    walker->stepper   = 0;
-    walker->left_ag   = 0;
-    walker->left_rb   = 0;
-    walker->right_ag  = 0;
-    walker->right_rb  = 0;
-    walker->spread    = spread;
-
-    walker->need_reset = TRUE;
-}
-
-static void
-_gradient_walker_reset (GradientWalker  *walker,
-                        xFixed_32_32     pos)
-{
-    int32_t                  x, left_x, right_x;
-    xRenderColor          *left_c, *right_c;
-    int                      n, count = walker->num_stops;
-    PictGradientStopPtr      stops = walker->stops;
-    
-    static const xRenderColor   transparent_black = { 0, 0, 0, 0 };
-    
-    switch (walker->spread)
-    {
-    case RepeatNormal:
-	x = (int32_t)pos & 0xFFFF;
-	for (n = 0; n < count; n++)
-	    if (x < stops[n].x)
-		break;
-	if (n == 0) {
-	    left_x =  stops[count-1].x - 0x10000;
-	    left_c = &stops[count-1].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-	
-	if (n == count) {
-	    right_x =  stops[0].x + 0x10000;
-	    right_c = &stops[0].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-	left_x  += (pos - x);
-	right_x += (pos - x);
-	break;
-	
-    case RepeatPad:
-	for (n = 0; n < count; n++)
-	    if (pos < stops[n].x)
-		break;
-	
-	if (n == 0) {
-	    left_x =  INT_MIN;
-	    left_c = &stops[0].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-	
-	if (n == count) {
-	    right_x =  INT_MAX;
-	    right_c = &stops[n-1].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-	break;
-	
-    case RepeatReflect:
-	x = (int32_t)pos & 0xFFFF;
-	if ((int32_t)pos & 0x10000)
-	    x = 0x10000 - x;
-	for (n = 0; n < count; n++)
-	    if (x < stops[n].x)
-		break;
-	
-	if (n == 0) {
-	    left_x =  -stops[0].x;
-	    left_c = &stops[0].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-	
-	if (n == count) {
-	    right_x = 0x20000 - stops[n-1].x;
-	    right_c = &stops[n-1].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-	
-	if ((int32_t)pos & 0x10000) {
-	    xRenderColor  *tmp_c;
-	    int32_t          tmp_x;
-	    
-	    tmp_x   = 0x10000 - right_x;
-	    right_x = 0x10000 - left_x;
-	    left_x  = tmp_x;
-	    
-	    tmp_c   = right_c;
-	    right_c = left_c;
-	    left_c  = tmp_c;
-
-	    x = 0x10000 - x;
-	}
-	left_x  += (pos - x);
-	right_x += (pos - x);
-	break;
-	
-    default:  /* RepeatNone */
-	for (n = 0; n < count; n++)
-	    if (pos < stops[n].x)
-		break;
-	
-	if (n == 0)
-	{
-	    left_x  =  INT_MIN;
-	    right_x =  stops[0].x;
-	    left_c  = right_c = (xRenderColor*) &transparent_black;
-	}
-	else if (n == count)
-	{
-	    left_x  = stops[n-1].x;
-	    right_x = INT_MAX;
-	    left_c  = right_c = (xRenderColor*) &transparent_black;
-	}
-	else
-	{
-	    left_x  =  stops[n-1].x;
-	    right_x =  stops[n].x;
-	    left_c  = &stops[n-1].color;
-	    right_c = &stops[n].color;
-	}
-    }
-    
-    walker->left_x   = left_x;
-    walker->right_x  = right_x;
-    walker->left_ag  = ((left_c->alpha >> 8) << 16)   | (left_c->green >> 8);
-    walker->left_rb  = ((left_c->red & 0xff00) << 8)  | (left_c->blue >> 8);
-    walker->right_ag = ((right_c->alpha >> 8) << 16)  | (right_c->green >> 8);
-    walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
-    
-    if ( walker->left_x == walker->right_x                ||
-	 ( walker->left_ag == walker->right_ag &&
-	   walker->left_rb == walker->right_rb )   )
-    {
-	walker->stepper = 0;
-    }
-    else
-    {
-	int32_t width = right_x - left_x;
-	walker->stepper = ((1 << 24) + width/2)/width;
-    }
-
-    walker->need_reset = FALSE;
-}
-
-#define  GRADIENT_WALKER_NEED_RESET(w,x)				\
-    ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
-
-
-/* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
-static CARD32
-_gradient_walker_pixel (GradientWalker  *walker,
-                        xFixed_32_32     x)
-{
-    int  dist, idist;
-    CARD32  t1, t2, a, color;
-    
-    if (GRADIENT_WALKER_NEED_RESET (walker, x))
-        _gradient_walker_reset (walker, x);
-    
-    dist  = ((int)(x - walker->left_x)*walker->stepper) >> 16;
-    idist = 256 - dist;
-    
-    /* combined INTERPOLATE and premultiply */
-    t1 = walker->left_rb*idist + walker->right_rb*dist;
-    t1 = (t1 >> 8) & 0xff00ff;
-    
-    t2  = walker->left_ag*idist + walker->right_ag*dist;
-    t2 &= 0xff00ff00;
-    
-    color = t2 & 0xff000000;
-    a     = t2 >> 24;
-    
-    t1  = t1*a + 0x800080;
-    t1  = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
-    
-    t2  = (t2 >> 8)*a + 0x800080;
-    t2  = (t2 + ((t2 >> 8) & 0xff00ff));
-    
-    return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
-}
-
-static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
-{
-     SourcePictPtr   pGradient = pict->pSourcePict;
-     GradientWalker  walker;
-     CARD32         *end = buffer + width;
- 
-     _gradient_walker_init (&walker, pGradient, pict->repeat);
-    
-    if (pGradient->type == SourcePictTypeSolidFill) {
-        register CARD32 color = pGradient->solidFill.color;
-        while (buffer < end) {
-            WRITE(buffer++, color);
-        }
-    } else if (pGradient->type == SourcePictTypeLinear) {
-        PictVector v, unit;
-        xFixed_32_32 l;
-        xFixed_48_16 dx, dy, a, b, off;
-	
-        /* reference point is the center of the pixel */
-        v.vector[0] = IntToxFixed(x) + xFixed1/2;
-        v.vector[1] = IntToxFixed(y) + xFixed1/2;
-        v.vector[2] = xFixed1;
-        if (pict->transform) {
-            if (!PictureTransformPoint3d (pict->transform, &v))
-                return;
-            unit.vector[0] = pict->transform->matrix[0][0];
-            unit.vector[1] = pict->transform->matrix[1][0];
-            unit.vector[2] = pict->transform->matrix[2][0];
-        } else {
-            unit.vector[0] = xFixed1;
-            unit.vector[1] = 0;
-            unit.vector[2] = 0;
-        }
-
-        dx = pGradient->linear.p2.x - pGradient->linear.p1.x;
-        dy = pGradient->linear.p2.y - pGradient->linear.p1.y;
-        l = dx*dx + dy*dy;
-        if (l != 0) {
-            a = (dx << 32) / l;
-            b = (dy << 32) / l;
-            off = (-a*pGradient->linear.p1.x - b*pGradient->linear.p1.y)>>16;
-        }
-        if (l == 0  || (unit.vector[2] == 0 && v.vector[2] == xFixed1)) {
-            xFixed_48_16 inc, t;
-            /* affine transformation only */
-            if (l == 0) {
-                t = 0;
-                inc = 0;
-            } else {
-                t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
-                inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
-            }
-
-	    if (pGradient->linear.class == SourcePictClassVertical)
-	    {
-		register CARD32 color;
-
-		color = _gradient_walker_pixel( &walker, t );
-		while (buffer < end)
-		    WRITE(buffer++, color);
-	    }
-	    else
-	    {
-                if (!mask) {
-                    while (buffer < end)
-                    {
-                        WRITE(buffer, _gradient_walker_pixel (&walker, t));
-                        buffer += 1;
-                        t      += inc;
-                    }
-                } else {
-                    while (buffer < end) {
-                        if (*mask++ & maskBits)
-                        {
-                            WRITE(buffer, _gradient_walker_pixel (&walker, t));
-                        }
-                        buffer += 1;
-                        t      += inc;
-                    }
-                }
-	    }
-	}
-	else /* projective transformation */
-	{
-	    xFixed_48_16 t;
-
-	    if (pGradient->linear.class == SourcePictClassVertical)
-	    {
-		register CARD32 color;
-
-		if (v.vector[2] == 0)
-		{
-		    t = 0;
-		}
-		else
-		{
-		    xFixed_48_16 x, y;
-
-		    x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
-		    y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
-		    t = ((a * x + b * y) >> 16) + off;
-		}
-
- 		color = _gradient_walker_pixel( &walker, t );
-		while (buffer < end)
-		    WRITE(buffer++, color);
-	    }
-	    else
-	    {
-		while (buffer < end)
-		{
-		    if (!mask || *mask++ & maskBits)
-		    {
-			if (v.vector[2] == 0) {
-			    t = 0;
-			} else {
-			    xFixed_48_16 x, y;
-			    x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
-			    y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
-			    t = ((a*x + b*y) >> 16) + off;
-			}
-			WRITE(buffer, _gradient_walker_pixel (&walker, t));
-		    }
-		    ++buffer;
-		    v.vector[0] += unit.vector[0];
-		    v.vector[1] += unit.vector[1];
-		    v.vector[2] += unit.vector[2];
-		}
-            }
-        }
-    } else {
-
-/*
- * In the radial gradient problem we are given two circles (c₁,r₁) and
- * (câ‚‚,râ‚‚) that define the gradient itself. Then, for any point p, we
- * must compute the value(s) of t within [0.0, 1.0] representing the
- * circle(s) that would color the point.
- *
- * There are potentially two values of t since the point p can be
- * colored by both sides of the circle, (which happens whenever one
- * circle is not entirely contained within the other).
- *
- * If we solve for a value of t that is outside of [0.0, 1.0] then we
- * use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
- * value within [0.0, 1.0].
- *
- * Here is an illustration of the problem:
- *
- *              pâ‚‚
- *           p  •
- *           •   ╲
- *        ·       ╲r₂
- *  p₁ ·           ╲
- *  •              θ╲
- *   ╲             ╌╌•
- *    ╲r₁        ·   c₂
- *    θ╲    ·
- *    ╌╌•
- *      c₁
- *
- * Given (c₁,r₁), (c₂,r₂) and p, we must find an angle θ such that two
- * points p₁ and p₂ on the two circles are collinear with p. Then, the
- * desired value of t is the ratio of the length of p₁p to the length
- * of p₁p₂.
- *
- * So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ and t.
- * We can also write six equations that constrain the problem:
- *
- * Point p₁ is a distance r₁ from c₁ at an angle of θ:
- *
- *	1. p₁x = c₁x + r₁·cos θ
- *	2. p₁y = c₁y + r₁·sin θ
- *
- * Point p₂ is a distance r₂ from c₂ at an angle of θ:
- *
- *	3. p₂x = c₂x + r2·cos θ
- *	4. p₂y = c₂y + r2·sin θ
- *
- * Point p lies at a fraction t along the line segment p₁p₂:
- *
- *	5. px = t·p₂x + (1-t)·p₁x
- *	6. py = t·p₂y + (1-t)·p₁y
- *
- * To solve, first subtitute 1-4 into 5 and 6:
- *
- * px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
- * py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
- *
- * Then solve each for cos θ and sin θ expressed as a function of t:
- *
- * cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
- * sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((r₂-r₁)·t + r₁)
- *
- * To simplify this a bit, we define new variables for several of the
- * common terms as shown below:
- *
- *              pâ‚‚
- *           p  •
- *           •   ╲
- *        ·  ┆    ╲r₂
- *  p₁ ·     ┆     ╲
- *  •     pdy┆      ╲
- *   ╲       ┆       •c₂
- *    ╲r₁    ┆   ·   ┆
- *     ╲    ·┆       ┆cdy
- *      •╌╌╌╌┴╌╌╌╌╌╌╌┘
- *    c₁  pdx   cdx
- *
- * cdx = (c₂x - c₁x)
- * cdy = (c₂y - c₁y)
- *  dr =  r₂-r₁
- * pdx =  px - c₁x
- * pdy =  py - c₁y
- *
- * Note that cdx, cdy, and dr do not depend on point p at all, so can
- * be pre-computed for the entire gradient. The simplifed equations
- * are now:
- *
- * cos θ = (-cdx·t + pdx) / (dr·t + r₁)
- * sin θ = (-cdy·t + pdy) / (dr·t + r₁)
- *
- * Finally, to get a single function of t and eliminate the last
- * unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
- * each equation, (we knew a quadratic was coming since it must be
- * possible to obtain two solutions in some cases):
- *
- * cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r₁·dr·t + r₁²)
- * sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r₁·dr·t + r₁²)
- *
- * Then add both together, set the result equal to 1, and express as a
- * standard quadratic equation in t of the form At² + Bt + C = 0
- *
- * (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r₁·dr)·t + (pdx² + pdy² - r₁²) = 0
- *
- * In other words:
- *
- * A = cdx² + cdy² - dr²
- * B = -2·(pdx·cdx + pdy·cdy + r₁·dr)
- * C = pdx² + pdy² - r₁²
- *
- * And again, notice that A does not depend on p, so can be
- * precomputed. From here we just use the quadratic formula to solve
- * for t:
- *
- * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
- */
-        /* radial or conical */
-        Bool affine = TRUE;
-        double cx = 1.;
-        double cy = 0.;
-        double cz = 0.;
-	double rx = x + 0.5;
-	double ry = y + 0.5;
-        double rz = 1.;
-
-        if (pict->transform) {
-            PictVector v;
-            /* reference point is the center of the pixel */
-            v.vector[0] = IntToxFixed(x) + xFixed1/2;
-            v.vector[1] = IntToxFixed(y) + xFixed1/2;
-            v.vector[2] = xFixed1;
-            if (!PictureTransformPoint3d (pict->transform, &v))
-                return;
-
-            cx = pict->transform->matrix[0][0]/65536.;
-            cy = pict->transform->matrix[1][0]/65536.;
-            cz = pict->transform->matrix[2][0]/65536.;
-            rx = v.vector[0]/65536.;
-            ry = v.vector[1]/65536.;
-            rz = v.vector[2]/65536.;
-            affine = pict->transform->matrix[2][0] == 0 && v.vector[2] == xFixed1;
-        }
-
-        if (pGradient->type == SourcePictTypeRadial) {
-	    PictRadialGradient *radial;
-	    radial = &pGradient->radial;
-            if (affine) {
-                while (buffer < end) {
-		    if (!mask || *mask++ & maskBits)
-		    {
-			double pdx, pdy;
-			double B, C;
-			double det;
-			double c1x = radial->c1.x / 65536.0;
-			double c1y = radial->c1.y / 65536.0;
-			double r1  = radial->c1.radius / 65536.0;
-                        xFixed_48_16 t;
-
-			pdx = rx - c1x;
-			pdy = ry - c1y;
-
-			B = -2 * (  pdx * radial->cdx
-				  + pdy * radial->cdy
-				  + r1 * radial->dr);
-			C = (pdx * pdx + pdy * pdy - r1 * r1);
-
-                        det = (B * B) - (4 * radial->A * C);
-			if (det < 0.0)
-			    det = 0.0;
-
-			if (radial->A < 0)
-			    t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
-			else
-			    t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
-			
- 			WRITE(buffer, _gradient_walker_pixel (&walker, t));
-		    }
-		    ++buffer;
-		    
-                    rx += cx;
-                    ry += cy;
-                }
-            } else {
-		/* projective */
-                while (buffer < end) {
-		    if (!mask || *mask++ & maskBits)
-		    {
-			double pdx, pdy;
-			double B, C;
-			double det;
-			double c1x = radial->c1.x / 65536.0;
-			double c1y = radial->c1.y / 65536.0;
-			double r1  = radial->c1.radius / 65536.0;
-                        xFixed_48_16 t;
-			double x, y;
-
-			if (rz != 0) {
-			    x = rx/rz;
-			    y = ry/rz;
-			} else {
-			    x = y = 0.;
-			}
-			
-			pdx = x - c1x;
-			pdy = y - c1y;
-
-			B = -2 * (  pdx * radial->cdx
-				  + pdy * radial->cdy
-				  + r1 * radial->dr);
-			C = (pdx * pdx + pdy * pdy - r1 * r1);
-
-                        det = (B * B) - (4 * radial->A * C);
-			if (det < 0.0)
-			    det = 0.0;
-
-			if (radial->A < 0)
-			    t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
-			else
-			    t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
-			
- 			WRITE(buffer, _gradient_walker_pixel (&walker, t));
-		    }
-		    ++buffer;
-		    
-                    rx += cx;
-                    ry += cy;
-		    rz += cz;
-                }
-            }
-        } else /* SourcePictTypeConical */ {
-            double a = pGradient->conical.angle/(180.*65536);
-            if (affine) {
-                rx -= pGradient->conical.center.x/65536.;
-                ry -= pGradient->conical.center.y/65536.;
-
-                while (buffer < end) {
-		    double angle;
-
-                    if (!mask || *mask++ & maskBits)
-		    {
-                        xFixed_48_16   t;
-			
-                        angle = atan2(ry, rx) + a;
-			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
-			
-			WRITE(buffer, _gradient_walker_pixel (&walker, t));
-		    }
-
-                    ++buffer;
-                    rx += cx;
-                    ry += cy;
-                }
-            } else {
-                while (buffer < end) {
-                    double x, y;
-                    double angle;
-		    
-                    if (!mask || *mask++ & maskBits)
-                    {
-			xFixed_48_16  t;
-			
-			if (rz != 0) {
-			    x = rx/rz;
-			    y = ry/rz;
-			} else {
-			    x = y = 0.;
-			}
-			x -= pGradient->conical.center.x/65536.;
-			y -= pGradient->conical.center.y/65536.;
-			angle = atan2(y, x) + a;
-			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
-			
-			WRITE(buffer, _gradient_walker_pixel (&walker, t));
-		    }
-		    
-                    ++buffer;
-                    rx += cx;
-                    ry += cy;
-                    rz += cz;
-                }
-            }
-        }
-    }
-}
-
-static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
-{
-    FbBits     *bits;
-    FbStride    stride;
-    int         bpp;
-    int         xoff, yoff, dx, dy;
-    fetchPixelProc   fetch;
-    PictVector	v;
-    PictVector  unit;
-    int         i;
-    BoxRec	box;
-    miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
-    Bool affine = TRUE;
-
-    fetch = fetchPixelProcForPicture(pict);
-
-    fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
-    x += xoff;
-    y += yoff;
-
-    dx = pict->pDrawable->x;
-    dy = pict->pDrawable->y;
-
-    /* reference point is the center of the pixel */
-    v.vector[0] = IntToxFixed(x - dx) + xFixed1 / 2;
-    v.vector[1] = IntToxFixed(y - dy) + xFixed1 / 2;
-    v.vector[2] = xFixed1;
-
-    /* when using convolution filters one might get here without a transform */
-    if (pict->transform) {
-        if (!PictureTransformPoint3d (pict->transform, &v)) {
-            fbFinishAccess (pict->pDrawable);
-            return;
-        }
-        unit.vector[0] = pict->transform->matrix[0][0];
-        unit.vector[1] = pict->transform->matrix[1][0];
-        unit.vector[2] = pict->transform->matrix[2][0];
-        affine = v.vector[2] == xFixed1 && unit.vector[2] == 0;
-    } else {
-        unit.vector[0] = xFixed1;
-        unit.vector[1] = 0;
-        unit.vector[2] = 0;
-    }
-
-    if (pict->filter == PictFilterNearest)
-    {
-        if (pict->repeatType == RepeatNormal) {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
-                for (i = 0; i < width; ++i) {
-		    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    if (!affine) {
-				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
-				x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
-			    } else {
-				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
-				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
-			    }
-			    WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-			}
-		    }
-
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            } else {
-                for (i = 0; i < width; ++i) {
-		    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    if (!affine) {
-				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
-				x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
-			    } else {
-				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
-				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
-			    }
-			    if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
-				WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-			    else
-				WRITE(buffer + i, 0);
-			}
-		    }
-
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            }
-        } else {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
-                box = pict->pCompositeClip->extents;
-                for (i = 0; i < width; ++i) {
-		    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    if (!affine) {
-				y = DIV(v.vector[1],v.vector[2]);
-				x = DIV(v.vector[0],v.vector[2]);
-			    } else {
-				y = v.vector[1]>>16;
-				x = v.vector[0]>>16;
-			    }
-			    WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
-				  0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
-			}
-		    }
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            } else {
-                for (i = 0; i < width; ++i) {
-                    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    if (!affine) {
-				y = DIV(v.vector[1],v.vector[2]);
-				x = DIV(v.vector[0],v.vector[2]);
-			    } else {
-				y = v.vector[1]>>16;
-				x = v.vector[0]>>16;
-			    }
-			    if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
-				WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-			    else
-				WRITE(buffer + i, 0);
-			}
-		    }
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            }
-        }
-    } else if (pict->filter == PictFilterBilinear) {
-        /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
-        v.vector[0] -= v.vector[2] / 2;
-        v.vector[1] -= v.vector[2] / 2;
-        unit.vector[0] -= unit.vector[2] / 2;
-        unit.vector[1] -= unit.vector[2] / 2;
-
-        if (pict->repeatType == RepeatNormal) {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
-                for (i = 0; i < width; ++i) {
-                    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    int x1, x2, y1, y2, distx, idistx, disty, idisty;
-			    FbBits *b;
-			    CARD32 tl, tr, bl, br, r;
-			    CARD32 ft, fb;
-
-			    if (!affine) {
-				xFixed_48_16 div;
-				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-				x1 = div >> 16;
-				distx = ((xFixed)div >> 8) & 0xff;
-				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-				y1 = div >> 16;
-				disty = ((xFixed)div >> 8) & 0xff;
-			    } else {
-				x1 = v.vector[0] >> 16;
-				distx = (v.vector[0] >> 8) & 0xff;
-				y1 = v.vector[1] >> 16;
-				disty = (v.vector[1] >> 8) & 0xff;
-			    }
-			    x2 = x1 + 1;
-			    y2 = y1 + 1;
-
-			    idistx = 256 - distx;
-			    idisty = 256 - disty;
-
-			    x1 = MOD (x1, pict->pDrawable->width);
-			    x2 = MOD (x2, pict->pDrawable->width);
-			    y1 = MOD (y1, pict->pDrawable->height);
-			    y2 = MOD (y2, pict->pDrawable->height);
-
-			    b = bits + (y1 + dy)*stride;
-
-			    tl = fetch(b, x1 + dx, indexed);
-			    tr = fetch(b, x2 + dx, indexed);
-			    b = bits + (y2 + dy)*stride;
-			    bl = fetch(b, x1 + dx, indexed);
-			    br = fetch(b, x2 + dx, indexed);
-
-			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
-			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-			    WRITE(buffer + i, r);
-			}
-		    }
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            } else {
-                for (i = 0; i < width; ++i) {
-		    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    int x1, x2, y1, y2, distx, idistx, disty, idisty;
-			    FbBits *b;
-			    CARD32 tl, tr, bl, br, r;
-			    CARD32 ft, fb;
-
-			    if (!affine) {
-				xFixed_48_16 div;
-				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-				x1 = div >> 16;
-				distx = ((xFixed)div >> 8) & 0xff;
-				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-				y1 = div >> 16;
-				disty = ((xFixed)div >> 8) & 0xff;
-			    } else {
-				x1 = v.vector[0] >> 16;
-				distx = (v.vector[0] >> 8) & 0xff;
-				y1 = v.vector[1] >> 16;
-				disty = (v.vector[1] >> 8) & 0xff;
-			    }
-			    x2 = x1 + 1;
-			    y2 = y1 + 1;
-
-			    idistx = 256 - distx;
-			    idisty = 256 - disty;
-
-			    x1 = MOD (x1, pict->pDrawable->width);
-			    x2 = MOD (x2, pict->pDrawable->width);
-			    y1 = MOD (y1, pict->pDrawable->height);
-			    y2 = MOD (y2, pict->pDrawable->height);
-
-			    b = bits + (y1 + dy)*stride;
-
-			    tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
-				? fetch(b, x1 + dx, indexed) : 0;
-			    tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
-				? fetch(b, x2 + dx, indexed) : 0;
-			    b = bits + (y2 + dy)*stride;
-			    bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
-				? fetch(b, x1 + dx, indexed) : 0;
-			    br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
-				? fetch(b, x2 + dx, indexed) : 0;
-
-			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
-			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-			    WRITE(buffer + i, r);
-			}
-		    }
-
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            }
-        } else {
-            if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
-                box = pict->pCompositeClip->extents;
-                for (i = 0; i < width; ++i) {
-		    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
-			    FbBits *b;
-			    CARD32 tl, tr, bl, br, r;
-			    Bool x1_out, x2_out, y1_out, y2_out;
-			    CARD32 ft, fb;
-
-			    if (!affine) {
-				xFixed_48_16 div;
-				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-				x1 = div >> 16;
-				distx = ((xFixed)div >> 8) & 0xff;
-				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-				y1 = div >> 16;
-				disty = ((xFixed)div >> 8) & 0xff;
-			    } else {
-				x1 = v.vector[0] >> 16;
-				distx = (v.vector[0] >> 8) & 0xff;
-				y1 = v.vector[1] >> 16;
-				disty = (v.vector[1] >> 8) & 0xff;
-			    }
-			    x2 = x1 + 1;
-			    y2 = y1 + 1;
-
-			    idistx = 256 - distx;
-			    idisty = 256 - disty;
-
-			    b = bits + (y1 + dy)*stride;
-			    x_off = x1 + dx;
-
-			    x1_out = (x1 < box.x1-dx) | (x1 >= box.x2-dx);
-			    x2_out = (x2 < box.x1-dx) | (x2 >= box.x2-dx);
-			    y1_out = (y1 < box.y1-dy) | (y1 >= box.y2-dy);
-			    y2_out = (y2 < box.y1-dy) | (y2 >= box.y2-dy);
-
-			    tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
-			    tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
-			    b += stride;
-			    bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
-			    br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
-
-			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
-			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-			    WRITE(buffer + i, r);
-			}
-		    }
-
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            } else {
-                for (i = 0; i < width; ++i) {
-                    if (!mask || mask[i] & maskBits)
-		    {
-			if (!v.vector[2]) {
-			    WRITE(buffer + i, 0);
-			} else {
-			    int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
-			    FbBits *b;
-			    CARD32 tl, tr, bl, br, r;
-			    CARD32 ft, fb;
-
-			    if (!affine) {
-				xFixed_48_16 div;
-				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-				x1 = div >> 16;
-				distx = ((xFixed)div >> 8) & 0xff;
-				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-				y1 = div >> 16;
-				disty = ((xFixed)div >> 8) & 0xff;
-			    } else {
-				x1 = v.vector[0] >> 16;
-				distx = (v.vector[0] >> 8) & 0xff;
-				y1 = v.vector[1] >> 16;
-				disty = (v.vector[1] >> 8) & 0xff;
-			    }
-			    x2 = x1 + 1;
-			    y2 = y1 + 1;
-
-			    idistx = 256 - distx;
-			    idisty = 256 - disty;
-
-			    b = bits + (y1 + dy)*stride;
-			    x_off = x1 + dx;
-
-			    tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
-				? fetch(b, x_off, indexed) : 0;
-			    tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
-				? fetch(b, x_off + 1, indexed) : 0;
-			    b += stride;
-			    bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
-				? fetch(b, x_off, indexed) : 0;
-			    br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
-				? fetch(b, x_off + 1, indexed) : 0;
-
-			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
-			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-			    WRITE(buffer + i, r);
-			}
-		    }
-
-                    v.vector[0] += unit.vector[0];
-                    v.vector[1] += unit.vector[1];
-                    v.vector[2] += unit.vector[2];
-                }
-            }
-        }
-    } else if (pict->filter == PictFilterConvolution) {
-        xFixed *params = pict->filter_params;
-        INT32 cwidth = xFixedToInt(params[0]);
-        INT32 cheight = xFixedToInt(params[1]);
-        int xoff = (params[0] - xFixed1) >> 1;
-	int yoff = (params[1] - xFixed1) >> 1;
-        params += 2;
-        for (i = 0; i < width; ++i) {
-	    if (!mask || mask[i] & maskBits)
-	    {
-		if (!v.vector[2]) {
-		    WRITE(buffer + i, 0);
-		} else {
-		    int x1, x2, y1, y2, x, y;
-		    INT32 srtot, sgtot, sbtot, satot;
-		    xFixed *p = params;
-
-		    if (!affine) {
-			xFixed_48_16 tmp;
-			tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
-			x1 = xFixedToInt(tmp);
-			tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
-			y1 = xFixedToInt(tmp);
-		    } else {
-			x1 = xFixedToInt(v.vector[0] - xoff);
-			y1 = xFixedToInt(v.vector[1] - yoff);
-		    }
-		    x2 = x1 + cwidth;
-		    y2 = y1 + cheight;
-
-		    srtot = sgtot = sbtot = satot = 0;
-
-		    for (y = y1; y < y2; y++) {
-			int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
-			for (x = x1; x < x2; x++) {
-			    if (*p) {
-				int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
-				if (POINT_IN_REGION (0, pict->pCompositeClip, tx + dx, ty + dy, &box)) {
-				    FbBits *b = bits + (ty + dy)*stride;
-				    CARD32 c = fetch(b, tx + dx, indexed);
-
-				    srtot += Red(c) * *p;
-				    sgtot += Green(c) * *p;
-				    sbtot += Blue(c) * *p;
-				    satot += Alpha(c) * *p;
-				}
-			    }
-			    p++;
-			}
-		    }
-
-		    satot >>= 16;
-		    srtot >>= 16;
-		    sgtot >>= 16;
-		    sbtot >>= 16;
-
-		    if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
-		    if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
-		    if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
-		    if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
-
-		    WRITE(buffer + i, ((satot << 24) |
-				       (srtot << 16) |
-				       (sgtot <<  8) |
-				       (sbtot       )));
-		}
-	    }
-            v.vector[0] += unit.vector[0];
-            v.vector[1] += unit.vector[1];
-            v.vector[2] += unit.vector[2];
-        }
-    }
-
-    fbFinishAccess (pict->pDrawable);
-}
-
-
-static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
-{
-    int i;
-    CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
-    CARD32 *alpha_buffer = _alpha_buffer;
-
-    if (!pict->alphaMap) {
-        fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
-	return;
-    }
-    if (width > SCANLINE_BUFFER_LENGTH)
-        alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
-
-    fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
-    fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
-		       y - pict->alphaOrigin.y, width, alpha_buffer,
-		       mask, maskBits);
-    for (i = 0; i < width; ++i) {
-        if (!mask || mask[i] & maskBits)
-	{
-	    int a = alpha_buffer[i]>>24;
-	    WRITE(buffer + i, (a << 24)
-		  | (div_255(Red(READ(buffer + i)) * a) << 16)
-		  | (div_255(Green(READ(buffer + i)) * a) << 8)
-		  | (div_255(Blue(READ(buffer + i)) * a)));
-	}
-    }
-
-    if (alpha_buffer != _alpha_buffer)
-        free(alpha_buffer);
-}
-
-static void fbStore(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
-{
-    FbBits *bits;
-    FbStride stride;
-    int bpp;
-    int xoff, yoff;
-    storeProc store = storeProcForPicture(pict);
-    miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
-
-    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-    x += xoff;
-    y += yoff;
-
-    bits += y*stride;
-    store(bits, buffer, x, width, indexed);
-    fbFinishAccess (pict->pDrawable);
-}
-
-static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
-{
-    FbBits *bits, *alpha_bits;
-    FbStride stride, astride;
-    int bpp, abpp;
-    int xoff, yoff;
-    int ax, ay;
-    storeProc store;
-    storeProc astore;
-    miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
-    miIndexedPtr aindexed;
-
-    if (!pict->alphaMap) {
-        fbStore(pict, x, y, width, buffer);
-	return;
-    }
-
-    store = storeProcForPicture(pict);
-    astore = storeProcForPicture(pict->alphaMap);
-    aindexed = (miIndexedPtr) pict->alphaMap->pFormat->index.devPrivate;
-
-    ax = x;
-    ay = y;
-
-    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-    x += xoff;
-    y += yoff;
-    fbGetDrawable (pict->alphaMap->pDrawable, alpha_bits, astride, abpp, xoff, yoff);
-    ax += xoff;
-    ay += yoff;
-
-    bits       += y*stride;
-    alpha_bits += (ay - pict->alphaOrigin.y)*astride;
-
-
-    store(bits, buffer, x, width, indexed);
-    astore(alpha_bits, buffer, ax - pict->alphaOrigin.x, width, aindexed);
-
-    fbFinishAccess (pict->alphaMap->pDrawable);
-    fbFinishAccess (pict->pDrawable);
-}
-
-typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
-typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
-
-#if 0
-void
-fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
-{
-    CARD32 *src_buffer = scanline_buffer;
-    CARD32 *dest_buffer = src_buffer + data->width;
-    int i;
-    scanStoreProc store;
-    scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
-    unsigned int srcClass = SourcePictClassUnknown;
-    unsigned int maskClass = SourcePictClassUnknown;
-    FbBits *bits;
-    FbStride stride;
-    int xoff, yoff;
-    
-    if (data->op == PictOpClear)
-        fetchSrc = NULL;
-    else if (!data->src->pDrawable) {
-        if (data->src->pSourcePict)
-	{
-            fetchSrc = fbFetchSourcePict;
-	    srcClass = SourcePictureClassify (data->src,
-					      data->xSrc, data->ySrc,
-					      data->width, data->height);
-	}
-    } else if (data->src->alphaMap)
-        fetchSrc = fbFetchExternalAlpha;
-    else if (data->src->repeatType == RepeatNormal &&
-             data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
-    {
-        fetchSrc = fbFetchSolid;
-	srcClass = SourcePictClassHorizontal;
-    }
-    else if (!data->src->transform && data->src->filter != PictFilterConvolution)
-        fetchSrc = fbFetch;
-    else
-        fetchSrc = fbFetchTransformed;
-    
-    if (data->mask && data->op != PictOpClear) {
-        if (!data->mask->pDrawable) {
-            if (data->mask->pSourcePict)
-                fetchMask = fbFetchSourcePict;
-        } else if (data->mask->alphaMap)
-	{
-            fetchMask = fbFetchExternalAlpha;
-	    maskClass = SourcePictureClassify (data->mask,
-					       data->xMask, data->yMask,
-					       data->width, data->height);
-	}
-        else if (data->mask->repeatType == RepeatNormal
-                 && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
-	{
-	    fetchMask = fbFetchSolid;
-	    maskClass = SourcePictClassHorizontal;
-	}
-        else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
-            fetchMask = fbFetch;
-        else
-            fetchMask = fbFetchTransformed;
-    } else {
-        fetchMask = NULL;
-    }
-    
-    if (data->dest->alphaMap)
-    {
-	fetchDest = fbFetchExternalAlpha;
-	store = fbStoreExternalAlpha;
-	
-	if (data->op == PictOpClear || data->op == PictOpSrc)
-	    fetchDest = NULL;
-    }
-    else
-    {
-	fetchDest = fbFetch;
-	store = fbStore;
-	
-	switch (data->op) {
-	case PictOpClear:
-	case PictOpSrc:
-	    fetchDest = NULL;
-	    /* fall-through */
-	case PictOpAdd:
-	case PictOpOver:
-	    switch (data->dest->format) {
-	    case PICT_a8r8g8b8:
-	    case PICT_x8r8g8b8:
-		store = NULL;
-		break;
-	    default:
-		break;
-	    }
-	    break;
-	}
-    }
-    
-    if (!store)
-    {
-	int bpp;
-	
-	fbGetDrawable (data->dest->pDrawable, bits, stride, bpp, xoff, yoff);
-    }
-    else
-    {
-	bits = NULL;
-	stride = 0;
-	xoff = yoff = 0;
-    }
-    
-    if (fetchSrc		   &&
-	fetchMask		   &&
-	data->mask		   &&
-	data->mask->componentAlpha &&
-	PICT_FORMAT_RGB (data->mask->format))
-    {
-	CARD32 *mask_buffer = dest_buffer + data->width;
-	CombineFuncC compose = composeFunctions.combineC[data->op];
-	if (!compose)
-	    return;
-	
-	for (i = 0; i < data->height; ++i) {
-	    /* fill first half of scanline with source */
-	    if (fetchSrc)
-	    {
-		if (fetchMask)
-		{
-		    /* fetch mask before source so that fetching of
-		       source can be optimized */
-		    fetchMask (data->mask, data->xMask, data->yMask + i,
-			       data->width, mask_buffer, 0, 0);
-		    
-		    if (maskClass == SourcePictClassHorizontal)
-			fetchMask = NULL;
-		}
-		
-		if (srcClass == SourcePictClassHorizontal)
-		{
-		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
-			      data->width, src_buffer, 0, 0);
-		    fetchSrc = NULL;
-		}
-		else
-		{
-		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
-			      data->width, src_buffer, mask_buffer,
-			      0xffffffff);
-		}
-	    }
-	    else if (fetchMask)
-	    {
-		fetchMask (data->mask, data->xMask, data->yMask + i,
-			   data->width, mask_buffer, 0, 0);
-	    }
-	    
-	    if (store)
-	    {
-		/* fill dest into second half of scanline */
-		if (fetchDest)
-		    fetchDest (data->dest, data->xDest, data->yDest + i,
-			       data->width, dest_buffer, 0, 0);
-		
-		/* blend */
-		compose (dest_buffer, src_buffer, mask_buffer, data->width);
-		
-		/* write back */
-		store (data->dest, data->xDest, data->yDest + i, data->width,
-		       dest_buffer);
-	    }
-	    else
-	    {
-		/* blend */
-		compose (bits + (data->yDest + i+ yoff) * stride +
-			 data->xDest + xoff,
-			 src_buffer, mask_buffer, data->width);
-	    }
-	}
-    }
-    else
-    {
-	CARD32 *src_mask_buffer = 0, *mask_buffer = 0;
-	CombineFuncU compose = composeFunctions.combineU[data->op];
-	if (!compose)
-	    return;
-	
-	if (fetchMask)
-	    mask_buffer = dest_buffer + data->width;
-	
-	for (i = 0; i < data->height; ++i) {
-	    /* fill first half of scanline with source */
-	    if (fetchSrc)
-	    {
-		if (fetchMask)
-		{
-		    /* fetch mask before source so that fetching of
-		       source can be optimized */
-		    fetchMask (data->mask, data->xMask, data->yMask + i,
-			       data->width, mask_buffer, 0, 0);
-		    
-		    if (maskClass == SourcePictClassHorizontal)
-			fetchMask = NULL;
-		}
-		
-		if (srcClass == SourcePictClassHorizontal)
-		{
-		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
-			      data->width, src_buffer, 0, 0);
-		    
-		    if (mask_buffer)
-		    {
-			fbCombineInU (mask_buffer, src_buffer, data->width);
-			src_mask_buffer = mask_buffer;
-		    }
-		    else
-			src_mask_buffer = src_buffer;
-		    
-		    fetchSrc = NULL;
-		}
-		else
-		{
-		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
-			      data->width, src_buffer, mask_buffer,
-			      0xff000000);
-		    
-		    if (mask_buffer)
-			composeFunctions.combineMaskU (src_buffer,
-						       mask_buffer,
-						       data->width);
-		    
-		    src_mask_buffer = src_buffer;
-		}
-	    }
-	    else if (fetchMask)
-	    {
-		fetchMask (data->mask, data->xMask, data->yMask + i,
-			   data->width, mask_buffer, 0, 0);
-		
-		fbCombineInU (mask_buffer, src_buffer, data->width);
-		
-		src_mask_buffer = mask_buffer;
-	    }
-	    
-	    if (store)
-	    {
-		/* fill dest into second half of scanline */
-		if (fetchDest)
-		    fetchDest (data->dest, data->xDest, data->yDest + i,
-			       data->width, dest_buffer, 0, 0);
-		
-		/* blend */
-		compose (dest_buffer, src_mask_buffer, data->width);
-		
-		/* write back */
-		store (data->dest, data->xDest, data->yDest + i, data->width,
-		       dest_buffer);
-	    }
-	    else
-	    {
-		/* blend */
-		compose (bits + (data->yDest + i+ yoff) * stride +
-			 data->xDest + xoff,
-			 src_mask_buffer, data->width);
-	    }
-	}
-    }
-
-    if (!store)
-	fbFinishAccess (data->dest->pDrawable);
-}
-#endif
-
-void
-fbCompositeGeneral (CARD8	op,
-		    PicturePtr	pSrc,
-		    PicturePtr	pMask,
-		    PicturePtr	pDst,
-		    INT16	xSrc,
-		    INT16	ySrc,
-		    INT16	xMask,
-		    INT16	yMask,
-		    INT16	xDst,
-		    INT16	yDst,
-		    CARD16	width,
-		    CARD16	height)
-{
-    return fbComposite (op, pSrc, pMask, pDst,
-			xSrc, ySrc, xMask, yMask, xDst, yDst,
-			width, height);
-}
-
-#endif
diff --git a/fb/fbpict.c b/fb/fbpict.c
index fc335ed..324d9b2 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1183,50 +1183,6 @@ out:
 	pixman_image_unref (dest);
 }    
 
-#if 0
-#define SCANLINE_BUFFER_LENGTH 2048
-
-static void
-oldfbCompositeRectWrapper  (CARD8	   op,
-			 PicturePtr pSrc,
-			 PicturePtr pMask,
-			 PicturePtr pDst,
-			 INT16      xSrc,
-			 INT16      ySrc,
-			 INT16      xMask,
-			 INT16      yMask,
-			 INT16      xDst,
-			 INT16      yDst,
-			 CARD16     width,
-			 CARD16     height)
-{
-    CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
-    CARD32 *scanline_buffer = _scanline_buffer;
-    FbComposeData data;
-
-    data.op = op;
-    data.src = pSrc;
-    data.mask = pMask;
-    data.dest = pDst;
-    data.xSrc = xSrc;
-    data.ySrc = ySrc;
-    data.xMask = xMask;
-    data.yMask = yMask;
-    data.xDest = xDst;
-    data.yDest = yDst;
-    data.width = width;
-    data.height = height;
-
-    if (width > SCANLINE_BUFFER_LENGTH)
-        scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
-
-    fbCompositeRect (&data, scanline_buffer);
-
-    if (scanline_buffer != _scanline_buffer)
-	free(scanline_buffer);
-}
-#endif
-
 void
 fbWalkCompositeRegion (CARD8 op,
 		       PicturePtr pSrc,
@@ -1932,6 +1888,25 @@ fbComposite (CARD8      op,
 			   srcRepeat, maskRepeat, func);
 }
 
+void
+fbCompositeGeneral (CARD8	op,
+		    PicturePtr	pSrc,
+		    PicturePtr	pMask,
+		    PicturePtr	pDst,
+		    INT16	xSrc,
+		    INT16	ySrc,
+		    INT16	xMask,
+		    INT16	yMask,
+		    INT16	xDst,
+		    INT16	yDst,
+		    CARD16	width,
+		    CARD16	height)
+{
+    return fbComposite (op, pSrc, pMask, pDst,
+			xSrc, ySrc, xMask, yMask, xDst, yDst,
+			width, height);
+}
+
 #endif /* RENDER */
 
 Bool
diff-tree a2e3614eb8f0fa198615df492b03ff36bc9c1121 (from c5ef84c325440af5fbdf9f44c3781d99a0392df9)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri May 18 11:33:11 2007 -0400

    Break image_from_pict() into a few subfunctions.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 4034a16..fc335ed 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -931,218 +931,222 @@ fbCompositeSrcSrc_nxn  (CARD8	   op,
     fbFinishAccess(pDst->pDrawable);
 }
 
-/*
- * Solid fill
-void
-fbCompositeSolidSrc_nxn  (CARD8	op,
-			  PicturePtr pSrc,
-			  PicturePtr pMask,
-			  PicturePtr pDst,
-			  INT16      xSrc,
-			  INT16      ySrc,
-			  INT16      xMask,
-			  INT16      yMask,
-			  INT16      xDst,
-			  INT16      yDst,
-			  CARD16     width,
-			  CARD16     height)
+static pixman_image_t *
+create_solid_fill_image (PicturePtr pict)
 {
+    PictSolidFill *solid = &pict->pSourcePict->solidFill;
+    pixman_color_t color;
+    CARD32 a, r, g, b;
+    
+    a = (solid->color & 0xff000000) >> 24;
+    r = (solid->color & 0x00ff0000) >> 16;
+    g = (solid->color & 0x0000ff00) >>  8;
+    b = (solid->color & 0x000000ff) >>  0;
     
+    color.alpha = (a << 8) | a;
+    color.red =   (r << 8) | r;
+    color.green = (g << 8) | g;
+    color.blue =  (b << 8) | b;
+    
+    return pixman_image_create_solid_fill (&color);
 }
- */
-
-#define SCANLINE_BUFFER_LENGTH 2048
 
 static pixman_image_t *
-image_from_pict (PicturePtr pict)
+create_linear_gradient_image (PictGradient *gradient)
 {
-    pixman_image_t *result = NULL;
-
-    if (!pict)
-	return NULL;
+    PictLinearGradient *linear = (PictLinearGradient *)gradient;
+    pixman_point_fixed_t p1;
+    pixman_point_fixed_t p2;
     
-    if (pict->pSourcePict)
-    {
-	SourcePictPtr sp = pict->pSourcePict;
-	
-	if (sp->type == SourcePictTypeSolidFill)
-	{
-	    PictSolidFill *solid = &pict->pSourcePict->solidFill;
-	    pixman_color_t color;
-	    CARD32 a, r, g, b;
-
-	    a = (solid->color & 0xff000000) >> 24;
-	    r = (solid->color & 0x00ff0000) >> 16;
-	    g = (solid->color & 0x0000ff00) >>  8;
-	    b = (solid->color & 0x000000ff) >>  0;
-
-	    color.alpha = (a << 8) | a;
-	    color.red =   (r << 8) | r;
-	    color.green = (g << 8) | g;
-	    color.blue =  (b << 8) | b;
-	    
-	    result = pixman_image_create_solid_fill (&color);
-	}
-	else
-	{
-	    PictGradient *gradient = &pict->pSourcePict->gradient;
-
-	    if (sp->type == SourcePictTypeLinear)
-	    {
-		PictLinearGradient *linear = &pict->pSourcePict->linear;
-		pixman_point_fixed_t p1;
-		pixman_point_fixed_t p2;
-
-		p1.x = linear->p1.x;
-		p1.y = linear->p1.y;
-		p2.x = linear->p2.x;
-		p2.y = linear->p2.y;
-		
-		result = pixman_image_create_linear_gradient (
-		    &p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
-	    }
-	    else if (sp->type == SourcePictTypeRadial)
-	    {
-		PictRadialGradient *radial = &pict->pSourcePict->radial;
-		
-		pixman_point_fixed_t c1;
-		pixman_point_fixed_t c2;
-
-		c1.x = radial->c1.x;
-		c1.y = radial->c1.y;
-		c2.x = radial->c2.x;
-		c2.y = radial->c2.y;
-		
-		result = pixman_image_create_radial_gradient (
-		    &c1, &c2, radial->c1.radius,
-		    radial->c2.radius,
-		    (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
-	    }
-	    else if (sp->type == SourcePictTypeConical)
-	    {
-		PictConicalGradient *conical = &pict->pSourcePict->conical;
-		pixman_point_fixed_t center;
-
-		center.x = conical->center.x;
-		center.y = conical->center.y;
-		
-		result = pixman_image_create_conical_gradient (
-		    &center, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
-		    gradient->nstops);
-	    }
-	    else
-	    {
-		/* Shouldn't happen */
-		result = NULL;
-	    }
-	}
-    }
-    else if (pict->pDrawable)
-    {
-	FbBits *bits;
-	FbStride stride;
-	int bpp, xoff, yoff;
-
-	fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+    p1.x = linear->p1.x;
+    p1.y = linear->p1.y;
+    p2.x = linear->p2.x;
+    p2.y = linear->p2.y;
+    
+    return pixman_image_create_linear_gradient (
+	&p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+}
 
-	bits += yoff * stride + xoff;
-	
-	result = pixman_image_create_bits (
-	    pict->format,
-	    pict->pDrawable->width, pict->pDrawable->height,
-	    (uint32_t *)bits, stride * sizeof (FbStride));
+static pixman_image_t *
+create_radial_gradient_image (PictGradient *gradient)
+{
+    PictRadialGradient *radial = (PictRadialGradient *)gradient;
+    pixman_point_fixed_t c1;
+    pixman_point_fixed_t c2;
+    
+    c1.x = radial->c1.x;
+    c1.y = radial->c1.y;
+    c2.x = radial->c2.x;
+    c2.y = radial->c2.y;
+    
+    return pixman_image_create_radial_gradient (
+	&c1, &c2, radial->c1.radius,
+	radial->c2.radius,
+	(pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+}
 
+static pixman_image_t *
+create_conical_gradient_image (PictGradient *gradient)
+{
+    PictConicalGradient *conical = (PictConicalGradient *)gradient;
+    pixman_point_fixed_t center;
+    
+    center.x = conical->center.x;
+    center.y = conical->center.y;
+    
+    return pixman_image_create_conical_gradient (
+	&center, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
+	gradient->nstops);
+}
 
+static pixman_image_t *
+create_bits_picture (PicturePtr pict)
+{
+    FbBits *bits;
+    FbStride stride;
+    int bpp, xoff, yoff;
+    pixman_image_t *image;
+    
+    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+    
+    bits += yoff * stride + xoff;
+    
+    image = pixman_image_create_bits (
+	pict->format,
+	pict->pDrawable->width, pict->pDrawable->height,
+	(uint32_t *)bits, stride * sizeof (FbStride));
+    
+    
 #ifdef FB_ACCESS_WRAPPER
 #if FB_SHIFT==5
-	
-	pixman_image_set_accessors (
-	    result,
-	    (pixman_read_memory_func_t)wfbReadMemory,
-	    (pixman_write_memory_func_t)wfbWriteMemory);
+    
+    pixman_image_set_accessors (image,
+				(pixman_read_memory_func_t)wfbReadMemory,
+				(pixman_write_memory_func_t)wfbWriteMemory);
+    
 #else
-
-#error The pixman library only works with sizeof (FbBits) == 5
-
+    
+#error The pixman library only works when FbBits is 32 bits wide
+    
 #endif
 #endif
-	
-	/* pCompositeClip is undefined for source pictures, so
-	 * only set the clip region for pictures with drawables
-	 */
-	pixman_image_set_clip_region (
-	    result, pict->pCompositeClip);
+    
+    /* pCompositeClip is undefined for source pictures, so
+     * only set the clip region for pictures with drawables
+     */
+    pixman_image_set_clip_region (image, pict->pCompositeClip);
+    
+    fbFinishAccess (pict->pDrawable);
+
+    return image;
+}
+
+static pixman_image_t *image_from_pict (PicturePtr pict);
 
-	fbFinishAccess (pict->pDrawable);
+static void
+set_image_properties (pixman_image_t *image, PicturePtr pict)
+{
+    pixman_repeat_t repeat;
+    pixman_filter_t filter;
+    
+    if (pict->transform)
+    {
+	pixman_image_set_transform (
+	    image, (pixman_transform_t *)pict->transform);
+    }
+    
+    switch (pict->repeatType)
+    {
+    default:
+    case RepeatNone:
+	repeat = PIXMAN_REPEAT_NONE;
+	break;
+	
+    case RepeatPad:
+	repeat = PIXMAN_REPEAT_PAD;
+	break;
+	
+    case RepeatNormal:
+	repeat = PIXMAN_REPEAT_NORMAL;
+	break;
+	
+    case RepeatReflect:
+	repeat = PIXMAN_REPEAT_REFLECT;
+	break;
+    }
+    
+    pixman_image_set_repeat (image, repeat);
+    
+    if (pict->alphaMap)
+    {
+	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap);
+	
+	pixman_image_set_alpha_map (
+	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
+	
+	pixman_image_unref (alpha_map);
     }
+    
+    pixman_image_set_component_alpha (image, pict->componentAlpha);
 
-    if (result)
+    switch (pict->filter)
     {
-	pixman_repeat_t repeat;
-	pixman_filter_t filter;
+    default:
+    case PictFilterNearest:
+    case PictFilterFast:
+	filter = PIXMAN_FILTER_NEAREST;
+	break;
 	
-	if (pict->transform)
-	{
-	    pixman_image_set_transform (
-		result, (pixman_transform_t *)pict->transform);
-	}
+    case PictFilterBilinear:
+    case PictFilterGood:
+	filter = PIXMAN_FILTER_BILINEAR;
+	break;
+	
+    case PictFilterConvolution:
+	filter = PIXMAN_FILTER_CONVOLUTION;
+	break;
+    }
+    
+    pixman_image_set_filter (image, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
+}
 
-	switch (pict->repeatType)
-	{
-	default:
-	case RepeatNone:
-	    repeat = PIXMAN_REPEAT_NONE;
-	    break;
-
-	case RepeatPad:
-	    repeat = PIXMAN_REPEAT_PAD;
-	    break;
-
-	case RepeatNormal:
-	    repeat = PIXMAN_REPEAT_NORMAL;
-	    break;
-
-	case RepeatReflect:
-	    repeat = PIXMAN_REPEAT_REFLECT;
-	    break;
-	}
+static pixman_image_t *
+image_from_pict (PicturePtr pict)
+{
+    pixman_image_t *image = NULL;
 
-	pixman_image_set_repeat (result, repeat);
+    if (!pict)
+	return NULL;
 
-	if (pict->alphaMap)
+    if (pict->pDrawable)
+    {
+	image = create_bits_picture (pict);
+    }
+    else if (pict->pSourcePict)
+    {
+	SourcePict *sp = pict->pSourcePict;
+	
+	if (sp->type == SourcePictTypeSolidFill)
 	{
-	    pixman_image_t *alpha_map = image_from_pict (pict->alphaMap);
-
-	    pixman_image_set_alpha_map (
-		result, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
-
-	    pixman_image_unref (alpha_map);
+	    image = create_solid_fill_image (pict);
 	}
-
-	pixman_image_set_component_alpha (result, pict->componentAlpha);
-
-	switch (pict->filter)
+	else
 	{
-	default:
-	case PictFilterNearest:
-	case PictFilterFast:
-	    filter = PIXMAN_FILTER_NEAREST;
-	    break;
-
-	case PictFilterBilinear:
-	case PictFilterGood:
-	    filter = PIXMAN_FILTER_BILINEAR;
-	    break;
-
-	case PictFilterConvolution:
-	    filter = PIXMAN_FILTER_CONVOLUTION;
-	    break;
+	    PictGradient *gradient = &pict->pSourcePict->gradient;
+	    
+	    if (sp->type == SourcePictTypeLinear)
+		image = create_linear_gradient_image (gradient);
+	    else if (sp->type == SourcePictTypeRadial)
+		image = create_radial_gradient_image (gradient);
+	    else if (sp->type == SourcePictTypeConical)
+		image = create_conical_gradient_image (gradient);
 	}
-
-	pixman_image_set_filter (result, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
     }
     
-    return result;
+    if (image)
+	set_image_properties (image, pict);
+    
+    return image;
 }
 
 static void
@@ -1180,6 +1184,8 @@ out:
 }    
 
 #if 0
+#define SCANLINE_BUFFER_LENGTH 2048
+
 static void
 oldfbCompositeRectWrapper  (CARD8	   op,
 			 PicturePtr pSrc,
diff-tree c5ef84c325440af5fbdf9f44c3781d99a0392df9 (from 076d070e186afeb416976ae74fbfd50c86db10c5)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu May 17 21:31:08 2007 -0400

    Make the general compositing code create a pixman image and call
    
    pixman_image_composite(). Leave the general code commented out for now.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 465f7d3..0e64de0 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -1553,7 +1553,6 @@ fbCombineSrcU (CARD32 *dest, const CARD3
     MEMCPY_WRAPPED(dest, src, width*sizeof(CARD32));
 }
 
-
 static FASTCALL void
 fbCombineOverU (CARD32 *dest, const CARD32 *src, int width)
 {
@@ -4028,6 +4027,7 @@ static void fbStoreExternalAlpha(Picture
 typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
 typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
 
+#if 0
 void
 fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
 {
@@ -4294,6 +4294,7 @@ fbCompositeRect (const FbComposeData *da
     if (!store)
 	fbFinishAccess (data->dest->pDrawable);
 }
+#endif
 
 void
 fbCompositeGeneral (CARD8	op,
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 1146e99..4034a16 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1,6 +1,7 @@
 /*
  *
  * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -29,6 +30,7 @@
 #include <string.h>
 
 #include "fb.h"
+#include <pixman/pixman.h>
 
 #ifdef RENDER
 
@@ -950,7 +952,199 @@ fbCompositeSolidSrc_nxn  (CARD8	op,
  */
 
 #define SCANLINE_BUFFER_LENGTH 2048
- 
+
+static pixman_image_t *
+image_from_pict (PicturePtr pict)
+{
+    pixman_image_t *result = NULL;
+
+    if (!pict)
+	return NULL;
+    
+    if (pict->pSourcePict)
+    {
+	SourcePictPtr sp = pict->pSourcePict;
+	
+	if (sp->type == SourcePictTypeSolidFill)
+	{
+	    PictSolidFill *solid = &pict->pSourcePict->solidFill;
+	    pixman_color_t color;
+	    CARD32 a, r, g, b;
+
+	    a = (solid->color & 0xff000000) >> 24;
+	    r = (solid->color & 0x00ff0000) >> 16;
+	    g = (solid->color & 0x0000ff00) >>  8;
+	    b = (solid->color & 0x000000ff) >>  0;
+
+	    color.alpha = (a << 8) | a;
+	    color.red =   (r << 8) | r;
+	    color.green = (g << 8) | g;
+	    color.blue =  (b << 8) | b;
+	    
+	    result = pixman_image_create_solid_fill (&color);
+	}
+	else
+	{
+	    PictGradient *gradient = &pict->pSourcePict->gradient;
+
+	    if (sp->type == SourcePictTypeLinear)
+	    {
+		PictLinearGradient *linear = &pict->pSourcePict->linear;
+		pixman_point_fixed_t p1;
+		pixman_point_fixed_t p2;
+
+		p1.x = linear->p1.x;
+		p1.y = linear->p1.y;
+		p2.x = linear->p2.x;
+		p2.y = linear->p2.y;
+		
+		result = pixman_image_create_linear_gradient (
+		    &p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+	    }
+	    else if (sp->type == SourcePictTypeRadial)
+	    {
+		PictRadialGradient *radial = &pict->pSourcePict->radial;
+		
+		pixman_point_fixed_t c1;
+		pixman_point_fixed_t c2;
+
+		c1.x = radial->c1.x;
+		c1.y = radial->c1.y;
+		c2.x = radial->c2.x;
+		c2.y = radial->c2.y;
+		
+		result = pixman_image_create_radial_gradient (
+		    &c1, &c2, radial->c1.radius,
+		    radial->c2.radius,
+		    (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+	    }
+	    else if (sp->type == SourcePictTypeConical)
+	    {
+		PictConicalGradient *conical = &pict->pSourcePict->conical;
+		pixman_point_fixed_t center;
+
+		center.x = conical->center.x;
+		center.y = conical->center.y;
+		
+		result = pixman_image_create_conical_gradient (
+		    &center, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
+		    gradient->nstops);
+	    }
+	    else
+	    {
+		/* Shouldn't happen */
+		result = NULL;
+	    }
+	}
+    }
+    else if (pict->pDrawable)
+    {
+	FbBits *bits;
+	FbStride stride;
+	int bpp, xoff, yoff;
+
+	fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+
+	bits += yoff * stride + xoff;
+	
+	result = pixman_image_create_bits (
+	    pict->format,
+	    pict->pDrawable->width, pict->pDrawable->height,
+	    (uint32_t *)bits, stride * sizeof (FbStride));
+
+
+#ifdef FB_ACCESS_WRAPPER
+#if FB_SHIFT==5
+	
+	pixman_image_set_accessors (
+	    result,
+	    (pixman_read_memory_func_t)wfbReadMemory,
+	    (pixman_write_memory_func_t)wfbWriteMemory);
+#else
+
+#error The pixman library only works with sizeof (FbBits) == 5
+
+#endif
+#endif
+	
+	/* pCompositeClip is undefined for source pictures, so
+	 * only set the clip region for pictures with drawables
+	 */
+	pixman_image_set_clip_region (
+	    result, pict->pCompositeClip);
+
+	fbFinishAccess (pict->pDrawable);
+    }
+
+    if (result)
+    {
+	pixman_repeat_t repeat;
+	pixman_filter_t filter;
+	
+	if (pict->transform)
+	{
+	    pixman_image_set_transform (
+		result, (pixman_transform_t *)pict->transform);
+	}
+
+	switch (pict->repeatType)
+	{
+	default:
+	case RepeatNone:
+	    repeat = PIXMAN_REPEAT_NONE;
+	    break;
+
+	case RepeatPad:
+	    repeat = PIXMAN_REPEAT_PAD;
+	    break;
+
+	case RepeatNormal:
+	    repeat = PIXMAN_REPEAT_NORMAL;
+	    break;
+
+	case RepeatReflect:
+	    repeat = PIXMAN_REPEAT_REFLECT;
+	    break;
+	}
+
+	pixman_image_set_repeat (result, repeat);
+
+	if (pict->alphaMap)
+	{
+	    pixman_image_t *alpha_map = image_from_pict (pict->alphaMap);
+
+	    pixman_image_set_alpha_map (
+		result, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
+
+	    pixman_image_unref (alpha_map);
+	}
+
+	pixman_image_set_component_alpha (result, pict->componentAlpha);
+
+	switch (pict->filter)
+	{
+	default:
+	case PictFilterNearest:
+	case PictFilterFast:
+	    filter = PIXMAN_FILTER_NEAREST;
+	    break;
+
+	case PictFilterBilinear:
+	case PictFilterGood:
+	    filter = PIXMAN_FILTER_BILINEAR;
+	    break;
+
+	case PictFilterConvolution:
+	    filter = PIXMAN_FILTER_CONVOLUTION;
+	    break;
+	}
+
+	pixman_image_set_filter (result, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
+    }
+    
+    return result;
+}
+
 static void
 fbCompositeRectWrapper  (CARD8	   op,
 			 PicturePtr pSrc,
@@ -965,6 +1159,41 @@ fbCompositeRectWrapper  (CARD8	   op,
 			 CARD16     width,
 			 CARD16     height)
 {
+    pixman_image_t *src = image_from_pict (pSrc);
+    pixman_image_t *dest = image_from_pict (pDst);
+    pixman_image_t *mask = image_from_pict (pMask);
+
+    if (!src || !dest || (pMask && !mask))
+	goto out;
+
+    pixman_image_composite_rect (op, src, mask, dest,
+				 xSrc, ySrc, xMask, yMask, xDst, yDst,
+				 width, height);
+    
+out:
+    if (src)
+	pixman_image_unref (src);
+    if (mask)
+	pixman_image_unref (mask);
+    if (dest)
+	pixman_image_unref (dest);
+}    
+
+#if 0
+static void
+oldfbCompositeRectWrapper  (CARD8	   op,
+			 PicturePtr pSrc,
+			 PicturePtr pMask,
+			 PicturePtr pDst,
+			 INT16      xSrc,
+			 INT16      ySrc,
+			 INT16      xMask,
+			 INT16      yMask,
+			 INT16      xDst,
+			 INT16      yDst,
+			 CARD16     width,
+			 CARD16     height)
+{
     CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
     CARD32 *scanline_buffer = _scanline_buffer;
     FbComposeData data;
@@ -990,6 +1219,7 @@ fbCompositeRectWrapper  (CARD8	   op,
     if (scanline_buffer != _scanline_buffer)
 	free(scanline_buffer);
 }
+#endif
 
 void
 fbWalkCompositeRegion (CARD8 op,
@@ -1030,7 +1260,7 @@ fbWalkCompositeRegion (CARD8 op,
     if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
 				   xMask, yMask, xDst, yDst, width, height))
         return;
-
+    
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
     while (n--)
diff-tree 076d070e186afeb416976ae74fbfd50c86db10c5 (from 915563eba530c5e2fdc2456cf1c7c3cc09b3add0)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu May 17 20:24:18 2007 -0700

    Use Screen block handler for rotation to draw under DRI lock.
    
    DRI uses a non-screen block/wakeup handler which will be executed after the
    screen block handler finishes. To ensure that the rotation block handler is
    executed under the DRI lock, dynamically wrap the screen block handler for
    rotation.

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 0c019e0..2d62600 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -562,6 +562,10 @@ typedef struct _xf86CrtcConfig {
     OptionInfoPtr	options;
 
     Bool		debug_modes;
+
+    /* wrap screen BlockHandler for rotation */
+    ScreenBlockHandlerProcPtr	BlockHandler;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 359501e..1379939 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -264,7 +264,7 @@ xf86RotatePrepare (ScreenPtr pScreen)
     }
 }
 
-static void
+static Bool
 xf86RotateRedisplay(ScreenPtr pScreen)
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
@@ -273,7 +273,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
     RegionPtr		region;
 
     if (!damage)
-	return;
+	return FALSE;
     xf86RotatePrepare (pScreen);
     region = DamageRegion(damage);
     if (REGION_NOTEMPTY(pScreen, region)) 
@@ -317,19 +317,25 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 	pScreen->SourceValidate = SourceValidate;
 	DamageEmpty(damage);
     }
+    return TRUE;
 }
 
 static void
-xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+xf86RotateBlockHandler(int screenNum, pointer blockData,
+		       pointer pTimeout, pointer pReadmask)
 {
-    ScreenPtr pScreen = (ScreenPtr) data;
-
-    xf86RotateRedisplay(pScreen);
-}
+    ScreenPtr		pScreen = screenInfo.screens[screenNum];
+    ScrnInfoPtr		pScrn = xf86Screens[screenNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
-static void
-xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
-{
+    pScreen->BlockHandler = xf86_config->BlockHandler;
+    (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+    if (xf86RotateRedisplay(pScreen))
+    {
+	/* Re-wrap if rotation is still happening */
+	xf86_config->BlockHandler = pScreen->BlockHandler;
+	pScreen->BlockHandler = xf86RotateBlockHandler;
+    }
 }
 
 static void
@@ -367,10 +373,6 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
 	}
 	DamageDestroy (xf86_config->rotation_damage);
 	xf86_config->rotation_damage = NULL;
-	/* Free block/wakeup handler */
-	RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
-				      xf86RotateWakeupHandler,
-				      (pointer) pScreen);
     }
 }
 
@@ -440,20 +442,12 @@ xf86CrtcRotate (xf86CrtcPtr crtc, Displa
 	    if (!xf86_config->rotation_damage)
 		goto bail2;
 	    
-	    /* Assign block/wakeup handler */
-	    if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
-						 xf86RotateWakeupHandler,
-						 (pointer) pScreen))
-	    {
-		goto bail3;
-	    }
+	    /* Wrap block handler */
+	    xf86_config->BlockHandler = pScreen->BlockHandler;
+	    pScreen->BlockHandler = xf86RotateBlockHandler;
 	}
 	if (0)
 	{
-bail3:
-	    DamageDestroy (xf86_config->rotation_damage);
-	    xf86_config->rotation_damage = NULL;
-	    
 bail2:
 	    if (shadow || shadowData)
 	    {
diff-tree 915563eba530c5e2fdc2456cf1c7c3cc09b3add0 (from 0375009a97c2ab7f0e0f0265463d45c0580388c6)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu May 17 20:22:43 2007 -0700

    Disable all outputs and crtcs at startup.
    
    Leaving devices enabled during server startup can cause problems during the
    initial mode setting in the server, especially when they are used for
    different purposes by the X server than by the BIOS. Disabling all of them
    before any mode setting is attempted provides a stable base upon which the
    remaining mode setting operations can be built.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 00ec56c..88c31af 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1723,8 +1723,26 @@ Bool
 xf86SetDesiredModes (ScrnInfoPtr scrn)
 {
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			c;
+    int			c, o;
+
+    /*
+     * Turn off everything so mode setting is done
+     * with hardware in a consistent state
+     */
+    for (o = 0; o < config->num_output; o++) 
+    {
+	xf86OutputPtr  output = config->output[o];
+	(*output->funcs->dpms)(output, DPMSModeOff);
+    }
 
+    for (c = 0; c < config->num_crtc; c++) 
+    {
+	xf86CrtcPtr crtc = config->crtc[c];
+
+	crtc->funcs->dpms(crtc, DPMSModeOff);
+	memset(&crtc->mode, 0, sizeof(crtc->mode));
+    }
+    
     for (c = 0; c < config->num_crtc; c++)
     {
 	xf86CrtcPtr	crtc = config->crtc[c];
diff-tree 0375009a97c2ab7f0e0f0265463d45c0580388c6 (from 546465ee6aa6584780aec6357f32d205c807ae71)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu May 17 12:59:24 2007 -0400

    Remove excessive unrolling in fbCompositeSrc_x888x8x8888() and fix bug where
    the source alpha was used instead of 0xff.

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index a322bec..8a132f6 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -295,6 +295,14 @@ in (__m64 src,
     return pix_multiply (src, mask);
 }
 
+static inline __m64
+in_over_full_src_alpha (__m64 src, __m64 mask, __m64 dest)
+{
+    src = _mm_or_si64 (src, MC(full_alpha));
+
+    return over(in (src, mask), mask, dest);
+}
+
 #ifndef _MSC_VER
 static inline __m64
 in_over (__m64 src,
@@ -1299,7 +1307,7 @@ fbCompositeSrc_x888x8x8888mmx (CARD8	op,
 
 	while (w && (unsigned long)dst & 7)
 	{
-	    __m64 s = load8888 (*src);
+	    __m64 s = load8888 (*src | 0xff000000);
 	    __m64 d = load8888 (*dst);
 
 	    *dst = store8888 (in_over (s, srca, vmask, d));
@@ -1309,75 +1317,26 @@ fbCompositeSrc_x888x8x8888mmx (CARD8	op,
 	    src++;
 	}
 
-	while (w >= 16)
+	while (w >= 2)
 	{
-	    __m64 vd0 = *(__m64 *)(dst + 0);
-	    __m64 vd1 = *(__m64 *)(dst + 2);
-	    __m64 vd2 = *(__m64 *)(dst + 4);
-	    __m64 vd3 = *(__m64 *)(dst + 6);
-	    __m64 vd4 = *(__m64 *)(dst + 8);
-	    __m64 vd5 = *(__m64 *)(dst + 10);
-	    __m64 vd6 = *(__m64 *)(dst + 12);
-	    __m64 vd7 = *(__m64 *)(dst + 14);
-
-	    __m64 vs0 = *(__m64 *)(src + 0);
-	    __m64 vs1 = *(__m64 *)(src + 2);
-	    __m64 vs2 = *(__m64 *)(src + 4);
-	    __m64 vs3 = *(__m64 *)(src + 6);
-	    __m64 vs4 = *(__m64 *)(src + 8);
-	    __m64 vs5 = *(__m64 *)(src + 10);
-	    __m64 vs6 = *(__m64 *)(src + 12);
-	    __m64 vs7 = *(__m64 *)(src + 14);
+	    
+	    __m64 vd0 = *(__m64 *)(dst);
+	    __m64 vs0 = *(__m64 *)(src);
 
 	    vd0 = pack8888 (
-		in_over (expand8888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
-		in_over (expand8888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
+		in_over_full_src_alpha (expand8888 (vs0, 0), vmask, expand8888 (vd0, 0)),
+		in_over_full_src_alpha (expand8888 (vs0, 1), vmask, expand8888 (vd0, 1)));
+
+	    *(__m64 *)(dst) = vd0;
 
-	    vd1 = pack8888 (
-		in_over (expand8888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
-		in_over (expand8888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
-
-	    vd2 = pack8888 (
-		in_over (expand8888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
-		in_over (expand8888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
-
-	    vd3 = pack8888 (
-		in_over (expand8888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
-		in_over (expand8888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
-
-	    vd4 = pack8888 (
-		in_over (expand8888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
-		in_over (expand8888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
-
-	    vd5 = pack8888 (
-		in_over (expand8888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
-		in_over (expand8888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
-
-	    vd6 = pack8888 (
-		in_over (expand8888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
-		in_over (expand8888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
-
-	    vd7 = pack8888 (
-		in_over (expand8888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
-		in_over (expand8888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
-
-	    *(__m64 *)(dst + 0) = vd0;
-	    *(__m64 *)(dst + 2) = vd1;
-	    *(__m64 *)(dst + 4) = vd2;
-	    *(__m64 *)(dst + 6) = vd3;
-	    *(__m64 *)(dst + 8) = vd4;
-	    *(__m64 *)(dst + 10) = vd5;
-	    *(__m64 *)(dst + 12) = vd6;
-	    *(__m64 *)(dst + 14) = vd7;
-
-	    w -= 16;
-	    dst += 16;
-	    src += 16;
+	    w -= 2;
+	    dst += 2;
+	    src += 2;
 	}
 
 	while (w)
 	{
-	    __m64 s = load8888 (*src);
+	    __m64 s = load8888 (*src | 0xff000000);
 	    __m64 d = load8888 (*dst);
 
 	    *dst = store8888 (in_over (s, srca, vmask, d));
diff-tree 546465ee6aa6584780aec6357f32d205c807ae71 (from 0fcd17c9181901c419cc32bc24c07fe5a6934d81)
Author: Soren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed May 16 17:42:04 2007 -0400

    Make fbFetch_b8g8r8() actually write the read value to the buffer

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index dd2a2f0..465f7d3 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -180,6 +180,7 @@ fbFetch_b8g8r8 (const FbBits *bits, int 
         b |= (READ(pixel++) << 8);
         b |= (READ(pixel++));
 #endif
+	WRITE(buffer++, b);
     }
 }
 
diff-tree 0fcd17c9181901c419cc32bc24c07fe5a6934d81 (from f4c1d5fc28a5a7fe2592505350f9e2331f6049b7)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue May 15 17:59:13 2007 -0400

    Use pixman short formats, revert the gradient_stop change

diff --git a/render/picture.h b/render/picture.h
index fc50387..1719587 100644
--- a/render/picture.h
+++ b/render/picture.h
@@ -36,12 +36,7 @@ typedef struct _Picture		*PicturePtr;
  * sample implementation allows only packed RGB and GBR
  * representations for data to simplify software rendering,
  */
-#define PICT_FORMAT(bpp,type,a,r,g,b)	(((bpp) << 24) |  \
-					 ((type) << 16) | \
-					 ((a) << 12) | \
-					 ((r) << 8) | \
-					 ((g) << 4) | \
-					 ((b)))
+#define PICT_FORMAT(bpp,type,a,r,g,b)	PIXMAN_FORMAT(bpp, type, a, r, g, b)
 
 /*
  * gray/color formats use a visual index instead of argb
@@ -50,77 +45,77 @@ typedef struct _Picture		*PicturePtr;
 					 ((type) << 16) | \
 					 ((vi)))
 
-#define PICT_FORMAT_BPP(f)	(((f) >> 24)       )
-#define PICT_FORMAT_TYPE(f)	(((f) >> 16) & 0xff)
-#define PICT_FORMAT_A(f)	(((f) >> 12) & 0x0f)
-#define PICT_FORMAT_R(f)	(((f) >>  8) & 0x0f)
-#define PICT_FORMAT_G(f)	(((f) >>  4) & 0x0f)
-#define PICT_FORMAT_B(f)	(((f)      ) & 0x0f)
-#define PICT_FORMAT_RGB(f)	(((f)      ) & 0xfff)
-#define PICT_FORMAT_VIS(f)	(((f)      ) & 0xffff)
-
-#define PICT_TYPE_OTHER	0
-#define PICT_TYPE_A	1
-#define PICT_TYPE_ARGB	2
-#define PICT_TYPE_ABGR	3
-#define PICT_TYPE_COLOR	4
-#define PICT_TYPE_GRAY	5
+#define PICT_FORMAT_BPP(f)	PIXMAN_FORMAT_BPP(f)
+#define PICT_FORMAT_TYPE(f)	PIXMAN_FORMAT_TYPE(f)
+#define PICT_FORMAT_A(f)	PIXMAN_FORMAT_A(f)
+#define PICT_FORMAT_R(f)	PIXMAN_FORMAT_R(f)
+#define PICT_FORMAT_G(f)	PIXMAN_FORMAT_G(f)
+#define PICT_FORMAT_B(f)	PIXMAN_FORMAT_B(f)
+#define PICT_FORMAT_RGB(f)	PIXMAN_FORMAT_RGB(f)
+#define PICT_FORMAT_VIS(f)	PIXMAN_FORMAT_VIS(f)
+
+#define PICT_TYPE_OTHER		PIXMAN_TYPE_OTHER
+#define PICT_TYPE_A		PIXMAN_TYPE_A
+#define PICT_TYPE_ARGB		PIXMAN_TYPE_ARGB
+#define PICT_TYPE_ABGR		PIXMAN_TYPE_ABGR
+#define PICT_TYPE_COLOR		PIXMAN_TYPE_COLOR
+#define PICT_TYPE_GRAY		PIXMAN_TYPE_GRAY
 
-#define PICT_FORMAT_COLOR(f)	(PICT_FORMAT_TYPE(f) & 2)
+#define PICT_FORMAT_COLOR(f)	PIXMAN_FORMAT_COLOR(f)
 
 /* 32bpp formats */
 typedef enum _PictFormatShort {
-   PICT_a8r8g8b8 =	PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8),
-   PICT_x8r8g8b8 =	PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8),
-   PICT_a8b8g8r8 =	PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8),
-   PICT_x8b8g8r8 =	PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8),
+    PICT_a8r8g8b8 =	PIXMAN_a8r8g8b8,
+    PICT_x8r8g8b8 =	PIXMAN_x8r8g8b8,
+    PICT_a8b8g8r8 =	PIXMAN_a8b8g8r8,
+    PICT_x8b8g8r8 =	PIXMAN_x8b8g8r8,
 
 /* 24bpp formats */
-   PICT_r8g8b8 =	PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8),
-   PICT_b8g8r8 =	PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8),
+    PICT_r8g8b8 =	PIXMAN_r8g8b8,
+    PICT_b8g8r8 =	PIXMAN_b8g8r8,
 
 /* 16bpp formats */
-   PICT_r5g6b5 =	PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5),
-   PICT_b5g6r5 =	PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5),
+    PICT_r5g6b5 =	PIXMAN_r5g6b5,
+    PICT_b5g6r5 =	PIXMAN_b5g6r5,
 
-   PICT_a1r5g5b5 =	PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5),
-   PICT_x1r5g5b5 =	PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5),
-   PICT_a1b5g5r5 =	PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5),
-   PICT_x1b5g5r5 =	PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5),
-   PICT_a4r4g4b4 =	PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4),
-   PICT_x4r4g4b4 =	PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4),
-   PICT_a4b4g4r4 =	PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4),
-   PICT_x4b4g4r4 =	PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4),
+    PICT_a1r5g5b5 =	PIXMAN_a1r5g5b5,
+    PICT_x1r5g5b5 =	PIXMAN_x1r5g5b5,
+    PICT_a1b5g5r5 =	PIXMAN_a1b5g5r5,
+    PICT_x1b5g5r5 =	PIXMAN_x1b5g5r5,
+    PICT_a4r4g4b4 =	PIXMAN_a4r4g4b4,
+    PICT_x4r4g4b4 =	PIXMAN_x4r4g4b4,
+    PICT_a4b4g4r4 =	PIXMAN_a4b4g4r4,
+    PICT_x4b4g4r4 =	PIXMAN_x4b4g4r4,
 
 /* 8bpp formats */
-   PICT_a8 =		PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0),
-   PICT_r3g3b2 =	PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2),
-   PICT_b2g3r3 =	PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2),
-   PICT_a2r2g2b2 =	PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2),
-   PICT_a2b2g2r2 =	PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2),
+    PICT_a8 =		PIXMAN_a8,
+    PICT_r3g3b2 =	PIXMAN_r3g3b2,
+    PICT_b2g3r3 =	PIXMAN_b2g3r3,
+    PICT_a2r2g2b2 =	PIXMAN_a2r2g2b2,
+    PICT_a2b2g2r2 =	PIXMAN_a2b2g2r2,
 
-   PICT_c8 =		PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0),
-   PICT_g8 =		PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0),
+    PICT_c8 =		PIXMAN_c8,
+    PICT_g8 =		PIXMAN_g8,
 
-   PICT_x4a4 =		PICT_FORMAT(8,PICT_TYPE_A,4,0,0,0),
+    PICT_x4a4 =		PIXMAN_x4a4,
 				    
-   PICT_x4c4 =		PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0),
-   PICT_x4g4 =		PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0),
+    PICT_x4c4 =		PIXMAN_x4c4,
+    PICT_x4g4 =		PIXMAN_x4g4,
 
 /* 4bpp formats */
-   PICT_a4 =		PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0),
-   PICT_r1g2b1 =	PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1),
-   PICT_b1g2r1 =	PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1),
-   PICT_a1r1g1b1 =	PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1),
-   PICT_a1b1g1r1 =	PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1),
+    PICT_a4 =		PIXMAN_a4,
+    PICT_r1g2b1 =	PIXMAN_r1g2b1,
+    PICT_b1g2r1 =	PIXMAN_b1g2r1,
+    PICT_a1r1g1b1 =	PIXMAN_a1r1g1b1,
+    PICT_a1b1g1r1 =	PIXMAN_a1b1g1r1,
 				    
-   PICT_c4 =		PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0),
-   PICT_g4 =		PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0),
+    PICT_c4 =		PIXMAN_c4,
+    PICT_g4 =		PIXMAN_g4,
 
 /* 1bpp formats */
-   PICT_a1 =		PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0),
+    PICT_a1 =		PIXMAN_a1,
 
-   PICT_g1 =		PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
+    PICT_g1 =		PIXMAN_g1,
 } PictFormatShort;
 
 /*
diff --git a/render/picturestr.h b/render/picturestr.h
index 9259cad..9c41fc1 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -73,7 +73,10 @@ typedef struct _PictSolidFill {
     CARD32 color;
 } PictSolidFill, *PictSolidFillPtr;
 
-typedef struct pixman_gradient_stop PictGradientStop, *PictGradientStopPtr;
+typedef struct _PictGradientStop {
+    xFixed x;
+    xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
 
 typedef struct _PictGradient {
     unsigned int type;
diff-tree f4c1d5fc28a5a7fe2592505350f9e2331f6049b7 (from f2e30e7d0a1d075e7e83c5b5ceca9e4752951138)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue May 15 17:12:22 2007 -0400

    Use pixman types for transforms and vectors

diff --git a/render/picturestr.h b/render/picturestr.h
index 6268768..9259cad 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -54,13 +54,8 @@ typedef struct _PictFormat {
     IndexFormatRec  index;
 } PictFormatRec;
 
-typedef struct _PictVector {
-    xFixed	    vector[3];
-} PictVector, *PictVectorPtr;
-
-typedef struct _PictTransform {
-    xFixed	    matrix[3][3];
-} PictTransform, *PictTransformPtr;
+typedef struct pixman_vector PictVector, *PictVectorPtr;
+typedef struct pixman_transform PictTransform, *PictTransformPtr;
 
 #define PICT_GRADIENT_STOPTABLE_SIZE 1024
 #define SourcePictTypeSolidFill 0
@@ -78,10 +73,7 @@ typedef struct _PictSolidFill {
     CARD32 color;
 } PictSolidFill, *PictSolidFillPtr;
 
-typedef struct _PictGradientStop {
-    xFixed x;
-    xRenderColor color;
-} PictGradientStop, *PictGradientStopPtr;
+typedef struct pixman_gradient_stop PictGradientStop, *PictGradientStopPtr;
 
 typedef struct _PictGradient {
     unsigned int type;
diff-tree f2e30e7d0a1d075e7e83c5b5ceca9e4752951138 (from 3da842bf930d7875599ca0c06cb4a09cfa987ac5)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue May 15 16:51:21 2007 -0400

    Use the pixman fixed point types and macros

diff --git a/render/picture.c b/render/picture.c
index 2022175..d0ae326 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1879,9 +1879,6 @@ AddTraps (PicturePtr	pPicture,
     (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
 }
 
-#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
-#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
-
 _X_EXPORT Bool
 PictureTransformPoint3d (PictTransformPtr transform,
                          PictVectorPtr	vector)
diff --git a/render/picture.h b/render/picture.h
index 1b62234..fc50387 100644
--- a/render/picture.h
+++ b/render/picture.h
@@ -25,6 +25,8 @@
 #ifndef _PICTURE_H_
 #define _PICTURE_H_
 
+#include <pixman/pixman.h>
+
 typedef struct _DirectFormat	*DirectFormatPtr;
 typedef struct _PictFormat	*PictFormatPtr;
 typedef struct _Picture		*PicturePtr;
@@ -171,54 +173,35 @@ extern int	RenderClientPrivateIndex;
 
 /* Fixed point updates from Carl Worth, USC, Information Sciences Institute */
 
-#if defined(WIN32) && !defined(__GNUC__)
-typedef __int64		xFixed_32_32;
-#else
-#  if defined (_LP64) || \
-      defined(__alpha__) || defined(__alpha) || \
-      defined(ia64) || defined(__ia64__) || \
-      defined(__sparc64__) || \
-      defined(__s390x__) || \
-      defined(amd64) || defined (__amd64__) || \
-      (defined(sgi) && (_MIPS_SZLONG == 64))
-typedef long		xFixed_32_32;
-# else
-#  if defined(__GNUC__) && \
-    ((__GNUC__ > 2) || \
-     ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 7)))
-__extension__
-#  endif
-typedef long long int	xFixed_32_32;
-# endif
-#endif
-
-typedef xFixed_32_32	xFixed_48_16;
-
-#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
-#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
-
-typedef CARD32		xFixed_1_31;
-typedef CARD32		xFixed_1_16;
-typedef INT32		xFixed_16_16;
+typedef pixman_fixed_32_32_t	xFixed_32_32;
+
+typedef pixman_fixed_48_16_t	xFixed_48_16;
+
+#define MAX_FIXED_48_16		pixman_max_fixed_48_16
+#define MIN_FIXED_48_16		pixman_min_fixed_48_16
+
+typedef pixman_fixed_1_31_t	xFixed_1_31;
+typedef pixman_fixed_1_16_t	xFixed_1_16;
+typedef pixman_fixed_16_16_t	xFixed_16_16;
 
 /*
  * An unadorned "xFixed" is the same as xFixed_16_16, 
  * (since it's quite common in the code) 
  */
-typedef	xFixed_16_16	xFixed;
+typedef	pixman_fixed_t	xFixed;
 #define XFIXED_BITS	16
 
-#define xFixedToInt(f)	(int) ((f) >> XFIXED_BITS)
-#define IntToxFixed(i)	((xFixed) (i) << XFIXED_BITS)
-#define xFixedE		((xFixed) 1)
-#define xFixed1		(IntToxFixed(1))
-#define xFixed1MinusE	(xFixed1 - xFixedE)
-#define xFixedFrac(f)	((f) & xFixed1MinusE)
-#define xFixedFloor(f)	((f) & ~xFixed1MinusE)
-#define xFixedCeil(f)	xFixedFloor((f) + xFixed1MinusE)
+#define xFixedToInt(f)	pixman_fixed_to_int(f)
+#define IntToxFixed(i)	pixman_int_to_fixed(i)
+#define xFixedE		pixman_fixed_e
+#define xFixed1		pixman_fixed_1
+#define xFixed1MinusE	pixman_fixed_1_minus_e
+#define xFixedFrac(f)	pixman_fixed_frac(f)
+#define xFixedFloor(f)	pixman_fixed_floor(f)
+#define xFixedCeil(f)	pixman_fixed_ceil(f)
 
-#define xFixedFraction(f)	((f) & xFixed1MinusE)
-#define xFixedMod2(f)		((f) & (xFixed1 | xFixed1MinusE))
+#define xFixedFraction(f)	pixman_fixed_fraction(f)
+#define xFixedMod2(f)		pixman_fixed_mod2(f)
 
 /* whether 't' is a well defined not obviously empty trapezoid */
 #define xTrapezoidValid(t)  ((t)->left.p1.y != (t)->left.p2.y && \
diff-tree 3da842bf930d7875599ca0c06cb4a09cfa987ac5 (from 1568b6b6a0d7337f29c7b87cc46ae64b3b0f8fdf)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue May 15 14:57:14 2007 -0400

    Revert various fast path functions to their pre-pixman-merge state
    since they fail rendercheck. Remove their associated macros.
    
    See bug 10903.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 7d94d00..1146e99 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -78,64 +78,6 @@ fbIn (CARD32 x, CARD8 y)
     return m|n|o|p;
 }
 
-#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))
-
-/*
- * This macro does src IN mask OVER dst when src and dst are 0888.
- * If src has alpha, this will not work
- */
-#define inOver0888(alpha, source, destval, dest) { \
- 	CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \
- 	CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
-	WRITE(dest, ((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00))); \
-    }
-
-/*
- * This macro does src IN mask OVER dst when src and dst are 0565 and
- * mask is a 5-bit alpha value.  Again, if src has alpha, this will not
- * work.
- */
-#define inOver0565(alpha, source, destval, dest) { \
- 	CARD16 dstrb = destval & 0xf81f; CARD16 dstg  = destval & 0x7e0; \
- 	CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
-	WRITE(dest, ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5)  + dstg) & 0x7e0))); \
-    }
-
-
-#define inOver2x0565(alpha, source, destval, dest) { \
- 	CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg  = (destval & 0xf81f07e0)>>5; \
- 	CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \
-	WRITE(dest, ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5)  + dstg)<<5) & 0xf81f07e0))); \
-    }
-
-
-#if IMAGE_BYTE_ORDER == LSBFirst
-#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
-					temp=count&3; \
-					where-=temp; \
-					workingWhere=(CARD32 *)where; \
-                                        workingVal=READ(workingWhere++); \
-					count=4-temp; \
-					workingVal>>=(8*temp)
-        #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)&0xff; (y)>>=8; (x)--;}
-	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
-	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
-        #define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; WRITE (wodst++, workingoDest); } 
-#else
-	#warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!"
-	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
-					temp=count&3; \
-					where-=temp; \
-					workingWhere=(CARD32 *)where; \
-                                        workingVal=READ(workingWhere++); \
-					count=4-temp; \
-					workingVal<<=(8*temp)
-        #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)>>24; (y)<<=8; (x)--;}
-	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
-	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
-        #define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; WRITE(wodst++, workingoDest); } 
-#endif
-
 /*
  * Naming convention:
  *
@@ -279,7 +221,6 @@ fbCompositeSolidMask_nx8888x8888C (CARD8
     fbFinishAccess (pDst->pDrawable);
 }
 
-#define srcAlphaCombine24(a,b) genericCombine24(a,b,srca,srcia)
 void
 fbCompositeSolidMask_nx8x0888 (CARD8      op,
 			       PicturePtr pSrc,
@@ -294,86 +235,53 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
 			       CARD16     width,
 			       CARD16     height)
 {
-    CARD32	src, srca, srcia;
-    CARD8	*dstLine, *dst, *edst;
+    CARD32	src, srca;
+    CARD8	*dstLine, *dst;
+    CARD32	d;
     CARD8	*maskLine, *mask, m;
     FbStride	dstStride, maskStride;
     CARD16	w;
-    CARD32 rs,gs,bs,rd,gd,bd;
 
     fbComposeGetSolid(pSrc, src, pDst->format);
 
     srca = src >> 24;
-    srcia = 255-srca;
     if (src == 0)
 	return;
 
-    rs=src&0xff;
-    gs=(src>>8)&0xff;
-    bs=(src>>16)&0xff;
-      
     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
     fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
 
     while (height--)
     {
-	/* fixme: cleanup unused */
-	unsigned long wt, wd;
-	CARD32 workingiDest;
-	CARD32 *widst;
- 	
-	edst = dst = dstLine;
+	dst = dstLine;
 	dstLine += dstStride;
 	mask = maskLine;
 	maskLine += maskStride;
 	w = width;
- 	
-#ifndef NO_MASKED_PACKED_READ
-	setupPackedReader(wd,wt,edst,widst,workingiDest);
-#endif
- 	
+
 	while (w--)
 	{
-#ifndef NO_MASKED_PACKED_READ
-	    readPackedDest(rd);
-	    readPackedDest(gd);
-	    readPackedDest(bd);
-#else
-	    rd = READ(edst++);
-	    gd = READ(edst++);
-	    bd = READ(edst++);
-#endif
 	    m = READ(mask++);
 	    if (m == 0xff)
 	    {
 		if (srca == 0xff)
-		{
-		    WRITE(dst++, rs);
-		    WRITE(dst++, gs);
-		    WRITE(dst++, bs);
-		}
+		    d = src;
 		else
 		{
-		    WRITE(dst++, (srcAlphaCombine24(rs, rd)>>8));
-		    WRITE(dst++, (srcAlphaCombine24(gs, gd)>>8));
-		    WRITE(dst++, (srcAlphaCombine24(bs, bd)>>8));
+		    d = Fetch24(dst);
+		    d = fbOver24 (src, d);
 		}
+		Store24(dst,d);
 	    }
 	    else if (m)
 	    {
-		int na=(srca*(int)m)>>8;
-		int nia=255-na;
-		WRITE(dst++, (genericCombine24(rs, rd, na, nia)>>8));
-		WRITE(dst++, (genericCombine24(gs, gd, na, nia)>>8));
-		WRITE(dst++, (genericCombine24(bs, bd, na, nia)>>8));
-	    }
-	    else
-	    {
-		dst+=3;
+		d = fbOver24 (fbIn(src,m), Fetch24(dst));
+		Store24(dst,d);
 	    }
+	    dst += 3;
 	}
     }
-    
+
     fbFinishAccess (pMask->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
@@ -392,105 +300,21 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
 				  CARD16     width,
 				  CARD16     height)
 {
-    CARD32	src, srca8, srca5;
+    CARD32	src, srca;
     CARD16	*dstLine, *dst;
-    CARD16	d;
-    CARD32	t;
+    CARD32	d;
     CARD8	*maskLine, *mask, m;
     FbStride	dstStride, maskStride;
-    CARD16	w,src16;
-    
-    fbComposeGetSolid(pSrc, src, pDst->format);
-    
-    if (src == 0)
-	return;
-      
-    srca8 = (src >> 24);
-    srca5 = (srca8 >> 3);
-    src16 = cvt8888to0565(src);
-     
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-    
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
- 
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0)
-		dst++;
-	    else if (srca5 == (0xff >> 3))
-	    {
-		if (m == 0xff)
-		    WRITE(dst++, src16);
-		else 
- 		{
-		    d = READ(dst);
-		    m >>= 3;
-		    inOver0565 (m, src16, d, dst++);
- 		}
-	    }
-	    else
-	    {
-		d = READ(dst);
-		if (m == 0xff) 
-		{
-		    t = fbOver24 (src, cvt0565to0888 (d));
-		}
-		else
-		{
-		    t = fbIn (src, m);
-		    t = fbOver (t, cvt0565to0888 (d));
-		}
-		WRITE(dst++, cvt8888to0565 (t));
-	    }
-	}
-    }
-    
-    fbFinishAccess (pMask->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-static void
-fbCompositeSolidMask_nx8888x0565 (CARD8      op,
-				  PicturePtr pSrc,
-				  PicturePtr pMask,
-				  PicturePtr pDst,
-				  INT16      xSrc,
-				  INT16      ySrc,
-				  INT16      xMask,
-				  INT16      yMask,
-				  INT16      xDst,
-				  INT16      yDst,
-				  CARD16     width,
-				  CARD16     height)
-{
-    CARD32	src, srca8, srca5;
-    CARD16	*dstLine, *dst;
-    CARD16	d;
-    CARD32	*maskLine, *mask;
-    CARD32	t;
-    CARD8	m;
-    FbStride	dstStride, maskStride;
-    CARD16	w, src16;
+    CARD16	w;
 
     fbComposeGetSolid(pSrc, src, pDst->format);
 
+    srca = src >> 24;
     if (src == 0)
 	return;
 
-    srca8 = src >> 24;
-    srca5 = srca8 >> 3;
-    src16 = cvt8888to0565(src);
-
     fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
 
     while (height--)
     {
@@ -502,38 +326,30 @@ fbCompositeSolidMask_nx8888x0565 (CARD8 
 
 	while (w--)
 	{
-	    m = READ(mask++) >> 24;
-	    if (m == 0)
-		dst++;
-	    else if (srca5 == (0xff >> 3))
+	    m = READ(mask++);
+	    if (m == 0xff)
 	    {
-		if (m == 0xff)
-		    WRITE(dst++, src16);
+		if (srca == 0xff)
+		    d = src;
 		else
 		{
 		    d = READ(dst);
-		    m >>= 3;
-		    inOver0565 (m, src16, d, dst++);
+		    d = fbOver24 (src, cvt0565to0888(d));
 		}
+		WRITE(dst, cvt8888to0565(d));
 	    }
-	    else
+	    else if (m)
 	    {
-		if (m == 0xff) 
-		{
-		    d = READ(dst);
-		    t = fbOver24 (src, cvt0565to0888 (d));
-		    WRITE(dst++, cvt8888to0565 (t));
-		}
-		else
-		{
-		    d = READ(dst);
-		    t = fbIn (src, m);
-		    t = fbOver (t, cvt0565to0888 (d));
-		    WRITE(dst++, cvt8888to0565 (t));
-		}
+		d = READ(dst);
+		d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
+		WRITE(dst, cvt8888to0565(d));
 	    }
+	    dst++;
 	}
     }
+
+    fbFinishAccess (pMask->pDrawable);
+    fbFinishAccess (pDst->pDrawable);
 }
 
 void
@@ -1060,295 +876,6 @@ fbCompositeSrcSrc_nxn  (CARD8	   op,
 			CARD16     width,
 			CARD16     height);
 
-static void
-fbCompositeTrans_0565xnx0565(CARD8      op,
-			     PicturePtr pSrc,
-			     PicturePtr pMask,
-			     PicturePtr pDst,
-			     INT16      xSrc,
-			     INT16      ySrc,
-			     INT16      xMask,
-			     INT16      yMask,
-			     INT16      xDst,
-			     INT16      yDst,
-			     CARD16     width,
-			     CARD16     height)
-{
-    CARD16	*dstLine, *dst;
-    CARD16	*srcLine, *src;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-    FbBits	mask;
-    CARD8	maskAlpha;
-    CARD16	s_16, d_16;
-    CARD32	s_32, d_32;
-    
-    fbComposeGetSolid (pMask, mask, pDst->format);
-    maskAlpha = mask >> 27;
-    
-    if (!maskAlpha)
-	return;
-    if (maskAlpha == 0xff)
-    {
-	fbCompositeSrcSrc_nxn (PictOpSrc, pSrc, pMask, pDst,
-			       xSrc, ySrc, xMask, yMask, xDst, yDst, 
-			       width, height);
-	return;
-    }
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	CARD32 *isrc, *idst;
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-	
-	if(((long)src&1)==1)
-	{
-	    s_16 = READ(src++);
-	    d_16 = READ(dst);
-	    inOver0565(maskAlpha, s_16, d_16, dst++);
-	    w--;
-	}
-	isrc=(CARD32 *)src;
-	if(((long)dst&1)==0)
-	{
-	    idst=(CARD32 *)dst;
-	    while (w>1)
-	    {
-		s_32 = READ(isrc++);
-		d_32 = READ(idst);
-		inOver2x0565(maskAlpha, s_32, d_32, idst++);
-		w-=2;
-	    }
-	    dst=(CARD16 *)idst;
-	}
-	else
-	{
-	    while (w > 1)
-	    {
-		s_32 = READ(isrc++);
-#if IMAGE_BYTE_ORDER == LSBFirst
-		s_16=s_32&0xffff;
-#else
-		s_16=s_32>>16;
-#endif
-		d_16 = READ(dst);
-		inOver0565 (maskAlpha, s_16, d_16, dst++);
-#if IMAGE_BYTE_ORDER == LSBFirst
-		s_16=s_32>>16;
-#else
-		s_16=s_32&0xffff;
-#endif
-		d_16 = READ(dst);
-		inOver0565(maskAlpha, s_16, d_16, dst++);
-		w-=2;
-	    }
-	}
-	src=(CARD16 *)isrc;
-	if(w!=0)
-	{
-	    s_16 = READ(src);
-	    d_16 = READ(dst);
-	    inOver0565(maskAlpha, s_16, d_16, dst);
-	}
-    }
-    
-    fbFinishAccess (pSrc->pDrawable);
-    fbFinishAccess (pDst->pDrawable);
-}
-
-/* macros for "i can't believe it's not fast" packed pixel handling */
-#define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
-
-static void
-fbCompositeTrans_0888xnx0888(CARD8      op,
- 			     PicturePtr pSrc,
- 			     PicturePtr pMask,
- 			     PicturePtr pDst,
- 			     INT16      xSrc,
- 			     INT16      ySrc,
- 			     INT16      xMask,
- 			     INT16      yMask,
- 			     INT16      xDst,
- 			     INT16      yDst,
- 			     CARD16     width,
- 			     CARD16     height)
-{
-    CARD8	*dstLine, *dst,*idst;
-    CARD8	*srcLine, *src;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-    FbBits	mask;
-    CARD16	maskAlpha,maskiAlpha;
-    
-    fbComposeGetSolid (pMask, mask, pDst->format);
-    maskAlpha = mask >> 24;
-    maskiAlpha= 255-maskAlpha;
-    
-    if (!maskAlpha)
- 	return;
-    /*
-      if (maskAlpha == 0xff)
-      {
-      fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
-      xSrc, ySrc, xMask, yMask, xDst, yDst, 
-      width, height);
-      return;
-      }
-    */
-    
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
-    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
-    
-    {
-	unsigned long ws,wt;
-	CARD32 workingSource;
-	CARD32 *wsrc, *wdst, *widst;
-	CARD32 rs, rd, nd;
-	CARD8 *isrc;
-	
-	
-	/* are xSrc and xDst at the same alignment?  if not, we need to be complicated :) */
-	/* if(0==0) */
-	if ((((xSrc * 3) & 3) != ((xDst * 3) & 3)) ||
-	    ((srcStride & 3) != (dstStride & 3)))
-	{
-	    while (height--)
-	    {
-		dst = dstLine;
-		dstLine += dstStride;
-		isrc = src = srcLine;
-		srcLine += srcStride;
-		w = width*3;
-		
-		setupPackedReader(ws,wt,isrc,wsrc,workingSource);
-		
-		/* get to word aligned */
-		switch(~(long)dst&3)
-		{
-		case 1:
-		    readPackedSource(rs);
-		    /* *dst++=alphamaskCombine24(rs, *dst)>>8; */
-		    rd = READ(dst);  /* make gcc happy.  hope it doens't cost us too much performance*/
-		    WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
-		    w--; if(w==0) break;
-		case 2:
-		    readPackedSource(rs);
-		    rd = READ(dst);
-		    WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
-		    w--; if(w==0) break;
-		case 3:
-		    readPackedSource(rs);
-		    rd = READ(dst);
-		    WRITE(dst++,alphamaskCombine24(rs, rd) >> 8);
-		    w--; if(w==0) break;
-		}
-		wdst=(CARD32 *)dst;
-		while (w>3)
-		{
-		    rs=READ(wsrc++);
-		    /* FIXME: write a special readPackedWord macro, which knows how to 
-		     * halfword combine
-		     */
-#if IMAGE_BYTE_ORDER == LSBFirst
-		    rd=READ(wdst);
-		    readPackedSource(nd);
-		    readPackedSource(rs);
-		    nd|=rs<<8;
-		    readPackedSource(rs);
-		    nd|=rs<<16;
-		    readPackedSource(rs);
-		    nd|=rs<<24;
-#else
-		    readPackedSource(nd);
-		    nd<<=24;
-		    readPackedSource(rs);
-		    nd|=rs<<16;
-		    readPackedSource(rs);
-		    nd|=rs<<8;
-		    readPackedSource(rs);
-		    nd|=rs;
-#endif
-		    inOver0888(maskAlpha, nd, rd, wdst++);
-		    w-=4;
-		}
-		src=(CARD8 *)wdst;
-		switch(w)
-		{
-		case 3:
-		    readPackedSource(rs);
-		    rd=READ(dst);
-		    WRITE(dst++,alphamaskCombine24(rs, rd)>>8);
-		case 2:
-		    readPackedSource(rs);
-		    rd = READ(dst);  
-		    WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
-		case 1:
-		    readPackedSource(rs);
-		    rd = READ(dst);  
-		    WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
-		}
-	    }
-	}
-	else
-	{
-	    while (height--)
-	    {
-		idst=dst = dstLine;
-		dstLine += dstStride;
-		src = srcLine;
-		srcLine += srcStride;
-		w = width*3;
-		/* get to word aligned */
-		switch(~(long)src&3)
-		{
-		case 1:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		    w--; if(w==0) break;
-		case 2:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		    w--; if(w==0) break;
-		case 3:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		    w--; if(w==0) break;
-		}
-		wsrc=(CARD32 *)src;
-		widst=(CARD32 *)dst;
-		while(w>3)
-		{
-		    rs = READ(wsrc++);
-		    rd = READ(widst);
-		    inOver0888 (maskAlpha, rs, rd, widst++);
-		    w-=4;
-		}
-		src=(CARD8 *)wsrc;
-		dst=(CARD8 *)widst;
-		switch(w)
-		{
-		case 3:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		case 2:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		case 1:
-		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
-		    WRITE(dst++, rd);
-		}
-	    }
-	}
-    }
-}
-
 /*
  * Simple bitblt
  */
@@ -1687,6 +1214,7 @@ fbComposite (CARD8      op,
 				break;
 			    }
 			}
+#if 0
 			else
 			{
 			    switch (pDst->format) {
@@ -1697,6 +1225,7 @@ fbComposite (CARD8      op,
 				break;
                             }
 			}
+#endif
 			break;
 		    case PICT_a8b8g8r8:
 			if (pMask->componentAlpha) {
@@ -1722,6 +1251,7 @@ fbComposite (CARD8      op,
 				break;
 			    }
 			}
+#if 0
 			else
 			{
 			    switch (pDst->format) {
@@ -1732,6 +1262,7 @@ fbComposite (CARD8      op,
 				break;
                             }
 			}
+#endif
 			break;
 		    case PICT_a1:
 			switch (pDst->format) {
@@ -1833,16 +1364,6 @@ fbComposite (CARD8      op,
 			 pMask->pDrawable->height == 1)
 		{
 		    switch (pSrc->format) {
-		    case PICT_r5g6b5:
-		    case PICT_b5g6r5:
-			if (pDst->format == pSrc->format)
-			    func = fbCompositeTrans_0565xnx0565;
-			break;
-		    case PICT_r8g8b8:
-		    case PICT_b8g8r8:
-			if (pDst->format == pSrc->format)
-			    func = fbCompositeTrans_0888xnx0888;
-			break;
 #ifdef USE_MMX
 		    case PICT_x8r8g8b8:
 			if ((pDst->format == PICT_a8r8g8b8 ||
diff-tree 1568b6b6a0d7337f29c7b87cc46ae64b3b0f8fdf (from dde0ceac4ea7639d0096bfd26f37c5851778854c)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Sat May 12 20:33:23 2007 -0400

    Port large amounts of the region code to pixman

diff --git a/mi/miregion.c b/mi/miregion.c
index 4bfe9c7..28d38a2 100644
--- a/mi/miregion.c
+++ b/mi/miregion.c
@@ -225,6 +225,37 @@ InitRegions (void)
     pixman_region_set_static_pointers (&miEmptyBox, &miEmptyData, &miBrokenData);
 }
 
+/*****************************************************************
+ *   RegionCreate(rect, size)
+ *     This routine does a simple malloc to make a structure of
+ *     REGION of "size" number of rectangles.
+ *****************************************************************/
+
+_X_EXPORT RegionPtr
+miRegionCreate(rect, size)
+    BoxPtr rect;
+    int size;
+{
+    RegionPtr pReg;
+   
+    pReg = (RegionPtr)xalloc(sizeof(RegionRec));
+    if (!pReg)
+	return &miBrokenRegion;
+
+    miRegionInit (pReg, rect, size);
+    
+    return(pReg);
+}
+
+_X_EXPORT void
+miRegionDestroy(pReg)
+    RegionPtr pReg;
+{
+    pixman_region_fini (pReg);
+    if (pReg != &miBrokenRegion)
+	xfree(pReg);
+}
+
 _X_EXPORT void
 miPrintRegion(rgn)
     RegionPtr rgn;
@@ -250,26 +281,7 @@ miRegionEqual(reg1, reg2)
     RegionPtr reg1;
     RegionPtr reg2;
 {
-    int i, num;
-    BoxPtr rects1, rects2;
-
-    if (reg1->extents.x1 != reg2->extents.x1) return FALSE;
-    if (reg1->extents.x2 != reg2->extents.x2) return FALSE;
-    if (reg1->extents.y1 != reg2->extents.y1) return FALSE;
-    if (reg1->extents.y2 != reg2->extents.y2) return FALSE;
-
-    num = REGION_NUM_RECTS(reg1);
-    if (num != REGION_NUM_RECTS(reg2)) return FALSE;
-    
-    rects1 = REGION_RECTS(reg1);
-    rects2 = REGION_RECTS(reg2);
-    for (i = 0; i != num; i++) {
-	if (rects1[i].x1 != rects2[i].x1) return FALSE;
-	if (rects1[i].x2 != rects2[i].x2) return FALSE;
-	if (rects1[i].y1 != rects2[i].y1) return FALSE;
-	if (rects1[i].y2 != rects2[i].y2) return FALSE;
-    }
-    return TRUE;
+    return pixman_region_equal (reg1, reg2);
 }
 
 #ifdef DEBUG
@@ -278,7 +290,7 @@ miValidRegion(reg)
     RegionPtr reg;
 {
     int i, numRects;
-
+    
     if ((reg->extents.x1 > reg->extents.x2) ||
 	(reg->extents.y1 > reg->extents.y2))
 	return FALSE;
@@ -293,7 +305,7 @@ miValidRegion(reg)
     {
 	BoxPtr pboxP, pboxN;
 	BoxRec box;
-
+	
 	pboxP = REGION_RECTS(reg);
 	box = *pboxP;
 	box.y2 = pboxP[numRects-1].y2;
@@ -304,7 +316,7 @@ miValidRegion(reg)
 		(pboxN->y1 >= pboxN->y2))
 		return FALSE;
 	    if (pboxN->x1 < box.x1)
-	        box.x1 = pboxN->x1;
+		box.x1 = pboxN->x1;
 	    if (pboxN->x2 > box.x2)
 		box.x2 = pboxN->x2;
 	    if ((pboxN->y1 < pboxP->y1) ||
@@ -318,45 +330,8 @@ miValidRegion(reg)
 		(box.y2 == reg->extents.y2));
     }
 }
-
 #endif /* DEBUG */
 
-
-/*****************************************************************
- *   RegionCreate(rect, size)
- *     This routine does a simple malloc to make a structure of
- *     REGION of "size" number of rectangles.
- *****************************************************************/
-
-_X_EXPORT RegionPtr
-miRegionCreate(rect, size)
-    BoxPtr rect;
-    int size;
-{
-    RegionPtr pReg;
-   
-    pReg = (RegionPtr)xalloc(sizeof(RegionRec));
-    if (!pReg)
-	return &miBrokenRegion;
-    if (rect)
-    {
-	pReg->extents = *rect;
-	pReg->data = (RegDataPtr)NULL;
-    }
-    else
-    {
-	pReg->extents = miEmptyBox;
-	if ((size > 1) && (pReg->data = xallocData(size)))
-	{
-	    pReg->data->size = size;
-	    pReg->data->numRects = 0;
-	}
-	else
-	    pReg->data = &miEmptyData;
-    }
-    return(pReg);
-}
-
 /*****************************************************************
  *   RegionInit(pReg, rect, size)
  *     Outer region rect is statically allocated.
@@ -369,39 +344,16 @@ miRegionInit(pReg, rect, size)
     int size;
 {
     if (rect)
-    {
-	pReg->extents = *rect;
-	pReg->data = (RegDataPtr)NULL;
-    }
+	pixman_region_init_with_extents (pReg, rect);
     else
-    {
-	pReg->extents = miEmptyBox;
-	if ((size > 1) && (pReg->data = xallocData(size)))
-	{
-	    pReg->data->size = size;
-	    pReg->data->numRects = 0;
-	}
-	else
-	    pReg->data = &miEmptyData;
-    }
-}
-
-_X_EXPORT void
-miRegionDestroy(pReg)
-    RegionPtr pReg;
-{
-    good(pReg);
-    xfreeData(pReg);
-    if (pReg != &miBrokenRegion)
-	xfree(pReg);
+	pixman_region_init (pReg);
 }
 
 _X_EXPORT void
 miRegionUninit(pReg)
     RegionPtr pReg;
 {
-    good(pReg);
-    xfreeData(pReg);
+    pixman_region_fini (pReg);
 }
 
 Bool
@@ -460,32 +412,9 @@ miRegionCopy(dst, src)
     RegionPtr dst;
     RegionPtr src;
 {
-    good(dst);
-    good(src);
-    if (dst == src)
-	return TRUE;
-    dst->extents = src->extents;
-    if (!src->data || !src->data->size)
-    {
-	xfreeData(dst);
-	dst->data = src->data;
-	return TRUE;
-    }
-    if (!dst->data || (dst->data->size < src->data->numRects))
-    {
-	xfreeData(dst);
-	dst->data = xallocData(src->data->numRects);
-	if (!dst->data)
-	    return miRegionBreak (dst);
-	dst->data->size = src->data->numRects;
-    }
-    dst->data->numRects = src->data->numRects;
-    memmove((char *)REGION_BOXPTR(dst),(char *)REGION_BOXPTR(src), 
-	  dst->data->numRects * sizeof(BoxRec));
-    return TRUE;
+    return pixman_region_copy (dst, src);
 }
 
-
 /*======================================================================
  *	    Generic Region Operator
  *====================================================================*/
@@ -916,8 +845,7 @@ miRegionOp(
  *-----------------------------------------------------------------------
  */
 static void
-miSetExtents (pReg)
-    RegionPtr pReg;
+miSetExtents (RegionPtr pReg)
 {
     BoxPtr pBox, pBoxEnd;
 
@@ -974,113 +902,13 @@ miSetExtents (pReg)
  *-----------------------------------------------------------------------
  */
 /*ARGSUSED*/
-static Bool
-miIntersectO (
-    RegionPtr	pReg,
-    BoxPtr	r1,
-    BoxPtr  	  	r1End,
-    BoxPtr	r2,
-    BoxPtr  	  	r2End,
-    short    	  	y1,
-    short    	  	y2,
-    Bool		*pOverlap)
-{
-    int  	x1;
-    int  	x2;
-    BoxPtr	pNextRect;
-
-    pNextRect = REGION_TOP(pReg);
-
-    assert(y1 < y2);
-    assert(r1 != r1End && r2 != r2End);
-
-    do {
-	x1 = max(r1->x1, r2->x1);
-	x2 = min(r1->x2, r2->x2);
-
-	/*
-	 * If there's any overlap between the two rectangles, add that
-	 * overlap to the new region.
-	 */
-	if (x1 < x2)
-	    NEWRECT(pReg, pNextRect, x1, y1, x2, y2);
-
-	/*
-	 * Advance the pointer(s) with the leftmost right side, since the next
-	 * rectangle on that list may still overlap the other region's
-	 * current rectangle.
-	 */
-	if (r1->x2 == x2) {
-	    r1++;
-	}
-	if (r2->x2 == x2) {
-	    r2++;
-	}
-    } while ((r1 != r1End) && (r2 != r2End));
-
-    return TRUE;
-}
-
-
 _X_EXPORT Bool
 miIntersect(newReg, reg1, reg2)
     RegionPtr 	newReg;     /* destination Region */
     RegionPtr 	reg1;
     RegionPtr	reg2;       /* source regions     */
 {
-    good(reg1);
-    good(reg2);
-    good(newReg);
-   /* check for trivial reject */
-    if (REGION_NIL(reg1)  || REGION_NIL(reg2) ||
-	!EXTENTCHECK(&reg1->extents, &reg2->extents))
-    {
-	/* Covers about 20% of all cases */
-	xfreeData(newReg);
-	newReg->extents.x2 = newReg->extents.x1;
-	newReg->extents.y2 = newReg->extents.y1;
-	if (REGION_NAR(reg1) || REGION_NAR(reg2))
-	{
-	    newReg->data = &miBrokenData;
-	    return FALSE;
-	}
-	else
-	    newReg->data = &miEmptyData;
-    }
-    else if (!reg1->data && !reg2->data)
-    {
-	/* Covers about 80% of cases that aren't trivially rejected */
-	newReg->extents.x1 = max(reg1->extents.x1, reg2->extents.x1);
-	newReg->extents.y1 = max(reg1->extents.y1, reg2->extents.y1);
-	newReg->extents.x2 = min(reg1->extents.x2, reg2->extents.x2);
-	newReg->extents.y2 = min(reg1->extents.y2, reg2->extents.y2);
-	xfreeData(newReg);
-	newReg->data = (RegDataPtr)NULL;
-    }
-    else if (!reg2->data && SUBSUMES(&reg2->extents, &reg1->extents))
-    {
-	return miRegionCopy(newReg, reg1);
-    }
-    else if (!reg1->data && SUBSUMES(&reg1->extents, &reg2->extents))
-    {
-	return miRegionCopy(newReg, reg2);
-    }
-    else if (reg1 == reg2)
-    {
-	return miRegionCopy(newReg, reg1);
-    }
-    else
-    {
-	/* General purpose intersection */
-	Bool overlap; /* result ignored */
-	if (!miRegionOp(newReg, reg1, reg2, miIntersectO, FALSE, FALSE,
-			&overlap))
-	    return FALSE;
-	miSetExtents(newReg);
-    }
-
-    good(newReg);
-    return(TRUE);
+    return pixman_region_intersect (newReg, reg1, reg2);
 }
 
 #define MERGERECT(r)						\
@@ -1183,78 +1011,9 @@ miUnion(newReg, reg1, reg2)
     RegionPtr 	reg1;
     RegionPtr	reg2;             /* source regions     */
 {
-    Bool overlap; /* result ignored */
-
-    /* Return TRUE if some overlap between reg1, reg2 */
-    good(reg1);
-    good(reg2);
-    good(newReg);
-    /*  checks all the simple cases */
-
-    /*
-     * Region 1 and 2 are the same
-     */
-    if (reg1 == reg2)
-    {
-	return miRegionCopy(newReg, reg1);
-    }
-
-    /*
-     * Region 1 is empty
-     */
-    if (REGION_NIL(reg1))
-    {
-	if (REGION_NAR(reg1))
-	    return miRegionBreak (newReg);
-        if (newReg != reg2)
-	    return miRegionCopy(newReg, reg2);
-        return TRUE;
-    }
-
-    /*
-     * Region 2 is empty
-     */
-    if (REGION_NIL(reg2))
-    {
-	if (REGION_NAR(reg2))
-	    return miRegionBreak (newReg);
-        if (newReg != reg1)
-	    return miRegionCopy(newReg, reg1);
-        return TRUE;
-    }
-
-    /*
-     * Region 1 completely subsumes region 2
-     */
-    if (!reg1->data && SUBSUMES(&reg1->extents, &reg2->extents))
-    {
-        if (newReg != reg1)
-	    return miRegionCopy(newReg, reg1);
-        return TRUE;
-    }
-
-    /*
-     * Region 2 completely subsumes region 1
-     */
-    if (!reg2->data && SUBSUMES(&reg2->extents, &reg1->extents))
-    {
-        if (newReg != reg2)
-	    return miRegionCopy(newReg, reg2);
-        return TRUE;
-    }
-
-    if (!miRegionOp(newReg, reg1, reg2, miUnionO, TRUE, TRUE, &overlap))
-	return FALSE;
-
-    newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1);
-    newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1);
-    newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2);
-    newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2);
-    good(newReg);
-    return TRUE;
+    return pixman_region_union (newReg, reg1, reg2);
 }
 
-
 /*======================================================================
  *	    Batch Rectangle Union
  *====================================================================*/
@@ -1659,6 +1418,7 @@ miRectsToRegion(nrects, prect, ctype)
     xRectangle		*prect;
     int			ctype;
 {
+    
     RegionPtr		pRgn;
     RegDataPtr		pData;
     BoxPtr		pBox;
@@ -1754,116 +1514,7 @@ miRectsToRegion(nrects, prect, ctype)
  *-----------------------------------------------------------------------
  */
 /*ARGSUSED*/
-static Bool
-miSubtractO (
-    RegionPtr	pReg,
-    BoxPtr	r1,
-    BoxPtr  	r1End,
-    BoxPtr	r2,
-    BoxPtr  	r2End,
-    short  	y1,
-    short  	y2,
-    Bool	*pOverlap)
-{
-    BoxPtr	pNextRect;
-    int  	x1;
-
-    x1 = r1->x1;
-    
-    assert(y1<y2);
-    assert(r1 != r1End && r2 != r2End);
-
-    pNextRect = REGION_TOP(pReg);
-
-    do
-    {
-	if (r2->x2 <= x1)
-	{
-	    /*
-	     * Subtrahend entirely to left of minuend: go to next subtrahend.
-	     */
-	    r2++;
-	}
-	else if (r2->x1 <= x1)
-	{
-	    /*
-	     * Subtrahend preceeds minuend: nuke left edge of minuend.
-	     */
-	    x1 = r2->x2;
-	    if (x1 >= r1->x2)
-	    {
-		/*
-		 * Minuend completely covered: advance to next minuend and
-		 * reset left fence to edge of new minuend.
-		 */
-		r1++;
-		if (r1 != r1End)
-		    x1 = r1->x1;
-	    }
-	    else
-	    {
-		/*
-		 * Subtrahend now used up since it doesn't extend beyond
-		 * minuend
-		 */
-		r2++;
-	    }
-	}
-	else if (r2->x1 < r1->x2)
-	{
-	    /*
-	     * Left part of subtrahend covers part of minuend: add uncovered
-	     * part of minuend to region and skip to next subtrahend.
-	     */
-	    assert(x1<r2->x1);
-	    NEWRECT(pReg, pNextRect, x1, y1, r2->x1, y2);
-
-	    x1 = r2->x2;
-	    if (x1 >= r1->x2)
-	    {
-		/*
-		 * Minuend used up: advance to new...
-		 */
-		r1++;
-		if (r1 != r1End)
-		    x1 = r1->x1;
-	    }
-	    else
-	    {
-		/*
-		 * Subtrahend used up
-		 */
-		r2++;
-	    }
-	}
-	else
-	{
-	    /*
-	     * Minuend used up: add any remaining piece before advancing.
-	     */
-	    if (r1->x2 > x1)
-		NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);
-	    r1++;
-	    if (r1 != r1End)
-		x1 = r1->x1;
-	}
-    } while ((r1 != r1End) && (r2 != r2End));
 
-
-    /*
-     * Add remaining minuend rectangles to region.
-     */
-    while (r1 != r1End)
-    {
-	assert(x1<r1->x2);
-	NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);
-	r1++;
-	if (r1 != r1End)
-	    x1 = r1->x1;
-    }
-    return TRUE;
-}
-	
 /*-
  *-----------------------------------------------------------------------
  * miSubtract --
@@ -1884,44 +1535,7 @@ miSubtract(regD, regM, regS)
     RegionPtr 	regM;
     RegionPtr	regS;          
 {
-    Bool overlap; /* result ignored */
-
-    good(regM);
-    good(regS);
-    good(regD);
-   /* check for trivial rejects */
-    if (REGION_NIL(regM) || REGION_NIL(regS) ||
-	!EXTENTCHECK(&regM->extents, &regS->extents))
-    {
-	if (REGION_NAR (regS))
-	    return miRegionBreak (regD);
-	return miRegionCopy(regD, regM);
-    }
-    else if (regM == regS)
-    {
-	xfreeData(regD);
-	regD->extents.x2 = regD->extents.x1;
-	regD->extents.y2 = regD->extents.y1;
-	regD->data = &miEmptyData;
-	return TRUE;
-    }
- 
-    /* Add those rectangles in region 1 that aren't in region 2,
-       do yucky substraction for overlaps, and
-       just throw away rectangles in region 2 that aren't in region 1 */
-    if (!miRegionOp(regD, regM, regS, miSubtractO, TRUE, FALSE, &overlap))
-	return FALSE;
-
-    /*
-     * Can't alter RegD's extents before we call miRegionOp because
-     * it might be one of the source regions and miRegionOp depends
-     * on the extents of those regions being unaltered. Besides, this
-     * way there's no checking against rectangles that will be nuked
-     * due to coalescing, so we have to examine fewer rectangles.
-     */
-    miSetExtents(regD);
-    good(regD);
-    return TRUE;
+    return pixman_region_subtract (regD, regM, regS);
 }
 
 /*======================================================================
@@ -1949,150 +1563,14 @@ miInverse(newReg, reg1, invRect)
     RegionPtr 	  reg1;         /* Region to invert */
     BoxPtr     	  invRect; 	/* Bounding box for inversion */
 {
-    RegionRec	  invReg;   	/* Quick and dirty region made from the
-				 * bounding box */
-    Bool	  overlap;	/* result ignored */
-
-    good(reg1);
-    good(newReg);
-   /* check for trivial rejects */
-    if (REGION_NIL(reg1) || !EXTENTCHECK(invRect, &reg1->extents))
-    {
-	if (REGION_NAR(reg1))
-	    return miRegionBreak (newReg);
-	newReg->extents = *invRect;
-	xfreeData(newReg);
-	newReg->data = (RegDataPtr)NULL;
-        return TRUE;
-    }
-
-    /* Add those rectangles in region 1 that aren't in region 2,
-       do yucky substraction for overlaps, and
-       just throw away rectangles in region 2 that aren't in region 1 */
-    invReg.extents = *invRect;
-    invReg.data = (RegDataPtr)NULL;
-    if (!miRegionOp(newReg, &invReg, reg1, miSubtractO, TRUE, FALSE, &overlap))
-	return FALSE;
-
-    /*
-     * Can't alter newReg's extents before we call miRegionOp because
-     * it might be one of the source regions and miRegionOp depends
-     * on the extents of those regions being unaltered. Besides, this
-     * way there's no checking against rectangles that will be nuked
-     * due to coalescing, so we have to examine fewer rectangles.
-     */
-    miSetExtents(newReg);
-    good(newReg);
-    return TRUE;
+    return pixman_region_inverse (newReg, reg1, invRect);
 }
-
-/*
- *   RectIn(region, rect)
- *   This routine takes a pointer to a region and a pointer to a box
- *   and determines if the box is outside/inside/partly inside the region.
- *
- *   The idea is to travel through the list of rectangles trying to cover the
- *   passed box with them. Anytime a piece of the rectangle isn't covered
- *   by a band of rectangles, partOut is set TRUE. Any time a rectangle in
- *   the region covers part of the box, partIn is set TRUE. The process ends
- *   when either the box has been completely covered (we reached a band that
- *   doesn't overlap the box, partIn is TRUE and partOut is false), the
- *   box has been partially covered (partIn == partOut == TRUE -- because of
- *   the banding, the first time this is true we know the box is only
- *   partially in the region) or is outside the region (we reached a band
- *   that doesn't overlap the box at all and partIn is false)
- */
-
 _X_EXPORT int
 miRectIn(region, prect)
     RegionPtr  region;
     BoxPtr     prect;
 {
-    int		x;
-    int		y;
-    BoxPtr	pbox;
-    BoxPtr	pboxEnd;
-    int		partIn, partOut;
-    int		numRects;
-
-    good(region);
-    numRects = REGION_NUM_RECTS(region);
-    /* useful optimization */
-    if (!numRects || !EXTENTCHECK(&region->extents, prect))
-        return(rgnOUT);
-
-    if (numRects == 1)
-    {
-	/* We know that it must be rgnIN or rgnPART */
-	if (SUBSUMES(&region->extents, prect))
-	    return(rgnIN);
-	else
-	    return(rgnPART);
-    }
-
-    partOut = FALSE;
-    partIn = FALSE;
-
-    /* (x,y) starts at upper left of rect, moving to the right and down */
-    x = prect->x1;
-    y = prect->y1;
-
-    /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
-    for (pbox = REGION_BOXPTR(region), pboxEnd = pbox + numRects;
-         pbox != pboxEnd;
-         pbox++)
-    {
-
-        if (pbox->y2 <= y)
-           continue;    /* getting up to speed or skipping remainder of band */
-
-        if (pbox->y1 > y)
-        {
-           partOut = TRUE;      /* missed part of rectangle above */
-           if (partIn || (pbox->y1 >= prect->y2))
-              break;
-           y = pbox->y1;        /* x guaranteed to be == prect->x1 */
-        }
-
-        if (pbox->x2 <= x)
-           continue;            /* not far enough over yet */
-
-        if (pbox->x1 > x)
-        {
-           partOut = TRUE;      /* missed part of rectangle to left */
-           if (partIn)
-              break;
-        }
-
-        if (pbox->x1 < prect->x2)
-        {
-            partIn = TRUE;      /* definitely overlap */
-            if (partOut)
-               break;
-        }
-
-        if (pbox->x2 >= prect->x2)
-        {
-           y = pbox->y2;        /* finished with this band */
-           if (y >= prect->y2)
-              break;
-           x = prect->x1;       /* reset x out to left again */
-        }
-	else
-	{
-	    /*
-	     * Because boxes in a band are maximal width, if the first box
-	     * to overlap the rectangle doesn't completely cover it in that
-	     * band, the rectangle must be partially out, since some of it
-	     * will be uncovered in that band. partIn will have been set true
-	     * by now...
-	     */
-	    partOut = TRUE;
-	    break;
-	}
-    }
-
-    return(partIn ? ((y < prect->y2) ? rgnPART : rgnIN) : rgnOUT);
+    return pixman_region_contains_rectangle (region, prect);
 }
 
 /* TranslateRegion(pReg, x, y)
@@ -2105,83 +1583,7 @@ miTranslateRegion(pReg, x, y)
     int x;
     int y;
 {
-    int x1, x2, y1, y2;
-    int nbox;
-    BoxPtr pbox;
-
-    good(pReg);
-    pReg->extents.x1 = x1 = pReg->extents.x1 + x;
-    pReg->extents.y1 = y1 = pReg->extents.y1 + y;
-    pReg->extents.x2 = x2 = pReg->extents.x2 + x;
-    pReg->extents.y2 = y2 = pReg->extents.y2 + y;
-    if (((x1 - MINSHORT)|(y1 - MINSHORT)|(MAXSHORT - x2)|(MAXSHORT - y2)) >= 0)
-    {
-	if (pReg->data && (nbox = pReg->data->numRects))
-	{
-	    for (pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
-	    {
-		pbox->x1 += x;
-		pbox->y1 += y;
-		pbox->x2 += x;
-		pbox->y2 += y;
-	    }
-	}
-	return;
-    }
-    if (((x2 - MINSHORT)|(y2 - MINSHORT)|(MAXSHORT - x1)|(MAXSHORT - y1)) <= 0)
-    {
-	pReg->extents.x2 = pReg->extents.x1;
-	pReg->extents.y2 = pReg->extents.y1;
-	xfreeData(pReg);
-	pReg->data = &miEmptyData;
-	return;
-    }
-    if (x1 < MINSHORT)
-	pReg->extents.x1 = MINSHORT;
-    else if (x2 > MAXSHORT)
-	pReg->extents.x2 = MAXSHORT;
-    if (y1 < MINSHORT)
-	pReg->extents.y1 = MINSHORT;
-    else if (y2 > MAXSHORT)
-	pReg->extents.y2 = MAXSHORT;
-    if (pReg->data && (nbox = pReg->data->numRects))
-    {
-	BoxPtr pboxout;
-
-	for (pboxout = pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
-	{
-	    pboxout->x1 = x1 = pbox->x1 + x;
-	    pboxout->y1 = y1 = pbox->y1 + y;
-	    pboxout->x2 = x2 = pbox->x2 + x;
-	    pboxout->y2 = y2 = pbox->y2 + y;
-	    if (((x2 - MINSHORT)|(y2 - MINSHORT)|
-		 (MAXSHORT - x1)|(MAXSHORT - y1)) <= 0)
-	    {
-		pReg->data->numRects--;
-		continue;
-	    }
-	    if (x1 < MINSHORT)
-		pboxout->x1 = MINSHORT;
-	    else if (x2 > MAXSHORT)
-		pboxout->x2 = MAXSHORT;
-	    if (y1 < MINSHORT)
-		pboxout->y1 = MINSHORT;
-	    else if (y2 > MAXSHORT)
-		pboxout->y2 = MAXSHORT;
-	    pboxout++;
-	}
-	if (pboxout != pbox)
-	{
-	    if (pReg->data->numRects == 1)
-	    {
-		pReg->extents = *REGION_BOXPTR(pReg);
-		xfreeData(pReg);
-		pReg->data = (RegDataPtr)NULL;
-	    }
-	    else
-		miSetExtents(pReg);
-	}
-    }
+    pixman_region_translate (pReg, x, y);
 }
 
 _X_EXPORT void
@@ -2189,12 +1591,7 @@ miRegionReset(pReg, pBox)
     RegionPtr pReg;
     BoxPtr pBox;
 {
-    good(pReg);
-    assert(pBox->x1<=pBox->x2);
-    assert(pBox->y1<=pBox->y2);
-    pReg->extents = *pBox;
-    xfreeData(pReg);
-    pReg->data = (RegDataPtr)NULL;
+    pixman_region_reset (pReg, pBox);
 }
 
 _X_EXPORT Bool
@@ -2203,40 +1600,14 @@ miPointInRegion(pReg, x, y, box)
     int x, y;
     BoxPtr box;     /* "return" value */
 {
-    BoxPtr pbox, pboxEnd;
-    int numRects;
-
-    good(pReg);
-    numRects = REGION_NUM_RECTS(pReg);
-    if (!numRects || !INBOX(&pReg->extents, x, y))
-        return(FALSE);
-    if (numRects == 1)
-    {
-	*box = pReg->extents;
-	return(TRUE);
-    }
-    for (pbox = REGION_BOXPTR(pReg), pboxEnd = pbox + numRects;
-	 pbox != pboxEnd;
-	 pbox++)
-    {
-        if (y >= pbox->y2)
-	   continue;		/* not there yet */
-	if ((y < pbox->y1) || (x < pbox->x1))
-	   break;		/* missed it */
-	if (x >= pbox->x2)
-	   continue;		/* not there yet */
-	*box = *pbox;
-	return(TRUE);
-    }
-    return(FALSE);
+    return pixman_region_contains_point (pReg, x, y, box);
 }
 
 _X_EXPORT Bool
 miRegionNotEmpty(pReg)
     RegionPtr pReg;
 {
-    good(pReg);
-    return(!REGION_NIL(pReg));
+    return pixman_region_not_empty (pReg);
 }
 
 Bool
diff-tree dde0ceac4ea7639d0096bfd26f37c5851778854c (from e037052ac522150786abf44d3a04c813cc490050)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Sat May 12 17:41:47 2007 -0400

    Add new InitRegions() function called from dix/main

diff --git a/dix/main.c b/dix/main.c
index 9a67ed9..623ce9c 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -253,6 +253,7 @@ main(int argc, char *argv[], char *envp[
     display = "0";
 
     InitGlobals();
+    InitRegions();
 #ifdef XPRINT
     PrinterInitGlobals();
 #endif
diff --git a/include/regionstr.h b/include/regionstr.h
index 8d47c02..f44cab7 100644
--- a/include/regionstr.h
+++ b/include/regionstr.h
@@ -225,6 +225,8 @@ extern RegDataRec miBrokenData;
 
 /* moved from mi.h */
 
+extern void InitRegions (void);
+
 extern RegionPtr miRegionCreate(
     BoxPtr /*rect*/,
     int /*size*/);
diff --git a/mi/miregion.c b/mi/miregion.c
index 0eab662..4bfe9c7 100644
--- a/mi/miregion.c
+++ b/mi/miregion.c
@@ -85,6 +85,7 @@ Equipment Corporation.
 #include "gc.h"
 #include "mi.h"
 #include "mispans.h"
+#include <pixman/pixman.h>
 
 #undef assert
 #ifdef DEBUG
@@ -218,6 +219,12 @@ _X_EXPORT RegDataRec miEmptyData = {0, 0
 RegDataRec  miBrokenData = {0, 0};
 static RegionRec   miBrokenRegion = { { 0, 0, 0, 0 }, &miBrokenData };
 
+extern void
+InitRegions (void)
+{
+    pixman_region_set_static_pointers (&miEmptyBox, &miEmptyData, &miBrokenData);
+}
+
 _X_EXPORT void
 miPrintRegion(rgn)
     RegionPtr rgn;
diff-tree e037052ac522150786abf44d3a04c813cc490050 (from 8e56f5be4b70773c899f01b9ccd2e88d523327e4)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Sat May 12 16:58:54 2007 -0400

    Turn boxes and regions into typedefs for pixman types

diff --git a/include/misc.h b/include/misc.h
index 2be1d66..e6a5e9e 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -239,7 +239,7 @@ extern int Ones(
     unsigned long /*mask*/);
 
 typedef struct _xPoint *DDXPointPtr;
-typedef struct _Box *BoxPtr;
+typedef struct pixman_box16 *BoxPtr;
 typedef struct _xEvent *xEventPtr;
 typedef struct _xRectangle *xRectanglePtr;
 typedef struct _GrabRec *GrabPtr;
diff --git a/include/miscstruct.h b/include/miscstruct.h
index c39f03c..4f5b1d5 100644
--- a/include/miscstruct.h
+++ b/include/miscstruct.h
@@ -51,12 +51,11 @@ SOFTWARE.
 #include "misc.h"
 #include <X11/Xprotostr.h>
 #include "gc.h"
+#include <pixman/pixman.h>
 
 typedef xPoint DDXPointRec;
 
-typedef struct _Box {
-    short x1, y1, x2, y2;
-} BoxRec;
+typedef struct pixman_box16 BoxRec;
 
 typedef union _DevUnion {
     pointer		ptr;
diff --git a/include/regionstr.h b/include/regionstr.h
index e6882e7..8d47c02 100644
--- a/include/regionstr.h
+++ b/include/regionstr.h
@@ -48,7 +48,7 @@ SOFTWARE.
 #ifndef REGIONSTRUCT_H
 #define REGIONSTRUCT_H
 
-typedef struct _Region RegionRec, *RegionPtr;
+typedef struct pixman_region16 RegionRec, *RegionPtr;
 
 #include "miscstruct.h"
 
@@ -64,16 +64,7 @@ typedef struct _Region RegionRec, *Regio
  *   clip region
  */
 
-typedef struct _RegData {
-    long	size;
-    long 	numRects;
-/*  BoxRec	rects[size];   in memory but not explicitly declared */
-} RegDataRec, *RegDataPtr;
-
-struct _Region {
-    BoxRec 	extents;
-    RegDataPtr	data;
-};
+typedef struct pixman_region16_data RegDataRec, *RegDataPtr;
 
 extern BoxRec miEmptyBox;
 extern RegDataRec miEmptyData;
diff-tree 8e56f5be4b70773c899f01b9ccd2e88d523327e4 (from a277f04ab08514462b7f10b4dd92eb326af85501)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri May 11 11:45:37 2007 -0400

    Add dependency on pixman 0.9.0

diff --git a/configure.ac b/configure.ac
index ffb1b85..d7d00e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -623,9 +623,11 @@ XEXT_INC='-I$(top_srcdir)/Xext'
 XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
+PIXMAN="[pixman >= 0.9.0]"
+
 dnl Core modules for most extensions, et al.
 REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
-REQUIRED_LIBS="xfont xau fontenc"
+REQUIRED_LIBS="xfont xau fontenc $PIXMAN"
 
 if test "x$DBUS" = xauto; then
        PKG_CHECK_MODULES(DBUS, dbus-1, [DBUS=yes], [DBUS=no])
@@ -1103,7 +1105,7 @@ dnl ------------------------------------
 dnl DMX DDX
 
 AC_MSG_CHECKING([whether to build Xdmx DDX])
-PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
+PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau $XDMCP_MODULES $PIXMAN], [have_dmx=yes], [have_dmx=no])
 if test "x$DMX" = xauto; then
 	DMX="$have_dmx"
 fi
diff-tree a277f04ab08514462b7f10b4dd92eb326af85501 (from 20c5250e487e032d392e2e4624021fccb1bfb72c)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed May 9 22:03:12 2007 -0400

    Remove mfb and cfb from include paths where they're not needed.

diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index 1581019..06e6d40 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -45,9 +45,6 @@ fontsmodule_LTLIBRARIES = libfreetype.la
 
 AM_CFLAGS = @XORG_CFLAGS@ @DIX_CFLAGS@
 INCLUDES = @XORG_INCS@ \
-           -I$(top_srcdir)/afb \
-           -I$(top_srcdir)/cfb \
-           -I$(top_srcdir)/mfb \
            -I$(top_srcdir)/dbe \
            -I$(top_srcdir)/hw/xfree86/loader \
            -I$(top_srcdir)/miext/shadow \
diff --git a/hw/xfree86/dixmods/afbmodule.c b/hw/xfree86/dixmods/afbmodule.c
index ee8cf20..b0aea6d 100644
--- a/hw/xfree86/dixmods/afbmodule.c
+++ b/hw/xfree86/dixmods/afbmodule.c
@@ -29,7 +29,6 @@
 #endif
 
 #include "xf86Module.h"
-#include "afb.h"
 
 static MODULESETUPPROTO(afbSetup);
 
diff --git a/hw/xfree86/dixmods/cfb32module.c b/hw/xfree86/dixmods/cfb32module.c
index 1451594..23708e4 100644
--- a/hw/xfree86/dixmods/cfb32module.c
+++ b/hw/xfree86/dixmods/cfb32module.c
@@ -28,10 +28,7 @@
 #include <xorg-config.h>
 #endif
 
-#define PSZ 32
-
 #include "xf86Module.h"
-#include "cfb.h"
 
 static MODULESETUPPROTO(cfb32Setup);
 
diff --git a/hw/xfree86/dixmods/cfbmodule.c b/hw/xfree86/dixmods/cfbmodule.c
index 693fd61..07074c1 100644
--- a/hw/xfree86/dixmods/cfbmodule.c
+++ b/hw/xfree86/dixmods/cfbmodule.c
@@ -28,10 +28,7 @@
 #include <xorg-config.h>
 #endif
 
-#define PSZ 8
-
 #include "xf86Module.h"
-#include "cfb.h"
 
 static MODULESETUPPROTO(cfbSetup);
 
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 06ce15a..7d76929 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -67,5 +67,3 @@ libmi_la_SOURCES = 	\
 	mizerarc.h	\
 	mizerclip.c	\
 	mizerline.c
-
-INCLUDES = -I$(top_srcdir)/mfb
diff-tree 20c5250e487e032d392e2e4624021fccb1bfb72c (from 8dcc37520d5e8c8b52cee81faa67fd5205548377)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed May 9 21:49:44 2007 -0400

    Use system copy of cbrt() if available.
    
    Also move the replacement inline into miarc.c, since that's the only user.

diff --git a/configure.ac b/configure.ac
index c8b40a1..ffb1b85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -182,6 +182,7 @@ AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP
 
 dnl Find the math libary
 AC_CHECK_LIB(m, sqrt)
+AC_CHECK_LIB(m, cbrt, AC_DEFINE(HAVE_CBRT, 1, [Have the 'cbrt' function]))
 
 AC_CHECK_HEADERS([ndbm.h dbm.h rpcsvc/dbm.h])
 
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 62e109b..919da60 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -102,6 +102,9 @@
 /* Define to 1 if you have the <byteswap.h> header file. */
 #undef HAVE_BYTESWAP_H
 
+/* Define to 1 if you have cbrt */
+#undef HAVE_CBRT
+
 /* Define to 1 if you have the <dbm.h> header file. */
 #undef HAVE_DBM_H
 
diff --git a/mi/Makefile.am b/mi/Makefile.am
index f262f4b..06ce15a 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -9,7 +9,6 @@ endif
 AM_CFLAGS = $(DIX_CFLAGS)
 
 libmi_la_SOURCES = 	\
-	cbrt.c		\
 	mi.h		\
 	miarc.c		\
 	mibank.c	\
diff --git a/mi/cbrt.c b/mi/cbrt.c
deleted file mode 100644
index c703fd9..0000000
--- a/mi/cbrt.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-
-Copyright 1990, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/* simple cbrt, in case your math library doesn't have a good one */
-
-/*
- * Would normally include <math.h> for this, but for the sake of compiler
- * warnings, we don't want to get duplicate declarations for cbrt().
- */
-
-double pow(double, double);
-double cbrt(double);
-
-double
-cbrt(double x)
-{
-    if (x > 0.0)
-	return pow(x, 1.0/3.0);
-    else
-	return -pow(-x, 1.0/3.0);
-}
diff --git a/mi/miarc.c b/mi/miarc.c
index 69c5acd..3b77ce7 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -51,14 +51,7 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#if defined(_XOPEN_SOURCE) || defined(__QNXNTO__) \
-	|| (defined(sun) && defined(__SVR4))
 #include <math.h>
-#else
-#define _XOPEN_SOURCE	/* to get prototype for hypot on some systems */
-#include <math.h>
-#undef _XOPEN_SOURCE
-#endif
 #include <X11/X.h>
 #include <X11/Xprotostr.h>
 #include "misc.h"
@@ -75,7 +68,17 @@ static double miDsin(double a);
 static double miDcos(double a);
 static double miDasin(double v);
 static double miDatan2(double dy, double dx);
-double	cbrt(double);
+
+#ifndef HAVE_CBRT
+static double
+cbrt(double x)
+{
+    if (x > 0.0)
+	return pow(x, 1.0/3.0);
+    else
+	return -pow(-x, 1.0/3.0);
+}
+#endif
 
 /*
  * some interesting sematic interpretation of the protocol:
diff-tree 8dcc37520d5e8c8b52cee81faa67fd5205548377 (from 6ff239cb4e67c0a2ea497a1714e5585c1d941af3)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed May 9 18:57:05 2007 -0400

    Use _X_INLINE instead of ad-hoc #defines.

diff --git a/mi/miarc.c b/mi/miarc.c
index 17b7891..69c5acd 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -100,37 +100,16 @@ double	cbrt(double);
 #undef max
 #undef min
 
-#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
-#define USE_INLINE
-#endif
-
-#ifdef USE_INLINE
-inline static int max (const int x, const int y)
+_X_INLINE static int max (const int x, const int y)
 {
 	return x>y? x:y;
 }
 
-inline static int min (const int x, const int y)
+_X_INLINE static int min (const int x, const int y)
 {
 	return x<y? x:y;
 }
 
-#else
-
-static int
-max (int x, int y)
-{
-	return x>y? x:y;
-}
-
-static int
-min (int x, int y)
-{
-	return x<y? x:y;
-}
-
-#endif
-
 struct bound {
 	double	min, max;
 };
diff --git a/mi/miregion.c b/mi/miregion.c
index e980ad1..0eab662 100644
--- a/mi/miregion.c
+++ b/mi/miregion.c
@@ -81,16 +81,11 @@ Equipment Corporation.
 
 #include "regionstr.h"
 #include <X11/Xprotostr.h>
+#include <X11/Xfuncproto.h>
 #include "gc.h"
 #include "mi.h"
 #include "mispans.h"
 
-#if defined (__GNUC__) && !defined (NO_INLINES)
-#define INLINE	__inline
-#else
-#define INLINE
-#endif
-
 #undef assert
 #ifdef DEBUG
 #define assert(expr) {if (!(expr)) \
@@ -506,7 +501,7 @@ miRegionCopy(dst, src)
  *
  *-----------------------------------------------------------------------
  */
-INLINE static int
+_X_INLINE static int
 miCoalesce (
     RegionPtr	pReg,	    	/* Region to coalesce		     */
     int	    	  	prevStart,  	/* Index of start of previous band   */
@@ -590,7 +585,7 @@ miCoalesce (
  *-----------------------------------------------------------------------
  */
 
-INLINE static Bool
+_X_INLINE static Bool
 miAppendNonO (
     RegionPtr	pReg,
     BoxPtr	r,
diff-tree 6ff239cb4e67c0a2ea497a1714e5585c1d941af3 (from 178d426311bb3c7160f72b5d95b0a137eda09ba9)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed May 9 18:38:33 2007 -0400

    Make the use of ICEIL slightly less ugly.

diff --git a/hw/xfree86/xaa/xaaWideLine.c b/hw/xfree86/xaa/xaaWideLine.c
index 9479b0d..a684d66 100644
--- a/hw/xfree86/xaa/xaaWideLine.c
+++ b/hw/xfree86/xaa/xaaWideLine.c
@@ -32,10 +32,6 @@ Original mi code written by Keith Packar
 #include "xaa.h"
 #include "xaalocal.h"
 
-#ifdef ICEILTEMPDECL
-ICEILTEMPDECL
-#endif
-
 #define DRAW_POINT(pScrn, x, y) \
   if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1); \
   else XAAPointHelper(pScrn, x, y)
diff --git a/mi/miarc.c b/mi/miarc.c
index 2bbbb0e..17b7891 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -77,10 +77,6 @@ static double miDasin(double v);
 static double miDatan2(double dy, double dx);
 double	cbrt(double);
 
-#ifdef ICEILTEMPDECL
-ICEILTEMPDECL
-#endif
-
 /*
  * some interesting sematic interpretation of the protocol:
  *
diff --git a/mi/mifpoly.h b/mi/mifpoly.h
index 8f05076..7bd77b3 100644
--- a/mi/mifpoly.h
+++ b/mi/mifpoly.h
@@ -48,6 +48,8 @@ SOFTWARE.
 #ifndef __MIFPOLY_H__
 #define __MIFPOLY_H__
 
+#include <X11/Xfuncproto.h>
+
 #define EPSILON	0.000001
 #define ISEQUAL(a,b) (Fabs((a) - (b)) <= EPSILON)
 #define UNEQUAL(a,b) (Fabs((a) - (b)) > EPSILON)
@@ -66,20 +68,11 @@ SOFTWARE.
 #define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */
 #define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */
 
-#ifdef NOINLINEICEIL
-#define ICEIL(x) ((int)ceil(x))
-#else
-#ifdef __GNUC__
-static __inline int ICEIL(double x)
+static _X_INLINE int ICEIL(double x)
 {
     int _cTmp = x;
     return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
 }
-#else
-#define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
-#define ICEILTEMPDECL static int _cTmp;
-#endif
-#endif
 
 /* Point with sub-pixel positioning.  In this case we use doubles, but
  * see mifpolycon.c for other suggestions 
diff --git a/mi/mifpolycon.c b/mi/mifpolycon.c
index 7bc1bb2..f851971 100644
--- a/mi/mifpolycon.c
+++ b/mi/mifpolycon.c
@@ -58,10 +58,6 @@ SOFTWARE.
 static int GetFPolyYBounds(SppPointPtr pts, int n, double yFtrans,
 			   int *by, int *ty);
 
-#ifdef ICEILTEMPDECL
-ICEILTEMPDECL
-#endif
-
 /*
  *	Written by Todd Newman; April. 1987.
  *
diff --git a/mi/miwideline.c b/mi/miwideline.c
index 08e4aa3..8c6022f 100644
--- a/mi/miwideline.c
+++ b/mi/miwideline.c
@@ -52,10 +52,6 @@ from The Open Group.
 #include "miwideline.h"
 #include "mi.h"
 
-#ifdef ICEILTEMPDECL
-ICEILTEMPDECL
-#endif
-
 static void miLineArc(DrawablePtr pDraw, GCPtr pGC,
 		      unsigned long pixel, SpanDataPtr spanData,
 		      LineFacePtr leftFace,
diff-tree 178d426311bb3c7160f72b5d95b0a137eda09ba9 (from ebaa6c920c82401952a0ccc991b94574306449bd)
Author: Colin Harrison <colin.harrison-at-virgin.net>
Date:   Fri May 11 10:08:42 2007 +0100

    Missing piece from bug 9808

diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 47875b4..0a7579b 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -38,6 +38,7 @@
 #include "winmultiwindowclass.h"
 #include "winprefs.h"
 #include "winmsg.h"
+#include "inputstr.h"
 
 /*
  * External global variables
@@ -494,8 +495,8 @@ winTopLevelWindowProc (HWND hwnd, UINT m
 	break;
 
       /* Has the mouse pointer crossed screens? */
-      if (s_pScreen != miPointerCurrentScreen ())
-	miPointerSetNewScreen (s_pScreenInfo->dwScreen,
+      if (s_pScreen != miPointerGetScreen(inputInfo.pointer))
+	miPointerSetScreen (inputInfo.pointer, s_pScreenInfo->dwScreen,
 			       ptMouse.x - s_pScreenInfo->dwXOffset,
 			       ptMouse.y - s_pScreenInfo->dwYOffset);
 
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index ffa8493..859aafd 100755
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -41,6 +41,7 @@
 #include <X11/Xatom.h>
 #include "winmultiwindowclass.h"
 #include "winmsg.h"
+#include "inputstr.h"
 
 
 /*
@@ -534,8 +535,8 @@ winMWExtWMWindowProc (HWND hwnd, UINT me
 	break;
 
       /* Has the mouse pointer crossed screens? */
-      if (pScreen != miPointerCurrentScreen ())
-	miPointerSetNewScreen (pScreenInfo->dwScreen,
+      if (pScreen != miPointerGetScreen(inputInfo.pointer))
+	miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen,
 			       ptMouse.x - pScreenInfo->dwXOffset,
 			       ptMouse.y - pScreenInfo->dwYOffset);
 
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 2974c41..29ea81f 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -40,6 +40,7 @@
 #include "winprefs.h"
 #include "winconfig.h"
 #include "winmsg.h"
+#include "inputstr.h"
 
 #ifdef XKB
 extern BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
@@ -723,8 +724,8 @@ winWindowProc (HWND hwnd, UINT message, 
 	break;
 
       /* Has the mouse pointer crossed screens? */
-      if (s_pScreen != miPointerCurrentScreen ())
-	miPointerSetNewScreen (s_pScreenInfo->dwScreen,
+      if (s_pScreen != miPointerGetScreen(inputInfo.pointer))
+	miPointerSetScreen (inputInfo.pointer, s_pScreenInfo->dwScreen,
 			       GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
 			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset);
 
diff-tree ebaa6c920c82401952a0ccc991b94574306449bd (from 86c4941727f7c673ae6bb88c67443fa25935c7f5)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu May 10 15:25:31 2007 +0200

    Disable Simba PCI bridge routing code (Bug #8020).
    
    The code in hw/xfree86/os-support/bus/sparcPci.c:simbaCheckBus()
    is trying to mimmick VGA routing by disabling I/O space responses
    behind the Simba PCI-PCI controller.
    
    Unfortunately, doing this also happens to disable access to the
    IDE controller I/O space registers, thus crashing the system.  The
    granularity of the I/O disabling in the Simba controller is not
    fine enough to disable VGA without also disabling the IDE controller
    registers.

diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index 7cc882d..f0cb916 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -327,7 +327,7 @@
 #  define INCLUDE_XF86_MAP_PCI_MEM
 #  define INCLUDE_XF86_NO_DOMAIN
 # endif
-# if !defined(__FreeBSD__)
+# if !defined(__FreeBSD__) && !defined(linux)
 #  define ARCH_PCI_PCI_BRIDGE sparcPciPciBridge
 # endif
 #elif defined(__amd64__) || defined(__amd64)
diff-tree 86c4941727f7c673ae6bb88c67443fa25935c7f5 (from be44018a3c6172caf3e91c36ea321420d104e79f)
Author: Colin Harrison <colin.harrison-at-virgin.net>
Date:   Wed May 9 16:55:27 2007 +0100

    fix an occasional crash in GetWindowName() (bug: 9798)

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1918e54..5401ecd 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -445,10 +445,7 @@ GetWindowName (Display *pDisplay, Window
     }
   else
     {
-      XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum);
-
-      /* */
-      if (nNum && ppList && *ppList)
+      if (XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList)
 	{
 	  *ppName = strdup (*ppList);
 	  XFreeStringList (ppList);
diff-tree be44018a3c6172caf3e91c36ea321420d104e79f (from d3248b66a650c6c629cd66240e25004869217d2e)
Author: Colin Harrison <colin.harrison-at-virgin.net>
Date:   Wed May 9 16:55:09 2007 +0100

    Fix bad use of hwnd (bug: 9808)

diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 0df896d..47875b4 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -444,7 +444,7 @@ winTopLevelWindowProc (HWND hwnd, UINT m
       /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
       if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0)
       {
-	EndPaint (hwndScreen, &ps);
+	EndPaint (hwnd, &ps);
 	return 0;
       }
 
@@ -474,7 +474,7 @@ winTopLevelWindowProc (HWND hwnd, UINT m
 	}
 
       /* EndPaint frees the DC */
-      EndPaint (hwndScreen, &ps);
+      EndPaint (hwnd, &ps);
       return 0;
 
     case WM_MOUSEMOVE:
diff-tree d3248b66a650c6c629cd66240e25004869217d2e (from 021e5df85d7c9373a2fed55512751d16e08128db)
Author: Colin Harrison <colin.harrison-at-virgin.net>
Date:   Wed May 9 16:54:46 2007 +0100

    Migrate some code to the new mi apis

diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index f0092e9..1507dd3 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -100,9 +100,10 @@ winMouseProc (DeviceIntPtr pDeviceInt, i
       InitPointerDeviceStruct (pDevice,
 			       map,
 			       lngMouseButtons + lngWheelEvents,
-			       miPointerGetMotionEvents,
+			       GetMotionHistory,
 			       winMouseCtrl,
-			       miPointerGetMotionBufferSize ());
+			       GetMotionHistorySize(),
+			       2);
       free(map);
 
 #if defined(XFree86Server) && defined(XINPUT)
diff-tree 021e5df85d7c9373a2fed55512751d16e08128db (from 1b3a0508a7aee1c7b14cd62216b4727fcc9181d4)
Author: David Nusinow <dnusinow at debian.org>
Date:   Mon May 7 21:03:40 2007 -0400

    Add more informative logging for module default loading
    
    When the modules section is parsed, if a module is set to be loaded by
    default, this will be logged. If it is redundantly specified in xorg.conf,
    this will also be noted. None of this logging will happen if the xorg.conf
    lacks a modules section.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index f44f042..7f1105f 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -290,6 +290,7 @@ xf86ModulelistFromConfig(pointer **optli
             modp = xf86configptr->conf_modules->mod_load_lst;
             while (modp) {
                 if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+                    xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
                     found = TRUE;
                     break;
                 }
@@ -299,6 +300,7 @@ xf86ModulelistFromConfig(pointer **optli
                 modp = xf86configptr->conf_modules->mod_disable_lst;
                 while (modp) {
                     if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+                        xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
                         found = TRUE;
                         break;
                     }
@@ -308,6 +310,7 @@ xf86ModulelistFromConfig(pointer **optli
             if (found == FALSE) {
 	            XF86ConfModulePtr ptr = xf86configptr->conf_modules;
 	            ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+                xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
             }
          }
     } else {
diff-tree 1b3a0508a7aee1c7b14cd62216b4727fcc9181d4 (from 030a578391c634bc68add6ada3f251cf3f8c3069)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Sun May 6 01:30:59 2007 -0700

    Fix documentation for Copy hook -- it can copy memory to the scanout
    buffer too.

diff --git a/exa/exa.h b/exa/exa.h
index 6c39a8f..cd90bbc 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -229,7 +229,7 @@ typedef struct _ExaDriver {
      * @{
      */
     /**
-     * PrepareCopy() sets up the driver for doing a copy within offscreen
+     * PrepareCopy() sets up the driver for doing a copy within video 
      * memory.
      *
      * @param pSrcPixmap source pixmap
diff-tree 030a578391c634bc68add6ada3f251cf3f8c3069 (from e91b9ddc7aa95abc2d4d314e8db204860771a099)
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu May 3 22:51:07 2007 -0400

    Provide UseDefaultFontPath option
    
    This provides a new option, UseDefaultFontPath. This option is enabled by
    default, and causes the X server to always append the default font path
    (defined at compile time) to the font path for the server. This will allow
    people to specify additional font paths if they want without breaking
    their font path, thus hopefully avoiding ye olde "fixed front" problem.
    
    Because this option is a ServerFlag option, the ServerFlags need to be
    processed before the files section of the config file, so swap the order
    that they are processed.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 301b17c..f44f042 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -604,16 +604,24 @@ configFiles(XF86ConfFilesPtr fileconf)
   char *log_buf;
 
   /* FontPath */
-
   /* Try XF86Config FontPath first */
   if (!xf86fpFlag) {
    if (fileconf) {
     if (fileconf->file_fontpath) {
       char *f = xf86ValidateFontPath(fileconf->file_fontpath);
       pathFrom = X_CONFIG;
-      if (*f)
-        defaultFontPath = f;
-      else {
+      if (*f) {
+        if (xf86Info.useDefaultFontPath) {
+          xf86Msg(X_WARNING, "Including the default font path %s.\n", defaultFontPath);
+          char *g = xnfalloc(strlen(defaultFontPath) + strlen(f) + 3);
+          strcpy(g, f);
+          strcat(g, ",");
+          defaultFontPath = strcat(g, defaultFontPath);
+          xfree(f);
+        } else {
+          defaultFontPath = f;
+        }
+      } else {
 	xf86Msg(X_WARNING,
 	    "FontPath is completely invalid.  Using compiled-in default.\n");
         fontPath = NULL;
@@ -781,6 +789,7 @@ typedef enum {
     FLAG_AIGLX,
     FLAG_IGNORE_ABI,
     FLAG_ALLOW_EMPTY_INPUT,
+    FLAG_USE_DEFAULT_FONT_PATH
 } FlagValues;
    
 static OptionInfoRec FlagOptions[] = {
@@ -856,6 +865,8 @@ static OptionInfoRec FlagOptions[] = {
         {0}, FALSE },
   { FLAG_IGNORE_ABI,			"IgnoreABI",			OPTV_BOOLEAN,
 	{0}, FALSE },
+  { FLAG_USE_DEFAULT_FONT_PATH,  "UseDefaultFontPath",			OPTV_BOOLEAN,
+	{0}, FALSE },
   { -1,				NULL,				OPTV_NONE,
 	{0}, FALSE },
 };
@@ -1055,6 +1066,13 @@ configServerFlags(XF86ConfFlagsPtr flags
     if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value))
         xf86Info.allowEmptyInput = TRUE;
 
+    xf86Info.useDefaultFontPath = TRUE;
+    xf86Info.useDefaultFontPathFrom = X_DEFAULT;
+    if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
+	xf86Info.useDefaultFontPath = value;
+	xf86Info.useDefaultFontPathFrom = X_CONFIG;
+    }
+
 /* Make sure that timers don't overflow CARD32's after multiplying */
 #define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
 
@@ -2490,9 +2508,9 @@ xf86HandleConfigFile(Bool autoconfig)
 
     /* Now process everything else */
 
-    if (!configFiles(xf86configptr->conf_files) ||
-        !configServerFlags(xf86configptr->conf_flags,
+    if (!configServerFlags(xf86configptr->conf_flags,
 			   xf86ConfigLayout.options) ||
+         !configFiles(xf86configptr->conf_files) ||
 	!configExtensions(xf86configptr->conf_extensions)
 #ifdef XF86DRI
 	|| !configDRI(xf86configptr->conf_dri)
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 659e566..7ca0669 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -120,6 +120,8 @@ typedef struct {
     MessageType		randRFrom;
     Bool		aiglx;
     MessageType		aiglxFrom;
+    Bool		useDefaultFontPath;
+    MessageType		useDefaultFontPathFrom;
     Bool        ignoreABI;
     struct {
 	Bool		disabled;		/* enable/disable deactivating
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index f964282..f2cb5ef 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -604,6 +604,11 @@ the builtin handler will be used.
 .BI "Option \*qAIGLX\*q \*q" boolean \*q
 enable or disable AIGLX. AIGLX is enabled by default.
 .TP 7
+.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
+Include the default font path even if other paths are specified in
+xorg.conf. If enabled, other font paths are included as well. Enabled by
+default.
+.TP 7
 .BI "Option \*qIgnoreABI\*q \*q" boolean \*q
 Allow modules built for a different, potentially incompatible version of
 the X server to load. Disabled by default.
diff-tree e91b9ddc7aa95abc2d4d314e8db204860771a099 (from d2f813f7db157fc83abc4b3726821c36ee7e40b1)
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu May 3 22:00:23 2007 -0400

    Improve modules loading defaults
    
    Provide default modules that may be overrided easily. Previously the
    server would load a set of default modules, but only if none were
    specified in the xorg.conf, or if you didn't have a xorg.conf at all. This
    patch provides a default set and you can add only the "Load" instructions
    to xorg.conf that you want without losing the defaults. Similarly, if you
    don't want to load a module that's loaded by default, you can add "Disable
    modulename" to your xorg.conf (see man xorg.conf in this release for
    details). This allows for a minimal "Modules" section, where the user only
    need specify what they want to be different. See bug #10541 for more.
    
    The list of default modules is taken from the set loaded by default when
    there was a xorg.conf containing no "Modules" section.
    
    A potential problem for some users is that some users disable a module,
    most notably DRI, by commenting out the "Load" line in their xorg.conf.
    This needs to be changed to an uncommented "Disable" line, as DRI is
    loaded by default.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 0421bf9..301b17c 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -254,6 +254,7 @@ xf86ModulelistFromConfig(pointer **optli
     char *ignore[] = { "GLcore", "speedo", "bitmap", "drm", NULL };
     pointer *optarray;
     XF86LoadPtr modp;
+    Bool found;
     
     /*
      * make sure the config file has been parsed and that we have a
@@ -266,35 +267,73 @@ xf86ModulelistFromConfig(pointer **optli
     }
     
     if (xf86configptr->conf_modules) {
-	/*
-	 * Walk the list of modules in the "Module" section to determine how
-	 * many we have.
-	 */
-	modp = xf86configptr->conf_modules->mod_load_lst;
-	while (modp) {
-            for (i = 0; ignore[i]; i++) {
-                if (strcmp(modp->load_name, ignore[i]) == 0)
-                    modp->ignore = 1;
+        /* Walk the disable list and let people know what we've parsed to
+         * not be loaded 
+         */
+        modp = xf86configptr->conf_modules->mod_disable_lst;
+        while (modp) {
+            xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
+	        modp = (XF86LoadPtr) modp->list.next;
+        }
+        /*
+         * Walk the default settings table. For each module listed to be
+         * loaded, make sure it's in the mod_load_lst. If it's not, make
+         * sure it's not in the mod_no_load_lst. If it's not disabled,
+         * append it to mod_load_lst
+         */
+         for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+            if (ModuleDefaults[i].toLoad == FALSE) {
+                xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
+                continue;
             }
-            if (!modp->ignore)
-	        count++;
-	    modp = (XF86LoadPtr) modp->list.next;
-	}
+            found = FALSE;
+            modp = xf86configptr->conf_modules->mod_load_lst;
+            while (modp) {
+                if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+                    found = TRUE;
+                    break;
+                }
+	        modp = (XF86LoadPtr) modp->list.next;
+            }
+            if (found == FALSE) {
+                modp = xf86configptr->conf_modules->mod_disable_lst;
+                while (modp) {
+                    if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+                        found = TRUE;
+                        break;
+                    }
+	                modp = (XF86LoadPtr) modp->list.next;
+                }
+            }
+            if (found == FALSE) {
+	            XF86ConfModulePtr ptr = xf86configptr->conf_modules;
+	            ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+            }
+         }
     } else {
 	xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
+	for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+	    if (ModuleDefaults[i].toLoad == TRUE) {
+		XF86ConfModulePtr ptr = xf86configptr->conf_modules;
+		ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+	    }
+	}
     }
 
-    if (count == 0) {
-	XF86ConfModulePtr ptr = xf86configptr->conf_modules;
-	ptr = xf86addNewLoadDirective(ptr, "extmod", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "dbe", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "glx", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "freetype", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "type1", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "record", XF86_LOAD_MODULE, NULL);
-	ptr = xf86addNewLoadDirective(ptr, "dri", XF86_LOAD_MODULE, NULL);
-	count = 7;
-    }
+	    /*
+	     * Walk the list of modules in the "Module" section to determine how
+	     * many we have.
+	    */
+	    modp = xf86configptr->conf_modules->mod_load_lst;
+	    while (modp) {
+                for (i = 0; ignore[i]; i++) {
+                    if (strcmp(modp->load_name, ignore[i]) == 0)
+                        modp->ignore = 1;
+                }
+                if (!modp->ignore)
+	            count++;
+	        modp = (XF86LoadPtr) modp->list.next;
+	    }
 
     /*
      * allocate the memory and walk the list again to fill in the pointers
@@ -303,22 +342,22 @@ xf86ModulelistFromConfig(pointer **optli
     optarray = xnfalloc((count + 1) * sizeof(pointer));
     count = 0;
     if (xf86configptr->conf_modules) {
-	modp = xf86configptr->conf_modules->mod_load_lst;
-	while (modp) {
+	    modp = xf86configptr->conf_modules->mod_load_lst;
+	    while (modp) {
             if (!modp->ignore) {
-	        modulearray[count] = modp->load_name;
-	        optarray[count] = modp->load_opt;
-	        count++;
+	            modulearray[count] = modp->load_name;
+	            optarray[count] = modp->load_opt;
+	            count++;
             }
-	    modp = (XF86LoadPtr) modp->list.next;
-	}
+	        modp = (XF86LoadPtr) modp->list.next;
+	    }
     }
     modulearray[count] = NULL;
     optarray[count] = NULL;
     if (optlist)
-	*optlist = optarray;
+	    *optlist = optarray;
     else
-	xfree(optarray);
+	    xfree(optarray);
     return modulearray;
 }
 
diff --git a/hw/xfree86/common/xf86Config.h b/hw/xfree86/common/xf86Config.h
index 3787ba2..7fc161d 100644
--- a/hw/xfree86/common/xf86Config.h
+++ b/hw/xfree86/common/xf86Config.h
@@ -33,6 +33,8 @@
 #ifndef _xf86_config_h
 #define _xf86_config_h
 
+#include "xf86Optrec.h"
+
 #ifdef HAVE_PARSER_DECLS
 /*
  * global structure that holds the result of parsing the config file
@@ -46,6 +48,23 @@ typedef enum _ConfigStatus {
     CONFIG_NOFILE
 } ConfigStatus;
 
+typedef struct _ModuleDefault {
+    char *name;
+    Bool toLoad;
+    XF86OptionPtr load_opt;
+} ModuleDefault;
+
+static ModuleDefault ModuleDefaults[] = {
+    {.name = "extmod",   .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "dbe",      .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "glx",      .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "freetype", .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "type1",    .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "record",   .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "dri",      .toLoad = TRUE,    .load_opt=NULL},
+    {.name = NULL,       .toLoad = FALSE,   .load_opt=NULL}
+};
+
 /*
  * prototypes
  */
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index 19315c0..f964282 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -639,6 +639,20 @@ Example: the Type 1 font rasteriser can 
 .B "Load \*qtype1\*q"
 .RE
 .RE
+.TP 7
+.BI "Disable  \*q" modulename \*q
+This instructs the server to not load the module called
+.IR modulename .
+Some modules are loaded by default in the server, and this overrides that
+default. If a
+.B Load
+instruction is given for the same module, it overrides the 
+.B Disable
+instruction and the module is loaded. The module name given should be the
+module's standard name, not the module file name. As with the
+.B Load
+instruction, the standard name is case-sensitive, and does not include the
+"lib" prefix, or the ".a", ".o", or ".so" suffixes.
 .PP
 The second form of entry is a
 .BR SubSection,
diff --git a/hw/xfree86/parser/Module.c b/hw/xfree86/parser/Module.c
index 81eff18..2012ce6 100644
--- a/hw/xfree86/parser/Module.c
+++ b/hw/xfree86/parser/Module.c
@@ -76,6 +76,7 @@ static xf86ConfigSymTabRec ModuleTab[] =
 {
 	{ENDSECTION, "endsection"},
 	{LOAD, "load"},
+    {DISABLE, "disable"}, 
 	{LOAD_DRIVER, "loaddriver"},
 	{SUBSECTION, "subsection"},
 	{-1, ""},
@@ -141,6 +142,13 @@ xf86parseModuleSection (void)
 				xf86addNewLoadDirective (ptr->mod_load_lst, val.str,
 									 XF86_LOAD_MODULE, NULL);
 			break;
+		case DISABLE:
+			if (xf86getSubToken (&(ptr->mod_comment)) != STRING)
+				Error (QUOTE_MSG, "Disable");
+			ptr->mod_disable_lst =
+				xf86addNewLoadDirective (ptr->mod_disable_lst, val.str,
+									 XF86_DISABLE_MODULE, NULL);
+			break;
 		case LOAD_DRIVER:
 			if (xf86getSubToken (&(ptr->mod_comment)) != STRING)
 				Error (QUOTE_MSG, "LoadDriver");
@@ -257,6 +265,15 @@ xf86freeModules (XF86ConfModulePtr ptr)
 		lptr = lptr->list.next;
 		xf86conffree (prev);
 	}
+	lptr = ptr->mod_disable_lst;
+	while (lptr)
+	{
+		TestFree (lptr->load_name);
+		TestFree (lptr->load_comment);
+		prev = lptr;
+		lptr = lptr->list.next;
+		xf86conffree (prev);
+	}
 	TestFree (ptr->mod_comment);
 	xf86conffree (ptr);
 }
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 89de97b..dc30823 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -82,6 +82,7 @@ XF86ConfFilesRec, *XF86ConfFilesPtr;
 /* Values for load_type */
 #define XF86_LOAD_MODULE	0
 #define XF86_LOAD_DRIVER	1
+#define XF86_DISABLE_MODULE	2
 
 typedef struct
 {
@@ -97,6 +98,7 @@ XF86LoadRec, *XF86LoadPtr;
 typedef struct
 {
 	XF86LoadPtr mod_load_lst;
+    XF86LoadPtr mod_disable_lst;
 	char *mod_comment;
 }
 XF86ConfModuleRec, *XF86ConfModulePtr;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index d5948dd..822bbb9 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -170,6 +170,7 @@ typedef enum {
     /* Module tokens */
     LOAD,
     LOAD_DRIVER,
+    DISABLE,
     
     /* Device tokens */
     DRIVER,
diff-tree d2f813f7db157fc83abc4b3726821c36ee7e40b1 (from e0959adcd8df2c61e98e76e708fceef9c7cd54eb)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed May 2 19:10:22 2007 -0400

    New fbWalkCompositeRegion() function
    
    This new function walks the composite region and calls a rectangle
    compositing function on each compositing rectangle. Previously there
    were buggy duplicates of this code in fbcompose.c and
    miext/rootles/safealpha/safeAlphaPicture.c.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 6e49893..dd2a2f0 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -4308,107 +4308,9 @@ fbCompositeGeneral (CARD8	op,
 		    CARD16	width,
 		    CARD16	height)
 {
-    RegionRec	    region;
-    int		    n;
-    BoxPtr	    pbox;
-    Bool	    srcRepeat = FALSE;
-    Bool	    maskRepeat = FALSE;
-    int		    w, h;
-    CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3];
-    CARD32 *scanline_buffer = _scanline_buffer;
-    FbComposeData compose_data;
-    
-    if (pSrc->pDrawable)
-        srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
-	    && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
-
-    if (pMask && pMask->pDrawable)
-	maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
-	    && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
-
-    if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
-        op = PictOpSrc;
-
-    if (!miComputeCompositeRegion (&region,
-				   pSrc,
-				   pMask,
-				   pDst,
-				   xSrc,
-				   ySrc,
-				   xMask,
-				   yMask,
-				   xDst,
-				   yDst,
-				   width,
-				   height))
-	return;
-
-    compose_data.op = op;
-    compose_data.src = pSrc;
-    compose_data.mask = pMask;
-    compose_data.dest = pDst;
-    if (width > SCANLINE_BUFFER_LENGTH)
-        scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
-
-    n = REGION_NUM_RECTS (&region);
-    pbox = REGION_RECTS (&region);
-    while (n--)
-    {
-	h = pbox->y2 - pbox->y1;
-	compose_data.ySrc = pbox->y1 - yDst + ySrc;
-	compose_data.yMask = pbox->y1 - yDst + yMask;
-	compose_data.yDest = pbox->y1;
-	while (h)
-	{
-	    compose_data.height = h;
-	    w = pbox->x2 - pbox->x1;
-	    compose_data.xSrc = pbox->x1 - xDst + xSrc;
-	    compose_data.xMask = pbox->x1 - xDst + xMask;
-	    compose_data.xDest = pbox->x1;
-	    if (maskRepeat)
-	    {
-		compose_data.yMask = mod (compose_data.yMask, pMask->pDrawable->height);
-		if (compose_data.height > pMask->pDrawable->height - compose_data.yMask)
-		    compose_data.height = pMask->pDrawable->height - compose_data.yMask;
-	    }
-	    if (srcRepeat)
-	    {
-		compose_data.ySrc = mod (compose_data.ySrc, pSrc->pDrawable->height);
-		if (compose_data.height > pSrc->pDrawable->height - compose_data.ySrc)
-		    compose_data.height = pSrc->pDrawable->height - compose_data.ySrc;
-	    }
-	    while (w)
-	    {
-		compose_data.width = w;
-		if (maskRepeat)
-		{
-		    compose_data.xMask = mod (compose_data.xMask, pMask->pDrawable->width);
-		    if (compose_data.width > pMask->pDrawable->width - compose_data.xMask)
-			compose_data.width = pMask->pDrawable->width - compose_data.xMask;
-		}
-		if (srcRepeat)
-		{
-		    compose_data.xSrc = mod (compose_data.xSrc, pSrc->pDrawable->width);
-		    if (compose_data.width > pSrc->pDrawable->width - compose_data.xSrc)
-			compose_data.width = pSrc->pDrawable->width - compose_data.xSrc;
-		}
-		fbCompositeRect(&compose_data, scanline_buffer);
-		w -= compose_data.width;
-		compose_data.xSrc += compose_data.width;
-		compose_data.xMask += compose_data.width;
-		compose_data.xDest += compose_data.width;
-	    }
-	    h -= compose_data.height;
-	    compose_data.ySrc += compose_data.height;
-	    compose_data.yMask += compose_data.height;
-	    compose_data.yDest += compose_data.height;
-	}
-	pbox++;
-    }
-    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
-
-    if (scanline_buffer != _scanline_buffer)
-        free(scanline_buffer);
+    return fbComposite (op, pSrc, pMask, pDst,
+			xSrc, ySrc, xMask, yMask, xDst, yDst,
+			width, height);
 }
 
 #endif
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 819d21a..7d94d00 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -37,19 +37,6 @@
 #include "fbpict.h"
 #include "fbmmx.h"
 
-typedef void	(*CompositeFunc) (CARD8      op,
-				  PicturePtr pSrc,
-				  PicturePtr pMask,
-				  PicturePtr pDst,
-				  INT16      xSrc,
-				  INT16      ySrc,
-				  INT16      xMask,
-                                  INT16      yMask,
-				  INT16      xDst,
-				  INT16      yDst,
-				  CARD16     width,
-				  CARD16     height);
-
 CARD32
 fbOver (CARD32 x, CARD32 y)
 {
@@ -1478,6 +1465,110 @@ fbCompositeRectWrapper  (CARD8	   op,
 }
 
 void
+fbWalkCompositeRegion (CARD8 op,
+		       PicturePtr pSrc,
+		       PicturePtr pMask,
+		       PicturePtr pDst,
+		       INT16 xSrc,
+		       INT16 ySrc,
+		       INT16 xMask,
+		       INT16 yMask,
+		       INT16 xDst,
+		       INT16 yDst,
+		       CARD16 width,
+		       CARD16 height,
+		       Bool srcRepeat,
+		       Bool maskRepeat,
+		       CompositeFunc compositeRect)
+{
+    RegionRec	    region;
+    int		    n;
+    BoxPtr	    pbox;
+    int		    w, h, w_this, h_this;
+    int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;
+    
+    xDst += pDst->pDrawable->x;
+    yDst += pDst->pDrawable->y;
+    if (pSrc->pDrawable)
+    {
+        xSrc += pSrc->pDrawable->x;
+        ySrc += pSrc->pDrawable->y;
+    }
+    if (pMask && pMask->pDrawable)
+    {
+	xMask += pMask->pDrawable->x;
+	yMask += pMask->pDrawable->y;
+    }
+
+    if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
+				   xMask, yMask, xDst, yDst, width, height))
+        return;
+
+    n = REGION_NUM_RECTS (&region);
+    pbox = REGION_RECTS (&region);
+    while (n--)
+    {
+	h = pbox->y2 - pbox->y1;
+	y_src = pbox->y1 - yDst + ySrc;
+	y_msk = pbox->y1 - yDst + yMask;
+	y_dst = pbox->y1;
+	while (h)
+	{
+	    h_this = h;
+	    w = pbox->x2 - pbox->x1;
+	    x_src = pbox->x1 - xDst + xSrc;
+	    x_msk = pbox->x1 - xDst + xMask;
+	    x_dst = pbox->x1;
+	    if (maskRepeat)
+	    {
+		y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
+		if (h_this > pMask->pDrawable->height - y_msk)
+		    h_this = pMask->pDrawable->height - y_msk;
+		y_msk += pMask->pDrawable->y;
+	    }
+	    if (srcRepeat)
+	    {
+		y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
+		if (h_this > pSrc->pDrawable->height - y_src)
+		    h_this = pSrc->pDrawable->height - y_src;
+		y_src += pSrc->pDrawable->y;
+	    }
+	    while (w)
+	    {
+		w_this = w;
+		if (maskRepeat)
+		{
+		    x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
+		    if (w_this > pMask->pDrawable->width - x_msk)
+			w_this = pMask->pDrawable->width - x_msk;
+		    x_msk += pMask->pDrawable->x;
+		}
+		if (srcRepeat)
+		{
+		    x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
+		    if (w_this > pSrc->pDrawable->width - x_src)
+			w_this = pSrc->pDrawable->width - x_src;
+		    x_src += pSrc->pDrawable->x;
+		}
+		(*compositeRect) (op, pSrc, pMask, pDst,
+				  x_src, y_src, x_msk, y_msk, x_dst, y_dst,
+				  w_this, h_this);
+		w -= w_this;
+		x_src += w_this;
+		x_msk += w_this;
+		x_dst += w_this;
+	    }
+	    h -= h_this;
+	    y_src += h_this;
+	    y_msk += h_this;
+	    y_dst += h_this;
+	}
+	pbox++;
+    }
+    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
+}
+
+void
 fbComposite (CARD8      op,
 	     PicturePtr pSrc,
 	     PicturePtr pMask,
@@ -1491,10 +1582,6 @@ fbComposite (CARD8      op,
 	     CARD16     width,
 	     CARD16     height)
 {
-    RegionRec	    region;
-    int		    n;
-    BoxPtr	    pbox;
-    CompositeFunc   func = NULL;
     Bool	    srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
     Bool	    maskRepeat = FALSE;
     Bool	    srcTransform = pSrc->transform != 0;
@@ -1502,8 +1589,7 @@ fbComposite (CARD8      op,
     Bool	    srcAlphaMap = pSrc->alphaMap != 0;
     Bool	    maskAlphaMap = FALSE;
     Bool	    dstAlphaMap = pDst->alphaMap != 0;
-    int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;
-    int		    w, h, w_this, h_this;
+    CompositeFunc   func = NULL;
 
 #ifdef USE_MMX
     static Bool mmx_setup = FALSE;
@@ -1513,13 +1599,6 @@ fbComposite (CARD8      op,
     }
 #endif
 
-    xDst += pDst->pDrawable->x;
-    yDst += pDst->pDrawable->y;
-    if (pSrc->pDrawable) {
-        xSrc += pSrc->pDrawable->x;
-        ySrc += pSrc->pDrawable->y;
-    }
-
     if (srcRepeat && srcTransform &&
 	pSrc->pDrawable->width == 1 &&
 	pSrc->pDrawable->height == 1)
@@ -1527,8 +1606,6 @@ fbComposite (CARD8      op,
     
     if (pMask && pMask->pDrawable)
     {
-	xMask += pMask->pDrawable->x;
-	yMask += pMask->pDrawable->y;
 	maskRepeat = pMask->repeatType == RepeatNormal;
 
 	if (pMask->filter == PictFilterConvolution)
@@ -1688,7 +1765,8 @@ fbComposite (CARD8      op,
 	    else if (!srcRepeat) /* has mask and non-repeating source */
 	    {
 		if (pSrc->pDrawable == pMask->pDrawable &&
-		    xSrc == xMask && ySrc == yMask &&
+		    xSrc + pSrc->pDrawable->x == xMask + pMask->pDrawable->x &&
+		    ySrc + pSrc->pDrawable->y == yMask + pMask->pDrawable->y &&
 		    !pMask->componentAlpha && !maskRepeat)
 		{
 		    /* source == mask: non-premultiplied data */
@@ -2091,73 +2169,10 @@ fbComposite (CARD8      op,
 	srcRepeat = FALSE;
     if (maskTransform)
 	maskRepeat = FALSE;
-    
-    if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
-				   xMask, yMask, xDst, yDst, width, height))
-        return;
 
-    n = REGION_NUM_RECTS (&region);
-    pbox = REGION_RECTS (&region);
-    while (n--)
-    {
-	h = pbox->y2 - pbox->y1;
-	y_src = pbox->y1 - yDst + ySrc;
-	y_msk = pbox->y1 - yDst + yMask;
-	y_dst = pbox->y1;
-	while (h)
-	{
-	    h_this = h;
-	    w = pbox->x2 - pbox->x1;
-	    x_src = pbox->x1 - xDst + xSrc;
-	    x_msk = pbox->x1 - xDst + xMask;
-	    x_dst = pbox->x1;
-	    if (maskRepeat)
-	    {
-		y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
-		if (h_this > pMask->pDrawable->height - y_msk)
-		    h_this = pMask->pDrawable->height - y_msk;
-		y_msk += pMask->pDrawable->y;
-	    }
-	    if (srcRepeat)
-	    {
-		y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
-		if (h_this > pSrc->pDrawable->height - y_src)
-		    h_this = pSrc->pDrawable->height - y_src;
-		y_src += pSrc->pDrawable->y;
-	    }
-	    while (w)
-	    {
-		w_this = w;
-		if (maskRepeat)
-		{
-		    x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
-		    if (w_this > pMask->pDrawable->width - x_msk)
-			w_this = pMask->pDrawable->width - x_msk;
-		    x_msk += pMask->pDrawable->x;
-		}
-		if (srcRepeat)
-		{
-		    x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
-		    if (w_this > pSrc->pDrawable->width - x_src)
-			w_this = pSrc->pDrawable->width - x_src;
-		    x_src += pSrc->pDrawable->x;
-		}
-		(*func) (op, pSrc, pMask, pDst,
-			 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
-			 w_this, h_this);
-		w -= w_this;
-		x_src += w_this;
-		x_msk += w_this;
-		x_dst += w_this;
-	    }
-	    h -= h_this;
-	    y_src += h_this;
-	    y_msk += h_this;
-	    y_dst += h_this;
-	}
-	pbox++;
-    }
-    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
+    fbWalkCompositeRegion (op, pSrc, pMask, pDst, xSrc, ySrc,
+			   xMask, yMask, xDst, yDst, width, height,
+			   srcRepeat, maskRepeat, func);
 }
 
 #endif /* RENDER */
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 86f271e..11cab3d 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -630,6 +630,36 @@ fbComposite (CARD8      op,
 	     CARD16     width,
 	     CARD16     height);
 
+typedef void	(*CompositeFunc) (CARD8      op,
+				  PicturePtr pSrc,
+				  PicturePtr pMask,
+				  PicturePtr pDst,
+				  INT16      xSrc,
+				  INT16      ySrc,
+				  INT16      xMask,
+                                  INT16      yMask,
+				  INT16      xDst,
+				  INT16      yDst,
+				  CARD16     width,
+				  CARD16     height);
+
+void
+fbWalkCompositeRegion (CARD8 op,
+		       PicturePtr pSrc,
+		       PicturePtr pMask,
+		       PicturePtr pDst,
+		       INT16 xSrc,
+		       INT16 ySrc,
+		       INT16 xMask,
+		       INT16 yMask,
+		       INT16 xDst,
+		       INT16 yDst,
+		       CARD16 width,
+		       CARD16 height,
+		       Bool srcRepeat,
+		       Bool maskRepeat,
+		       CompositeFunc compositeRect);
+
 /* fbtrap.c */
 
 void
diff --git a/miext/rootless/safeAlpha/safeAlphaPicture.c b/miext/rootless/safeAlpha/safeAlphaPicture.c
index 6ccc05a..0ed2f3e 100644
--- a/miext/rootless/safeAlpha/safeAlphaPicture.c
+++ b/miext/rootless/safeAlpha/safeAlphaPicture.c
@@ -46,22 +46,6 @@
 #include "fbpict.h"
 #include "safeAlpha.h"
 #include "rootlessCommon.h"
-# define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
-
-
-typedef void	(*CompositeFunc) (CARD8      op,
-				  PicturePtr pSrc,
-				  PicturePtr pMask,
-				  PicturePtr pDst,
-				  INT16      xSrc,
-				  INT16      ySrc,
-				  INT16      xMask,
-                                  INT16      yMask,
-				  INT16      xDst,
-				  INT16      yDst,
-				  CARD16     width,
-				  CARD16     height);
-
 
 /* Optimized version of fbCompositeSolidMask_nx8x8888 */
 void
@@ -148,46 +132,22 @@ SafeAlphaCompositeSolidMask_nx8x8888(
 }
 
 void
-SafeAlphaComposite (CARD8      op,
-    PicturePtr      pSrc,
-    PicturePtr      pMask,
-    PicturePtr      pDst,
-    INT16           xSrc,
-    INT16           ySrc,
-    INT16           xMask,
-    INT16           yMask,
-    INT16           xDst,
-    INT16           yDst,
-    CARD16          width,
-    CARD16          height)
+SafeAlphaComposite (CARD8           op,
+		    PicturePtr      pSrc,
+		    PicturePtr      pMask,
+		    PicturePtr      pDst,
+		    INT16           xSrc,
+		    INT16           ySrc,
+		    INT16           xMask,
+		    INT16           yMask,
+		    INT16           xDst,
+		    INT16           yDst,
+		    CARD16          width,
+		    CARD16          height)
 {
-    RegionRec	    region;
-    int		    n;
-    BoxPtr	    pbox;
-    CompositeFunc   func = 0;
-    Bool	    srcRepeat = pSrc->repeat;
-    Bool	    maskRepeat = FALSE;
-    Bool            srcAlphaMap = pSrc->alphaMap != 0;
-    Bool	    maskAlphaMap = FALSE;
-    Bool            dstAlphaMap = pDst->alphaMap != 0;
-    int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;
-    int		    w, h, w_this, h_this;
-    int		    dstDepth = pDst->pDrawable->depth;
-    int		    oldFormat = pDst->format;
-
-    xDst += pDst->pDrawable->x;
-    yDst += pDst->pDrawable->y;
-    xSrc += pSrc->pDrawable->x;
-    ySrc += pSrc->pDrawable->y;
-    if (pMask)
-    {
-	xMask += pMask->pDrawable->x;
-	yMask += pMask->pDrawable->y;
-	maskRepeat = pMask->repeat;
-	maskAlphaMap = pMask->alphaMap != 0;
-    }
-
-
+    int oldDepth = pDst->pDrawable->depth;
+    int oldFormat = pDst->format;
+    
     /*
      * We can use the more optimized fbpict code, but it sets bits above
      * the depth to zero. Temporarily adjust destination depth if needed.
@@ -198,6 +158,7 @@ SafeAlphaComposite (CARD8      op,
     {
 	pDst->pDrawable->depth = 32;
     }
+    
     /* For rootless preserve the alpha in x8r8g8b8 which really is
      * a8r8g8b8
      */
@@ -205,441 +166,34 @@ SafeAlphaComposite (CARD8      op,
     {
         pDst->format = PICT_a8r8g8b8;
     }
-
-
-
-    if (!pSrc->transform && !(pMask && pMask->transform))
-    if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
-    switch (op) {
-    case PictOpSrc:
-#ifdef USE_MMX
-	if (!pMask && pSrc->format == pDst->format &&
-	    pSrc->pDrawable != pDst->pDrawable)
-	{
-	    func = fbCompositeCopyAreammx;
-	}
-#endif
-	break;
-    case PictOpOver:
-	if (pMask)
-	{
-	    if (srcRepeat && 
-		pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1)
-	    {
-		srcRepeat = FALSE;
-		if (PICT_FORMAT_COLOR(pSrc->format)) {
-		    switch (pMask->format) {
-		    case PICT_a8:
-			switch (pDst->format) {
-			case PICT_r5g6b5:
-			case PICT_b5g6r5:
-#ifdef USE_MMX
-			    if (fbHaveMMX())
-				func = fbCompositeSolidMask_nx8x0565mmx;
-			    else
-#endif
-			    func = fbCompositeSolidMask_nx8x0565;
-			    break;
-			case PICT_r8g8b8:
-			case PICT_b8g8r8:
-			    func = fbCompositeSolidMask_nx8x0888;
-			    break;
-			case PICT_a8r8g8b8:
-			case PICT_x8r8g8b8:
-			case PICT_a8b8g8r8:
-			case PICT_x8b8g8r8:
-			    func = SafeAlphaCompositeSolidMask_nx8x8888;
-			    break;
-			}
-			break;
-		    case PICT_a8r8g8b8:
-			if (pMask->componentAlpha) {
-			    switch (pDst->format) {
-			    case PICT_a8r8g8b8:
-			    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x8888Cmmx;
-				else
-#endif
-				func = fbCompositeSolidMask_nx8888x8888C;
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x0565Cmmx;
-				else
-#endif
-				func = fbCompositeSolidMask_nx8888x0565C;
-				break;
-			    }
-			}
-			break;
-		    case PICT_a8b8g8r8:
-			if (pMask->componentAlpha) {
-			    switch (pDst->format) {
-			    case PICT_a8b8g8r8:
-			    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x8888Cmmx;
-				else
-#endif
-				func = fbCompositeSolidMask_nx8888x8888C;
-				break;
-			    case PICT_b5g6r5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSolidMask_nx8888x0565Cmmx;
-				else
-#endif
-				func = fbCompositeSolidMask_nx8888x0565C;
-				break;
-			    }
-			}
-			break;
-		    case PICT_a1:
-			switch (pDst->format) {
-			case PICT_r5g6b5:
-			case PICT_b5g6r5:
-			case PICT_r8g8b8:
-			case PICT_b8g8r8:
-			case PICT_a8r8g8b8:
-			case PICT_x8r8g8b8:
-			case PICT_a8b8g8r8:
-			case PICT_x8b8g8r8:
-			    func = fbCompositeSolidMask_nx1xn;
-			    break;
-			}
-			break;
-		    }
-		}
-	    }
-	    else /* has mask and non-repeating source */
-	    {
-		if (pSrc->pDrawable == pMask->pDrawable &&
-		    xSrc == xMask && ySrc == yMask &&
-		    !pMask->componentAlpha)
-		{
-		    /* source == mask: non-premultiplied data */
-		    switch (pSrc->format) {
-		    case PICT_x8b8g8r8:
-			switch (pMask->format) {
-			case PICT_a8r8g8b8:
-			case PICT_a8b8g8r8:
-			    switch (pDst->format) {
-			    case PICT_a8r8g8b8:
-			    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx8888mmx;
-#endif
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx0565mmx;
-#endif
-				break;
-			    }
-			    break;
-			}
-			break;
-		    case PICT_x8r8g8b8:
-			switch (pMask->format) {
-			case PICT_a8r8g8b8:
-			case PICT_a8b8g8r8:
-			    switch (pDst->format) {
-			    case PICT_a8b8g8r8:
-			    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx8888mmx;
-#endif
-				break;
-			    case PICT_r5g6b5:
-#ifdef USE_MMX
-				if (fbHaveMMX())
-				    func = fbCompositeSrc_8888RevNPx0565mmx;
-#endif
-				break;
-			    }
-			    break;
-			}
-			break;
-		    }
-		    break;
-	}
-	else
-	{
-		    /* non-repeating source, repeating mask => translucent window */
-		    if (maskRepeat &&
-			pMask->pDrawable->width == 1 &&
-			pMask->pDrawable->height == 1)
-		    {
-			if (pSrc->format == PICT_x8r8g8b8 &&
-			    pDst->format == PICT_x8r8g8b8 &&
-			    pMask->format == PICT_a8)
-			{
-#ifdef USE_MMX
-			    if (fbHaveMMX())
-				func = fbCompositeSrc_8888x8x8888mmx;
-#endif
-			}
-		    }
-		}
-	    }
-	}
-	else /* no mask */
-	{
-	    if (srcRepeat &&
-		pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1)
-	    {
-		/* no mask and repeating source */
-	    switch (pSrc->format) {
-	    case PICT_a8r8g8b8:
-		    switch (pDst->format) {
-		    case PICT_a8r8g8b8:
-	    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			{
-			    srcRepeat = FALSE;
-			    func = fbCompositeSolid_nx8888mmx;
-			}
-#endif
-			break;
-		    case PICT_r5g6b5:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			{
-			    srcRepeat = FALSE;
-			    func = fbCompositeSolid_nx0565mmx;
-			}
-#endif
-			break;
-		    }
-		    break;
-		}
-	    }
-	    else
-	    {
-		switch (pSrc->format) {
-		case PICT_a8r8g8b8:
-		switch (pDst->format) {
-		case PICT_a8r8g8b8:
-		case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x8888mmx;
-			else
-#endif
-		    func = fbCompositeSrc_8888x8888;
-		    break;
-		case PICT_r8g8b8:
-		    func = fbCompositeSrc_8888x0888;
-		    break;
-		case PICT_r5g6b5:
-		    func = fbCompositeSrc_8888x0565;
-		    break;
-		}
-		break;
-		case PICT_x8r8g8b8:
-		    switch (pDst->format) {
-		    case PICT_a8r8g8b8:
-		    case PICT_x8r8g8b8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeCopyAreammx;
-#endif
-			break;
-		    }
-		case PICT_x8b8g8r8:
-		    switch (pDst->format) {
-	    case PICT_a8b8g8r8:
-	    case PICT_x8b8g8r8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeCopyAreammx;
-#endif
-			break;
-		    }
-		    break;
-		case PICT_a8b8g8r8:
-		switch (pDst->format) {
-		case PICT_a8b8g8r8:
-		case PICT_x8b8g8r8:
-#ifdef USE_MMX
-			if (fbHaveMMX())
-			    func = fbCompositeSrc_8888x8888mmx;
-			else
-#endif
-		    func = fbCompositeSrc_8888x8888;
-		    break;
-		case PICT_b8g8r8:
-		    func = fbCompositeSrc_8888x0888;
-		    break;
-		case PICT_b5g6r5:
-		    func = fbCompositeSrc_8888x0565;
-		    break;
-		}
-		break;
-	    case PICT_r5g6b5:
-		switch (pDst->format) {
-		case PICT_r5g6b5:
-		    func = fbCompositeSrc_0565x0565;
-		    break;
-		}
-		break;
-	    case PICT_b5g6r5:
-		switch (pDst->format) {
-		case PICT_b5g6r5:
-		    func = fbCompositeSrc_0565x0565;
-		    break;
-		}
-		break;
-	    }
-	}
-	}
-	break;
-    case PictOpAdd:
-	if (pMask == 0)
-	{
-	    switch (pSrc->format) {
-	    case PICT_a8r8g8b8:
-		switch (pDst->format) {
-		case PICT_a8r8g8b8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8888x8888mmx;
-		    else
-#endif
-		    func = fbCompositeSrcAdd_8888x8888;
-		    break;
-		}
-		break;
-	    case PICT_a8b8g8r8:
-		switch (pDst->format) {
-		case PICT_a8b8g8r8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8888x8888mmx;
-		    else
-#endif
-		    func = fbCompositeSrcAdd_8888x8888;
-		    break;
-		}
-		break;
-	    case PICT_a8:
-		switch (pDst->format) {
-		case PICT_a8:
-#ifdef USE_MMX
-		    if (fbHaveMMX())
-			func = fbCompositeSrcAdd_8000x8000mmx;
-		    else
-#endif
-		    func = fbCompositeSrcAdd_8000x8000;
-		    break;
-		}
-		break;
-	    case PICT_a1:
-		switch (pDst->format) {
-		case PICT_a1:
-		    func = fbCompositeSrcAdd_1000x1000;
-		    break;
-		}
-		break;
-	    }
-	}
-	break;
-    }
-
-    if (!func) {
-        /* no fast path, use the general code */
-        fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
-        // Reset destination depth and format to their true value
-        pDst->pDrawable->depth = dstDepth;
-        pDst->format = oldFormat;
-        return;
+    
+    if (pSrc->pDrawable && pMask->pDrawable &&
+	!pSrc->transform && !pMask->transform &&
+	!pSrc->alphaMap && !pMask->alphaMap &&
+	!pMask->repeat && !pMask->componentAlpha && !pDst->alphaMap &&
+	pMask->format == PICT_a8 &&
+	pSrc->repeatType == RepeatNormal && 
+	pSrc->pDrawable->width == 1 &&
+	pSrc->pDrawable->height == 1 &&
+	(pDst->format == PICT_a8r8g8b8 ||
+	 pDst->format == PICT_x8r8g8b8 ||
+	 pDst->format == PICT_a8b8g8r8 ||
+	 pDst->format == PICT_x8b8g8r8))
+    {
+	fbWalkCompositeRegion (op, pSrc, pMask, pDst,
+			       xSrc, ySrc, xMask, yMask, xDst, yDst,
+			       width, height,
+			       TRUE /* srcRepeat */,
+			       FALSE /* maskRepeat */,
+			       SafeAlphaCompositeSolidMask_nx8x8888);
     }
-
-    if (!miComputeCompositeRegion (&region,
- 				   pSrc,
- 				   pMask,
- 				   pDst,
- 				   xSrc,
- 				   ySrc,
- 				   xMask,
- 				   yMask,
- 				   xDst,
- 				   yDst,
- 				   width,
-                                   height))
-        return;
-
-    n = REGION_NUM_RECTS (&region);
-    pbox = REGION_RECTS (&region);
-    while (n--)
+    else
     {
-	h = pbox->y2 - pbox->y1;
-	y_src = pbox->y1 - yDst + ySrc;
-	y_msk = pbox->y1 - yDst + yMask;
-	y_dst = pbox->y1;
-	while (h)
-	{
-	    h_this = h;
-	    w = pbox->x2 - pbox->x1;
-	    x_src = pbox->x1 - xDst + xSrc;
-	    x_msk = pbox->x1 - xDst + xMask;
-	    x_dst = pbox->x1;
-	    if (maskRepeat)
-	    {
-		y_msk = mod (y_msk, pMask->pDrawable->height);
-		if (h_this > pMask->pDrawable->height - y_msk)
-		    h_this = pMask->pDrawable->height - y_msk;
-	    }
-	    if (srcRepeat)
-	    {
-		y_src = mod (y_src, pSrc->pDrawable->height);
-		if (h_this > pSrc->pDrawable->height - y_src)
-		    h_this = pSrc->pDrawable->height - y_src;
-	    }
-	    while (w)
-	    {
-		w_this = w;
-		if (maskRepeat)
-		{
-		    x_msk = mod (x_msk, pMask->pDrawable->width);
-		    if (w_this > pMask->pDrawable->width - x_msk)
-			w_this = pMask->pDrawable->width - x_msk;
-		}
-		if (srcRepeat)
-		{
-		    x_src = mod (x_src, pSrc->pDrawable->width);
-		    if (w_this > pSrc->pDrawable->width - x_src)
-			w_this = pSrc->pDrawable->width - x_src;
-		}
-		(*func) (op, pSrc, pMask, pDst,
-			 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
-			 w_this, h_this);
-		w -= w_this;
-		x_src += w_this;
-		x_msk += w_this;
-		x_dst += w_this;
-	    }
-	    h -= h_this;
-	    y_src += h_this;
-	    y_msk += h_this;
-	    y_dst += h_this;
-	}
-	pbox++;
+	fbComposite (op, pSrc, pMask, pDst,
+		     xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
     }
-    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
 
-    // Reset destination depth/format to its true value
-    pDst->pDrawable->depth = dstDepth;
+    pDst->pDrawable->depth = oldDepth;
     pDst->format = oldFormat;
 }
 
diff-tree e0959adcd8df2c61e98e76e708fceef9c7cd54eb (from c1e1d6b98a6708860e5b5f6e21d8d5b1d8ce9075)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue May 1 13:41:48 2007 -0400

    Add fbCompositeRect() as another special case in the switch of doom in fbpict.c
    
    This is phase one of getting the two region walkers in fbcompose.c and
    fbpict.c merged together.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 24b552e..6e49893 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -4027,7 +4027,7 @@ static void fbStoreExternalAlpha(Picture
 typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
 typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
 
-static void
+void
 fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
 {
     CARD32 *src_buffer = scanline_buffer;
diff --git a/fb/fbpict.c b/fb/fbpict.c
index a735967..819d21a 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1018,14 +1018,6 @@ fbCompositeSolidMask_nx1xn (CARD8      o
     FbBits	src;
 
     fbComposeGetSolid(pSrc, src, pDst->format);
-
-    if ((src & 0xff000000) != 0xff000000)
-    {
-	fbCompositeGeneral  (op, pSrc, pMask, pDst,
-			     xSrc, ySrc, xMask, yMask, xDst, yDst,
-			     width, height);
-	return;
-    }
     fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
     fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
 
@@ -1443,6 +1435,48 @@ fbCompositeSolidSrc_nxn  (CARD8	op,
 }
  */
 
+#define SCANLINE_BUFFER_LENGTH 2048
+ 
+static void
+fbCompositeRectWrapper  (CARD8	   op,
+			 PicturePtr pSrc,
+			 PicturePtr pMask,
+			 PicturePtr pDst,
+			 INT16      xSrc,
+			 INT16      ySrc,
+			 INT16      xMask,
+			 INT16      yMask,
+			 INT16      xDst,
+			 INT16      yDst,
+			 CARD16     width,
+			 CARD16     height)
+{
+    CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
+    CARD32 *scanline_buffer = _scanline_buffer;
+    FbComposeData data;
+
+    data.op = op;
+    data.src = pSrc;
+    data.mask = pMask;
+    data.dest = pDst;
+    data.xSrc = xSrc;
+    data.ySrc = ySrc;
+    data.xMask = xMask;
+    data.yMask = yMask;
+    data.xDest = xDst;
+    data.yDest = yDst;
+    data.width = width;
+    data.height = height;
+
+    if (width > SCANLINE_BUFFER_LENGTH)
+        scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
+
+    fbCompositeRect (&data, scanline_buffer);
+
+    if (scanline_buffer != _scanline_buffer)
+	free(scanline_buffer);
+}
+
 void
 fbComposite (CARD8      op,
 	     PicturePtr pSrc,
@@ -1632,8 +1666,14 @@ fbComposite (CARD8      op,
 			case PICT_x8r8g8b8:
 			case PICT_a8b8g8r8:
 			case PICT_x8b8g8r8:
-			    func = fbCompositeSolidMask_nx1xn;
+			{
+			    FbBits src;
+
+			    fbComposeGetSolid(pSrc, src, pDst->format);
+			    if ((src & 0xff000000) == 0xff000000)
+				func = fbCompositeSolidMask_nx1xn;
 			    break;
+			}
 			default:
 			    break;
 			}
@@ -1642,7 +1682,7 @@ fbComposite (CARD8      op,
 			break;
 		    }
 		}
-		if (func != fbCompositeGeneral)
+		if (func)
 		    srcRepeat = FALSE;
 	    }
 	    else if (!srcRepeat) /* has mask and non-repeating source */
@@ -1755,7 +1795,7 @@ fbComposite (CARD8      op,
 			break;
 		    }
 		    
-		    if (func != fbCompositeGeneral)
+		    if (func)
 			maskRepeat = FALSE;
 		}
 	    }
@@ -2043,9 +2083,7 @@ fbComposite (CARD8      op,
     }
 
     if (!func) {
-         /* no fast path, use the general code */
-         fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
-         return;
+	func = fbCompositeRectWrapper;
     }
 
     /* if we are transforming, we handle repeats in fbFetchTransformed */
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 5246cd5..86f271e 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -383,6 +383,9 @@ typedef struct _FbComposeData {
     CARD16	height;
 } FbComposeData;
 
+void
+fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer);
+
 typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
 typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
 typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
diff-tree c1e1d6b98a6708860e5b5f6e21d8d5b1d8ce9075 (from bd0abb2844ef9faf28703e592cfebb886004234c)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed May 2 15:55:40 2007 -0600

    In __glXCreateARGBConfig(), insert the new GL mode at the _end_ of the linked list.
    
    Previously, the new mode was added at the head of the list.  This caused the
    positional correspondence between modes and the XMesaVisuals array to be off
    by one.  The net result was GLX clients failing when they tried to use the
    last GLX mode/visual.
    
    We still have the problem of DRI drivers not being able to use the extra
    mode/visual introduced by __glXCreateARGBConfig().  glXCreateContext fails
    with BadAlloc if it's attempted.  This is also the source of the often-
    seen warning "libGL warning: 3D driver claims to not support visual xxx"
    Look into fixing that someday...

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 6273edc..932878f 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1019,6 +1019,7 @@ __glXCreateARGBConfig(__GLXscreen *scree
     VisualPtr visual;
     int i;
 
+    /* search for a 32-bit visual */
     visual = NULL;
     for (i = 0; i < screen->pScreen->numVisuals; i++) 
 	if (screen->pScreen->visuals[i].nplanes == 32) {
@@ -1037,8 +1038,22 @@ __glXCreateARGBConfig(__GLXscreen *scree
     if (modes == NULL)
 	return;
 
-    modes->next = screen->modes;
-    screen->modes = modes;
+    /* Insert this new mode at the TAIL of the linked list.
+     * Previously, the mode was incorrectly inserted at the head of the
+     * list, causing find_mesa_visual() to be off by one.  This would
+     * GLX clients to blow up if they attempted to use the last mode
+     * in the list!
+     */
+    {
+        __GLcontextModes *prev = NULL, *m;
+        for (m = screen->modes; m; m = m->next)
+            prev = m;
+        if (prev)
+            prev->next = modes;
+        else
+            screen->modes = modes;
+    }
+
     screen->numUsableVisuals++;
     screen->numVisuals++;
 
@@ -1104,6 +1119,9 @@ int DoGetFBConfigs(__GLXclientState *cl,
     }
     pGlxScreen = __glXActiveScreens[screen];
 
+    /* Create the "extra" 32bpp ARGB visual, if not already added.
+     * XXX This is questionable place to do so!  Re-examine this someday.
+     */
     __glXCreateARGBConfig(pGlxScreen);
 
     reply.numFBConfigs = pGlxScreen->numUsableVisuals;
diff-tree bd0abb2844ef9faf28703e592cfebb886004234c (from 71fc5b3e9309182978ead676965d65ca93a4e3b9)
Author: Tilman Sauerbeck <tilman at code-monkey.de>
Date:   Wed May 2 17:20:48 2007 +0200

    Bug #10823: Fixed default OSNAME value.
    
    We try to get OSNAME from uname by default now.

diff --git a/configure.ac b/configure.ac
index 9d4a50a..c8b40a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -374,11 +374,6 @@ fi
 AC_MSG_RESULT([$mmx_capable])
 AM_CONDITIONAL(MMX_CAPABLE, [test "x$mmx_capable" = xyes])
 
-
-OSNAME=`uname -srm`
-AC_DEFINE_UNQUOTED(OSNAME, "$OSNAME", 
-	[Define to OS Name string to display for build OS in Xorg log])
-
 DEFAULT_VENDOR_NAME="The X.Org Foundation"
 DEFAULT_VENDOR_NAME_SHORT="X.Org"
 DEFAULT_VERSION_MAJOR=7
@@ -444,9 +439,9 @@ AC_ARG_WITH(builder-addr,    AS_HELP_STR
 				  [Builder address (default: xorg at lists.freedesktop.org)]),
 				[ BUILDERADDR="$withval" ],
 				[ BUILDERADDR="xorg at lists.freedesktop.org" ])
-AC_ARG_WITH(os-name,         AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: UNKNOWN)]),
+AC_ARG_WITH(os-name,         AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: output of "uname -srm")]),
 				[ OSNAME="$withval" ],
-				[ OSNAME="UNKNOWN" ])
+				[ OSNAME=`uname -srm` ])
 AC_ARG_WITH(os-vendor,       AS_HELP_STRING([--with-os-vendor=OSVENDOR], [Name of OS vendor]),
 				[ OSVENDOR="$withval" ],
 				[ OSVENDOR="" ])
@@ -948,6 +943,11 @@ AC_DEFINE_UNQUOTED(XORG_RELEASE, ["$VEND
 AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
 AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
 AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address])
+
+if test -z "$OSNAME"; then
+    OSNAME="UNKNOWN"
+fi
+
 AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name])
 AC_DEFINE_UNQUOTED(OSVENDOR, ["$OSVENDOR"], [Operating System Vendor])
 AC_DEFINE_UNQUOTED(BUILDERSTRING, ["$BUILDERSTRING"], [Builder string])
diff-tree 71fc5b3e9309182978ead676965d65ca93a4e3b9 (from 873ef75b1e8c94d39670c981c4d830ab8bcc018b)
Author: Keith Packard <keithp at keithp.com>
Date:   Wed May 2 11:41:11 2007 +0200

    Fix for a divide by zero that can be triggered by a malicious client.
    
    Problem reported by Derek Abdine of rapid7.com. Thanks.

diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 4c67bcd..478a80f 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -117,6 +117,9 @@ fbRasterizeTrapezoid (PicturePtr    pPic
     RenderEdge	l, r;
     xFixed	t, b;
     
+    if (!xTrapezoidValid (trap))
+	return;
+
     fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
 
     width = pPicture->pDrawable->width;
diff --git a/render/renderedge.c b/render/renderedge.c
index 199ec22..c2ffabe 100644
--- a/render/renderedge.c
+++ b/render/renderedge.c
@@ -143,6 +143,7 @@ RenderEdgeInit (RenderEdge	*e,
     dx = x_bot - x_top;
     dy = y_bot - y_top;
     e->dy = dy;
+    e->dx = 0;
     if (dy)
     {
 	if (dx >= 0)
diff-tree 873ef75b1e8c94d39670c981c4d830ab8bcc018b (from 6b33459bf5aac23c3ecc7002d091c02f327d907a)
Author: Colin Guthrie <gmane at colin.guthr.ie>
Date:   Mon Apr 30 10:33:12 2007 -0600

    fix __glXErrorCallBack() proto

diff --git a/hw/dmx/glxProxy/glxext.h b/hw/dmx/glxProxy/glxext.h
index 8572aa4..0113937 100644
--- a/hw/dmx/glxProxy/glxext.h
+++ b/hw/dmx/glxProxy/glxext.h
@@ -67,7 +67,7 @@ extern void __glXFreeGLXPixmap( __GLXpix
 
 extern void __glXNoSuchRenderOpcode(GLbyte*);
 extern int __glXNoSuchSingleOpcode(__GLXclientState*, GLbyte*);
-extern void __glXErrorCallBack(__GLinterface *gc, GLenum code);
+extern void __glXErrorCallBack(GLenum code);
 extern void __glXClearErrorOccured(void);
 extern GLboolean __glXErrorOccured(void);
 extern void __glXResetLargeCommandStatus(__GLXclientState*);
diff-tree 6b33459bf5aac23c3ecc7002d091c02f327d907a (from parents)
Merge: 18252a515d4989b983a3b7389636045e06d0f246 3c91a993e8c752002adf85c317216e1487c20780
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Apr 30 10:26:19 2007 -0600

    Merge branch 'master' of git+ssh://brianp@git.freedesktop.org/git/xorg/xserver

diff-tree 3c91a993e8c752002adf85c317216e1487c20780 (from a261e1325057974d58440812b93c00c0caa4423a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:49:41 2007 +0200

    EXA: Fix OffscreenValidate build with DEBUG_OFFSCREEN enabled.

diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 38ad58f..6fe646a 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -54,7 +54,7 @@ ExaOffscreenValidate (ScreenPtr pScreen)
 	assert (area->offset >= area->base_offset &&
 		area->offset < (area->base_offset + area->size));
 	if (prev)
-	    assert (prev->base_offset + prev->area.size == area->base_offset);
+	    assert (prev->base_offset + prev->size == area->base_offset);
 	prev = area;
     }
     assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
diff-tree a261e1325057974d58440812b93c00c0caa4423a (from b1b6674a919943a8ac37e54d02e8d0d23a642b1d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:49:35 2007 +0200

    EXA: Remove DrawableDirty.
    
    Convert the remaining callers to PixmapDirty.

diff --git a/exa/exa.c b/exa/exa.c
index 3d77800..c5b5a66 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -172,29 +172,6 @@ exaPixmapDirty (PixmapPtr pPix, int x1, 
     REGION_UNINIT(pScreen, &region);
 }
 
-/**
- * exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for
- * optimizations in pixmap migration when no changes have occurred.
- */
-void
-exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2)
-{
-    PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
-    int xoff, yoff;
-
-    x1 = max(x1, pDrawable->x);
-    y1 = max(y1, pDrawable->y);
-    x2 = min(x2, pDrawable->x + pDrawable->width);
-    y2 = min(y2, pDrawable->y + pDrawable->height);
-
-    if (x1 >= x2 || y1 >= y2)
-	return;
-
-    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
-    exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
-}
-
 static Bool
 exaDestroyPixmap (PixmapPtr pPixmap)
 {
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index b976082..ece5898 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -351,9 +351,6 @@ void
 exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
 		      int *xp, int *yp);
 
-void
-exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
-
 Bool
 exaDrawableIsOffscreen (DrawablePtr pDrawable);
 
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 06881e3..5e7c67f 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -764,6 +764,7 @@ exaRasterizeTrapezoid (PicturePtr pPictu
 {
     DrawablePtr pDraw = pPicture->pDrawable;
     ExaMigrationRec pixmaps[1];
+    int xoff, yoff;
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = TRUE;
@@ -772,8 +773,10 @@ exaRasterizeTrapezoid (PicturePtr pPictu
 
     exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
     fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
-    exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
-		     pDraw->x + pDraw->width, pDraw->y + pDraw->height);
+    exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
+    exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+		   pDraw->x + xoff + pDraw->width,
+		   pDraw->y + yoff + pDraw->height);
     exaFinishAccess(pDraw, EXA_PREPARE_DEST);
 }
 
@@ -787,6 +790,7 @@ exaAddTriangles (PicturePtr pPicture, IN
 {
     DrawablePtr pDraw = pPicture->pDrawable;
     ExaMigrationRec pixmaps[1];
+    int xoff, yoff;
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = TRUE;
@@ -795,8 +799,10 @@ exaAddTriangles (PicturePtr pPicture, IN
 
     exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
     fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
-    exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
-		     pDraw->x + pDraw->width, pDraw->y + pDraw->height);
+    exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
+    exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+		   pDraw->x + xoff + pDraw->width,
+		   pDraw->y + yoff + pDraw->height);
     exaFinishAccess(pDraw, EXA_PREPARE_DEST);
 }
 
diff-tree b1b6674a919943a8ac37e54d02e8d0d23a642b1d (from 584697a2231ac782f362a925e1489c15483a8791)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:49:28 2007 +0200

    EXA: FillSpans improvements.
    
    * Don't need to track damage.
    * Always migrate for fallbacks.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 4aa2d63..bf63f2c 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -74,6 +74,7 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
 					 pGC->planemask,
 					 pGC->fgPixel))
     {
+	exaDoMigration (pixmaps, 1, FALSE);
 	ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
 	return;
     }
@@ -109,8 +110,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
 	    (*pExaScr->info->Solid) (pPixmap,
 				     fullX1 + off_x, fullY1 + off_y,
 				     fullX2 + off_x, fullY1 + 1 + off_y);
-	    exaPixmapDirty (pPixmap, fullX1 + off_x, fullY1 + off_y,
-			    fullX2 + off_x, fullY1 + 1 + off_y);
 	}
 	else
 	{
@@ -129,8 +128,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
 			(*pExaScr->info->Solid) (pPixmap,
 						 partX1 + off_x, fullY1 + off_y,
 						 partX2 + off_x, fullY1 + 1 + off_y);
-			exaPixmapDirty (pPixmap, partX1 + off_x, fullY1 + off_y,
-					partX2 + off_x, fullY1 + 1 + off_y);
 		    }
 		}
 		pbox++;
diff-tree 584697a2231ac782f362a925e1489c15483a8791 (from 982d7c2c0b948ba04c8eefa475d660981e6ed9f9)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:49:09 2007 +0200

    EXA: SolidBoxClipped improvements.
    
    * Centralize handling of fallbacks and damage tracking.
    * Always migrate for fallbacks.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 800c4f0..4aa2d63 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -826,20 +826,19 @@ exaSolidBoxClipped (DrawablePtr	pDrawabl
 	pPixmap->drawable.width > pExaScr->info->maxX ||
 	pPixmap->drawable.height > pExaScr->info->maxY)
     {
-	exaDoMigration (pixmaps, 1, FALSE);
-	goto fallback;
+	fallback = TRUE;
     } else {
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+    exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
 
-    if (!pPixmap ||
+    if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
 	!(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
     {
-fallback:
 	EXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		      exaDrawableLocation(pDrawable)));
+	exaDoMigration (pixmaps, 1, FALSE);
 	fallback = TRUE;
 	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
@@ -878,10 +877,10 @@ fallback:
 	    (*pExaScr->info->Solid) (pPixmap,
 				     partX1 + xoff, partY1 + yoff,
 				     partX2 + xoff, partY2 + yoff);
-	    exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff,
-			    partX2 + xoff, partY2 + yoff);
-	} else
-	    exaDrawableDirty (pDrawable, partX1, partY1, partX2, partY2);
+	}
+
+	exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
+			partY2 + yoff);
     }
 
     if (fallback)
diff-tree 982d7c2c0b948ba04c8eefa475d660981e6ed9f9 (from d2245386eed200e77a8c84bdda36ab29e39fd593)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:48:59 2007 +0200

    EXA: CopyNtoN improvements.
    
    * Centralize handling of fallbacks and damage tracking.
    * Always migrate for fallbacks.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 6a0fbb7..800c4f0 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -390,6 +390,7 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable
     int	    src_off_x, src_off_y;
     int	    dst_off_x, dst_off_y;
     ExaMigrationRec pixmaps[2];
+    Bool fallback = FALSE;
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
@@ -407,62 +408,64 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable
 	pDstPixmap->drawable.width > pExaScr->info->maxX ||
 	pDstPixmap->drawable.height > pExaScr->info->maxY)
     {
-	exaDoMigration (pixmaps, 2, FALSE);
-	goto fallback;
+	fallback = TRUE;
     } else {
 	exaDoMigration (pixmaps, 2, TRUE);
     }
 
     /* Mixed directions must be handled specially if the card is lame */
-    if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS &&
+    if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
 	reverse != upsidedown) {
-	if (!exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
+	if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
 			       dx, dy))
-	    goto fallback;
-	return;
+	    return;
+	fallback = TRUE;
     }
 
-    if ((pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) &&
-	(pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) &&
-	(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap,
-				       reverse ? -1 : 1, upsidedown ? -1 : 1,
-				       pGC ? pGC->alu : GXcopy,
-				       pGC ? pGC->planemask : FB_ALLONES))
+    pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
+    pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+
+    exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
+    exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
+
+    if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
+	!exaPixmapIsOffscreen(pDstPixmap) ||
+	!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
+					upsidedown ? -1 : 1,
+					pGC ? pGC->alu : GXcopy,
+					pGC ? pGC->planemask : FB_ALLONES)) {
+	fallback = TRUE;
+	EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
+		      exaDrawableLocation(pSrcDrawable),
+		      exaDrawableLocation(pDstDrawable)));
+	exaDoMigration (pixmaps, 2, FALSE);
+	exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
+	exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
+	fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
+		    pbox, nbox, dx, dy, reverse, upsidedown,
+		    bitplane, closure);
+	exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
+	exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
+    }
+
+    while (nbox--)
     {
-	while (nbox--)
-	{
+	if (!fallback)
 	    (*pExaScr->info->Copy) (pDstPixmap,
 				    pbox->x1 + dx + src_off_x,
 				    pbox->y1 + dy + src_off_y,
 				    pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
-				    pbox->x2 - pbox->x1,
-				    pbox->y2 - pbox->y1);
-	    exaPixmapDirty (pDstPixmap,
-			    pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
-			    pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
-	    pbox++;
-	}
-	(*pExaScr->info->DoneCopy) (pDstPixmap);
-	exaMarkSync(pDstDrawable->pScreen);
-	return;
-    }
-
-fallback:
-    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
-		  exaDrawableLocation(pSrcDrawable),
-		  exaDrawableLocation(pDstDrawable)));
-    exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
-    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
-		pbox, nbox, dx, dy, reverse, upsidedown,
-		bitplane, closure);
-    exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
-    exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
-    while (nbox--)
-    {
-	exaDrawableDirty (pDstDrawable, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+				    pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+	exaPixmapDirty (pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
+			pbox->x2  + dst_off_x, pbox->y2 + dst_off_y);
 	pbox++;
     }
+
+    if (fallback)
+	return;
+
+    (*pExaScr->info->DoneCopy) (pDstPixmap);
+    exaMarkSync (pDstDrawable->pScreen);
 }
 
 RegionPtr
diff-tree d2245386eed200e77a8c84bdda36ab29e39fd593 (from 0880aaac9c83019fec2e3d32871f74c7a407f8b3)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:48:31 2007 +0200

    EXA: GetImage improvements.
    
    Only migrate when appropriate. In particular, don't migrate to offscreen in the
    no-fallback case as copying from system memory should usually be as fast if not
    faster than DownloadFromScreen, in particular if the bits need to be uploaded
    to offscreen first.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index dd02fef..6a0fbb7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1330,27 +1330,22 @@ exaGetImage (DrawablePtr pDrawable, int 
     int xoff, yoff;
     Bool ok;
 
-    if (pExaScr->swappedOut || pExaScr->info->DownloadFromScreen == NULL)
-	goto fallback;
+    if (pExaScr->info->DownloadFromScreen == NULL)
+	goto migrate_and_fallback;
 
     /* Only cover the ZPixmap, solid copy case. */
     if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
-	goto fallback;
+	goto migrate_and_fallback;
 
     /* Only try to handle the 8bpp and up cases, since we don't want to think
      * about <8bpp.
      */
     if (pDrawable->bitsPerPixel < 8)
+	goto migrate_and_fallback;
+
+    if (pExaScr->swappedOut)
 	goto fallback;
 
-    /* Migrate, but assume that we could accelerate the download. It is up to
-     * the migration scheme to ensure that this case doesn't result in bad
-     * moving of pixmaps.
-     */
-    pixmaps[0].as_dst = FALSE;
-    pixmaps[0].as_src = TRUE;
-    pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
-    exaDoMigration (pixmaps, 1, TRUE);
     pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
     if (pPix == NULL)
 	goto fallback;
@@ -1365,12 +1360,12 @@ exaGetImage (DrawablePtr pDrawable, int 
 	return;
     }
 
-fallback:
+migrate_and_fallback:
     pixmaps[0].as_dst = FALSE;
     pixmaps[0].as_src = TRUE;
     pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
     exaDoMigration (pixmaps, 1, FALSE);
-
+fallback:
     ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
 }
 
diff-tree 0880aaac9c83019fec2e3d32871f74c7a407f8b3 (from 7fca16901187ade48e83e6a2684ef464b1912357)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:48:19 2007 +0200

    EXA: PutImage improvements.
    
    * Migrate for fallbacks when appropriate.
    * Add damage tracking in ExaCheckPutImage.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index fc1f3d7..dd02fef 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -154,8 +154,9 @@ exaPutImage (DrawablePtr pDrawable, GCPt
     int xoff, yoff;
     int src_stride, bpp = pDrawable->bitsPerPixel;
 
-    if (pExaScr->swappedOut || pExaScr->info->UploadToScreen == NULL)
-	goto migrate_and_fallback;
+    pixmaps[0].as_dst = TRUE;
+    pixmaps[0].as_src = FALSE;
+    pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
 
     /* Don't bother with under 8bpp, XYPixmaps. */
     if (format != ZPixmap || bpp < 8)
@@ -165,10 +166,14 @@ exaPutImage (DrawablePtr pDrawable, GCPt
     if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
 	goto migrate_and_fallback;
 
-    pixmaps[0].as_dst = TRUE;
-    pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+    if (pExaScr->swappedOut)
+	goto fallback;
+
     exaDoMigration (pixmaps, 1, TRUE);
+
+    if (pExaScr->info->UploadToScreen == NULL)
+	goto fallback;
+
     pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
     if (pPix == NULL)
@@ -221,25 +226,23 @@ exaPutImage (DrawablePtr pDrawable, GCPt
 
 	    fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
 		      src_stride / sizeof(FbStip),
-		      (x1 - x) * bpp,
-		      dst + (y1 + yoff) * dst_stride,
+		      (x1 - x) * dstBpp,
+		      dst + (y1 + dstYoff) * dst_stride,
 		      dst_stride,
-		      (x1 + xoff) * bpp,
-		      (x2 - x1) * bpp,
+		      (x1 + dstXoff) * dstBpp,
+		      (x2 - x1) * dstBpp,
 		      y2 - y1,
-		      GXcopy, FB_ALLONES, bpp);
+		      GXcopy, FB_ALLONES, dstBpp);
 
 	    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
 	}
+
 	exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
     }
 
     return;
 
 migrate_and_fallback:
-    pixmaps[0].as_dst = TRUE;
-    pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
     exaDoMigration (pixmaps, 1, FALSE);
 
 fallback:
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index a7f9398..708d1ea 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -88,10 +88,15 @@ ExaCheckPutImage (DrawablePtr pDrawable,
 		 int x, int y, int w, int h, int leftPad, int format,
 		 char *bits)
 {
+    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+    int xoff, yoff;
+
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+    exaPixmapDirty(pPixmap, x + xoff, y + yoff, x + xoff + w, y + yoff + h);
 }
 
 RegionPtr
diff-tree 7fca16901187ade48e83e6a2684ef464b1912357 (from a8d6ebdf9338dc2f6ff9a532e6fec460a70d3b1e)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:48:11 2007 +0200

    EXA: ImageGlyphBlt improvements.
    
    * Don't waste effort on invisible glyphs.
    * Only track damage for bounding box instead of each glyph separately.
    * Always migrate for fallbacks.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 721882b..fc1f3d7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -915,12 +915,36 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
     int		    dstBpp;
     int		    dstXoff, dstYoff;
     FbBits	    depthMask;
+    PixmapPtr	    pPixmap = exaGetDrawablePixmap(pDrawable);
+    ExaMigrationRec pixmaps[1];
+    int		    xBack, widthBack, yBack, heightBack;
+
+    for (ppci = ppciInit, n = nglyph, widthBack = 0; n; n--)
+	widthBack += (*ppci++)->metrics.characterWidth;
+
+    xBack = x;
+    if (widthBack < 0)
+    {
+	xBack += widthBack;
+	widthBack = -widthBack;
+    }
+    yBack = y - FONTASCENT(pGC->font);
+    heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+    if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
+	(xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
+	return;
+
+    pixmaps[0].as_dst = TRUE;
+    pixmaps[0].as_src = TRUE;
+    pixmaps[0].pPix = pPixmap;
 
     depthMask = FbFullMask(pDrawable->depth);
     if ((pGC->planemask & depthMask) != depthMask)
     {
+	exaDoMigration(pixmaps, 1, FALSE);
 	ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
-	return;
+	goto damage;
     }
     glyph = NULL;
     switch (pDrawable->bitsPerPixel) {
@@ -932,6 +956,8 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
 
     x += pDrawable->x;
     y += pDrawable->y;
+    xBack += pDrawable->x;
+    yBack += pDrawable->y;
 
     if (TERMINALFONT (pGC->font) && !glyph)
     {
@@ -939,23 +965,6 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
     }
     else
     {
-	int		xBack, widthBack;
-	int		yBack, heightBack;
-
-	ppci = ppciInit;
-	n = nglyph;
-	widthBack = 0;
-	while (n--)
-	    widthBack += (*ppci++)->metrics.characterWidth;
-
-        xBack = x;
-	if (widthBack < 0)
-	{
-	    xBack += widthBack;
-	    widthBack = -widthBack;
-	}
-	yBack = y - FONTASCENT(pGC->font);
-	heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
         exaSolidBoxClipped (pDrawable,
 			    fbGetCompositeClip(pGC),
 			    pGC->planemask,
@@ -968,74 +977,50 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
     }
 
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+    exaDoMigration(pixmaps, 1, FALSE);
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     exaPrepareAccessGC (pGC);
 
     fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 
-    ppci = ppciInit;
-    while (nglyph--)
+    for (ppci = ppciInit; nglyph; nglyph--, x += pci->metrics.characterWidth)
     {
 	pci = *ppci++;
-	pglyph = FONTGLYPHBITS(pglyphBase, pci);
 	gWidth = GLYPHWIDTHPIXELS(pci);
 	gHeight = GLYPHHEIGHTPIXELS(pci);
-	if (gWidth && gHeight)
-	{
-	    gx = x + pci->metrics.leftSideBearing;
-	    gy = y - pci->metrics.ascent;
-	    if (glyph && gWidth <= sizeof (FbStip) * 8 &&
-		fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
-	    {
-		(*glyph) (dst + (gy + dstYoff) * dstStride,
-			  dstStride,
-			  dstBpp,
-			  (FbStip *) pglyph,
-			  pPriv->fg,
-			  gx + dstXoff,
-			  gHeight);
-		exaDrawableDirty (pDrawable, gx, gy, gx + gWidth, gy + gHeight);
-	    }
-	    else
-	    {
-		RegionPtr pClip = fbGetCompositeClip(pGC);
-		int nbox;
-		BoxPtr pbox;
-
-		gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
-		fbPutXYImage (pDrawable,
-			      pClip,
-			      pPriv->fg,
-			      pPriv->bg,
-			      pPriv->pm,
-			      GXcopy,
-			      opaque,
-
-			      gx,
-			      gy,
-			      gWidth, gHeight,
-
-			      (FbStip *) pglyph,
-			      gStride,
-			      0);
-
-		for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
-		     nbox--; pbox++) {
-		    int x1 = max(gx, pbox->x1), x2 = min(gx + gWidth, pbox->x2);
-		    int y1 = max(gy, pbox->y1), y2 = min(gy + gHeight, pbox->y2);
+	gx = x + pci->metrics.leftSideBearing;
+	gy = y - pci->metrics.ascent;
 
-		    if (x1 >= x2 || y1 >= y2)
-			continue;
+	if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
+	    (gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
+	    gy >= (yBack + heightBack))
+	    continue;
 
-		    exaDrawableDirty (pDrawable, gx, gy, gx + gWidth,
-				      gy + gHeight);
-		}
-	    }
+	pglyph = FONTGLYPHBITS(pglyphBase, pci);
+
+	if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+	    fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+	{
+	    (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
+		      (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
+	}
+	else
+	{
+	    RegionPtr pClip = fbGetCompositeClip(pGC);
+
+	    gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+	    fbPutXYImage (pDrawable, pClip, pPriv->fg, pPriv->bg, pPriv->pm,
+			  GXcopy, opaque, gx, gy, gWidth, gHeight,
+			  (FbStip *) pglyph, gStride, 0);
 	}
-	x += pci->metrics.characterWidth;
     }
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+
+damage:
+    exaGetDrawableDeltas(pDrawable, pPixmap, &dstXoff, &dstYoff);
+    exaPixmapDirty(pPixmap, xBack + dstXoff, yBack + dstYoff,
+		   xBack + dstXoff + widthBack, yBack + dstYoff + heightBack);
 }
 
 const GCOps exaOps = {
diff-tree a8d6ebdf9338dc2f6ff9a532e6fec460a70d3b1e (from 81b055605c34b5823f6c5f63cc0f92f43c6b7252)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:47:53 2007 +0200

    EXA: Defer to FillRegionTiled in Composite when possible.
    
    Committed separately as this case is hard to hit and has only been tested
    lightly.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index 63a412c..06881e3 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -651,6 +651,45 @@ exaComposite(CARD8	op,
 		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 		goto done;
 	    }
+	    else if (pSrcPixmap && !pSrc->transform &&
+		     pSrc->repeatType == RepeatNormal)
+	    {
+		RegionRec region;
+		DDXPointRec srcOrg;
+
+		/* Let's see if the driver can do the repeat in one go */
+		if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
+		    !pDst->alphaMap)
+		{
+		    ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
+						ySrc, xMask, yMask, xDst, yDst,
+						width, height);
+		    if (ret == 1)
+			goto done;
+		}
+
+		/* Now see if we can use exaFillRegionTiled() */
+		xDst += pDst->pDrawable->x;
+		yDst += pDst->pDrawable->y;
+		xSrc += pSrc->pDrawable->x;
+		ySrc += pSrc->pDrawable->y;
+
+		if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc,
+					       ySrc, xMask, yMask, xDst, yDst,
+					       width, height))
+		    goto done;
+
+		srcOrg.x = (xSrc - xDst) % pSrcPixmap->drawable.width;
+		srcOrg.y = (ySrc - yDst) % pSrcPixmap->drawable.height;
+
+		ret = exaFillRegionTiled(pDst->pDrawable, &region, pSrcPixmap,
+					 &srcOrg, FB_ALLONES, GXcopy);
+
+		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+
+		if (ret)
+		    goto done;
+	    }
 	}
     }
 
diff-tree 81b055605c34b5823f6c5f63cc0f92f43c6b7252 (from ce317a5b76c053f449122c46e1372bf8e067cb4c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:47:43 2007 +0200

    EXA: Composite improvements.
    
    * Defer to simpler hooks in more cases (inspired by XAA behaviour).
    * Move damage tracking from lower to higher level functions.
    * Always migrate for fallbacks.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index 2234cdb..63a412c 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -297,15 +297,15 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 
     nbox = REGION_NUM_RECTS(&region);
     pbox = REGION_RECTS(&region);
+
     while (nbox--)
     {
 	(*pExaScr->info->Solid) (pDstPix,
 				 pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
 				 pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
-	exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
-			pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
 	pbox++;
     }
+
     (*pExaScr->info->DoneSolid) (pDstPix);
     exaMarkSync(pDst->pDrawable->pScreen);
 
@@ -446,8 +446,6 @@ exaTryDriverComposite(CARD8		op,
 				     pbox->y1 + dst_off_y,
 				     pbox->x2 - pbox->x1,
 				     pbox->y2 - pbox->y1);
-	exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
-			pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
 	pbox++;
     }
     (*pExaScr->info->DoneComposite) (pDstPix);
@@ -521,6 +519,9 @@ exaTryMagicTwoPassCompositeHelper(CARD8 
 				  CARD16 height)
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
+    DrawablePtr pDstDraw = pDst->pDrawable;
+    PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
+    int xoff, yoff;
 
     assert(op == PictOpOver);
 
@@ -539,6 +540,12 @@ exaTryMagicTwoPassCompositeHelper(CARD8 
     exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
 		 xDst, yDst, width, height);
 
+    exaGetDrawableDeltas(pDstDraw, pDstPixmap, &xoff, &yoff);
+    xoff += pDstDraw->x;
+    yoff += pDstDraw->y;
+    exaPixmapDirty(pDstPixmap, xDst + xoff, yDst + yoff, xDst + xoff + width,
+		   yDst + yoff + height);
+
     /* Then, add in the source value times the destination alpha factors (1.0).
      */
     exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
@@ -565,6 +572,28 @@ exaComposite(CARD8	op,
     int ret = -1;
     Bool saveSrcRepeat = pSrc->repeat;
     Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
+    ExaMigrationRec pixmaps[3];
+    int npixmaps = 1;
+    PixmapPtr pSrcPixmap = NULL;
+
+    pixmaps[0].as_dst = TRUE;
+    pixmaps[0].as_src = exaOpReadsDestination(op);
+    pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
+
+    if (pSrc->pDrawable) {
+	pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
+	pixmaps[npixmaps].as_dst = FALSE;
+	pixmaps[npixmaps].as_src = TRUE;
+	pixmaps[npixmaps].pPix = pSrcPixmap;
+	npixmaps++;
+    }
+
+    if (pMask && pMask->pDrawable) {
+	pixmaps[npixmaps].as_dst = FALSE;
+	pixmaps[npixmaps].as_src = TRUE;
+	pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
+	npixmaps++;
+    }
 
     /* We currently don't support acceleration of gradients, or other pictures
      * with a NULL pDrawable.
@@ -583,19 +612,24 @@ exaComposite(CARD8	op,
 
     if (!pMask)
     {
-	if (op == PictOpSrc)
+      if ((op == PictOpSrc &&
+	   ((pSrc->format == pDst->format) ||
+	    (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
+	    (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
+	  (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
+	   pSrc->format == pDst->format &&
+	   (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8)))
 	{
 	    if (pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1 && pSrc->repeat &&
-		pSrc->repeatType == RepeatNormal)
+		pSrc->pDrawable->height == 1 &&
+		pSrc->repeat)
 	    {
 		ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
 					    width, height);
 		if (ret == 1)
 		    goto done;
 	    }
-	    else if (!pSrc->repeat && !pSrc->transform &&
-		     pSrc->format == pDst->format)
+	    else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
 	    {
 		RegionRec	region;
 
@@ -660,39 +694,14 @@ exaComposite(CARD8	op,
 	}
     }
 
-    if (ret != 0) {
-	ExaMigrationRec pixmaps[3];
-	/* failure to accelerate was not due to pixmaps being in the wrong
-	 * locations.
-	 */
-	pixmaps[0].as_dst = TRUE;
-	pixmaps[0].as_src = exaOpReadsDestination(op);
-	pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
-	pixmaps[1].as_dst = FALSE;
-	pixmaps[1].as_src = TRUE;
-	pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
-	if (pMask) {
-	    pixmaps[2].as_dst = FALSE;
-	    pixmaps[2].as_src = TRUE;
-	    pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
-	    exaDoMigration(pixmaps, 3, FALSE);
-	} else {
-	    exaDoMigration(pixmaps, 2, FALSE);
-	}
-    }
-
 fallback:
 #if DEBUG_TRACE_FALL
     exaPrintCompositeFallback (op, pSrc, pMask, pDst);
 #endif
 
+    exaDoMigration(pixmaps, npixmaps, FALSE);
     ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
 		      xMask, yMask, xDst, yDst, width, height);
-    exaDrawableDirty(pDst->pDrawable,
-		     pDst->pDrawable->x + xDst,
-		     pDst->pDrawable->y + yDst,
-		     pDst->pDrawable->x + xDst + width,
-		     pDst->pDrawable->y + yDst + height);
 
 done:
     pSrc->repeat = saveSrcRepeat;
diff-tree ce317a5b76c053f449122c46e1372bf8e067cb4c (from 0c8905ebc91cf654facef84ee52231a358deec5c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:47:16 2007 +0200

    EXA: Glyphs improvements.
    
    * Don't waste effort on invisible glyphs.
    * Add damage tracking where necessary.
    * Always migrate for fallbacks.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index d48a142..2234cdb 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -845,10 +845,11 @@ exaGlyphs (CARD8	op,
     PixmapPtr	pPixmap = NULL;
     PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = NULL;
+    PixmapPtr   pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
     PicturePtr  pMask;
     ScreenPtr   pScreen = pDst->pDrawable->pScreen;
     int		width = 0, height = 0;
-    int		x, y;
+    int		x, y, x1, y1, xoff, yoff;
     int		xDst = list->xOff, yDst = list->yOff;
     int		n;
     int		error;
@@ -892,7 +893,12 @@ exaGlyphs (CARD8	op,
 	xRectangle  rect;
 	
 	miGlyphExtents (nlist, list, glyphs, &extents);
-	
+
+	extents.x1 = max(extents.x1, 0);
+	extents.y1 = max(extents.y1, 0);
+	extents.x2 = min(extents.x2, pDst->pDrawable->width);
+	extents.y2 = min(extents.y2, pDst->pDrawable->height);
+
 	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
 	    return;
 	width = extents.x2 - extents.x1;
@@ -918,6 +924,7 @@ exaGlyphs (CARD8	op,
 	rect.width = width;
 	rect.height = height;
 	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
 	FreeScratchGC (pGC);
 	x = -extents.x1;
 	y = -extents.y1;
@@ -929,6 +936,8 @@ exaGlyphs (CARD8	op,
 	y = 0;
     }
 
+    exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
+
     while (nlist--)
     {
 	GCPtr pGC = NULL;
@@ -983,13 +992,21 @@ exaGlyphs (CARD8	op,
 	pixmaps[0].as_dst = TRUE;
 	pixmaps[0].as_src = TRUE;
 	pixmaps[0].pPix = pPixmap;
-	exaDoMigration (pixmaps, 1, TRUE);
+	exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
 
 	while (n--)
 	{
 	    GlyphPtr glyph = *glyphs++;
 	    pointer glyphdata = (pointer) (glyph + 1);
-	    
+	    DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
+
+	    x1 = x - glyph->info.x;
+	    y1 = y - glyph->info.y;
+
+	    if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
+		(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
+		goto nextglyph;
+
 	    (*pScreen->ModifyPixmapHeader) (pScratchPixmap, 
 					    glyph->info.width,
 					    glyph->info.height,
@@ -1048,17 +1065,22 @@ exaGlyphs (CARD8	op,
 	    if (maskFormat)
 	    {
 		exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
-			      x - glyph->info.x, y - glyph->info.y,
-			      glyph->info.width, glyph->info.height);
+			      x1, y1, glyph->info.width, glyph->info.height);
+		exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
+			       y1 + glyph->info.height);
 	    }
 	    else
 	    {
 		exaComposite (op, pSrc, pPicture, pDst,
-			      xSrc + (x - glyph->info.x) - xDst,
-			      ySrc + (y - glyph->info.y) - yDst,
-			      0, 0, x - glyph->info.x, y - glyph->info.y,
-			      glyph->info.width, glyph->info.height);
+			      xSrc + x1 - xDst, ySrc + y1 - yDst,
+			      0, 0, x1, y1, glyph->info.width,
+			      glyph->info.height);
+		x1 += pDst->pDrawable->x + xoff;
+		y1 += pDst->pDrawable->y + yoff;
+		exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
+			       y1 + glyph->info.height);
 	    }
+nextglyph:
 	    x += glyph->info.xOff;
 	    y += glyph->info.yOff;
 	}
diff-tree 0c8905ebc91cf654facef84ee52231a358deec5c (from 567f18a09bfb05f448be40c7ebe0f210f955601c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:47:08 2007 +0200

    EXA: PolyFillRect improvements.
    
    * Convert rects to region and use it for damage tracking.
    * When possible, defer to exaFillRegion{Solid,Tiled} using converted region.
    * Always migrate for fallbacks.
    * Move damage tracking out of ExaCheckPolyFillRect.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 95084fc..721882b 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -618,6 +618,9 @@ exaPolySegment (DrawablePtr pDrawable, G
     DEALLOCATE_LOCAL(prect);
 }
 
+static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
+				Pixel pixel, CARD32 planemask, CARD32 alu);
+
 static void
 exaPolyFillRect(DrawablePtr pDrawable,
 		GCPtr	    pGC,
@@ -626,7 +629,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
 {
     ExaScreenPriv (pDrawable->pScreen);
     RegionPtr	    pClip = fbGetCompositeClip(pGC);
-    PixmapPtr	    pPixmap;
+    PixmapPtr	    pPixmap = exaGetDrawablePixmap(pDrawable);
     register BoxPtr pbox;
     BoxPtr	    pextent;
     int		    extentX1, extentX2, extentY1, extentY2;
@@ -635,39 +638,80 @@ exaPolyFillRect(DrawablePtr pDrawable,
     int		    xoff, yoff;
     int		    xorg, yorg;
     int		    n;
-    ExaMigrationRec pixmaps[1];
+    ExaMigrationRec pixmaps[2];
+    RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
+    RegionPtr pDamageReg = DamageRegion(ExaGetPixmapPriv(pPixmap)->pDamage);
+
+    /* Compute intersection of rects and clip region */
+    REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
+    REGION_INTERSECT(pScreen, pReg, pClip, pReg);
+
+    if (!REGION_NUM_RECTS(pReg)) {
+	REGION_DESTROY(pScreen, pReg);
+	return;
+    }
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pPix = pPixmap;
  
+    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+
     if (pExaScr->swappedOut ||
-	pGC->fillStyle != FillSolid ||
 	pPixmap->drawable.width > pExaScr->info->maxX ||
 	pPixmap->drawable.height > pExaScr->info->maxY)
     {
-	exaDoMigration (pixmaps, 1, FALSE);
-	ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
-	while (nrect-- >= 0) {
-	    exaDrawableDirty(pDrawable,
-			     pDrawable->x + prect->x,
-			     pDrawable->y + prect->y,
-			     pDrawable->x + prect->x + prect->width,
-			     pDrawable->y + prect->y + prect->height);
-	    prect++;
+	goto fallback;
+    }
+
+    /* For ROPs where overlaps don't matter, convert rectangles to region and
+     * call exaFillRegion{Solid,Tiled}.
+     */
+    if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
+	(pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop ||
+	 pGC->alu == GXcopyInverted || pGC->alu == GXset)) {
+	if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
+	     exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
+				pGC->fgPixel : pGC->tile.pixel,	pGC->planemask,
+				pGC->alu)) ||
+	    (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
+	     exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
+				pGC->planemask, pGC->alu))) {
+	    goto damage;
 	}
-	return;
-    } else {
-	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
+    if (pGC->fillStyle != FillSolid &&
+	!(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
+    {
+	goto fallback;
+    }
+
+    exaDoMigration (pixmaps, 1, TRUE);
+
+    if (!exaPixmapIsOffscreen (pPixmap) ||
 	!(*pExaScr->info->PrepareSolid) (pPixmap,
 					 pGC->alu,
 					 pGC->planemask,
 					 pGC->fgPixel))
     {
+fallback:
+	if (pGC->fillStyle == FillTiled && !pGC->tileIsPixel) {
+	    pixmaps[1].as_dst = FALSE;
+	    pixmaps[1].as_src = TRUE;
+	    pixmaps[1].pPix = pGC->tile.pixmap;
+	    exaDoMigration (pixmaps, 2, FALSE);
+	} else {
+	    exaDoMigration (pixmaps, 1, FALSE);
+	}
+
 	ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
+
+damage:
+	REGION_TRANSLATE(pScreen, pReg, xoff, yoff);
+	REGION_UNION(pScreen, pDamageReg, pReg, pDamageReg);
+	REGION_DESTROY(pScreen, pReg);
+
 	return;
     }
 
@@ -715,7 +759,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
 	    pbox = REGION_RECTS(pClip);
 	    /*
 	     * clip the rectangle to each box in the clip region
-	     * this is logically equivalent to calling Intersect()
+	     * this is logically equivalent to calling Intersect(),
+	     * but rectangles may overlap each other here.
 	     */
 	    while(n--)
 	    {
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 7713a08..a7f9398 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -201,32 +201,11 @@ ExaCheckPolyFillRect (DrawablePtr pDrawa
 {
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
-    if (nrect) {
-	int x1 = max(prect->x, 0), y1 = max(prect->y, 0);
-	int x2 = min(prect->x + prect->width, pDrawable->width);
-	int y2 = min(prect->y + prect->height, pDrawable->height);
-
-	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-	exaPrepareAccessGC (pGC);
-	fbPolyFillRect (pDrawable, pGC, nrect, prect);
-	exaFinishAccessGC (pGC);
-	exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-
-	/* Only track bounding box of damage, as this path can degenerate to
-	 * zillions of damage boxes
-	 */
-	while (--nrect)
-	{
-	    prect++;
-	    x1 = min(x1, prect->x);
-	    x2 = max(x2, prect->x + prect->width);
-	    y1 = min(y1, prect->y);
-	    y2 = max(y2, prect->y + prect->height);
-	}
-
-	exaDrawableDirty (pDrawable, pDrawable->x + x1, pDrawable->y + y1,
-			  pDrawable->x + x2, pDrawable->y + y2);
-    }
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pGC);
+    fbPolyFillRect (pDrawable, pGC, nrect, prect);
+    exaFinishAccessGC (pGC);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
diff-tree 567f18a09bfb05f448be40c7ebe0f210f955601c (from e869573b52fac69fb88cea120daaeec59c7a3461)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:46:49 2007 +0200

    EXA: FillRegion{Solid,Tiled} improvements.
    
    * Support planemasks, different ALUs and arbitrary tile origin.
    * Leave damage tracking and non-trivial fallbacks to callers.
    * Always migrate for fallbacks.
    
    This is in preparation for using these from more other functions.

diff --git a/exa/exa.c b/exa/exa.c
index 23fe555..3d77800 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -126,7 +126,7 @@ exaGetDrawablePixmap(DrawablePtr pDrawab
  * the backing drawable. These coordinates are nonzero only for redirected
  * windows.
  */
-static void
+void
 exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
 		      int *xp, int *yp)
 {
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index e633d80..95084fc 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1043,10 +1043,12 @@ exaCopyWindow(WindowPtr pWin, DDXPointRe
     REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
 }
 
-static void
+static Bool
 exaFillRegionSolid (DrawablePtr	pDrawable,
 		    RegionPtr	pRegion,
-		    Pixel	pixel)
+		    Pixel	pixel,
+		    CARD32	planemask,
+		    CARD32	alu)
 {
     ExaScreenPriv(pDrawable->pScreen);
     PixmapPtr pPixmap;
@@ -1062,22 +1064,19 @@ exaFillRegionSolid (DrawablePtr	pDrawabl
     if (pPixmap->drawable.width > pExaScr->info->maxX ||
 	pPixmap->drawable.height > pExaScr->info->maxY)
     {
-	exaDoMigration (pixmaps, 1, FALSE);
 	goto fallback;
     } else {
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
     if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
-	(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
+	(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
     {
 	while (nbox--)
 	{
 	    (*pExaScr->info->Solid) (pPixmap,
 				     pBox->x1 + xoff, pBox->y1 + yoff,
 				     pBox->x2 + xoff, pBox->y2 + yoff);
-	    exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
-			    pBox->x2 + xoff, pBox->y2 + yoff);
 	    pBox++;
 	}
 	(*pExaScr->info->DoneSolid) (pPixmap);
@@ -1086,27 +1085,30 @@ exaFillRegionSolid (DrawablePtr	pDrawabl
     else
     {
 fallback:
+	if (alu != GXcopy || planemask != FB_ALLONES)
+	    return FALSE;
 	EXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		      exaDrawableLocation(pDrawable)));
+	exaDoMigration (pixmaps, 1, FALSE);
 	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	fbFillRegionSolid (pDrawable, pRegion, 0,
 			   fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
 	exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-	while (nbox--)
-	{
-	    exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-	    pBox++;
-	}
     }
+
+    return TRUE;
 }
 
 /* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
  * Based on fbFillRegionTiled(), fbTile().
  */
-static void
+Bool
 exaFillRegionTiled (DrawablePtr	pDrawable,
 		    RegionPtr	pRegion,
-		    PixmapPtr	pTile)
+		    PixmapPtr	pTile,
+		    DDXPointPtr pPatOrg,
+		    CARD32	planemask,
+		    CARD32	alu)
 {
     ExaScreenPriv(pDrawable->pScreen);
     PixmapPtr pPixmap;
@@ -1122,10 +1124,10 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
     /* If we're filling with a solid color, grab it out and go to
      * FillRegionSolid, saving numerous copies.
      */
-    if (tileWidth == 1 && tileHeight == 1) {
-	exaFillRegionSolid(pDrawable, pRegion, exaGetPixmapFirstPixel (pTile));
-	return;
-    }
+    if (tileWidth == 1 && tileHeight == 1)
+	return exaFillRegionSolid(pDrawable, pRegion,
+				  exaGetPixmapFirstPixel (pTile), planemask,
+				  alu);
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
@@ -1139,7 +1141,6 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
 	tileWidth > pExaScr->info->maxX ||
 	tileHeight > pExaScr->info->maxY)
     {
-	exaDoMigration (pixmaps, 2, FALSE);
 	goto fallback;
     } else {
 	exaDoMigration (pixmaps, 2, TRUE);
@@ -1153,8 +1154,9 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
     if (!exaPixmapIsOffscreen(pTile))
 	goto fallback;
 
-    if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile, &tileXoff, &tileYoff), pPixmap, 0, 0, GXcopy,
-				       FB_ALLONES))
+    if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
+							     &tileXoff, &tileYoff),
+				       pPixmap, 0, 0, alu, planemask))
     {
 	while (nbox--)
 	{
@@ -1162,7 +1164,7 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
 	    int dstY = pBox->y1;
 	    int tileY;
 
-	    tileY = (dstY - pDrawable->y) % tileHeight;
+	    tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
 	    while (height > 0) {
 		int width = pBox->x2 - pBox->x1;
 		int dstX = pBox->x1;
@@ -1173,7 +1175,7 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
 		    h = height;
 		height -= h;
 
-		tileX = (dstX - pDrawable->x) % tileWidth;
+		tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
 		while (width > 0) {
 		    int w = tileWidth - tileX;
 		    if (w > width)
@@ -1190,38 +1192,44 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
 		dstY += h;
 		tileY = 0;
 	    }
-	    exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
-			    pBox->x2 + xoff, pBox->y2 + yoff);
 	    pBox++;
 	}
 	(*pExaScr->info->DoneCopy) (pPixmap);
 	exaMarkSync(pDrawable->pScreen);
-	return;
+	return TRUE;
     }
 
 fallback:
+    if (alu != GXcopy || planemask != FB_ALLONES)
+	return FALSE;
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
 		  exaDrawableLocation(&pTile->drawable),
 		  exaDrawableLocation(pDrawable)));
+    exaDoMigration (pixmaps, 2, FALSE);
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
     fbFillRegionTiled (pDrawable, pRegion, pTile);
     exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    while (nbox--)
-    {
-	exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-	pBox++;
-    }
+
+    return TRUE;
 }
 
 void
 exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
 {
     ExaScreenPriv (pWin->drawable.pScreen);
-    if (!REGION_NUM_RECTS(pRegion))
+    PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
+    int xoff, yoff;
+    BoxPtr pBox;
+    int nbox = REGION_NUM_RECTS(pRegion);
+
+    if (!nbox)
 	return;
+
     if (!pExaScr->swappedOut) {
+	DDXPointRec zeros = { 0, 0 };
+
         switch (what) {
         case PW_BACKGROUND:
             switch (pWin->backgroundState) {
@@ -1235,25 +1243,41 @@ exaPaintWindow(WindowPtr pWin, RegionPtr
                                                                  what);
                 return;
             case BackgroundPixel:
-                exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel);
-                return;
+		exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
+				   FB_ALLONES, GXcopy);
+                goto damage;
             case BackgroundPixmap:
-                exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap);
-                return;
+                exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
+				   &zeros, FB_ALLONES, GXcopy);
+                goto damage;
             }
             break;
         case PW_BORDER:
             if (pWin->borderIsPixel) {
-                exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel);
-                return;
+                exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
+				   FB_ALLONES, GXcopy);
+                goto damage;
             } else {
-                exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap);
-                return;
+                exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
+				   &zeros, FB_ALLONES, GXcopy);
+                goto damage;
             }
             break;
         }
     }
     ExaCheckPaintWindow (pWin, pRegion, what);
+
+damage:
+    exaGetDrawableDeltas((DrawablePtr)pWin, pPixmap, &xoff, &yoff);
+
+    pBox = REGION_RECTS(pRegion);
+
+    while (nbox--)
+    {
+	exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
+			pBox->x2 + xoff, pBox->y2 + yoff);
+	pBox++;
+    }
 }
 
 /**
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 382f059..b976082 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -288,6 +288,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
 void
 exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
 
+Bool
+exaFillRegionTiled (DrawablePtr	pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+		    DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
+
 void
 exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
 
@@ -344,6 +348,10 @@ void
 exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
 
 void
+exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
+		      int *xp, int *yp);
+
+void
 exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
 
 Bool
diff-tree e869573b52fac69fb88cea120daaeec59c7a3461 (from d3f8667341bfe6dc7d0258c4ad69377f37d88d95)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:45:48 2007 +0200

    EXA: exaAssertNotDirty improvements.
    
    * Return early if the valid region is empty or the pixmap is pinned.
    * Fix loop for several cliprects.

diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index eedc5fd..70d8e12 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -464,12 +464,10 @@ exaAssertNotDirty (PixmapPtr pPixmap)
     BoxPtr pBox = REGION_RECTS(pValidReg);
     Bool ret = TRUE;
 
-    if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL)
+    if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
 	return ret;
 
-    dst = pExaPixmap->sys_ptr;
     dst_pitch = pExaPixmap->sys_pitch;
-    src = pExaPixmap->fb_ptr;
     src_pitch = pExaPixmap->fb_pitch;
     cpp = pPixmap->drawable.bitsPerPixel / 8;
 
@@ -486,21 +484,18 @@ exaAssertNotDirty (PixmapPtr pPixmap)
 		continue;
 
 	    rowbytes = (pBox->x2 - pBox->x1) * cpp;
-	    src += pBox->y1 * src_pitch + pBox->x1 * cpp;
-	    dst += pBox->y1 * dst_pitch + pBox->x1 * cpp;
+	    src = pExaPixmap->fb_ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
+	    dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
 
-	    for (y = pBox->y2 - pBox->y1; y; y--) {
-		if (memcmp(dst + pBox->y1 * dst_pitch + pBox->x1 * cpp,
-			   src + pBox->y1 * src_pitch + pBox->x1 * cpp,
-			   (pBox->x2 - pBox->x1) * cpp) != 0) {
+	    for (y = pBox->y1; y < pBox->y2;
+		 y++, src += src_pitch, dst += dst_pitch) {
+		if (memcmp(dst, src, rowbytes) != 0) {
 		    ret = FALSE;
+		    exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
+				   pBox->y2);
 		    break;
 		}
-		src += src_pitch;
-		dst += dst_pitch;
 	    }
-	    src -= pBox->y1 * src_pitch + pBox->x1 * cpp;
-	    dst -= pBox->y1 * dst_pitch + pBox->x1 * cpp;
     }
     exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
 
diff-tree d3f8667341bfe6dc7d0258c4ad69377f37d88d95 (from 5e4b3232dafe3b0dec65bf639bebaba4774210b7)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:44:27 2007 +0200

    EXA: Fix exaEnableDisableFBAccess for nested disables and enables.

diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 7708dd7..38ad58f 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -341,13 +341,15 @@ exaEnableDisableFBAccess (int index, Boo
     ScreenPtr pScreen = screenInfo.screens[index];
     ExaScreenPriv (pScreen);
 
-    if (!enable) {
+    if (!enable && pExaScr->disableFbCount++ == 0) {
 	if (pExaScr->info->exa_minor < 1)
 	    ExaOffscreenSwapOut (pScreen);
 	else
 	    ExaOffscreenEjectPixmaps (pScreen);
 	pExaScr->swappedOut = TRUE;
-    } else {
+    }
+    
+    if (enable && --pExaScr->disableFbCount == 0) {
 	if (pExaScr->info->exa_minor < 1)
 	    ExaOffscreenSwapIn (pScreen);
 	pExaScr->swappedOut = FALSE;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 984cb66..382f059 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -113,6 +113,7 @@ typedef struct {
     enum ExaMigrationHeuristic	 migration;
     Bool			 hideOffscreenPixmapData;
     Bool			 checkDirtyCorrectness;
+    unsigned			 disableFbCount;
 } ExaScreenPrivRec, *ExaScreenPrivPtr;
 
 /*
diff-tree 5e4b3232dafe3b0dec65bf639bebaba4774210b7 (from 2866e0bac9b8dd3892c5e68abcfc6c97cebaf88a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:38:22 2007 +0200

    Fix fbCompositeTrans_0888xnx0888 build for wfb on big endian.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 2c10398..a735967 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -140,7 +140,7 @@ fbIn (CARD32 x, CARD8 y)
 					temp=count&3; \
 					where-=temp; \
 					workingWhere=(CARD32 *)where; \
-                                        workingVal=READ(workingWhere)++; \
+                                        workingVal=READ(workingWhere++); \
 					count=4-temp; \
 					workingVal<<=(8*temp)
         #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)>>24; (y)<<=8; (x)--;}
diff-tree 2866e0bac9b8dd3892c5e68abcfc6c97cebaf88a (from 78a20455356ccc310f73cfc65ad65a7677eee7e5)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Apr 29 23:38:13 2007 +0200

    Fix a couple of picture repeat fields incorrectly compared to RepeatNormal.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index b78d728..d48a142 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -627,8 +627,8 @@ exaComposite(CARD8	op,
 	    pMask->repeat = 0;
 
     if (pExaScr->info->PrepareComposite &&
-	(!pSrc->repeat || pSrc->repeat == RepeatNormal) &&
-	(!pMask || !pMask->repeat || pMask->repeat == RepeatNormal) &&
+	(!pSrc->repeat || pSrc->repeatType == RepeatNormal) &&
+	(!pMask || !pMask->repeat || pMask->repeatType == RepeatNormal) &&
 	!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
     {
 	Bool isSrcSolid;
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 0a08aff..2c10398 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1495,7 +1495,7 @@ fbComposite (CARD8      op,
     {
 	xMask += pMask->pDrawable->x;
 	yMask += pMask->pDrawable->y;
-	maskRepeat = pMask->repeat == RepeatNormal;
+	maskRepeat = pMask->repeatType == RepeatNormal;
 
 	if (pMask->filter == PictFilterConvolution)
 	    maskTransform = TRUE;
diff --git a/hw/xgl/xglcompose.c b/hw/xgl/xglcompose.c
index d2aead0..34f7a0c 100644
--- a/hw/xgl/xglcompose.c
+++ b/hw/xgl/xglcompose.c
@@ -177,7 +177,7 @@ xglCompositeGeneral (CARD8	     op,
     {
 	if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
 	{
-	    if (pSrc->pDrawable && pSrc->repeat == RepeatNormal)
+	    if (pSrc->pDrawable && pSrc->repeatType == RepeatNormal)
 	    {
 		XGL_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable);
 
diff-tree 78a20455356ccc310f73cfc65ad65a7677eee7e5 (from 6c4f1826bf2c5f30f5fe6e489a02b6375478b380)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 27 15:20:24 2007 -0400

    Pixman merging
    
    More msvc++ porting

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index cea8ad9..a322bec 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -1700,7 +1700,9 @@ fbSolidFillmmx (DrawablePtr	pDraw,
     CARD8	*byte_line;
     FbBits      *bits;
     int		xoff, yoff;
+#ifdef __GNUC__
     __m64	v1, v2, v3, v4, v5, v6, v7;
+#endif
     
     CHECKPOINT();
     
@@ -1730,6 +1732,7 @@ fbSolidFillmmx (DrawablePtr	pDraw,
     fill = ((ullong)xor << 32) | xor;
     vfill = (__m64)fill;
     
+#ifdef __GNUC__
     __asm__ (
 	"movq		%7,	%0\n"
 	"movq		%7,	%1\n"
@@ -1741,6 +1744,7 @@ fbSolidFillmmx (DrawablePtr	pDraw,
 	: "=y" (v1), "=y" (v2), "=y" (v3),
 	  "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
 	: "y" (vfill));
+#endif
     
     while (height--)
     {
@@ -1766,6 +1770,7 @@ fbSolidFillmmx (DrawablePtr	pDraw,
 
 	while (w >= 64)
 	{
+#ifdef __GNUC__
 	    __asm__ (
 		"movq	%1,	  (%0)\n"
 		"movq	%2,	 8(%0)\n"
@@ -1780,7 +1785,16 @@ fbSolidFillmmx (DrawablePtr	pDraw,
 		  "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
 		  "y" (v4), "y" (v5), "y" (v6), "y" (v7)
 		: "memory");
-	    
+#else
+	    *(__m64*) (d +  0) = vfill;
+	    *(__m64*) (d +  8) = vfill;
+	    *(__m64*) (d + 16) = vfill;
+	    *(__m64*) (d + 24) = vfill;
+	    *(__m64*) (d + 32) = vfill;
+	    *(__m64*) (d + 40) = vfill;
+	    *(__m64*) (d + 48) = vfill;
+	    *(__m64*) (d + 56) = vfill;
+#endif    
 	    w -= 64;
 	    d += 64;
 	}
@@ -2823,6 +2837,7 @@ fbCopyAreammx (DrawablePtr	pSrc,
 	
 	while (w >= 64)
 	{
+#ifdef __GNUC__
 	    __asm__ (
 		"movq	  (%1),	  %%mm0\n"
 		"movq	 8(%1),	  %%mm1\n"
@@ -2846,6 +2861,24 @@ fbCopyAreammx (DrawablePtr	pSrc,
 		: "memory",
 		  "%mm0", "%mm1", "%mm2", "%mm3",
 		  "%mm4", "%mm5", "%mm6", "%mm7");
+#else
+	    __m64 v0 = *(__m64 *)(s + 0);
+	    __m64 v1 = *(__m64 *)(s + 8);
+	    __m64 v2 = *(__m64 *)(s + 16);
+	    __m64 v3 = *(__m64 *)(s + 24);
+	    __m64 v4 = *(__m64 *)(s + 32);
+	    __m64 v5 = *(__m64 *)(s + 40);
+	    __m64 v6 = *(__m64 *)(s + 48);
+	    __m64 v7 = *(__m64 *)(s + 56);
+	    *(__m64 *)(d + 0)  = v0;
+	    *(__m64 *)(d + 8)  = v1;
+	    *(__m64 *)(d + 16) = v2;
+	    *(__m64 *)(d + 24) = v3;
+	    *(__m64 *)(d + 32) = v4;
+	    *(__m64 *)(d + 40) = v5;
+	    *(__m64 *)(d + 48) = v6;
+	    *(__m64 *)(d + 56) = v7;
+#endif	    
 	    
 	    w -= 64;
 	    s += 64;
diff-tree 6c4f1826bf2c5f30f5fe6e489a02b6375478b380 (from ae04f2cb0a068cdc1e519627bf745de0c9e4a85a)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 27 08:13:08 2007 -0400

    Bug fix in fbCompositeIn_nx8x8888
    
    Make sure both halves of the dst word is set to zero when the masks
    are both 0.

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 0e90746..cea8ad9 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -1900,7 +1900,7 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (CAR
 	    }
 	    else
 	    {
-		*dst = 0;
+		*(ullong *)dst = 0;
 	    }
 
 	    mask += 2;
diff-tree ae04f2cb0a068cdc1e519627bf745de0c9e4a85a (from 6c8152d6ee9eeb21a68a8bbfed1540939e5bcd1f)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Thu Apr 26 15:28:04 2007 -0400

    Fix the 'relink' target for kdrive servers.

diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am
index e078049..267d772 100644
--- a/hw/kdrive/Makefile.am
+++ b/hw/kdrive/Makefile.am
@@ -23,14 +23,20 @@ if KDRIVELINUX
 LINUX_SUBDIRS = linux
 endif
 
-SUBDIRS =			\
-	src			\
-	$(LINUX_SUBDIRS)	\
+SERVER_SUBDIRS = 		\
 	$(XSDL_SUBDIRS)		\
 	$(FBDEV_SUBDIRS)	\
 	$(VESA_SUBDIRS)		\
 	$(XEPHYR_SUBDIRS)       \
 	$(XFAKE_SUBDIRS)
 
+SUBDIRS =			\
+	src			\
+	$(LINUX_SUBDIRS)	\
+	$(SERVER_SUBDIRS)
+
 DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \
                smi via fbdev sdl ephyr src linux fake sis300
+
+relink:
+	@for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done
diff --git a/hw/kdrive/ati/Makefile.am b/hw/kdrive/ati/Makefile.am
index 76635fb..61c1c84 100644
--- a/hw/kdrive/ati/Makefile.am
+++ b/hw/kdrive/ati/Makefile.am
@@ -62,3 +62,6 @@ Xati_LDADD = \
 	$(ATI_LIBS)			\
 	@KDRIVE_LIBS@			\
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/chips/Makefile.am b/hw/kdrive/chips/Makefile.am
index 2f8a88d..a0a10d7 100644
--- a/hw/kdrive/chips/Makefile.am
+++ b/hw/kdrive/chips/Makefile.am
@@ -24,3 +24,6 @@ Xchips_LDADD = \
 	$(CHIPS_LIBS)				\
 	@KDRIVE_LIBS@                           \
 	@XSERVER_LIBS@				
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index c201fe9..1e820c0 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -29,3 +29,6 @@ Xephyr_LDADD = 						\
 	../../../exa/libexa.la				\
 	@KDRIVE_LIBS@					\
         @XEPHYR_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/epson/Makefile.am b/hw/kdrive/epson/Makefile.am
index a5bc70b..d36230a 100644
--- a/hw/kdrive/epson/Makefile.am
+++ b/hw/kdrive/epson/Makefile.am
@@ -24,3 +24,6 @@ Xepson_LDADD = \
 	$(EPSON_LIBS)			       \
 	@KDRIVE_LIBS@                          \
 	@XSERVER_LIBS@				
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/fake/Makefile.am b/hw/kdrive/fake/Makefile.am
index d7ebfc2..69fdf59 100644
--- a/hw/kdrive/fake/Makefile.am
+++ b/hw/kdrive/fake/Makefile.am
@@ -20,3 +20,6 @@ Xfake_LDADD = 						\
 	libfake.a					\
 	@KDRIVE_LIBS@					\
         @XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index cb71801..b7a863b 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -18,4 +18,7 @@ Xfbdev_LDADD = 						\
 	libfbdev.a					\
 	@KDRIVE_LIBS@					\
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
 endif
diff --git a/hw/kdrive/i810/Makefile.am b/hw/kdrive/i810/Makefile.am
index 5039585..79093da 100644
--- a/hw/kdrive/i810/Makefile.am
+++ b/hw/kdrive/i810/Makefile.am
@@ -27,3 +27,6 @@ Xi810_LDADD = \
 	$(I810_LIBS)					\
 	@KDRIVE_LIBS@                                  \
 	@XSERVER_LIBS@					
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/mach64/Makefile.am b/hw/kdrive/mach64/Makefile.am
index 67712e2..b4d9a4e 100644
--- a/hw/kdrive/mach64/Makefile.am
+++ b/hw/kdrive/mach64/Makefile.am
@@ -31,3 +31,6 @@ Xmach64_LDADD = 					\
 	$(MACH64_LIBS)					\
 	@KDRIVE_LIBS@					\
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/mga/Makefile.am b/hw/kdrive/mga/Makefile.am
index ee07989..db1a956 100644
--- a/hw/kdrive/mga/Makefile.am
+++ b/hw/kdrive/mga/Makefile.am
@@ -26,3 +26,6 @@ Xmga_LDADD = \
 	$(MGA_LIBS)					\
 	@KDRIVE_LIBS@                                  \
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/neomagic/Makefile.am b/hw/kdrive/neomagic/Makefile.am
index 9a1af99..33bc3a9 100644
--- a/hw/kdrive/neomagic/Makefile.am
+++ b/hw/kdrive/neomagic/Makefile.am
@@ -38,3 +38,6 @@ Xneomagic_LDADD = \
 	$(NEOMAGIC_LIBS)            \
 	@KDRIVE_LIBS@               \
 	@XSERVER_LIBS@		  
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/nvidia/Makefile.am b/hw/kdrive/nvidia/Makefile.am
index 67eff69..79d2738 100644
--- a/hw/kdrive/nvidia/Makefile.am
+++ b/hw/kdrive/nvidia/Makefile.am
@@ -27,3 +27,6 @@ Xnvidia_LDADD = \
 	$(NVIDIA_LIBS)				\
 	@KDRIVE_LIBS@				\
 	@XSERVER_LIBS@			
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/pm2/Makefile.am b/hw/kdrive/pm2/Makefile.am
index a7b0f00..ec70276 100644
--- a/hw/kdrive/pm2/Makefile.am
+++ b/hw/kdrive/pm2/Makefile.am
@@ -25,3 +25,6 @@ Xpm2_LDADD = \
 	$(PM2_LIBS)				\
 	@KDRIVE_LIBS@                          \
 	@XSERVER_LIBS@			
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/r128/Makefile.am b/hw/kdrive/r128/Makefile.am
index eab80cc..1ca1a60 100644
--- a/hw/kdrive/r128/Makefile.am
+++ b/hw/kdrive/r128/Makefile.am
@@ -24,3 +24,6 @@ Xr128_LDADD = \
 	$(R128_LIBS)				\
 	@KDRIVE_LIBS@                          \
 	@XSERVER_LIBS@					
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/sdl/Makefile.am b/hw/kdrive/sdl/Makefile.am
index f5abb86..fa09640 100644
--- a/hw/kdrive/sdl/Makefile.am
+++ b/hw/kdrive/sdl/Makefile.am
@@ -11,3 +11,6 @@ Xsdl_LDADD = @KDRIVE_PURE_LIBS@				\
 	@KDRIVE_LIBS@                                  \
 	@XSERVER_LIBS@					\
 	@XSDL_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/sis300/Makefile.am b/hw/kdrive/sis300/Makefile.am
index 9802074..62f3266 100644
--- a/hw/kdrive/sis300/Makefile.am
+++ b/hw/kdrive/sis300/Makefile.am
@@ -38,3 +38,6 @@ Xsis_LDADD = \
 	$(SIS_LIBS)				\
 	@KDRIVE_LIBS@                          \
 	$(TSLIB_FLAG)
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/smi/Makefile.am b/hw/kdrive/smi/Makefile.am
index 0fd9729..a6ac474 100644
--- a/hw/kdrive/smi/Makefile.am
+++ b/hw/kdrive/smi/Makefile.am
@@ -29,3 +29,6 @@ Xsmi_LDADD = \
 	$(SMI_LIBS)				\
 	@KDRIVE_LIBS@                          \
 	@XSERVER_LIBS@					
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/vesa/Makefile.am b/hw/kdrive/vesa/Makefile.am
index 54a6f47..e062fe7 100644
--- a/hw/kdrive/vesa/Makefile.am
+++ b/hw/kdrive/vesa/Makefile.am
@@ -23,3 +23,6 @@ Xvesa_LDADD = \
 	libvesa.a 				\
 	@KDRIVE_LIBS@				\
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/via/Makefile.am b/hw/kdrive/via/Makefile.am
index 0ea8881..1c57969 100644
--- a/hw/kdrive/via/Makefile.am
+++ b/hw/kdrive/via/Makefile.am
@@ -25,3 +25,6 @@ Xvia_LDADD =						\
 	$(VIA_LIBS)					\
 	@KDRIVE_LIBS@					\
 	@XSERVER_LIBS@
+
+relink:
+	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff-tree 6c8152d6ee9eeb21a68a8bbfed1540939e5bcd1f (from 2208c6087d6bffcb24a30891a56430e28735874c)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Thu Apr 26 14:59:04 2007 -0400

    Remove old edid_modes.c, it lives in hw/xfree86/modes/ now.

diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
deleted file mode 100644
index 926bc89..0000000
--- a/hw/xfree86/ddc/edid_modes.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-
-/*
- * TODO:
- *  - for those with access to the VESA DMT standard; review please.
- */
-#define MODEPREFIX(name) NULL, NULL, name, 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
-
-DisplayModeRec DDCEstablishedModes[17] = {
-    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
-    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
-    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
-    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
-    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
-    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
-    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
-    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
-    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
-    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
-    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
-    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
-    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
-    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
-    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
-};
-
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
-        ((timing->t_manu & 0x80) << 9);
-    int i;
-
-    for (i = 0; i < 17; i++) {
-        if (bits & (0x01 << i)) {
-            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-    }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    int i;
-
-    for (i = 0; i < STD_TIMINGS; i++) {
-        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
-            Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
-                                timing[i].refresh, FALSE, FALSE);
-	    Mode->type = M_T_DRIVER;
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-    }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred)
-{
-    DisplayModePtr Mode;
-
-    /*
-     * Refuse to create modes that are insufficiently large.  64 is a random
-     * number, maybe the spec says something about what the minimum is.  In
-     * particular I see this frequently with _old_ EDID, 1.0 or so, so maybe
-     * our parser is just being too aggresive there.
-     */
-    if (timing->h_active < 64 || timing->v_active < 64) {
-	xf86DrvMsg(scrnIndex, X_INFO,
-		   "%s: Ignoring tiny %dx%d mode\n", __func__,
-		   timing->h_active, timing->v_active);
-	return NULL;
-    }
-
-    /* We don't do stereo */
-    if (timing->stereo) {
-        xf86DrvMsg(scrnIndex, X_INFO,
-		   "%s: Ignoring: We don't handle stereo.\n", __func__);
-        return NULL;
-    }
-
-    /* We only do seperate sync currently */
-    if (timing->sync != 0x03) {
-         xf86DrvMsg(scrnIndex, X_INFO,
-		    "%s: %dx%d Warning: We only handle seperate"
-                    " sync.\n", __func__, timing->h_active, timing->v_active);
-    }
-
-    Mode = xnfalloc(sizeof(DisplayModeRec));
-    memset(Mode, 0, sizeof(DisplayModeRec));
-
-    Mode->type = M_T_DRIVER;
-    if (preferred)
-	Mode->type |= M_T_PREFERRED;
-
-    Mode->Clock = timing->clock / 1000.0;
-
-    Mode->HDisplay = timing->h_active;
-    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
-    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
-    Mode->HTotal = timing->h_active + timing->h_blanking;
-
-    Mode->VDisplay = timing->v_active;
-    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
-    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
-    Mode->VTotal = timing->v_active + timing->v_blanking;
-
-    xf86SetModeDefaultName(Mode);
-
-    /* We ignore h/v_size and h/v_border for now. */
-
-    if (timing->interlaced)
-        Mode->Flags |= V_INTERLACE;
-
-    if (timing->misc & 0x02)
-        Mode->Flags |= V_PHSYNC;
-    else
-        Mode->Flags |= V_NHSYNC;
-
-    if (timing->misc & 0x01)
-        Mode->Flags |= V_PVSYNC;
-    else
-        Mode->Flags |= V_NVSYNC;
-
-    return Mode;
-}
-
-/*
- *
- */
-static void
-DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
-{
-    DisplayModePtr Mode = Modes;
-
-    if (!Monitor || !Modes)
-        return;
-
-    /* set up the ranges for scanning through the modes */
-    Monitor->nHsync = 1;
-    Monitor->hsync[0].lo = 1024.0;
-    Monitor->hsync[0].hi = 0.0;
-
-    Monitor->nVrefresh = 1;
-    Monitor->vrefresh[0].lo = 1024.0;
-    Monitor->vrefresh[0].hi = 0.0;
-
-    while (Mode) {
-        if (!Mode->HSync)
-            Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
-
-        if (!Mode->VRefresh)
-            Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
-                ((float) (Mode->HTotal * Mode->VTotal));
-
-        if (Mode->HSync < Monitor->hsync[0].lo)
-            Monitor->hsync[0].lo = Mode->HSync;
-
-        if (Mode->HSync > Monitor->hsync[0].hi)
-            Monitor->hsync[0].hi = Mode->HSync;
-
-        if (Mode->VRefresh < Monitor->vrefresh[0].lo)
-            Monitor->vrefresh[0].lo = Mode->VRefresh;
-
-        if (Mode->VRefresh > Monitor->vrefresh[0].hi)
-            Monitor->vrefresh[0].hi = Mode->VRefresh;
-
-        Mode = Mode->next;
-    }
-}
-
-DisplayModePtr
-xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
-{
-    int preferred, i;
-    DisplayModePtr Modes = NULL, Mode;
-
-    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-
-    /* Add established timings */
-    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    /* Add standard timings */
-    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    for (i = 0; i < DET_TIMINGS; i++) {
-	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
-
-        switch (det_mon->type) {
-        case DT:
-            Mode = DDCModeFromDetailedTiming(scrnIndex,
-                                             &det_mon->section.d_timings,
-					     preferred);
-	    preferred = 0;
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        case DS_STD_TIMINGS:
-            Mode = DDCModesFromStandardTiming(scrnIndex,
-					      det_mon->section.std_t);
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        default:
-            break;
-        }
-    }
-
-    return Modes;
-}
-
-/*
- * Fill out MonPtr with xf86MonPtr information.
- */
-void
-xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
-{
-    DisplayModePtr Modes = NULL, Mode;
-    int i, clock;
-    Bool have_hsync = FALSE, have_vrefresh = FALSE;
-
-    if (!Monitor || !DDC)
-        return;
-
-    Monitor->DDC = DDC;
-
-    Monitor->widthmm = 10 * DDC->features.hsize;
-    Monitor->heightmm = 10 * DDC->features.vsize;
-
-    /* If this is a digital display, then we can use reduced blanking */
-    if (DDC->features.input_type)
-        Monitor->reducedblanking = TRUE;
-    /* Allow the user to also enable this through config */
-
-    Modes = xf86DDCGetModes(scrnIndex, DDC);
-
-    /* Skip EDID ranges if they were specified in the config file */
-    have_hsync = (Monitor->nHsync != 0);
-    have_vrefresh = (Monitor->nVrefresh != 0);
-
-    /* Go through the detailed monitor sections */
-    for (i = 0; i < DET_TIMINGS; i++) {
-        switch (DDC->det_mon[i].type) {
-        case DS_RANGES:
-	    if (!have_hsync) {
-		if (!Monitor->nHsync)
-		    xf86DrvMsg(scrnIndex, X_INFO,
-			    "Using EDID range info for horizontal sync\n");
-		Monitor->hsync[Monitor->nHsync].lo =
-		    DDC->det_mon[i].section.ranges.min_h;
-		Monitor->hsync[Monitor->nHsync].hi =
-		    DDC->det_mon[i].section.ranges.max_h;
-		Monitor->nHsync++;
-	    } else {
-		xf86DrvMsg(scrnIndex, X_INFO,
-			"Using hsync ranges from config file\n");
-	    }
-
-	    if (!have_vrefresh) {
-		if (!Monitor->nVrefresh)
-		    xf86DrvMsg(scrnIndex, X_INFO,
-			    "Using EDID range info for vertical refresh\n");
-		Monitor->vrefresh[Monitor->nVrefresh].lo =
-		    DDC->det_mon[i].section.ranges.min_v;
-		Monitor->vrefresh[Monitor->nVrefresh].hi =
-		    DDC->det_mon[i].section.ranges.max_v;
-		Monitor->nVrefresh++;
-	    } else {
-		xf86DrvMsg(scrnIndex, X_INFO,
-			"Using vrefresh ranges from config file\n");
-	    }
-
-	    clock = DDC->det_mon[i].section.ranges.max_clock * 1000;
-	    if (clock > Monitor->maxPixClock)
-		Monitor->maxPixClock = clock;
-
-            break;
-        default:
-            break;
-        }
-    }
-
-    if (Modes) {
-        /* Print Modes */
-        xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
-
-        Mode = Modes;
-        while (Mode) {
-            xf86PrintModeline(scrnIndex, Mode);
-            Mode = Mode->next;
-        }
-
-        /* Do we still need ranges to be filled in? */
-        if (!Monitor->nHsync || !Monitor->nVrefresh)
-            DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
-
-        /* look for last Mode */
-        Mode = Modes;
-
-        while (Mode->next)
-            Mode = Mode->next;
-
-        /* add to MonPtr */
-        if (Monitor->Modes) {
-            Monitor->Last->next = Modes;
-            Modes->prev = Monitor->Last;
-            Monitor->Last = Mode;
-        } else {
-            Monitor->Modes = Modes;
-            Monitor->Last = Mode;
-        }
-    }
-}
diff-tree 2208c6087d6bffcb24a30891a56430e28735874c (from a300ef84cee26febfbe08c497d0d063588130bdd)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 14:40:30 2007 -0400

    Change expand_alpha_rev to expand_alpha in mmxSaturateU

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 164776a..0e90746 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -640,7 +640,7 @@ mmxCombineSaturateU (CARD32 *dest, const
 
         if (sa > da) {
             __m64 msa = load8888(FbIntDiv(da, sa) << 24);
-            msa = expand_alpha_rev(msa);
+            msa = expand_alpha(msa);
             ms = pix_multiply(ms, msa);
         }
         md = pix_add(md, ms);
diff-tree a300ef84cee26febfbe08c497d0d063588130bdd (from 0ebe48be59368b55c618f60d4656300bd7f52ed9)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 14:37:53 2007 -0400

    Fix typo in previous commit

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 7f1a7b1..164776a 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -639,7 +639,7 @@ mmxCombineSaturateU (CARD32 *dest, const
         CARD32 da = ~d >> 24;
 
         if (sa > da) {
-            __m64 msa = load8888(FbIntDiv(da, sa))<<24;
+            __m64 msa = load8888(FbIntDiv(da, sa) << 24);
             msa = expand_alpha_rev(msa);
             ms = pix_multiply(ms, msa);
         }
diff-tree 0ebe48be59368b55c618f60d4656300bd7f52ed9 (from 4fe918b38553133c27e5ae672e5c43984a9bbaea)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 14:36:32 2007 -0400

    Pixman merge
    
    - Changes to support MS Visual C++
    
    - use inline instead of __inline__
    
    - Fix rounding errors (Billy Biggs, from xserver via pixman)

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 875fec0..7f1a7b1 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -85,30 +85,40 @@
 
 typedef unsigned long long ullong;
 
+#ifdef __GNUC__
+typedef ullong mmxdatafield;
+#endif
+#ifdef _MSC_VER
+typedef unsigned __int64 ullong;
+typedef __m64 mmxdatafield;
+#endif
+
 typedef struct
 {
-    ullong mmx_4x00ff;
-    ullong mmx_4x0080;
-    ullong mmx_565_rgb;
-    ullong mmx_565_unpack_multiplier;
-    ullong mmx_565_r;
-    ullong mmx_565_g;
-    ullong mmx_565_b;
-    ullong mmx_mask_0;
-    ullong mmx_mask_1;
-    ullong mmx_mask_2;
-    ullong mmx_mask_3;
-    ullong mmx_full_alpha;
-    ullong mmx_ffff0000ffff0000;
-    ullong mmx_0000ffff00000000;
-    ullong mmx_000000000000ffff;
+    mmxdatafield mmx_4x00ff;
+    mmxdatafield mmx_4x0080;
+    mmxdatafield mmx_565_rgb;
+    mmxdatafield mmx_565_unpack_multiplier;
+    mmxdatafield mmx_565_r;
+    mmxdatafield mmx_565_g;
+    mmxdatafield mmx_565_b;
+    mmxdatafield mmx_mask_0;
+    mmxdatafield mmx_mask_1;
+    mmxdatafield mmx_mask_2;
+    mmxdatafield mmx_mask_3;
+    mmxdatafield mmx_full_alpha;
+    mmxdatafield mmx_ffff0000ffff0000;
+    mmxdatafield mmx_0000ffff00000000;
+    mmxdatafield mmx_000000000000ffff;
 } MMXData;
 
 static const MMXData c =
 {
+#ifdef __GNUC__
     .mmx_4x00ff =			0x00ff00ff00ff00ffULL,
     .mmx_4x0080 =			0x0080008000800080ULL,
     .mmx_565_rgb =			0x000001f0003f001fULL,
+    .mmx_565_unpack_multiplier =	0x0000008404100840ULL,
     .mmx_565_r =			0x000000f800000000ULL,
     .mmx_565_g =			0x0000000000fc0000ULL,
     .mmx_565_b =			0x00000000000000f8ULL,
@@ -117,15 +127,42 @@ static const MMXData c =
     .mmx_mask_2 =			0xffff0000ffffffffULL,
     .mmx_mask_3 =			0x0000ffffffffffffULL,
     .mmx_full_alpha =			0x00ff000000000000ULL,
-    .mmx_565_unpack_multiplier =	0x0000008404100840ULL,
     .mmx_ffff0000ffff0000 =		0xffff0000ffff0000ULL,
     .mmx_0000ffff00000000 =		0x0000ffff00000000ULL,
     .mmx_000000000000ffff =		0x000000000000ffffULL,
+#endif
+#ifdef _MSC_VER
+    { 0x00ff00ff00ff00ffUI64 },
+    { 0x0080008000800080UI64 },
+    { 0x000001f0003f001fUI64 },
+    { 0x0000008404100840UI64 },
+    { 0x000000f800000000UI64 },
+    { 0x0000000000fc0000UI64 },
+    { 0x00000000000000f8UI64 },
+    { 0xffffffffffff0000UI64 },
+    { 0xffffffff0000ffffUI64 },
+    { 0xffff0000ffffffffUI64 },
+    { 0x0000ffffffffffffUI64 },
+    { 0x00ff000000000000UI64 },
+    { 0xffff0000ffff0000UI64 },
+    { 0x0000ffff00000000UI64 },
+    { 0x000000000000ffffUI64 },
+#endif
 };
 
+#ifdef _MSC_VER
+#undef inline
+#define inline __forceinline
+#endif
+
+#ifdef __GNUC__
 #define MC(x) ((__m64) c.mmx_##x)
+#endif
+#ifdef _MSC_VER
+#define MC(x) c.mmx_##x
+#endif
 
-static __inline__ __m64
+static inline __m64
 shift (__m64 v, int s)
 {
     if (s > 0)
@@ -136,13 +173,13 @@ shift (__m64 v, int s)
 	return v;
 }
 
-static __inline__ __m64
+static inline __m64
 negate (__m64 mask)
 {
     return _mm_xor_si64 (mask, MC(4x00ff));
 }
 
-static __inline__ __m64
+static inline __m64
 pix_multiply (__m64 a, __m64 b)
 {
     __m64 res;
@@ -155,7 +192,7 @@ pix_multiply (__m64 a, __m64 b)
     return res;
 }
 
-static __inline__ __m64
+static inline __m64
 pix_add (__m64 a, __m64 b)
 {
     return  _mm_adds_pu8 (a, b);
@@ -163,19 +200,19 @@ pix_add (__m64 a, __m64 b)
 
 #ifdef USE_SSE
 
-static __inline__ __m64
+static inline __m64
 expand_alpha (__m64 pixel)
 {
     return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 3, 3, 3));
 }
 
-static __inline__ __m64
+static inline __m64
 expand_alpha_rev (__m64 pixel)
 {
     return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(0, 0, 0, 0));
 }    
 
-static __inline__ __m64
+static inline __m64
 invert_colors (__m64 pixel)
 {
     return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 0, 1, 2));
@@ -183,7 +220,7 @@ invert_colors (__m64 pixel)
 
 #else
 
-static __inline__ __m64
+static inline __m64
 expand_alpha (__m64 pixel)
 {
     __m64 t1, t2;
@@ -197,7 +234,7 @@ expand_alpha (__m64 pixel)
     return t1;
 }
 
-static __inline__ __m64
+static inline __m64
 expand_alpha_rev (__m64 pixel)
 {
     __m64 t1, t2;
@@ -214,7 +251,7 @@ expand_alpha_rev (__m64 pixel)
     return t1;
 }
 
-static __inline__ __m64
+static inline __m64
 invert_colors (__m64 pixel)
 {
     __m64 x, y, z;
@@ -236,13 +273,13 @@ invert_colors (__m64 pixel)
 
 #endif
 
-static __inline__ __m64
+static inline __m64
 over (__m64 src, __m64 srca, __m64 dest)
 {
     return  _mm_adds_pu8 (src, pix_multiply(dest, negate(srca)));
 }
 
-static __inline__ __m64
+static inline __m64
 over_rev_non_pre (__m64 src, __m64 dest)
 {
     __m64 srca = expand_alpha (src);
@@ -251,14 +288,15 @@ over_rev_non_pre (__m64 src, __m64 dest)
     return over(pix_multiply(invert_colors(src), srcfaaa), srca, dest);
 }
 
-static __inline__ __m64
+static inline __m64
 in (__m64 src,
     __m64 mask)
 {
     return pix_multiply (src, mask);
 }
 
-static __inline__ __m64
+#ifndef _MSC_VER
+static inline __m64
 in_over (__m64 src,
 	 __m64 srca,
 	 __m64 mask,
@@ -266,20 +304,23 @@ in_over (__m64 src,
 {
     return over(in(src, mask), pix_multiply(srca, mask), dest);
 }
+#else
+#define in_over(src, srca, mask, dest) over(in(src, mask), pix_multiply(srca, mask), dest)
+#endif
 
-static __inline__ __m64
+static inline __m64
 load8888 (CARD32 v)
 {
     return _mm_unpacklo_pi8 (_mm_cvtsi32_si64 (v), _mm_setzero_si64());
 }
 
-static __inline__ __m64
+static inline __m64
 pack8888 (__m64 lo, __m64 hi)
 {
     return _mm_packs_pu16 (lo, hi);
 }
 
-static __inline__ CARD32
+static inline CARD32
 store8888 (__m64 v)
 {
     return _mm_cvtsi64_si32(pack8888(v, _mm_setzero_si64()));
@@ -299,7 +340,7 @@ store8888 (__m64 v)
  * Note the trick here - the top word is shifted by another nibble to
  * avoid it bumping into the middle word
  */
-static __inline__ __m64
+static inline __m64
 expand565 (__m64 pixel, int pos)
 {
     __m64 p = pixel;
@@ -319,7 +360,7 @@ expand565 (__m64 pixel, int pos)
     return _mm_srli_pi16 (pixel, 8);
 }
 
-static __inline__ __m64
+static inline __m64
 expand8888 (__m64 in, int pos)
 {
     if (pos == 0)
@@ -328,7 +369,7 @@ expand8888 (__m64 in, int pos)
 	return _mm_unpackhi_pi8 (in, _mm_setzero_si64());
 }
 
-static __inline__ __m64
+static inline __m64
 pack565 (__m64 pixel, __m64 target, int pos)
 {
     __m64 p = pixel;
@@ -358,20 +399,28 @@ pack565 (__m64 pixel, __m64 target, int 
     return _mm_or_si64 (b, p);
 }
 
-static __inline__ __m64
+#ifndef _MSC_VER
+static inline __m64
 pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b)
 {
-    x = _mm_mullo_pi16 (x, a);                  
-    y = _mm_mullo_pi16 (y, b);                  
-    x = _mm_srli_pi16(x, 1);                    
-    y = _mm_srli_pi16(y, 1);                    
-    x = _mm_adds_pu16 (x, y);                    
-    x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8)); 
+    x = _mm_mullo_pi16 (x, a);
+    y = _mm_mullo_pi16 (y, b);
     x = _mm_adds_pu16 (x, MC(4x0080));
-    x = _mm_srli_pi16 (x, 7);
+    x = _mm_adds_pu16 (x, y);
+    x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8));
+    x = _mm_srli_pi16 (x, 8);
 
     return x;
 }
+#else
+#define pix_add_mul(x, a, y, b) \
+( x = _mm_mullo_pi16 (x, a), \
+  y = _mm_mullo_pi16 (y, b), \
+  x = _mm_adds_pu16 (x, MC(4x0080)), \
+  x = _mm_adds_pu16 (x, y), \
+  x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8)), \
+  _mm_srli_pi16 (x, 8) )
+#endif
 
 /* --------------- MMX code patch for fbcompose.c --------------------- */
 
@@ -590,7 +639,7 @@ mmxCombineSaturateU (CARD32 *dest, const
         CARD32 da = ~d >> 24;
 
         if (sa > da) {
-            __m64 msa = load8888(FbIntDiv(da, sa));
+            __m64 msa = load8888(FbIntDiv(da, sa))<<24;
             msa = expand_alpha_rev(msa);
             ms = pix_multiply(ms, msa);
         }
diff-tree 4fe918b38553133c27e5ae672e5c43984a9bbaea (from 0ff7c94fcf6497ee8575f81cf97eeeb3a857739e)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 12:41:01 2007 -0400

    Fix bug 8871 - scrolling corruption with a compositing manager
    
    Call miHandleExposures() in CopyArea/CopyPlane explicitly in cw to
    generate GraphicsExposes correctly.

diff --git a/miext/cw/cw_ops.c b/miext/cw/cw_ops.c
index 80b7280..82ec999 100644
--- a/miext/cw/cw_ops.c
+++ b/miext/cw/cw_ops.c
@@ -30,6 +30,7 @@
 #include "gcstruct.h"
 #include "pixmapstr.h"
 #include "cw.h"
+#include "mi.h"
 
 #define SETUP_BACKING_DST(_pDst, _pGC) \
     cwGCPtr pGCPrivate = getCwGC (_pGC); \
@@ -185,7 +186,7 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr
 	   int w, int h, int dstx, int dsty)
 {
     int		odstx, odsty;
-    RegionPtr	exposed = NULL;
+    int		osrcx, osrcy;
     SETUP_BACKING_DST(pDst, pGC);
     SETUP_BACKING_SRC(pSrc, pGC);
 
@@ -193,19 +194,20 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr
 
     odstx = dstx;
     odsty = dsty;
+    osrcx = srcx;
+    osrcy = srcy;
     CW_OFFSET_XY_DST(dstx, dsty);
     CW_OFFSET_XY_SRC(srcx, srcy);
 
-    exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
-					   pBackingGC, srcx, srcy, w, h,
-					   dstx, dsty);
-
-    if (exposed != NULL)
-	REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
-
+    (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
+				 pBackingGC, srcx, srcy, w, h,
+				 dstx, dsty);
+    
     EPILOGUE(pGC);
 
-    return exposed;
+    return miHandleExposures(pSrc, pDst, pGC,
+			     osrcx, osrcy, w, h,
+			     odstx, odsty, 0);
 }
 
 static RegionPtr
@@ -213,7 +215,7 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePt
 	    int w, int h, int dstx, int dsty, unsigned long plane)
 {
     int		odstx, odsty;
-    RegionPtr	exposed = NULL;
+    int		osrcx, osrcy;
     SETUP_BACKING_DST(pDst, pGC);
     SETUP_BACKING_SRC(pSrc, pGC);
 
@@ -221,19 +223,20 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePt
 
     odstx = dstx;
     odsty = dsty;
+    osrcx = srcx;
+    osrcy = srcy;
     CW_OFFSET_XY_DST(dstx, dsty);
     CW_OFFSET_XY_SRC(srcx, srcy);
 
-    exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
-					    pBackingGC, srcx, srcy, w, h,
-					    dstx, dsty, plane);
-
-    if (exposed != NULL)
-	REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
+    (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
+				  pBackingGC, srcx, srcy, w, h,
+				  dstx, dsty, plane);
 
     EPILOGUE(pGC);
 
-    return exposed;
+    return miHandleExposures(pSrc, pDst, pGC,
+			     osrcx, osrcy, w, h,
+			     odstx, odsty, plane);
 }
 
 static void
diff-tree 0ff7c94fcf6497ee8575f81cf97eeeb3a857739e (from 701ccb4a22cfd646ccb7f19b7b3a476aeb5ce2da)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 10:56:02 2007 -0400

    Pixman merge
    
    Make use of fbCompositeSrcAdd_8888x8x8mmx

diff --git a/fb/fbpict.c b/fb/fbpict.c
index ace19fd..0a08aff 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1962,7 +1962,12 @@ fbComposite (CARD8      op,
 		pDst->format == PICT_a8)
 	    {
 		srcRepeat = FALSE;
-		func = fbCompositeSrcAdd_8888x8x8;
+#ifdef USE_MMX
+		if (fbHaveMMX())
+		    func = fbCompositeSrcAdd_8888x8x8mmx;
+		else
+#endif
+		    func = fbCompositeSrcAdd_8888x8x8;
 	    }
 	}
 	break;
diff-tree 701ccb4a22cfd646ccb7f19b7b3a476aeb5ce2da (from a54ef54db19dcd36ed86b33cff2bc369f9690a15)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 10:49:06 2007 -0400

    Pixman merge
    
    - Remove stray default label
    
    - Integrate new MMX ops SolidMaskSrc_nx8x8888mmx, In_8x8mmx, and
      In_nx8x8mmx
    
    - Formatting changes to reduce diff noise

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 1932b3e..ace19fd 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1641,8 +1641,6 @@ fbComposite (CARD8      op,
 		    default:
 			break;
 		    }
-		default:
-		    break;
 		}
 		if (func != fbCompositeGeneral)
 		    srcRepeat = FALSE;
@@ -1969,19 +1967,73 @@ fbComposite (CARD8      op,
 	}
 	break;
     case PictOpSrc:
-#ifdef USE_MMX
-	if (!pMask && pSrc->format == pDst->format &&
-	    pSrc->format != PICT_a8 && pSrc->pDrawable != pDst->pDrawable)
+	if (pMask)
 	{
-	    func = fbCompositeCopyAreammx;
+#ifdef USE_MMX
+	    if (fbCanGetSolid (pSrc))
+	    {
+		if (pMask->format == PICT_a8)
+		{
+		    switch (pDst->format)
+		    {
+		    case PICT_a8r8g8b8:
+		    case PICT_x8r8g8b8:
+		    case PICT_a8b8g8r8:
+		    case PICT_x8b8g8r8:
+			if (fbHaveMMX())
+			{
+			    srcRepeat = FALSE;
+			    func = fbCompositeSolidMaskSrc_nx8x8888mmx;
+			}
+			break;
+		    default:
+			break;
+		    }
+		}
+	    }
+#endif
 	}
 	else
-#endif
-	    if (pMask == 0)
+	{
+	    if (pSrc->format == pDst->format)
 	    {
-		if (pSrc->format == pDst->format)
+#ifdef USE_MMX
+		if (pSrc->pDrawable != pDst->pDrawable && fbHaveMMX() &&
+		    (PICT_FORMAT_BPP (pSrc->format) == 16 ||
+		     PICT_FORMAT_BPP (pSrc->format) == 32))
+		    func = fbCompositeCopyAreammx;
+		else
+#endif
 		    func = fbCompositeSrcSrc_nxn;
 	    }
+	}
+	break;
+    case PictOpIn:
+#ifdef USE_MMX
+	if (pSrc->format == PICT_a8 &&
+	    pDst->format == PICT_a8 &&
+	    !pMask)
+	{
+	    if (fbHaveMMX())
+		func = fbCompositeIn_8x8mmx;
+	}
+	else if (srcRepeat && pMask && !pMask->componentAlpha &&
+		 (pSrc->format == PICT_a8r8g8b8 ||
+		  pSrc->format == PICT_a8b8g8r8)   &&
+		 (pMask->format == PICT_a8)        &&
+		 pDst->format == PICT_a8)
+	{
+	    if (fbHaveMMX())
+	    {
+		srcRepeat = FALSE;
+		func = fbCompositeIn_nx8x8mmx;
+	    }
+	}
+#else
+	func = NULL;
+#endif
+       break;
+    default:
 	break;
     }
 
@@ -1991,26 +2043,16 @@ fbComposite (CARD8      op,
          return;
     }
 
-    if (!miComputeCompositeRegion (&region,
- 				   pSrc,
- 				   pMask,
- 				   pDst,
- 				   xSrc,
- 				   ySrc,
- 				   xMask,
- 				   yMask,
- 				   xDst,
- 				   yDst,
- 				   width,
-                                   height))
-        return;
-
     /* if we are transforming, we handle repeats in fbFetchTransformed */
     if (srcTransform)
 	srcRepeat = FALSE;
     if (maskTransform)
 	maskRepeat = FALSE;
     
+    if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
+				   xMask, yMask, xDst, yDst, width, height))
+        return;
+
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
     while (n--)
diff-tree a54ef54db19dcd36ed86b33cff2bc369f9690a15 (from 3571b8e65b0857322d12e291305cfe29ea497c3c)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 10:24:25 2007 -0400

    Pixman merge
    
    Make sure fbCompositeSrc_x888x8x8888mmx and fbCompositeSrc_8888x8x8888mmx
    are used when possible.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 4fb949d..1932b3e 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1647,7 +1647,7 @@ fbComposite (CARD8      op,
 		if (func != fbCompositeGeneral)
 		    srcRepeat = FALSE;
 	    }
-	    else if (! srcRepeat) /* has mask and non-repeating source */
+	    else if (!srcRepeat) /* has mask and non-repeating source */
 	    {
 		if (pSrc->pDrawable == pMask->pDrawable &&
 		    xSrc == xMask && ySrc == yMask &&
@@ -1712,44 +1712,55 @@ fbComposite (CARD8      op,
 		    }
 		    break;
 		}
-		else
+		else if (maskRepeat &&
+			 pMask->pDrawable->width == 1 &&
+			 pMask->pDrawable->height == 1)
 		{
-		    /* non-repeating source, repeating mask => translucent window */
-		    if (fbCanGetSolid(pMask))
-		    {
-			if (pSrc->format == PICT_x8r8g8b8 &&
-			    pDst->format == PICT_x8r8g8b8 &&
-			    pMask->format == PICT_a8)
-			{
+		    switch (pSrc->format) {
+		    case PICT_r5g6b5:
+		    case PICT_b5g6r5:
+			if (pDst->format == pSrc->format)
+			    func = fbCompositeTrans_0565xnx0565;
+			break;
+		    case PICT_r8g8b8:
+		    case PICT_b8g8r8:
+			if (pDst->format == pSrc->format)
+			    func = fbCompositeTrans_0888xnx0888;
+			break;
 #ifdef USE_MMX
-			    if (fbHaveMMX())
-				func = fbCompositeSrc_8888x8x8888mmx;
+		    case PICT_x8r8g8b8:
+			if ((pDst->format == PICT_a8r8g8b8 ||
+			     pDst->format == PICT_x8r8g8b8) &&
+			    pMask->format == PICT_a8 && fbHaveMMX())
+			    func = fbCompositeSrc_x888x8x8888mmx;
+			break;
+		    case PICT_x8b8g8r8:
+			if ((pDst->format == PICT_a8b8g8r8 ||
+			     pDst->format == PICT_x8b8g8r8) &&
+			    pMask->format == PICT_a8 && fbHaveMMX())
+			    func = fbCompositeSrc_x888x8x8888mmx;
+			break;
+		    case PICT_a8r8g8b8:
+			if ((pDst->format == PICT_a8r8g8b8 ||
+			     pDst->format == PICT_x8r8g8b8) &&
+			    pMask->format == PICT_a8 && fbHaveMMX())
+			    func = fbCompositeSrc_8888x8x8888mmx;
+			break;
+		    case PICT_a8b8g8r8:
+			if ((pDst->format == PICT_a8b8g8r8 ||
+			     pDst->format == PICT_x8b8g8r8) &&
+			    pMask->format == PICT_a8 && fbHaveMMX())
+			    func = fbCompositeSrc_8888x8x8888mmx;
+			break;
 #endif
-			}
+		    default:
+			break;
 		    }
+		    
+		    if (func != fbCompositeGeneral)
+			maskRepeat = FALSE;
 		}
 	    }
-	    else if (maskRepeat &&
-		     pMask->pDrawable->width == 1 &&
-		     pMask->pDrawable->height == 1)
-	    {
-		switch (pSrc->format) {
-		case PICT_r5g6b5:
-		case PICT_b5g6r5:
-		    if (pDst->format == pSrc->format)
-		        func = fbCompositeTrans_0565xnx0565;
-		    break;
- 		case PICT_r8g8b8:
- 		case PICT_b8g8r8:
- 		    if (pDst->format == pSrc->format)
- 		        func = fbCompositeTrans_0888xnx0888;
- 		    break;
-		default:
-		    break;
-		}
-		if (func != fbCompositeGeneral)
-		    maskRepeat = FALSE;
-	    }
 	}
 	else /* no mask */
 	{
diff-tree 3571b8e65b0857322d12e291305cfe29ea497c3c (from c0346e57e6d3857994f7af76060c502c2fdea294)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 26 09:45:11 2007 -0400

    More pixman merging
    
    - Move some code around to minimize diff noise
    
    - Add mmx ops from pixman that never made it into X
    
    - Merge Jeff Muizelaar's bugfixes to fbCompositeSrc_8888x8x8888mmx and
      fbCompositeSrc_x888x8x8888mmx.

diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 5bbede1..875fec0 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -1140,23 +1140,22 @@ fbCompositeSrc_8888x8x8888mmx (CARD8	op,
 {
     CARD32	*dstLine, *dst;
     CARD32	*srcLine, *src;
-    CARD8	*maskLine;
     CARD32	mask;
     __m64	vmask;
-    FbStride	dstStride, srcStride, maskStride;
+    FbStride	dstStride, srcStride;
     CARD16	w;
     __m64  srca;
-    
+
     CHECKPOINT();
-    
+
     fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
     fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
 
-    mask = *maskLine << 24 | *maskLine << 16 | *maskLine << 8 | *maskLine;
+    fbComposeGetSolid (pMask, mask, pDst->format);
+    mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
     vmask = load8888 (mask);
     srca = MC(4x00ff);
-    
+
     while (height--)
     {
 	dst = dstLine;
@@ -1169,9 +1168,93 @@ fbCompositeSrc_8888x8x8888mmx (CARD8	op,
 	{
 	    __m64 s = load8888 (*src);
 	    __m64 d = load8888 (*dst);
-	    
+
+	    *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
+
+	    w--;
+	    dst++;
+	    src++;
+	}
+
+	while (w >= 2)
+	{
+	    __m64 vs = *(__m64 *)src;
+	    __m64 vd = *(__m64 *)dst;
+	    __m64 vsrc0 = expand8888 (vs, 0);
+	    __m64 vsrc1 = expand8888 (vs, 1);
+
+	    *(__m64 *)dst = pack8888 (
+		in_over (vsrc0, expand_alpha (vsrc0), vmask, expand8888 (vd, 0)),
+		in_over (vsrc1, expand_alpha (vsrc1), vmask, expand8888 (vd, 1)));
+
+	    w -= 2;
+	    dst += 2;
+	    src += 2;
+	}
+
+	while (w)
+	{
+	    __m64 s = load8888 (*src);
+	    __m64 d = load8888 (*dst);
+
+	    *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
+
+	    w--;
+	    dst++;
+	    src++;
+	}
+    }
+
+    _mm_empty();
+}
+
+void
+fbCompositeSrc_x888x8x8888mmx (CARD8	op,
+			       PicturePtr pSrc,
+			       PicturePtr pMask,
+			       PicturePtr pDst,
+			       INT16	xSrc,
+			       INT16	ySrc,
+			       INT16      xMask,
+			       INT16      yMask,
+			       INT16      xDst,
+			       INT16      yDst,
+			       CARD16     width,
+			       CARD16     height)
+{
+    CARD32	*dstLine, *dst;
+    CARD32	*srcLine, *src;
+    CARD32	mask;
+    __m64	vmask;
+    FbStride	dstStride, srcStride;
+    CARD16	w;
+    __m64  srca;
+
+    CHECKPOINT();
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+    fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+    fbComposeGetSolid (pMask, mask, pDst->format);
+
+    mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
+    vmask = load8888 (mask);
+    srca = MC(4x00ff);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w && (unsigned long)dst & 7)
+	{
+	    __m64 s = load8888 (*src);
+	    __m64 d = load8888 (*dst);
+
 	    *dst = store8888 (in_over (s, srca, vmask, d));
-	    
+
 	    w--;
 	    dst++;
 	    src++;
@@ -1197,39 +1280,39 @@ fbCompositeSrc_8888x8x8888mmx (CARD8	op,
 	    __m64 vs6 = *(__m64 *)(src + 12);
 	    __m64 vs7 = *(__m64 *)(src + 14);
 
-	    vd0 = (__m64)pack8888 (
+	    vd0 = pack8888 (
 		in_over (expand8888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
 		in_over (expand8888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
-	
-	    vd1 = (__m64)pack8888 (
+
+	    vd1 = pack8888 (
 		in_over (expand8888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
 		in_over (expand8888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
-	
-	    vd2 = (__m64)pack8888 (
+
+	    vd2 = pack8888 (
 		in_over (expand8888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
 		in_over (expand8888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
-	
-	    vd3 = (__m64)pack8888 (
+
+	    vd3 = pack8888 (
 		in_over (expand8888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
 		in_over (expand8888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
-	
-	    vd4 = (__m64)pack8888 (
+
+	    vd4 = pack8888 (
 		in_over (expand8888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
 		in_over (expand8888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
-	
-	    vd5 = (__m64)pack8888 (
+
+	    vd5 = pack8888 (
 		in_over (expand8888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
 		in_over (expand8888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
-	
-	    vd6 = (__m64)pack8888 (
+
+	    vd6 = pack8888 (
 		in_over (expand8888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
 		in_over (expand8888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
-	
-	    vd7 = (__m64)pack8888 (
+
+	    vd7 = pack8888 (
 		in_over (expand8888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
 		in_over (expand8888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
 
-    	    *(__m64 *)(dst + 0) = vd0;
+	    *(__m64 *)(dst + 0) = vd0;
 	    *(__m64 *)(dst + 2) = vd1;
 	    *(__m64 *)(dst + 4) = vd2;
 	    *(__m64 *)(dst + 6) = vd3;
@@ -1237,26 +1320,26 @@ fbCompositeSrc_8888x8x8888mmx (CARD8	op,
 	    *(__m64 *)(dst + 10) = vd5;
 	    *(__m64 *)(dst + 12) = vd6;
 	    *(__m64 *)(dst + 14) = vd7;
-	
+
 	    w -= 16;
 	    dst += 16;
 	    src += 16;
 	}
-	
+
 	while (w)
 	{
 	    __m64 s = load8888 (*src);
 	    __m64 d = load8888 (*dst);
-	    
+
 	    *dst = store8888 (in_over (s, srca, vmask, d));
-	    
+
 	    w--;
 	    dst++;
 	    src++;
 	}
     }
 
-    _mm_empty(); 
+    _mm_empty();
 }
 
 void
@@ -1534,24 +1617,274 @@ fbCompositeSolidMask_nx8x8888mmx (CARD8 
 	while (w)
 	{
 	    ullong m = *mask;
-	    
+	    
+	    if (m)
+	    {
+		__m64 vdest = load8888(*dst);
+		vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), vdest);
+		*dst = store8888(vdest);
+	    }
+	    
+	    w--;
+	    mask++;
+	    dst++;
+	}
+    }
+    
+    _mm_empty();
+}
+
+
+Bool
+fbSolidFillmmx (DrawablePtr	pDraw,
+		int		x,
+		int		y,
+		int		width,
+		int		height,
+		FbBits		xor)
+{ 
+    FbStride	stride;
+    int		bpp;
+    ullong	fill;
+    __m64	vfill;
+    CARD32	byte_width;
+    CARD8	*byte_line;
+    FbBits      *bits;
+    int		xoff, yoff;
+    __m64	v1, v2, v3, v4, v5, v6, v7;
+    
+    CHECKPOINT();
+    
+    fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
+    
+    if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
+	return FALSE;
+    
+    if (bpp != 16 && bpp != 32)
+	return FALSE;
+    
+    if (bpp == 16)
+    {
+	stride = stride * sizeof (FbBits) / 2;
+	byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
+	byte_width = 2 * width;
+	stride *= 2;
+    }
+    else
+    {
+	stride = stride * sizeof (FbBits) / 4;
+	byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
+	byte_width = 4 * width;
+	stride *= 4;
+    }
+    
+    fill = ((ullong)xor << 32) | xor;
+    vfill = (__m64)fill;
+    
+    __asm__ (
+	"movq		%7,	%0\n"
+	"movq		%7,	%1\n"
+	"movq		%7,	%2\n"
+	"movq		%7,	%3\n"
+	"movq		%7,	%4\n"
+	"movq		%7,	%5\n"
+	"movq		%7,	%6\n"
+	: "=y" (v1), "=y" (v2), "=y" (v3),
+	  "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+	: "y" (vfill));
+    
+    while (height--)
+    {
+	int w;
+	CARD8 *d = byte_line;
+	byte_line += stride;
+	w = byte_width;
+	
+	while (w >= 2 && ((unsigned long)d & 3))
+	{
+	    *(CARD16 *)d = xor;
+	    w -= 2;
+	    d += 2;
+	}
+	
+	while (w >= 4 && ((unsigned long)d & 7))
+	{
+	    *(CARD32 *)d = xor;
+	    
+	    w -= 4;
+	    d += 4;
+	}
+
+	while (w >= 64)
+	{
+	    __asm__ (
+		"movq	%1,	  (%0)\n"
+		"movq	%2,	 8(%0)\n"
+		"movq	%3,	16(%0)\n"
+		"movq	%4,	24(%0)\n"
+		"movq	%5,	32(%0)\n"
+		"movq	%6,	40(%0)\n"
+		"movq	%7,	48(%0)\n"
+		"movq	%8,	56(%0)\n"
+		:
+		: "r" (d),
+		  "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
+		  "y" (v4), "y" (v5), "y" (v6), "y" (v7)
+		: "memory");
+	    
+	    w -= 64;
+	    d += 64;
+	}
+	
+	while (w >= 4)
+	{
+	    *(CARD32 *)d = xor;
+	    
+	    w -= 4;
+	    d += 4;
+	}
+	if (w >= 2)
+	{
+	    *(CARD16 *)d = xor;
+	    w -= 2;
+	    d += 2;
+	}
+    }
+    
+    _mm_empty();
+    return TRUE;
+}
+
+void
+fbCompositeSolidMaskSrc_nx8x8888mmx (CARD8      op,
+				     PicturePtr pSrc,
+				     PicturePtr pMask,
+				     PicturePtr pDst,
+				     INT16      xSrc,
+				     INT16      ySrc,
+				     INT16      xMask,
+				     INT16      yMask,
+				     INT16      xDst,
+				     INT16      yDst,
+				     CARD16     width,
+				     CARD16     height)
+{
+    CARD32	src, srca;
+    CARD32	*dstLine, *dst;
+    CARD8	*maskLine, *mask;
+    FbStride	dstStride, maskStride;
+    CARD16	w;
+    __m64	vsrc, vsrca;
+    ullong	srcsrc;
+
+    CHECKPOINT();
+
+    fbComposeGetSolid(pSrc, src, pDst->format);
+
+    srca = src >> 24;
+    if (srca == 0)
+    {
+	fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0);
+	return;
+    }
+
+    srcsrc = (ullong)src << 32 | src;
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+    vsrc = load8888 (src);
+    vsrca = expand_alpha (vsrc);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	CHECKPOINT();
+
+	while (w && (unsigned long)dst & 7)
+	{
+	    ullong m = *mask;
+
+	    if (m)
+	    {
+		__m64 vdest = in(vsrc, expand_alpha_rev ((__m64)m));
+		*dst = store8888(vdest);
+	    }
+	    else
+	    {
+		*dst = 0;
+	    }
+
+	    w--;
+	    mask++;
+	    dst++;
+	}
+
+	CHECKPOINT();
+
+	while (w >= 2)
+	{
+	    ullong m0, m1;
+	    m0 = *mask;
+	    m1 = *(mask + 1);
+
+	    if (srca == 0xff && (m0 & m1) == 0xff)
+	    {
+		*(ullong *)dst = srcsrc;
+	    }
+	    else if (m0 | m1)
+	    {
+		__m64 vdest;
+		__m64 dest0, dest1;
+
+		vdest = *(__m64 *)dst;
+
+		dest0 = in(vsrc, expand_alpha_rev ((__m64)m0));
+		dest1 = in(vsrc, expand_alpha_rev ((__m64)m1));
+
+		*(__m64 *)dst = pack8888(dest0, dest1);
+	    }
+	    else
+	    {
+		*dst = 0;
+	    }
+
+	    mask += 2;
+	    dst += 2;
+	    w -= 2;
+	}
+
+	CHECKPOINT();
+
+	while (w)
+	{
+	    ullong m = *mask;
+
 	    if (m)
 	    {
 		__m64 vdest = load8888(*dst);
-		vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), vdest);
+		vdest = in(vsrc, expand_alpha_rev ((__m64)m));
 		*dst = store8888(vdest);
 	    }
-	    
+	    else
+	    {
+		*dst = 0;
+	    }
+
 	    w--;
 	    mask++;
 	    dst++;
 	}
     }
-    
+
     _mm_empty();
 }
 
-
 void
 fbCompositeSolidMask_nx8x0565mmx (CARD8      op,
 				  PicturePtr pSrc,
@@ -2003,6 +2336,232 @@ fbCompositeSolidMask_nx8888x0565Cmmx (CA
 }
 
 void
+fbCompositeIn_nx8x8mmx (CARD8	op,
+			PicturePtr pSrc,
+			PicturePtr pMask,
+			PicturePtr pDst,
+			INT16      xSrc,
+			INT16      ySrc,
+			INT16      xMask,
+			INT16      yMask,
+			INT16      xDst,
+			INT16      yDst,
+			CARD16     width,
+			CARD16     height)
+{
+    CARD8	*dstLine, *dst;
+    CARD8	*maskLine, *mask;
+    FbStride	dstStride, maskStride;
+    CARD16	w;
+    CARD32	src;
+    CARD8	sa;
+    __m64	vsrc, vsrca;
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+    fbComposeGetSolid(pSrc, src, pDst->format);
+
+    sa = src >> 24;
+    if (sa == 0)
+	return;
+
+    vsrc = load8888(src);
+    vsrca = expand_alpha(vsrc);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	if ((((unsigned long)pDst & 3) == 0) &&
+	    (((unsigned long)pSrc & 3) == 0))
+	{
+	    while (w >= 4)
+	    {
+		CARD32 m;
+		__m64 vmask;
+		__m64 vdest;
+
+		m = 0;
+
+		vmask = load8888 (*(CARD32 *)mask);
+		vdest = load8888 (*(CARD32 *)dst);
+
+		*(CARD32 *)dst = store8888 (in (in (vsrca, vmask), vdest));
+
+		dst += 4;
+		mask += 4;
+		w -= 4;
+	    }
+	}
+
+	while (w--)
+	{
+	    CARD16	tmp;
+	    CARD8	a;
+	    CARD32	m, d;
+	    CARD32	r;
+
+	    a = *mask++;
+	    d = *dst;
+
+	    m = FbInU (sa, 0, a, tmp);
+	    r = FbInU (m, 0, d, tmp);
+
+	    *dst++ = r;
+	}
+    }
+
+    _mm_empty();
+}
+
+void
+fbCompositeIn_8x8mmx (CARD8	op,
+		      PicturePtr pSrc,
+		      PicturePtr pMask,
+		      PicturePtr pDst,
+		      INT16      xSrc,
+		      INT16      ySrc,
+		      INT16      xMask,
+		      INT16      yMask,
+		      INT16      xDst,
+		      INT16      yDst,
+		      CARD16     width,
+		      CARD16     height)
+{
+    CARD8	*dstLine, *dst;
+    CARD8	*srcLine, *src;
+    FbStride	srcStride, dstStride;
+    CARD16	w;
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+    fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	if ((((unsigned long)pDst & 3) == 0) &&
+	    (((unsigned long)pSrc & 3) == 0))
+	{
+	    while (w >= 4)
+	    {
+		CARD32 *s = (CARD32 *)src;
+		CARD32 *d = (CARD32 *)dst;
+
+		*d = store8888 (in (load8888 (*s), load8888 (*d)));
+
+		w -= 4;
+		dst += 4;
+		src += 4;
+	    }
+	}
+
+	while (w--)
+	{
+	    CARD8 s, d;
+	    CARD16 tmp;
+
+	    s = *src;
+	    d = *dst;
+
+	    *dst = FbInU (s, 0, d, tmp);
+
+	    src++;
+	    dst++;
+	}
+    }
+
+    _mm_empty ();
+}
+
+void
+fbCompositeSrcAdd_8888x8x8mmx (CARD8   op,
+			       PicturePtr pSrc,
+			       PicturePtr pMask,
+			       PicturePtr pDst,
+			       INT16      xSrc,
+			       INT16      ySrc,
+			       INT16      xMask,
+			       INT16      yMask,
+			       INT16      xDst,
+			       INT16      yDst,
+			       CARD16     width,
+			       CARD16     height)
+{
+    CARD8	*dstLine, *dst;
+    CARD8	*maskLine, *mask;
+    FbStride	dstStride, maskStride;
+    CARD16	w;
+    CARD32	src;
+    CARD8	sa;
+    __m64	vsrc, vsrca;
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+    fbComposeGetSolid(pSrc, src, pDst->format);
+
+    sa = src >> 24;
+    if (sa == 0)
+	return;
+
+    vsrc = load8888(src);
+    vsrca = expand_alpha(vsrc);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	if ((((unsigned long)pMask & 3) == 0) &&
+	    (((unsigned long)pDst  & 3) == 0))
+	{
+	    while (w >= 4)
+	    {
+		__m64 vmask = load8888 (*(CARD32 *)mask);
+		__m64 vdest = load8888 (*(CARD32 *)dst);
+
+		*(CARD32 *)dst = store8888 (_mm_adds_pu8 (in (vsrca, vmask), vdest));
+
+		w -= 4;
+		dst += 4;
+		mask += 4;
+	    }
+	}
+
+	while (w--)
+	{
+	    CARD16	tmp;
+	    CARD16	a;
+	    CARD32	m, d;
+	    CARD32	r;
+
+	    a = *mask++;
+	    d = *dst;
+
+	    m = FbInU (sa, 0, a, tmp);
+	    r = FbAdd (m, d, 0, tmp);
+
+	    *dst++ = r;
+	}
+    }
+
+    _mm_empty();
+}
+
+void
 fbCompositeSrcAdd_8000x8000mmx (CARD8	op,
 				PicturePtr pSrc,
 				PicturePtr pMask,
@@ -2135,126 +2694,6 @@ fbCompositeSrcAdd_8888x8888mmx (CARD8		o
 }
 
 Bool
-fbSolidFillmmx (DrawablePtr	pDraw,
-		int		x,
-		int		y,
-		int		width,
-		int		height,
-		FbBits		xor)
-{ 
-    FbStride	stride;
-    int		bpp;
-    ullong	fill;
-    __m64	vfill;
-    CARD32	byte_width;
-    CARD8	*byte_line;
-    FbBits      *bits;
-    int		xoff, yoff;
-    __m64	v1, v2, v3, v4, v5, v6, v7;
-    
-    CHECKPOINT();
-    
-    fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
-    
-    if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
-	return FALSE;
-    
-    if (bpp != 16 && bpp != 32)
-	return FALSE;
-    
-    if (bpp == 16)
-    {
-	stride = stride * sizeof (FbBits) / 2;
-	byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
-	byte_width = 2 * width;
-	stride *= 2;
-    }
-    else
-    {
-	stride = stride * sizeof (FbBits) / 4;
-	byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
-	byte_width = 4 * width;
-	stride *= 4;
-    }
-    
-    fill = ((ullong)xor << 32) | xor;
-    vfill = (__m64)fill;
-    
-    __asm__ (
-	"movq		%7,	%0\n"
-	"movq		%7,	%1\n"
-	"movq		%7,	%2\n"
-	"movq		%7,	%3\n"
-	"movq		%7,	%4\n"
-	"movq		%7,	%5\n"
-	"movq		%7,	%6\n"
-	: "=y" (v1), "=y" (v2), "=y" (v3),
-	  "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
-	: "y" (vfill));
-    
-    while (height--)
-    {
-	int w;
-	CARD8 *d = byte_line;
-	byte_line += stride;
-	w = byte_width;
-	
-	while (w >= 2 && ((unsigned long)d & 3))
-	{
-	    *(CARD16 *)d = xor;
-	    w -= 2;
-	    d += 2;
-	}
-	
-	while (w >= 4 && ((unsigned long)d & 7))
-	{
-	    *(CARD32 *)d = xor;
-	    
-	    w -= 4;
-	    d += 4;
-	}
-
-	while (w >= 64)
-	{
-	    __asm__ (
-		"movq	%1,	  (%0)\n"
-		"movq	%2,	 8(%0)\n"
-		"movq	%3,	16(%0)\n"
-		"movq	%4,	24(%0)\n"
-		"movq	%5,	32(%0)\n"
-		"movq	%6,	40(%0)\n"
-		"movq	%7,	48(%0)\n"
-		"movq	%8,	56(%0)\n"
-		:
-		: "r" (d),
-		  "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
-		  "y" (v4), "y" (v5), "y" (v6), "y" (v7)
-		: "memory");
-	    
-	    w -= 64;
-	    d += 64;
-	}
-	
-	while (w >= 4)
-	{
-	    *(CARD32 *)d = xor;
-	    
-	    w -= 4;
-	    d += 4;
-	}
-	if (w >= 2)
-	{
-	    *(CARD16 *)d = xor;
-	    w -= 2;
-	    d += 2;
-	}
-    }
-    
-    _mm_empty();
-    return TRUE;
-}
-
-Bool
 fbCopyAreammx (DrawablePtr	pSrc,
 	       DrawablePtr	pDst,
 	       int		src_x,
diff --git a/fb/fbmmx.h b/fb/fbmmx.h
index b3e4d71..ca9c7e7 100644
--- a/fb/fbmmx.h
+++ b/fb/fbmmx.h
@@ -82,6 +82,32 @@ void fbCompositeSrc_8888x8888mmx (CARD8	
 				  INT16		yDst,
 				  CARD16	width,
 				  CARD16	height);
+void
+fbCompositeSolidMaskSrc_nx8x8888mmx (CARD8      op,
+				     PicturePtr pSrc,
+				     PicturePtr pMask,
+				     PicturePtr pDst,
+				     INT16      xSrc,
+				     INT16      ySrc,
+				     INT16      xMask,
+				     INT16      yMask,
+				     INT16      xDst,
+				     INT16      yDst,
+				     CARD16     width,
+				     CARD16     height);
+void
+fbCompositeSrc_x888x8x8888mmx (CARD8	op,
+			       PicturePtr pSrc,
+			       PicturePtr pMask,
+			       PicturePtr pDst,
+			       INT16	xSrc,
+			       INT16	ySrc,
+			       INT16      xMask,
+			       INT16      yMask,
+			       INT16      xDst,
+			       INT16      yDst,
+			       CARD16     width,
+			       CARD16     height);
 void fbCompositeSolidMask_nx8888x8888Cmmx (CARD8	op,
 					   PicturePtr	pSrc,
 					   PicturePtr	pMask,
@@ -106,6 +132,42 @@ void fbCompositeSolidMask_nx8x8888mmx (C
 				       INT16      yDst,
 				       CARD16     width,
 				       CARD16     height);
+void fbCompositeIn_nx8x8mmx (CARD8	op,
+			PicturePtr pSrc,
+			PicturePtr pMask,
+			PicturePtr pDst,
+			INT16      xSrc,
+			INT16      ySrc,
+			INT16      xMask,
+			INT16      yMask,
+			INT16      xDst,
+			INT16      yDst,
+			CARD16     width,
+			CARD16     height);
+void fbCompositeIn_8x8mmx (CARD8	op,
+		      PicturePtr pSrc,
+		      PicturePtr pMask,
+		      PicturePtr pDst,
+		      INT16      xSrc,
+		      INT16      ySrc,
+		      INT16      xMask,
+		      INT16      yMask,
+		      INT16      xDst,
+		      INT16      yDst,
+		      CARD16     width,
+		      CARD16     height);
+void fbCompositeSrcAdd_8888x8x8mmx (CARD8   op,
+			       PicturePtr pSrc,
+			       PicturePtr pMask,
+			       PicturePtr pDst,
+			       INT16      xSrc,
+			       INT16      ySrc,
+			       INT16      xMask,
+			       INT16      yMask,
+			       INT16      xDst,
+			       INT16      yDst,
+			       CARD16     width,
+			       CARD16     height);
 void fbCompositeSrcAdd_8000x8000mmx (CARD8	op,
 				     PicturePtr pSrc,
 				     PicturePtr pMask,
diff-tree c0346e57e6d3857994f7af76060c502c2fdea294 (from 67347739b0571b2978468e8088480b105f505ad2)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Apr 26 12:02:45 2007 +0930

    Require inputproto 1.4.2.
    
    Requirement was introduced with c7e2ba0c9b9b1fc1aed8f91f86471c4c8e650b78.

diff --git a/configure.ac b/configure.ac
index 872f376..9d4a50a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -628,7 +628,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.l
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau fontenc"
 
 if test "x$DBUS" = xauto; then
diff-tree 67347739b0571b2978468e8088480b105f505ad2 (from c056ce95d89ef1df57edf47149fc34cd3925496e)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed Apr 25 14:19:39 2007 -0400

    Don't treat convolution filters as transformations.
    
    Some rearrangement of code to get it closer to pixman.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index f9f5368..4fb949d 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1461,9 +1461,9 @@ fbComposite (CARD8      op,
     int		    n;
     BoxPtr	    pbox;
     CompositeFunc   func = NULL;
-    Bool	    srcRepeat = pSrc->pDrawable && pSrc->repeat;
+    Bool	    srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
     Bool	    maskRepeat = FALSE;
-    Bool	    srcTransform = pSrc->pDrawable && pSrc->transform;
+    Bool	    srcTransform = pSrc->transform != 0;
     Bool	    maskTransform = FALSE;
     Bool	    srcAlphaMap = pSrc->alphaMap != 0;
     Bool	    maskAlphaMap = FALSE;
@@ -1479,9 +1479,6 @@ fbComposite (CARD8      op,
     }
 #endif
 
-    if (pSrc->filter == PictFilterConvolution)
-	srcTransform = TRUE;
-    
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
     if (pSrc->pDrawable) {
@@ -1517,21 +1514,6 @@ fbComposite (CARD8      op,
         && (pSrc->filter != PictFilterConvolution)
         && (!pMask || pMask->filter != PictFilterConvolution))
     switch (op) {
-    case PictOpSrc:
-#ifdef USE_MMX
-	if (!pMask && pSrc->format == pDst->format &&
-	    pSrc->format != PICT_a8 && pSrc->pDrawable != pDst->pDrawable)
-	{
-	    func = fbCompositeCopyAreammx;
-	}
-	else
-#endif
-	    if (pMask == 0)
-	    {
-		if (pSrc->format == pDst->format)
-		    func = fbCompositeSrcSrc_nxn;
-	    }
-	break;
     case PictOpOver:
 	if (pMask)
 	{
@@ -1975,6 +1957,21 @@ fbComposite (CARD8      op,
 	    }
 	}
 	break;
+    case PictOpSrc:
+#ifdef USE_MMX
+	if (!pMask && pSrc->format == pDst->format &&
+	    pSrc->format != PICT_a8 && pSrc->pDrawable != pDst->pDrawable)
+	{
+	    func = fbCompositeCopyAreammx;
+	}
+	else
+#endif
+	    if (pMask == 0)
+	    {
+		if (pSrc->format == pDst->format)
+		    func = fbCompositeSrcSrc_nxn;
+	    }
+	break;
     }
 
     if (!func) {
diff-tree c056ce95d89ef1df57edf47149fc34cd3925496e (from c19ece1d8c32dc81740a4036a642661f54064e75)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed Apr 25 13:21:47 2007 -0400

    Port MSVC++ CPU detection code from pixman. (Vladimir Vukicevic).

diff --git a/fb/fbpict.c b/fb/fbpict.c
index b4cddd7..f9f5368 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1509,7 +1509,6 @@ fbComposite (CARD8      op,
 	    pMask->pDrawable->width == 1 &&
 	    pMask->pDrawable->height == 1)
 	    maskTransform = FALSE;
-	    
     }
 
     if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
@@ -2116,7 +2115,7 @@ enum CPUFeatures {
 
 static unsigned int detectCPUFeatures(void) {
     unsigned int features = 0;
-    unsigned int result;
+    unsigned int result = 0;
 
 #ifdef HAVE_GETISAX
     if (getisax(&result, 1)) {
@@ -2133,8 +2132,13 @@ static unsigned int detectCPUFeatures(vo
     }
 #else
     char vendor[13];
+#ifdef _MSC_VER
+    int vendor0 = 0, vendor1, vendor2;
+#endif
     vendor[0] = 0;
     vendor[12] = 0;
+
+#ifdef __GNUC__
     /* see p. 118 of amd64 instruction set manual Vol3 */
     /* We need to be careful about the handling of %ebx and
      * %esp here. We can't declare either one as clobbered
@@ -2153,7 +2157,7 @@ static unsigned int detectCPUFeatures(vo
              "pop %%eax\n"
              "mov $0x0, %%edx\n"
              "xor %%ecx, %%eax\n"
-             "jz 1\n"
+             "jz 1f\n"
 
              "mov $0x00000000, %%eax\n"
 	     "push %%ebx\n"
@@ -2177,6 +2181,45 @@ static unsigned int detectCPUFeatures(vo
              : "%eax", "%ecx", "%edx"
         );
 
+#elif defined (_MSC_VER)
+
+    _asm {
+      pushfd
+      pop eax
+      mov ecx, eax
+      xor eax, 00200000h
+      push eax
+      popfd
+      pushfd
+      pop eax
+      mov edx, 0
+      xor eax, ecx
+      jz nocpuid
+
+      mov eax, 0
+      push ebx
+      cpuid
+      mov eax, ebx
+      pop ebx
+      mov vendor0, eax
+      mov vendor1, edx
+      mov vendor2, ecx
+      mov eax, 1
+      push ebx
+      cpuid
+      pop ebx
+    nocpuid:
+      mov result, edx
+    }
+    memmove (vendor+0, &vendor0, 4);
+    memmove (vendor+4, &vendor1, 4);
+    memmove (vendor+8, &vendor2, 4);
+
+#else
+#   error unsupported compiler
+#endif
+    
+    features = 0;
     if (result) {
         /* result now contains the standard feature bits */
         if (result & (1 << 15))
@@ -2191,14 +2234,13 @@ static unsigned int detectCPUFeatures(vo
             (strcmp(vendor, "AuthenticAMD") == 0 ||
              strcmp(vendor, "Geode by NSC") == 0)) {
             /* check for AMD MMX extensions */
-
-            unsigned int result;            
+#ifdef __GNUC__
             __asm__("push %%ebx\n"
                     "mov $0x80000000, %%eax\n"
                     "cpuid\n"
                     "xor %%edx, %%edx\n"
                     "cmp $0x1, %%eax\n"
-                    "jge 2\n"
+                    "jge 2f\n"
                     "mov $0x80000001, %%eax\n"
                     "cpuid\n"
                     "2:\n"
@@ -2208,11 +2250,27 @@ static unsigned int detectCPUFeatures(vo
                     :
                     : "%eax", "%ecx", "%edx"
                 );
+#elif defined _MSC_VER
+            _asm {
+              push ebx
+              mov eax, 80000000h
+              cpuid
+              xor edx, edx
+              cmp eax, 1
+              jge notamd
+              mov eax, 80000001h
+              cpuid
+            notamd:
+              pop ebx
+              mov result, edx
+            }
+#endif
             if (result & (1<<22))
                 features |= MMX_Extensions;
         }
     }
 #endif /* HAVE_GETISAX */
+
     return features;
 }
 
diff-tree c19ece1d8c32dc81740a4036a642661f54064e75 (from 48c73dfc369fdf8f6023436ebe82bb604f76bb80)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed Apr 25 12:34:19 2007 -0400

    Integrate optimization from xserver from David Reveman where repeats
    
    get handled by fbFetchTransformed() rather than in the region walking
    code.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index b9c463a..b4cddd7 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1463,6 +1463,8 @@ fbComposite (CARD8      op,
     CompositeFunc   func = NULL;
     Bool	    srcRepeat = pSrc->pDrawable && pSrc->repeat;
     Bool	    maskRepeat = FALSE;
+    Bool	    srcTransform = pSrc->pDrawable && pSrc->transform;
+    Bool	    maskTransform = FALSE;
     Bool	    srcAlphaMap = pSrc->alphaMap != 0;
     Bool	    maskAlphaMap = FALSE;
     Bool	    dstAlphaMap = pDst->alphaMap != 0;
@@ -1476,23 +1478,42 @@ fbComposite (CARD8      op,
         mmx_setup = TRUE;
     }
 #endif
-        
+
+    if (pSrc->filter == PictFilterConvolution)
+	srcTransform = TRUE;
+    
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
     if (pSrc->pDrawable) {
         xSrc += pSrc->pDrawable->x;
         ySrc += pSrc->pDrawable->y;
     }
+
+    if (srcRepeat && srcTransform &&
+	pSrc->pDrawable->width == 1 &&
+	pSrc->pDrawable->height == 1)
+	srcTransform = FALSE;
+    
     if (pMask && pMask->pDrawable)
     {
 	xMask += pMask->pDrawable->x;
 	yMask += pMask->pDrawable->y;
 	maskRepeat = pMask->repeat == RepeatNormal;
+
+	if (pMask->filter == PictFilterConvolution)
+	    maskTransform = TRUE;
+
 	maskAlphaMap = pMask->alphaMap != 0;
+
+	if (maskRepeat && maskTransform &&
+	    pMask->pDrawable->width == 1 &&
+	    pMask->pDrawable->height == 1)
+	    maskTransform = FALSE;
+	    
     }
 
     if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
-        && !pSrc->transform && !(pMask && pMask->transform)
+        && !srcTransform && !maskTransform
         && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
         && (pSrc->filter != PictFilterConvolution)
         && (!pMask || pMask->filter != PictFilterConvolution))
@@ -1977,6 +1998,12 @@ fbComposite (CARD8      op,
                                    height))
         return;
 
+    /* if we are transforming, we handle repeats in fbFetchTransformed */
+    if (srcTransform)
+	srcRepeat = FALSE;
+    if (maskTransform)
+	maskRepeat = FALSE;
+    
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
     while (n--)
diff-tree 48c73dfc369fdf8f6023436ebe82bb604f76bb80 (from 66ba3d758a368bf83d75bab8b08bdb6b34925e40)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed Apr 25 12:09:22 2007 -0400

    Add function fbCompositeSrcAdd_8888x8x8(), and fix a bug where
    
    srcRepeat = FALSE would be set in the wrong place.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index db70872..b9c463a 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -894,6 +894,61 @@ fbCompositeSrcAdd_8888x8888 (CARD8	op,
     fbFinishAccess (pSrc->pDrawable);
 }
 
+static void
+fbCompositeSrcAdd_8888x8x8 (CARD8      op,
+			    PicturePtr pSrc,
+			    PicturePtr pMask,
+			    PicturePtr pDst,
+			    INT16      xSrc,
+			    INT16      ySrc,
+			    INT16      xMask,
+			    INT16      yMask,
+			    INT16      xDst,
+			    INT16      yDst,
+			    CARD16     width,
+			    CARD16     height)
+{
+    CARD8	*dstLine, *dst;
+    CARD8	*maskLine, *mask;
+    FbStride	dstStride, maskStride;
+    CARD16	w;
+    CARD32	src;
+    CARD8	sa;
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+    fbComposeGetSolid (pSrc, src, pDst->format);
+    sa = (src >> 24);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    CARD16	tmp;
+	    CARD16	a;
+	    CARD32	m, d;
+	    CARD32	r;
+
+	    a = READ(mask++);
+	    d = READ(dst);
+
+	    m = FbInU (sa, 0, a, tmp);
+	    r = FbAdd (m, d, 0, tmp);
+
+	    WRITE(dst++, r);
+	}
+    }
+    
+    fbFinishAccess(pDst->pDrawable);
+    fbFinishAccess(pMask->pDrawable);
+}
+
 void
 fbCompositeSrcAdd_1000x1000 (CARD8	op,
 			     PicturePtr pSrc,
@@ -1587,6 +1642,8 @@ fbComposite (CARD8      op,
 		default:
 		    break;
 		}
+		if (func != fbCompositeGeneral)
+		    srcRepeat = FALSE;
 	    }
 	    else if (! srcRepeat) /* has mask and non-repeating source */
 	    {
@@ -1669,8 +1726,6 @@ fbComposite (CARD8      op,
 			}
 		    }
 		}
-		if (func != fbCompositeGeneral)
-		    srcRepeat = FALSE;
 	    }
 	    else if (maskRepeat &&
 		     pMask->pDrawable->width == 1 &&
@@ -1887,6 +1942,18 @@ fbComposite (CARD8      op,
 		break;
 	    }
 	}
+	else
+	{
+	    if ((pSrc->format == PICT_a8r8g8b8	||
+		 pSrc->format == PICT_a8b8g8r8) &&
+		fbCanGetSolid (pSrc)		&&
+		pMask->format == PICT_a8	&&
+		pDst->format == PICT_a8)
+	    {
+		srcRepeat = FALSE;
+		func = fbCompositeSrcAdd_8888x8x8;
+	    }
+	}
 	break;
     }
 
diff-tree 66ba3d758a368bf83d75bab8b08bdb6b34925e40 (from c09e68ce30dabd6b7068b163b9d2382d85d0d0bc)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Wed Apr 25 10:31:38 2007 -0400

    Various fixes from xserver via pixman (Billy Biggs)

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 44bee1b..db70872 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -123,7 +123,7 @@ fbIn (CARD32 x, CARD8 y)
 
 
 #if IMAGE_BYTE_ORDER == LSBFirst
-#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
+#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
 					temp=count&3; \
 					where-=temp; \
 					workingWhere=(CARD32 *)where; \
@@ -136,7 +136,7 @@ fbIn (CARD32 x, CARD8 y)
         #define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; WRITE (wodst++, workingoDest); } 
 #else
 	#warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!"
-	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
+	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
 					temp=count&3; \
 					where-=temp; \
 					workingWhere=(CARD32 *)where; \
@@ -331,7 +331,7 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
     while (height--)
     {
 	/* fixme: cleanup unused */
-	unsigned int wt, wd;
+	unsigned long wt, wd;
 	CARD32 workingiDest;
 	CARD32 *widst;
  	
@@ -1074,7 +1074,7 @@ fbCompositeTrans_0565xnx0565(CARD8      
 	srcLine += srcStride;
 	w = width;
 	
-	if(((int)src&1)==1)
+	if(((long)src&1)==1)
 	{
 	    s_16 = READ(src++);
 	    d_16 = READ(dst);
@@ -1082,7 +1082,7 @@ fbCompositeTrans_0565xnx0565(CARD8      
 	    w--;
 	}
 	isrc=(CARD32 *)src;
-	if(((int)dst&1)==0)
+	if(((long)dst&1)==0)
 	{
 	    idst=(CARD32 *)dst;
 	    while (w>1)
@@ -1173,7 +1173,7 @@ fbCompositeTrans_0888xnx0888(CARD8      
     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
     
     {
-	unsigned int ws,wt;
+	unsigned long ws,wt;
 	CARD32 workingSource;
 	CARD32 *wsrc, *wdst, *widst;
 	CARD32 rs, rd, nd;
@@ -1196,7 +1196,7 @@ fbCompositeTrans_0888xnx0888(CARD8      
 		setupPackedReader(ws,wt,isrc,wsrc,workingSource);
 		
 		/* get to word aligned */
-		switch(!(int)src&3)
+		switch(~(long)dst&3)
 		{
 		case 1:
 		    readPackedSource(rs);
@@ -1272,7 +1272,7 @@ fbCompositeTrans_0888xnx0888(CARD8      
 		srcLine += srcStride;
 		w = width*3;
 		/* get to word aligned */
-		switch(!(int)src&3)
+		switch(~(long)src&3)
 		{
 		case 1:
 		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
diff-tree c09e68ce30dabd6b7068b163b9d2382d85d0d0bc (from 9c80eda826448822328bb678a7d284cc43fffb17)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed Apr 25 16:46:26 2007 -0400

    Paper over a crash at exit during GLX teardown.

diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index ecfa4d7..b50740c 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -258,12 +258,14 @@ __glXMesaScreenDestroy(__GLXscreen *scre
     __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
     int i;
 
-    for (i = 0; i < mesaScreen->num_vis; i++) {
-	if (mesaScreen->xm_vis[i])
-	    XMesaDestroyVisual(mesaScreen->xm_vis[i]);
-    }
+    if (mesaScreen->xm_vis) {
+	for (i = 0; i < mesaScreen->num_vis; i++) {
+	    if (mesaScreen->xm_vis[i])
+		XMesaDestroyVisual(mesaScreen->xm_vis[i]);
+	}
 
-    xfree(mesaScreen->xm_vis);
+	xfree(mesaScreen->xm_vis);
+    }
 
     __glXScreenDestroy(screen);
 
diff-tree 9c80eda826448822328bb678a7d284cc43fffb17 (from d322608dc929d5f8cda07a53143a4f28423e0460)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed Apr 25 16:35:04 2007 -0400

    Disable RANDR's fake Xinerama protocol when there's more than one screen.
    
    ... in the protocol sense.  Xinerama doesn't have any provision for more
    than one protocol screen each with its own geometry.
    
    Red Hat bug #231257.

diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 1db27f1..2a57e4e 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -428,6 +428,14 @@ RRXineramaExtensionInit(void)
 	return;
 #endif
 
+    /*
+     * Xinerama isn't capable enough to have multiple protocol screens each
+     * with their own output geometry.  So if there's more than one protocol
+     * screen, just don't even try.
+     */
+    if (screenInfo.numScreens > 1)
+	return;
+
     (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
 			ProcRRXineramaDispatch,
 			SProcRRXineramaDispatch,
diff-tree d322608dc929d5f8cda07a53143a4f28423e0460 (from 3ba1e8ab6d69566e1a3f8f0eb4605631aeffc8e5)
Author: Adam Jackson <ajax at benzedrine.nwnk.net>
Date:   Wed Apr 25 16:29:48 2007 -0400

    Fix a buffer overrun on machines with excessively large PCI busses.
    
    Formerly we sized an array with a compile time constant, then initialized
    its size to the same constant, but the Linux PCI init code would increase
    that "constant".  So if you happened to have more than 128 PCI devices,
    you'd happily scribble into whatever variables happened to be in .bss
    after that array.
    
    Only really fixed for Linux atm.  Other OSes will simply (still) fail to
    work on video devices above the 128th PCI device.

diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index b80371d..bc5e11f 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -232,14 +232,14 @@ _X_EXPORT int            pciNumBuses = 0
 int            pciMaxBusNum = MAX_PCI_BUSES;
 static Bool    inProbe = FALSE;
 
-static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, };
+static pciConfigPtr *pci_devp = NULL;
 
 static int readPciBios( PCITAG Tag, CARD8* tmp, ADDRESS hostbase,
 			unsigned char * buf, int len, PciBiosType BiosType );
 
 static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len);
 
-int xf86MaxPciDevs = MAX_PCI_DEVICES;
+int xf86MaxPciDevs = 0;
 
 /*
  * Platform specific PCI function pointers.
@@ -272,6 +272,14 @@ pciInit()
 	if (pciNumBuses <= 0)
 	    ARCH_PCI_OS_INIT();
 #endif
+	if (xf86MaxPciDevs == 0) {
+	    xf86Msg(X_WARNING,
+		    "OS did not count PCI devices, guessing wildly\n");
+	    xf86MaxPciDevs = MAX_PCI_DEVICES;
+	}
+	if (pci_devp)
+	    xfree(pci_devp);
+	pci_devp = xnfcalloc(xf86MaxPciDevs + 1, sizeof(pciConfigPtr));
 }
 
 void pciSetOSBIOSPtr(int (*bios_fn)(PCITAG Tag, int basereg, unsigned char * buf, int len))
@@ -920,7 +928,7 @@ xf86scanpci(int flags)
      * result in an endless recursion if platform/OS specific PCI
      * bus probing code calls this function from with in it.
      */
-    if (done || pci_devp[0])
+    if (done || pci_devp)
 	return pci_devp;
 
     done = TRUE;
diff-tree 3ba1e8ab6d69566e1a3f8f0eb4605631aeffc8e5 (from 0a2fe443d25b1ca25349aba3f748df986952e20f)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Apr 24 17:20:14 2007 -0700

    Include xf86Rename.h in xf86RandR12.h.

diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h
index 0d3346a..4fd855c 100644
--- a/hw/xfree86/modes/xf86RandR12.h
+++ b/hw/xfree86/modes/xf86RandR12.h
@@ -24,6 +24,9 @@
 #define _XF86_RANDR_H_
 #include <randrstr.h>
 #include <X11/extensions/render.h>
+#if XF86_MODES_RENAME
+#include "xf86Rename.h"
+#endif
 
 Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
 Bool xf86RandR12Init(ScreenPtr pScreen);
diff-tree 0a2fe443d25b1ca25349aba3f748df986952e20f (from 7e16da7b78c422f96387502b9cc29eaa1741543f)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 19:02:44 2007 -0400

    Use READ/WRITE macros for new functions introduced in previous commits.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 8ca7336..44bee1b 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -100,7 +100,7 @@ fbIn (CARD32 x, CARD8 y)
 #define inOver0888(alpha, source, destval, dest) { \
  	CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \
  	CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
-	dest =((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
+	WRITE(dest, ((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00))); \
     }
 
 /*
@@ -111,42 +111,42 @@ fbIn (CARD32 x, CARD8 y)
 #define inOver0565(alpha, source, destval, dest) { \
  	CARD16 dstrb = destval & 0xf81f; CARD16 dstg  = destval & 0x7e0; \
  	CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
-	dest = ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5)  + dstg) & 0x7e0)); \
+	WRITE(dest, ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5)  + dstg) & 0x7e0))); \
     }
 
 
 #define inOver2x0565(alpha, source, destval, dest) { \
  	CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg  = (destval & 0xf81f07e0)>>5; \
  	CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \
-	dest = ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5)  + dstg)<<5) & 0xf81f07e0)); \
+	WRITE(dest, ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5)  + dstg)<<5) & 0xf81f07e0))); \
     }
 
 
 #if IMAGE_BYTE_ORDER == LSBFirst
-	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
+#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
 					temp=count&3; \
 					where-=temp; \
 					workingWhere=(CARD32 *)where; \
-					workingVal=*workingWhere++; \
+                                        workingVal=READ(workingWhere++); \
 					count=4-temp; \
 					workingVal>>=(8*temp)
-	#define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)&0xff; (y)>>=8; (x)--;}
+        #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)&0xff; (y)>>=8; (x)--;}
 	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
 	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
-	#define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; *wodst++=workingoDest; } 
+        #define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; WRITE (wodst++, workingoDest); } 
 #else
 	#warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!"
 	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
 					temp=count&3; \
 					where-=temp; \
 					workingWhere=(CARD32 *)where; \
-					workingVal=*workingWhere++; \
+                                        workingVal=READ(workingWhere)++; \
 					count=4-temp; \
 					workingVal<<=(8*temp)
-	#define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)>>24; (y)<<=8; (x)--;}
+        #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)>>24; (y)<<=8; (x)--;}
 	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
 	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
-	#define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; } 
+        #define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; WRITE(wodst++, workingoDest); } 
 #endif
 
 /*
@@ -328,65 +328,65 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
     fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
 
-     while (height--)
-  	{
-	        /* fixme: cleanup unused */
- 		unsigned int wt,wd;
- 		CARD32 workingiDest;
- 		CARD32 *widst;
- 		
- 		edst=dst = dstLine;
- 		dstLine += dstStride;
- 		mask = maskLine;
- 		maskLine += maskStride;
- 		w = width;
- 		
+    while (height--)
+    {
+	/* fixme: cleanup unused */
+	unsigned int wt, wd;
+	CARD32 workingiDest;
+	CARD32 *widst;
+ 	
+	edst = dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+ 	
 #ifndef NO_MASKED_PACKED_READ
- 		setupPackedReader(wd,wt,edst,widst,workingiDest);
+	setupPackedReader(wd,wt,edst,widst,workingiDest);
 #endif
- 				
- 		while (w--)
- 		{
+ 	
+	while (w--)
+	{
 #ifndef NO_MASKED_PACKED_READ
- 			readPackedDest(rd);
- 			readPackedDest(gd);
- 			readPackedDest(bd);
+	    readPackedDest(rd);
+	    readPackedDest(gd);
+	    readPackedDest(bd);
 #else
- 			rd= *edst++;
- 			gd= *edst++;
- 			bd= *edst++;
-#endif
- 			m = *mask++;
- 			if (m == 0xff)
- 			{
- 				if (srca == 0xff)
- 				{
- 					*dst++=rs;
- 					*dst++=gs;
- 					*dst++=bs;
- 				}
- 				else
- 				{
- 					*dst++=(srcAlphaCombine24(rs, rd)>>8);
- 					*dst++=(srcAlphaCombine24(gs, gd)>>8);
- 					*dst++=(srcAlphaCombine24(bs, bd)>>8);
-				}
- 			}
- 			else if (m)
- 			{
- 				int na=(srca*(int)m)>>8;
- 				int nia=255-na;
- 				*dst++=(genericCombine24(rs, rd, na, nia)>>8);
- 				*dst++=(genericCombine24(gs, gd, na, nia)>>8);
- 				*dst++=(genericCombine24(bs, bd, na, nia)>>8);
- 			}
- 			else
- 			{
- 				dst+=3;
- 			}
+	    rd = READ(edst++);
+	    gd = READ(edst++);
+	    bd = READ(edst++);
+#endif
+	    m = READ(mask++);
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		{
+		    WRITE(dst++, rs);
+		    WRITE(dst++, gs);
+		    WRITE(dst++, bs);
 		}
+		else
+		{
+		    WRITE(dst++, (srcAlphaCombine24(rs, rd)>>8));
+		    WRITE(dst++, (srcAlphaCombine24(gs, gd)>>8));
+		    WRITE(dst++, (srcAlphaCombine24(bs, bd)>>8));
+		}
+	    }
+	    else if (m)
+	    {
+		int na=(srca*(int)m)>>8;
+		int nia=255-na;
+		WRITE(dst++, (genericCombine24(rs, rd, na, nia)>>8));
+		WRITE(dst++, (genericCombine24(gs, gd, na, nia)>>8));
+		WRITE(dst++, (genericCombine24(bs, bd, na, nia)>>8));
+	    }
+	    else
+	    {
+		dst+=3;
+	    }
 	}
-
+    }
+    
     fbFinishAccess (pMask->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
@@ -414,8 +414,6 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
     CARD16	w,src16;
     
     fbComposeGetSolid(pSrc, src, pDst->format);
-
-    
     
     if (src == 0)
 	return;
@@ -437,23 +435,23 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
  
 	while (w--)
 	{
-	    m = *mask++;
+	    m = READ(mask++);
 	    if (m == 0)
 		dst++;
 	    else if (srca5 == (0xff >> 3))
 	    {
 		if (m == 0xff)
-		    *dst++ = src16;
+		    WRITE(dst++, src16);
 		else 
  		{
-		    d = *dst;
+		    d = READ(dst);
 		    m >>= 3;
-		    inOver0565 (m, src16, d, *dst++);
+		    inOver0565 (m, src16, d, dst++);
  		}
 	    }
 	    else
 	    {
-		d = *dst;
+		d = READ(dst);
 		if (m == 0xff) 
 		{
 		    t = fbOver24 (src, cvt0565to0888 (d));
@@ -463,7 +461,7 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
 		    t = fbIn (src, m);
 		    t = fbOver (t, cvt0565to0888 (d));
 		}
-		*dst++ = cvt8888to0565 (t);
+		WRITE(dst++, cvt8888to0565 (t));
 	    }
 	}
     }
@@ -517,34 +515,34 @@ fbCompositeSolidMask_nx8888x0565 (CARD8 
 
 	while (w--)
 	{
-	    m = *mask++ >> 24;
+	    m = READ(mask++) >> 24;
 	    if (m == 0)
 		dst++;
 	    else if (srca5 == (0xff >> 3))
 	    {
 		if (m == 0xff)
-		    *dst++ = src16;
+		    WRITE(dst++, src16);
 		else
 		{
-		    d = *dst;
+		    d = READ(dst);
 		    m >>= 3;
-		    inOver0565 (m, src16, d, *dst++);
+		    inOver0565 (m, src16, d, dst++);
 		}
 	    }
 	    else
 	    {
 		if (m == 0xff) 
 		{
-		    d = *dst;
+		    d = READ(dst);
 		    t = fbOver24 (src, cvt0565to0888 (d));
-		    *dst++ = cvt8888to0565 (t);
+		    WRITE(dst++, cvt8888to0565 (t));
 		}
 		else
 		{
-		    d = *dst;
+		    d = READ(dst);
 		    t = fbIn (src, m);
 		    t = fbOver (t, cvt0565to0888 (d));
-		    *dst++ = cvt8888to0565 (t);
+		    WRITE(dst++, cvt8888to0565 (t));
 		}
 	    }
 	}
@@ -1078,9 +1076,9 @@ fbCompositeTrans_0565xnx0565(CARD8      
 	
 	if(((int)src&1)==1)
 	{
-	    s_16 = *src++;
-	    d_16 = *dst;
-	    inOver0565(maskAlpha, s_16, d_16, *dst++);
+	    s_16 = READ(src++);
+	    d_16 = READ(dst);
+	    inOver0565(maskAlpha, s_16, d_16, dst++);
 	    w--;
 	}
 	isrc=(CARD32 *)src;
@@ -1089,9 +1087,9 @@ fbCompositeTrans_0565xnx0565(CARD8      
 	    idst=(CARD32 *)dst;
 	    while (w>1)
 	    {
-		s_32 = *isrc++;
-		d_32 = *idst;
-		inOver2x0565(maskAlpha, s_32, d_32, *idst++);
+		s_32 = READ(isrc++);
+		d_32 = READ(idst);
+		inOver2x0565(maskAlpha, s_32, d_32, idst++);
 		w-=2;
 	    }
 	    dst=(CARD16 *)idst;
@@ -1100,30 +1098,30 @@ fbCompositeTrans_0565xnx0565(CARD8      
 	{
 	    while (w > 1)
 	    {
-		s_32 = *isrc++;
+		s_32 = READ(isrc++);
 #if IMAGE_BYTE_ORDER == LSBFirst
 		s_16=s_32&0xffff;
 #else
 		s_16=s_32>>16;
 #endif
-		d_16 = *dst;
-		inOver0565 (maskAlpha, s_16, d_16, *dst++);
+		d_16 = READ(dst);
+		inOver0565 (maskAlpha, s_16, d_16, dst++);
 #if IMAGE_BYTE_ORDER == LSBFirst
 		s_16=s_32>>16;
 #else
 		s_16=s_32&0xffff;
 #endif
-		d_16 = *dst;
-		inOver0565(maskAlpha, s_16, d_16, *dst++);
+		d_16 = READ(dst);
+		inOver0565(maskAlpha, s_16, d_16, dst++);
 		w-=2;
 	    }
 	}
 	src=(CARD16 *)isrc;
 	if(w!=0)
 	{
-	    s_16 = *src;
-	    d_16 = *dst;
-	    inOver0565(maskAlpha, s_16, d_16, *dst);
+	    s_16 = READ(src);
+	    d_16 = READ(dst);
+	    inOver0565(maskAlpha, s_16, d_16, dst);
 	}
     }
     
@@ -1133,6 +1131,7 @@ fbCompositeTrans_0565xnx0565(CARD8      
 
 /* macros for "i can't believe it's not fast" packed pixel handling */
 #define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
+
 static void
 fbCompositeTrans_0888xnx0888(CARD8      op,
  			     PicturePtr pSrc,
@@ -1146,175 +1145,175 @@ fbCompositeTrans_0888xnx0888(CARD8      
  			     INT16      yDst,
  			     CARD16     width,
  			     CARD16     height)
- {
-     CARD8	*dstLine, *dst,*idst;
-     CARD8	*srcLine, *src;
-     FbStride	dstStride, srcStride;
-     CARD16	w;
-     FbBits	mask;
-     CARD16	maskAlpha,maskiAlpha;
-     
-     fbComposeGetSolid (pMask, mask, pDst->format);
-     maskAlpha = mask >> 24;
- 	maskiAlpha= 255-maskAlpha;
-     
-     if (!maskAlpha)
- 	return;
-     /*
-     if (maskAlpha == 0xff)
-     {
- 	fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
- 				  xSrc, ySrc, xMask, yMask, xDst, yDst, 
- 				  width, height);
+{
+    CARD8	*dstLine, *dst,*idst;
+    CARD8	*srcLine, *src;
+    FbStride	dstStride, srcStride;
+    CARD16	w;
+    FbBits	mask;
+    CARD16	maskAlpha,maskiAlpha;
+    
+    fbComposeGetSolid (pMask, mask, pDst->format);
+    maskAlpha = mask >> 24;
+    maskiAlpha= 255-maskAlpha;
+    
+    if (!maskAlpha)
  	return;
-     }
-     */
- 	
-     fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
-     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
-  
-  	{
- 		unsigned int ws,wt;
- 		CARD32 workingSource;
-		CARD32 *wsrc, *wdst, *widst;
-		CARD32 rs, rd, nd;
-		CARD8 *isrc;
-
- 
- 		/* are xSrc and xDst at the same alignment?  if not, we need to be complicated :) */
- 		/* if(0==0) */
-		if( (((xSrc*3)&3)!=((xDst*3)&3)) || ((srcStride&3)!=(dstStride&3)))
- 		{
- 			while (height--)
- 			{
-			        dst = dstLine;
- 				dstLine += dstStride;
- 				isrc = src = srcLine;
- 				srcLine += srcStride;
- 				w = width*3;
- 				
-				setupPackedReader(ws,wt,isrc,wsrc,workingSource);
-				
- 				/* get to word aligned */
- 				switch(!(int)src&3)
- 				{
- 					case 1:
-					        readPackedSource(rs);
-						/* *dst++=alphamaskCombine24(rs, *dst)>>8; */
-						rd=*dst;  /* make gcc happy.  hope it doens't cost us too much performance*/
-						*dst++=alphamaskCombine24(rs, rd)>>8;
-						w--; if(w==0) break;
- 					case 2:
-					        readPackedSource(rs);
-						rd=*dst;  
-						*dst++=alphamaskCombine24(rs, rd)>>8;
- 						w--; if(w==0) break;
- 					case 3:
-					        readPackedSource(rs);
-						rd=*dst;  
-						*dst++=alphamaskCombine24(rs, rd)>>8;
- 						w--; if(w==0) break;
- 				}
- 				wdst=(CARD32 *)dst;
-				while (w>3)
-				{
- 					rs=*wsrc++;
-					/* FIXME: write a special readPackedWord macro, which knows how to 
-					 * halfword combine
-					 */
- #if IMAGE_BYTE_ORDER == LSBFirst
-					rd=*wdst;
-					readPackedSource(nd);
-					readPackedSource(rs);
-					nd|=rs<<8;
-					readPackedSource(rs);
-					nd|=rs<<16;
-					readPackedSource(rs);
-					nd|=rs<<24;
+    /*
+      if (maskAlpha == 0xff)
+      {
+      fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
+      xSrc, ySrc, xMask, yMask, xDst, yDst, 
+      width, height);
+      return;
+      }
+    */
+    
+    fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
+    fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+    
+    {
+	unsigned int ws,wt;
+	CARD32 workingSource;
+	CARD32 *wsrc, *wdst, *widst;
+	CARD32 rs, rd, nd;
+	CARD8 *isrc;
+	
+	
+	/* are xSrc and xDst at the same alignment?  if not, we need to be complicated :) */
+	/* if(0==0) */
+	if ((((xSrc * 3) & 3) != ((xDst * 3) & 3)) ||
+	    ((srcStride & 3) != (dstStride & 3)))
+	{
+	    while (height--)
+	    {
+		dst = dstLine;
+		dstLine += dstStride;
+		isrc = src = srcLine;
+		srcLine += srcStride;
+		w = width*3;
+		
+		setupPackedReader(ws,wt,isrc,wsrc,workingSource);
+		
+		/* get to word aligned */
+		switch(!(int)src&3)
+		{
+		case 1:
+		    readPackedSource(rs);
+		    /* *dst++=alphamaskCombine24(rs, *dst)>>8; */
+		    rd = READ(dst);  /* make gcc happy.  hope it doens't cost us too much performance*/
+		    WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
+		    w--; if(w==0) break;
+		case 2:
+		    readPackedSource(rs);
+		    rd = READ(dst);
+		    WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
+		    w--; if(w==0) break;
+		case 3:
+		    readPackedSource(rs);
+		    rd = READ(dst);
+		    WRITE(dst++,alphamaskCombine24(rs, rd) >> 8);
+		    w--; if(w==0) break;
+		}
+		wdst=(CARD32 *)dst;
+		while (w>3)
+		{
+		    rs=READ(wsrc++);
+		    /* FIXME: write a special readPackedWord macro, which knows how to 
+		     * halfword combine
+		     */
+#if IMAGE_BYTE_ORDER == LSBFirst
+		    rd=READ(wdst);
+		    readPackedSource(nd);
+		    readPackedSource(rs);
+		    nd|=rs<<8;
+		    readPackedSource(rs);
+		    nd|=rs<<16;
+		    readPackedSource(rs);
+		    nd|=rs<<24;
 #else
-					readPackedSource(nd);
-					nd<<=24;
-					readPackedSource(rs);
-					nd|=rs<<16;
-					readPackedSource(rs);
-					nd|=rs<<8;
-					readPackedSource(rs);
-					nd|=rs;
-#endif
-					inOver0888(maskAlpha, nd, rd, *wdst++);
- 					w-=4;
- 				}
- 				src=(CARD8 *)wdst;
- 				switch(w)
- 				{
- 					case 3:
-						readPackedSource(rs);
-						rd=*dst;  
-						*dst++=alphamaskCombine24(rs, rd)>>8;
- 					case 2:
-					        readPackedSource(rs);
-						rd=*dst;  
-						*dst++=alphamaskCombine24(rs, rd)>>8;
- 					case 1:
-                                               readPackedSource(rs);
-                                               rd=*dst;  
-                                               *dst++=alphamaskCombine24(rs, rd)>>8;
- 				}
- 			}
- 		}
- 		else
- 		{
- 			while (height--)
- 			{
- 				idst=dst = dstLine;
- 				dstLine += dstStride;
- 				src = srcLine;
- 				srcLine += srcStride;
- 				w = width*3;
- 				/* get to word aligned */
- 				switch(!(int)src&3)
- 				{
-					case 1:
- 						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 						w--; if(w==0) break;
- 					case 2:
- 						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 						w--; if(w==0) break;
-					case 3:
- 						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 						w--; if(w==0) break;
- 				}
- 				wsrc=(CARD32 *)src;
- 				widst=(CARD32 *)dst;
- 				while(w>3)
- 				{
- 					rs = *wsrc++;
- 					rd = *widst;
- 					inOver0888 (maskAlpha, rs, rd, *widst++);
- 					w-=4;
- 				}
-				src=(CARD8 *)wsrc;
- 				dst=(CARD8 *)widst;
- 				switch(w)
- 				{
- 					case 3:
- 						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 					case 2:
-						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 					case 1:
- 						rd=alphamaskCombine24(*src++, *dst)>>8;
- 						*dst++=rd;
- 				}
- 			}
- 		}
- 	}
-  }
-
+		    readPackedSource(nd);
+		    nd<<=24;
+		    readPackedSource(rs);
+		    nd|=rs<<16;
+		    readPackedSource(rs);
+		    nd|=rs<<8;
+		    readPackedSource(rs);
+		    nd|=rs;
+#endif
+		    inOver0888(maskAlpha, nd, rd, wdst++);
+		    w-=4;
+		}
+		src=(CARD8 *)wdst;
+		switch(w)
+		{
+		case 3:
+		    readPackedSource(rs);
+		    rd=READ(dst);
+		    WRITE(dst++,alphamaskCombine24(rs, rd)>>8);
+		case 2:
+		    readPackedSource(rs);
+		    rd = READ(dst);  
+		    WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
+		case 1:
+		    readPackedSource(rs);
+		    rd = READ(dst);  
+		    WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
+		}
+	    }
+	}
+	else
+	{
+	    while (height--)
+	    {
+		idst=dst = dstLine;
+		dstLine += dstStride;
+		src = srcLine;
+		srcLine += srcStride;
+		w = width*3;
+		/* get to word aligned */
+		switch(!(int)src&3)
+		{
+		case 1:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		    w--; if(w==0) break;
+		case 2:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		    w--; if(w==0) break;
+		case 3:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		    w--; if(w==0) break;
+		}
+		wsrc=(CARD32 *)src;
+		widst=(CARD32 *)dst;
+		while(w>3)
+		{
+		    rs = READ(wsrc++);
+		    rd = READ(widst);
+		    inOver0888 (maskAlpha, rs, rd, widst++);
+		    w-=4;
+		}
+		src=(CARD8 *)wsrc;
+		dst=(CARD8 *)widst;
+		switch(w)
+		{
+		case 3:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		case 2:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		case 1:
+		    rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+		    WRITE(dst++, rd);
+		}
+	    }
+	}
+    }
+}
 
 /*
  * Simple bitblt
diff-tree 7e16da7b78c422f96387502b9cc29eaa1741543f (from 2d9a7a768747ca39a800475f12c424c298018dc6)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 18:15:34 2007 -0400

    Remove #if 0'ed blocks

diff --git a/fb/fbpict.c b/fb/fbpict.c
index d027e35..8ca7336 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -783,47 +783,6 @@ fbCompositeSrc_8888x0565 (CARD8      op,
     fbFinishAccess (pSrc->pDrawable);
 }
 
-#if 0
-void
-fbCompositeSrc_0565x0565 (CARD8      op,
-			  PicturePtr pSrc,
-			  PicturePtr pMask,
-			  PicturePtr pDst,
-			  INT16      xSrc,
-			  INT16      ySrc,
-			  INT16      xMask,
-			  INT16      yMask,
-			  INT16      xDst,
-			  INT16      yDst,
-			  CARD16     width,
-			  CARD16     height)
-{
-    CARD16	*dstLine, *dst;
-    CARD16	*srcLine, *src;
-    FbStride	dstStride, srcStride;
-    CARD16	w;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	    WRITE(dst, READ(src++));
-    }
-
-    fbFinishAccess (pDst->pDrawable);
-    fbFinishAccess (pSrc->pDrawable);
-}
-#endif
-
 void
 fbCompositeSrcAdd_8000x8000 (CARD8	op,
 			     PicturePtr pSrc,
diff-tree 18252a515d4989b983a3b7389636045e06d0f246 (from ce099a9b78195540ec251a6a3dbe26019c1a686d)
Author: Brian <brian at yutani.localnet.net>
Date:   Tue Apr 24 14:10:09 2007 -0600

    bump release date to reflect input code updates

diff --git a/hw/dmx/dmx-config.h b/hw/dmx/dmx-config.h
index 9647448..18a0535 100644
--- a/hw/dmx/dmx-config.h
+++ b/hw/dmx/dmx-config.h
@@ -66,7 +66,7 @@
     ((year-2000) *     10000) + \
     ((month)     *       100) + \
     ((day)       *         1)
-#define VENDOR_RELEASE  DMX_VENDOR_RELEASE(1,2,2004,6,30)
+#define VENDOR_RELEASE  DMX_VENDOR_RELEASE(1,2,2007,4,24)
 #define VENDOR_STRING   "DMX Project"
 
 /* Enable the DMX extension */
diff-tree 2d9a7a768747ca39a800475f12c424c298018dc6 (from fde4a5adf02d3067a064ebf6bdd666aa5784cfe9)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 14:46:59 2007 -0400

    From pixman (Jeff Muizelaar)
    
        Fix up the fast-path compositing operators; those are useful for
        sources without alpha, but can't be used for sources with
        alpha. Also, replaced fbCompositeSrcSrc_nxn with call to fbBlt as
        this function must handle 1, 4, 8, 16, 24, 32 bpp objects. Would
        be nice to optimize fbBlt for common cases involving 8, 16, 24 and
        32bpp.
    
        From Keith Packard.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 660112c..d027e35 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -64,20 +64,6 @@ fbOver (CARD32 x, CARD32 y)
     return m|n|o|p;
 }
 
-static CARD32
-fbIn24 (CARD32 x, CARD8 y)
-{
-    CARD16  a = y;
-    CARD16  t;
-    CARD32  m,n,o,p;
-
-    m = FbInU(x,0,a,t);
-    n = FbInU(x,8,a,t);
-    o = FbInU(x,16,a,t);
-    p = (y << 24);
-    return m|n|o|p;
-}
-
 CARD32
 fbOver24 (CARD32 x, CARD32 y)
 {
@@ -107,22 +93,34 @@ fbIn (CARD32 x, CARD8 y)
 
 #define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))
 
-#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \
-	dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \
-	drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
-	*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
-
-#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \
-	dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \
-	drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
-	*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
-	
-// Note: this macro expects 6 bits of alpha, not 8!
-#define fastCombine0565(alpha, source, destval, destptr) { \
-	CARD16 dstrb = destval & 0xf81f; CARD16 dstg  = destval & 0x7e0; \
-	CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
-	destptr= ((((drb>>6) + dstrb)&0xf81f) | (((dg>>6)  + dstg) & 0x7e0)); \
-	}
+/*
+ * This macro does src IN mask OVER dst when src and dst are 0888.
+ * If src has alpha, this will not work
+ */
+#define inOver0888(alpha, source, destval, dest) { \
+ 	CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \
+ 	CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
+	dest =((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
+    }
+
+/*
+ * This macro does src IN mask OVER dst when src and dst are 0565 and
+ * mask is a 5-bit alpha value.  Again, if src has alpha, this will not
+ * work.
+ */
+#define inOver0565(alpha, source, destval, dest) { \
+ 	CARD16 dstrb = destval & 0xf81f; CARD16 dstg  = destval & 0x7e0; \
+ 	CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
+	dest = ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5)  + dstg) & 0x7e0)); \
+    }
+
+
+#define inOver2x0565(alpha, source, destval, dest) { \
+ 	CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg  = (destval & 0xf81f07e0)>>5; \
+ 	CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \
+	dest = ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5)  + dstg)<<5) & 0xf81f07e0)); \
+    }
+
 
 #if IMAGE_BYTE_ORDER == LSBFirst
 	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
@@ -150,6 +148,7 @@ fbIn (CARD32 x, CARD8 y)
 	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
 	#define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; } 
 #endif
+
 /*
  * Naming convention:
  *
@@ -310,7 +309,6 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
 {
     CARD32	src, srca, srcia;
     CARD8	*dstLine, *dst, *edst;
-    CARD32	d;
     CARD8	*maskLine, *mask, m;
     FbStride	dstStride, maskStride;
     CARD16	w;
@@ -332,7 +330,7 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
 
      while (height--)
   	{
- 		// fixme: cleanup unused
+	        /* fixme: cleanup unused */
  		unsigned int wt,wd;
  		CARD32 workingiDest;
  		CARD32 *widst;
@@ -407,61 +405,152 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
 				  CARD16     width,
 				  CARD16     height)
 {
-     CARD32	src, srca,na, rsrca;
-     CARD16	*dstLine, *dst;
-     CARD16	d;
-     CARD8	*maskLine, *mask, m;
-     FbStride	dstStride, maskStride;
-     CARD16	w,src16;
-  
-     fbComposeGetSolid(pSrc, src, pDst->format);
-     src16 = cvt8888to0565(src);
-      
-     rsrca = src >> 24;
-     srca=rsrca>>2;
-      if (src == 0)
- 		return;
+    CARD32	src, srca8, srca5;
+    CARD16	*dstLine, *dst;
+    CARD16	d;
+    CARD32	t;
+    CARD8	*maskLine, *mask, m;
+    FbStride	dstStride, maskStride;
+    CARD16	w,src16;
+    
+    fbComposeGetSolid(pSrc, src, pDst->format);
+
+    
+    
+    if (src == 0)
+	return;
       
-      fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-      fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+    srca8 = (src >> 24);
+    srca5 = (srca8 >> 3);
+    src16 = cvt8888to0565(src);
+     
+    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
     
- 	while (height--)
-  	{
- 		dst = dstLine;
- 		dstLine += dstStride;
- 		mask = maskLine;
- 		maskLine += maskStride;
- 		w = width;
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
  
- 		while (w--)
-  		{
- 			m = *mask++;
- 			if (m == 0xff)
- 			{
- 				if (srca == 0xff)
- 				{
- 					*dst=src16;
- 				}
- 				else
- 				{
- 					d = *dst;
- 					fastCombine0565(srca, src16, d, *dst++);
- 				}
- 			}
- 			else if (m)
- 			{
- 				na=(rsrca*(int)m)>>10;
- 				d = *dst;
- 				fastCombine0565(na, src16, d, *dst++);
- 			}
- 			else
- 				dst++;
-  		}
-  	}
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0)
+		dst++;
+	    else if (srca5 == (0xff >> 3))
+	    {
+		if (m == 0xff)
+		    *dst++ = src16;
+		else 
+ 		{
+		    d = *dst;
+		    m >>= 3;
+		    inOver0565 (m, src16, d, *dst++);
+ 		}
+	    }
+	    else
+	    {
+		d = *dst;
+		if (m == 0xff) 
+		{
+		    t = fbOver24 (src, cvt0565to0888 (d));
+		}
+		else
+		{
+		    t = fbIn (src, m);
+		    t = fbOver (t, cvt0565to0888 (d));
+		}
+		*dst++ = cvt8888to0565 (t);
+	    }
+	}
+    }
+    
     fbFinishAccess (pMask->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
 
+static void
+fbCompositeSolidMask_nx8888x0565 (CARD8      op,
+				  PicturePtr pSrc,
+				  PicturePtr pMask,
+				  PicturePtr pDst,
+				  INT16      xSrc,
+				  INT16      ySrc,
+				  INT16      xMask,
+				  INT16      yMask,
+				  INT16      xDst,
+				  INT16      yDst,
+				  CARD16     width,
+				  CARD16     height)
+{
+    CARD32	src, srca8, srca5;
+    CARD16	*dstLine, *dst;
+    CARD16	d;
+    CARD32	*maskLine, *mask;
+    CARD32	t;
+    CARD8	m;
+    FbStride	dstStride, maskStride;
+    CARD16	w, src16;
+
+    fbComposeGetSolid(pSrc, src, pDst->format);
+
+    if (src == 0)
+	return;
+
+    srca8 = src >> 24;
+    srca5 = srca8 >> 3;
+    src16 = cvt8888to0565(src);
+
+    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++ >> 24;
+	    if (m == 0)
+		dst++;
+	    else if (srca5 == (0xff >> 3))
+	    {
+		if (m == 0xff)
+		    *dst++ = src16;
+		else
+		{
+		    d = *dst;
+		    m >>= 3;
+		    inOver0565 (m, src16, d, *dst++);
+		}
+	    }
+	    else
+	    {
+		if (m == 0xff) 
+		{
+		    d = *dst;
+		    t = fbOver24 (src, cvt0565to0888 (d));
+		    *dst++ = cvt8888to0565 (t);
+		}
+		else
+		{
+		    d = *dst;
+		    t = fbIn (src, m);
+		    t = fbOver (t, cvt0565to0888 (d));
+		    *dst++ = cvt8888to0565 (t);
+		}
+	    }
+	}
+    }
+}
+
 void
 fbCompositeSolidMask_nx8888x0565C (CARD8      op,
 				   PicturePtr pSrc,
@@ -516,14 +605,14 @@ fbCompositeSolidMask_nx8888x0565C (CARD8
 		else
 		{
 		    d = READ(dst);
-		    d = fbOver24 (src, cvt0565to8888(d));
+		    d = fbOver24 (src, cvt0565to0888(d));
 		    WRITE(dst, cvt8888to0565(d));
 		}
 	    }
 	    else if (ma)
 	    {
 		d = READ(dst);
-		d = cvt0565to8888(d);
+		d = cvt0565to0888(d);
 		FbInOverC (src, srca, ma, d, 0, m);
 		FbInOverC (src, srca, ma, d, 8, n);
 		FbInOverC (src, srca, ma, d, 16, o);
@@ -682,7 +771,7 @@ fbCompositeSrc_8888x0565 (CARD8      op,
 		else
 		{
 		    d = READ(dst);
-		    d = fbOver24 (s, cvt0565to8888(d));
+		    d = fbOver24 (s, cvt0565to0888(d));
 		}
 		WRITE(dst, cvt8888to0565(d));
 	    }
@@ -694,6 +783,7 @@ fbCompositeSrc_8888x0565 (CARD8      op,
     fbFinishAccess (pSrc->pDrawable);
 }
 
+#if 0
 void
 fbCompositeSrc_0565x0565 (CARD8      op,
 			  PicturePtr pSrc,
@@ -732,6 +822,7 @@ fbCompositeSrc_0565x0565 (CARD8      op,
     fbFinishAccess (pDst->pDrawable);
     fbFinishAccess (pSrc->pDrawable);
 }
+#endif
 
 void
 fbCompositeSrcAdd_8000x8000 (CARD8	op,
@@ -964,6 +1055,19 @@ fbCompositeSolidMask_nx1xn (CARD8      o
 /*
  * Apply a constant alpha value in an over computation
  */
+static void
+fbCompositeSrcSrc_nxn  (CARD8	   op,
+			PicturePtr pSrc,
+			PicturePtr pMask,
+			PicturePtr pDst,
+			INT16      xSrc,
+			INT16      ySrc,
+			INT16      xMask,
+			INT16      yMask,
+			INT16      xDst,
+			INT16      yDst,
+			CARD16     width,
+			CARD16     height);
 
 static void
 fbCompositeTrans_0565xnx0565(CARD8      op,
@@ -985,19 +1089,19 @@ fbCompositeTrans_0565xnx0565(CARD8      
     CARD16	w;
     FbBits	mask;
     CARD8	maskAlpha;
-    CARD16	s_16, d_16, r_16;
-    CARD32	s_32, d_32, i_32, r_32;
+    CARD16	s_16, d_16;
+    CARD32	s_32, d_32;
     
     fbComposeGetSolid (pMask, mask, pDst->format);
-    maskAlpha = mask >> 26;
+    maskAlpha = mask >> 27;
     
     if (!maskAlpha)
 	return;
     if (maskAlpha == 0xff)
     {
-	fbCompositeSrc_0565x0565 (op, pSrc, pMask, pDst,
-				  xSrc, ySrc, xMask, yMask, xDst, yDst, 
-				  width, height);
+	fbCompositeSrcSrc_nxn (PictOpSrc, pSrc, pMask, pDst,
+			       xSrc, ySrc, xMask, yMask, xDst, yDst, 
+			       width, height);
 	return;
     }
 
@@ -1005,55 +1109,70 @@ fbCompositeTrans_0565xnx0565(CARD8      
     fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
 
     while (height--)
- 	{
- 		CARD32 *isrc;
- 		dst = dstLine;
- 		dstLine += dstStride;
- 		src = srcLine;
- 		srcLine += srcStride;
- 		w = width;
- 		
- 		if(((int)src&1)==1)
- 		{
- 			s_16 = *src++;
- 			d_16 = *dst;
- 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
- 			w--;
- 		}
- 		isrc=(CARD32 *)src;
- 		while (w>1)
- 		{
- 			s_32=*isrc++;
+    {
+	CARD32 *isrc, *idst;
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+	
+	if(((int)src&1)==1)
+	{
+	    s_16 = *src++;
+	    d_16 = *dst;
+	    inOver0565(maskAlpha, s_16, d_16, *dst++);
+	    w--;
+	}
+	isrc=(CARD32 *)src;
+	if(((int)dst&1)==0)
+	{
+	    idst=(CARD32 *)dst;
+	    while (w>1)
+	    {
+		s_32 = *isrc++;
+		d_32 = *idst;
+		inOver2x0565(maskAlpha, s_32, d_32, *idst++);
+		w-=2;
+	    }
+	    dst=(CARD16 *)idst;
+	}
+	else
+	{
+	    while (w > 1)
+	    {
+		s_32 = *isrc++;
 #if IMAGE_BYTE_ORDER == LSBFirst
- 			s_16=s_32&0xffff;
+		s_16=s_32&0xffff;
 #else
-			s_16=s_32>>16;
+		s_16=s_32>>16;
 #endif
- 			d_16 = *dst;
- 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
- #if IMAGE_BYTE_ORDER == LSBFirst
- 			s_16=s_32>>16;
- #else
- 			s_16=s_32&0xffff;
- #endif
- 			d_16 = *dst;
- 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
- 			w-=2;
- 		}
- 		src=(CARD16 *)isrc;
- 		if(w!=0)
- 		{
- 			s_16 = *src;
- 			d_16 = *dst;
- 			fastCombine0565(maskAlpha, s_16, d_16, *dst);
- 		}
- 	}
-
+		d_16 = *dst;
+		inOver0565 (maskAlpha, s_16, d_16, *dst++);
+#if IMAGE_BYTE_ORDER == LSBFirst
+		s_16=s_32>>16;
+#else
+		s_16=s_32&0xffff;
+#endif
+		d_16 = *dst;
+		inOver0565(maskAlpha, s_16, d_16, *dst++);
+		w-=2;
+	    }
+	}
+	src=(CARD16 *)isrc;
+	if(w!=0)
+	{
+	    s_16 = *src;
+	    d_16 = *dst;
+	    inOver0565(maskAlpha, s_16, d_16, *dst);
+	}
+    }
+    
     fbFinishAccess (pSrc->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
 
-// macros for "i can't believe it's not fast" packed pixel handling
+/* macros for "i can't believe it's not fast" packed pixel handling */
 #define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
 static void
 fbCompositeTrans_0888xnx0888(CARD8      op,
@@ -1082,140 +1201,105 @@ fbCompositeTrans_0888xnx0888(CARD8      
      
      if (!maskAlpha)
  	return;
-     //if (maskAlpha == 0xff)
-     //{
- 	//fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
- 	//			  xSrc, ySrc, xMask, yMask, xDst, yDst, 
- 	//			  width, height);
- 	//return;
-     //}
+     /*
+     if (maskAlpha == 0xff)
+     {
+ 	fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
+ 				  xSrc, ySrc, xMask, yMask, xDst, yDst, 
+ 				  width, height);
+ 	return;
+     }
+     */
  	
      fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
      fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
   
   	{
- 		unsigned int ws,wt,wd,ww;
+ 		unsigned int ws,wt;
  		CARD32 workingSource;
- 		CARD32 *wsrc;
- 		CARD32 rs,gs,bs;
- 		CARD32 rd,gd,bd;
- 
- 		CARD32 workingiDest,workingoDest;
- 		CARD32 *widst,*wodst;
- 
+		CARD32 *wsrc, *wdst, *widst;
+		CARD32 rs, rd, nd;
+		CARD8 *isrc;
+
  
- 		// are xSrc and xDst at the same alignment?  if not, we need to be complicated :)
- 		//if(0==0)
- 		if( (((xSrc*3)&3)!=((xDst*3)&3)) || (srcStride&3)!=0 || (dstStride&3)!=0)
+ 		/* are xSrc and xDst at the same alignment?  if not, we need to be complicated :) */
+ 		/* if(0==0) */
+		if( (((xSrc*3)&3)!=((xDst*3)&3)) || ((srcStride&3)!=(dstStride&3)))
  		{
  			while (height--)
  			{
- 				idst=dst = dstLine;
+			        dst = dstLine;
  				dstLine += dstStride;
- 				src = srcLine;
+ 				isrc = src = srcLine;
  				srcLine += srcStride;
  				w = width*3;
  				
- 				setupPackedReader(wd,wt,idst,widst,workingiDest);
- 				ww=(int)dst;
- 				wt=ww&3;
- 				dst-=wt; 
- 				wodst=(CARD32 *)dst; 
- 				workingoDest=*wodst; 
- 				ww=4-wt;
-#if IMAGE_BYTE_ORDER == LSBFirst
- 				workingoDest<<=(8*(ww+1));
-#else
- 				workingoDest>>=(8*(ww+1));
-#endif
- 
- 				// get to word aligned
+				setupPackedReader(ws,wt,isrc,wsrc,workingSource);
+				
+ 				/* get to word aligned */
  				switch(!(int)src&3)
  				{
  					case 1:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
- 						w--; if(w==0) break;
+					        readPackedSource(rs);
+						/* *dst++=alphamaskCombine24(rs, *dst)>>8; */
+						rd=*dst;  /* make gcc happy.  hope it doens't cost us too much performance*/
+						*dst++=alphamaskCombine24(rs, rd)>>8;
+						w--; if(w==0) break;
  					case 2:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
+					        readPackedSource(rs);
+						rd=*dst;  
+						*dst++=alphamaskCombine24(rs, rd)>>8;
  						w--; if(w==0) break;
  					case 3:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
+					        readPackedSource(rs);
+						rd=*dst;  
+						*dst++=alphamaskCombine24(rs, rd)>>8;
  						w--; if(w==0) break;
  				}
- 				wsrc=(CARD32 *)src;
+ 				wdst=(CARD32 *)dst;
 				while (w>3)
 				{
  					rs=*wsrc++;
- 					// FIXME: write a version of readPackedDest() which
- 					// can collect 4 bytes at once if we're on a boundry (which we're
- 					// actually guarenteed not to be in this version, but do it anyhow), and can
- 					// collect as 2 16bit words on a 2byte boundry, and then use the 32bit combine here
+					/* FIXME: write a special readPackedWord macro, which knows how to 
+					 * halfword combine
+					 */
  #if IMAGE_BYTE_ORDER == LSBFirst
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24(rs&0xff, rd)>>8;
- 					writePacked(rd);
- 
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8;
- 					writePacked(rd);
- 					
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8;
- 					writePacked(rd);
- 					
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24(rs>>24, rd)>>8;
- 					writePacked(rd);
- #else
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24(rs>>24, rd)>>8;
- 					writePacked(rd);
- 					
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8;
- 					writePacked(rd);
- 					
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8;
- 					writePacked(rd);
- 
- 					readPackedDest(rd);
- 					rd=alphamaskCombine24(rs&0xff, rd)>>8;
- 					writePacked(rd);
- #endif
+					rd=*wdst;
+					readPackedSource(nd);
+					readPackedSource(rs);
+					nd|=rs<<8;
+					readPackedSource(rs);
+					nd|=rs<<16;
+					readPackedSource(rs);
+					nd|=rs<<24;
+#else
+					readPackedSource(nd);
+					nd<<=24;
+					readPackedSource(rs);
+					nd|=rs<<16;
+					readPackedSource(rs);
+					nd|=rs<<8;
+					readPackedSource(rs);
+					nd|=rs;
+#endif
+					inOver0888(maskAlpha, nd, rd, *wdst++);
  					w-=4;
  				}
- 				src=(CARD8 *)wsrc;
+ 				src=(CARD8 *)wdst;
  				switch(w)
  				{
  					case 3:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
+						readPackedSource(rs);
+						rd=*dst;  
+						*dst++=alphamaskCombine24(rs, rd)>>8;
  					case 2:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
+					        readPackedSource(rs);
+						rd=*dst;  
+						*dst++=alphamaskCombine24(rs, rd)>>8;
  					case 1:
- 						readPackedDest(rd);
- 						rd=alphamaskCombine24(*src++, rd)>>8;
- 						writePacked(rd);
- 				}
- 				dst=(CARD8 *)wodst;
- 				switch(ww)
- 				{
- 					case 1:
- 						dst[2]=(workingoDest>>8)&0xff;
- 					case 2:
- 						dst[1]=(workingoDest>>16)&0xff;
- 					case 3:
- 						dst[0]=workingoDest>>24;
+                                               readPackedSource(rs);
+                                               rd=*dst;  
+                                               *dst++=alphamaskCombine24(rs, rd)>>8;
  				}
  			}
  		}
@@ -1228,7 +1312,7 @@ fbCompositeTrans_0888xnx0888(CARD8      
  				src = srcLine;
  				srcLine += srcStride;
  				w = width*3;
- 				// get to word aligned
+ 				/* get to word aligned */
  				switch(!(int)src&3)
  				{
 					case 1:
@@ -1246,13 +1330,11 @@ fbCompositeTrans_0888xnx0888(CARD8      
  				}
  				wsrc=(CARD32 *)src;
  				widst=(CARD32 *)dst;
- 
-				register CARD32 t1, t2, t3, t4;
  				while(w>3)
  				{
  					rs = *wsrc++;
  					rd = *widst;
- 					fastcombine32(maskAlpha, rs, rd, widst, t1, t2, t3, t4);
+ 					inOver0888 (maskAlpha, rs, rd, *widst++);
  					w-=4;
  				}
 				src=(CARD8 *)wsrc;
@@ -1300,80 +1382,29 @@ fbCompositeSrcSrc_nxn  (CARD8	   op,
     int		dstXoff, dstYoff;
     int		srcBpp;
     int		dstBpp;
-    // these need to be signed now!
-    int 	iwidth=width;
-    int 	iheight=height;
     Bool	reverse = FALSE;
     Bool	upsidedown = FALSE;
-    int initialWidth=width;
-    int initialX=xDst;
- 
- 	// FIXME: this is possibly the worst piece of code I've ever written.
- 	// My main objection to it, is that it is incrfedibly slow in a few cases, due to the
- 	// call-per-repeat structure of it - the *correct* solution is to implement
- 	// repeat into fbBlt(), but that's a nontrivial job, and it's far more 
- 	// important to get the "requireRepeat" stuff implented functionally
-	// first, *then* make it fast.
- 	//  -- jj
-    Bool srcRepeat=pSrc->repeat;
-    CARD32 srcHeight=pSrc->pDrawable->height;
-    CARD32 srcWidth=pSrc->pDrawable->width;
+    
+    fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
+    fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
+	
+    fbBlt (src + (ySrc + srcYoff) * srcStride,
+	   srcStride,
+	   (xSrc + srcXoff) * srcBpp,
  
- 	fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
- 	fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
+	   dst + (yDst + dstYoff) * dstStride,
+	   dstStride,
+	   (xDst + dstXoff) * dstBpp,
 
- 	if(srcRepeat)
- 	{
- 		xSrc%=srcWidth;
- 		ySrc%=srcHeight;
- 	}
- 	
- 	while(iheight>0)
-	{
- 		int wheight=iheight;
- 		if(wheight>(srcHeight-ySrc))
- 			wheight=(srcHeight-ySrc);
- 		iwidth=initialWidth;
- 		xDst=initialX;
- 		while(iwidth>0)
- 		{
-			int wwidth=iwidth;
- 			if(wwidth>(srcWidth-xSrc))
- 				wwidth=(srcWidth-xSrc);
- 
- 			fbBlt (src + (ySrc + srcYoff) * srcStride,
- 					srcStride,
- 					(xSrc + srcXoff) * srcBpp,
- 
-					dst + (yDst + dstYoff) * dstStride,
- 					dstStride,
- 					(xDst + dstXoff) * dstBpp,
- 
- 					(wwidth) * dstBpp,
- 					(wheight),
- 
- 					GXcopy,
-					FB_ALLONES,
- 					dstBpp,
- 
- 					reverse,
- 					upsidedown);
- 			if(!srcRepeat)
- 				iwidth=0;
- 			else
-			{
- 				xDst+=wwidth;
- 				iwidth-=wwidth;
- 			}
- 		}
- 		if(!srcRepeat)
- 			iheight=0;
- 		else
- 		{
- 			yDst+=wheight;
- 			iheight-=wheight;
- 		}
- 	}
+	   (width) * dstBpp,
+	   (height),
+
+	   GXcopy,
+	   FB_ALLONES,
+	   dstBpp,
+
+	   reverse,
+	   upsidedown);
     
     fbFinishAccess(pSrc->pDrawable);
     fbFinishAccess(pDst->pDrawable);
@@ -1530,6 +1561,16 @@ fbComposite (CARD8      op,
 				break;
 			    }
 			}
+			else
+			{
+			    switch (pDst->format) {
+                            case PICT_r5g6b5:
+                                func = fbCompositeSolidMask_nx8888x0565;
+                                break;
+			    default:
+				break;
+                            }
+			}
 			break;
 		    case PICT_a8b8g8r8:
 			if (pMask->componentAlpha) {
@@ -1555,6 +1596,16 @@ fbComposite (CARD8      op,
 				break;
 			    }
 			}
+			else
+			{
+			    switch (pDst->format) {
+                            case PICT_b5g6r5:
+                                func = fbCompositeSolidMask_nx8888x0565;
+                                break;
+			    default:
+				break;
+                            }
+			}
 			break;
 		    case PICT_a1:
 			switch (pDst->format) {
@@ -1722,7 +1773,20 @@ fbComposite (CARD8      op,
 	    }
 	    else if (! srcRepeat)
 	    {
-		switch (pSrc->format) {
+		/*
+		 * Formats without alpha bits are just Copy with Over
+		 */
+		if (pSrc->format == pDst->format && !PICT_FORMAT_A(pSrc->format))
+		{
+#ifdef USE_MMX
+		    if (fbHaveMMX() &&
+			(pSrc->format == PICT_x8r8g8b8 || pSrc->format == PICT_x8b8g8r8))
+			func = fbCompositeCopyAreammx;
+		    else
+#endif
+			func = fbCompositeSrcSrc_nxn;
+		}
+		else switch (pSrc->format) {
 		case PICT_a8r8g8b8:
 		    switch (pDst->format) {
 		    case PICT_a8r8g8b8:
@@ -1800,24 +1864,6 @@ fbComposite (CARD8      op,
 			break;
 		    }
 		    break;
-		case PICT_r5g6b5:
-		    switch (pDst->format) {
-		    case PICT_r5g6b5:
-			func = fbCompositeSrc_0565x0565;
-			break;
-		    default:
-			break;
-		    }
-		    break;
-		case PICT_b5g6r5:
-		    switch (pDst->format) {
-		    case PICT_b5g6r5:
-			func = fbCompositeSrc_0565x0565;
-			break;
-		    default:
-			break;
-		    }
-		    break;
 		default:
 		    break;
 		}
@@ -1908,14 +1954,6 @@ fbComposite (CARD8      op,
 
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
-    // FIXME: this is bascially a "white list" of composites that work
-    // with repeat until they are all implented.  Once that's done, we
-    // remove the checks below entirely
-    if(func==fbCompositeSrcSrc_nxn)
-    {
-	    srcRepeat=maskRepeat=FALSE;
-    }
-
     while (n--)
     {
 	h = pbox->y2 - pbox->y1;
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 76cab5b..5246cd5 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -121,7 +121,7 @@ fbCanGetSolid(PicturePtr pict)
 	break; \
     case 16: \
 	(bits) = READ((CARD16 *) __bits__); \
-	(bits) = cvt0565to8888(bits); \
+	(bits) = cvt0565to0888(bits); \
 	break; \
     case 8: \
 	(bits) = READ((CARD8 *) __bits__); \
@@ -161,7 +161,7 @@ fbCanGetSolid(PicturePtr pict)
 #define cvt8888to0565(s)    ((((s) >> 3) & 0x001f) | \
 			     (((s) >> 5) & 0x07e0) | \
 			     (((s) >> 8) & 0xf800))
-#define cvt0565to8888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+#define cvt0565to0888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
 			     ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
 			     ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
 
diff-tree fde4a5adf02d3067a064ebf6bdd666aa5784cfe9 (from 13e1d5ea55b0a3b7729316c8e37d3d8fca2075b5)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 13:30:43 2007 -0400

    From xserver via pixman (Jeff Muizelaar)
    
         Add some optimizations from jaymz. Also adds some compile
         warnings that will hopefully go awa y as we continue merging.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 072f8d8..660112c 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -105,6 +105,51 @@ fbIn (CARD32 x, CARD8 y)
     return m|n|o|p;
 }
 
+#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))
+
+#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \
+	dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \
+	drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
+	*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
+
+#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \
+	dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \
+	drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
+	*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
+	
+// Note: this macro expects 6 bits of alpha, not 8!
+#define fastCombine0565(alpha, source, destval, destptr) { \
+	CARD16 dstrb = destval & 0xf81f; CARD16 dstg  = destval & 0x7e0; \
+	CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
+	destptr= ((((drb>>6) + dstrb)&0xf81f) | (((dg>>6)  + dstg) & 0x7e0)); \
+	}
+
+#if IMAGE_BYTE_ORDER == LSBFirst
+	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
+					temp=count&3; \
+					where-=temp; \
+					workingWhere=(CARD32 *)where; \
+					workingVal=*workingWhere++; \
+					count=4-temp; \
+					workingVal>>=(8*temp)
+	#define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)&0xff; (y)>>=8; (x)--;}
+	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
+	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
+	#define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; *wodst++=workingoDest; } 
+#else
+	#warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!"
+	#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
+					temp=count&3; \
+					where-=temp; \
+					workingWhere=(CARD32 *)where; \
+					workingVal=*workingWhere++; \
+					count=4-temp; \
+					workingVal<<=(8*temp)
+	#define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)>>24; (y)<<=8; (x)--;}
+	#define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
+	#define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
+	#define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; } 
+#endif
 /*
  * Naming convention:
  *
@@ -248,6 +293,7 @@ fbCompositeSolidMask_nx8888x8888C (CARD8
     fbFinishAccess (pDst->pDrawable);
 }
 
+#define srcAlphaCombine24(a,b) genericCombine24(a,b,srca,srcia)
 void
 fbCompositeSolidMask_nx8x0888 (CARD8      op,
 			       PicturePtr pSrc,
@@ -262,52 +308,86 @@ fbCompositeSolidMask_nx8x0888 (CARD8    
 			       CARD16     width,
 			       CARD16     height)
 {
-    CARD32	src, srca;
-    CARD8	*dstLine, *dst;
+    CARD32	src, srca, srcia;
+    CARD8	*dstLine, *dst, *edst;
     CARD32	d;
     CARD8	*maskLine, *mask, m;
     FbStride	dstStride, maskStride;
     CARD16	w;
+    CARD32 rs,gs,bs,rd,gd,bd;
 
     fbComposeGetSolid(pSrc, src, pDst->format);
 
     srca = src >> 24;
+    srcia = 255-srca;
     if (src == 0)
 	return;
 
+    rs=src&0xff;
+    gs=(src>>8)&0xff;
+    bs=(src>>16)&0xff;
+      
     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
     fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
 
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = Fetch24(dst);
-		    d = fbOver24 (src, d);
+     while (height--)
+  	{
+ 		// fixme: cleanup unused
+ 		unsigned int wt,wd;
+ 		CARD32 workingiDest;
+ 		CARD32 *widst;
+ 		
+ 		edst=dst = dstLine;
+ 		dstLine += dstStride;
+ 		mask = maskLine;
+ 		maskLine += maskStride;
+ 		w = width;
+ 		
+#ifndef NO_MASKED_PACKED_READ
+ 		setupPackedReader(wd,wt,edst,widst,workingiDest);
+#endif
+ 				
+ 		while (w--)
+ 		{
+#ifndef NO_MASKED_PACKED_READ
+ 			readPackedDest(rd);
+ 			readPackedDest(gd);
+ 			readPackedDest(bd);
+#else
+ 			rd= *edst++;
+ 			gd= *edst++;
+ 			bd= *edst++;
+#endif
+ 			m = *mask++;
+ 			if (m == 0xff)
+ 			{
+ 				if (srca == 0xff)
+ 				{
+ 					*dst++=rs;
+ 					*dst++=gs;
+ 					*dst++=bs;
+ 				}
+ 				else
+ 				{
+ 					*dst++=(srcAlphaCombine24(rs, rd)>>8);
+ 					*dst++=(srcAlphaCombine24(gs, gd)>>8);
+ 					*dst++=(srcAlphaCombine24(bs, bd)>>8);
+				}
+ 			}
+ 			else if (m)
+ 			{
+ 				int na=(srca*(int)m)>>8;
+ 				int nia=255-na;
+ 				*dst++=(genericCombine24(rs, rd, na, nia)>>8);
+ 				*dst++=(genericCombine24(gs, gd, na, nia)>>8);
+ 				*dst++=(genericCombine24(bs, bd, na, nia)>>8);
+ 			}
+ 			else
+ 			{
+ 				dst+=3;
+ 			}
 		}
-		Store24(dst,d);
-	    }
-	    else if (m)
-	    {
-		d = fbOver24 (fbIn(src,m), Fetch24(dst));
-		Store24(dst,d);
-	    }
-	    dst += 3;
 	}
-    }
 
     fbFinishAccess (pMask->pDrawable);
     fbFinishAccess (pDst->pDrawable);
@@ -327,54 +407,57 @@ fbCompositeSolidMask_nx8x0565 (CARD8    
 				  CARD16     width,
 				  CARD16     height)
 {
-    CARD32	src, srca;
-    CARD16	*dstLine, *dst;
-    CARD32	d;
-    CARD8	*maskLine, *mask, m;
-    FbStride	dstStride, maskStride;
-    CARD16	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = READ(dst);
-		    d = fbOver24 (src, cvt0565to8888(d));
-		}
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    else if (m)
-	    {
-		d = READ(dst);
-		d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
-		WRITE(dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-
+     CARD32	src, srca,na, rsrca;
+     CARD16	*dstLine, *dst;
+     CARD16	d;
+     CARD8	*maskLine, *mask, m;
+     FbStride	dstStride, maskStride;
+     CARD16	w,src16;
+  
+     fbComposeGetSolid(pSrc, src, pDst->format);
+     src16 = cvt8888to0565(src);
+      
+     rsrca = src >> 24;
+     srca=rsrca>>2;
+      if (src == 0)
+ 		return;
+      
+      fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+      fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+    
+ 	while (height--)
+  	{
+ 		dst = dstLine;
+ 		dstLine += dstStride;
+ 		mask = maskLine;
+ 		maskLine += maskStride;
+ 		w = width;
+ 
+ 		while (w--)
+  		{
+ 			m = *mask++;
+ 			if (m == 0xff)
+ 			{
+ 				if (srca == 0xff)
+ 				{
+ 					*dst=src16;
+ 				}
+ 				else
+ 				{
+ 					d = *dst;
+ 					fastCombine0565(srca, src16, d, *dst++);
+ 				}
+ 			}
+ 			else if (m)
+ 			{
+ 				na=(rsrca*(int)m)>>10;
+ 				d = *dst;
+ 				fastCombine0565(na, src16, d, *dst++);
+ 			}
+ 			else
+ 				dst++;
+  		}
+  	}
     fbFinishAccess (pMask->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
@@ -906,7 +989,7 @@ fbCompositeTrans_0565xnx0565(CARD8      
     CARD32	s_32, d_32, i_32, r_32;
     
     fbComposeGetSolid (pMask, mask, pDst->format);
-    maskAlpha = mask >> 24;
+    maskAlpha = mask >> 26;
     
     if (!maskAlpha)
 	return;
@@ -922,31 +1005,276 @@ fbCompositeTrans_0565xnx0565(CARD8      
     fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
 
     while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s_16 = READ(src++);
-	    s_32 = cvt0565to8888(s_16);
-	    d_16 = READ(dst);
-	    d_32 = cvt0565to8888(d_16);
-	    
-	    i_32 = fbIn24 (s_32, maskAlpha);
-	    r_32 = fbOver24 (i_32, d_32);
-	    r_16 = cvt8888to0565(r_32);
-	    WRITE(dst++, r_16);
-	}
-    }
+ 	{
+ 		CARD32 *isrc;
+ 		dst = dstLine;
+ 		dstLine += dstStride;
+ 		src = srcLine;
+ 		srcLine += srcStride;
+ 		w = width;
+ 		
+ 		if(((int)src&1)==1)
+ 		{
+ 			s_16 = *src++;
+ 			d_16 = *dst;
+ 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
+ 			w--;
+ 		}
+ 		isrc=(CARD32 *)src;
+ 		while (w>1)
+ 		{
+ 			s_32=*isrc++;
+#if IMAGE_BYTE_ORDER == LSBFirst
+ 			s_16=s_32&0xffff;
+#else
+			s_16=s_32>>16;
+#endif
+ 			d_16 = *dst;
+ 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
+ #if IMAGE_BYTE_ORDER == LSBFirst
+ 			s_16=s_32>>16;
+ #else
+ 			s_16=s_32&0xffff;
+ #endif
+ 			d_16 = *dst;
+ 			fastCombine0565(maskAlpha, s_16, d_16, *dst++);
+ 			w-=2;
+ 		}
+ 		src=(CARD16 *)isrc;
+ 		if(w!=0)
+ 		{
+ 			s_16 = *src;
+ 			d_16 = *dst;
+ 			fastCombine0565(maskAlpha, s_16, d_16, *dst);
+ 		}
+ 	}
 
     fbFinishAccess (pSrc->pDrawable);
     fbFinishAccess (pDst->pDrawable);
 }
 
+// macros for "i can't believe it's not fast" packed pixel handling
+#define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
+static void
+fbCompositeTrans_0888xnx0888(CARD8      op,
+ 			     PicturePtr pSrc,
+ 			     PicturePtr pMask,
+ 			     PicturePtr pDst,
+ 			     INT16      xSrc,
+ 			     INT16      ySrc,
+ 			     INT16      xMask,
+ 			     INT16      yMask,
+ 			     INT16      xDst,
+ 			     INT16      yDst,
+ 			     CARD16     width,
+ 			     CARD16     height)
+ {
+     CARD8	*dstLine, *dst,*idst;
+     CARD8	*srcLine, *src;
+     FbStride	dstStride, srcStride;
+     CARD16	w;
+     FbBits	mask;
+     CARD16	maskAlpha,maskiAlpha;
+     
+     fbComposeGetSolid (pMask, mask, pDst->format);
+     maskAlpha = mask >> 24;
+ 	maskiAlpha= 255-maskAlpha;
+     
+     if (!maskAlpha)
+ 	return;
+     //if (maskAlpha == 0xff)
+     //{
+ 	//fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
+ 	//			  xSrc, ySrc, xMask, yMask, xDst, yDst, 
+ 	//			  width, height);
+ 	//return;
+     //}
+ 	
+     fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
+     fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+  
+  	{
+ 		unsigned int ws,wt,wd,ww;
+ 		CARD32 workingSource;
+ 		CARD32 *wsrc;
+ 		CARD32 rs,gs,bs;
+ 		CARD32 rd,gd,bd;
+ 
+ 		CARD32 workingiDest,workingoDest;
+ 		CARD32 *widst,*wodst;
+ 
+ 
+ 		// are xSrc and xDst at the same alignment?  if not, we need to be complicated :)
+ 		//if(0==0)
+ 		if( (((xSrc*3)&3)!=((xDst*3)&3)) || (srcStride&3)!=0 || (dstStride&3)!=0)
+ 		{
+ 			while (height--)
+ 			{
+ 				idst=dst = dstLine;
+ 				dstLine += dstStride;
+ 				src = srcLine;
+ 				srcLine += srcStride;
+ 				w = width*3;
+ 				
+ 				setupPackedReader(wd,wt,idst,widst,workingiDest);
+ 				ww=(int)dst;
+ 				wt=ww&3;
+ 				dst-=wt; 
+ 				wodst=(CARD32 *)dst; 
+ 				workingoDest=*wodst; 
+ 				ww=4-wt;
+#if IMAGE_BYTE_ORDER == LSBFirst
+ 				workingoDest<<=(8*(ww+1));
+#else
+ 				workingoDest>>=(8*(ww+1));
+#endif
+ 
+ 				// get to word aligned
+ 				switch(!(int)src&3)
+ 				{
+ 					case 1:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 						w--; if(w==0) break;
+ 					case 2:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 						w--; if(w==0) break;
+ 					case 3:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 						w--; if(w==0) break;
+ 				}
+ 				wsrc=(CARD32 *)src;
+				while (w>3)
+				{
+ 					rs=*wsrc++;
+ 					// FIXME: write a version of readPackedDest() which
+ 					// can collect 4 bytes at once if we're on a boundry (which we're
+ 					// actually guarenteed not to be in this version, but do it anyhow), and can
+ 					// collect as 2 16bit words on a 2byte boundry, and then use the 32bit combine here
+ #if IMAGE_BYTE_ORDER == LSBFirst
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24(rs&0xff, rd)>>8;
+ 					writePacked(rd);
+ 
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8;
+ 					writePacked(rd);
+ 					
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8;
+ 					writePacked(rd);
+ 					
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24(rs>>24, rd)>>8;
+ 					writePacked(rd);
+ #else
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24(rs>>24, rd)>>8;
+ 					writePacked(rd);
+ 					
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8;
+ 					writePacked(rd);
+ 					
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8;
+ 					writePacked(rd);
+ 
+ 					readPackedDest(rd);
+ 					rd=alphamaskCombine24(rs&0xff, rd)>>8;
+ 					writePacked(rd);
+ #endif
+ 					w-=4;
+ 				}
+ 				src=(CARD8 *)wsrc;
+ 				switch(w)
+ 				{
+ 					case 3:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 					case 2:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 					case 1:
+ 						readPackedDest(rd);
+ 						rd=alphamaskCombine24(*src++, rd)>>8;
+ 						writePacked(rd);
+ 				}
+ 				dst=(CARD8 *)wodst;
+ 				switch(ww)
+ 				{
+ 					case 1:
+ 						dst[2]=(workingoDest>>8)&0xff;
+ 					case 2:
+ 						dst[1]=(workingoDest>>16)&0xff;
+ 					case 3:
+ 						dst[0]=workingoDest>>24;
+ 				}
+ 			}
+ 		}
+ 		else
+ 		{
+ 			while (height--)
+ 			{
+ 				idst=dst = dstLine;
+ 				dstLine += dstStride;
+ 				src = srcLine;
+ 				srcLine += srcStride;
+ 				w = width*3;
+ 				// get to word aligned
+ 				switch(!(int)src&3)
+ 				{
+					case 1:
+ 						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 						w--; if(w==0) break;
+ 					case 2:
+ 						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 						w--; if(w==0) break;
+					case 3:
+ 						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 						w--; if(w==0) break;
+ 				}
+ 				wsrc=(CARD32 *)src;
+ 				widst=(CARD32 *)dst;
+ 
+				register CARD32 t1, t2, t3, t4;
+ 				while(w>3)
+ 				{
+ 					rs = *wsrc++;
+ 					rd = *widst;
+ 					fastcombine32(maskAlpha, rs, rd, widst, t1, t2, t3, t4);
+ 					w-=4;
+ 				}
+				src=(CARD8 *)wsrc;
+ 				dst=(CARD8 *)widst;
+ 				switch(w)
+ 				{
+ 					case 3:
+ 						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 					case 2:
+						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 					case 1:
+ 						rd=alphamaskCombine24(*src++, *dst)>>8;
+ 						*dst++=rd;
+ 				}
+ 			}
+ 		}
+ 	}
+  }
+
+
 /*
  * Simple bitblt
  */
@@ -972,30 +1300,81 @@ fbCompositeSrcSrc_nxn  (CARD8	   op,
     int		dstXoff, dstYoff;
     int		srcBpp;
     int		dstBpp;
+    // these need to be signed now!
+    int 	iwidth=width;
+    int 	iheight=height;
     Bool	reverse = FALSE;
     Bool	upsidedown = FALSE;
+    int initialWidth=width;
+    int initialX=xDst;
+ 
+ 	// FIXME: this is possibly the worst piece of code I've ever written.
+ 	// My main objection to it, is that it is incrfedibly slow in a few cases, due to the
+ 	// call-per-repeat structure of it - the *correct* solution is to implement
+ 	// repeat into fbBlt(), but that's a nontrivial job, and it's far more 
+ 	// important to get the "requireRepeat" stuff implented functionally
+	// first, *then* make it fast.
+ 	//  -- jj
+    Bool srcRepeat=pSrc->repeat;
+    CARD32 srcHeight=pSrc->pDrawable->height;
+    CARD32 srcWidth=pSrc->pDrawable->width;
+ 
+ 	fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
+ 	fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
+
+ 	if(srcRepeat)
+ 	{
+ 		xSrc%=srcWidth;
+ 		ySrc%=srcHeight;
+ 	}
+ 	
+ 	while(iheight>0)
+	{
+ 		int wheight=iheight;
+ 		if(wheight>(srcHeight-ySrc))
+ 			wheight=(srcHeight-ySrc);
+ 		iwidth=initialWidth;
+ 		xDst=initialX;
+ 		while(iwidth>0)
+ 		{
+			int wwidth=iwidth;
+ 			if(wwidth>(srcWidth-xSrc))
+ 				wwidth=(srcWidth-xSrc);
+ 
+ 			fbBlt (src + (ySrc + srcYoff) * srcStride,
+ 					srcStride,
+ 					(xSrc + srcXoff) * srcBpp,
+ 
+					dst + (yDst + dstYoff) * dstStride,
+ 					dstStride,
+ 					(xDst + dstXoff) * dstBpp,
+ 
+ 					(wwidth) * dstBpp,
+ 					(wheight),
+ 
+ 					GXcopy,
+					FB_ALLONES,
+ 					dstBpp,
+ 
+ 					reverse,
+ 					upsidedown);
+ 			if(!srcRepeat)
+ 				iwidth=0;
+ 			else
+			{
+ 				xDst+=wwidth;
+ 				iwidth-=wwidth;
+ 			}
+ 		}
+ 		if(!srcRepeat)
+ 			iheight=0;
+ 		else
+ 		{
+ 			yDst+=wheight;
+ 			iheight-=wheight;
+ 		}
+ 	}
     
-    fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
-    fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
-
-    fbBlt (src + (ySrc + srcYoff) * srcStride,
-	   srcStride,
-	   (xSrc + srcXoff) * srcBpp,
-
-	   dst + (yDst + dstYoff) * dstStride,
-	   dstStride,
-	   (xDst + dstXoff) * dstBpp,
-
-	   (width) * dstBpp,
-	   (height),
-
-	   GXcopy,
-	   FB_ALLONES,
-	   dstBpp,
-
-	   reverse,
-	   upsidedown);
-
     fbFinishAccess(pSrc->pDrawable);
     fbFinishAccess(pDst->pDrawable);
 }
@@ -1294,6 +1673,11 @@ fbComposite (CARD8      op,
 		    if (pDst->format == pSrc->format)
 		        func = fbCompositeTrans_0565xnx0565;
 		    break;
+ 		case PICT_r8g8b8:
+ 		case PICT_b8g8r8:
+ 		    if (pDst->format == pSrc->format)
+ 		        func = fbCompositeTrans_0888xnx0888;
+ 		    break;
 		default:
 		    break;
 		}
@@ -1524,6 +1908,14 @@ fbComposite (CARD8      op,
 
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
+    // FIXME: this is bascially a "white list" of composites that work
+    // with repeat until they are all implented.  Once that's done, we
+    // remove the checks below entirely
+    if(func==fbCompositeSrcSrc_nxn)
+    {
+	    srcRepeat=maskRepeat=FALSE;
+    }
+
     while (n--)
     {
 	h = pbox->y2 - pbox->y1;
diff-tree 13e1d5ea55b0a3b7729316c8e37d3d8fca2075b5 (from 077a5d4555676d5775e990468a697b6890c6d609)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 12:59:18 2007 -0400

    Fix format vs formatCode in previous commit

diff --git a/fb/fbpict.c b/fb/fbpict.c
index bc737d8..072f8d8 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1085,7 +1085,7 @@ fbComposite (CARD8      op,
 #endif
 	    if (pMask == 0)
 	    {
-		if (pSrc->format_code == pDst->format_code)
+		if (pSrc->format == pDst->format)
 		    func = fbCompositeSrcSrc_nxn;
 	    }
 	break;
diff-tree 077a5d4555676d5775e990468a697b6890c6d609 (from 09436fb7c38a9819bde770c4c21143591671c4d7)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Tue Apr 24 12:57:55 2007 -0400

    Add functions fbCompositeSrcSrc_nxn() and fbCompositeTrans_0565xnx0565
    from xserver via pixman. Add READ/WRITE and fbFinishAccess as
    appropriate.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index cd6cac2..bc737d8 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -64,6 +64,20 @@ fbOver (CARD32 x, CARD32 y)
     return m|n|o|p;
 }
 
+static CARD32
+fbIn24 (CARD32 x, CARD8 y)
+{
+    CARD16  a = y;
+    CARD16  t;
+    CARD32  m,n,o,p;
+
+    m = FbInU(x,0,a,t);
+    n = FbInU(x,8,a,t);
+    o = FbInU(x,16,a,t);
+    p = (y << 24);
+    return m|n|o|p;
+}
+
 CARD32
 fbOver24 (CARD32 x, CARD32 y)
 {
@@ -864,6 +878,148 @@ fbCompositeSolidMask_nx1xn (CARD8      o
 
 # define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
 
+/*
+ * Apply a constant alpha value in an over computation
+ */
+
+static void
+fbCompositeTrans_0565xnx0565(CARD8      op,
+			     PicturePtr pSrc,
+			     PicturePtr pMask,
+			     PicturePtr pDst,
+			     INT16      xSrc,
+			     INT16      ySrc,
+			     INT16      xMask,
+			     INT16      yMask,
+			     INT16      xDst,
+			     INT16      yDst,
+			     CARD16     width,
+			     CARD16     height)
+{
+    CARD16	*dstLine, *dst;
+    CARD16	*srcLine, *src;
+    FbStride	dstStride, srcStride;
+    CARD16	w;
+    FbBits	mask;
+    CARD8	maskAlpha;
+    CARD16	s_16, d_16, r_16;
+    CARD32	s_32, d_32, i_32, r_32;
+    
+    fbComposeGetSolid (pMask, mask, pDst->format);
+    maskAlpha = mask >> 24;
+    
+    if (!maskAlpha)
+	return;
+    if (maskAlpha == 0xff)
+    {
+	fbCompositeSrc_0565x0565 (op, pSrc, pMask, pDst,
+				  xSrc, ySrc, xMask, yMask, xDst, yDst, 
+				  width, height);
+	return;
+    }
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
+    fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s_16 = READ(src++);
+	    s_32 = cvt0565to8888(s_16);
+	    d_16 = READ(dst);
+	    d_32 = cvt0565to8888(d_16);
+	    
+	    i_32 = fbIn24 (s_32, maskAlpha);
+	    r_32 = fbOver24 (i_32, d_32);
+	    r_16 = cvt8888to0565(r_32);
+	    WRITE(dst++, r_16);
+	}
+    }
+
+    fbFinishAccess (pSrc->pDrawable);
+    fbFinishAccess (pDst->pDrawable);
+}
+
+/*
+ * Simple bitblt
+ */
+
+static void
+fbCompositeSrcSrc_nxn  (CARD8	   op,
+			PicturePtr pSrc,
+			PicturePtr pMask,
+			PicturePtr pDst,
+			INT16      xSrc,
+			INT16      ySrc,
+			INT16      xMask,
+			INT16      yMask,
+			INT16      xDst,
+			INT16      yDst,
+			CARD16     width,
+			CARD16     height)
+{
+    FbBits	*dst;
+    FbBits	*src;
+    FbStride	dstStride, srcStride;
+    int		srcXoff, srcYoff;
+    int		dstXoff, dstYoff;
+    int		srcBpp;
+    int		dstBpp;
+    Bool	reverse = FALSE;
+    Bool	upsidedown = FALSE;
+    
+    fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
+    fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
+
+    fbBlt (src + (ySrc + srcYoff) * srcStride,
+	   srcStride,
+	   (xSrc + srcXoff) * srcBpp,
+
+	   dst + (yDst + dstYoff) * dstStride,
+	   dstStride,
+	   (xDst + dstXoff) * dstBpp,
+
+	   (width) * dstBpp,
+	   (height),
+
+	   GXcopy,
+	   FB_ALLONES,
+	   dstBpp,
+
+	   reverse,
+	   upsidedown);
+
+    fbFinishAccess(pSrc->pDrawable);
+    fbFinishAccess(pDst->pDrawable);
+}
+
+/*
+ * Solid fill
+void
+fbCompositeSolidSrc_nxn  (CARD8	op,
+			  PicturePtr pSrc,
+			  PicturePtr pMask,
+			  PicturePtr pDst,
+			  INT16      xSrc,
+			  INT16      ySrc,
+			  INT16      xMask,
+			  INT16      yMask,
+			  INT16      xDst,
+			  INT16      yDst,
+			  CARD16     width,
+			  CARD16     height)
+{
+    
+}
+ */
+
 void
 fbComposite (CARD8      op,
 	     PicturePtr pSrc,
@@ -925,7 +1081,13 @@ fbComposite (CARD8      op,
 	{
 	    func = fbCompositeCopyAreammx;
 	}
+	else
 #endif
+	    if (pMask == 0)
+	    {
+		if (pSrc->format_code == pDst->format_code)
+		    func = fbCompositeSrcSrc_nxn;
+	    }
 	break;
     case PictOpOver:
 	if (pMask)
@@ -933,7 +1095,6 @@ fbComposite (CARD8      op,
 	    if (fbCanGetSolid(pSrc) &&
 		!maskRepeat)
 	    {
-		srcRepeat = FALSE;
 		if (PICT_FORMAT_COLOR(pSrc->format)) {
 		    switch (pMask->format) {
 		    case PICT_a8:
@@ -1120,6 +1281,24 @@ fbComposite (CARD8      op,
 			}
 		    }
 		}
+		if (func != fbCompositeGeneral)
+		    srcRepeat = FALSE;
+	    }
+	    else if (maskRepeat &&
+		     pMask->pDrawable->width == 1 &&
+		     pMask->pDrawable->height == 1)
+	    {
+		switch (pSrc->format) {
+		case PICT_r5g6b5:
+		case PICT_b5g6r5:
+		    if (pDst->format == pSrc->format)
+		        func = fbCompositeTrans_0565xnx0565;
+		    break;
+		default:
+		    break;
+		}
+		if (func != fbCompositeGeneral)
+		    maskRepeat = FALSE;
 	    }
 	}
 	else /* no mask */
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 434526e..76cab5b 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -123,6 +123,14 @@ fbCanGetSolid(PicturePtr pict)
 	(bits) = READ((CARD16 *) __bits__); \
 	(bits) = cvt0565to8888(bits); \
 	break; \
+    case 8: \
+	(bits) = READ((CARD8 *) __bits__); \
+	(bits) = (bits) << 24; \
+	break; \
+    case 1: \
+	(bits) = READ((CARD32 *) __bits__);			\
+	(bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
+	break; \
     default: \
 	return; \
     } \
diff-tree 09436fb7c38a9819bde770c4c21143591671c4d7 (from c7e2ba0c9b9b1fc1aed8f91f86471c4c8e650b78)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 24 22:52:33 2007 +0930

    Disable devices before removing, remove unrecoverable devices.

diff --git a/dix/devices.c b/dix/devices.c
index e8ca5df..e227617 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -577,6 +577,7 @@ RemoveDevice(DeviceIntPtr dev)
         return BadImplementation;
 
     deviceid = dev->id;
+    DisableDevice(dev);
 
     prev = NULL;
     for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 0af1c6a..2d0a376 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -771,11 +771,30 @@ xf86InitValuatorDefaults(DeviceIntPtr de
  * Device will be moved to the off_devices list, but it will still be there
  * until you really clean up after it.
  * Notifies the client about an inactive device.
+ * 
+ * @param panic True if device is unrecoverable and needs to be removed.
  */
 _X_EXPORT void
-xf86DisableDevice(DeviceIntPtr dev)
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
 {
-    DisableDevice(dev);
+    devicePresenceNotify ev;
+    DeviceIntRec dummyDev;
+
+    if(!panic)
+    {
+        DisableDevice(dev);
+    } else
+    {
+        ev.type = DevicePresenceNotify;
+        ev.time = currentTime.milliseconds;
+        ev.devchange = DeviceUnrecoverable;
+        ev.deviceid = dev->id;
+        dummyDev.id = 0;
+        SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+                (xEvent *) &ev, 1);
+
+        DeleteInputDeviceRequest(dev);
+    }
 }
 
 /**
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index f5beb6c..7ef28ed 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -187,7 +187,7 @@ void xf86InitValuatorAxisStruct(DeviceIn
 void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
 void xf86AddEnabledDevice(InputInfoPtr pInfo);
 void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
-void xf86DisableDevice(DeviceIntPtr dev);
+void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
 void xf86EnableDevice(DeviceIntPtr dev);
 
 /* xf86Helper.c */
diff-tree c7e2ba0c9b9b1fc1aed8f91f86471c4c8e650b78 (from ce099a9b78195540ec251a6a3dbe26019c1a686d)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 24 21:34:47 2007 +0930

    Use DevicePresence events to tell the client about enabled/disabled devices.
    
    Include the device id in the event sent to the client.

diff --git a/dix/devices.c b/dix/devices.c
index 7d8fd03..e8ca5df 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -75,6 +75,7 @@ SOFTWARE.
 #include "swaprep.h"
 #include "dixevents.h"
 
+#include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
 #include "exglobals.h"
 #include "exevents.h"
@@ -157,6 +158,8 @@ EnableDevice(DeviceIntPtr dev)
 {
     DeviceIntPtr *prev;
     int ret;
+    DeviceIntRec dummyDev;
+    devicePresenceNotify ev;
 
     for (prev = &inputInfo.off_devices;
 	 *prev && (*prev != dev);
@@ -175,6 +178,14 @@ EnableDevice(DeviceIntPtr dev)
     *prev = dev;
     dev->next = NULL;
 
+    ev.type = DevicePresenceNotify;
+    ev.time = currentTime.milliseconds;
+    ev.devchange = DeviceEnabled;
+    ev.deviceid = dev->id;
+    dummyDev.id = 0;
+    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+                          (xEvent *) &ev, 1);
+
     return TRUE;
 }
 
@@ -182,6 +193,8 @@ Bool
 DisableDevice(DeviceIntPtr dev)
 {
     DeviceIntPtr *prev;
+    DeviceIntRec dummyDev;
+    devicePresenceNotify ev;
 
     for (prev = &inputInfo.devices;
 	 *prev && (*prev != dev);
@@ -194,6 +207,15 @@ DisableDevice(DeviceIntPtr dev)
     *prev = dev->next;
     dev->next = inputInfo.off_devices;
     inputInfo.off_devices = dev;
+
+    ev.type = DevicePresenceNotify;
+    ev.time = currentTime.milliseconds;
+    ev.devchange = DeviceDisabled;
+    ev.deviceid = dev->id;
+    dummyDev.id = 0;
+    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+                          (xEvent *) &ev, 1);
+
     return TRUE;
 }
 
@@ -212,8 +234,8 @@ ActivateDevice(DeviceIntPtr dev)
     
     ev.type = DevicePresenceNotify;
     ev.time = currentTime.milliseconds;
-    ev.devchange = 0;
-    ev.deviceid = 0;
+    ev.devchange = DeviceAdded;
+    ev.deviceid = dev->id;
     dummyDev.id = 0;
     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
                           (xEvent *) &ev, 1);
@@ -547,12 +569,15 @@ RemoveDevice(DeviceIntPtr dev)
     int ret = BadMatch;
     devicePresenceNotify ev;
     DeviceIntRec dummyDev;
+    int deviceid;
 
     DebugF("(dix) removing device %d\n", dev->id);
 
     if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
         return BadImplementation;
 
+    deviceid = dev->id;
+
     prev = NULL;
     for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
 	next = tmp->next;
@@ -587,8 +612,8 @@ RemoveDevice(DeviceIntPtr dev)
         inputInfo.numDevices--;
         ev.type = DevicePresenceNotify;
         ev.time = currentTime.milliseconds;
-        ev.devchange = 0;
-        ev.deviceid = 0;
+        ev.devchange = DeviceRemoved;
+        ev.deviceid = deviceid;
         dummyDev.id = 0;
         SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
                               (xEvent *) &ev, 1);
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 6ebb087..0af1c6a 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -764,4 +764,29 @@ xf86InitValuatorDefaults(DeviceIntPtr de
     }
 }
 
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ */
+_X_EXPORT void
+xf86DisableDevice(DeviceIntPtr dev)
+{
+    DisableDevice(dev);
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client. 
+ */
+_X_EXPORT void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+    EnableDevice(dev);
+}
+
 /* end of xf86Xinput.c */
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index b2bc8de..f5beb6c 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -187,6 +187,8 @@ void xf86InitValuatorAxisStruct(DeviceIn
 void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
 void xf86AddEnabledDevice(InputInfoPtr pInfo);
 void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
+void xf86DisableDevice(DeviceIntPtr dev);
+void xf86EnableDevice(DeviceIntPtr dev);
 
 /* xf86Helper.c */
 void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
@@ -204,6 +206,7 @@ int xf86GetMotionEvents(DeviceIntPtr dev
 void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
 			     pointer extraOpts);
 
+
 /* Legacy hatred */
 #define SendCoreEvents 59
 #define DontSendCoreEvents 60
diff-tree ce099a9b78195540ec251a6a3dbe26019c1a686d (from b5e1f7869b2f12a1c2baa7f699ae609fc9ad50aa)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Apr 23 12:34:01 2007 -0600

    fix bug in which maxKeysPerModifier wasn't getting set

diff --git a/dix/devices.c b/dix/devices.c
index c2d4f22..7d8fd03 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1241,6 +1241,7 @@ DoSetModifierMapping(ClientPtr client, K
             }
             else {
                 pDev->key->modifierKeyMap = NULL;
+                pDev->key->maxKeysPerModifier = 0;
             }
         }
     }
diff-tree b5e1f7869b2f12a1c2baa7f699ae609fc9ad50aa (from 84838268b34661d598f8e4856fab355f414930d9)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Mon Apr 23 14:16:30 2007 -0400

    Remove #if 0'ed merge leftovers

diff --git a/render/picture.c b/render/picture.c
index 201ceb2..2022175 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1051,23 +1051,6 @@ CreateRadialGradientPicture (Picture pid
     radial = &pPicture->pSourcePict->radial;
 
     radial->type = SourcePictTypeRadial;
-#if 0
-    {
-        double x = (double)innerRadius / (double)outerRadius;
-        radial->dx = (outer->x - inner->x);
-        radial->dy = (outer->y - inner->y);
-        radial->fx = (inner->x) - x*radial->dx;
-        radial->fy = (inner->y) - x*radial->dy;
-        radial->m = 1./(1+x);
-        radial->b = -x*radial->m;
-        radial->dx /= 65536.;
-        radial->dy /= 65536.;
-        radial->fx /= 65536.;
-        radial->fy /= 65536.;
-        x = outerRadius/65536.;
-        radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
-    }
-#endif
     radial->c1.x = inner->x;
     radial->c1.y = inner->y;
     radial->c1.radius = innerRadius;
diff-tree 84838268b34661d598f8e4856fab355f414930d9 (from 38d14e858980a1b0c087344d24bf6aebf755663c)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Mon Apr 23 13:19:54 2007 -0400

    Gradient fixes
    
    * Port fix for bug 7685 from pixman. Patch by Carl Worth
    
    * Add projective version of radial gradient code.
    
    * Make sure that all Pict*Gradient types have PictGradient as prefix,
      since code in various places relies on that.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 0faf783..24b552e 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -3148,13 +3148,128 @@ static void fbFetchSourcePict(PicturePtr
             }
         }
     } else {
+
+/*
+ * In the radial gradient problem we are given two circles (c₁,r₁) and
+ * (câ‚‚,râ‚‚) that define the gradient itself. Then, for any point p, we
+ * must compute the value(s) of t within [0.0, 1.0] representing the
+ * circle(s) that would color the point.
+ *
+ * There are potentially two values of t since the point p can be
+ * colored by both sides of the circle, (which happens whenever one
+ * circle is not entirely contained within the other).
+ *
+ * If we solve for a value of t that is outside of [0.0, 1.0] then we
+ * use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
+ * value within [0.0, 1.0].
+ *
+ * Here is an illustration of the problem:
+ *
+ *              pâ‚‚
+ *           p  •
+ *           •   ╲
+ *        ·       ╲r₂
+ *  p₁ ·           ╲
+ *  •              θ╲
+ *   ╲             ╌╌•
+ *    ╲r₁        ·   c₂
+ *    θ╲    ·
+ *    ╌╌•
+ *      c₁
+ *
+ * Given (c₁,r₁), (c₂,r₂) and p, we must find an angle θ such that two
+ * points p₁ and p₂ on the two circles are collinear with p. Then, the
+ * desired value of t is the ratio of the length of p₁p to the length
+ * of p₁p₂.
+ *
+ * So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ and t.
+ * We can also write six equations that constrain the problem:
+ *
+ * Point p₁ is a distance r₁ from c₁ at an angle of θ:
+ *
+ *	1. p₁x = c₁x + r₁·cos θ
+ *	2. p₁y = c₁y + r₁·sin θ
+ *
+ * Point p₂ is a distance r₂ from c₂ at an angle of θ:
+ *
+ *	3. p₂x = c₂x + r2·cos θ
+ *	4. p₂y = c₂y + r2·sin θ
+ *
+ * Point p lies at a fraction t along the line segment p₁p₂:
+ *
+ *	5. px = t·p₂x + (1-t)·p₁x
+ *	6. py = t·p₂y + (1-t)·p₁y
+ *
+ * To solve, first subtitute 1-4 into 5 and 6:
+ *
+ * px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
+ * py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
+ *
+ * Then solve each for cos θ and sin θ expressed as a function of t:
+ *
+ * cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
+ * sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((r₂-r₁)·t + r₁)
+ *
+ * To simplify this a bit, we define new variables for several of the
+ * common terms as shown below:
+ *
+ *              pâ‚‚
+ *           p  •
+ *           •   ╲
+ *        ·  ┆    ╲r₂
+ *  p₁ ·     ┆     ╲
+ *  •     pdy┆      ╲
+ *   ╲       ┆       •c₂
+ *    ╲r₁    ┆   ·   ┆
+ *     ╲    ·┆       ┆cdy
+ *      •╌╌╌╌┴╌╌╌╌╌╌╌┘
+ *    c₁  pdx   cdx
+ *
+ * cdx = (c₂x - c₁x)
+ * cdy = (c₂y - c₁y)
+ *  dr =  r₂-r₁
+ * pdx =  px - c₁x
+ * pdy =  py - c₁y
+ *
+ * Note that cdx, cdy, and dr do not depend on point p at all, so can
+ * be pre-computed for the entire gradient. The simplifed equations
+ * are now:
+ *
+ * cos θ = (-cdx·t + pdx) / (dr·t + r₁)
+ * sin θ = (-cdy·t + pdy) / (dr·t + r₁)
+ *
+ * Finally, to get a single function of t and eliminate the last
+ * unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
+ * each equation, (we knew a quadratic was coming since it must be
+ * possible to obtain two solutions in some cases):
+ *
+ * cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+ * sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+ *
+ * Then add both together, set the result equal to 1, and express as a
+ * standard quadratic equation in t of the form At² + Bt + C = 0
+ *
+ * (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r₁·dr)·t + (pdx² + pdy² - r₁²) = 0
+ *
+ * In other words:
+ *
+ * A = cdx² + cdy² - dr²
+ * B = -2·(pdx·cdx + pdy·cdy + r₁·dr)
+ * C = pdx² + pdy² - r₁²
+ *
+ * And again, notice that A does not depend on p, so can be
+ * precomputed. From here we just use the quadratic formula to solve
+ * for t:
+ *
+ * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
+ */
         /* radial or conical */
         Bool affine = TRUE;
         double cx = 1.;
         double cy = 0.;
         double cz = 0.;
-        double rx = x;
-        double ry = y;
+	double rx = x + 0.5;
+	double ry = y + 0.5;
         double rz = 1.;
 
         if (pict->transform) {
@@ -3176,25 +3291,38 @@ static void fbFetchSourcePict(PicturePtr
         }
 
         if (pGradient->type == SourcePictTypeRadial) {
+	    PictRadialGradient *radial;
+	    radial = &pGradient->radial;
             if (affine) {
-                rx -= pGradient->radial.fx;
-                ry -= pGradient->radial.fy;
-
                 while (buffer < end) {
-		    double b, c, det, s;
-		    
 		    if (!mask || *mask++ & maskBits)
 		    {
-			xFixed_48_16  t;
+			double pdx, pdy;
+			double B, C;
+			double det;
+			double c1x = radial->c1.x / 65536.0;
+			double c1y = radial->c1.y / 65536.0;
+			double r1  = radial->c1.radius / 65536.0;
+                        xFixed_48_16 t;
+
+			pdx = rx - c1x;
+			pdy = ry - c1y;
+
+			B = -2 * (  pdx * radial->cdx
+				  + pdy * radial->cdy
+				  + r1 * radial->dr);
+			C = (pdx * pdx + pdy * pdy - r1 * r1);
+
+                        det = (B * B) - (4 * radial->A * C);
+			if (det < 0.0)
+			    det = 0.0;
+
+			if (radial->A < 0)
+			    t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+			else
+			    t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
 			
-			b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
-			c = -(rx*rx + ry*ry);
-			det = (b * b) - (4 * pGradient->radial.a * c);
-			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-			
-			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
-			
-			WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ 			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    ++buffer;
 		    
@@ -3202,35 +3330,50 @@ static void fbFetchSourcePict(PicturePtr
                     ry += cy;
                 }
             } else {
+		/* projective */
                 while (buffer < end) {
-                    double x, y;
-                    double b, c, det, s;
-
 		    if (!mask || *mask++ & maskBits)
 		    {
-			xFixed_48_16  t;
-			
+			double pdx, pdy;
+			double B, C;
+			double det;
+			double c1x = radial->c1.x / 65536.0;
+			double c1y = radial->c1.y / 65536.0;
+			double r1  = radial->c1.radius / 65536.0;
+                        xFixed_48_16 t;
+			double x, y;
+
 			if (rz != 0) {
 			    x = rx/rz;
 			    y = ry/rz;
 			} else {
 			    x = y = 0.;
 			}
-			x -= pGradient->radial.fx;
-			y -= pGradient->radial.fy;
-			b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
-			c = -(x*x + y*y);
-			det = (b * b) - (4 * pGradient->radial.a * c);
-			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
 			
-			WRITE(buffer, _gradient_walker_pixel (&walker, t));
+			pdx = x - c1x;
+			pdy = y - c1y;
+
+			B = -2 * (  pdx * radial->cdx
+				  + pdy * radial->cdy
+				  + r1 * radial->dr);
+			C = (pdx * pdx + pdy * pdy - r1 * r1);
+
+                        det = (B * B) - (4 * radial->A * C);
+			if (det < 0.0)
+			    det = 0.0;
+
+			if (radial->A < 0)
+			    t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+			else
+			    t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
+			
+ 			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    ++buffer;
 		    
                     rx += cx;
                     ry += cy;
-                    rz += cz;
+		    rz += cz;
                 }
             }
         } else /* SourcePictTypeConical */ {
diff --git a/render/picture.c b/render/picture.c
index 3f64182..201ceb2 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1051,6 +1051,7 @@ CreateRadialGradientPicture (Picture pid
     radial = &pPicture->pSourcePict->radial;
 
     radial->type = SourcePictTypeRadial;
+#if 0
     {
         double x = (double)innerRadius / (double)outerRadius;
         radial->dx = (outer->x - inner->x);
@@ -1066,7 +1067,20 @@ CreateRadialGradientPicture (Picture pid
         x = outerRadius/65536.;
         radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
     }
-
+#endif
+    radial->c1.x = inner->x;
+    radial->c1.y = inner->y;
+    radial->c1.radius = innerRadius;
+    radial->c2.x = outer->x;
+    radial->c2.y = outer->y;
+    radial->c2.radius = outerRadius;
+    radial->cdx = (radial->c2.x - radial->c1.x) / 65536.;
+    radial->cdy = (radial->c2.y - radial->c1.y) / 65536.;
+    radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.;
+    radial->A = (  radial->cdx * radial->cdx
+		   + radial->cdy * radial->cdy
+		   - radial->dr  * radial->dr);
+    
     initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
     if (*error) {
         xfree(pPicture);
diff --git a/render/picturestr.h b/render/picturestr.h
index 3f3c600..6268768 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -105,17 +105,26 @@ typedef struct _PictLinearGradient {
     xPointFixed p2;
 } PictLinearGradient, *PictLinearGradientPtr;
 
+typedef struct _PictCircle {
+    xFixed x;
+    xFixed y;
+    xFixed radius;
+} PictCircle, *PictCirclePtr;
+
 typedef struct _PictRadialGradient {
     unsigned int type;
+    unsigned int class;
     int nstops;
     PictGradientStopPtr stops;
-    double fx;
-    double fy;
-    double dx;
-    double dy;
-    double a;
-    double m;
-    double b;
+    int stopRange;
+    CARD32 *colorTable;
+    int colorTableSize;
+    PictCircle c1;
+    PictCircle c2;
+    double cdx;
+    double cdy;
+    double dr;
+    double A;
 } PictRadialGradient, *PictRadialGradientPtr;
 
 typedef struct _PictConicalGradient {
diff-tree 38d14e858980a1b0c087344d24bf6aebf755663c (from ca784df84e07227a4cc0a1add079884f557b7a00)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Sun Apr 22 18:04:27 2007 -0700

    Adjust the screen pixmap's dimensions in xf86RandR12ScreenSetSize.

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 90de585..db91274 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -337,6 +337,7 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
     ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
     WindowPtr		pRoot = WindowTable[pScreen->myNum];
+    PixmapPtr		pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
     Bool		ret = FALSE;
 
     if (randrp->virtualX == -1 || randrp->virtualY == -1)
@@ -353,8 +354,8 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
 
     ret = TRUE;
 
-    pScreen->width = width;
-    pScreen->height = height;
+    pScreen->width = pScrnPix->drawable.width = width;
+    pScreen->height = pScrnPix->drawable.height = height;
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
 
diff-tree ca784df84e07227a4cc0a1add079884f557b7a00 (from 55bd8668e7d4100579bcd6c16a804d9f25267070)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Sun Apr 22 16:26:01 2007 -0700

    Fix unbalanced fbGetDrawable added in commit 0a9239ec.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 8b5700b..0faf783 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -4146,6 +4146,9 @@ fbCompositeRect (const FbComposeData *da
 	    }
 	}
     }
+
+    if (!store)
+	fbFinishAccess (data->dest->pDrawable);
 }
 
 void
diff-tree 55bd8668e7d4100579bcd6c16a804d9f25267070 (from 41dd7ab067adde8f66cd9f74c5a6570c325518a5)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 14:53:37 2007 -0400

    Remove #if 0'ed leftovers from merge

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 6b366f7..8b5700b 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -3019,10 +3019,6 @@ _gradient_walker_pixel (GradientWalker  
 
 static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
-#if 0
-    SourcePictPtr pGradient = pict->pSourcePict;
-    CARD32 *end = buffer + width;
-#endif
      SourcePictPtr   pGradient = pict->pSourcePict;
      GradientWalker  walker;
      CARD32         *end = buffer + width;
diff-tree 41dd7ab067adde8f66cd9f74c5a6570c325518a5 (from c1b73f0f2acd56b423b91a04f1e1b3cdcad0069f)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 14:51:40 2007 -0400

     Fix gradient walker to not reset needlessly
    
        Previously the gradient walker was doing excessive resets, (such
        as on every pixel in constant-colored regions or outside the
        gradient with CAIRO_EXTEND_NONE). Don't do that.
    
        Carl Worth, from pixman

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 365a85f..6b366f7 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -2803,12 +2803,13 @@ typedef struct
     CARD32        right_rb;
     int32_t       left_x;
     int32_t       right_x;
-    int32_t       width_x;
     int32_t       stepper;
     
     PictGradientStopPtr      stops;
     int                      num_stops;
     unsigned int             spread;
+
+    int		  need_reset;
 } GradientWalker;
 
 static void
@@ -2820,13 +2821,14 @@ _gradient_walker_init (GradientWalker  *
     walker->stops     = pGradient->gradient.stops;
     walker->left_x    = 0;
     walker->right_x   = 0x10000;
-    walker->width_x   = 0;  /* will force a reset */
     walker->stepper   = 0;
     walker->left_ag   = 0;
     walker->left_rb   = 0;
     walker->right_ag  = 0;
     walker->right_rb  = 0;
     walker->spread    = spread;
+
+    walker->need_reset = TRUE;
 }
 
 static void
@@ -2958,27 +2960,29 @@ _gradient_walker_reset (GradientWalker  
     
     walker->left_x   = left_x;
     walker->right_x  = right_x;
-    walker->width_x  = right_x - left_x;
     walker->left_ag  = ((left_c->alpha >> 8) << 16)   | (left_c->green >> 8);
     walker->left_rb  = ((left_c->red & 0xff00) << 8)  | (left_c->blue >> 8);
     walker->right_ag = ((right_c->alpha >> 8) << 16)  | (right_c->green >> 8);
     walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
     
-    if ( walker->width_x == 0                      ||
+    if ( walker->left_x == walker->right_x                ||
 	 ( walker->left_ag == walker->right_ag &&
 	   walker->left_rb == walker->right_rb )   )
     {
-	walker->width_x = 1;
 	walker->stepper = 0;
     }
     else
     {
-	walker->stepper = ((1 << 24) + walker->width_x/2)/walker->width_x;
+	int32_t width = right_x - left_x;
+	walker->stepper = ((1 << 24) + width/2)/width;
     }
+
+    walker->need_reset = FALSE;
 }
 
 #define  GRADIENT_WALKER_NEED_RESET(w,x)				\
-    ( (x) < (w)->left_x || (x) - (w)->left_x >= (w)->width_x )
+    ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
+
 
 /* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
 static CARD32
diff-tree c1b73f0f2acd56b423b91a04f1e1b3cdcad0069f (from 38f718799c68995c2d9a1680355bd55fd925009e)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 14:34:13 2007 -0400

    Fixing gradient repeat mode computations in previous patch. From David
    
    Turner.

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 5ddff23..365a85f 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -2916,13 +2916,15 @@ _gradient_walker_reset (GradientWalker  
 	    xRenderColor  *tmp_c;
 	    int32_t          tmp_x;
 	    
-	    tmp_x   = 0x20000 - right_x;
-	    right_x = 0x20000 - left_x;
+	    tmp_x   = 0x10000 - right_x;
+	    right_x = 0x10000 - left_x;
 	    left_x  = tmp_x;
 	    
 	    tmp_c   = right_c;
 	    right_c = left_c;
 	    left_c  = tmp_c;
+
+	    x = 0x10000 - x;
 	}
 	left_x  += (pos - x);
 	right_x += (pos - x);
@@ -3074,14 +3076,14 @@ static void fbFetchSourcePict(PicturePtr
 
 		color = _gradient_walker_pixel( &walker, t );
 		while (buffer < end)
-		    *buffer++ = color;
+		    WRITE(buffer++, color);
 	    }
 	    else
 	    {
                 if (!mask) {
                     while (buffer < end)
                     {
-                        *buffer = _gradient_walker_pixel (&walker, t);
+                        WRITE(buffer, _gradient_walker_pixel (&walker, t));
                         buffer += 1;
                         t      += inc;
                     }
@@ -3089,7 +3091,7 @@ static void fbFetchSourcePict(PicturePtr
                     while (buffer < end) {
                         if (*mask++ & maskBits)
                         {
-                            *buffer = _gradient_walker_pixel (&walker, t);
+                            WRITE(buffer, _gradient_walker_pixel (&walker, t));
                         }
                         buffer += 1;
                         t      += inc;
@@ -3118,12 +3120,9 @@ static void fbFetchSourcePict(PicturePtr
 		    t = ((a * x + b * y) >> 16) + off;
 		}
 
-#if 0
-		color = gradientPixel (pGradient, t, pict->repeat);
-#endif
  		color = _gradient_walker_pixel( &walker, t );
 		while (buffer < end)
-		    *buffer++ = color;
+		    WRITE(buffer++, color);
 	    }
 	    else
 	    {
@@ -3139,7 +3138,7 @@ static void fbFetchSourcePict(PicturePtr
 			    y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
 			    t = ((a*x + b*y) >> 16) + off;
 			}
-			*buffer = _gradient_walker_pixel (&walker, t);
+			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    ++buffer;
 		    v.vector[0] += unit.vector[0];
@@ -3195,7 +3194,7 @@ static void fbFetchSourcePict(PicturePtr
 			
 			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
 			
-			*buffer = _gradient_walker_pixel (&walker, t);
+			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    ++buffer;
 		    
@@ -3225,7 +3224,7 @@ static void fbFetchSourcePict(PicturePtr
 			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
 			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
 			
-			*buffer = _gradient_walker_pixel (&walker, t);
+			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    ++buffer;
 		    
@@ -3250,7 +3249,7 @@ static void fbFetchSourcePict(PicturePtr
                         angle = atan2(ry, rx) + a;
 			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
 			
-			*buffer = _gradient_walker_pixel (&walker, t);
+			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 
                     ++buffer;
@@ -3277,7 +3276,7 @@ static void fbFetchSourcePict(PicturePtr
 			angle = atan2(y, x) + a;
 			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
 			
-			*buffer = _gradient_walker_pixel (&walker, t);
+			WRITE(buffer, _gradient_walker_pixel (&walker, t));
 		    }
 		    
                     ++buffer;
@@ -3342,7 +3341,7 @@ static void fbFetchTransformed(PicturePt
 		    if (!mask || mask[i] & maskBits)
 		    {
 			if (!v.vector[2]) {
-			    buffer[i] = 0;
+			    WRITE(buffer + i, 0);
 			} else {
 			    if (!affine) {
 				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
@@ -3351,7 +3350,7 @@ static void fbFetchTransformed(PicturePt
 				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
 				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
 			    }
-			    buffer[i] = fetch(bits + (y + dy)*stride, x + dx, indexed);
+			    WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
 			}
 		    }
 
@@ -3364,7 +3363,7 @@ static void fbFetchTransformed(PicturePt
 		    if (!mask || mask[i] & maskBits)
 		    {
 			if (!v.vector[2]) {
-			    buffer[i] = 0;
+			    WRITE(buffer + i, 0);
 			} else {
 			    if (!affine) {
 				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
@@ -3374,9 +3373,9 @@ static void fbFetchTransformed(PicturePt
 				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
 			    }
 			    if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
-				buffer[i] = fetch(bits + (y + dy)*stride, x + dx, indexed);
+				WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
 			    else
-				buffer[i] = 0;
+				WRITE(buffer + i, 0);
 			}
 		    }
 
diff-tree 38f718799c68995c2d9a1680355bd55fd925009e (from 9c4b14d4f6a1fe018acd64789434216cd1560a4a)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 13:59:11 2007 -0400

    Remove a few memory references in fbFetchTransformed

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 9b5af8e..5ddff23 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -3351,7 +3351,7 @@ static void fbFetchTransformed(PicturePt
 				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
 				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
 			    }
-			    buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+			    buffer[i] = fetch(bits + (y + dy)*stride, x + dx, indexed);
 			}
 		    }
 
@@ -3374,7 +3374,7 @@ static void fbFetchTransformed(PicturePt
 				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
 			    }
 			    if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
-				buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+				buffer[i] = fetch(bits + (y + dy)*stride, x + dx, indexed);
 			    else
 				buffer[i] = 0;
 			}
diff-tree 9c4b14d4f6a1fe018acd64789434216cd1560a4a (from cd2c1714eb4946bf7b1fc194fe074f8024a2ec23)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 13:23:58 2007 -0400

    Integrate David Turner's gradient optimizations from pixman

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index de3a371..9b5af8e 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -2795,79 +2795,234 @@ static void fbFetch(PicturePtr pict, int
 #define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :		\
 		  ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
 
-static CARD32
-xRenderColorMultToCard32 (xRenderColor *c)
+typedef struct
 {
-    return
-	((((CARD32) c->red   * c->alpha) >> 24) << 16) |
-	((((CARD32) c->green * c->alpha) >> 24) <<  8) |
-	((((CARD32) c->blue  * c->alpha) >> 24) <<  0) |
-	((((CARD32) c->alpha		 ) >> 8)  << 24);
-}
+    CARD32        left_ag;
+    CARD32        left_rb;
+    CARD32        right_ag;
+    CARD32        right_rb;
+    int32_t       left_x;
+    int32_t       right_x;
+    int32_t       width_x;
+    int32_t       stepper;
+    
+    PictGradientStopPtr      stops;
+    int                      num_stops;
+    unsigned int             spread;
+} GradientWalker;
 
-static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
+static void
+_gradient_walker_init (GradientWalker  *walker,
+		       SourcePictPtr    pGradient,
+		       unsigned int     spread)
 {
-    int ipos = (pos * pGradient->gradient.stopRange - 1) >> 16;
+    walker->num_stops = pGradient->gradient.nstops;
+    walker->stops     = pGradient->gradient.stops;
+    walker->left_x    = 0;
+    walker->right_x   = 0x10000;
+    walker->width_x   = 0;  /* will force a reset */
+    walker->stepper   = 0;
+    walker->left_ag   = 0;
+    walker->left_rb   = 0;
+    walker->right_ag  = 0;
+    walker->right_rb  = 0;
+    walker->spread    = spread;
+}
 
-    /* calculate the actual offset. */
-    if (ipos < 0 || ipos >= pGradient->gradient.stopRange)
+static void
+_gradient_walker_reset (GradientWalker  *walker,
+                        xFixed_32_32     pos)
+{
+    int32_t                  x, left_x, right_x;
+    xRenderColor          *left_c, *right_c;
+    int                      n, count = walker->num_stops;
+    PictGradientStopPtr      stops = walker->stops;
+    
+    static const xRenderColor   transparent_black = { 0, 0, 0, 0 };
+    
+    switch (walker->spread)
     {
-	if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal)
-	{
-	    ipos = ipos % pGradient->gradient.stopRange;
-	    ipos = ipos < 0 ? pGradient->gradient.stopRange + ipos : ipos;
-
+    case RepeatNormal:
+	x = (int32_t)pos & 0xFFFF;
+	for (n = 0; n < count; n++)
+	    if (x < stops[n].x)
+		break;
+	if (n == 0) {
+	    left_x =  stops[count-1].x - 0x10000;
+	    left_c = &stops[count-1].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
+	}
+	
+	if (n == count) {
+	    right_x =  stops[0].x + 0x10000;
+	    right_c = &stops[0].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	left_x  += (pos - x);
+	right_x += (pos - x);
+	break;
+	
+    case RepeatPad:
+	for (n = 0; n < count; n++)
+	    if (pos < stops[n].x)
+		break;
+	
+	if (n == 0) {
+	    left_x =  INT_MIN;
+	    left_c = &stops[0].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
 	}
-	else if (spread == RepeatReflect)
+	
+	if (n == count) {
+	    right_x =  INT_MAX;
+	    right_c = &stops[n-1].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	break;
+	
+    case RepeatReflect:
+	x = (int32_t)pos & 0xFFFF;
+	if ((int32_t)pos & 0x10000)
+	    x = 0x10000 - x;
+	for (n = 0; n < count; n++)
+	    if (x < stops[n].x)
+		break;
+	
+	if (n == 0) {
+	    left_x =  -stops[0].x;
+	    left_c = &stops[0].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
+	}
+	
+	if (n == count) {
+	    right_x = 0x20000 - stops[n-1].x;
+	    right_c = &stops[n-1].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	
+	if ((int32_t)pos & 0x10000) {
+	    xRenderColor  *tmp_c;
+	    int32_t          tmp_x;
+	    
+	    tmp_x   = 0x20000 - right_x;
+	    right_x = 0x20000 - left_x;
+	    left_x  = tmp_x;
+	    
+	    tmp_c   = right_c;
+	    right_c = left_c;
+	    left_c  = tmp_c;
+	}
+	left_x  += (pos - x);
+	right_x += (pos - x);
+	break;
+	
+    default:  /* RepeatNone */
+	for (n = 0; n < count; n++)
+	    if (pos < stops[n].x)
+		break;
+	
+	if (n == 0)
 	{
-	    const int limit = pGradient->gradient.stopRange * 2 - 1;
-
-	    ipos = ipos % limit;
-	    ipos = ipos < 0 ? limit + ipos : ipos;
-	    ipos = ipos >= pGradient->gradient.stopRange ? limit - ipos : ipos;
-
+	    left_x  =  INT_MIN;
+	    right_x =  stops[0].x;
+	    left_c  = right_c = (xRenderColor*) &transparent_black;
 	}
-	else if (spread == RepeatPad)
+	else if (n == count)
 	{
-	    if (ipos < 0)
-		ipos = 0;
-	    else
-		ipos = pGradient->gradient.stopRange - 1;
+	    left_x  = stops[n-1].x;
+	    right_x = INT_MAX;
+	    left_c  = right_c = (xRenderColor*) &transparent_black;
 	}
-	else  /* RepeatNone */
+	else
 	{
-	    return 0;
+	    left_x  =  stops[n-1].x;
+	    right_x =  stops[n].x;
+	    left_c  = &stops[n-1].color;
+	    right_c = &stops[n].color;
 	}
     }
-
-    if (pGradient->gradient.colorTableSize)
+    
+    walker->left_x   = left_x;
+    walker->right_x  = right_x;
+    walker->width_x  = right_x - left_x;
+    walker->left_ag  = ((left_c->alpha >> 8) << 16)   | (left_c->green >> 8);
+    walker->left_rb  = ((left_c->red & 0xff00) << 8)  | (left_c->blue >> 8);
+    walker->right_ag = ((right_c->alpha >> 8) << 16)  | (right_c->green >> 8);
+    walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
+    
+    if ( walker->width_x == 0                      ||
+	 ( walker->left_ag == walker->right_ag &&
+	   walker->left_rb == walker->right_rb )   )
     {
-	return pGradient->gradient.colorTable[ipos];
+	walker->width_x = 1;
+	walker->stepper = 0;
     }
     else
     {
-	int i;
-
-	if (ipos <= pGradient->gradient.stops->x)
-	    return xRenderColorMultToCard32 (&pGradient->gradient.stops->color);
+	walker->stepper = ((1 << 24) + walker->width_x/2)/walker->width_x;
+    }
+}
 
-	for (i = 1; i < pGradient->gradient.nstops; i++)
-	{
-	    if (pGradient->gradient.stops[i].x >= ipos)
-		return PictureGradientColor (&pGradient->gradient.stops[i - 1],
-					     &pGradient->gradient.stops[i],
-					     ipos);
-	}
+#define  GRADIENT_WALKER_NEED_RESET(w,x)				\
+    ( (x) < (w)->left_x || (x) - (w)->left_x >= (w)->width_x )
 
-	return xRenderColorMultToCard32 (&pGradient->gradient.stops[--i].color);
-    }
+/* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
+static CARD32
+_gradient_walker_pixel (GradientWalker  *walker,
+                        xFixed_32_32     x)
+{
+    int  dist, idist;
+    CARD32  t1, t2, a, color;
+    
+    if (GRADIENT_WALKER_NEED_RESET (walker, x))
+        _gradient_walker_reset (walker, x);
+    
+    dist  = ((int)(x - walker->left_x)*walker->stepper) >> 16;
+    idist = 256 - dist;
+    
+    /* combined INTERPOLATE and premultiply */
+    t1 = walker->left_rb*idist + walker->right_rb*dist;
+    t1 = (t1 >> 8) & 0xff00ff;
+    
+    t2  = walker->left_ag*idist + walker->right_ag*dist;
+    t2 &= 0xff00ff00;
+    
+    color = t2 & 0xff000000;
+    a     = t2 >> 24;
+    
+    t1  = t1*a + 0x800080;
+    t1  = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
+    
+    t2  = (t2 >> 8)*a + 0x800080;
+    t2  = (t2 + ((t2 >> 8) & 0xff00ff));
+    
+    return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
 }
 
 static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
+#if 0
     SourcePictPtr pGradient = pict->pSourcePict;
     CARD32 *end = buffer + width;
-
+#endif
+     SourcePictPtr   pGradient = pict->pSourcePict;
+     GradientWalker  walker;
+     CARD32         *end = buffer + width;
+ 
+     _gradient_walker_init (&walker, pGradient, pict->repeat);
+    
     if (pGradient->type == SourcePictTypeSolidFill) {
         register CARD32 color = pGradient->solidFill.color;
         while (buffer < end) {
@@ -2877,7 +3032,7 @@ static void fbFetchSourcePict(PicturePtr
         PictVector v, unit;
         xFixed_32_32 l;
         xFixed_48_16 dx, dy, a, b, off;
-
+	
         /* reference point is the center of the pixel */
         v.vector[0] = IntToxFixed(x) + xFixed1/2;
         v.vector[1] = IntToxFixed(y) + xFixed1/2;
@@ -2917,20 +3072,29 @@ static void fbFetchSourcePict(PicturePtr
 	    {
 		register CARD32 color;
 
-		color = gradientPixel (pGradient, t, pict->repeat);
+		color = _gradient_walker_pixel( &walker, t );
 		while (buffer < end)
 		    *buffer++ = color;
 	    }
 	    else
 	    {
-		while (buffer < end) {
-		    if (!mask || *mask++ & maskBits)
-		    {
-			*buffer = gradientPixel (pGradient, t, pict->repeat);
-		    }
-		    ++buffer;
-		    t += inc;
-		}
+                if (!mask) {
+                    while (buffer < end)
+                    {
+                        *buffer = _gradient_walker_pixel (&walker, t);
+                        buffer += 1;
+                        t      += inc;
+                    }
+                } else {
+                    while (buffer < end) {
+                        if (*mask++ & maskBits)
+                        {
+                            *buffer = _gradient_walker_pixel (&walker, t);
+                        }
+                        buffer += 1;
+                        t      += inc;
+                    }
+                }
 	    }
 	}
 	else /* projective transformation */
@@ -2954,7 +3118,10 @@ static void fbFetchSourcePict(PicturePtr
 		    t = ((a * x + b * y) >> 16) + off;
 		}
 
+#if 0
 		color = gradientPixel (pGradient, t, pict->repeat);
+#endif
+ 		color = _gradient_walker_pixel( &walker, t );
 		while (buffer < end)
 		    *buffer++ = color;
 	    }
@@ -2972,7 +3139,7 @@ static void fbFetchSourcePict(PicturePtr
 			    y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
 			    t = ((a*x + b*y) >> 16) + off;
 			}
-			*buffer = gradientPixel(pGradient, t, pict->repeat);
+			*buffer = _gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
 		    v.vector[0] += unit.vector[0];
@@ -3016,19 +3183,22 @@ static void fbFetchSourcePict(PicturePtr
 
                 while (buffer < end) {
 		    double b, c, det, s;
-
+		    
 		    if (!mask || *mask++ & maskBits)
 		    {
+			xFixed_48_16  t;
+			
 			b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
 			c = -(rx*rx + ry*ry);
 			det = (b * b) - (4 * pGradient->radial.a * c);
 			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-			WRITE(buffer, gradientPixel(pGradient,
-						    (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
-						    pict->repeatType));
+			
+			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
+			
+			*buffer = _gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
-
+		    
                     rx += cx;
                     ry += cy;
                 }
@@ -3039,6 +3209,8 @@ static void fbFetchSourcePict(PicturePtr
 
 		    if (!mask || *mask++ & maskBits)
 		    {
+			xFixed_48_16  t;
+			
 			if (rz != 0) {
 			    x = rx/rz;
 			    y = ry/rz;
@@ -3051,12 +3223,12 @@ static void fbFetchSourcePict(PicturePtr
 			c = -(x*x + y*y);
 			det = (b * b) - (4 * pGradient->radial.a * c);
 			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-			*buffer = gradientPixel(pGradient,
-						(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
-						pict->repeat);
+			t = (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536);
+			
+			*buffer = _gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
-
+		    
                     rx += cx;
                     ry += cy;
                     rz += cz;
@@ -3071,12 +3243,14 @@ static void fbFetchSourcePict(PicturePtr
                 while (buffer < end) {
 		    double angle;
 
-		    if (!mask || *mask++ & maskBits)
+                    if (!mask || *mask++ & maskBits)
 		    {
-			angle = atan2(ry, rx) + a;
-
-			*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
-						pict->repeat);
+                        xFixed_48_16   t;
+			
+                        angle = atan2(ry, rx) + a;
+			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
+			
+			*buffer = _gradient_walker_pixel (&walker, t);
 		    }
 
                     ++buffer;
@@ -3085,9 +3259,13 @@ static void fbFetchSourcePict(PicturePtr
                 }
             } else {
                 while (buffer < end) {
-                    double x, y, angle;
-		    if (!mask || *mask++ & maskBits)
-		    {
+                    double x, y;
+                    double angle;
+		    
+                    if (!mask || *mask++ & maskBits)
+                    {
+			xFixed_48_16  t;
+			
 			if (rz != 0) {
 			    x = rx/rz;
 			    y = ry/rz;
@@ -3097,9 +3275,11 @@ static void fbFetchSourcePict(PicturePtr
 			x -= pGradient->conical.center.x/65536.;
 			y -= pGradient->conical.center.y/65536.;
 			angle = atan2(y, x) + a;
-			*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
-						pict->repeat);
+			t     = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
+			
+			*buffer = _gradient_walker_pixel (&walker, t);
 		    }
+		    
                     ++buffer;
                     rx += cx;
                     ry += cy;
diff-tree cd2c1714eb4946bf7b1fc194fe074f8024a2ec23 (from 67545333ec0b08db783e94e9e3ec55873dea19a3)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Apr 21 12:40:51 2007 -0600

    add slang_mem.c

diff --git a/GL/mesa/shader/slang/Makefile.am b/GL/mesa/shader/slang/Makefile.am
index 7f0cd64..71498ee 100644
--- a/GL/mesa/shader/slang/Makefile.am
+++ b/GL/mesa/shader/slang/Makefile.am
@@ -31,6 +31,7 @@ nodist_libslang_la_SOURCES = slang_built
 		      slang_library_noise.c \
 		      slang_link.c \
 		      slang_log.c \
+		      slang_mem.c \
 		      slang_preprocess.c \
 		      slang_print.c \
 		      slang_simplify.c \
diff-tree 67545333ec0b08db783e94e9e3ec55873dea19a3 (from 39bc8bb0fdc854dcf9bbc0857fec84d50fa4f3b2)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Apr 21 12:40:33 2007 -0600

    replace occlude.c w/ queryobj.c

diff --git a/GL/mesa/main/Makefile.am b/GL/mesa/main/Makefile.am
index 2b838e9..f8ce137 100644
--- a/GL/mesa/main/Makefile.am
+++ b/GL/mesa/main/Makefile.am
@@ -61,10 +61,10 @@ nodist_libmain_la_SOURCES = accum.c \
                     matrix.c \
                     mipmap.c \
                     mm.c \
-                    occlude.c \
                     pixel.c \
                     points.c \
                     polygon.c \
+		    queryobj.c \
                     rastpos.c \
                     rbadaptors.c \
                     renderbuffer.c \
diff-tree 39bc8bb0fdc854dcf9bbc0857fec84d50fa4f3b2 (from 3daa5c1a991d659b1386a09e33b044470d489cb3)
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Apr 20 14:22:42 2007 -0700

    Don't call xf86RandR12TellChanged if it doesn't exist. Add some exports to xf86Rename.h.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index ad0f5ff..00ec56c 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1903,7 +1903,9 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, Di
 	}
     }
     xf86DisableUnusedFunctions(pScrn);
+#if RANDR_12_INTERFACE
     xf86RandR12TellChanged (pScrn->pScreen);
+#endif
     return ok;
 }
 
diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h
index 9dcfef5..b8c1d70 100644
--- a/hw/xfree86/modes/xf86Rename.h
+++ b/hw/xfree86/modes/xf86Rename.h
@@ -25,6 +25,12 @@
 
 #include "local_xf86Rename.h"
 
+#define xf86_cursors_fini XF86NAME(xf86_cursors_fini)
+#define xf86_cursors_init XF86NAME(xf86_cursors_init)
+#define xf86_hide_cursors XF86NAME(xf86_hide_cursors)
+#define xf86_reload_cursors XF86NAME(xf86_reload_cursors)
+#define xf86_show_cursors XF86NAME(xf86_show_cursors)
+#define xf86ConnectorGetName XF86NAME(xf86ConnectorGetName)
 #define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
 #define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
 #define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
@@ -35,6 +41,7 @@
 #define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
 #define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
 #define xf86CVTMode XF86NAME(xf86CVTMode)
+#define xf86DDCMonitorSet XF86NAME(xf86DDCMonitorSet)
 #define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
 #define xf86DPMSSet XF86NAME(xf86DPMSSet)
 #define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
@@ -52,9 +59,11 @@
 #define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
 #define xf86OutputRename XF86NAME(xf86OutputRename)
 #define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
+#define xf86OutputUseScreenMonitor XF86NAME(xf86OutputUseScreenMonitor)
 #define xf86PrintModeline XF86NAME(xf86PrintModeline)
 #define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
 #define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
+#define xf86RotateCloseScreen XF86NAME(xf86RotateCloseScreen)
 #define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
 #define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
 #define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
diff-tree 3daa5c1a991d659b1386a09e33b044470d489cb3 (from 9c2e955f6792e80fb84f848ed9e6ebbfd79f7130)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Fri Apr 20 09:43:16 2007 -0400

    Fix pixman bug 5777, patch by David Reveman

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 3043637..de3a371 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -2064,114 +2064,116 @@ static CombineFuncU fbCombineFuncU[] = {
     fbCombineConjointXorU,
 };
 
-static FASTCALL void
-fbCombineMaskC (CARD32 *src, CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskC (CARD32 *src, CARD32 *mask)
 {
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 a = READ(mask + i);
+    CARD32 a = *mask;
 
-        CARD32	x;
-        CARD16	xa;
-
-        if (!a)
-        {
-            WRITE(src + i, 0);
-            continue;
-        }
+    CARD32	x;
+    CARD16	xa;
 
-        x = READ(src + i);
-        if (a == 0xffffffff)
-        {
-            x = x >> 24;
-            x |= x << 8;
-            x |= x << 16;
-            WRITE(mask + i, x);
-            continue;
-        }
+    if (!a)
+    {
+	WRITE(src, 0);
+	return;
+    }
 
-        xa = x >> 24;
-        FbByteMulC(x, a);
-        WRITE(src + i, x);
-        FbByteMul(a, xa);
-        WRITE(mask + i, a);
+    x = READ(src);
+    if (a == 0xffffffff)
+    {
+	x = x >> 24;
+	x |= x << 8;
+	x |= x << 16;
+	WRITE(mask, x);
+	return;
     }
+
+    xa = x >> 24;
+    FbByteMulC(x, a);
+    WRITE(src, x);
+    FbByteMul(a, xa);
+    WRITE(mask, a);
 }
 
-static FASTCALL void
-fbCombineMaskValueC (CARD32 *src, const CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskValueC (CARD32 *src, const CARD32 *mask)
 {
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 a = READ(mask + i);
-        CARD32	x;
+    CARD32 a = READ(mask);
+    CARD32	x;
 
-        if (!a)
-        {
-            WRITE(src + i, 0);
-            continue;
-        }
+    if (!a)
+    {
+	WRITE(src, 0);
+	return;
+    }
 
-        if (a == 0xffffffff)
-            continue;
+    if (a == 0xffffffff)
+	return;
 
-        x = READ(src + i);
-        FbByteMulC(x, a);
-        WRITE(src + i, x);
-    }
+    x = READ(src);
+    FbByteMulC(x, a);
+    WRITE(src,x);
 }
 
-
-static FASTCALL void
-fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask)
 {
-    int i;
-    for (i = 0; i < width; ++i) {
-        CARD32 a = READ(mask + i);
-        CARD32	x;
-
-        if (!a)
-            continue;
+    CARD32 a = READ(mask);
+    CARD32	x;
 
-        x = READ(src + i) >> 24;
-        if (x == 0xff)
-            continue;
-        if (a == 0xffffffff)
-        {
-            x = x >> 24;
-            x |= x << 8;
-            x |= x << 16;
-            WRITE(mask + i, x);
-            continue;
-        }
+    if (!a)
+	return;
 
-        FbByteMul(a, x);
-        WRITE(mask + i, a);
+    x = READ(src) >> 24;
+    if (x == 0xff)
+	return;
+    if (a == 0xffffffff)
+    {
+	x = x >> 24;
+	x |= x << 8;
+	x |= x << 16;
+	WRITE(mask, x);
+	return;
     }
+
+    FbByteMul(a, x);
+    WRITE(mask, a);
 }
 
 static FASTCALL void
 fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
-    memset(dest, 0, width*sizeof(CARD32));
+    MEMSET_WRAPPED(dest, 0, width*sizeof(CARD32));
 }
 
 static FASTCALL void
 fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
-    fbCombineMaskValueC(src, mask, width);
-    MEMCPY_WRAPPED(dest, src, width*sizeof(CARD32));
+    int i;
+
+    for (i = 0; i < width; ++i) {
+	CARD32 s = READ(src + i);
+	CARD32 m = READ(mask + i);
+
+	fbCombineMaskValueC (&s, &m);
+
+	WRITE(dest, s);
+    }
 }
 
 static FASTCALL void
 fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
-        CARD32  s = READ(src + i);
-        CARD32  a = ~READ(mask + i);
+	CARD32 s = READ(src + i);
+	CARD32 m = READ(mask + i);
+	CARD32 a;
+
+	fbCombineMaskC (&s, &m);
 
+	a = ~m;
         if (a != 0xffffffff)
         {
             if (a)
@@ -2189,7 +2191,7 @@ static FASTCALL void
 fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskValueC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 d = READ(dest + i);
         CARD32 a = ~d >> 24;
@@ -2197,6 +2199,10 @@ fbCombineOverReverseC (CARD32 *dest, CAR
         if (a)
         {
             CARD32 s = READ(src + i);
+	    CARD32 m = READ(mask + i);
+
+	    fbCombineMaskValueC (&s, &m);
+
             if (a != 0xff)
             {
                 FbByteMulAdd(s, a, d);
@@ -2210,14 +2216,17 @@ static FASTCALL void
 fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskValueC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 d = READ(dest + i);
         CARD16 a = d >> 24;
         CARD32 s = 0;
         if (a)
         {
-            s = READ(src + i);
+	    CARD32 m = READ(mask + i);
+
+	    s = READ(src + i);
+	    fbCombineMaskValueC (&s, &m);
             if (a != 0xff)
             {
                 FbByteMul(s, a);
@@ -2231,10 +2240,15 @@ static FASTCALL void
 fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskAlphaC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
-        CARD32 a = READ(mask + i);
+        CARD32 s = READ(src + i);
+        CARD32 m = READ(mask + i);
+        CARD32 a;
+
+	fbCombineMaskAlphaC (&s, &m);
 
+	a = m;
         if (a != 0xffffffff)
         {
             CARD32 d = 0;
@@ -2243,7 +2257,7 @@ fbCombineInReverseC (CARD32 *dest, CARD3
                 d = READ(dest + i);
                 FbByteMulC(d, a);
             }
-            WRITE(dest + i, d);
+            WRITE(dest + i, d); 
         }
     }
 }
@@ -2252,14 +2266,18 @@ static FASTCALL void
 fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskValueC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 d = READ(dest + i);
         CARD16 a = ~d >> 24;
         CARD32 s = 0;
         if (a)
         {
-            s = READ(src + i);
+	    CARD32 m = READ(mask + i);
+
+	    s = READ(src + i);
+	    fbCombineMaskValueC (&s, &m);
+
             if (a != 0xff)
             {
                 FbByteMul(s, a);
@@ -2273,10 +2291,15 @@ static FASTCALL void
 fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskAlphaC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
-        CARD32 a = ~READ(mask + i);
+	CARD32 s = READ(src + i);
+	CARD32 m = READ(mask + i);
+	CARD32 a;
 
+	fbCombineMaskAlphaC (&s, &m);
+
+        a = ~m;
         if (a != 0xffffffff)
         {
             CARD32 d = 0;
@@ -2294,12 +2317,18 @@ static FASTCALL void
 fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 d = READ(dest + i);
         CARD32 s = READ(src + i);
-        CARD32 ad = ~READ(mask + i);
+        CARD32 m = READ(mask + i);
+        CARD32 ad;
         CARD16 as = d >> 24;
+
+	fbCombineMaskC (&s, &m);
+
+        ad = ~m;
+
         FbByteAddMulC(d, ad, s, as);
         WRITE(dest + i, d);
     }
@@ -2309,13 +2338,19 @@ static FASTCALL void
 fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
 
         CARD32 d = READ(dest + i);
         CARD32 s = READ(src + i);
-        CARD32 ad = READ(mask + i);
+        CARD32 m = READ(mask + i);
+        CARD32 ad;
         CARD16 as = ~d >> 24;
+
+	fbCombineMaskC (&s, &m);
+
+	ad = m;
+
         FbByteAddMulC(d, ad, s, as);
         WRITE(dest + i, d);
     }
@@ -2325,12 +2360,18 @@ static FASTCALL void
 fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 d = READ(dest + i);
         CARD32 s = READ(src + i);
-        CARD32 ad = ~READ(mask + i);
+        CARD32 m = READ(mask + i);
+        CARD32 ad;
         CARD16 as = ~d >> 24;
+
+	fbCombineMaskC (&s, &m);
+
+	ad = ~m;
+
         FbByteAddMulC(d, ad, s, as);
         WRITE(dest + i, d);
     }
@@ -2340,10 +2381,14 @@ static FASTCALL void
 fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskValueC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32 s = READ(src + i);
+        CARD32 m = READ(mask + i);
         CARD32 d = READ(dest + i);
+
+	fbCombineMaskValueC (&s, &m);
+
         FbByteAdd(d, s);
         WRITE(dest + i, d);
     }
@@ -2353,7 +2398,7 @@ static FASTCALL void
 fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32  s, d;
         CARD16  sa, sr, sg, sb, da;
@@ -2362,10 +2407,14 @@ fbCombineSaturateC (CARD32 *dest, CARD32
 
         d = READ(dest + i);
         s = READ(src + i);
-        sa = (READ(mask + i) >> 24);
-        sr = (READ(mask + i) >> 16) & 0xff;
-        sg = (READ(mask + i) >>  8) & 0xff;
-        sb = (READ(mask + i)      ) & 0xff;
+	m = READ(mask + i);
+
+	fbCombineMaskC (&s, &m);
+
+        sa = (m >> 24);
+        sr = (m >> 16) & 0xff;
+        sg = (m >>  8) & 0xff;
+        sb = (m      ) & 0xff;
         da = ~d >> 24;
 
         if (sb <= da)
@@ -2396,7 +2445,7 @@ static FASTCALL void
 fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32  s, d;
         CARD32  m,n,o,p;
@@ -2406,10 +2455,14 @@ fbCombineDisjointGeneralC (CARD32 *dest,
         CARD8   da;
 
         s = READ(src + i);
-        sa = READ(mask + i);
+        m = READ(mask + i);
         d = READ(dest + i);
         da = d >> 24;
 
+	fbCombineMaskC (&s, &m);
+
+	sa = m;
+
         switch (combine & CombineA) {
         default:
             Fa = 0;
@@ -2516,7 +2569,7 @@ static FASTCALL void
 fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
 {
     int i;
-    fbCombineMaskC(src, mask, width);
+
     for (i = 0; i < width; ++i) {
         CARD32  s, d;
         CARD32  m,n,o,p;
@@ -2526,10 +2579,14 @@ fbCombineConjointGeneralC (CARD32 *dest,
         CARD8   da;
 
         s = READ(src + i);
-        sa = READ(mask + i);
+        m = READ(mask + i);
         d = READ(dest + i);
         da = d >> 24;
 
+	fbCombineMaskC (&s, &m);
+
+        sa = m;
+
         switch (combine & CombineA) {
         default:
             Fa = 0;
diff-tree 9c2e955f6792e80fb84f848ed9e6ebbfd79f7130 (from 96ef0f78438b60436c3940817980a3ab4070c7e8)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Apr 20 07:21:19 2007 -0600

    regenerated to add GL_CLIENT_ATTRIB_STACK_DEPTH (bug 9823)

diff --git a/GL/glx/indirect_size_get.c b/GL/glx/indirect_size_get.c
index ccb25f8..f29ae47 100644
--- a/GL/glx/indirect_size_get.c
+++ b/GL/glx/indirect_size_get.c
@@ -370,6 +370,7 @@ __glGetBooleanv_size(GLenum e)
     case GL_PROJECTION_STACK_DEPTH:
     case GL_TEXTURE_STACK_DEPTH:
     case GL_ATTRIB_STACK_DEPTH:
+    case GL_CLIENT_ATTRIB_STACK_DEPTH:
     case GL_ALPHA_TEST:
     case GL_ALPHA_TEST_FUNC:
     case GL_ALPHA_TEST_REF:
@@ -448,6 +449,7 @@ __glGetBooleanv_size(GLenum e)
     case GL_MAX_NAME_STACK_DEPTH:
     case GL_MAX_PROJECTION_STACK_DEPTH:
     case GL_MAX_TEXTURE_STACK_DEPTH:
+    case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
     case GL_SUBPIXEL_BITS:
     case GL_INDEX_BITS:
     case GL_RED_BITS:
diff-tree 96ef0f78438b60436c3940817980a3ab4070c7e8 (from 7ca4baffb5569ea12b578a4a3f69e93d272d6c6d)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 17:39:51 2007 -0700

    Disable SourceValidate in rotation to capture cursor.
    
    SourceValidate is used exclusively by the software cursor code to pull the
    cursor off of the screen before using the screen as a source operand. This
    eliminates the software cursor from the frame buffer while painting the
    rotated image though. Disabling this function by temporarily setting the
    screen function pointer to NULL causes the cursor image to be captured.
    (cherry picked from commit 05e1c45ade9c558820685bfd2541617a2e8de816)

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 94f95a0..359501e 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -278,8 +278,18 @@ xf86RotateRedisplay(ScreenPtr pScreen)
     region = DamageRegion(damage);
     if (REGION_NOTEMPTY(pScreen, region)) 
     {
-	int		    c;
-	
+	int			c;
+	SourceValidateProcPtr	SourceValidate;
+
+	/*
+	 * SourceValidate is used by the software cursor code
+	 * to pull the cursor off of the screen when reading
+	 * bits from the frame buffer. Bypassing this function
+	 * leaves the software cursor in place
+	 */
+	SourceValidate = pScreen->SourceValidate;
+	pScreen->SourceValidate = NULL;
+
 	for (c = 0; c < xf86_config->num_crtc; c++)
 	{
 	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
@@ -304,6 +314,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 		REGION_UNINIT (pScreen, &crtc_damage);
 	    }
 	}
+	pScreen->SourceValidate = SourceValidate;
 	DamageEmpty(damage);
     }
 }
diff-tree 7ca4baffb5569ea12b578a4a3f69e93d272d6c6d (from 806a537e644d8cc9e53f3ac52efb49453e5aa1fb)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 17:37:18 2007 -0700

    Was accidentally disabling rotation updates in mode set.
    
    Setting a mode on an unrotated CRTC was causing all of the rotation updates
    to be disabled; the loop looking for active rotation wasn't actually looking
    at each crtc, it was looking at the modified crtc many times.
    (cherry picked from commit 8b217dee3a6c46b13fc9571a4a9a95bc55686cdb)

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e8fafd0..94f95a0 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -284,7 +284,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 	{
 	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
 
-	    if (crtc->rotation != RR_Rotate_0)
+	    if (crtc->rotation != RR_Rotate_0 && crtc->enabled)
 	    {
 		BoxRec	    box;
 		RegionRec   crtc_damage;
@@ -338,7 +338,8 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
     }
 
     for (c = 0; c < xf86_config->num_crtc; c++)
-	if (crtc->rotatedPixmap || crtc->rotatedData)
+	if (xf86_config->crtc[c]->rotatedPixmap ||
+	    xf86_config->crtc[c]->rotatedData)
 	    return;
 
     /*
diff-tree 806a537e644d8cc9e53f3ac52efb49453e5aa1fb (from 0a9239ec258828ec1da6c208634a55fc4053d7da)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 17:49:34 2007 -0700

    Revert "Suppress software cursor removal during rotated shadow buffer drawing."
    
    This reverts commit 999b681cf3973af4191506e49cde06963b11a774.
    Replacing this with simpler code that just disables SourceValidate
    during rotation redisplay.

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 5127c15..e8fafd0 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -39,7 +39,6 @@
 #include "xf86Crtc.h"
 #include "xf86Modes.h"
 #include "xf86RandR12.h"
-#include "misprite.h"
 #include "X11/extensions/render.h"
 #define DPMS_SERVER
 #include "X11/extensions/dpms.h"
@@ -280,11 +279,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
     if (REGION_NOTEMPTY(pScreen, region)) 
     {
 	int		    c;
-
-#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(7,2,0,0,dummy)
-	/* Disable software cursor removal for this drawing */
-	miSpriteDrawInternal(pScreen, TRUE);
-#endif
+	
 	for (c = 0; c < xf86_config->num_crtc; c++)
 	{
 	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
@@ -309,9 +304,6 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 		REGION_UNINIT (pScreen, &crtc_damage);
 	    }
 	}
-#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(7,2,0,0,dummy)
-	miSpriteDrawInternal(pScreen, FALSE);
-#endif
 	DamageEmpty(damage);
     }
 }
diff --git a/mi/misprite.c b/mi/misprite.c
index 71e6ab0..c0560a4 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -288,8 +288,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, 
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pScreenPriv->internalDraw == 0 &&
-	pDrawable->type == DRAWABLE_WINDOW &&
+    if (pDrawable->type == DRAWABLE_WINDOW &&
         pScreenPriv->isUp &&
 	ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
     {
@@ -319,8 +318,7 @@ miSpriteGetSpans (pDrawable, wMax, ppt, 
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pScreenPriv->internalDraw == 0 &&
-	pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
+    if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
     {
 	DDXPointPtr    	pts;
 	int    		*widths;
@@ -362,8 +360,7 @@ miSpriteSourceValidate (pDrawable, x, y,
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pScreenPriv->internalDraw == 0 &&
-	pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
+    if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
 	ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
 		    x, y, width, height))
     {
@@ -389,8 +386,7 @@ miSpriteCopyWindow (WindowPtr pWindow, D
     /*
      * Damage will take care of destination check
      */
-    if (pScreenPriv->internalDraw == 0 &&
-	pScreenPriv->isUp &&
+    if (pScreenPriv->isUp &&
 	RECT_IN_REGION (pScreen, prgnSrc, &pScreenPriv->saved) != rgnOUT)
     {
 	SPRITE_DEBUG (("CopyWindow remove\n"));
@@ -831,28 +827,3 @@ miSpriteComputeSaved (pScreen)
     pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
     pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
 }
-
-/**
- * Enables internal drawing support, which disables removal of the
- * cursor when the screen pixmap is sourced from.
- *
- * This can be used to allow software cursors to be read by RandR rotation
- * shadow code.
- */
-void
-miSpriteDrawInternal(ScreenPtr pScreen, Bool enable)
-{
-    miSpriteScreenPtr   pScreenPriv;
-
-    /* Check that miSprite has been set up this generation */
-    if (miSpriteGeneration != serverGeneration)
-	return;
-
-    pScreenPriv = (miSpriteScreenPtr)
-	pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
-    if (enable)
-	pScreenPriv->internalDraw++;
-    else
-	pScreenPriv->internalDraw--;
-}
diff --git a/mi/misprite.h b/mi/misprite.h
index 0a1bcc1..5173b77 100644
--- a/mi/misprite.h
+++ b/mi/misprite.h
@@ -92,5 +92,3 @@ extern Bool miSpriteInitialize(
     miSpriteCursorFuncPtr /*cursorFuncs*/,
     miPointerScreenFuncPtr /*screenFuncs*/
 );
-
-void miSpriteDrawInternal(ScreenPtr pScreen, Bool enable);
diff --git a/mi/mispritest.h b/mi/mispritest.h
index 2deaa45..5075f05 100644
--- a/mi/mispritest.h
+++ b/mi/mispritest.h
@@ -76,7 +76,6 @@ typedef struct {
     WindowPtr	    pCacheWin;		/* window the cursor last seen in */
     Bool	    isInCacheWin;
     Bool	    checkPixels;	/* check colormap collision */
-    int		    internalDraw;
     xColorItem	    colors[2];
     ColormapPtr	    pInstalledMap;
     ColormapPtr	    pColormap;
diff-tree 0a9239ec258828ec1da6c208634a55fc4053d7da (from d0e55774e0da641ba85c5173f27f68de27372747)
Author: Soren Sandmann Pedersen <ssp at dhcp83-218.boston.redhat.com>
Date:   Thu Apr 19 18:19:34 2007 -0400

    Merge David Reveman's gradient optimization patch from pixman

diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 6ea9483..3043637 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -40,6 +40,65 @@
 #include "mipict.h"
 #include "fbpict.h"
 
+static unsigned int
+SourcePictureClassify (PicturePtr pict,
+		       int	  x,
+		       int	  y,
+		       int	  width,
+		       int	  height)
+{
+    if (pict->pSourcePict->type == SourcePictTypeSolidFill)
+    {
+	pict->pSourcePict->solidFill.class = SourcePictClassHorizontal;
+    }
+    else if (pict->pSourcePict->type == SourcePictTypeLinear)
+    {
+	PictVector   v;
+	xFixed_32_32 l;
+	xFixed_48_16 dx, dy, a, b, off;
+	xFixed_48_16 factors[4];
+	int	     i;
+
+	dx = pict->pSourcePict->linear.p2.x - pict->pSourcePict->linear.p1.x;
+	dy = pict->pSourcePict->linear.p2.y - pict->pSourcePict->linear.p1.y;
+	l = dx * dx + dy * dy;
+	if (l)
+	{
+	    a = (dx << 32) / l;
+	    b = (dy << 32) / l;
+	}
+	else
+	{
+	    a = b = 0;
+	}
+
+	off = (-a * pict->pSourcePict->linear.p1.x
+	       -b * pict->pSourcePict->linear.p1.y) >> 16;
+
+	for (i = 0; i < 3; i++)
+	{
+	    v.vector[0] = IntToxFixed ((i % 2) * (width  - 1) + x);
+	    v.vector[1] = IntToxFixed ((i / 2) * (height - 1) + y);
+	    v.vector[2] = xFixed1;
+
+	    if (pict->transform)
+	    {
+		if (!PictureTransformPoint3d (pict->transform, &v))
+		    return SourcePictClassUnknown;
+	    }
+
+	    factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
+	}
+
+	if (factors[2] == factors[0])
+	    pict->pSourcePict->linear.class = SourcePictClassHorizontal;
+	else if (factors[1] == factors[0])
+	    pict->pSourcePict->linear.class = SourcePictClassVertical;
+    }
+
+    return pict->pSourcePict->solidFill.class;
+}
+
 #define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
 
 #define SCANLINE_BUFFER_LENGTH 2048
@@ -86,9 +145,9 @@ fbFetch_x8b8g8r8 (const FbBits *bits, in
     const CARD32 *end = pixel + width;
     while (pixel < end) {
         WRITE(buffer++, 0xff000000 |
-                        ((READ(pixel) & 0x0000ff00) |
-                         ((READ(pixel) >> 16) & 0xff) |
-                         ((READ(pixel) & 0xff) << 16)));
+	      ((READ(pixel) & 0x0000ff00) |
+	       ((READ(pixel) >> 16) & 0xff) |
+	       ((READ(pixel) & 0xff) << 16)));
         ++pixel;
     }
 }
@@ -132,8 +191,8 @@ fbFetch_r5g6b5 (const FbBits *bits, int 
     while (pixel < end) {
         CARD32  p = READ(pixel++);
         CARD32 r = (((p) << 3) & 0xf8) | 
-                   (((p) << 5) & 0xfc00) |
-                   (((p) << 8) & 0xf80000);
+	    (((p) << 5) & 0xfc00) |
+	    (((p) << 8) & 0xf80000);
         r |= (r >> 5) & 0x70007;
         r |= (r >> 6) & 0x300;
         WRITE(buffer++, 0xff000000 | r);
@@ -335,7 +394,7 @@ fbFetch_b2g3r3 (const FbBits *bits, int 
              ((p & 0x07) << 3) |
              ((p & 0x06) << 6)) << 16;
         WRITE(buffer++, (0xff000000 | r | g | b));
-	}
+    }
 }
 
 static FASTCALL void
@@ -558,7 +617,7 @@ static fetchProc fetchProcForPicture (Pi
     case PICT_c8: return  fbFetch_c8;
     case PICT_g8: return  fbFetch_c8;
     case PICT_x4a4: return fbFetch_x4a4;
-    
+
         /* 4bpp formats */
     case PICT_a4: return  fbFetch_a4;
     case PICT_r1g2b1: return fbFetch_r1g2b1;
@@ -1095,8 +1154,8 @@ fbStore_r5g6b5 (FbBits *bits, const CARD
     for (i = 0; i < width; ++i) {
         CARD32 s = READ(values + i);
         WRITE(pixel++, ((s >> 3) & 0x001f) |
-                       ((s >> 5) & 0x07e0) |
-                       ((s >> 8) & 0xf800));
+	      ((s >> 5) & 0x07e0) |
+	      ((s >> 8) & 0xf800));
     }
 }
 
@@ -1108,8 +1167,8 @@ fbStore_b5g6r5 (FbBits *bits, const CARD
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((b << 8) & 0xf800) |
-                       ((g << 3) & 0x07e0) |
-                       ((r >> 3)         ));
+	      ((g << 3) & 0x07e0) |
+	      ((r >> 3)         ));
     }
 }
 
@@ -1121,9 +1180,9 @@ fbStore_a1r5g5b5 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Splita(READ(values + i));
         WRITE(pixel++, ((a << 8) & 0x8000) |
-                       ((r << 7) & 0x7c00) |
-                       ((g << 2) & 0x03e0) |
-                       ((b >> 3)         ));
+	      ((r << 7) & 0x7c00) |
+	      ((g << 2) & 0x03e0) |
+	      ((b >> 3)         ));
     }
 }
 
@@ -1135,8 +1194,8 @@ fbStore_x1r5g5b5 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((r << 7) & 0x7c00) |
-                       ((g << 2) & 0x03e0) |
-                       ((b >> 3)         ));
+	      ((g << 2) & 0x03e0) |
+	      ((b >> 3)         ));
     }
 }
 
@@ -1148,10 +1207,10 @@ fbStore_a1b5g5r5 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Splita(READ(values + i));
         WRITE(pixel++, ((a << 8) & 0x8000) |
-                       ((b << 7) & 0x7c00) |
-                       ((g << 2) & 0x03e0) |
-                       ((r >> 3)         ));
-	}
+	      ((b << 7) & 0x7c00) |
+	      ((g << 2) & 0x03e0) |
+	      ((r >> 3)         ));
+    }
 }
 
 static FASTCALL void
@@ -1162,8 +1221,8 @@ fbStore_x1b5g5r5 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((b << 7) & 0x7c00) |
-                       ((g << 2) & 0x03e0) |
-                       ((r >> 3)         ));
+	      ((g << 2) & 0x03e0) |
+	      ((r >> 3)         ));
     }
 }
 
@@ -1175,9 +1234,9 @@ fbStore_a4r4g4b4 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Splita(READ(values + i));
         WRITE(pixel++, ((a << 8) & 0xf000) |
-                       ((r << 4) & 0x0f00) |
-                       ((g     ) & 0x00f0) |
-                       ((b >> 4)         ));
+	      ((r << 4) & 0x0f00) |
+	      ((g     ) & 0x00f0) |
+	      ((b >> 4)         ));
     }
 }
 
@@ -1189,8 +1248,8 @@ fbStore_x4r4g4b4 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((r << 4) & 0x0f00) |
-                       ((g     ) & 0x00f0) |
-                       ((b >> 4)         ));
+	      ((g     ) & 0x00f0) |
+	      ((b >> 4)         ));
     }
 }
 
@@ -1202,9 +1261,9 @@ fbStore_a4b4g4r4 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Splita(READ(values + i));
         WRITE(pixel++, ((a << 8) & 0xf000) |
-                       ((b << 4) & 0x0f00) |
-                       ((g     ) & 0x00f0) |
-                       ((r >> 4)         ));
+	      ((b << 4) & 0x0f00) |
+	      ((g     ) & 0x00f0) |
+	      ((r >> 4)         ));
     }
 }
 
@@ -1216,8 +1275,8 @@ fbStore_x4b4g4r4 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((b << 4) & 0x0f00) |
-                       ((g     ) & 0x00f0) |
-                       ((r >> 4)         ));
+	      ((g     ) & 0x00f0) |
+	      ((r >> 4)         ));
     }
 }
 
@@ -1239,8 +1298,8 @@ fbStore_r3g3b2 (FbBits *bits, const CARD
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((r     ) & 0xe0) |
-                       ((g >> 3) & 0x1c) |
-                       ((b >> 6)       ));
+	      ((g >> 3) & 0x1c) |
+	      ((b >> 6)       ));
     }
 }
 
@@ -1252,8 +1311,8 @@ fbStore_b2g3r3 (FbBits *bits, const CARD
     for (i = 0; i < width; ++i) {
         Split(READ(values + i));
         WRITE(pixel++, ((b     ) & 0xe0) |
-                       ((g >> 3) & 0x1c) |
-                       ((r >> 6)       ));
+	      ((g >> 3) & 0x1c) |
+	      ((r >> 6)       ));
     }
 }
 
@@ -1265,9 +1324,9 @@ fbStore_a2r2g2b2 (FbBits *bits, const CA
     for (i = 0; i < width; ++i) {
         Splita(READ(values + i));
         WRITE(pixel++, ((a     ) & 0xc0) |
-                       ((r >> 2) & 0x30) |
-                       ((g >> 4) & 0x0c) |
-                       ((b >> 6)       ));
+	      ((r >> 2) & 0x30) |
+	      ((g >> 4) & 0x0c) |
+	      ((b >> 6)       ));
     }
 }
 
@@ -1293,11 +1352,11 @@ fbStore_x4a4 (FbBits *bits, const CARD32
 
 #define Store8(l,o,v)  (((CARD8 *) l)[(o) >> 3] = (v))
 #if IMAGE_BYTE_ORDER == MSBFirst
-#define Store4(l,o,v)  Store8(l,o,((o) & 4 ? \
-				   (Fetch8(l,o) & 0xf0) | (v) : \
+#define Store4(l,o,v)  Store8(l,o,((o) & 4 ?			\
+				   (Fetch8(l,o) & 0xf0) | (v) :		\
 				   (Fetch8(l,o) & 0x0f) | ((v) << 4)))
 #else
-#define Store4(l,o,v)  Store8(l,o,((o) & 4 ? \
+#define Store4(l,o,v)  Store8(l,o,((o) & 4 ?			       \
 				   (Fetch8(l,o) & 0x0f) | ((v) << 4) : \
 				   (Fetch8(l,o) & 0xf0) | (v)))
 #endif
@@ -1655,22 +1714,22 @@ fbCombineSaturateU (CARD32 *dest, const 
  A nor B, areas covered only by A, areas covered only by B and finally
  areas covered by both A and B.
 
-		Disjoint			Conjoint
-		Fa		Fb		Fa		Fb
-(0,0,0,0)	0		0		0		0
-(0,A,0,A)	1		0		1		0
-(0,0,B,B)	0		1		0		1
-(0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
-(0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
-(0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
-(0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
-(0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
-(0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
-(0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
-(0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
-(0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
+ Disjoint			Conjoint
+ Fa		Fb		Fa		Fb
+ (0,0,0,0)	0		0		0		0
+ (0,A,0,A)	1		0		1		0
+ (0,0,B,B)	0		1		0		1
+ (0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
+ (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
+ (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
+ (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
+ (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
+ (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
+ (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
+ (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
+ (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
 
- */
+*/
 
 #define CombineAOut 1
 #define CombineAIn  2
@@ -2634,7 +2693,7 @@ FbComposeFunctions composeFunctions = {
 };
 
 
-static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
     FbBits *bits;
     FbStride stride;
@@ -2656,7 +2715,7 @@ static void fbFetchSolid(PicturePtr pict
     fbFinishAccess (pict->pDrawable);
 }
 
-static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
     FbBits *bits;
     FbStride stride;
@@ -2676,43 +2735,78 @@ static void fbFetch(PicturePtr pict, int
 }
 
 #define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
-#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\
-        ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
+#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :		\
+		  ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
 
+static CARD32
+xRenderColorMultToCard32 (xRenderColor *c)
+{
+    return
+	((((CARD32) c->red   * c->alpha) >> 24) << 16) |
+	((((CARD32) c->green * c->alpha) >> 24) <<  8) |
+	((((CARD32) c->blue  * c->alpha) >> 24) <<  0) |
+	((((CARD32) c->alpha		 ) >> 8)  << 24);
+}
 
 static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
 {
-    int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
+    int ipos = (pos * pGradient->gradient.stopRange - 1) >> 16;
 
     /* calculate the actual offset. */
-    if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
-        if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
-            ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
-            ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
+    if (ipos < 0 || ipos >= pGradient->gradient.stopRange)
+    {
+	if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal)
+	{
+	    ipos = ipos % pGradient->gradient.stopRange;
+	    ipos = ipos < 0 ? pGradient->gradient.stopRange + ipos : ipos;
+
+	}
+	else if (spread == RepeatReflect)
+	{
+	    const int limit = pGradient->gradient.stopRange * 2 - 1;
 
-        } else if (spread == RepeatReflect) {
-            const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
-            ipos = ipos % limit;
-            ipos = ipos < 0 ? limit + ipos : ipos;
-            ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
+	    ipos = ipos % limit;
+	    ipos = ipos < 0 ? limit + ipos : ipos;
+	    ipos = ipos >= pGradient->gradient.stopRange ? limit - ipos : ipos;
 
-        } else if (spread == RepeatPad) {
-            if (ipos < 0)
-                ipos = 0;
-            else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
-                ipos = PICT_GRADIENT_STOPTABLE_SIZE-1;
-        } else { /* RepeatNone */
-            return 0;
-        }
+	}
+	else if (spread == RepeatPad)
+	{
+	    if (ipos < 0)
+		ipos = 0;
+	    else
+		ipos = pGradient->gradient.stopRange - 1;
+	}
+	else  /* RepeatNone */
+	{
+	    return 0;
+	}
+    }
+
+    if (pGradient->gradient.colorTableSize)
+    {
+	return pGradient->gradient.colorTable[ipos];
     }
+    else
+    {
+	int i;
 
-    assert(ipos >= 0);
-    assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
+	if (ipos <= pGradient->gradient.stops->x)
+	    return xRenderColorMultToCard32 (&pGradient->gradient.stops->color);
 
-    return pGradient->linear.colorTable[ipos];
+	for (i = 1; i < pGradient->gradient.nstops; i++)
+	{
+	    if (pGradient->gradient.stops[i].x >= ipos)
+		return PictureGradientColor (&pGradient->gradient.stops[i - 1],
+					     &pGradient->gradient.stops[i],
+					     ipos);
+	}
+
+	return xRenderColorMultToCard32 (&pGradient->gradient.stops[--i].color);
+    }
 }
 
-static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
     SourcePictPtr pGradient = pict->pSourcePict;
     CARD32 *end = buffer + width;
@@ -2761,26 +2855,73 @@ static void fbFetchSourcePict(PicturePtr
                 t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
                 inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
             }
-            while (buffer < end) {
-                WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
-                t += inc;
-            }
-        } else {
-            /* projective transformation */
-            while (buffer < end) {
-                xFixed_48_16 t;
-                if (v.vector[2] == 0) {
-                    t = 0;
-                } else {
-                    xFixed_48_16 x, y;
-                    x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
-                    y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
-                    t = ((a*x + b*y) >> 16) + off;
-                }
-                WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
-                v.vector[0] += unit.vector[0];
-                v.vector[1] += unit.vector[1];
-                v.vector[2] += unit.vector[2];
+
+	    if (pGradient->linear.class == SourcePictClassVertical)
+	    {
+		register CARD32 color;
+
+		color = gradientPixel (pGradient, t, pict->repeat);
+		while (buffer < end)
+		    *buffer++ = color;
+	    }
+	    else
+	    {
+		while (buffer < end) {
+		    if (!mask || *mask++ & maskBits)
+		    {
+			*buffer = gradientPixel (pGradient, t, pict->repeat);
+		    }
+		    ++buffer;
+		    t += inc;
+		}
+	    }
+	}
+	else /* projective transformation */
+	{
+	    xFixed_48_16 t;
+
+	    if (pGradient->linear.class == SourcePictClassVertical)
+	    {
+		register CARD32 color;
+
+		if (v.vector[2] == 0)
+		{
+		    t = 0;
+		}
+		else
+		{
+		    xFixed_48_16 x, y;
+
+		    x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
+		    y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
+		    t = ((a * x + b * y) >> 16) + off;
+		}
+
+		color = gradientPixel (pGradient, t, pict->repeat);
+		while (buffer < end)
+		    *buffer++ = color;
+	    }
+	    else
+	    {
+		while (buffer < end)
+		{
+		    if (!mask || *mask++ & maskBits)
+		    {
+			if (v.vector[2] == 0) {
+			    t = 0;
+			} else {
+			    xFixed_48_16 x, y;
+			    x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
+			    y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
+			    t = ((a*x + b*y) >> 16) + off;
+			}
+			*buffer = gradientPixel(pGradient, t, pict->repeat);
+		    }
+		    ++buffer;
+		    v.vector[0] += unit.vector[0];
+		    v.vector[1] += unit.vector[1];
+		    v.vector[2] += unit.vector[2];
+		}
             }
         }
     } else {
@@ -2817,14 +2958,20 @@ static void fbFetchSourcePict(PicturePtr
                 ry -= pGradient->radial.fy;
 
                 while (buffer < end) {
-                    double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
-                    double c = -(rx*rx + ry*ry);
-                    double det = (b * b) - (4 * pGradient->radial.a * c);
-                    double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-                    WRITE(buffer, gradientPixel(pGradient,
-                                                (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
-                                                pict->repeatType));
-                    ++buffer;
+		    double b, c, det, s;
+
+		    if (!mask || *mask++ & maskBits)
+		    {
+			b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
+			c = -(rx*rx + ry*ry);
+			det = (b * b) - (4 * pGradient->radial.a * c);
+			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+			WRITE(buffer, gradientPixel(pGradient,
+						    (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
+						    pict->repeatType));
+		    }
+		    ++buffer;
+
                     rx += cx;
                     ry += cy;
                 }
@@ -2832,22 +2979,27 @@ static void fbFetchSourcePict(PicturePtr
                 while (buffer < end) {
                     double x, y;
                     double b, c, det, s;
-                    if (rz != 0) {
-                        x = rx/rz;
-                        y = ry/rz;
-                    } else {
-                        x = y = 0.;
-                    }
-                    x -= pGradient->radial.fx;
-                    y -= pGradient->radial.fy;
-                    b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
-                    c = -(x*x + y*y);
-                    det = (b * b) - (4 * pGradient->radial.a * c);
-                    s = (-b + sqrt(det))/(2. * pGradient->radial.a);
-                    WRITE(buffer, gradientPixel(pGradient,
-                                                (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
-                                                pict->repeatType));
-                    ++buffer;
+
+		    if (!mask || *mask++ & maskBits)
+		    {
+			if (rz != 0) {
+			    x = rx/rz;
+			    y = ry/rz;
+			} else {
+			    x = y = 0.;
+			}
+			x -= pGradient->radial.fx;
+			y -= pGradient->radial.fy;
+			b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
+			c = -(x*x + y*y);
+			det = (b * b) - (4 * pGradient->radial.a * c);
+			s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+			*buffer = gradientPixel(pGradient,
+						(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
+						pict->repeat);
+		    }
+		    ++buffer;
+
                     rx += cx;
                     ry += cy;
                     rz += cz;
@@ -2860,28 +3012,37 @@ static void fbFetchSourcePict(PicturePtr
                 ry -= pGradient->conical.center.y/65536.;
 
                 while (buffer < end) {
-                    double angle = atan2(ry, rx) + a;
-                    WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
-                                                pict->repeatType));
+		    double angle;
+
+		    if (!mask || *mask++ & maskBits)
+		    {
+			angle = atan2(ry, rx) + a;
+
+			*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+						pict->repeat);
+		    }
+
                     ++buffer;
                     rx += cx;
                     ry += cy;
                 }
             } else {
-
                 while (buffer < end) {
                     double x, y, angle;
-                    if (rz != 0) {
-                        x = rx/rz;
-                        y = ry/rz;
-                    } else {
-                        x = y = 0.;
-                    }
-                    x -= pGradient->conical.center.x/65536.;
-                    y -= pGradient->conical.center.y/65536.;
-                    angle = atan2(y, x) + a;
-                    WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
-                                                pict->repeatType));
+		    if (!mask || *mask++ & maskBits)
+		    {
+			if (rz != 0) {
+			    x = rx/rz;
+			    y = ry/rz;
+			} else {
+			    x = y = 0.;
+			}
+			x -= pGradient->conical.center.x/65536.;
+			y -= pGradient->conical.center.y/65536.;
+			angle = atan2(y, x) + a;
+			*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+						pict->repeat);
+		    }
                     ++buffer;
                     rx += cx;
                     ry += cy;
@@ -2892,9 +3053,7 @@ static void fbFetchSourcePict(PicturePtr
     }
 }
 
-
-
-static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
     FbBits     *bits;
     FbStride    stride;
@@ -2943,39 +3102,47 @@ static void fbFetchTransformed(PicturePt
         if (pict->repeatType == RepeatNormal) {
             if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        if (!affine) {
-                            y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
-                            x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
-                        } else {
-                            y = MOD(v.vector[1]>>16, pict->pDrawable->height);
-                            x = MOD(v.vector[0]>>16, pict->pDrawable->width);
-                        }
-                        WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-                    }
+		    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    buffer[i] = 0;
+			} else {
+			    if (!affine) {
+				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+				x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+			    } else {
+				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+			    }
+			    buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+			}
+		    }
+
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
                 }
             } else {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        if (!affine) {
-                            y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
-                            x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
-                        } else {
-                            y = MOD(v.vector[1]>>16, pict->pDrawable->height);
-                            x = MOD(v.vector[0]>>16, pict->pDrawable->width);
-                        }
-                        if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
-                            WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-                        else
-                            WRITE(buffer + i, 0);
-                    }
+		    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    buffer[i] = 0;
+			} else {
+			    if (!affine) {
+				y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+				x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+			    } else {
+				y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+				x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+			    }
+			    if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
+				buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+			    else
+				buffer[i] = 0;
+			}
+		    }
+
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
@@ -2985,40 +3152,46 @@ static void fbFetchTransformed(PicturePt
             if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        if (!affine) {
-                            y = DIV(v.vector[1],v.vector[2]);
-                            x = DIV(v.vector[0],v.vector[2]);
-                        } else {
-                            y = v.vector[1]>>16;
-                            x = v.vector[0]>>16;
-                        }
-                        WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
-                                          0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
-                    }
+		    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    if (!affine) {
+				y = DIV(v.vector[1],v.vector[2]);
+				x = DIV(v.vector[0],v.vector[2]);
+			    } else {
+				y = v.vector[1]>>16;
+				x = v.vector[0]>>16;
+			    }
+			    WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
+				  0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
+			}
+		    }
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
                 }
             } else {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        if (!affine) {
-                            y = DIV(v.vector[1],v.vector[2]);
-                            x = DIV(v.vector[0],v.vector[2]);
-                        } else {
-                            y = v.vector[1]>>16;
-                            x = v.vector[0]>>16;
-                        }
-                        if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
-                            WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
-                        else
-                            WRITE(buffer + i, 0);
-                    }
+                    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    if (!affine) {
+				y = DIV(v.vector[1],v.vector[2]);
+				x = DIV(v.vector[0],v.vector[2]);
+			    } else {
+				y = v.vector[1]>>16;
+				x = v.vector[0]>>16;
+			    }
+			    if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
+				WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
+			    else
+				WRITE(buffer + i, 0);
+			}
+		    }
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
@@ -3035,126 +3208,133 @@ static void fbFetchTransformed(PicturePt
         if (pict->repeatType == RepeatNormal) {
             if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        int x1, x2, y1, y2, distx, idistx, disty, idisty;
-                        FbBits *b;
-                        CARD32 tl, tr, bl, br, r;
-                        CARD32 ft, fb;
-
-                        if (!affine) {
-                            xFixed_48_16 div;
-                            div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-                            x1 = div >> 16;
-                            distx = ((xFixed)div >> 8) & 0xff;
-                            div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-                            y1 = div >> 16;
-                            disty = ((xFixed)div >> 8) & 0xff;
-                        } else {
-                            x1 = v.vector[0] >> 16;
-                            distx = (v.vector[0] >> 8) & 0xff;
-                            y1 = v.vector[1] >> 16;
-                            disty = (v.vector[1] >> 8) & 0xff;
-                        }
-                        x2 = x1 + 1;
-                        y2 = y1 + 1;
-
-                        idistx = 256 - distx;
-                        idisty = 256 - disty;
-
-                        x1 = MOD (x1, pict->pDrawable->width);
-                        x2 = MOD (x2, pict->pDrawable->width);
-                        y1 = MOD (y1, pict->pDrawable->height);
-                        y2 = MOD (y2, pict->pDrawable->height);
-
-                        b = bits + (y1 + dy)*stride;
-
-                        tl = fetch(b, x1 + dx, indexed);
-                        tr = fetch(b, x2 + dx, indexed);
-                        b = bits + (y2 + dy)*stride;
-                        bl = fetch(b, x1 + dx, indexed);
-                        br = fetch(b, x2 + dx, indexed);
-
-                        ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-                        fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-                        r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-                        ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-                        fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-                        r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-                        ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-                        fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-                        r |= (((ft * idisty + fb * disty)) & 0xff0000);
-                        ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-                        fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-                        r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-                        WRITE(buffer + i, r);
-                    }
+                    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    int x1, x2, y1, y2, distx, idistx, disty, idisty;
+			    FbBits *b;
+			    CARD32 tl, tr, bl, br, r;
+			    CARD32 ft, fb;
+
+			    if (!affine) {
+				xFixed_48_16 div;
+				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+				x1 = div >> 16;
+				distx = ((xFixed)div >> 8) & 0xff;
+				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+				y1 = div >> 16;
+				disty = ((xFixed)div >> 8) & 0xff;
+			    } else {
+				x1 = v.vector[0] >> 16;
+				distx = (v.vector[0] >> 8) & 0xff;
+				y1 = v.vector[1] >> 16;
+				disty = (v.vector[1] >> 8) & 0xff;
+			    }
+			    x2 = x1 + 1;
+			    y2 = y1 + 1;
+
+			    idistx = 256 - distx;
+			    idisty = 256 - disty;
+
+			    x1 = MOD (x1, pict->pDrawable->width);
+			    x2 = MOD (x2, pict->pDrawable->width);
+			    y1 = MOD (y1, pict->pDrawable->height);
+			    y2 = MOD (y2, pict->pDrawable->height);
+
+			    b = bits + (y1 + dy)*stride;
+
+			    tl = fetch(b, x1 + dx, indexed);
+			    tr = fetch(b, x2 + dx, indexed);
+			    b = bits + (y2 + dy)*stride;
+			    bl = fetch(b, x1 + dx, indexed);
+			    br = fetch(b, x2 + dx, indexed);
+
+			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
+			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+			    WRITE(buffer + i, r);
+			}
+		    }
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
                 }
             } else {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        int x1, x2, y1, y2, distx, idistx, disty, idisty;
-                        FbBits *b;
-                        CARD32 tl, tr, bl, br, r;
-                        CARD32 ft, fb;
-
-                        if (!affine) {
-                            xFixed_48_16 div;
-                            div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-                            x1 = div >> 16;
-                            distx = ((xFixed)div >> 8) & 0xff;
-                            div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-                            y1 = div >> 16;
-                            disty = ((xFixed)div >> 8) & 0xff;
-                        } else {
-                            x1 = v.vector[0] >> 16;
-                            distx = (v.vector[0] >> 8) & 0xff;
-                            y1 = v.vector[1] >> 16;
-                            disty = (v.vector[1] >> 8) & 0xff;
-                        }
-                        x2 = x1 + 1;
-                        y2 = y1 + 1;
-
-                        idistx = 256 - distx;
-                        idisty = 256 - disty;
-
-                        x1 = MOD (x1, pict->pDrawable->width);
-                        x2 = MOD (x2, pict->pDrawable->width);
-                        y1 = MOD (y1, pict->pDrawable->height);
-                        y2 = MOD (y2, pict->pDrawable->height);
-
-                        b = bits + (y1 + dy)*stride;
-
-                        tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
-                             ? fetch(b, x1 + dx, indexed) : 0;
-                        tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
-                             ? fetch(b, x2 + dx, indexed) : 0;
-                        b = bits + (y2 + dy)*stride;
-                        bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
-                             ? fetch(b, x1 + dx, indexed) : 0;
-                        br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
-                             ? fetch(b, x2 + dx, indexed) : 0;
-
-                        ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-                        fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-                        r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-                        ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-                        fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-                        r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-                        ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-                        fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-                        r |= (((ft * idisty + fb * disty)) & 0xff0000);
-                        ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-                        fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-                        r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-                        WRITE(buffer + i, r);
-                    }
+		    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    int x1, x2, y1, y2, distx, idistx, disty, idisty;
+			    FbBits *b;
+			    CARD32 tl, tr, bl, br, r;
+			    CARD32 ft, fb;
+
+			    if (!affine) {
+				xFixed_48_16 div;
+				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+				x1 = div >> 16;
+				distx = ((xFixed)div >> 8) & 0xff;
+				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+				y1 = div >> 16;
+				disty = ((xFixed)div >> 8) & 0xff;
+			    } else {
+				x1 = v.vector[0] >> 16;
+				distx = (v.vector[0] >> 8) & 0xff;
+				y1 = v.vector[1] >> 16;
+				disty = (v.vector[1] >> 8) & 0xff;
+			    }
+			    x2 = x1 + 1;
+			    y2 = y1 + 1;
+
+			    idistx = 256 - distx;
+			    idisty = 256 - disty;
+
+			    x1 = MOD (x1, pict->pDrawable->width);
+			    x2 = MOD (x2, pict->pDrawable->width);
+			    y1 = MOD (y1, pict->pDrawable->height);
+			    y2 = MOD (y2, pict->pDrawable->height);
+
+			    b = bits + (y1 + dy)*stride;
+
+			    tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
+				? fetch(b, x1 + dx, indexed) : 0;
+			    tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
+				? fetch(b, x2 + dx, indexed) : 0;
+			    b = bits + (y2 + dy)*stride;
+			    bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
+				? fetch(b, x1 + dx, indexed) : 0;
+			    br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
+				? fetch(b, x2 + dx, indexed) : 0;
+
+			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
+			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+			    WRITE(buffer + i, r);
+			}
+		    }
+
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
@@ -3164,124 +3344,132 @@ static void fbFetchTransformed(PicturePt
             if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
-                        FbBits *b;
-                        CARD32 tl, tr, bl, br, r;
-                        Bool x1_out, x2_out, y1_out, y2_out;
-                        CARD32 ft, fb;
-
-                        if (!affine) {
-                            xFixed_48_16 div;
-                            div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-                            x1 = div >> 16;
-                            distx = ((xFixed)div >> 8) & 0xff;
-                            div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-                            y1 = div >> 16;
-                            disty = ((xFixed)div >> 8) & 0xff;
-                        } else {
-                            x1 = v.vector[0] >> 16;
-                            distx = (v.vector[0] >> 8) & 0xff;
-                            y1 = v.vector[1] >> 16;
-                            disty = (v.vector[1] >> 8) & 0xff;
-                        }
-                        x2 = x1 + 1;
-                        y2 = y1 + 1;
-
-                        idistx = 256 - distx;
-                        idisty = 256 - disty;
-
-                        b = bits + (y1 + dy)*stride;
-                        x_off = x1 + dx;
-
-                        x1_out = (x1 < box.x1-dx) | (x1 >= box.x2-dx);
-                        x2_out = (x2 < box.x1-dx) | (x2 >= box.x2-dx);
-                        y1_out = (y1 < box.y1-dy) | (y1 >= box.y2-dy);
-                        y2_out = (y2 < box.y1-dy) | (y2 >= box.y2-dy);
-
-                        tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
-                        tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
-                        b += stride;
-                        bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
-                        br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
-
-                        ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-                        fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-                        r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-                        ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-                        fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-                        r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-                        ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-                        fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-                        r |= (((ft * idisty + fb * disty)) & 0xff0000);
-                        ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-                        fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-                        r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-                        WRITE(buffer + i, r);
-                    }
+		    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+			    FbBits *b;
+			    CARD32 tl, tr, bl, br, r;
+			    Bool x1_out, x2_out, y1_out, y2_out;
+			    CARD32 ft, fb;
+
+			    if (!affine) {
+				xFixed_48_16 div;
+				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+				x1 = div >> 16;
+				distx = ((xFixed)div >> 8) & 0xff;
+				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+				y1 = div >> 16;
+				disty = ((xFixed)div >> 8) & 0xff;
+			    } else {
+				x1 = v.vector[0] >> 16;
+				distx = (v.vector[0] >> 8) & 0xff;
+				y1 = v.vector[1] >> 16;
+				disty = (v.vector[1] >> 8) & 0xff;
+			    }
+			    x2 = x1 + 1;
+			    y2 = y1 + 1;
+
+			    idistx = 256 - distx;
+			    idisty = 256 - disty;
+
+			    b = bits + (y1 + dy)*stride;
+			    x_off = x1 + dx;
+
+			    x1_out = (x1 < box.x1-dx) | (x1 >= box.x2-dx);
+			    x2_out = (x2 < box.x1-dx) | (x2 >= box.x2-dx);
+			    y1_out = (y1 < box.y1-dy) | (y1 >= box.y2-dy);
+			    y2_out = (y2 < box.y1-dy) | (y2 >= box.y2-dy);
+
+			    tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
+			    tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
+			    b += stride;
+			    bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
+			    br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
+
+			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
+			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+			    WRITE(buffer + i, r);
+			}
+		    }
+
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
                 }
             } else {
                 for (i = 0; i < width; ++i) {
-                    if (!v.vector[2]) {
-                        WRITE(buffer + i, 0);
-                    } else {
-                        int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
-                        FbBits *b;
-                        CARD32 tl, tr, bl, br, r;
-                        CARD32 ft, fb;
-
-                        if (!affine) {
-                            xFixed_48_16 div;
-                            div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
-                            x1 = div >> 16;
-                            distx = ((xFixed)div >> 8) & 0xff;
-                            div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
-                            y1 = div >> 16;
-                            disty = ((xFixed)div >> 8) & 0xff;
-                        } else {
-                            x1 = v.vector[0] >> 16;
-                            distx = (v.vector[0] >> 8) & 0xff;
-                            y1 = v.vector[1] >> 16;
-                            disty = (v.vector[1] >> 8) & 0xff;
-                        }
-                        x2 = x1 + 1;
-                        y2 = y1 + 1;
-
-                        idistx = 256 - distx;
-                        idisty = 256 - disty;
-
-                        b = bits + (y1 + dy)*stride;
-                        x_off = x1 + dx;
-
-                        tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
-                             ? fetch(b, x_off, indexed) : 0;
-                        tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
-                             ? fetch(b, x_off + 1, indexed) : 0;
-                        b += stride;
-                        bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
-                             ? fetch(b, x_off, indexed) : 0;
-                        br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
-                             ? fetch(b, x_off + 1, indexed) : 0;
-
-                        ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
-                        fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
-                        r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-                        ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
-                        fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
-                        r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-                        ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
-                        fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
-                        r |= (((ft * idisty + fb * disty)) & 0xff0000);
-                        ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
-                        fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
-                        r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-                        WRITE(buffer + i, r);
-                    }
+                    if (!mask || mask[i] & maskBits)
+		    {
+			if (!v.vector[2]) {
+			    WRITE(buffer + i, 0);
+			} else {
+			    int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+			    FbBits *b;
+			    CARD32 tl, tr, bl, br, r;
+			    CARD32 ft, fb;
+
+			    if (!affine) {
+				xFixed_48_16 div;
+				div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+				x1 = div >> 16;
+				distx = ((xFixed)div >> 8) & 0xff;
+				div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+				y1 = div >> 16;
+				disty = ((xFixed)div >> 8) & 0xff;
+			    } else {
+				x1 = v.vector[0] >> 16;
+				distx = (v.vector[0] >> 8) & 0xff;
+				y1 = v.vector[1] >> 16;
+				disty = (v.vector[1] >> 8) & 0xff;
+			    }
+			    x2 = x1 + 1;
+			    y2 = y1 + 1;
+
+			    idistx = 256 - distx;
+			    idisty = 256 - disty;
+
+			    b = bits + (y1 + dy)*stride;
+			    x_off = x1 + dx;
+
+			    tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
+				? fetch(b, x_off, indexed) : 0;
+			    tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
+				? fetch(b, x_off + 1, indexed) : 0;
+			    b += stride;
+			    bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
+				? fetch(b, x_off, indexed) : 0;
+			    br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
+				? fetch(b, x_off + 1, indexed) : 0;
+
+			    ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+			    fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+			    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+			    ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+			    fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+			    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+			    ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+			    fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+			    r |= (((ft * idisty + fb * disty)) & 0xff0000);
+			    ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+			    fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+			    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+			    WRITE(buffer + i, r);
+			}
+		    }
+
                     v.vector[0] += unit.vector[0];
                     v.vector[1] += unit.vector[1];
                     v.vector[2] += unit.vector[2];
@@ -3296,62 +3484,65 @@ static void fbFetchTransformed(PicturePt
 	int yoff = (params[1] - xFixed1) >> 1;
         params += 2;
         for (i = 0; i < width; ++i) {
-            if (!v.vector[2]) {
-                WRITE(buffer + i, 0);
-            } else {
-                int x1, x2, y1, y2, x, y;
-                INT32 srtot, sgtot, sbtot, satot;
-                xFixed *p = params;
-
-                if (!affine) {
-                    xFixed_48_16 tmp;
-                    tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
-                    x1 = xFixedToInt(tmp);
-                    tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
-                    y1 = xFixedToInt(tmp);
-                } else {
-                    x1 = xFixedToInt(v.vector[0] - xoff);
-                    y1 = xFixedToInt(v.vector[1] - yoff);
-                }
-                x2 = x1 + cwidth;
-                y2 = y1 + cheight;
-
-                srtot = sgtot = sbtot = satot = 0;
-
-                for (y = y1; y < y2; y++) {
-                    int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
-                    for (x = x1; x < x2; x++) {
-                        if (*p) {
-                            int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
-                            if (POINT_IN_REGION (0, pict->pCompositeClip, tx + dx, ty + dy, &box)) {
-                                FbBits *b = bits + (ty + dy)*stride;
-                                CARD32 c = fetch(b, tx + dx, indexed);
-
-                                srtot += Red(c) * *p;
-                                sgtot += Green(c) * *p;
-                                sbtot += Blue(c) * *p;
-                                satot += Alpha(c) * *p;
-                            }
-                        }
-                        p++;
-                    }
-                }
-
-		satot >>= 16;
-		srtot >>= 16;
-		sgtot >>= 16;
-		sbtot >>= 16;
-
-                if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
-                if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
-                if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
-                if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
-
-                WRITE(buffer + i, ((satot << 24) |
-                                  (srtot << 16) |
-                                  (sgtot <<  8) |
-                                  (sbtot       )));
-            }
+	    if (!mask || mask[i] & maskBits)
+	    {
+		if (!v.vector[2]) {
+		    WRITE(buffer + i, 0);
+		} else {
+		    int x1, x2, y1, y2, x, y;
+		    INT32 srtot, sgtot, sbtot, satot;
+		    xFixed *p = params;
+
+		    if (!affine) {
+			xFixed_48_16 tmp;
+			tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
+			x1 = xFixedToInt(tmp);
+			tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
+			y1 = xFixedToInt(tmp);
+		    } else {
+			x1 = xFixedToInt(v.vector[0] - xoff);
+			y1 = xFixedToInt(v.vector[1] - yoff);
+		    }
+		    x2 = x1 + cwidth;
+		    y2 = y1 + cheight;
+
+		    srtot = sgtot = sbtot = satot = 0;
+
+		    for (y = y1; y < y2; y++) {
+			int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
+			for (x = x1; x < x2; x++) {
+			    if (*p) {
+				int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
+				if (POINT_IN_REGION (0, pict->pCompositeClip, tx + dx, ty + dy, &box)) {
+				    FbBits *b = bits + (ty + dy)*stride;
+				    CARD32 c = fetch(b, tx + dx, indexed);
+
+				    srtot += Red(c) * *p;
+				    sgtot += Green(c) * *p;
+				    sbtot += Blue(c) * *p;
+				    satot += Alpha(c) * *p;
+				}
+			    }
+			    p++;
+			}
+		    }
+
+		    satot >>= 16;
+		    srtot >>= 16;
+		    sgtot >>= 16;
+		    sbtot >>= 16;
+
+		    if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+		    if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+		    if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+		    if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+
+		    WRITE(buffer + i, ((satot << 24) |
+				       (srtot << 16) |
+				       (sgtot <<  8) |
+				       (sbtot       )));
+		}
+	    }
             v.vector[0] += unit.vector[0];
             v.vector[1] += unit.vector[1];
             v.vector[2] += unit.vector[2];
@@ -3362,27 +3553,32 @@ static void fbFetchTransformed(PicturePt
 }
 
 
-static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
 {
     int i;
     CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
     CARD32 *alpha_buffer = _alpha_buffer;
 
     if (!pict->alphaMap) {
-        fbFetchTransformed(pict, x, y, width, buffer);
+        fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
 	return;
     }
     if (width > SCANLINE_BUFFER_LENGTH)
         alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
 
-    fbFetchTransformed(pict, x, y, width, buffer);
-    fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer);
+    fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
+    fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
+		       y - pict->alphaOrigin.y, width, alpha_buffer,
+		       mask, maskBits);
     for (i = 0; i < width; ++i) {
-        int a = alpha_buffer[i]>>24;
-        WRITE(buffer + i, (a << 24)
-                          | (div_255(Red(READ(buffer + i)) * a) << 16)
-                          | (div_255(Green(READ(buffer + i)) * a) << 8)
-                          | (div_255(Blue(READ(buffer + i)) * a)));
+        if (!mask || mask[i] & maskBits)
+	{
+	    int a = alpha_buffer[i]>>24;
+	    WRITE(buffer + i, (a << 24)
+		  | (div_255(Red(READ(buffer + i)) * a) << 16)
+		  | (div_255(Green(READ(buffer + i)) * a) << 8)
+		  | (div_255(Blue(READ(buffer + i)) * a)));
+	}
     }
 
     if (alpha_buffer != _alpha_buffer)
@@ -3450,7 +3646,7 @@ static void fbStoreExternalAlpha(Picture
 }
 
 typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
-typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *);
+typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
 
 static void
 fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
@@ -3460,31 +3656,52 @@ fbCompositeRect (const FbComposeData *da
     int i;
     scanStoreProc store;
     scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
-
+    unsigned int srcClass = SourcePictClassUnknown;
+    unsigned int maskClass = SourcePictClassUnknown;
+    FbBits *bits;
+    FbStride stride;
+    int xoff, yoff;
+    
     if (data->op == PictOpClear)
         fetchSrc = NULL;
     else if (!data->src->pDrawable) {
         if (data->src->pSourcePict)
+	{
             fetchSrc = fbFetchSourcePict;
+	    srcClass = SourcePictureClassify (data->src,
+					      data->xSrc, data->ySrc,
+					      data->width, data->height);
+	}
     } else if (data->src->alphaMap)
         fetchSrc = fbFetchExternalAlpha;
     else if (data->src->repeatType == RepeatNormal &&
              data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
+    {
         fetchSrc = fbFetchSolid;
+	srcClass = SourcePictClassHorizontal;
+    }
     else if (!data->src->transform && data->src->filter != PictFilterConvolution)
         fetchSrc = fbFetch;
     else
         fetchSrc = fbFetchTransformed;
-
+    
     if (data->mask && data->op != PictOpClear) {
         if (!data->mask->pDrawable) {
             if (data->mask->pSourcePict)
                 fetchMask = fbFetchSourcePict;
         } else if (data->mask->alphaMap)
+	{
             fetchMask = fbFetchExternalAlpha;
+	    maskClass = SourcePictureClassify (data->mask,
+					       data->xMask, data->yMask,
+					       data->width, data->height);
+	}
         else if (data->mask->repeatType == RepeatNormal
                  && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
-            fetchMask = fbFetchSolid;
+	{
+	    fetchMask = fbFetchSolid;
+	    maskClass = SourcePictClassHorizontal;
+	}
         else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
             fetchMask = fbFetch;
         else
@@ -3492,78 +3709,206 @@ fbCompositeRect (const FbComposeData *da
     } else {
         fetchMask = NULL;
     }
-
-    if (data->dest->alphaMap) {
-        fetchDest = fbFetchExternalAlpha;
-        store = fbStoreExternalAlpha;
-    } else {
-        fetchDest = fbFetch;
-        store = fbStore;
+    
+    if (data->dest->alphaMap)
+    {
+	fetchDest = fbFetchExternalAlpha;
+	store = fbStoreExternalAlpha;
+	
+	if (data->op == PictOpClear || data->op == PictOpSrc)
+	    fetchDest = NULL;
     }
-    if (data->op == PictOpClear || data->op == PictOpSrc)
-        fetchDest = NULL;
-
-    if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) {
-        CARD32 *mask_buffer = dest_buffer + data->width;
-        CombineFuncC compose = composeFunctions.combineC[data->op];
-        if (!compose)
-            return;
-
-        for (i = 0; i < data->height; ++i)
-        {
-            /* fill first half of scanline with source */
-            fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
-            fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer);
-
-            /* fill dest into second half of scanline */
-            if (fetchDest)
-                fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-
-            /* blend */
-            compose(dest_buffer, src_buffer, mask_buffer, data->width);
-
-            /* write back */
-            store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-        }
-    } else {
-
-        CombineFuncU compose = composeFunctions.combineU[data->op];
-        if (!compose)
-            return;
-
-        if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
-            fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
-            if (fetchMask) {
-                fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer);
-                composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
-            }
-            fetchSrc = NULL;
-            fetchMask = NULL;
-        }
-
-        for (i = 0; i < data->height; ++i)
-        {
-            /* fill first half of scanline with source */
-            if (fetchSrc) {
-                fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
-
-                /* add in mask */
-                if (fetchMask) {
-                    fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
-                    composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
-                }
-            }
-
-            /* fill dest into second half of scanline */
-            if (fetchDest)
-                fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-
-            /* blend */
-            compose(dest_buffer, src_buffer, data->width);
-
-            /* write back */
-            store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-        }
+    else
+    {
+	fetchDest = fbFetch;
+	store = fbStore;
+	
+	switch (data->op) {
+	case PictOpClear:
+	case PictOpSrc:
+	    fetchDest = NULL;
+	    /* fall-through */
+	case PictOpAdd:
+	case PictOpOver:
+	    switch (data->dest->format) {
+	    case PICT_a8r8g8b8:
+	    case PICT_x8r8g8b8:
+		store = NULL;
+		break;
+	    default:
+		break;
+	    }
+	    break;
+	}
+    }
+    
+    if (!store)
+    {
+	int bpp;
+	
+	fbGetDrawable (data->dest->pDrawable, bits, stride, bpp, xoff, yoff);
+    }
+    else
+    {
+	bits = NULL;
+	stride = 0;
+	xoff = yoff = 0;
+    }
+    
+    if (fetchSrc		   &&
+	fetchMask		   &&
+	data->mask		   &&
+	data->mask->componentAlpha &&
+	PICT_FORMAT_RGB (data->mask->format))
+    {
+	CARD32 *mask_buffer = dest_buffer + data->width;
+	CombineFuncC compose = composeFunctions.combineC[data->op];
+	if (!compose)
+	    return;
+	
+	for (i = 0; i < data->height; ++i) {
+	    /* fill first half of scanline with source */
+	    if (fetchSrc)
+	    {
+		if (fetchMask)
+		{
+		    /* fetch mask before source so that fetching of
+		       source can be optimized */
+		    fetchMask (data->mask, data->xMask, data->yMask + i,
+			       data->width, mask_buffer, 0, 0);
+		    
+		    if (maskClass == SourcePictClassHorizontal)
+			fetchMask = NULL;
+		}
+		
+		if (srcClass == SourcePictClassHorizontal)
+		{
+		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
+			      data->width, src_buffer, 0, 0);
+		    fetchSrc = NULL;
+		}
+		else
+		{
+		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
+			      data->width, src_buffer, mask_buffer,
+			      0xffffffff);
+		}
+	    }
+	    else if (fetchMask)
+	    {
+		fetchMask (data->mask, data->xMask, data->yMask + i,
+			   data->width, mask_buffer, 0, 0);
+	    }
+	    
+	    if (store)
+	    {
+		/* fill dest into second half of scanline */
+		if (fetchDest)
+		    fetchDest (data->dest, data->xDest, data->yDest + i,
+			       data->width, dest_buffer, 0, 0);
+		
+		/* blend */
+		compose (dest_buffer, src_buffer, mask_buffer, data->width);
+		
+		/* write back */
+		store (data->dest, data->xDest, data->yDest + i, data->width,
+		       dest_buffer);
+	    }
+	    else
+	    {
+		/* blend */
+		compose (bits + (data->yDest + i+ yoff) * stride +
+			 data->xDest + xoff,
+			 src_buffer, mask_buffer, data->width);
+	    }
+	}
+    }
+    else
+    {
+	CARD32 *src_mask_buffer = 0, *mask_buffer = 0;
+	CombineFuncU compose = composeFunctions.combineU[data->op];
+	if (!compose)
+	    return;
+	
+	if (fetchMask)
+	    mask_buffer = dest_buffer + data->width;
+	
+	for (i = 0; i < data->height; ++i) {
+	    /* fill first half of scanline with source */
+	    if (fetchSrc)
+	    {
+		if (fetchMask)
+		{
+		    /* fetch mask before source so that fetching of
+		       source can be optimized */
+		    fetchMask (data->mask, data->xMask, data->yMask + i,
+			       data->width, mask_buffer, 0, 0);
+		    
+		    if (maskClass == SourcePictClassHorizontal)
+			fetchMask = NULL;
+		}
+		
+		if (srcClass == SourcePictClassHorizontal)
+		{
+		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
+			      data->width, src_buffer, 0, 0);
+		    
+		    if (mask_buffer)
+		    {
+			fbCombineInU (mask_buffer, src_buffer, data->width);
+			src_mask_buffer = mask_buffer;
+		    }
+		    else
+			src_mask_buffer = src_buffer;
+		    
+		    fetchSrc = NULL;
+		}
+		else
+		{
+		    fetchSrc (data->src, data->xSrc, data->ySrc + i,
+			      data->width, src_buffer, mask_buffer,
+			      0xff000000);
+		    
+		    if (mask_buffer)
+			composeFunctions.combineMaskU (src_buffer,
+						       mask_buffer,
+						       data->width);
+		    
+		    src_mask_buffer = src_buffer;
+		}
+	    }
+	    else if (fetchMask)
+	    {
+		fetchMask (data->mask, data->xMask, data->yMask + i,
+			   data->width, mask_buffer, 0, 0);
+		
+		fbCombineInU (mask_buffer, src_buffer, data->width);
+		
+		src_mask_buffer = mask_buffer;
+	    }
+	    
+	    if (store)
+	    {
+		/* fill dest into second half of scanline */
+		if (fetchDest)
+		    fetchDest (data->dest, data->xDest, data->yDest + i,
+			       data->width, dest_buffer, 0, 0);
+		
+		/* blend */
+		compose (dest_buffer, src_mask_buffer, data->width);
+		
+		/* write back */
+		store (data->dest, data->xDest, data->yDest + i, data->width,
+		       dest_buffer);
+	    }
+	    else
+	    {
+		/* blend */
+		compose (bits + (data->yDest + i+ yoff) * stride +
+			 data->xDest + xoff,
+			 src_mask_buffer, data->width);
+	    }
+	}
     }
 }
 
@@ -3593,11 +3938,11 @@ fbCompositeGeneral (CARD8	op,
     
     if (pSrc->pDrawable)
         srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
-                    && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
+	    && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
 
     if (pMask && pMask->pDrawable)
 	maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
-                     && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
+	    && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
 
     if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
         op = PictOpSrc;
@@ -3614,7 +3959,7 @@ fbCompositeGeneral (CARD8	op,
 				   yDst,
 				   width,
 				   height))
-	    return;
+	return;
 
     compose_data.op = op;
     compose_data.src = pSrc;
@@ -3675,7 +4020,7 @@ fbCompositeGeneral (CARD8	op,
 	    compose_data.ySrc += compose_data.height;
 	    compose_data.yMask += compose_data.height;
 	    compose_data.yDest += compose_data.height;
-    }
+	}
 	pbox++;
     }
     REGION_UNINIT (pDst->pDrawable->pScreen, &region);
diff --git a/render/picture.c b/render/picture.c
index c30649c..3f64182 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -890,54 +890,22 @@ static unsigned int INTERPOLATE_PIXEL_25
     return x;
 }
 
-static void initGradientColorTable(SourcePictPtr pGradient, int *error)
-{
-    int begin_pos, end_pos;
-    xFixed incr, dpos;
-    int pos, current_stop;
-    PictGradientStopPtr stops = pGradient->linear.stops;
-    int nstops = pGradient->linear.nstops;
-
-    /* The position where the gradient begins and ends */
-    begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
-    end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
-
-    pos = 0; /* The position in the color table. */
-
-    /* Up to first point */
-    while (pos <= begin_pos) {
-        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
-        ++pos;
-    }
-
-    incr =  (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
-    dpos = incr * pos; /* The position in terms of 0-1. */
-
-    current_stop = 0; /* We always interpolate between current and current + 1. */
-
-    /* Gradient area */
-    while (pos < end_pos) {
-        unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
-        unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+		      PictGradientStopPtr stop2,
+		      CARD32	          x)
+{
+     CARD32 current_color, next_color;
+     int	   dist, idist;
 
-        int dist = (int)(256*(dpos - stops[current_stop].x)
-                         / (stops[current_stop+1].x - stops[current_stop].x));
-        int idist = 256 - dist;
+     current_color = xRenderColorToCard32 (stop1->color);
+     next_color    = xRenderColorToCard32 (stop2->color);
 
-        pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+     dist  = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
+     idist = 256 - dist;
 
-        ++pos;
-        dpos += incr;
-
-        if (dpos > stops[current_stop + 1].x)
-            ++current_stop;
-    }
-
-    /* After last point */
-    while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
-        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
-        ++pos;
-    }
+     return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
+					       next_color, dist));
 }
 
 static void initGradient(SourcePictPtr pGradient, int stopCount,
@@ -953,26 +921,30 @@ static void initGradient(SourcePictPtr p
 
     dpos = -1;
     for (i = 0; i < stopCount; ++i) {
-        if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+        if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) {
             *error = BadValue;
             return;
         }
         dpos = stopPoints[i];
     }
 
-    pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
-    if (!pGradient->linear.stops) {
+    pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop));
+    if (!pGradient->gradient.stops) {
         *error = BadAlloc;
         return;
     }
 
-    pGradient->linear.nstops = stopCount;
+    pGradient->gradient.nstops = stopCount;
 
     for (i = 0; i < stopCount; ++i) {
-        pGradient->linear.stops[i].x = stopPoints[i];
-        pGradient->linear.stops[i].color = stopColors[i];
+        pGradient->gradient.stops[i].x = stopPoints[i];
+        pGradient->gradient.stops[i].color = stopColors[i];
     }
-    initGradientColorTable(pGradient, error);
+
+    pGradient->gradient.class	       = SourcePictClassUnknown;
+    pGradient->gradient.stopRange      = 0xffff;
+    pGradient->gradient.colorTable     = NULL;
+    pGradient->gradient.colorTableSize = 0;
 }
 
 static PicturePtr createSourcePicture(void)
@@ -980,9 +952,9 @@ static PicturePtr createSourcePicture(vo
     PicturePtr pPicture;
     pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
     pPicture->pDrawable = 0;
-    pPicture->format = PICT_a8r8g8b8;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
+    pPicture->format = PICT_a8r8g8b8;
     pPicture->devPrivates = 0;
 
     SetPictureToDefaults(pPicture);
@@ -1027,10 +999,6 @@ CreateLinearGradientPicture (Picture pid
         *error = BadAlloc;
         return 0;
     }
-    if (p1->x == p2->x && p1->y == p2->y) {
-        *error = BadValue;
-        return 0;
-    }
 
     pPicture->id = pid;
     pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
@@ -1072,14 +1040,6 @@ CreateRadialGradientPicture (Picture pid
         *error = BadAlloc;
         return 0;
     }
-    {
-        double dx = (double)(inner->x - outer->x);
-        double dy = (double)(inner->y - outer->y);
-        if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
-            *error = BadValue;
-            return 0;
-        }
-    }
 
     pPicture->id = pid;
     pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
@@ -1627,13 +1587,17 @@ FreePicture (pointer	value,
     {
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
-        if (!pPicture->pDrawable) {
-            if (pPicture->pSourcePict) {
-                if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
-                    xfree(pPicture->pSourcePict->linear.stops);
-                xfree(pPicture->pSourcePict);
-            }
-        } else {
+
+	if (pPicture->pSourcePict)
+	{
+	    if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+		xfree(pPicture->pSourcePict->linear.stops);
+
+	    xfree(pPicture->pSourcePict);
+	}
+
+	if (pPicture->pDrawable)
+	{
             ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
             PictureScreenPtr    ps = GetPictureScreen(pScreen);
 	
diff --git a/render/picturestr.h b/render/picturestr.h
index f1617f6..3f3c600 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -68,8 +68,13 @@ typedef struct _PictTransform {
 #define SourcePictTypeRadial 2
 #define SourcePictTypeConical 3
 
+#define SourcePictClassUnknown    0
+#define SourcePictClassHorizontal 1
+#define SourcePictClassVertical   2
+
 typedef struct _PictSolidFill {
     unsigned int type;
+    unsigned int class;
     CARD32 color;
 } PictSolidFill, *PictSolidFillPtr;
 
@@ -80,16 +85,22 @@ typedef struct _PictGradientStop {
 
 typedef struct _PictGradient {
     unsigned int type;
+    unsigned int class;
     int nstops;
     PictGradientStopPtr stops;
-    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    int stopRange;
+    CARD32 *colorTable;
+    int colorTableSize;
 } PictGradient, *PictGradientPtr;
 
 typedef struct _PictLinearGradient {
     unsigned int type;
+    unsigned int class;
     int nstops;
     PictGradientStopPtr stops;
-    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    int stopRange;
+    CARD32 *colorTable;
+    int colorTableSize;
     xPointFixed p1;
     xPointFixed p2;
 } PictLinearGradient, *PictLinearGradientPtr;
@@ -98,7 +109,6 @@ typedef struct _PictRadialGradient {
     unsigned int type;
     int nstops;
     PictGradientStopPtr stops;
-    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
     double fx;
     double fy;
     double dx;
@@ -110,9 +120,12 @@ typedef struct _PictRadialGradient {
 
 typedef struct _PictConicalGradient {
     unsigned int type;
+    unsigned int class;
     int nstops;
     PictGradientStopPtr stops;
-    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    int stopRange;
+    CARD32 *colorTable;
+    int colorTableSize;
     xPointFixed center;
     xFixed angle;
 } PictConicalGradient, *PictConicalGradientPtr;
@@ -624,6 +637,11 @@ Bool
 PictureTransformPoint3d (PictTransformPtr transform,
                          PictVectorPtr	vector);
 
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+		      PictGradientStopPtr stop2,
+		      CARD32	          x);
+
 void RenderExtensionInit (void);
 
 Bool
diff-tree d0e55774e0da641ba85c5173f27f68de27372747 (from e1f0b3e70b696d7ea4cf9e6ed30d751e7fdbc577)
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date:   Thu Apr 19 11:39:53 2007 +0200

    libdri: Make sure the new DRIInfo keepFDOpen member is honoured.

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 35da8a6..355d281 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -473,6 +473,9 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
     pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
     pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
 
+    if (!pDRIEntPriv->keepFDOpen)
+	pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
+
     pDRIEntPriv->refCount++;
 
     return TRUE;
diff-tree e1f0b3e70b696d7ea4cf9e6ed30d751e7fdbc577 (from c6972c893359f8fa7631ae674330f3f4f7010ba0)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Apr 19 12:00:24 2007 +0930

    config: Return errors as negative numbers, device ids as positive numbers.
    Update dbus-api documentation.

diff --git a/config/config.c b/config/config.c
index 4861d9e..9b38faf 100644
--- a/config/config.c
+++ b/config/config.c
@@ -308,12 +308,15 @@ configMessage(DBusConnection *connection
 
         if (ret != BadDrawable && ret != BadAlloc) {
             if (!strlen(dbus_message_get_signature(reply)))
+            {
+                ret = -ret; /* return errors as negative numbers */
                 if (!dbus_message_iter_append_basic(&r_iter, DBUS_TYPE_INT32, &ret)) {
                     ErrorF("[config] couldn't append to iterator\n");
                     dbus_message_unref(reply);
                     dbus_error_free(&error);
                     return DBUS_HANDLER_RESULT_HANDLED;
                 }
+            }
 
             if (!dbus_connection_send(bus, reply, NULL))
                 ErrorF("[config] failed to send reply\n");
diff --git a/config/dbus-api b/config/dbus-api
index cada792..654c22b 100644
--- a/config/dbus-api
+++ b/config/dbus-api
@@ -15,25 +15,23 @@ org.x.config.input:
         Option names beginning with _ are not allowed; they are reserved
         for internal use.
 
-        Returns one int32, which is an X Status, as defined in X.h.  If
-        everything is successful, Success will be returned.  BadMatch will
-        be returned if the options given do not match any device.  BadValue
-        is returned for a malformed message.
+        Returns one signed int32, which is the device id of the new device.
+        If the return value is a negative number, it represents the X
+        Status, as defined in X.h. BadMatch will be returned if the options
+        given do not match any device.  BadValue is returned for a malformed
+        message.  (Example: 8 is new device id 8. -8 is BadMatch.)
 
         Notably, BadAlloc is never returned: the server internally signals
         to D-BUS that the attempt failed for lack of memory.
 
-        The return does not notify the client of which devices were created
-        or modified as a result of this request: clients are encouraged to
-        listen for the XInput DevicePresenceNotify event to monitor changes
-        in the device list.
-
     org.x.config.input.remove:
         Takes one int32 argument, which is the device ID to remove, i.e.:
          i
         is the signature.
-        Same return values as org.x.config.input.add.
+
+        Returns one signed int32 which represents an X status as defined in
+        X.h. See org.x.config.input.add. Error codes are negative numbers.
 
     org.x.config.input.listDevices:
-        Lists the currently active devices.
+        Lists the currently active devices. No argument. 
         Return value is sequence of <id> <name> <id> <name> ...
diff-tree c6972c893359f8fa7631ae674330f3f4f7010ba0 (from 999b681cf3973af4191506e49cde06963b11a774)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Wed Apr 18 12:10:05 2007 +0930

    Change dbus 'listDevices' call to not require an argument.
    Update dbus-api documentation, plug memory leak on dbus reply error.

diff --git a/config/config.c b/config/config.c
index 9828091..4861d9e 100644
--- a/config/config.c
+++ b/config/config.c
@@ -280,11 +280,6 @@ configMessage(DBusConnection *connection
 
     if (strcmp(dbus_message_get_interface(message),
                "org.x.config.input") == 0) {
-        if (!dbus_message_iter_init(message, &iter)) {
-            ErrorF("[config] failed to init iterator\n");
-            dbus_error_free(&error);
-            return DBUS_HANDLER_RESULT_NEED_MEMORY; /* ?? */
-        }
 
         if (!(reply = dbus_message_new_method_return(message))) {
             ErrorF("[config] failed to create the reply message\n");
@@ -292,18 +287,30 @@ configMessage(DBusConnection *connection
             return DBUS_HANDLER_RESULT_NEED_MEMORY;
         }
         dbus_message_iter_init_append(reply, &r_iter);
-        
-        if (strcmp(dbus_message_get_member(message), "add") == 0)
-            ret = configAddDevice(message, &iter, reply, &r_iter, &error);
-        else if (strcmp(dbus_message_get_member(message), "remove") == 0)
-            ret = configRemoveDevice(message, &iter, &error);
-        else if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
-            ret = configListDevices(message, &iter, reply, &r_iter, &error);
-        if (ret != BadDrawable && ret != BadAlloc) {
 
+        /* listDevices doesn't take any arguments */
+        if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
+            ret = configListDevices(message, NULL, reply, &r_iter, &error);
+        else 
+        {
+            if (!dbus_message_iter_init(message, &iter)) {
+                ErrorF("[config] failed to init iterator\n");
+                dbus_message_unref(reply);
+                dbus_error_free(&error);
+                return DBUS_HANDLER_RESULT_NEED_MEMORY; /* ?? */
+            }
+
+            if (strcmp(dbus_message_get_member(message), "add") == 0)
+                ret = configAddDevice(message, &iter, reply, &r_iter, &error);
+            else if (strcmp(dbus_message_get_member(message), "remove") == 0)
+                ret = configRemoveDevice(message, &iter, &error);
+        }
+
+        if (ret != BadDrawable && ret != BadAlloc) {
             if (!strlen(dbus_message_get_signature(reply)))
                 if (!dbus_message_iter_append_basic(&r_iter, DBUS_TYPE_INT32, &ret)) {
                     ErrorF("[config] couldn't append to iterator\n");
+                    dbus_message_unref(reply);
                     dbus_error_free(&error);
                     return DBUS_HANDLER_RESULT_HANDLED;
                 }
diff --git a/config/dbus-api b/config/dbus-api
index 53bb3e4..cada792 100644
--- a/config/dbus-api
+++ b/config/dbus-api
@@ -33,3 +33,7 @@ org.x.config.input:
          i
         is the signature.
         Same return values as org.x.config.input.add.
+
+    org.x.config.input.listDevices:
+        Lists the currently active devices.
+        Return value is sequence of <id> <name> <id> <name> ...
diff-tree 999b681cf3973af4191506e49cde06963b11a774 (from 28bb34eec63bf3c98f38ba7fc044f6419aaa3307)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 18 14:33:27 2007 -0700

    Suppress software cursor removal during rotated shadow buffer drawing.

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e8fafd0..5127c15 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -39,6 +39,7 @@
 #include "xf86Crtc.h"
 #include "xf86Modes.h"
 #include "xf86RandR12.h"
+#include "misprite.h"
 #include "X11/extensions/render.h"
 #define DPMS_SERVER
 #include "X11/extensions/dpms.h"
@@ -279,7 +280,11 @@ xf86RotateRedisplay(ScreenPtr pScreen)
     if (REGION_NOTEMPTY(pScreen, region)) 
     {
 	int		    c;
-	
+
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(7,2,0,0,dummy)
+	/* Disable software cursor removal for this drawing */
+	miSpriteDrawInternal(pScreen, TRUE);
+#endif
 	for (c = 0; c < xf86_config->num_crtc; c++)
 	{
 	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
@@ -304,6 +309,9 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 		REGION_UNINIT (pScreen, &crtc_damage);
 	    }
 	}
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(7,2,0,0,dummy)
+	miSpriteDrawInternal(pScreen, FALSE);
+#endif
 	DamageEmpty(damage);
     }
 }
diff --git a/mi/misprite.c b/mi/misprite.c
index c0560a4..71e6ab0 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -288,7 +288,8 @@ miSpriteGetImage (pDrawable, sx, sy, w, 
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pDrawable->type == DRAWABLE_WINDOW &&
+    if (pScreenPriv->internalDraw == 0 &&
+	pDrawable->type == DRAWABLE_WINDOW &&
         pScreenPriv->isUp &&
 	ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
     {
@@ -318,7 +319,8 @@ miSpriteGetSpans (pDrawable, wMax, ppt, 
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
+    if (pScreenPriv->internalDraw == 0 &&
+	pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
     {
 	DDXPointPtr    	pts;
 	int    		*widths;
@@ -360,7 +362,8 @@ miSpriteSourceValidate (pDrawable, x, y,
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
-    if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
+    if (pScreenPriv->internalDraw == 0 &&
+	pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
 	ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
 		    x, y, width, height))
     {
@@ -386,7 +389,8 @@ miSpriteCopyWindow (WindowPtr pWindow, D
     /*
      * Damage will take care of destination check
      */
-    if (pScreenPriv->isUp &&
+    if (pScreenPriv->internalDraw == 0 &&
+	pScreenPriv->isUp &&
 	RECT_IN_REGION (pScreen, prgnSrc, &pScreenPriv->saved) != rgnOUT)
     {
 	SPRITE_DEBUG (("CopyWindow remove\n"));
@@ -827,3 +831,28 @@ miSpriteComputeSaved (pScreen)
     pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
     pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
 }
+
+/**
+ * Enables internal drawing support, which disables removal of the
+ * cursor when the screen pixmap is sourced from.
+ *
+ * This can be used to allow software cursors to be read by RandR rotation
+ * shadow code.
+ */
+void
+miSpriteDrawInternal(ScreenPtr pScreen, Bool enable)
+{
+    miSpriteScreenPtr   pScreenPriv;
+
+    /* Check that miSprite has been set up this generation */
+    if (miSpriteGeneration != serverGeneration)
+	return;
+
+    pScreenPriv = (miSpriteScreenPtr)
+	pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+    if (enable)
+	pScreenPriv->internalDraw++;
+    else
+	pScreenPriv->internalDraw--;
+}
diff --git a/mi/misprite.h b/mi/misprite.h
index 5173b77..0a1bcc1 100644
--- a/mi/misprite.h
+++ b/mi/misprite.h
@@ -92,3 +92,5 @@ extern Bool miSpriteInitialize(
     miSpriteCursorFuncPtr /*cursorFuncs*/,
     miPointerScreenFuncPtr /*screenFuncs*/
 );
+
+void miSpriteDrawInternal(ScreenPtr pScreen, Bool enable);
diff --git a/mi/mispritest.h b/mi/mispritest.h
index 5075f05..2deaa45 100644
--- a/mi/mispritest.h
+++ b/mi/mispritest.h
@@ -76,6 +76,7 @@ typedef struct {
     WindowPtr	    pCacheWin;		/* window the cursor last seen in */
     Bool	    isInCacheWin;
     Bool	    checkPixels;	/* check colormap collision */
+    int		    internalDraw;
     xColorItem	    colors[2];
     ColormapPtr	    pInstalledMap;
     ColormapPtr	    pColormap;
diff-tree 28bb34eec63bf3c98f38ba7fc044f6419aaa3307 (from 5d8e8a7f4b3226bffd9e4d6d9326688f475b0183)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 18 13:48:28 2007 -0700

    Belatedly bump XORG_VERSION for 7.2.

diff --git a/configure.ac b/configure.ac
index edec92c..872f376 100644
--- a/configure.ac
+++ b/configure.ac
@@ -382,9 +382,9 @@ AC_DEFINE_UNQUOTED(OSNAME, "$OSNAME", 
 DEFAULT_VENDOR_NAME="The X.Org Foundation"
 DEFAULT_VENDOR_NAME_SHORT="X.Org"
 DEFAULT_VERSION_MAJOR=7
-DEFAULT_VERSION_MINOR=1
-DEFAULT_VERSION_PATCH=99
-DEFAULT_VERSION_SNAP=2
+DEFAULT_VERSION_MINOR=2
+DEFAULT_VERSION_PATCH=0
+DEFAULT_VERSION_SNAP=0
 DEFAULT_RELEASE_DATE="21 December 2005"
 DEFAULT_VENDOR_WEB="http://wiki.x.org"
 
diff-tree 5d8e8a7f4b3226bffd9e4d6d9326688f475b0183 (from 53fb42e65c2b2ff58a4a324b7f05cff8a587720a)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 18 13:22:26 2007 -0700

    Remove libminimi build.
    
    It appears to have been a leftover of a previous incarnation of the build
    system that didn't handle miinitext.c well.

diff --git a/configure.ac b/configure.ac
index cb8b435..edec92c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -986,7 +986,6 @@ else
 fi
 CWRAP_LIB='$(top_builddir)/os/libcwrapper.la'
 MI_LIB='$(top_builddir)/mi/libmi.la'
-MINIMI_LIB='$(top_builddir)/mi/libminimi.la'
 MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
 MI_INC='-I$(top_srcdir)/mi'
 FB_LIB='$(top_builddir)/fb/libfb.la'
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 42f75ae..f262f4b 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libminimi.la libmi.la
+noinst_LTLIBRARIES = libmi.la
 
 if XORG
 sdk_HEADERS = mibank.h micmap.h miline.h mipointer.h mi.h mibstore.h \
@@ -8,8 +8,7 @@ endif
 
 AM_CFLAGS = $(DIX_CFLAGS)
 
-# libminimi is for dmx - it has different defines for miinitext.c
-libminimi_la_SOURCES = 	\
+libmi_la_SOURCES = 	\
 	cbrt.c		\
 	mi.h		\
 	miarc.c		\
@@ -70,6 +69,4 @@ libminimi_la_SOURCES = 	\
 	mizerclip.c	\
 	mizerline.c
 
-libmi_la_SOURCES = $(libminimi_la_SOURCES)
-
 INCLUDES = -I$(top_srcdir)/mfb
diff-tree 53fb42e65c2b2ff58a4a324b7f05cff8a587720a (from fc162c6cfa06f0b012743d6d79cef45cf0166229)
Author: Erik Andrén <erik.andren at gmail.com>
Date:   Tue Apr 17 21:34:47 2007 -0700

    Syncmaster 226 monitor needs 60Hz refresh (#10545).
    
    I've managed to solve my own bug (#10545) by applying the following
    patch to the xserver.
    
    Please apply.
    
    <Conspiracy mode on>
    This monitor is "Vista Certified". I wonder if this is a pure coincidence...
    <Conspiracy mode off>
    
    With kind regards
    Erik Andrén
    (cherry picked from commit a63704f14a1d97b9a00fef6fa290e74e51b9732b)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 18e42dd..46cb6c4 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -86,6 +86,11 @@ static Bool quirk_prefer_large_60 (int s
     if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
 	DDC->vendor.prod_id == 44358)
 	return TRUE;
+
+    /* Samsung SyncMaster 226BW */
+    if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+	DDC->vendor.prod_id == 638)
+	return TRUE;
     
     return FALSE;
 }


More information about the xorg-commit mailing list