xserver: Branch 'mpx' - 66 commits

Peter Hutterer whot at kemper.freedesktop.org
Mon Apr 30 03:07:21 EEST 2007


 GL/glx/Makefile.am               |    3 
 GL/glx/glxcontext.h              |    3 
 GL/glx/glxglcore.c               |   13 
 GL/glx/glxscreens.h              |    3 
 GL/glx/indirect_size_get.c       |    2 
 GL/mesa/X/Makefile.am            |    2 
 GL/mesa/main/Makefile.am         |    2 
 GL/mesa/shader/slang/Makefile.am |    1 
 GL/mesa/tnl/Makefile.am          |    2 
 configure.ac                     |    9 
 dix/devices.c                    |   35 
 dix/events.c                     |  441 ++++++++
 fb/fbcompose.c                   | 2087 ++++++++++++++++++++++++++-------------
 fb/fbmmx.c                       |  982 +++++++++++++-----
 fb/fbmmx.h                       |   62 +
 fb/fbpict.c                      | 1048 +++++++++++++++++--
 fb/fbpict.h                      |   12 
 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/xf86Xinput.c   |   44 
 hw/xfree86/common/xf86Xinput.h   |    3 
 hw/xfree86/ddc/edid_modes.c      |  361 ------
 hw/xfree86/dri/dri.c             |  507 ++++++---
 hw/xfree86/dri/dri.h             |   18 
 hw/xfree86/dri/dristruct.h       |   24 
 hw/xfree86/dri/sarea.h           |    5 
 hw/xfree86/loader/loadmod.c      |    2 
 hw/xfree86/modes/xf86Crtc.c      |   78 +
 hw/xfree86/modes/xf86Crtc.h      |   12 
 hw/xfree86/modes/xf86EdidModes.c |   10 
 hw/xfree86/modes/xf86RandR12.c   |    5 
 hw/xfree86/modes/xf86RandR12.h   |    3 
 hw/xfree86/modes/xf86Rename.h    |    9 
 hw/xfree86/modes/xf86Rotate.c    |   20 
 hw/xfree86/os-support/bus/Pci.c  |   14 
 mi/Makefile.am                   |    7 
 miext/cw/cw_ops.c                |   37 
 randr/rrcrtc.c                   |    6 
 randr/rrxinerama.c               |    8 
 render/picture.c                 |  137 --
 render/picturestr.h              |   49 
 58 files changed, 4350 insertions(+), 1782 deletions(-)

New commits:
diff-tree f28eea0647f007c2e2415ecc6fceef46201faad4 (from parents)
Merge: 339b73e710a0920608a3fbcb20b406f0f6c4e0f6 ae04f2cb0a068cdc1e519627bf745de0c9e4a85a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Apr 27 16:34:36 2007 +0930

    Merge branch 'master' into mpx
    
    Conflicts:
    
    	dix/devices.c
    	dix/events.c

diff --cc dix/devices.c
index cf6090d,e227617..a6e1415
@@@ -693,15 -569,16 +715,19 @@@
      int ret = BadMatch;
      devicePresenceNotify ev;
      DeviceIntRec dummyDev;
 +    ScreenPtr screen = screenInfo.screens[0];
+     int deviceid;
  
      DebugF("(dix) removing device %d\n", dev->id);
  
      if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
          return BadImplementation;
  
 +    screen->UndisplayCursor(dev, screen);
 +
+     deviceid = dev->id;
+     DisableDevice(dev);
+ 
      prev = NULL;
      for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
  	next = tmp->next;
diff --cc dix/events.c
index da3f6aa,bc6b6ae..deb2da1
@@@ -107,12 -107,10 +107,16 @@@
  
  ******************************************************************/
  
 +/* 
 + * MPX additions
 + * Copyright 2006 by Peter Hutterer
 + * Author: Peter Hutterer <peter at cs.unisa.edu.au>
 + */
 +
+ /** @file
+  * This file handles event delivery and a big part of the server-side protocol
+  * handling (the parts for input devices).
+  */
  
  #ifdef HAVE_DIX_CONFIG_H
  #include <dix-config.h>
@@@ -230,39 -252,43 +258,38 @@@
      TimeStamp		time;
  } syncEvents;
  
 +#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
 +
 +/** 
 + * True if device owns a cursor, false if device shares a cursor sprite with
 + * another device.
 + */
 +_X_EXPORT Bool
 +DevHasCursor(DeviceIntPtr pDev) 
 +{
 +    return (pDev != inputInfo.pointer && pDev->spriteInfo->spriteOwner);
 +}
 +
  /*
 - * The window trace information is used to avoid having to compute all the
 - * windows between the root and the current pointer window each time a button
 - * or key goes down. The grabs on each of those windows must be checked.
 - * 
 - * @see XYToWindow() for a documentation on how the array is set up.
 + * Return true if a device is a pointer, check is the same as used by XI to
 + * fill the 'use' field.
   */
 -static WindowPtr *spriteTrace = (WindowPtr *)NULL;
 -#define ROOT spriteTrace[0]
 -static int spriteTraceSize = 0;
 -static int spriteTraceGood;
 +_X_EXPORT Bool
 +IsPointerDevice(DeviceIntPtr dev)
 +{
 +    return ((dev->valuator && dev->button) || dev == inputInfo.pointer);
 +}
  
 -/**
 - * DIX sprite information. This is the sprite as seen from the DIX. It does
 - * not represent the actual sprite rendered to the screen.
 - * 
 +/*
 + * Return true if a device is a keyboard, check is the same as used by XI to
 + * fill the 'use' field.
   */
 -static  struct {
 -    CursorPtr	current;
 -    BoxRec	hotLimits;	/* logical constraints of hot spot */
 -    Bool	confined;	/* confined to screen */
 -#if defined(SHAPE) || defined(PANORAMIX)
 -    RegionPtr	hotShape;	/* additional logical shape constraint */
 -#endif
 -    BoxRec	physLimits;	/* physical constraints of hot spot */
 -    WindowPtr	win;		/* window of logical position */
 -    HotSpot	hot;		/* logical pointer position */
 -    HotSpot	hotPhys;	/* physical pointer position */
 -#ifdef PANORAMIX
 -    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
 -    RegionRec   Reg1;	        /* Region 1 for confining motion */
 -    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
 -    WindowPtr   windows[MAXSCREENS];
 -    WindowPtr	confineWin;	/* confine window */ 
 -#endif
 -} sprite;			/* info about the cursor sprite */
 +_X_EXPORT Bool
 +IsKeyboardDevice(DeviceIntPtr dev)
 +{
 +    return ((dev->key && dev->kbdfeed) || dev == inputInfo.keyboard);
 +}
  
- 
  #ifdef XEVIE
  _X_EXPORT WindowPtr xeviewin;
  _X_EXPORT HotSpot xeviehot;
@@@ -885,19 -882,24 +915,26 @@@
  }
  
  _X_EXPORT Bool
 -PointerConfinedToScreen(void)
 +PointerConfinedToScreen(DeviceIntPtr pDev)
  {
 -    return sprite.confined;
 +    return pDev->spriteInfo->sprite->confined;
  }
  
+ /**
+  * Update the sprite cursor to the given cursor.
+  *
+  * ChangeToCursor() will display the new cursor and free the old cursor (if
+  * applicable). If the provided cursor is already the updated cursor, nothing
+  * happens.
+  */
  static void
 -ChangeToCursor(CursorPtr cursor)
 +ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
  {
 +    SpritePtr pSprite = pDev->spriteInfo->sprite;
 +
  #ifdef PANORAMIX
      if(!noPanoramiXExtension) {
 -	XineramaChangeToCursor(cursor);
 +	XineramaChangeToCursor(pDev, cursor);
  	return;
      }
  #endif
@@@ -926,13 -929,16 +965,18 @@@
      return FALSE;
  }
  
+ /**
+  * Update the cursor displayed on the screen.
+  *
+  * Called whenever a cursor may have changed shape or position.  
+  */
  static void
 -PostNewCursor(void)
 +PostNewCursor(DeviceIntPtr pDev)
  {
      WindowPtr win;
 -    GrabPtr grab = inputInfo.pointer->grab;
 +    GrabPtr grab = pDev->coreGrab.grab;
 +    SpritePtr   pSprite = pDev->spriteInfo->sprite;
 +    CursorPtr   pCursor;
  
      if (syncEvents.playingEvents)
  	return;
@@@ -949,52 -955,50 +993,61 @@@
  	    win = grab->window;
      }
      else
 -	win = sprite.win;
 +	win = pSprite->win;
      for (; win; win = win->parent)
 -	if (win->optional && win->optional->cursor != NullCursor)
 -	{
 -	    ChangeToCursor(win->optional->cursor);
 -	    return;
 +    {
 +	if (win->optional) 
 +        {
 +            pCursor = WindowGetDeviceCursor(win, pDev);
 +            if (!pCursor && win->optional->cursor != NullCursor)
 +                pCursor = win->optional->cursor;
 +            if (pCursor)
 +            {
 +                ChangeToCursor(pDev, pCursor);
 +                return;
 +            }
  	}
 +    }
  }
  
 +
  /**
 - * @return root window of current active screen.
 + * @param dev device which you want to know its current root window
 + * @return root window where dev's sprite is located
   */
  _X_EXPORT WindowPtr
 -GetCurrentRootWindow(void)
 +GetCurrentRootWindow(DeviceIntPtr dev)
  {
 -    return ROOT;
 +    return RootWindow(dev);
  }
  
+ /**
+  * @return window underneath the cursor sprite.
+  */
  _X_EXPORT WindowPtr
 -GetSpriteWindow(void)
 +GetSpriteWindow(DeviceIntPtr pDev)
  {
 -    return sprite.win;
 +    return pDev->spriteInfo->sprite->win;
  }
  
+ /**
+  * @return current sprite cursor.
+  */
  _X_EXPORT CursorPtr
 -GetSpriteCursor(void)
 +GetSpriteCursor(DeviceIntPtr pDev)
  {
 -    return sprite.current;
 +    return pDev->spriteInfo->sprite->current;
  }
  
+ /**
+  * Set x/y current sprite position in screen coordinates.
+  */
  _X_EXPORT void
 -GetSpritePosition(int *px, int *py)
 +GetSpritePosition(DeviceIntPtr pDev, int *px, int *py)
  {
 -    *px = sprite.hotPhys.x;
 -    *py = sprite.hotPhys.y;
 +    SpritePtr pSprite = pDev->spriteInfo->sprite;
 +    *px = pSprite->hotPhys.x;
 +    *py = pSprite->hotPhys.y;
  }
  
  #ifdef PANORAMIX
@@@ -1703,9 -1711,26 +1815,26 @@@
      }
  }
  
+ /**
+  * Deliver events to a window. At this point, we do not yet know if the event
+  * actually needs to be delivered. May activate a grab if the event is a
+  * button press.
+  *
+  * More than one event may be delivered at a time. This is the case with
+  * DeviceMotionNotifies which may be followed by DeviceValuator events.
+  * 
+  * @param pWin The window that would get the event.
+  * @param pEvents The events to be delivered.
+  * @param count Number of elements in pEvents.
+  * @param filter Mask based on event type.
+  * @param grab Possible grab on the device that caused the event. 
+  * @param mskidx Mask index, depending on device that caused event.
+  *
+  * @return Number of events delivered to various clients.
+  */
  int
 -DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, 
 -                      Mask filter, GrabPtr grab, int mskidx)
 +DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 +        *pEvents, int count, Mask filter, GrabPtr grab, int mskidx)
  {
      int deliveries = 0, nondeliveries = 0;
      int attempt;
@@@ -1875,9 -1893,16 +2013,17 @@@
      return 2;
  }
  
+ /**
+  * Adjust event fields to comply with the window properties.
+  *
+  * @param xE Event to be modified in place
+  * @param pWin The window to get the information from.
+  * @param child Child window setting for event (if applicable)
+  * @param calcChild If True, calculate the child window.
+  */
  static void
  FixUpEventFromWindow(
 +    DeviceIntPtr pDev,
      xEvent *xE,
      WindowPtr pWin,
      Window child,
@@@ -2062,8 -2111,19 +2236,19 @@@
      return FALSE;
  }
  
+ /**
+  * Traversed from the root window to the window at the position x/y. While
+  * traversing, it sets up the traversal history in the spriteTrace array.
+  * After completing, the spriteTrace history is set in the following way:
+  *   spriteTrace[0] ... root window
+  *   spriteTrace[1] ... top level window that encloses x/y
+  *       ...
+  *   spriteTrace[spriteTraceGood - 1] ... window at x/y
+  *
+  * @returns the window at the given coordinates.
+  */
  static WindowPtr 
 -XYToWindow(int x, int y)
 +XYToWindow(DeviceIntPtr pDev, int x, int y)
  {
      WindowPtr  pWin;
      BoxRec		box;
@@@ -2110,16 -2167,19 +2295,22 @@@
  	else
  	    pWin = pWin->nextSib;
      }
 -    return spriteTrace[spriteTraceGood-1];
 +    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
  }
  
+ /**
+  * Update the sprite coordinates based on the event. Update the cursor
+  * position, then update the event with the new coordinates that may have been
+  * changed. If the window underneath the sprite has changed, change to new
+  * cursor and send enter/leave events.
+  */
 -static Bool
 -CheckMotion(xEvent *xE)
 +Bool
 +CheckMotion(xEvent *xE, DeviceIntPtr pDev)
  {
 -    WindowPtr prevSpriteWin = sprite.win;
 +    WindowPtr prevSpriteWin;
 +    SpritePtr pSprite = pDev->spriteInfo->sprite;
 +        
 +    prevSpriteWin = pSprite->win;
  
  #ifdef PANORAMIX
      if(!noPanoramiXExtension)
@@@ -3456,9 -3458,12 +3721,13 @@@
      return NullWindow;
  }
  
+ /**
+  * Assembles an EnterNotify or LeaveNotify and sends it event to the client. 
+  * The core devices are used to fill in the event fields.
+  */
  static void
  EnterLeaveEvent(
 +    DeviceIntPtr mouse,
      int type,
      int mode,
      int detail,
@@@ -3610,27 -3544,28 +3879,36 @@@
      }
  }
  
+ /**
+  * Send enter notifies to all parent windows up to ancestor.
+  * This function recurses.
+  */
  static void
 -EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
 +EnterNotifies(DeviceIntPtr pDev, 
 +              WindowPtr ancestor, 
 +              WindowPtr child, 
 +              int mode, 
 +              int detail) 
  {
      WindowPtr	parent = child->parent;
  
      if (ancestor == parent)
  	return;
 -    EnterNotifies(ancestor, parent, mode, detail);
 -    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
 -}
 +    EnterNotifies(pDev, ancestor, parent, mode, detail);
 +    EnterLeaveEvent(pDev, EnterNotify, mode, detail, parent,
 +                    child->drawable.id); }
  
+ 
+ /**
+  * Send leave notifies to all parent windows up to ancestor.
+  * This function recurses.
+  */
  static void
 -LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
 +LeaveNotifies(DeviceIntPtr pDev, 
 +              WindowPtr child, 
 +              WindowPtr ancestor, 
 +              int mode, 
 +              int detail)
  {
      WindowPtr  pWin;
  
@@@ -3644,11 -3578,15 +3922,18 @@@
      }
  }
  
+ /**
+  * Figure out if enter/leave events are necessary and send them to the
+  * appropriate windows.
+  * 
+  * @param fromWin Window the sprite moved out of.
+  * @param toWin Window the sprite moved into.
+  */
  static void
 -DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
 +DoEnterLeaveEvents(DeviceIntPtr pDev, 
 +        WindowPtr fromWin, 
 +        WindowPtr toWin, 
 +        int mode) 
  {
      if (fromWin == toWin)
  	return;
@@@ -4447,16 -4402,19 +4816,21 @@@
      }
  }
  
 -void
 +/**
 + * This function is deprecated! It shouldn't be used anymore. It used to free
 + * the spriteTraces, but now they are freed when the SpriteRec is freed.
 + */
 +_X_DEPRECATED void
  CloseDownEvents(void)
  {
 -  xfree(spriteTrace);
 -  spriteTrace = NULL;
 -  spriteTraceSize = 0;
 +
  }
  
+ /**
+  * Server-side protocol handling for SendEvent request.
+  *
+  * Locates the window to send the event to and forwards the event. 
+  */
  int
  ProcSendEvent(ClientPtr client)
  {
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 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;
 }
diff-tree fc162c6cfa06f0b012743d6d79cef45cf0166229 (from c41e3bd713206c0bbd8ab8cef4c83eb7ba7e1c3c)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Apr 16 09:55:58 2007 -0700

    Allow outputs to be explicitly enabled in config, overriding detect.
    
    Option "Enable" "True" will force the server to enable an output at startup
    time, even if the output is not connected. This also causes the default
    modes to be added for this output, allowing even sync ranges to be used to
    pick out standard modes.
    (cherry picked from commit a3d73ba2cb7e13a6d129cd88d6a7f7d756e2ced2)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 87820de..ad0f5ff 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -436,15 +436,29 @@ xf86OutputSetMonitor (xf86OutputPtr outp
 }
 
 static Bool
-xf86OutputEnabled (xf86OutputPtr    output)
+xf86OutputEnabled (xf86OutputPtr output)
 {
-    /* Check to see if this output was disabled in the config file */
-    if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
-	xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
+    Bool    enable, disable;
+
+    /* check to see if this output was enabled in the config file */
+    if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
+    {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s enabled by config file\n", output->name);
+	return TRUE;
+    }
+    /* or if this output was disabled in the config file */
+    if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
     {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s disabled by config file\n", output->name);
 	return FALSE;
     }
-    return TRUE;
+    /* otherwise, enable if it is not disconnected */
+    enable = output->status != XF86OutputStatusDisconnected;
+    xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+    	    "Output %s %sconnected\n", output->name, enable ? "" : "dis");
+    return enable;
 }
 
 static Bool
@@ -1232,7 +1246,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, 
 	 */
 	output->status = (*output->funcs->detect)(output);
 
-	if (output->status == XF86OutputStatusDisconnected)
+	if (!xf86OutputEnabled (output))
 	{
 	    xf86OutputSetEDID (output, NULL);
 	    continue;
@@ -1543,8 +1557,7 @@ xf86InitialConfiguration (ScrnInfoPtr sc
 	xf86OutputPtr output = config->output[o];
 	
 	modes[o] = NULL;
-	enabled[o] = (xf86OutputEnabled (output) &&
-		      output->status != XF86OutputStatusDisconnected);
+	enabled[o] = xf86OutputEnabled (output);
     }
     
     /*
@@ -1589,8 +1602,20 @@ xf86InitialConfiguration (ScrnInfoPtr sc
     {
 	xf86OutputPtr output = config->output[o];
 	
-	if (enabled[o] && !modes[o])
-	    modes[o] = xf86ClosestMode (output, target_mode, target_rotation, width, height);
+	if (enabled[o])
+	{
+	    if (!modes[o])
+		modes[o] = xf86ClosestMode (output, target_mode,
+					    target_rotation, width, height);
+	    if (!modes[o])
+		xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+			    "Output %s enabled but has no modes\n",
+			    output->name);
+	    else
+		xf86DrvMsg (scrn->scrnIndex, X_INFO,
+			    "Output %s using initial mode %s\n",
+			    output->name, modes[o]->name);
+	}
     }
 
     /*
diff-tree c41e3bd713206c0bbd8ab8cef4c83eb7ba7e1c3c (from 97a2c2579c56c304705c934f3b536473645747df)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Apr 16 09:53:42 2007 -0700

    Use default screen monitor for one of the outputs.
    
    By default, use the screen monitor section for output 0, however, a driver
    can change which output gets the screen monitor by calling
    xf86OutputUseScreenMonitor.
    (cherry picked from commit f4a8e54caf6b9431711383a39f55a18e7fd654f4)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 7e7c7e7..87820de 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -414,10 +414,25 @@ xf86OutputSetMonitor (xf86OutputPtr outp
     xfree (option_name);
     output->conf_monitor = xf86findMonitor (monitor,
 					    xf86configptr->conf_monitor_lst);
+    /*
+     * Find the monitor section of the screen and use that
+     */
+    if (!output->conf_monitor && output->use_screen_monitor)
+	output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
+						xf86configptr->conf_monitor_lst);
     if (output->conf_monitor)
+    {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s using monitor section %s\n",
+		    output->name, output->conf_monitor->mon_identifier);
 	xf86ProcessOptions (output->scrn->scrnIndex,
 			    output->conf_monitor->mon_option_lst,
 			    output->options);
+    }
+    else
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s has no monitor section\n",
+		    output->name);
 }
 
 static Bool
@@ -463,7 +478,7 @@ xf86OutputInitialRotation (xf86OutputPtr
 
 xf86OutputPtr
 xf86OutputCreate (ScrnInfoPtr		    scrn,
-		  const xf86OutputFuncsRec *funcs,
+		  const xf86OutputFuncsRec  *funcs,
 		  const char		    *name)
 {
     xf86OutputPtr	output, *outputs;
@@ -486,6 +501,10 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
 	strcpy (output->name, name);
     }
     output->subpixel_order = SubPixelUnknown;
+    /*
+     * Use the old per-screen monitor section for the first output
+     */
+    output->use_screen_monitor = (xf86_config->num_output == 0);
 #ifdef RANDR_12_INTERFACE
     output->randr_output = NULL;
 #endif
@@ -537,6 +556,16 @@ xf86OutputRename (xf86OutputPtr output, 
 }
 
 void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
+{
+    if (use_screen_monitor != output->use_screen_monitor)
+    {
+	output->use_screen_monitor = use_screen_monitor;
+	xf86OutputSetMonitor (output);
+    }
+}
+
+void
 xf86OutputDestroy (xf86OutputPtr output)
 {
     ScrnInfoPtr		scrn = output->scrn;
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 030f6bf..0c019e0 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -479,6 +479,9 @@ struct _xf86Output {
     /** driver private information */
     void		*driver_private;
     
+    /** Whether to use the old per-screen Monitor config section */
+    Bool		use_screen_monitor;
+
 #ifdef RANDR_12_INTERFACE
     /**
      * RandR 1.2 output structure.
@@ -618,9 +621,12 @@ xf86CrtcInUse (xf86CrtcPtr crtc);
  * Output functions
  */
 xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr		scrn,
-		      const xf86OutputFuncsRec *funcs,
-		      const char	*name);
+xf86OutputCreate (ScrnInfoPtr		    scrn,
+		  const xf86OutputFuncsRec  *funcs,
+		  const char		    *name);
+
+void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor);
 
 Bool
 xf86OutputRename (xf86OutputPtr output, const char *name);
diff-tree 97a2c2579c56c304705c934f3b536473645747df (from deda7791dfa34d0563c8d7fa2a0660ac27e6858c)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Apr 16 09:39:47 2007 -0700

    Using wrong log level in extension to built-in message
    
    was: typo in built-in module log message
    (cherry picked from commit 00cfd1f765895b4d1b2234f3203727a8871b64b0)

diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index db12da4..6a1c65e 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -869,7 +869,7 @@ doLoadModule(const char *module, const c
     for (cim = compiled_in_modules; *cim; cim++)
 	if (!strcmp (module, *cim))
 	{
-	    xf86MsgVerb(X_INFO, 3, "Module already built-in\n");
+	    xf86MsgVerb(X_INFO, 0, "Module already built-in\n");
 	    return (ModuleDescPtr) 1;
 	}
 
diff-tree deda7791dfa34d0563c8d7fa2a0660ac27e6858c (from 02d42f344ce020c9b84723671cb9c68d5c064933)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Apr 16 11:35:22 2007 -0600

    remove sources deleted in Mesa

diff --git a/GL/mesa/tnl/Makefile.am b/GL/mesa/tnl/Makefile.am
index 84301d3..b3c8206 100644
--- a/GL/mesa/tnl/Makefile.am
+++ b/GL/mesa/tnl/Makefile.am
@@ -21,8 +21,6 @@ INCLUDES = -I at MESA_SOURCE@/include \
 nodist_libtnl_la_SOURCES = t_context.c \
                       t_draw.c \
                       t_pipeline.c \
-                      t_vb_arbprogram.c \
-                      t_vb_arbprogram_sse.c \
                       t_vb_cull.c \
                       t_vb_fog.c \
                       t_vb_light.c \
diff-tree 02d42f344ce020c9b84723671cb9c68d5c064933 (from b5823ea3e1ed5a0449d44da05165a46719dcf287)
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date:   Mon Apr 16 17:24:53 2007 +0200

    Changes for single-entity multi-screen DRI.
    
    The entity (device) has a locking SAREA and a master file descriptor
    that optionally isn't closed between server generation.
    
    The locking SAREA contains the device hardware lock.
    Each DRI screen creates an new SAREA containing the drawable lock,
    drawable-and private info, the drawable SAREA.
    
    The first screen optionally shares its drawable SAREA with the
    device SAREA.
    
    Default is to close the master descriptor between server generations,
    and to share the drawable SAREA of the first screen with the device locking
    SAREA. Thus we should (hopefully) have full backwards compatibility.
    
    Mesa changes to support single-device multiple screens are pending.

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 7bd07c0..35da8a6 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -43,6 +43,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include <string.h>
 #include <stdio.h>
 #include <sys/ioctl.h>
+#include <errno.h>
 
 #define NEED_REPLIES
 #define NEED_EVENTS
@@ -77,6 +78,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 extern Bool noPanoramiXExtension;
 #endif
 
+static int DRIEntPrivIndex = -1;
 static int DRIScreenPrivIndex = -1;
 static int DRIWindowPrivIndex = -1;
 static unsigned long DRIGeneration = 0;
@@ -112,18 +114,203 @@ DRIDrvMsg(int scrnIndex, MessageType typ
 }
 
 
+static void
+DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
+{
+    if (pDRIEntPriv->pLSAREA != NULL) {
+	drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
+	pDRIEntPriv->pLSAREA = NULL;
+    }
+    if (pDRIEntPriv->hLSAREA != 0) {
+	drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
+    }
+    if (pDRIEntPriv->drmFD >= 0) {
+	drmClose(pDRIEntPriv->drmFD);
+	pDRIEntPriv->drmFD = 0;
+    }
+}
+
+int
+DRIMasterFD(ScrnInfoPtr pScrn)
+{
+    return DRI_ENT_PRIV(pScrn)->drmFD;
+}
+
+void *
+DRIMasterSareaPointer(ScrnInfoPtr pScrn)
+{
+    return DRI_ENT_PRIV(pScrn)->pLSAREA;
+}
+
+drm_handle_t
+DRIMasterSareaHandle(ScrnInfoPtr pScrn)
+{
+    return DRI_ENT_PRIV(pScrn)->hLSAREA;
+}
+
+
+Bool
+DRIOpenDRMMaster(ScrnInfoPtr pScrn,
+		 unsigned long sAreaSize,
+		 const char *busID,
+		 const char *drmDriverName)
+{
+    drmSetVersion saveSv, sv;
+    Bool drmWasAvailable;
+    DRIEntPrivPtr pDRIEntPriv;
+    DRIEntPrivRec tmp;
+    drmVersionPtr drmlibv;
+    int drmlibmajor, drmlibminor;
+    const char *openBusID;
+    int count;
+    int err;
+
+    if (DRIEntPrivIndex == -1)
+	DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
+
+    pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+    if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
+	return TRUE;
+
+    drmWasAvailable = drmAvailable();
+
+    memset(&tmp, 0, sizeof(tmp));
+
+    /* Check the DRM lib version.
+     * drmGetLibVersion was not supported in version 1.0, so check for
+     * symbol first to avoid possible crash or hang.
+     */
+
+    drmlibmajor = 1;
+    drmlibminor = 0;
+    if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
+	drmlibv = drmGetLibVersion(-1);
+	if (drmlibv != NULL) {
+	    drmlibmajor = drmlibv->version_major;
+	    drmlibminor = drmlibv->version_minor;
+	    drmFreeVersion(drmlibv);
+	}
+    }
+
+    /* Check if the libdrm can handle falling back to loading based on name
+     * if a busid string is passed.
+     */
+    openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
+
+    tmp.drmFD = -1;
+    sv.drm_di_major = 1;
+    sv.drm_di_minor = 1;
+    sv.drm_dd_major = -1;
+
+    saveSv = sv;
+    count = 10;
+    while (count--) {
+	tmp.drmFD = drmOpen(drmDriverName, openBusID);
+
+	if (tmp.drmFD < 0) {
+	    DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
+	    goto out_err;
+	}
+
+	err = drmSetInterfaceVersion(tmp.drmFD, &sv);
+
+	if (err != -EPERM)
+	    break;
+
+	sv = saveSv;
+	drmClose(tmp.drmFD);
+	tmp.drmFD = -1;
+	usleep(100000);
+    }
+
+    if (tmp.drmFD <= 0) {
+	DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
+	goto out_err;
+    }
+
+    if (!drmWasAvailable) {
+	DRIDrvMsg(-1, X_INFO,
+		  "[drm] loaded kernel module for \"%s\" driver.\n",
+		  drmDriverName);
+    }
+
+    if (err != 0) {
+	sv.drm_di_major = 1;
+	sv.drm_di_minor = 0;
+    }
+
+    DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
+	      sv.drm_di_major, sv.drm_di_minor);
+
+    if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
+	err = 0;
+    else
+	err = drmSetBusid(tmp.drmFD, busID);
+
+    if (err) {
+	DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
+	goto out_err;
+    }
+
+    /*
+     * Create a lock-containing sarea.
+     */
+
+    if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
+		   DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
+        DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
+	tmp.hLSAREA = 0;
+	goto out_err;
+    }
+
+    if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
+		(drmAddressPtr)(&tmp.pLSAREA)) < 0) {
+        DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
+	tmp.pLSAREA = NULL;
+	goto out_err;
+    }
+
+    memset(tmp.pLSAREA, 0, sAreaSize);
+
+    /*
+     * Reserved contexts are handled by the first opened screen.
+     */
+
+    tmp.resOwner = NULL;
+
+    if (!pDRIEntPriv)
+	pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
+
+    if (!pDRIEntPriv) {
+        DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
+		  "DRM device.\n");
+	goto out_err;
+    }
+    *pDRIEntPriv = tmp;
+    xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
+	pDRIEntPriv;
+
+    DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
+    return TRUE;
+
+  out_err:
+
+    DRIOpenDRMCleanup(&tmp);
+    return FALSE;
+}
+
+
 Bool
 DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
 {
     DRIScreenPrivPtr    pDRIPriv;
     drm_context_t *       reserved;
     int                 reserved_count;
-    int                 i, fd, drmWasAvailable;
+    int                 i;
     Bool                xineramaInCore = FALSE;
-    int                 err = 0;
-    char                *openbusid;
-    drmVersionPtr       drmlibv;
-    int                 drmlibmajor, drmlibminor, drmdimajor, drmdiminor;
+    DRIEntPrivPtr       pDRIEntPriv;
+    ScrnInfoPtr         pScrn = xf86Screens[pScreen->myNum];
 
     if (DRIGeneration != serverGeneration) {
 	if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
@@ -153,47 +340,12 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
 	}
     }
 
-    drmWasAvailable = drmAvailable();
-
-    /* Check the DRM lib version.
-     * drmGetLibVersion was not supported in version 1.0, so check for
-     * symbol first to avoid possible crash or hang.
-     */
-    drmlibmajor = 1;
-    drmlibminor = 0;
-    if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
-	drmlibv = drmGetLibVersion(-1);
-	if (drmlibv != NULL) {
-	    drmlibmajor = drmlibv->version_major;
-	    drmlibminor = drmlibv->version_minor;
-	    drmFreeVersion(drmlibv);
-	}
-    }
-
-    /* Check if the libdrm can handle falling back to loading based on name
-     * if a busid string is passed.
-     */
-    if (drmlibmajor == 1 && drmlibminor >= 2)
-	openbusid = pDRIInfo->busIdString;
-    else
-	openbusid = NULL;
-
-    /* Note that drmOpen will try to load the kernel module, if needed. */
-    fd = drmOpen(pDRIInfo->drmDriverName, openbusid);
-    if (fd < 0) {
-        /* failed to open DRM */
-        pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
-        DRIDrvMsg(pScreen->myNum, X_INFO,
-                  "[drm] drmOpen failed\n");
-        return FALSE;
-    }
+    if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
+			  pDRIInfo->busIdString,
+			  pDRIInfo->drmDriverName))
+	return FALSE;
 
-    if (!drmWasAvailable) {
-       /* drmOpen loaded the kernel module, print a message to say so */
-       DRIDrvMsg(pScreen->myNum, X_INFO,
-                 "[drm] loaded kernel module for \"%s\" driver\n",
-                 pDRIInfo->drmDriverName);
-    }
+    pDRIEntPriv = DRI_ENT_PRIV(pScrn);
 
     pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
     if (!pDRIPriv) {
@@ -202,7 +354,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
     }
 
     pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
-    pDRIPriv->drmFD = fd;
+    pDRIPriv->drmFD = pDRIEntPriv->drmFD;
     pDRIPriv->directRenderingSupport = TRUE;
     pDRIPriv->pDriverInfo = pDRIInfo;
     pDRIPriv->nrWindows = 0;
@@ -214,89 +366,54 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
 
     pDRIPriv->grabbedDRILock = FALSE;
     pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
+    *pDRMFD = pDRIPriv->drmFD;
 
-    if (drmlibmajor == 1 && drmlibminor >= 2) {
-	drmSetVersion sv;
+    if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
 
-	/* Get the interface version, asking for 1.1. */
-	sv.drm_di_major = 1;
-	sv.drm_di_minor = 1;
-	sv.drm_dd_major = -1;
-	err = drmSetInterfaceVersion(pDRIPriv->drmFD, &sv);
-	if (err == 0) {
-	    drmdimajor = sv.drm_di_major;
-	    drmdiminor = sv.drm_di_minor;
-	} else {
-	    /* failure, so set it to 1.0.0. */
-	    drmdimajor = 1;
-	    drmdiminor = 0;
+	if (drmAddMap( pDRIPriv->drmFD,
+		       0,
+		       pDRIPriv->pDriverInfo->SAREASize,
+		       DRM_SHM,
+		       0,
+		       &pDRIPriv->hSAREA) < 0)
+	{
+	    pDRIPriv->directRenderingSupport = FALSE;
+	    pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
+	    drmClose(pDRIPriv->drmFD);
+	    DRIDrvMsg(pScreen->myNum, X_INFO,
+		      "[drm] drmAddMap failed\n");
+	    return FALSE;
 	}
-    }
-    else {
-	/* We can't check the DI DRM interface version, so set it to 1.0.0. */
-	drmdimajor = 1;
-	drmdiminor = 0;
-    }
-    DRIDrvMsg(pScreen->myNum, X_INFO,
-              "[drm] DRM interface version %d.%d\n", drmdimajor, drmdiminor);
-
-    /* If the interface minor number is 1.1, then we've opened a DRM device
-     * that already had the busid set through drmOpen.
-     */
-    if (drmdimajor == 1 && drmdiminor >= 1)
-	err = 0;
-    else
-	err = drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString);
-
-    if (err < 0) {
-	pDRIPriv->directRenderingSupport = FALSE;
-	pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
-	drmClose(pDRIPriv->drmFD);
-        DRIDrvMsg(pScreen->myNum, X_INFO,
-                  "[drm] drmSetBusid failed (%d, %s), %s\n",
-                  pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString, strerror(-err));
-	return FALSE;
-    }
-
-    *pDRMFD = pDRIPriv->drmFD;
-    DRIDrvMsg(pScreen->myNum, X_INFO,
-	      "[drm] created \"%s\" driver at busid \"%s\"\n",
-	      pDRIPriv->pDriverInfo->drmDriverName,
-	      pDRIPriv->pDriverInfo->busIdString);
+	DRIDrvMsg(pScreen->myNum, X_INFO,
+		  "[drm] added %d byte SAREA at %p\n",
+		  pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
 
-    if (drmAddMap( pDRIPriv->drmFD,
-		   0,
-		   pDRIPriv->pDriverInfo->SAREASize,
-		   DRM_SHM,
-		   DRM_CONTAINS_LOCK,
-		   &pDRIPriv->hSAREA) < 0)
-    {
-	pDRIPriv->directRenderingSupport = FALSE;
-	pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
-	drmClose(pDRIPriv->drmFD);
-        DRIDrvMsg(pScreen->myNum, X_INFO,
-                  "[drm] drmAddMap failed\n");
-	return FALSE;
+	/* Backwards compat. */
+	if (drmMap( pDRIPriv->drmFD,
+		    pDRIPriv->hSAREA,
+		    pDRIPriv->pDriverInfo->SAREASize,
+		    (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
+	{
+	    pDRIPriv->directRenderingSupport = FALSE;
+	    pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
+	    drmClose(pDRIPriv->drmFD);
+	    DRIDrvMsg(pScreen->myNum, X_INFO,
+		      "[drm] drmMap failed\n");
+	    return FALSE;
+	}
+	DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
+		  pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+	memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
+    } else {
+	DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
+		  "SAREA also for drawables.\n");
+	pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
+	pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
+	pDRIEntPriv->sAreaGrabbed = TRUE;
     }
-    DRIDrvMsg(pScreen->myNum, X_INFO,
-	      "[drm] added %d byte SAREA at %p\n",
-	      pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
 
-    if (drmMap( pDRIPriv->drmFD,
-		pDRIPriv->hSAREA,
-		pDRIPriv->pDriverInfo->SAREASize,
-		(drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
-    {
-	pDRIPriv->directRenderingSupport = FALSE;
-	pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
-	drmClose(pDRIPriv->drmFD);
-        DRIDrvMsg(pScreen->myNum, X_INFO,
-                  "[drm] drmMap failed\n");
-	return FALSE;
-    }
-    memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
-    DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
-	      pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+    pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
+    pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
 
     if (drmAddMap( pDRIPriv->drmFD,
 		   (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
@@ -316,22 +433,26 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
     DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
 	      pDRIPriv->hFrameBuffer);
 
-				/* Add tags for reserved contexts */
-    if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
-					      &reserved_count))) {
-	int  i;
-	void *tag;
-
-	for (i = 0; i < reserved_count; i++) {
-	    tag = DRICreateContextPrivFromHandle(pScreen,
-						 reserved[i],
-						 DRI_CONTEXT_RESERVED);
-	    drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+    if (pDRIEntPriv->resOwner == NULL) {
+	pDRIEntPriv->resOwner = pScreen;
+
+	/* Add tags for reserved contexts */
+	if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+						  &reserved_count))) {
+	    int  i;
+	    void *tag;
+
+	    for (i = 0; i < reserved_count; i++) {
+		tag = DRICreateContextPrivFromHandle(pScreen,
+						     reserved[i],
+						     DRI_CONTEXT_RESERVED);
+		drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+	    }
+	    drmFreeReservedContextList(reserved);
+	    DRIDrvMsg(pScreen->myNum, X_INFO,
+		      "[drm] added %d reserved context%s for kernel\n",
+		      reserved_count, reserved_count > 1 ? "s" : "");
 	}
-	drmFreeReservedContextList(reserved);
-	DRIDrvMsg(pScreen->myNum, X_INFO,
-		  "[drm] added %d reserved context%s for kernel\n",
-		  reserved_count, reserved_count > 1 ? "s" : "");
     }
 
     /* validate max drawable table entry set by driver */
@@ -349,6 +470,11 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfo
 	pDRIPriv->pSAREA->drawableTable[i].flags = 0;
     }
 
+    pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
+    pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
+
+    pDRIEntPriv->refCount++;
+
     return TRUE;
 }
 
@@ -490,6 +616,9 @@ DRICloseScreen(ScreenPtr pScreen)
     DRIInfoPtr       pDRIInfo;
     drm_context_t *    reserved;
     int              reserved_count;
+    ScrnInfoPtr      pScrn = xf86Screens[pScreen->myNum];
+    DRIEntPrivPtr    pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+    Bool closeMaster;
 
     if (pDRIPriv && pDRIPriv->directRenderingSupport) {
 
@@ -542,38 +671,55 @@ DRICloseScreen(ScreenPtr pScreen)
 	}
 
 				/* Remove tags for reserved contexts */
-	if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+	if (pDRIEntPriv->resOwner == pScreen) {
+	    pDRIEntPriv->resOwner = NULL;
+
+	    if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
 						  &reserved_count))) {
-	    int  i;
+		int  i;
 
-	    for (i = 0; i < reserved_count; i++) {
-		DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
-						       reserved[i]));
+		for (i = 0; i < reserved_count; i++) {
+		    DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
+							   reserved[i]));
+		}
+		drmFreeReservedContextList(reserved);
+		DRIDrvMsg(pScreen->myNum, X_INFO,
+			  "[drm] removed %d reserved context%s for kernel\n",
+			  reserved_count, reserved_count > 1 ? "s" : "");
 	    }
-	    drmFreeReservedContextList(reserved);
-	    DRIDrvMsg(pScreen->myNum, X_INFO,
-		      "[drm] removed %d reserved context%s for kernel\n",
-		      reserved_count, reserved_count > 1 ? "s" : "");
 	}
 
 	/* Make sure signals get unblocked etc. */
 	drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
-	pDRIPriv->lockRefCount = 0;
-	DRIDrvMsg(pScreen->myNum, X_INFO,
-		  "[drm] unmapping %d bytes of SAREA %p at %p\n",
-		  pDRIInfo->SAREASize,
-		  pDRIPriv->hSAREA,
-		  pDRIPriv->pSAREA);
-	if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
-	    DRIDrvMsg(pScreen->myNum, X_ERROR,
-		      "[drm] unable to unmap %d bytes"
-		      " of SAREA %p at %p\n",
+	pDRIPriv->pLockRefCount = NULL;
+	closeMaster = (--pDRIEntPriv->refCount == 0) &&
+	    !pDRIEntPriv->keepFDOpen;
+	if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
+	    DRIDrvMsg(pScreen->myNum, X_INFO,
+		      "[drm] unmapping %d bytes of SAREA %p at %p\n",
 		      pDRIInfo->SAREASize,
 		      pDRIPriv->hSAREA,
 		      pDRIPriv->pSAREA);
+	    if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
+		DRIDrvMsg(pScreen->myNum, X_ERROR,
+			  "[drm] unable to unmap %d bytes"
+			  " of SAREA %p at %p\n",
+			  pDRIInfo->SAREASize,
+			  pDRIPriv->hSAREA,
+			  pDRIPriv->pSAREA);
+	    }
+	} else {
+	    pDRIEntPriv->sAreaGrabbed = FALSE;
 	}
 
-	drmClose(pDRIPriv->drmFD);
+	if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
+	    drmClose(pDRIPriv->drmFD);
+	    if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
+		DRIDrvMsg(pScreen->myNum, X_INFO,
+			  "[drm] Closed DRM master.\n");
+		pDRIEntPriv->drmFD = -1;
+	    }
+	}
 
 	xfree(pDRIPriv);
 	pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
@@ -2001,28 +2147,46 @@ void
 DRILock(ScreenPtr pScreen, int flags)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    if(!pDRIPriv) return;
 
-    if (!pDRIPriv->lockRefCount)
-        DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext, flags);
-    pDRIPriv->lockRefCount++;
+    if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+    if (!*pDRIPriv->pLockRefCount) {
+        DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
+	*pDRIPriv->pLockingContext = pDRIPriv->myContext;
+    } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
+	DRIDrvMsg(pScreen->myNum, X_ERROR,
+		  "[DRI] Locking deadlock.\n"
+		  "\tAlready locked with context %d,\n"
+		  "\ttrying to lock with context %d.\n",
+		  pDRIPriv->pLockingContext,
+		  pDRIPriv->myContext);
+    }
+    (*pDRIPriv->pLockRefCount)++;
 }
 
 void
 DRIUnlock(ScreenPtr pScreen)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    if(!pDRIPriv) return;
 
-    if (pDRIPriv->lockRefCount > 0) {
-        pDRIPriv->lockRefCount--;
-    }
-    else {
-        ErrorF("DRIUnlock called when not locked\n");
+    if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+    if (*pDRIPriv->pLockRefCount > 0) {
+	if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
+	    DRIDrvMsg(pScreen->myNum, X_ERROR,
+		      "[DRI] Unlocking inconsistency:\n"
+		      "\tContext %d trying to unlock lock held by context %d\n",
+		      pDRIPriv->pLockingContext,
+		      pDRIPriv->myContext);
+	}
+	(*pDRIPriv->pLockRefCount)--;
+    } else {
+        DRIDrvMsg(pScreen->myNum, X_ERROR,
+		  "DRIUnlock called when not locked.\n");
         return;
     }
-    if (!pDRIPriv->lockRefCount)
-        DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext);
+    if (! *pDRIPriv->pLockRefCount)
+        DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
 }
 
 void *
diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h
index f65c571..a21338a 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -107,7 +107,7 @@ typedef struct {
  */
 
 #define DRIINFO_MAJOR_VERSION   5
-#define DRIINFO_MINOR_VERSION   1
+#define DRIINFO_MINOR_VERSION   2
 #define DRIINFO_PATCH_VERSION   0
 
 typedef struct {
@@ -176,9 +176,17 @@ typedef struct {
 
     /* New with DRI version 5.1.0 */
     void        (*ClipNotify)(ScreenPtr pScreen, WindowPtr *ppWin, int num);
+
+    /* New with DRI version 5.2.0 */
+    Bool                allocSarea;
+    Bool                keepFDOpen;
 } DRIInfoRec, *DRIInfoPtr;
 
 
+extern Bool DRIOpenDRMMaster(ScrnInfoPtr pScrn, unsigned long sAreaSize,
+			     const char *busID,
+			     const char *drmDriverName);
+
 extern Bool DRIScreenInit(ScreenPtr pScreen,
                           DRIInfoPtr pDRIInfo,
                           int *pDRMFD);
@@ -344,6 +352,14 @@ extern char *DRICreatePCIBusID(pciVideoP
 
 extern int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *));
 extern int drmRemoveSIGIOHandler(int fd);
+extern int DRIMasterFD(ScrnInfoPtr pScrn);
+
+extern void *DRIMasterSareaPointer(ScrnInfoPtr pScrn);
+
+extern drm_handle_t DRIMasterSareaHandle(ScrnInfoPtr pScrn);
+
+
+
 #define _DRI_H_
 
 #endif
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index 9c42ff9..a3bac85 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -73,6 +73,11 @@ struct _DRIContextPrivRec
 #define DRI_SCREEN_PRIV_FROM_INDEX(screenIndex) ((DRIScreenPrivPtr) \
     (screenInfo.screens[screenIndex]->devPrivates[DRIScreenPrivIndex].ptr))
 
+#define DRI_ENT_PRIV(pScrn)  \
+    ((DRIEntPrivIndex < 0) ? \
+     NULL:		     \
+     ((DRIEntPrivPtr)(xf86GetEntityPrivate((pScrn)->entityList[0], \
+					   DRIEntPrivIndex)->ptr)))
 
 typedef struct _DRIScreenPrivRec
 {
@@ -103,6 +108,25 @@ typedef struct _DRIScreenPrivRec
     Bool		wrapped;
     Bool		windowsTouched;
     int			lockRefCount;
+    drm_handle_t        hLSAREA;      /* Handle to SAREA containing lock, for mapping */
+    XF86DRILSAREAPtr    pLSAREA;      /* Mapped pointer to SAREA containing lock */
+    int*                pLockRefCount;
+    int*                pLockingContext;
 } DRIScreenPrivRec, *DRIScreenPrivPtr;
 
+
+typedef struct _DRIEntPrivRec {
+    int drmFD;
+    Bool drmOpened;
+    Bool sAreaGrabbed;
+    drm_handle_t hLSAREA;
+    XF86DRILSAREAPtr pLSAREA;
+    unsigned long sAreaSize;
+    int lockRefCount;
+    int lockingContext;
+    ScreenPtr resOwner;
+    Bool keepFDOpen;
+    int refCount;
+} DRIEntPrivRec, *DRIEntPrivPtr;
+
 #endif /* DRI_STRUCT_H */
diff --git a/hw/xfree86/dri/sarea.h b/hw/xfree86/dri/sarea.h
index a0d6084..1528cc1 100644
--- a/hw/xfree86/dri/sarea.h
+++ b/hw/xfree86/dri/sarea.h
@@ -89,4 +89,9 @@ typedef struct _XF86DRISAREA {
     drm_context_t			dummy_context;
 } XF86DRISAREARec, *XF86DRISAREAPtr;
 
+typedef struct _XF86DRILSAREA  {
+    drmLock                     lock;
+    drmLock                     otherLocks[31];
+} XF86DRILSAREARec, *XF86DRILSAREAPtr;
+
 #endif
diff-tree b5823ea3e1ed5a0449d44da05165a46719dcf287 (from cc4eb1c7ea1bace7ed69cfd80c99d22933282ae1)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Apr 15 22:59:19 2007 -0300

    RandR 1.2 spec says CRTC info contains screen-relative geometry.
    
    Was reporting mode size instead of adjusting for rotation.
    (cherry picked from commit e2e7c47a528447e90cff6cf10d2ce457742ef48d)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 1dfc3bb..c8c2be2 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -518,6 +518,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
     RROutput			*outputs;
     RROutput			*possible;
     int				i, j, k, n;
+    int				width, height;
     
     REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
     crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
@@ -540,8 +541,9 @@ ProcRRGetCrtcInfo (ClientPtr client)
     rep.timestamp = pScrPriv->lastSetTime.milliseconds;
     rep.x = crtc->x;
     rep.y = crtc->y;
-    rep.width = mode ? mode->mode.width : 0;
-    rep.height = mode ? mode->mode.height : 0;
+    RRCrtcGetScanoutSize (crtc, &width, &height);
+    rep.width = width;
+    rep.height = height;
     rep.mode = mode ? mode->mode.id : 0;
     rep.rotation = crtc->rotation;
     rep.rotations = crtc->rotations;
diff-tree cc4eb1c7ea1bace7ed69cfd80c99d22933282ae1 (from eba81a0a01f8a61151d8bf9f3d83bda85ca26e73)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Apr 13 15:04:29 2007 -0300

    Add quirk for Acer AL1706 monitor to force 60hz refresh.
    
    This Acer monitor reports support for 75hz refresh via EDID, and yet when
    that rate is delivered, the monitor does not sync and reports out of range.
    Use the existing 60hz quirk for this monitor.
    (cherry picked from commit 1328a288e9030a472a915077160f090d1afd4126)

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 7a8ec19..18e42dd 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -82,6 +82,11 @@ static Bool quirk_prefer_large_60 (int s
 	DDC->vendor.prod_id == 1516)
 	return TRUE;
     
+    /* Acer AL1706 */
+    if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
+	DDC->vendor.prod_id == 44358)
+	return TRUE;
+    
     return FALSE;
 }
 
diff-tree eba81a0a01f8a61151d8bf9f3d83bda85ca26e73 (from 6b040b79f0e247b6f2da8f7d239443743e96de67)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Apr 14 18:30:09 2007 +0300

    glx: move __glXMesaProvider from GLcore module to glx module.
    
    This treats the GLcore provider similar to DRI provider, using a subset of
    XMesa as the GLcore interface.

diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am
index cd1130d..c4141bc 100644
--- a/GL/glx/Makefile.am
+++ b/GL/glx/Makefile.am
@@ -46,12 +46,13 @@ libglx_la_SOURCES = \
         glxdrawable.h \
         glxext.c \
         glxext.h \
-	glxvisuals.c \
+        glxglcore.c \
         glxscreens.c \
         glxscreens.h \
         glxserver.h \
         glxutil.c \
         glxutil.h \
+        glxvisuals.c \
         indirect_dispatch.c \
         indirect_dispatch.h \
         indirect_dispatch_swap.c \
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
new file mode 100644
index 0000000..ecfa4d7
--- /dev/null
+++ b/GL/glx/glxglcore.c
@@ -0,0 +1,409 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+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 PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin at precisioninsight.com>
+ *   Brian E. Paul <brian at precisioninsight.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <GL/xmesa.h>
+#include <GL/internal/glcore.h>
+#include <glxserver.h>
+#include <glxscreens.h>
+#include <glxdrawable.h>
+#include <glxcontext.h>
+#include <glxutil.h>
+
+#include "glcontextmodes.h"
+#include "os.h"
+
+typedef struct __GLXMESAscreen   __GLXMESAscreen;
+typedef struct __GLXMESAcontext  __GLXMESAcontext;
+typedef struct __GLXMESAdrawable __GLXMESAdrawable;
+
+struct __GLXMESAscreen {
+    __GLXscreen   base;
+    int           index;
+    int		  num_vis;
+    XMesaVisual  *xm_vis;
+};
+
+struct __GLXMESAcontext {
+    __GLXcontext base;
+    XMesaContext xmesa;
+};
+
+struct __GLXMESAdrawable {
+    __GLXdrawable base;
+    XMesaBuffer   xm_buf;
+};
+
+static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid);
+
+
+static void
+__glXMesaDrawableDestroy(__GLXdrawable *base)
+{
+    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
+
+    if (glxPriv->xm_buf != NULL)
+      XMesaDestroyBuffer(glxPriv->xm_buf);
+    xfree(glxPriv);
+}
+
+static GLboolean
+__glXMesaDrawableResize(__GLXdrawable *base)
+{
+    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
+
+    XMesaResizeBuffers(glxPriv->xm_buf);
+
+    return GL_TRUE;
+}
+
+static GLboolean
+__glXMesaDrawableSwapBuffers(__GLXdrawable *base)
+{
+    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
+
+    /* This is terrifying: XMesaSwapBuffers() ends up calling CopyArea
+     * to do the buffer swap, but this assumes that the server holds
+     * the lock and has its context visible.  If another screen uses a
+     * DRI driver, that will have installed the DRI enter/leave server
+     * functions, which lifts the lock during GLX dispatch.  This is
+     * why we need to re-take the lock and swap in the server context
+     * before calling XMesaSwapBuffers() here.  /me shakes head. */
+
+    __glXenterServer();
+
+    XMesaSwapBuffers(glxPriv->xm_buf);
+
+    __glXleaveServer();
+
+    return GL_TRUE;
+}
+
+
+static __GLXdrawable *
+__glXMesaScreenCreateDrawable(__GLXscreen *screen,
+			      DrawablePtr pDraw,
+			      XID drawId,
+			      __GLcontextModes *modes)
+{
+    __GLXMESAdrawable *glxPriv;
+    XMesaVisual xm_vis;
+
+    glxPriv = xalloc(sizeof *glxPriv);
+    if (glxPriv == NULL)
+	return NULL;
+
+    memset(glxPriv, 0, sizeof *glxPriv);
+
+    if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) {
+        xfree(glxPriv);
+	return NULL;
+    }
+
+    glxPriv->base.destroy     = __glXMesaDrawableDestroy;
+    glxPriv->base.resize      = __glXMesaDrawableResize;
+    glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers;
+
+    xm_vis = find_mesa_visual(screen, modes->visualID);
+    if (xm_vis == NULL) {
+	ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
+	       modes->visualID);
+	xfree(glxPriv);
+	return NULL;
+    }
+
+    if (glxPriv->base.type == DRAWABLE_WINDOW) {
+	glxPriv->xm_buf = XMesaCreateWindowBuffer(xm_vis, (WindowPtr)pDraw);
+    } else {
+	glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0);
+    }
+
+    return &glxPriv->base;
+}
+
+static void
+__glXMesaContextDestroy(__GLXcontext *baseContext)
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+
+    XMesaDestroyContext(context->xmesa);
+    __glXContextDestroy(&context->base);
+    xfree(context);
+}
+
+static int
+__glXMesaContextMakeCurrent(__GLXcontext *baseContext)
+
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+    __GLXMESAdrawable *drawPriv = (__GLXMESAdrawable *) context->base.drawPriv;
+    __GLXMESAdrawable *readPriv = (__GLXMESAdrawable *) context->base.readPriv;
+
+    return XMesaMakeCurrent2(context->xmesa,
+			     drawPriv->xm_buf,
+			     readPriv->xm_buf);
+}
+
+static int
+__glXMesaContextLoseCurrent(__GLXcontext *baseContext)
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+
+    return XMesaLoseCurrent(context->xmesa);
+}
+
+static int
+__glXMesaContextCopy(__GLXcontext *baseDst,
+		     __GLXcontext *baseSrc,
+		     unsigned long mask)
+{
+    __GLXMESAcontext *dst = (__GLXMESAcontext *) baseDst;
+    __GLXMESAcontext *src = (__GLXMESAcontext *) baseSrc;
+
+    return XMesaCopyContext(src->xmesa, dst->xmesa, mask);
+}
+
+static int
+__glXMesaContextForceCurrent(__GLXcontext *baseContext)
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+
+    /* GlxSetRenderTables() call for XGL moved in XMesaForceCurrent() */
+
+    return XMesaForceCurrent(context->xmesa);
+}
+
+static __GLXcontext *
+__glXMesaScreenCreateContext(__GLXscreen *screen,
+			     __GLcontextModes *modes,
+			     __GLXcontext *baseShareContext)
+{
+    __GLXMESAcontext *context;
+    __GLXMESAcontext *shareContext = (__GLXMESAcontext *) baseShareContext;
+    XMesaVisual xm_vis;
+    XMesaContext xm_share;
+
+    context = xalloc (sizeof (__GLXMESAcontext));
+    if (context == NULL)
+	return NULL;
+
+    memset(context, 0, sizeof *context);
+
+    context->base.pGlxScreen = screen;
+    context->base.modes      = modes;
+
+    context->base.destroy        = __glXMesaContextDestroy;
+    context->base.makeCurrent    = __glXMesaContextMakeCurrent;
+    context->base.loseCurrent    = __glXMesaContextLoseCurrent;
+    context->base.copy           = __glXMesaContextCopy;
+    context->base.forceCurrent   = __glXMesaContextForceCurrent;
+
+    xm_vis = find_mesa_visual(screen, modes->visualID);
+    if (!xm_vis) {
+	ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
+	       modes->visualID);
+	xfree(context);
+	return NULL;
+    }
+
+    xm_share = shareContext ? shareContext->xmesa : NULL;
+    context->xmesa = XMesaCreateContext(xm_vis, xm_share);
+    if (!context->xmesa) {
+	xfree(context);
+	return NULL;
+    }
+
+    return &context->base;
+}
+
+static void
+__glXMesaScreenDestroy(__GLXscreen *screen)
+{
+    __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
+    int i;
+
+    for (i = 0; i < mesaScreen->num_vis; i++) {
+	if (mesaScreen->xm_vis[i])
+	    XMesaDestroyVisual(mesaScreen->xm_vis[i]);
+    }
+
+    xfree(mesaScreen->xm_vis);
+
+    __glXScreenDestroy(screen);
+
+    xfree(screen);
+}
+
+static XMesaVisual
+find_mesa_visual(__GLXscreen *screen, VisualID vid)
+{
+    __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
+    const __GLcontextModes *modes;
+    unsigned i = 0;
+
+    for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) {
+	if ( modes->visualID == vid ) {
+	    break;
+	}
+
+	i++;
+    }
+
+    return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL;
+}
+
+static void init_screen_visuals(__GLXMESAscreen *screen)
+{
+    ScreenPtr pScreen = screen->base.pScreen;
+    __GLcontextModes *modes;
+    XMesaVisual *pXMesaVisual;
+    int *used;
+    int i, j, size;
+
+    /* Alloc space for the list of XMesa visuals */
+    size = screen->base.numVisuals * sizeof(XMesaVisual);
+    pXMesaVisual = (XMesaVisual *) xalloc(size);
+    memset(pXMesaVisual, 0, size);
+
+    /* FIXME: Change 'used' to be a array of bits (rather than of ints),
+     * FIXME: create a stack array of 8 or 16 bytes.  If 'numVisuals' is less
+     * FIXME: than 64 or 128 the stack array can be used instead of calling
+     * FIXME: __glXMalloc / __glXFree.  If nothing else, convert 'used' to
+     * FIXME: array of bytes instead of ints!
+     */
+    used = (int *) xalloc(pScreen->numVisuals * sizeof(int));
+    memset(used, 0, pScreen->numVisuals * sizeof(int));
+
+    i = 0;
+    for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) {
+	const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
+	const int nplanes = (modes->rgbBits - modes->alphaBits);
+	const VisualPtr pVis = pScreen->visuals;
+
+	for (j = 0; j < pScreen->numVisuals; j++) {
+	    if (pVis[j].class     == vis_class &&
+		pVis[j].nplanes   == nplanes &&
+		pVis[j].redMask   == modes->redMask &&
+		pVis[j].greenMask == modes->greenMask &&
+		pVis[j].blueMask  == modes->blueMask &&
+		!used[j]) {
+
+		/* Create the XMesa visual */
+		pXMesaVisual[i] =
+		    XMesaCreateVisual(pScreen,
+				      &pVis[j],
+				      modes->rgbMode,
+				      (modes->alphaBits > 0),
+				      modes->doubleBufferMode,
+				      modes->stereoMode,
+				      GL_TRUE, /* ximage_flag */
+				      modes->depthBits,
+				      modes->stencilBits,
+				      modes->accumRedBits,
+				      modes->accumGreenBits,
+				      modes->accumBlueBits,
+				      modes->accumAlphaBits,
+				      modes->samples,
+				      modes->level,
+				      modes->visualRating);
+		/* Set the VisualID */
+		modes->visualID = pVis[j].vid;
+
+		/* Mark this visual used */
+		used[j] = 1;
+		break;
+	    }
+	}
+
+	if ( j == pScreen->numVisuals ) {
+	    ErrorF("No matching visual for __GLcontextMode with "
+		   "visual class = %d (%d), nplanes = %u\n",
+		   vis_class, 
+		   modes->visualType,
+		   (modes->rgbBits - modes->alphaBits) );
+	}
+	else if ( modes->visualID == -1 ) {
+	    FatalError( "Matching visual found, but visualID still -1!\n" );
+	}
+
+	i++;
+    }
+
+    xfree(used);
+
+    screen->num_vis = pScreen->numVisuals;
+    screen->xm_vis = pXMesaVisual;
+}
+
+static __GLXscreen *
+__glXMesaScreenProbe(ScreenPtr pScreen)
+{
+    __GLXMESAscreen *screen;
+
+    screen = xalloc(sizeof *screen);
+    if (screen == NULL)
+	return NULL;
+
+    __glXScreenInit(&screen->base, pScreen);
+
+    screen->base.destroy        = __glXMesaScreenDestroy;
+    screen->base.createContext  = __glXMesaScreenCreateContext;
+    screen->base.createDrawable = __glXMesaScreenCreateDrawable;
+    screen->base.pScreen       = pScreen;
+
+    /*
+     * Find the GLX visuals that are supported by this screen and create
+     * XMesa's visuals.
+     */
+    init_screen_visuals(screen);
+
+    return &screen->base;
+}
+
+__GLXprovider __glXMesaProvider = {
+    __glXMesaScreenProbe,
+    "MESA",
+    NULL
+};
+
+__GLXprovider *
+GlxGetMesaProvider (void)
+{
+    return &__glXMesaProvider;
+}
diff --git a/GL/mesa/X/Makefile.am b/GL/mesa/X/Makefile.am
index f8f16c3..ace1181 100644
--- a/GL/mesa/X/Makefile.am
+++ b/GL/mesa/X/Makefile.am
@@ -22,8 +22,6 @@ AM_CFLAGS = \
 	-DXFree86Server \
 	@GLX_DEFINES@
 
-libX_la_SOURCES = xf86glx.c
-
 nodist_libX_la_SOURCES = \
                   xm_api.c \
 		  xm_buffer.c \
diff --git a/GL/mesa/X/xf86glx.c b/GL/mesa/X/xf86glx.c
deleted file mode 100644
index ecfa4d7..0000000
--- a/GL/mesa/X/xf86glx.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-All Rights Reserved.
-
-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 PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- *   Kevin E. Martin <kevin at precisioninsight.com>
- *   Brian E. Paul <brian at precisioninsight.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include <GL/xmesa.h>
-#include <GL/internal/glcore.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxutil.h>
-
-#include "glcontextmodes.h"
-#include "os.h"
-
-typedef struct __GLXMESAscreen   __GLXMESAscreen;
-typedef struct __GLXMESAcontext  __GLXMESAcontext;
-typedef struct __GLXMESAdrawable __GLXMESAdrawable;
-
-struct __GLXMESAscreen {
-    __GLXscreen   base;
-    int           index;
-    int		  num_vis;
-    XMesaVisual  *xm_vis;
-};
-
-struct __GLXMESAcontext {
-    __GLXcontext base;
-    XMesaContext xmesa;
-};
-
-struct __GLXMESAdrawable {
-    __GLXdrawable base;
-    XMesaBuffer   xm_buf;
-};
-
-static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid);
-
-
-static void
-__glXMesaDrawableDestroy(__GLXdrawable *base)
-{
-    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
-
-    if (glxPriv->xm_buf != NULL)
-      XMesaDestroyBuffer(glxPriv->xm_buf);
-    xfree(glxPriv);
-}
-
-static GLboolean
-__glXMesaDrawableResize(__GLXdrawable *base)
-{
-    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
-
-    XMesaResizeBuffers(glxPriv->xm_buf);
-
-    return GL_TRUE;
-}
-
-static GLboolean
-__glXMesaDrawableSwapBuffers(__GLXdrawable *base)
-{
-    __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
-
-    /* This is terrifying: XMesaSwapBuffers() ends up calling CopyArea
-     * to do the buffer swap, but this assumes that the server holds
-     * the lock and has its context visible.  If another screen uses a
-     * DRI driver, that will have installed the DRI enter/leave server
-     * functions, which lifts the lock during GLX dispatch.  This is
-     * why we need to re-take the lock and swap in the server context
-     * before calling XMesaSwapBuffers() here.  /me shakes head. */
-
-    __glXenterServer();
-
-    XMesaSwapBuffers(glxPriv->xm_buf);
-
-    __glXleaveServer();
-
-    return GL_TRUE;
-}
-
-
-static __GLXdrawable *
-__glXMesaScreenCreateDrawable(__GLXscreen *screen,
-			      DrawablePtr pDraw,
-			      XID drawId,
-			      __GLcontextModes *modes)
-{
-    __GLXMESAdrawable *glxPriv;
-    XMesaVisual xm_vis;
-
-    glxPriv = xalloc(sizeof *glxPriv);
-    if (glxPriv == NULL)
-	return NULL;
-
-    memset(glxPriv, 0, sizeof *glxPriv);
-
-    if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) {
-        xfree(glxPriv);
-	return NULL;
-    }
-
-    glxPriv->base.destroy     = __glXMesaDrawableDestroy;
-    glxPriv->base.resize      = __glXMesaDrawableResize;
-    glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers;
-
-    xm_vis = find_mesa_visual(screen, modes->visualID);
-    if (xm_vis == NULL) {
-	ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
-	       modes->visualID);
-	xfree(glxPriv);
-	return NULL;
-    }
-
-    if (glxPriv->base.type == DRAWABLE_WINDOW) {
-	glxPriv->xm_buf = XMesaCreateWindowBuffer(xm_vis, (WindowPtr)pDraw);
-    } else {
-	glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0);
-    }
-
-    return &glxPriv->base;
-}
-
-static void
-__glXMesaContextDestroy(__GLXcontext *baseContext)
-{
-    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
-
-    XMesaDestroyContext(context->xmesa);
-    __glXContextDestroy(&context->base);
-    xfree(context);
-}
-
-static int
-__glXMesaContextMakeCurrent(__GLXcontext *baseContext)
-
-{
-    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
-    __GLXMESAdrawable *drawPriv = (__GLXMESAdrawable *) context->base.drawPriv;
-    __GLXMESAdrawable *readPriv = (__GLXMESAdrawable *) context->base.readPriv;
-
-    return XMesaMakeCurrent2(context->xmesa,
-			     drawPriv->xm_buf,
-			     readPriv->xm_buf);
-}
-
-static int
-__glXMesaContextLoseCurrent(__GLXcontext *baseContext)
-{
-    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
-
-    return XMesaLoseCurrent(context->xmesa);
-}
-
-static int
-__glXMesaContextCopy(__GLXcontext *baseDst,
-		     __GLXcontext *baseSrc,
-		     unsigned long mask)
-{
-    __GLXMESAcontext *dst = (__GLXMESAcontext *) baseDst;
-    __GLXMESAcontext *src = (__GLXMESAcontext *) baseSrc;
-
-    return XMesaCopyContext(src->xmesa, dst->xmesa, mask);
-}
-
-static int
-__glXMesaContextForceCurrent(__GLXcontext *baseContext)
-{
-    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
-
-    /* GlxSetRenderTables() call for XGL moved in XMesaForceCurrent() */
-
-    return XMesaForceCurrent(context->xmesa);
-}
-
-static __GLXcontext *
-__glXMesaScreenCreateContext(__GLXscreen *screen,
-			     __GLcontextModes *modes,
-			     __GLXcontext *baseShareContext)
-{
-    __GLXMESAcontext *context;
-    __GLXMESAcontext *shareContext = (__GLXMESAcontext *) baseShareContext;
-    XMesaVisual xm_vis;
-    XMesaContext xm_share;
-
-    context = xalloc (sizeof (__GLXMESAcontext));
-    if (context == NULL)
-	return NULL;
-
-    memset(context, 0, sizeof *context);
-
-    context->base.pGlxScreen = screen;
-    context->base.modes      = modes;
-
-    context->base.destroy        = __glXMesaContextDestroy;
-    context->base.makeCurrent    = __glXMesaContextMakeCurrent;
-    context->base.loseCurrent    = __glXMesaContextLoseCurrent;
-    context->base.copy           = __glXMesaContextCopy;
-    context->base.forceCurrent   = __glXMesaContextForceCurrent;
-
-    xm_vis = find_mesa_visual(screen, modes->visualID);
-    if (!xm_vis) {
-	ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
-	       modes->visualID);
-	xfree(context);
-	return NULL;
-    }
-
-    xm_share = shareContext ? shareContext->xmesa : NULL;
-    context->xmesa = XMesaCreateContext(xm_vis, xm_share);
-    if (!context->xmesa) {
-	xfree(context);
-	return NULL;
-    }
-
-    return &context->base;
-}
-
-static void
-__glXMesaScreenDestroy(__GLXscreen *screen)
-{
-    __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
-    int i;
-
-    for (i = 0; i < mesaScreen->num_vis; i++) {
-	if (mesaScreen->xm_vis[i])
-	    XMesaDestroyVisual(mesaScreen->xm_vis[i]);
-    }
-
-    xfree(mesaScreen->xm_vis);
-
-    __glXScreenDestroy(screen);
-
-    xfree(screen);
-}
-
-static XMesaVisual
-find_mesa_visual(__GLXscreen *screen, VisualID vid)
-{
-    __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
-    const __GLcontextModes *modes;
-    unsigned i = 0;
-
-    for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) {
-	if ( modes->visualID == vid ) {
-	    break;
-	}
-
-	i++;
-    }
-
-    return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL;
-}
-
-static void init_screen_visuals(__GLXMESAscreen *screen)
-{
-    ScreenPtr pScreen = screen->base.pScreen;
-    __GLcontextModes *modes;
-    XMesaVisual *pXMesaVisual;
-    int *used;
-    int i, j, size;
-
-    /* Alloc space for the list of XMesa visuals */
-    size = screen->base.numVisuals * sizeof(XMesaVisual);
-    pXMesaVisual = (XMesaVisual *) xalloc(size);
-    memset(pXMesaVisual, 0, size);
-
-    /* FIXME: Change 'used' to be a array of bits (rather than of ints),
-     * FIXME: create a stack array of 8 or 16 bytes.  If 'numVisuals' is less
-     * FIXME: than 64 or 128 the stack array can be used instead of calling
-     * FIXME: __glXMalloc / __glXFree.  If nothing else, convert 'used' to
-     * FIXME: array of bytes instead of ints!
-     */
-    used = (int *) xalloc(pScreen->numVisuals * sizeof(int));
-    memset(used, 0, pScreen->numVisuals * sizeof(int));
-
-    i = 0;
-    for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) {
-	const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
-	const int nplanes = (modes->rgbBits - modes->alphaBits);
-	const VisualPtr pVis = pScreen->visuals;
-
-	for (j = 0; j < pScreen->numVisuals; j++) {
-	    if (pVis[j].class     == vis_class &&
-		pVis[j].nplanes   == nplanes &&
-		pVis[j].redMask   == modes->redMask &&
-		pVis[j].greenMask == modes->greenMask &&
-		pVis[j].blueMask  == modes->blueMask &&
-		!used[j]) {
-
-		/* Create the XMesa visual */
-		pXMesaVisual[i] =
-		    XMesaCreateVisual(pScreen,
-				      &pVis[j],
-				      modes->rgbMode,
-				      (modes->alphaBits > 0),
-				      modes->doubleBufferMode,
-				      modes->stereoMode,
-				      GL_TRUE, /* ximage_flag */
-				      modes->depthBits,
-				      modes->stencilBits,
-				      modes->accumRedBits,
-				      modes->accumGreenBits,
-				      modes->accumBlueBits,
-				      modes->accumAlphaBits,
-				      modes->samples,
-				      modes->level,
-				      modes->visualRating);
-		/* Set the VisualID */
-		modes->visualID = pVis[j].vid;
-
-		/* Mark this visual used */
-		used[j] = 1;
-		break;
-	    }
-	}
-
-	if ( j == pScreen->numVisuals ) {
-	    ErrorF("No matching visual for __GLcontextMode with "
-		   "visual class = %d (%d), nplanes = %u\n",
-		   vis_class, 
-		   modes->visualType,
-		   (modes->rgbBits - modes->alphaBits) );
-	}
-	else if ( modes->visualID == -1 ) {
-	    FatalError( "Matching visual found, but visualID still -1!\n" );
-	}
-
-	i++;
-    }
-
-    xfree(used);
-
-    screen->num_vis = pScreen->numVisuals;
-    screen->xm_vis = pXMesaVisual;
-}
-
-static __GLXscreen *
-__glXMesaScreenProbe(ScreenPtr pScreen)
-{
-    __GLXMESAscreen *screen;
-
-    screen = xalloc(sizeof *screen);
-    if (screen == NULL)
-	return NULL;
-
-    __glXScreenInit(&screen->base, pScreen);
-
-    screen->base.destroy        = __glXMesaScreenDestroy;
-    screen->base.createContext  = __glXMesaScreenCreateContext;
-    screen->base.createDrawable = __glXMesaScreenCreateDrawable;
-    screen->base.pScreen       = pScreen;
-
-    /*
-     * Find the GLX visuals that are supported by this screen and create
-     * XMesa's visuals.
-     */
-    init_screen_visuals(screen);
-
-    return &screen->base;
-}
-
-__GLXprovider __glXMesaProvider = {
-    __glXMesaScreenProbe,
-    "MESA",
-    NULL
-};
-
-__GLXprovider *
-GlxGetMesaProvider (void)
-{
-    return &__glXMesaProvider;
-}
diff-tree 6b040b79f0e247b6f2da8f7d239443743e96de67 (from 2c833f60acb3dc358815a99cd295ef7fc695c45d)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Apr 14 18:29:52 2007 +0300

    glx: drop xmesaP.h include from xf86glx.c
    
    The declarations for the xfree86-specific XMesa functions were moved up to
    xmesa.h, requires Mesa as of 2007-04-13.

diff --git a/GL/mesa/X/xf86glx.c b/GL/mesa/X/xf86glx.c
index 6fffdeb..ecfa4d7 100644
--- a/GL/mesa/X/xf86glx.c
+++ b/GL/mesa/X/xf86glx.c
@@ -45,7 +45,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include <glxdrawable.h>
 #include <glxcontext.h>
 #include <glxutil.h>
-#include "xmesaP.h"
 
 #include "glcontextmodes.h"
 #include "os.h"
diff-tree 2c833f60acb3dc358815a99cd295ef7fc695c45d (from 7ccebc50b98ac175fdbdfaab081bcead62e60ee3)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Apr 14 18:29:25 2007 +0300

    glx: drop stray CAPI define.
    
    SI imports/exports were dropped from Mesa.

diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h
index a54e323..eb10ee2 100644
--- a/GL/glx/glxcontext.h
+++ b/GL/glx/glxcontext.h
@@ -40,9 +40,6 @@
 **
 */
 
-/* XXX: should be defined somewhere globally */
-#define CAPI
-
 #include "GL/internal/glcore.h"
 
 typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index a7700f6..bba4557 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -40,9 +40,6 @@
 **
 */
 
-/* XXX: should be defined somewhere globally */
-#define CAPI
-
 #include "GL/internal/glcore.h"
 
 /*
diff-tree 7ccebc50b98ac175fdbdfaab081bcead62e60ee3 (from 33a5d9605e3e282f6aa1921d7321a2a12ef02c42)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Apr 13 13:08:44 2007 +0930

    Documentation for events.c.

diff --git a/dix/events.c b/dix/events.c
index 093a316..bc6b6ae 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -107,6 +107,10 @@ of the copyright holder.
 
 ******************************************************************/
 
+/** @file
+ * This file handles event delivery and a big part of the server-side protocol
+ * handling (the parts for input devices).
+ */
 
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
@@ -168,7 +172,9 @@ static xEvent *xeviexE;
 #include "dixevents.h"
 #include "dixgrabs.h"
 #include "dispatch.h"
-
+/**
+ * Extension events type numbering starts at EXTENSION_EVENT_BASE.
+ */
 #define EXTENSION_EVENT_BASE  64
 
 #define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
@@ -214,6 +220,28 @@ _X_EXPORT CallbackListPtr DeviceEventCal
 Mask DontPropagateMasks[DNPMCOUNT];
 static int DontPropagateRefCnts[DNPMCOUNT];
 
+/**
+ * Main input device struct. 
+ *     inputInfo.pointer 
+ *     is the core pointer. Referred to as "virtual core pointer", "VCP",
+ *     "core pointer" or inputInfo.pointer. There is exactly one core pointer,
+ *     but multiple devices may send core events. If a device generates core
+ *     events, those events will appear to originate from the core pointer.
+ * 
+ *     inputInfo.keyboard
+ *     is the core keyboard ("virtual core keyboard", "VCK", "core keyboard").
+ *     See inputInfo.pointer.
+ * 
+ *     inputInfo.devices
+ *     linked list containing all devices including VCK and VCP. The VCK will
+ *     always be the first entry, the VCP the second entry in the device list.
+ *
+ *     inputInfo.off_devices
+ *     Devices that have not been initialized and are thus turned off.
+ *
+ *     inputInfo.numDevices
+ *     Total number of devices.
+ */
 _X_EXPORT InputInfo inputInfo;
 
 static struct {
@@ -228,12 +256,19 @@ static struct {
  * The window trace information is used to avoid having to compute all the
  * windows between the root and the current pointer window each time a button
  * or key goes down. The grabs on each of those windows must be checked.
+ * 
+ * @see XYToWindow() for a documentation on how the array is set up.
  */
 static WindowPtr *spriteTrace = (WindowPtr *)NULL;
 #define ROOT spriteTrace[0]
 static int spriteTraceSize = 0;
 static int spriteTraceGood;
 
+/**
+ * DIX sprite information. This is the sprite as seen from the DIX. It does
+ * not represent the actual sprite rendered to the screen.
+ * 
+ */
 static  struct {
     CursorPtr	current;
     BoxRec	hotLimits;	/* logical constraints of hot spot */
@@ -270,6 +305,9 @@ static WindowPtr XYToWindow(
     int y
 );
 
+/**
+ * Max event opcode.
+ */
 extern int lastEvent;
 
 static Mask lastEventMask;
@@ -849,6 +887,13 @@ PointerConfinedToScreen(void)
     return sprite.confined;
 }
 
+/**
+ * Update the sprite cursor to the given cursor.
+ *
+ * ChangeToCursor() will display the new cursor and free the old cursor (if
+ * applicable). If the provided cursor is already the updated cursor, nothing
+ * happens.
+ */
 static void
 ChangeToCursor(CursorPtr cursor)
 {
@@ -873,7 +918,9 @@ ChangeToCursor(CursorPtr cursor)
     }
 }
 
-/* returns true if b is a descendent of a */
+/**
+ * @returns true if b is a descendent of a 
+ */
 Bool
 IsParent(WindowPtr a, WindowPtr b)
 {
@@ -882,6 +929,11 @@ IsParent(WindowPtr a, WindowPtr b)
     return FALSE;
 }
 
+/**
+ * Update the cursor displayed on the screen.
+ *
+ * Called whenever a cursor may have changed shape or position.  
+ */
 static void
 PostNewCursor(void)
 {
@@ -912,24 +964,36 @@ PostNewCursor(void)
 	}
 }
 
+/**
+ * @return root window of current active screen.
+ */
 _X_EXPORT WindowPtr
 GetCurrentRootWindow(void)
 {
     return ROOT;
 }
 
+/**
+ * @return window underneath the cursor sprite.
+ */
 _X_EXPORT WindowPtr
 GetSpriteWindow(void)
 {
     return sprite.win;
 }
 
+/**
+ * @return current sprite cursor.
+ */
 _X_EXPORT CursorPtr
 GetSpriteCursor(void)
 {
     return sprite.current;
 }
 
+/**
+ * Set x/y current sprite position in screen coordinates.
+ */
 _X_EXPORT void
 GetSpritePosition(int *px, int *py)
 {
@@ -1231,6 +1295,19 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, 
     ComputeFreezes();
 }
 
+/**
+ * Activate a pointer grab on the given device. A pointer grab will cause all
+ * core pointer events to be delivered to the grabbing client only. Can cause
+ * the cursor to change if a grab cursor is set.
+ * 
+ * As a pointer grab can only be issued on the core devices, mouse is always
+ * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
+ * 
+ * @param mouse The device to grab.
+ * @param grab The grab structure, needs to be setup.
+ * @param autoGrab True if the grab was caused by a button down event and not
+ * explicitely by a client. 
+ */
 void
 ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, 
                     TimeStamp time, Bool autoGrab)
@@ -1259,6 +1336,12 @@ ActivatePointerGrab(DeviceIntPtr mouse, 
     CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
 }
 
+/**
+ * Delete grab on given device, update the sprite.
+ *
+ * As a pointer grab can only be issued on the core devices, mouse is always
+ * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
+ */
 void
 DeactivatePointerGrab(DeviceIntPtr mouse)
 {
@@ -1283,6 +1366,11 @@ DeactivatePointerGrab(DeviceIntPtr mouse
     ComputeFreezes();
 }
 
+/**
+ * Activate a keyboard grab on the given device. 
+ *
+ * Extension devices have ActivateKeyboardGrab() set as their grabbing proc.
+ */
 void
 ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
 {
@@ -1309,6 +1397,9 @@ ActivateKeyboardGrab(DeviceIntPtr keybd,
     CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
 }
 
+/**
+ * Delete keyboard grab for the given device. 
+ */
 void
 DeactivateKeyboardGrab(DeviceIntPtr keybd)
 {
@@ -1441,6 +1532,11 @@ AllowSome(ClientPtr client, TimeStamp ti
     }
 }
 
+/**
+ * Server-side protocol handling for AllowEvents request.
+ *
+ * Release some events from a frozen device. Only applicable for core devices.
+ */
 int
 ProcAllowEvents(ClientPtr client)
 {
@@ -1484,6 +1580,9 @@ ProcAllowEvents(ClientPtr client)
     return Success;
 }
 
+/**
+ * Deactivate grabs from any device that has been grabbed by the client.
+ */
 void
 ReleaseActiveGrabs(ClientPtr client)
 {
@@ -1510,6 +1609,30 @@ ReleaseActiveGrabs(ClientPtr client)
  *            The following procedures deal with delivering events        *
  **************************************************************************/
 
+/**
+ * Deliver the given events to the given client.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ *
+ * TryClientEvents() is the last station before actually writing the events to
+ * the socket. Anything that is not filtered here, will get delivered to the
+ * client. 
+ * An event is only delivered if 
+ *   - mask and filter match up.
+ *   - no other client has a grab on the device that caused the event.
+ * 
+ *
+ * @param client The target client to deliver to.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param mask Event mask as set by the window.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event. 
+ *
+ * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the
+ * client.
+ */
 _X_EXPORT int
 TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, 
                  Mask filter, GrabPtr grab)
@@ -1588,6 +1711,23 @@ TryClientEvents (ClientPtr client, xEven
     }
 }
 
+/**
+ * Deliver events to a window. At this point, we do not yet know if the event
+ * actually needs to be delivered. May activate a grab if the event is a
+ * button press.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ * 
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event. 
+ * @param mskidx Mask index, depending on device that caused event.
+ *
+ * @return Number of events delivered to various clients.
+ */
 int
 DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, 
                       Mask filter, GrabPtr grab, int mskidx)
@@ -1707,6 +1847,15 @@ XineramaTryClientEventsResult(
 }
 #endif
 
+/**
+ * Try to deliver events to the interested parties.
+ *
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param dontClient Don't deliver to the dontClient.
+ */
 int
 MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, 
                            int count, Mask filter, ClientPtr dontClient)
@@ -1744,6 +1893,14 @@ MaybeDeliverEventsToClient(WindowPtr pWi
     return 2;
 }
 
+/**
+ * Adjust event fields to comply with the window properties.
+ *
+ * @param xE Event to be modified in place
+ * @param pWin The window to get the information from.
+ * @param child Child window setting for event (if applicable)
+ * @param calcChild If True, calculate the child window.
+ */
 static void
 FixUpEventFromWindow(
     xEvent *xE,
@@ -1798,6 +1955,22 @@ FixUpEventFromWindow(
     }
 }
 
+/**
+ * Deliver events caused by input devices. Called for all core input events
+ * and XI events. No filtering of events happens before DeliverDeviceEvents(),
+ * it will be called for any event that comes out of the event queue.
+ * 
+ * For all core events, dev is either inputInfo.pointer or inputInfo.keyboard.
+ * For all extension events, dev is the device that caused the event.
+ *
+ * @param pWin Window to deliver event to.
+ * @param xE Events to deliver.
+ * @param grab Possible grab on a device.
+ * @param stopAt Don't recurse up to the root window.
+ * @param dev The device that is responsible for the event.
+ * @param count number of events in xE.
+ *
+ */
 int
 DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, 
                     WindowPtr stopAt, DeviceIntPtr dev, int count)
@@ -1861,7 +2034,19 @@ DeliverDeviceEvents(WindowPtr pWin, xEve
     return 0;
 }
 
-/* not useful for events that propagate up the tree or extension events */
+/**
+ * Deliver event to a window and it's immediate parent. Used for most window
+ * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that
+ * propagate up the tree or extension events 
+ *
+ * In case of a ReparentNotify event, the event will be delivered to the
+ * otherParent as well.
+ *
+ * @param pWin Window to deliver events to.
+ * @param xE Events to deliver.
+ * @param count number of events in xE.
+ * @param otherParent Used for ReparentNotify events.
+ */
 _X_EXPORT int
 DeliverEvents(WindowPtr pWin, xEvent *xE, int count, 
               WindowPtr otherParent)
@@ -1926,6 +2111,17 @@ PointInBorderSize(WindowPtr pWin, int x,
     return FALSE;
 }
 
+/**
+ * Traversed from the root window to the window at the position x/y. While
+ * traversing, it sets up the traversal history in the spriteTrace array.
+ * After completing, the spriteTrace history is set in the following way:
+ *   spriteTrace[0] ... root window
+ *   spriteTrace[1] ... top level window that encloses x/y
+ *       ...
+ *   spriteTrace[spriteTraceGood - 1] ... window at x/y
+ *
+ * @returns the window at the given coordinates.
+ */
 static WindowPtr 
 XYToWindow(int x, int y)
 {
@@ -1974,6 +2170,12 @@ XYToWindow(int x, int y)
     return spriteTrace[spriteTraceGood-1];
 }
 
+/**
+ * Update the sprite coordinates based on the event. Update the cursor
+ * position, then update the event with the new coordinates that may have been
+ * changed. If the window underneath the sprite has changed, change to new
+ * cursor and send enter/leave events.
+ */
 static Bool
 CheckMotion(xEvent *xE)
 {
@@ -2046,6 +2248,10 @@ CheckMotion(xEvent *xE)
     return TRUE;
 }
 
+/**
+ * Windows have restructured, we need to update the sprite position and the
+ * sprite's cursor.
+ */
 _X_EXPORT void
 WindowsRestructured(void)
 {
@@ -2091,6 +2297,10 @@ void ReinitializeRootWindow(WindowPtr wi
 }
 #endif
 
+/**
+ * Set the given window to sane values, display the cursor in the center of
+ * the screen. Called from main() with the root window on the first screen.
+ */
 void
 DefineInitialRootWindow(WindowPtr win)
 {
@@ -2297,6 +2507,10 @@ XineramaWarpPointer(ClientPtr client)
 #endif
 
 
+/**
+ * Server-side protocol handling for WarpPointer request.
+ * Warps the cursor position to the coordinates given in the request.
+ */
 int
 ProcWarpPointer(ClientPtr client)
 {
@@ -2405,8 +2619,15 @@ BorderSizeNotEmpty(WindowPtr pWin)
      return FALSE;
 }
 
-/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
-	passive grab set on the window to be activated. */
+/** 
+ * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ * passive grab set on the window to be activated. 
+ * 
+ * @param pWin The window that may be subject to a passive grab.
+ * @param device Device that caused the event.
+ * @param xE List of events (multiple ones for DeviceMotionNotify)
+ * @count number of elements in xE.
+ */
 
 static Bool
 CheckPassiveGrabsOnWindow(
@@ -2556,6 +2777,16 @@ CheckDeviceGrabs(DeviceIntPtr device, xE
     return FALSE;
 }
 
+/**
+ * Called for keyboard events to deliver event to whatever client owns the
+ * focus. Event is delivered to the keyboard's focus window, the root window
+ * or to the window owning the input focus.
+ *
+ * @param keybd The keyboard originating the event.
+ * @param xE The event list.
+ * @param window Window underneath the sprite.
+ * @param count number of events in xE.
+ */
 void
 DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
 {
@@ -2584,6 +2815,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, 
 				NullGrab, mskidx);
 }
 
+/**
+ * Deliver an event from a device that is currently grabbed. Uses
+ * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the
+ * grab. If not, TryClientEvents() is used.
+ *
+ * @param deactivateGrab True if the device's grab should be deactivated.
+ */
 void
 DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, 
                     Bool deactivateGrab, int count)
@@ -2666,6 +2904,17 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIn
 	}
 }
 
+/**
+ * Main keyboard event processing function for core keyboard events. 
+ * Updates the events fields from the current pointer state and delivers the
+ * event.
+ *
+ * For key events, xE will always be a single event.
+ *
+ * @param xE Event list
+ * @param keybd The device that caused an event.
+ * @param count Number of elements in xE.
+ */
 void
 #ifdef XKB
 CoreProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count)
@@ -2861,6 +3110,18 @@ FixKeyState (xEvent *xE, DeviceIntPtr ke
 }
 #endif
 
+/** 
+ * Main pointer event processing function for core pointer events. 
+ * For motion events: update the sprite.
+ * For all other events: Update the event fields based on the current sprite
+ * state.
+ *
+ * For core pointer events, xE will always be a single event.
+ *
+ * @param xE Event list
+ * @param mouse The device that caused an event.
+ * @param count Number of elements in xE.
+ */
 void
 #ifdef XKB
 CoreProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
@@ -2974,6 +3235,18 @@ ProcessPointerEvent (xEvent *xE, DeviceI
 #define AtMostOneClient \
 	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
 
+/**
+ * Recalculate which events may be deliverable for the given window.
+ * Recalculated mask is used for quicker determination which events may be
+ * delivered to a window.
+ *
+ * The otherEventMasks on a WindowOptional is the combination of all event
+ * masks set by all clients on the window.
+ * deliverableEventMask is the combination of the eventMask and the
+ * otherEventMask.
+ *
+ * Traverses to siblings and parents of the window.
+ */
 void
 RecalculateDeliverableEvents(pWin)
     WindowPtr pWin;
@@ -3172,6 +3445,9 @@ EventSuppressForWindow(WindowPtr pWin, C
     return Success;
 }
 
+/**
+ * @return The window that is the first ancestor of both a and b.
+ */
 static WindowPtr 
 CommonAncestor(
     WindowPtr a,
@@ -3182,6 +3458,10 @@ CommonAncestor(
     return NullWindow;
 }
 
+/**
+ * Assembles an EnterNotify or LeaveNotify and sends it event to the client. 
+ * The core devices are used to fill in the event fields.
+ */
 static void
 EnterLeaveEvent(
     int type,
@@ -3264,6 +3544,10 @@ EnterLeaveEvent(
     }
 }
 
+/**
+ * Send enter notifies to all parent windows up to ancestor.
+ * This function recurses.
+ */
 static void
 EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
 {
@@ -3275,6 +3559,11 @@ EnterNotifies(WindowPtr ancestor, Window
     EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
 }
 
+
+/**
+ * Send leave notifies to all parent windows up to ancestor.
+ * This function recurses.
+ */
 static void
 LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
 {
@@ -3289,6 +3578,13 @@ LeaveNotifies(WindowPtr child, WindowPtr
     }
 }
 
+/**
+ * Figure out if enter/leave events are necessary and send them to the
+ * appropriate windows.
+ * 
+ * @param fromWin Window the sprite moved out of.
+ * @param toWin Window the sprite moved into.
+ */
 static void
 DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
 {
@@ -3522,6 +3818,23 @@ DoFocusEvents(DeviceIntPtr dev, WindowPt
     }
 }
 
+/**
+ * Set the input focus to the given window. Subsequent keyboard events will be
+ * delivered to the given window.
+ * 
+ * Usually called from ProcSetInputFocus as result of a client request. If so,
+ * the device is the inputInfo.keyboard.
+ * If called from ProcXSetInputFocus as result of a client xinput request, the
+ * device is set to the device specified by the client.
+ *
+ * @param client Client that requested input focus change.
+ * @param dev Focus device. 
+ * @param focusID The window to obtain the focus. Can be PointerRoot or None.
+ * @param revertTo Specifies where the focus reverts to when window becomes
+ * unviewable.
+ * @param ctime Specifies the time.
+ * @param followOK True if pointer is allowed to follow the keyboard.
+ */
 int
 SetInputFocus(
     ClientPtr client,
@@ -3598,6 +3911,11 @@ SetInputFocus(
     return Success;
 }
 
+/**
+ * Server-side protocol handling for SetInputFocus request.
+ *
+ * Sets the input focus for the virtual core keyboard.
+ */
 int
 ProcSetInputFocus(client)
     ClientPtr client;
@@ -3613,6 +3931,12 @@ ProcSetInputFocus(client)
 			 stuff->revertTo, stuff->time, FALSE);
 }
 
+/**
+ * Server-side protocol handling for GetInputFocus request.
+ * 
+ * Sends the current input focus for the virtual core keyboard back to the
+ * client.
+ */
 int
 ProcGetInputFocus(ClientPtr client)
 {
@@ -3634,6 +3958,12 @@ ProcGetInputFocus(ClientPtr client)
     return Success;
 }
 
+/**
+ * Server-side protocol handling for Grabpointer request.
+ *
+ * Sets an active grab on the inputInfo.pointer and returns success status to
+ * client.
+ */
 int
 ProcGrabPointer(ClientPtr client)
 {
@@ -3741,6 +4071,14 @@ ProcGrabPointer(ClientPtr client)
     return Success;
 }
 
+/**
+ * Server-side protocol handling for ChangeActivePointerGrab request.
+ *
+ * Changes properties of the grab hold by the client. If the client does not
+ * hold an active grab on the device, nothing happens. 
+ *
+ * Works on the core pointer only.
+ */
 int
 ProcChangeActivePointerGrab(ClientPtr client)
 {
@@ -3787,6 +4125,11 @@ ProcChangeActivePointerGrab(ClientPtr cl
     return Success;
 }
 
+/**
+ * Server-side protocol handling for UngrabPointer request.
+ *
+ * Deletes the pointer grab on the core pointer device.
+ */
 int
 ProcUngrabPointer(ClientPtr client)
 {
@@ -3806,6 +4149,24 @@ ProcUngrabPointer(ClientPtr client)
     return Success;
 }
 
+/**
+ * Sets a grab on the given device.
+ * 
+ * Called from ProcGrabKeyboard to work on the inputInfo.keyboard.
+ * Called from ProcXGrabDevice to work on the device specified by the client.
+ * 
+ * The parameters this_mode and other_mode represent the keyboard_mode and
+ * pointer_mode parameters of XGrabKeyboard(). 
+ * See man page for details on all the parameters
+ * 
+ * @param client Client that owns the grab.
+ * @param dev The device to grab. 
+ * @param this_mode GrabModeSync or GrabModeAsync
+ * @param other_mode GrabModeSync or GrabModeAsync
+ * @param status Return code to be returned to the caller.
+ * 
+ * @returns Success or BadValue.
+ */
 int
 GrabDevice(ClientPtr client, DeviceIntPtr dev, 
            unsigned this_mode, unsigned other_mode, Window grabWindow, 
@@ -3864,6 +4225,11 @@ GrabDevice(ClientPtr client, DeviceIntPt
     return Success;
 }
 
+/**
+ * Server-side protocol handling for GrabKeyboard request.
+ *
+ * Grabs the inputInfo.keyboad and returns success status to client.
+ */
 int
 ProcGrabKeyboard(ClientPtr client)
 {
@@ -3892,6 +4258,11 @@ ProcGrabKeyboard(ClientPtr client)
     return Success;
 }
 
+/**
+ * Server-side protocol handling for UngrabKeyboard request.
+ *
+ * Deletes a possible grab on the inputInfo.keyboard.
+ */
 int
 ProcUngrabKeyboard(ClientPtr client)
 {
@@ -3911,6 +4282,11 @@ ProcUngrabKeyboard(ClientPtr client)
     return Success;
 }
 
+/**
+ * Server-side protocol handling for QueryPointer request.
+ *
+ * Returns the current state and position of the core pointer to the client. 
+ */
 int
 ProcQueryPointer(ClientPtr client)
 {
@@ -3969,6 +4345,10 @@ ProcQueryPointer(ClientPtr client)
     return(Success);    
 }
 
+/**
+ * Initializes the device list and the DIX sprite to sane values. Allocates
+ * trace memory used for quick window traversal.
+ */
 void
 InitEvents(void)
 {
@@ -4030,6 +4410,11 @@ CloseDownEvents(void)
   spriteTraceSize = 0;
 }
 
+/**
+ * Server-side protocol handling for SendEvent request.
+ *
+ * Locates the window to send the event to and forwards the event. 
+ */
 int
 ProcSendEvent(ClientPtr client)
 {
@@ -4117,6 +4502,12 @@ ProcSendEvent(ClientPtr client)
     return Success;
 }
 
+/**
+ * Server-side protocol handling for UngrabKey request.
+ *
+ * Deletes a passive grab for the given key. Only works on the
+ * inputInfo.keyboard.
+ */
 int
 ProcUngrabKey(ClientPtr client)
 {
@@ -4159,6 +4550,12 @@ ProcUngrabKey(ClientPtr client)
     return(Success);
 }
 
+/**
+ * Server-side protocol handling for GrabKey request.
+ *
+ * Creates a grab for the inputInfo.keyboard and adds it to the list of
+ * passive grabs. 
+ */
 int
 ProcGrabKey(ClientPtr client)
 {
@@ -4214,6 +4611,12 @@ ProcGrabKey(ClientPtr client)
 }
 
 
+/**
+ * Server-side protocol handling for GrabButton request.
+ *
+ * Creates a grab for the inputInfo.pointer and adds it as a passive grab to
+ * the list.
+ */
 int
 ProcGrabButton(ClientPtr client)
 {
@@ -4287,6 +4690,11 @@ ProcGrabButton(ClientPtr client)
     return AddPassiveGrabToList(grab);
 }
 
+/**
+ * Server-side protocol handling for UngrabButton request.
+ *
+ * Deletes a passive grab on the inputInfo.pointer from the list.
+ */
 int
 ProcUngrabButton(ClientPtr client)
 {
@@ -4320,6 +4728,17 @@ ProcUngrabButton(ClientPtr client)
     return(Success);
 }
 
+/**
+ * Deactivate any grab that may be on the window, remove the focus.
+ * Delete any XInput extension events from the window too. Does not change the
+ * window mask. Use just before the window is deleted.
+ *
+ * If freeResources is set, passive grabs on the window are deleted.
+ *
+ * @param pWin The window to delete events from.
+ * @param freeResources True if resources associated with the window should be
+ * deleted.
+ */
 void
 DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
 {
@@ -4409,7 +4828,9 @@ DeleteWindowFromAnyEvents(WindowPtr pWin
 }
 
 /**
- * Call this whenever some window at or below pWin has changed geometry 
+ * Call this whenever some window at or below pWin has changed geometry. If
+ * there is a grab on the window, the cursor will be re-confined into the
+ * window.
  */
 _X_EXPORT void
 CheckCursorConfinement(WindowPtr pWin)
@@ -4445,6 +4866,9 @@ EventMaskForClient(WindowPtr pWin, Clien
     return 0;
 }
 
+/**
+ * Server-side protocol handling for RecolorCursor request.
+ */
 int
 ProcRecolorCursor(ClientPtr client)
 {
@@ -4486,6 +4910,20 @@ ProcRecolorCursor(ClientPtr client)
     return (Success);
 }
 
+/**
+ * Write the given events to a client, swapping the byte order if necessary.
+ * To swap the byte ordering, a callback is called that has to be set up for
+ * the given event type.
+ *
+ * In the case of DeviceMotionNotify trailed by DeviceValuators, the events
+ * can be more than one. Usually it's just one event. 
+ *
+ * Do not modify the event structure passed in. See comment below.
+ * 
+ * @param pClient Client to send events to.
+ * @param count Number of events.
+ * @param events The event list.
+ */
 _X_EXPORT void
 WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
 {



More information about the xorg-commit mailing list