From eaedc21febeadad4cf0e370f5d97e7bdb4470870 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Tue, 5 Apr 2011 09:51:44 +0000
Subject: xserver xkeyboard-config libxcb xkbcomp mesa git update 5 Apr 2011

---
 xorg-server/dix/colormap.c     | 5540 ++++++++++++++++++++--------------------
 xorg-server/dix/dixfonts.c     |   18 +-
 xorg-server/dix/eventconvert.c | 1537 ++++++-----
 xorg-server/dix/extension.c    |  721 +++---
 4 files changed, 3901 insertions(+), 3915 deletions(-)

(limited to 'xorg-server/dix')

diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c
index b04739ad0..0e1feb6c4 100644
--- a/xorg-server/dix/colormap.c
+++ b/xorg-server/dix/colormap.c
@@ -1,2769 +1,2771 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include "misc.h"
-#include "dix.h"
-#include "dixstruct.h"
-#include "colormapst.h"
-#include "os.h"
-#include "scrnintstr.h"
-#include "resource.h"
-#include "windowstr.h"
-#include "privates.h"
-#include "xace.h"
-
-static Pixel FindBestPixel(
-    EntryPtr /*pentFirst*/,
-    int /*size*/,
-    xrgb * /*prgb*/,
-    int /*channel*/
-);
-
-static int AllComp(
-    EntryPtr /*pent*/,
-    xrgb * /*prgb*/
-);
-
-static int RedComp(
-    EntryPtr /*pent*/,
-    xrgb * /*prgb*/
-);
-
-static int GreenComp(
-    EntryPtr /*pent*/,
-    xrgb * /*prgb*/
-);
-
-static int BlueComp(
-    EntryPtr /*pent*/,
-    xrgb * /*prgb*/
-);
-
-static void FreePixels(
-    ColormapPtr /*pmap*/,
-    int /*client*/
-);
-
-static void CopyFree(
-    int /*channel*/,
-    int /*client*/,
-    ColormapPtr /*pmapSrc*/,
-    ColormapPtr /*pmapDst*/
-);
-
-static void FreeCell(
-    ColormapPtr /*pmap*/,
-    Pixel /*i*/,
-    int /*channel*/
-);
-
-static void UpdateColors(
-    ColormapPtr /*pmap*/
-);
-
-static int AllocDirect(
-    int /*client*/,
-    ColormapPtr /*pmap*/,
-    int /*c*/,
-    int /*r*/,
-    int /*g*/,
-    int /*b*/,
-    Bool /*contig*/,
-    Pixel * /*pixels*/,
-    Pixel * /*prmask*/,
-    Pixel * /*pgmask*/,
-    Pixel * /*pbmask*/
-);
-
-static int AllocPseudo(
-    int /*client*/,
-    ColormapPtr /*pmap*/,
-    int /*c*/,
-    int /*r*/,
-    Bool /*contig*/,
-    Pixel * /*pixels*/,
-    Pixel * /*pmask*/,
-    Pixel ** /*pppixFirst*/
-);
-
-static Bool AllocCP(
-    ColormapPtr /*pmap*/,
-    EntryPtr /*pentFirst*/,
-    int /*count*/,
-    int /*planes*/,
-    Bool /*contig*/,
-    Pixel * /*pixels*/,
-    Pixel * /*pMask*/
-);
-
-static Bool AllocShared(
-    ColormapPtr /*pmap*/,
-    Pixel * /*ppix*/,
-    int /*c*/,
-    int /*r*/,
-    int /*g*/,
-    int /*b*/,
-    Pixel /*rmask*/,
-    Pixel /*gmask*/,
-    Pixel /*bmask*/,
-    Pixel * /*ppixFirst*/
-);
-
-static int FreeCo(
-    ColormapPtr /*pmap*/,
-    int /*client*/,
-    int /*color*/,
-    int /*npixIn*/,
-    Pixel * /*ppixIn*/,
-    Pixel /*mask*/
-);
-
-static int   TellNoMap(
-    WindowPtr	/*pwin*/,
-    Colormap 	* /*pmid*/
-);
-
-static void FindColorInRootCmap (
-    ColormapPtr	/* pmap */,
-    EntryPtr	/* pentFirst */,
-    int		/* size */,
-    xrgb*	/* prgb */,
-    Pixel*	/* pPixel */,
-    int		/* channel */,
-    ColorCompareProcPtr /* comp */
-);
-
-#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
-#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
-#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
-#if COMPOSITE
-#define ALPHAMASK(vis)	((vis)->nplanes < 32 ? 0 : \
-			 (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
-#else
-#define ALPHAMASK(vis)	0
-#endif
-
-#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
-
-/* GetNextBitsOrBreak(bits, mask, base)  -- 
- * (Suggestion: First read the macro, then read this explanation.
- *
- * Either generate the next value to OR in to a pixel or break out of this
- * while loop 
- *
- * This macro is used when we're trying to generate all 2^n combinations of
- * bits in mask.  What we're doing here is counting in binary, except that
- * the bits we use to count may not be contiguous.  This macro will be
- * called 2^n times, returning a different value in bits each time. Then
- * it will cause us to break out of a surrounding loop. (It will always be
- * called from within a while loop.)
- * On call: mask is the value we want to find all the combinations for
- * base has 1 bit set where the least significant bit of mask is set
- *
- * For example,if mask is 01010, base should be 0010 and we count like this:
- * 00010 (see this isn't so hard), 
- *     then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
- *      we add that to bits getting (0100 + 0100) =
- * 01000 for our next value.
- *      then we add 0010 to get 
- * 01010 and we're done (easy as 1, 2, 3)
- */
-#define GetNextBitsOrBreak(bits, mask, base)	\
-	    if((bits) == (mask)) 		\
-		break;		 		\
-	    (bits) += (base);		 	\
-	    while((bits) & ~(mask))		\
-		(bits) += ((bits) & ~(mask));	
-/* ID of server as client */
-#define SERVER_ID	0
-
-typedef struct _colorResource
-{
-	Colormap	mid;
-	int		client;
-} colorResource;
-
-/* Invariants:
- * refcnt == 0 means entry is empty
- * refcnt > 0 means entry is useable by many clients, so it can't be changed
- * refcnt == AllocPrivate means entry owned by one client only
- * fShared should only be set if refcnt == AllocPrivate, and only in red map
- */
-
-
-/** 
- * Create and initialize the color map 
- * 
- * \param mid    resource to use for this colormap
- * \param alloc  1 iff all entries are allocated writable
- */
-int
-CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, 
-                ColormapPtr *ppcmap, int alloc, int client)
-{
-    int		class, size;
-    unsigned long sizebytes;
-    ColormapPtr	pmap;
-    EntryPtr	pent;
-    int		i;
-    Pixel	*ppix, **pptr;
-
-    class = pVisual->class;
-    if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
-	return BadMatch;
-
-    size = pVisual->ColormapEntries;
-    sizebytes = (size * sizeof(Entry)) +
-		(MAXCLIENTS * sizeof(Pixel *)) +
-		(MAXCLIENTS * sizeof(int));
-    if ((class | DynamicClass) == DirectColor)
-	sizebytes *= 3;
-    sizebytes += sizeof(ColormapRec);
-    if (mid == pScreen->defColormap) {
-	pmap = malloc(sizebytes);
-	if (!pmap)
-	    return BadAlloc;
-	if (!dixAllocatePrivates(&pmap->devPrivates, PRIVATE_COLORMAP)) {
-	    free (pmap);
-	    return BadAlloc;
-	}
-    } else {
-	pmap = _dixAllocateObjectWithPrivates(sizebytes, sizebytes,
-					      offsetof(ColormapRec, devPrivates), PRIVATE_COLORMAP);
-	if (!pmap)
-	    return BadAlloc;
-    }
-#if defined(_XSERVER64)
-    pmap->pad0 = 0;
-    pmap->pad1 = 0;
-#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
-    pmap->pad2 = 0;
-#endif
-#endif
-    pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));    
-    sizebytes = size * sizeof(Entry);
-    pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
-    pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
-				 (MAXCLIENTS * sizeof(Pixel *)));
-    pmap->mid = mid;
-    pmap->flags = 0; 	/* start out with all flags clear */
-    if(mid == pScreen->defColormap)
-	pmap->flags |= IsDefault;
-    pmap->pScreen = pScreen;
-    pmap->pVisual = pVisual;
-    pmap->class = class;
-    if ((class | DynamicClass) == DirectColor)
-	size = NUMRED(pVisual);
-    pmap->freeRed = size;
-    memset((char *) pmap->red, 0, (int)sizebytes);
-    memset((char *) pmap->numPixelsRed, 0, MAXCLIENTS * sizeof(int));
-    for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
-	*pptr = (Pixel *)NULL;
-    if (alloc == AllocAll)
-    {
-	if (class & DynamicClass)
-	    pmap->flags |= AllAllocated;
-	for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
-	    pent->refcnt = AllocPrivate;
-	pmap->freeRed = 0;
-	ppix = malloc(size * sizeof(Pixel));
-	if (!ppix)
-	{
-	    free(pmap);
-	    return BadAlloc;
-	}
-	pmap->clientPixelsRed[client] = ppix;
-	for(i = 0; i < size; i++)
-	    ppix[i] = i;
-	pmap->numPixelsRed[client] = size;
-    }
-
-    if ((class | DynamicClass) == DirectColor)
-    {
-	pmap->freeGreen = NUMGREEN(pVisual);
-	pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
-				 (MAXCLIENTS * sizeof(int)));
-	pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
-	pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
-				       (MAXCLIENTS * sizeof(Pixel *)));
-	pmap->freeBlue = NUMBLUE(pVisual);
-	pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
-				(MAXCLIENTS * sizeof(int)));
-	pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
-	pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
-				      (MAXCLIENTS * sizeof(Pixel *)));
-
-	memset((char *) pmap->green, 0, (int)sizebytes);
-	memset((char *) pmap->blue, 0, (int)sizebytes);
-
-	memmove((char *) pmap->clientPixelsGreen,
-		(char *) pmap->clientPixelsRed,
-	      MAXCLIENTS * sizeof(Pixel *));
-	memmove((char *) pmap->clientPixelsBlue,
-		(char *) pmap->clientPixelsRed,
-	      MAXCLIENTS * sizeof(Pixel *));
-	memset((char *) pmap->numPixelsGreen, 0, MAXCLIENTS * sizeof(int));
-	memset((char *) pmap->numPixelsBlue, 0, MAXCLIENTS * sizeof(int));
-
-	/* If every cell is allocated, mark its refcnt */
-	if (alloc == AllocAll)
-	{
-	    size = pmap->freeGreen;
-	    for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
-		pent->refcnt = AllocPrivate;
-	    pmap->freeGreen = 0;
-	    ppix = malloc(size * sizeof(Pixel));
-	    if (!ppix)
-	    {
-		free(pmap->clientPixelsRed[client]);
-		free(pmap);
-		return BadAlloc;
-	    }
-	    pmap->clientPixelsGreen[client] = ppix;
-	    for(i = 0; i < size; i++)
-		ppix[i] = i;
-	    pmap->numPixelsGreen[client] = size;
-
-	    size = pmap->freeBlue;
-	    for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
-		pent->refcnt = AllocPrivate;
-	    pmap->freeBlue = 0;
-	    ppix = malloc(size * sizeof(Pixel));
-	    if (!ppix)
-	    {
-		free(pmap->clientPixelsGreen[client]);
-		free(pmap->clientPixelsRed[client]);
-		free(pmap);
-		return BadAlloc;
-	    }
-	    pmap->clientPixelsBlue[client] = ppix;
-	    for(i = 0; i < size; i++)
-		ppix[i] = i;
-	    pmap->numPixelsBlue[client] = size;
-	}
-    }
-    pmap->flags |= BeingCreated;
-
-    if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
-	return BadAlloc;
-
-    /*  
-     * Security creation/labeling check
-     */
-    i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP,
-		 pmap, RT_NONE, NULL, DixCreateAccess);
-    if (i != Success) {
-	FreeResource(mid, RT_NONE);
-	return i;
-    }
-
-    /* If the device wants a chance to initialize the colormap in any way,
-     * this is it.  In specific, if this is a Static colormap, this is the
-     * time to fill in the colormap's values */
-    if (!(*pScreen->CreateColormap)(pmap))
-    {
-	FreeResource (mid, RT_NONE);
-	return BadAlloc;
-    }
-    pmap->flags &= ~BeingCreated;
-    *ppcmap = pmap;
-    return Success;
-}
-
-/**
- *
- * \param value  must conform to DeleteType
- */
-int
-FreeColormap (pointer value, XID mid)
-{
-    int	i;
-    EntryPtr pent;
-    ColormapPtr	pmap = (ColormapPtr)value;
-
-    if(CLIENT_ID(mid) != SERVER_ID)
-    {
-        (*pmap->pScreen->UninstallColormap) (pmap);
-        WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
-    }
-
-    /* This is the device's chance to undo anything it needs to, especially
-     * to free any storage it allocated */
-    (*pmap->pScreen->DestroyColormap)(pmap);
-
-    if(pmap->clientPixelsRed)
-    {
-	for(i = 0; i < MAXCLIENTS; i++)
-	    free(pmap->clientPixelsRed[i]);
-    }
-
-    if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
-    {
-	for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
-	    pent >= pmap->red;
-	    pent--)
-	{
-	    if(pent->fShared)
-	    {
-		if (--pent->co.shco.red->refcnt == 0)
-		    free(pent->co.shco.red);
-		if (--pent->co.shco.green->refcnt == 0)
-		    free(pent->co.shco.green);
-		if (--pent->co.shco.blue->refcnt == 0)
-		    free(pent->co.shco.blue);
-	    }
-	}
-    }
-    if((pmap->class | DynamicClass) == DirectColor)
-    {
-        for(i = 0; i < MAXCLIENTS; i++)
-	{
-            free(pmap->clientPixelsGreen[i]);
-            free(pmap->clientPixelsBlue[i]);
-        }
-    }
-
-    if (pmap->flags & IsDefault) {
-	dixFreePrivates(pmap->devPrivates, PRIVATE_COLORMAP);
-	free(pmap);
-    } else
-	dixFreeObjectWithPrivates(pmap, PRIVATE_COLORMAP);
-    return Success;
-}
-
-/* Tell window that pmid has disappeared */
-static int
-TellNoMap (WindowPtr pwin, Colormap *pmid)
-{
-    xEvent 	xE;
-
-    if (wColormap(pwin) == *pmid)
-    {
-	/* This should be call to DeliverEvent */
-	xE.u.u.type = ColormapNotify;
-	xE.u.colormap.window = pwin->drawable.id;
-	xE.u.colormap.colormap = None;
-	xE.u.colormap.new = TRUE;
-	xE.u.colormap.state = ColormapUninstalled;
-#ifdef PANORAMIX
-        if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
-#endif
-	   DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
-	if (pwin->optional) {
-	    pwin->optional->colormap = None;
-	    CheckWindowOptionalNeed (pwin);
-	}
-    }
-
-    return WT_WALKCHILDREN;
-}
-
-/* Tell window that pmid got uninstalled */
-int
-TellLostMap (WindowPtr pwin, pointer value)
-{
-    Colormap 	*pmid = (Colormap *)value;
-    xEvent 	xE;
-
-#ifdef PANORAMIX
-    if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
-	return WT_STOPWALKING;
-#endif
-    if (wColormap(pwin) == *pmid)
-    {
-	/* This should be call to DeliverEvent */
-	xE.u.u.type = ColormapNotify;
-	xE.u.colormap.window = pwin->drawable.id;
-	xE.u.colormap.colormap = *pmid;
-	xE.u.colormap.new = FALSE;
-	xE.u.colormap.state = ColormapUninstalled;
-	DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
-    }
-
-    return WT_WALKCHILDREN;
-}
-
-/* Tell window that pmid got installed */
-int
-TellGainedMap (WindowPtr pwin, pointer value)
-{
-    Colormap 	*pmid = (Colormap *)value;
-    xEvent 	xE;
-
-#ifdef PANORAMIX
-    if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
-	return WT_STOPWALKING;
-#endif
-    if (wColormap (pwin) == *pmid)
-    {
-	/* This should be call to DeliverEvent */
-	xE.u.u.type = ColormapNotify;
-	xE.u.colormap.window = pwin->drawable.id;
-	xE.u.colormap.colormap = *pmid;
-	xE.u.colormap.new = FALSE;
-	xE.u.colormap.state = ColormapInstalled;
-	DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
-    }
-
-    return WT_WALKCHILDREN;
-}
-
-  
-int
-CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
-{
-    ColormapPtr	pmap = (ColormapPtr) NULL;
-    int		result, alloc, size;
-    Colormap	midSrc;
-    ScreenPtr	pScreen;
-    VisualPtr	pVisual;
-
-    pScreen = pSrc->pScreen;
-    pVisual = pSrc->pVisual;
-    midSrc = pSrc->mid;
-    alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
-            AllocAll : AllocNone;
-    size = pVisual->ColormapEntries;
-
-    /* If the create returns non-0, it failed */
-    result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
-    if(result != Success)
-        return result;
-    if(alloc == AllocAll)
-    {
-	memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
-	if((pmap->class | DynamicClass) == DirectColor)
-	{
-	    memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
-	    memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
-	}
-	pSrc->flags &= ~AllAllocated;
-	FreePixels(pSrc, client);
-	UpdateColors(pmap);
-	return Success;
-    }
-
-    CopyFree(REDMAP, client, pSrc, pmap);
-    if ((pmap->class | DynamicClass) == DirectColor)
-    {
-	CopyFree(GREENMAP, client, pSrc, pmap);
-	CopyFree(BLUEMAP, client, pSrc, pmap);
-    }
-    if (pmap->class & DynamicClass)
-	UpdateColors(pmap);
-    /* XXX should worry about removing any RT_CMAPENTRY resource */
-    return Success;
-}
-
-/* Helper routine for freeing large numbers of cells from a map */
-static void
-CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
-{
-    int		z, npix;
-    EntryPtr	pentSrcFirst, pentDstFirst;
-    EntryPtr	pentSrc, pentDst;
-    Pixel	*ppix;
-    int		nalloc;
-
-    switch(channel)
-    {
-      default:	/* so compiler can see that everything gets initialized */
-      case REDMAP:
-	ppix = (pmapSrc->clientPixelsRed)[client];
-	npix = (pmapSrc->numPixelsRed)[client];
-	pentSrcFirst = pmapSrc->red;
-	pentDstFirst = pmapDst->red;
-	break;
-      case GREENMAP:
-	ppix = (pmapSrc->clientPixelsGreen)[client];
-	npix = (pmapSrc->numPixelsGreen)[client];
-	pentSrcFirst = pmapSrc->green;
-	pentDstFirst = pmapDst->green;
-	break;
-      case BLUEMAP:
-	ppix = (pmapSrc->clientPixelsBlue)[client];
-	npix = (pmapSrc->numPixelsBlue)[client];
-	pentSrcFirst = pmapSrc->blue;
-	pentDstFirst = pmapDst->blue;
-	break;
-    }
-    nalloc = 0;
-    if (pmapSrc->class & DynamicClass)
-    {
-	for(z = npix; --z >= 0; ppix++)
-	{
-	    /* Copy entries */
-	    pentSrc = pentSrcFirst + *ppix;
-	    pentDst = pentDstFirst + *ppix;
-	    if (pentDst->refcnt > 0)
-	    {
-		pentDst->refcnt++;
-	    }
-	    else
-	    {
-		*pentDst = *pentSrc;
-		nalloc++;
-		if (pentSrc->refcnt > 0)
-		    pentDst->refcnt = 1;
-		else
-		    pentSrc->fShared = FALSE;
-	    }
-	    FreeCell(pmapSrc, *ppix, channel);
-	}
-    }
-
-    /* Note that FreeCell has already fixed pmapSrc->free{Color} */
-    switch(channel)
-    {
-      case REDMAP:
-        pmapDst->freeRed -= nalloc;
-        (pmapDst->clientPixelsRed)[client] =
-	    (pmapSrc->clientPixelsRed)[client];
-        (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
-        (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
-        (pmapSrc->numPixelsRed)[client] = 0;
-	break;
-      case GREENMAP:
-        pmapDst->freeGreen -= nalloc;
-        (pmapDst->clientPixelsGreen)[client] =
-	    (pmapSrc->clientPixelsGreen)[client];
-        (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
-        (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
-        (pmapSrc->numPixelsGreen)[client] = 0;
-	break;
-      case BLUEMAP:
-        pmapDst->freeBlue -= nalloc;
-        pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
-        pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
-        pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
-        pmapSrc->numPixelsBlue[client] = 0;
-	break;
-    }
-}
-
-/* Free the ith entry in a color map.  Must handle freeing of
- * colors allocated through AllocColorPlanes */
-static void
-FreeCell (ColormapPtr pmap, Pixel i, int channel)
-{
-    EntryPtr pent;
-    int	*pCount;
-
-
-    switch (channel)
-    {
-      default:	/* so compiler can see that everything gets initialized */
-      case PSEUDOMAP:
-      case REDMAP:
-          pent = (EntryPtr) &pmap->red[i];
-	  pCount = &pmap->freeRed;
-	  break;
-      case GREENMAP:
-          pent = (EntryPtr) &pmap->green[i];
-	  pCount = &pmap->freeGreen;
-	  break;
-      case BLUEMAP:
-          pent = (EntryPtr) &pmap->blue[i];
-	  pCount = &pmap->freeBlue;
-	  break;
-    }
-    /* If it's not privately allocated and it's not time to free it, just
-     * decrement the count */
-    if (pent->refcnt > 1)
-	pent->refcnt--;
-    else
-    {
-        /* If the color type is shared, find the sharedcolor. If decremented
-         * refcnt is 0, free the shared cell. */
-        if (pent->fShared)
-	{
-	    if(--pent->co.shco.red->refcnt == 0)
-		free(pent->co.shco.red);
-	    if(--pent->co.shco.green->refcnt == 0)
-		free(pent->co.shco.green);
-	    if(--pent->co.shco.blue->refcnt == 0)
-		free(pent->co.shco.blue);
-	    pent->fShared = FALSE;
-	}
-	pent->refcnt = 0;
-	*pCount += 1;
-    }
-}
-
-static void
-UpdateColors (ColormapPtr pmap)
-{
-    xColorItem		*defs;
-    xColorItem *pdef;
-    EntryPtr 	pent;
-    VisualPtr	pVisual;
-    int			i, n, size;
-
-    pVisual = pmap->pVisual;
-    size = pVisual->ColormapEntries;
-    defs = malloc(size * sizeof(xColorItem));
-    if (!defs)
-	return;
-    n = 0;
-    pdef = defs;
-    if (pmap->class == DirectColor)
-    {
-        for (i = 0; i < size; i++)
-	{
-	    if (!pmap->red[i].refcnt &&
-		!pmap->green[i].refcnt &&
-		!pmap->blue[i].refcnt)
-		continue;
-	    pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
-			  ((Pixel)i << pVisual->offsetGreen) |
-			  ((Pixel)i << pVisual->offsetBlue);
-	    pdef->red = pmap->red[i].co.local.red;
-	    pdef->green = pmap->green[i].co.local.green;
-	    pdef->blue = pmap->blue[i].co.local.blue;
-	    pdef->flags = DoRed|DoGreen|DoBlue;
-	    pdef++;
-	    n++;
-	}
-    }
-    else
-    {
-        for (i = 0, pent = pmap->red; i < size; i++, pent++)
-	{
-	    if (!pent->refcnt)
-		continue;
-	    pdef->pixel = i;
-	    if(pent->fShared)
-	    {
-		pdef->red = pent->co.shco.red->color;
-		pdef->green = pent->co.shco.green->color;
-		pdef->blue = pent->co.shco.blue->color;
-	    }
-	    else
-	    {
-		pdef->red = pent->co.local.red;
-		pdef->green = pent->co.local.green;
-		pdef->blue = pent->co.local.blue;
-	    }
-	    pdef->flags = DoRed|DoGreen|DoBlue;
-	    pdef++;
-	    n++;
-	}
-    }
-    if (n)
-	(*pmap->pScreen->StoreColors)(pmap, n, defs);
-    free(defs);
-}
-
-/* Get a read-only color from a ColorMap (probably slow for large maps)
- * Returns by changing the value in pred, pgreen, pblue and pPix
- */
-int
-AllocColor (ColormapPtr pmap, 
-            unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, 
-            Pixel *pPix, int client)
-{
-    Pixel	pixR, pixG, pixB;
-    int		entries;
-    xrgb	rgb;
-    int		class;
-    VisualPtr	pVisual;
-    int		npix;
-    Pixel	*ppix;
-
-    pVisual = pmap->pVisual;
-    (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
-    rgb.red = *pred;
-    rgb.green = *pgreen;
-    rgb.blue = *pblue;
-    class = pmap->class;
-    entries = pVisual->ColormapEntries;
-
-    /* If the colormap is being created, then we want to be able to change
-     * the colormap, even if it's a static type. Otherwise, we'd never be
-     * able to initialize static colormaps
-     */
-    if(pmap->flags & BeingCreated)
-	class |= DynamicClass;
-
-    /* If this is one of the static storage classes, and we're not initializing
-     * it, the best we can do is to find the closest color entry to the
-     * requested one and return that.
-     */
-    switch (class) {
-    case StaticColor:
-    case StaticGray:
-	/* Look up all three components in the same pmap */
-	*pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
-	*pred = pmap->red[pixR].co.local.red;
-	*pgreen = pmap->red[pixR].co.local.green;
-	*pblue = pmap->red[pixR].co.local.blue;
-	npix = pmap->numPixelsRed[client];
-	ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-				  (npix + 1) * sizeof(Pixel));
-	if (!ppix)
-	    return BadAlloc;
-	ppix[npix] = pixR;
-	pmap->clientPixelsRed[client] = ppix;
-	pmap->numPixelsRed[client]++;
-	break;
-
-    case TrueColor:
-	/* Look up each component in its own map, then OR them together */
-	pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
-	pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
-	pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
-	*pPix = (pixR << pVisual->offsetRed) |
-		(pixG << pVisual->offsetGreen) |
-		(pixB << pVisual->offsetBlue) |
-		ALPHAMASK(pVisual);
-	
-	*pred = pmap->red[pixR].co.local.red;
-	*pgreen = pmap->green[pixG].co.local.green;
-	*pblue = pmap->blue[pixB].co.local.blue;
-	npix = pmap->numPixelsRed[client];
-	ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-				  (npix + 1) * sizeof(Pixel));
-	if (!ppix)
-	    return BadAlloc;
-	ppix[npix] = pixR;
-	pmap->clientPixelsRed[client] = ppix;
-	npix = pmap->numPixelsGreen[client];
-	ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
-				  (npix + 1) * sizeof(Pixel));
-	if (!ppix)
-	    return BadAlloc;
-	ppix[npix] = pixG;
-	pmap->clientPixelsGreen[client] = ppix;
-	npix = pmap->numPixelsBlue[client];
-	ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
-				  (npix + 1) * sizeof(Pixel));
-	if (!ppix)
-	    return BadAlloc;
-	ppix[npix] = pixB;
-	pmap->clientPixelsBlue[client] = ppix;
-	pmap->numPixelsRed[client]++;
-	pmap->numPixelsGreen[client]++;
-	pmap->numPixelsBlue[client]++;
-	break;
-
-    case GrayScale:
-    case PseudoColor:
-	if (pmap->mid != pmap->pScreen->defColormap &&
-	    pmap->pVisual->vid == pmap->pScreen->rootVisual)
-	{
-	    ColormapPtr prootmap;
-	    dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
-				    RT_COLORMAP, clients[client], DixReadAccess);
-
-	    if (pmap->class == prootmap->class)
-		FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, 
-			pPix, PSEUDOMAP, AllComp);
-	}
-	if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
-		      client, AllComp) != Success)
-	    return BadAlloc;
-        break;
-
-    case DirectColor:
-	if (pmap->mid != pmap->pScreen->defColormap &&
-	    pmap->pVisual->vid == pmap->pScreen->rootVisual)
-	{
-	    ColormapPtr prootmap;
-	    dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
-				    RT_COLORMAP, clients[client], DixReadAccess);
-
-	    if (pmap->class == prootmap->class)
-	    {
-		pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; 
-		FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, 
-			&pixR, REDMAP, RedComp);
-		pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; 
-		FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb, 
-			&pixG, GREENMAP, GreenComp);
-		pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; 
-		FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb, 
-			&pixB, BLUEMAP, BlueComp);
-		*pPix = pixR | pixG | pixB;
-	    }
-	}
-
-	pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; 
-	if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
-		      client, RedComp) != Success)
-	    return BadAlloc;
-	pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; 
-	if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
-		      GREENMAP, client, GreenComp) != Success)
-	{
-	    (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
-	    return BadAlloc;
-	}
-	pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; 
-	if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
-		      client, BlueComp) != Success)
-	{
-	    (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
-	    (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
-	    return BadAlloc;
-	}
-	*pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
-
-	break;
-    }
-
-    /* if this is the client's first pixel in this colormap, tell the
-     * resource manager that the client has pixels in this colormap which
-     * should be freed when the client dies */
-    if ((pmap->numPixelsRed[client] == 1) &&
-	(CLIENT_ID(pmap->mid) != client) &&
-	!(pmap->flags & BeingCreated))
-    {
-	colorResource	*pcr;
-
-	pcr = malloc(sizeof(colorResource));
-	if (!pcr)
-	{
-	    (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
-	    return BadAlloc;
-	}
-	pcr->mid = pmap->mid;
-	pcr->client = client;
-	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
-	    return BadAlloc;
-    }
-    return Success;
-}
-
-/*
- * FakeAllocColor -- fake an AllocColor request by
- * returning a free pixel if availible, otherwise returning
- * the closest matching pixel.  This is used by the mi
- * software sprite code to recolor cursors.  A nice side-effect
- * is that this routine will never return failure.
- */
-
-void
-FakeAllocColor (ColormapPtr pmap, xColorItem *item)
-{
-    Pixel pixR, pixG, pixB;
-    Pixel temp;
-    int	entries;
-    xrgb rgb;
-    int	class;
-    VisualPtr pVisual;
-
-    pVisual = pmap->pVisual;
-    rgb.red = item->red;
-    rgb.green = item->green;
-    rgb.blue = item->blue;
-    (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
-    class = pmap->class;
-    entries = pVisual->ColormapEntries;
-
-    switch (class) {
-    case GrayScale:
-    case PseudoColor:
-	temp = 0;
-	item->pixel = 0;
-	if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
-		      -1, AllComp) == Success) {
-	    item->pixel = temp;
-	    break;
-	}
-	/* fall through ... */
-    case StaticColor:
-    case StaticGray:
-	item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
-	break;
-
-    case DirectColor:
-	/* Look up each component in its own map, then OR them together */
-	pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed; 
-	pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen; 
-	pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue; 
-	if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
-		      -1, RedComp) != Success)
-	    pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
-			<< pVisual->offsetRed;
-	if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
-		      GREENMAP, -1, GreenComp) != Success)
-	    pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
-				 GREENMAP) << pVisual->offsetGreen;
-	if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
-		      -1, BlueComp) != Success)
-	    pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
-			<< pVisual->offsetBlue;
-	item->pixel = pixR | pixG | pixB;
-	break;
-
-    case TrueColor:
-	/* Look up each component in its own map, then OR them together */
-	pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
-	pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
-	pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
-	item->pixel = (pixR << pVisual->offsetRed) |
-		      (pixG << pVisual->offsetGreen) |
-		      (pixB << pVisual->offsetBlue);
-	break;
-    }
-}
-
-/* free a pixel value obtained from FakeAllocColor */
-void
-FakeFreeColor(ColormapPtr pmap, Pixel pixel)
-{
-    VisualPtr pVisual;
-    Pixel pixR, pixG, pixB;
-
-    switch (pmap->class) {
-    case GrayScale:
-    case PseudoColor:
-	if (pmap->red[pixel].refcnt == AllocTemporary)
-	    pmap->red[pixel].refcnt = 0;
-	break;
-    case DirectColor:
-	pVisual = pmap->pVisual;
-	pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed; 
-	pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; 
-	pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; 
-	if (pmap->red[pixR].refcnt == AllocTemporary)
-	    pmap->red[pixR].refcnt = 0;
-	if (pmap->green[pixG].refcnt == AllocTemporary)
-	    pmap->green[pixG].refcnt = 0;
-	if (pmap->blue[pixB].refcnt == AllocTemporary)
-	    pmap->blue[pixB].refcnt = 0;
-	break;
-    }
-}
-
-typedef unsigned short	BigNumUpper;
-typedef unsigned long	BigNumLower;
-
-#define BIGNUMLOWERBITS	24
-#define BIGNUMUPPERBITS	16
-#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
-#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
-#define UPPERPART(i)	((i) >> BIGNUMLOWERBITS)
-#define LOWERPART(i)	((i) & (BIGNUMLOWER - 1))
-
-typedef struct _bignum {
-    BigNumUpper	upper;
-    BigNumLower	lower;
-} BigNumRec, *BigNumPtr;
-
-#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
-			    ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
-
-#define UnsignedToBigNum(u,r)	(((r)->upper = UPPERPART(u)), \
-				 ((r)->lower = LOWERPART(u)))
-
-#define MaxBigNum(r)		(((r)->upper = BIGNUMUPPER-1), \
-				 ((r)->lower = BIGNUMLOWER-1))
-
-static void
-BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
-{
-    BigNumLower	lower, carry = 0;
-
-    lower = x->lower + y->lower;
-    if (lower >= BIGNUMLOWER) {
-	lower -= BIGNUMLOWER;
-	carry = 1;
-    }
-    r->lower = lower;
-    r->upper = x->upper + y->upper + carry;
-}
-
-static Pixel
-FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
-{
-    EntryPtr	pent;
-    Pixel	pixel, final;
-    long	dr, dg, db;
-    unsigned long   sq;
-    BigNumRec	minval, sum, temp;
-
-    final = 0;
-    MaxBigNum(&minval);
-    /* look for the minimal difference */
-    for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
-    {
-	dr = dg = db = 0;
-	switch(channel)
-	{
-	  case PSEUDOMAP:
-	      dg = (long) pent->co.local.green - prgb->green;
-	      db = (long) pent->co.local.blue - prgb->blue;
-	  case REDMAP:
-	      dr = (long) pent->co.local.red - prgb->red;
-	      break;
-	  case GREENMAP:
-	      dg = (long) pent->co.local.green - prgb->green;
-	      break;
-	  case BLUEMAP:
-	      db = (long) pent->co.local.blue - prgb->blue;
-	      break;
-	}
-	sq = dr * dr;
-	UnsignedToBigNum (sq, &sum);
-	sq = dg * dg;
-	UnsignedToBigNum (sq, &temp);
-	BigNumAdd (&sum, &temp, &sum);
-	sq = db * db;
-	UnsignedToBigNum (sq, &temp);
-	BigNumAdd (&sum, &temp, &sum);
-	if (BigNumGreater (&minval, &sum))
-	{
-	    final = pixel;
-	    minval = sum;
-	}
-    }
-    return final;
-}
-
-static void
-FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size, 
-                     xrgb *prgb, Pixel *pPixel, int channel, 
-                     ColorCompareProcPtr comp)
-{
-    EntryPtr    pent;
-    Pixel	pixel;
-    int         count;
-
-    if ((pixel = *pPixel) >= size)
-	pixel = 0;
-    for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
-    {
-	if (pent->refcnt > 0 && (*comp) (pent, prgb))
-	{
-	    switch (channel)
-	    {
-	    case REDMAP:
-		pixel <<= pmap->pVisual->offsetRed;
-		break;
-	    case GREENMAP:
-		pixel <<= pmap->pVisual->offsetGreen;
-		break;
-	    case BLUEMAP:
-		pixel <<= pmap->pVisual->offsetBlue;
-		break;
-	    default: /* PSEUDOMAP */
-		break;
-	    }
-	    *pPixel = pixel;
-	}
-    }
-}
-
-/* Tries to find a color in pmap that exactly matches the one requested in prgb
- * if it can't it allocates one.
- * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
- * load *pPixel with that value, otherwise set it to 0
- */
-int
-FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb, 
-           Pixel *pPixel, int channel, int client, 
-           ColorCompareProcPtr comp)
-{
-    EntryPtr	pent;
-    Bool	foundFree;
-    Pixel	pixel, Free = 0;
-    int		npix, count, *nump = NULL;
-    Pixel	**pixp = NULL, *ppix;
-    xColorItem	def;
-
-    foundFree = FALSE;
-
-    if((pixel = *pPixel) >= size)
-	pixel = 0;
-    /* see if there is a match, and also look for a free entry */
-    for (pent = pentFirst + pixel, count = size; --count >= 0; )
-    {
-        if (pent->refcnt > 0)
-	{
-    	    if ((*comp) (pent, prgb))
-	    {
-		if (client >= 0)
-		    pent->refcnt++;
-		*pPixel = pixel;
-		switch(channel)
-		{
-		  case REDMAP:
-		    *pPixel <<= pmap->pVisual->offsetRed;
-		  case PSEUDOMAP:
-		    break;
-		  case GREENMAP:
-		    *pPixel <<= pmap->pVisual->offsetGreen;
-		    break;
-		  case BLUEMAP:
-		    *pPixel <<= pmap->pVisual->offsetBlue;
-		    break;
-		}
-		goto gotit;
-    	    }
-        }
-	else if (!foundFree && pent->refcnt == 0)
-	{
-	    Free = pixel;
-	    foundFree = TRUE;
-	    /* If we're initializing the colormap, then we are looking for
-	     * the first free cell we can find, not to minimize the number
-	     * of entries we use.  So don't look any further. */
-	    if(pmap->flags & BeingCreated)
-		break;
-	}
-	pixel++;
-	if(pixel >= size)
-	{
-	    pent = pentFirst;
-	    pixel = 0;
-	}
-	else
-	    pent++;
-    }
-
-    /* If we got here, we didn't find a match.  If we also didn't find
-     * a free entry, we're out of luck.  Otherwise, we'll usurp a free
-     * entry and fill it in */
-    if (!foundFree)
-	return BadAlloc;
-    pent = pentFirst + Free;
-    pent->fShared = FALSE;
-    pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
-
-    switch (channel)
-    {
-      case PSEUDOMAP:
-        pent->co.local.red = prgb->red;
-        pent->co.local.green = prgb->green;
-        pent->co.local.blue = prgb->blue;
-        def.red = prgb->red;
-	def.green = prgb->green;
-	def.blue = prgb->blue;
-	def.flags = (DoRed|DoGreen|DoBlue);
-	if (client >= 0)
-	    pmap->freeRed--;
-	def.pixel = Free;
-	break;
-
-      case REDMAP:
-        pent->co.local.red = prgb->red;
-        def.red = prgb->red;
-	def.green = pmap->green[0].co.local.green;
-	def.blue = pmap->blue[0].co.local.blue;
-	def.flags = DoRed;
-	if (client >= 0)
-	    pmap->freeRed--;
-	def.pixel = Free << pmap->pVisual->offsetRed;
-	break;
-
-      case GREENMAP:
-	pent->co.local.green = prgb->green;
-	def.red = pmap->red[0].co.local.red;
-        def.green = prgb->green;
-	def.blue = pmap->blue[0].co.local.blue;
-	def.flags = DoGreen;
-	if (client >= 0)
-	    pmap->freeGreen--;
-	def.pixel = Free << pmap->pVisual->offsetGreen;
-	break;
-
-      case BLUEMAP:
-	pent->co.local.blue = prgb->blue;
-	def.red = pmap->red[0].co.local.red;
-	def.green = pmap->green[0].co.local.green;
-	def.blue = prgb->blue;
-	def.flags = DoBlue;
-	if (client >= 0)
-	    pmap->freeBlue--;
-	def.pixel = Free << pmap->pVisual->offsetBlue;
-	break;
-    }
-    (*pmap->pScreen->StoreColors) (pmap, 1, &def);
-    pixel = Free;	
-    *pPixel = def.pixel;
-
-gotit:
-    if (pmap->flags & BeingCreated || client == -1)
-	return Success;
-    /* Now remember the pixel, for freeing later */
-    switch (channel)
-    {
-      case PSEUDOMAP:
-      case REDMAP:
-	nump = pmap->numPixelsRed;
-	pixp = pmap->clientPixelsRed;
-	break;
-
-      case GREENMAP:
-	nump = pmap->numPixelsGreen;
-	pixp = pmap->clientPixelsGreen;
-	break;
-
-      case BLUEMAP:
-	nump = pmap->numPixelsBlue;
-	pixp = pmap->clientPixelsBlue;
-	break;
-    }
-    npix = nump[client];
-    ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel));
-    if (!ppix)
-    {
-	pent->refcnt--;
-	if (!pent->fShared)
-	    switch (channel)
-	    {
-	      case PSEUDOMAP:
-	      case REDMAP:
-		pmap->freeRed++;
-		break;
-	      case GREENMAP:
-		pmap->freeGreen++;
-		break;
-	      case BLUEMAP:
-		pmap->freeBlue++;
-		break;
-	    }
-	return BadAlloc;
-    }
-    ppix[npix] = pixel;
-    pixp[client] = ppix;
-    nump[client]++;
-
-    return Success;
-}
-
-/* Comparison functions -- passed to FindColor to determine if an
- * entry is already the color we're looking for or not */
-static int
-AllComp (EntryPtr pent, xrgb *prgb)
-{
-    if((pent->co.local.red == prgb->red) &&
-       (pent->co.local.green == prgb->green) &&
-       (pent->co.local.blue == prgb->blue) )
-       return 1;
-    return 0;
-}
-
-static int
-RedComp (EntryPtr pent, xrgb *prgb)
-{
-    if (pent->co.local.red == prgb->red) 
-	return 1;
-    return 0;
-}
-
-static int
-GreenComp (EntryPtr pent, xrgb *prgb)
-{
-    if (pent->co.local.green == prgb->green) 
-	return 1;
-    return 0;
-}
-
-static int
-BlueComp (EntryPtr pent, xrgb *prgb)
-{
-    if (pent->co.local.blue == prgb->blue) 
-	return 1;
-    return 0;
-}
-
-
-/* Read the color value of a cell */
-
-int
-QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList, ClientPtr client)
-{
-    Pixel	*ppix, pixel;
-    xrgb	*prgb;
-    VisualPtr	pVisual;
-    EntryPtr	pent;
-    Pixel	i;
-    int		errVal = Success;
-
-    pVisual = pmap->pVisual;
-    if ((pmap->class | DynamicClass) == DirectColor)
-    {
-	int numred, numgreen, numblue;
-	Pixel rgbbad;
-
-	numred = NUMRED(pVisual);
-	numgreen = NUMGREEN(pVisual);
-	numblue = NUMBLUE(pVisual);
-	rgbbad = ~RGBMASK(pVisual);
-	for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
-	{
-	    pixel = *ppix;
-	    if (pixel & rgbbad) {
-		client->errorValue = pixel;
-		errVal =  BadValue;
-		continue;
-	    }
-	    i  = (pixel & pVisual->redMask) >> pVisual->offsetRed;
-	    if (i >= numred)
-	    {
-		client->errorValue = pixel;
-		errVal =  BadValue;
-		continue;
-	    }
-	    prgb->red = pmap->red[i].co.local.red;
-	    i  = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
-	    if (i >= numgreen)
-	    {
-		client->errorValue = pixel;
-		errVal =  BadValue;
-		continue;
-	    }
-	    prgb->green = pmap->green[i].co.local.green;
-	    i  = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
-	    if (i >= numblue)
-	    {
-		client->errorValue = pixel;
-		errVal =  BadValue;
-		continue;
-	    }
-	    prgb->blue = pmap->blue[i].co.local.blue;
-	}
-    }
-    else
-    {
-	for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
-	{
-	    pixel = *ppix;
-	    if (pixel >= pVisual->ColormapEntries)
-	    {
-		client->errorValue = pixel;
-		errVal = BadValue;
-	    }
-	    else
-	    {
-		pent = (EntryPtr)&pmap->red[pixel];
-		if (pent->fShared)
-		{
-		    prgb->red = pent->co.shco.red->color;
-		    prgb->green = pent->co.shco.green->color;
-		    prgb->blue = pent->co.shco.blue->color;
-		}
-		else
-		{
-		    prgb->red = pent->co.local.red;
-		    prgb->green = pent->co.local.green;
-		    prgb->blue = pent->co.local.blue;
-		}
-	    }
-	}
-    }
-    return errVal;
-}
-
-static void
-FreePixels(ColormapPtr pmap, int client)
-{
-    Pixel *ppix, *ppixStart;
-    int n;
-    int	class;
-
-    class = pmap->class;
-    ppixStart = pmap->clientPixelsRed[client];
-    if (class & DynamicClass)
-    {
-	n = pmap->numPixelsRed[client];
-	for (ppix = ppixStart; --n >= 0; )
-	{
-	    FreeCell(pmap, *ppix, REDMAP);
-	    ppix++;
-	}
-    }
-
-    free(ppixStart);
-    pmap->clientPixelsRed[client] = (Pixel *) NULL;
-    pmap->numPixelsRed[client] = 0;
-    if ((class | DynamicClass) == DirectColor) 
-    {
-        ppixStart = pmap->clientPixelsGreen[client];
-	if (class & DynamicClass)
-	    for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
-		FreeCell(pmap, *ppix++, GREENMAP);
-	free(ppixStart);
-	pmap->clientPixelsGreen[client] = (Pixel *) NULL;
-	pmap->numPixelsGreen[client] = 0;
-
-        ppixStart = pmap->clientPixelsBlue[client];
-	if (class & DynamicClass)
-	    for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
-		FreeCell(pmap, *ppix++, BLUEMAP);
-	free(ppixStart);
-	pmap->clientPixelsBlue[client] = (Pixel *) NULL;
-	pmap->numPixelsBlue[client] = 0;
-    }
-}
-
-/** 
- * Frees all of a client's colors and cells.
- *
- *  \param value  must conform to DeleteType
- *  \unused fakeid
- */
-int
-FreeClientPixels (pointer value, XID fakeid)
-{
-    pointer pmap;
-    colorResource *pcr = value;
-    int rc;
-
-    rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient,
-				 DixRemoveAccess);
-    if (rc == Success)
-	FreePixels((ColormapPtr)pmap, pcr->client);
-    free(pcr);
-    return Success;
-}
-
-int
-AllocColorCells (int client, ColormapPtr pmap, int colors, int planes, 
-                 Bool contig, Pixel *ppix, Pixel *masks)
-{
-    Pixel	rmask, gmask, bmask, *ppixFirst, r, g, b;
-    int		n, class;
-    int		ok;
-    int		oldcount;
-    colorResource *pcr = (colorResource *)NULL;
-
-    class = pmap->class;
-    if (!(class & DynamicClass))
-	return BadAlloc; /* Shouldn't try on this type */
-    oldcount = pmap->numPixelsRed[client];
-    if (pmap->class == DirectColor)
-	oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
-    if (!oldcount && (CLIENT_ID(pmap->mid) != client))
-    {
-	pcr = malloc(sizeof(colorResource));
-	if (!pcr)
-	    return BadAlloc;
-    }
-
-    if (pmap->class == DirectColor)
-    {
-        ok = AllocDirect (client, pmap, colors, planes, planes, planes,
-			  contig, ppix, &rmask, &gmask, &bmask);
-	if(ok == Success)
-	{
-	    for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
-	    {
-		while(!(rmask & r))
-		    r += r;
-		while(!(gmask & g))
-		    g += g;
-		while(!(bmask & b))
-		    b += b;
-		*masks++ = r | g | b;
-	    }
-	}
-    }
-    else
-    {
-        ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
-			  &ppixFirst);
-	if(ok == Success)
-	{
-	    for (r = 1, n = planes; --n >= 0; r += r)
-	    {
-		while(!(rmask & r))
-		    r += r;
-		*masks++ = r;
-	    }
-	}
-    }
-
-    /* if this is the client's first pixels in this colormap, tell the
-     * resource manager that the client has pixels in this colormap which
-     * should be freed when the client dies */
-    if ((ok == Success) && pcr)
-    {
-	pcr->mid = pmap->mid;
-	pcr->client = client;
-	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
-	    ok = BadAlloc;
-    } else free(pcr);
-
-    return ok;
-}
-
-
-int
-AllocColorPlanes (int client, ColormapPtr pmap, int colors, 
-                  int r, int g, int b, Bool contig, Pixel *pixels, 
-                  Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
-{
-    int		ok;
-    Pixel	mask, *ppixFirst;
-    Pixel shift;
-    int i;
-    int		class;
-    int		oldcount;
-    colorResource *pcr = (colorResource *)NULL;
-
-    class = pmap->class;
-    if (!(class & DynamicClass))
-	return BadAlloc; /* Shouldn't try on this type */
-    oldcount = pmap->numPixelsRed[client];
-    if (class == DirectColor)
-	oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
-    if (!oldcount && (CLIENT_ID(pmap->mid) != client))
-    {
-	pcr = malloc(sizeof(colorResource));
-	if (!pcr)
-	    return BadAlloc;
-    }
-
-    if (class == DirectColor)
-    {
-        ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
-			  prmask, pgmask, pbmask);
-    }
-    else
-    {
-	/* Allocate the proper pixels */
-	/* XXX This is sort of bad, because of contig is set, we force all
-	 * r + g + b bits to be contiguous.  Should only force contiguity
-	 * per mask 
-	 */
-        ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
-			  &mask, &ppixFirst);
-
-	if(ok == Success)
-	{
-	    /* now split that mask into three */
-	    *prmask = *pgmask = *pbmask = 0;
-	    shift = 1;
-	    for (i = r; --i >= 0; shift += shift)
-	    {
-		while (!(mask & shift))
-		    shift += shift;
-		*prmask |= shift;
-	    }
-	    for (i = g; --i >= 0; shift += shift)
-	    {
-		while (!(mask & shift))
-		    shift += shift;
-		*pgmask |= shift;
-	    }
-	    for (i = b; --i >= 0; shift += shift)
-	    {
-		while (!(mask & shift))
-		    shift += shift;
-		*pbmask |= shift;
-	    }
-
-	    /* set up the shared color cells */
-	    if (!AllocShared(pmap, pixels, colors, r, g, b,
-			     *prmask, *pgmask, *pbmask, ppixFirst))
-	    {
-		(void)FreeColors(pmap, client, colors, pixels, mask);
-		ok = BadAlloc;
-	    }
-	}
-    }
-
-    /* if this is the client's first pixels in this colormap, tell the
-     * resource manager that the client has pixels in this colormap which
-     * should be freed when the client dies */
-    if ((ok == Success) && pcr)
-    {
-	pcr->mid = pmap->mid;
-	pcr->client = client;
-	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
-	    ok = BadAlloc;
-    } else free(pcr);
-
-    return ok;
-}
-
-static int
-AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig, 
-             Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
-{
-    Pixel	*ppixRed, *ppixGreen, *ppixBlue;
-    Pixel	*ppix, *pDst, *p;
-    int		npix, npixR, npixG, npixB;
-    Bool	okR, okG, okB;
-    Pixel	*rpix = 0, *gpix = 0, *bpix = 0;
-
-    npixR = c << r;
-    npixG = c << g;
-    npixB = c << b;
-    if ((r >= 32) || (g >= 32) || (b >= 32) ||
-	(npixR > pmap->freeRed) || (npixR < c) ||
-	(npixG > pmap->freeGreen) || (npixG < c) ||
-	(npixB > pmap->freeBlue) || (npixB < c))
-	return BadAlloc;
-
-    /* start out with empty pixels */
-    for(p = pixels; p < pixels + c; p++)
-	*p = 0;
-
-    ppixRed = malloc(npixR * sizeof(Pixel));
-    ppixGreen = malloc(npixG * sizeof(Pixel));
-    ppixBlue = malloc(npixB * sizeof(Pixel));
-    if (!ppixRed || !ppixGreen || !ppixBlue)
-    {
-	free(ppixBlue);
-	free(ppixGreen);
-	free(ppixRed);
-	return BadAlloc;
-    }
-
-    okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
-    okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
-    okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
-
-    if (okR && okG && okB)
-    {
-	rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-				  (pmap->numPixelsRed[client] + (c << r)) *
-				  sizeof(Pixel));
-	if (rpix)
-	    pmap->clientPixelsRed[client] = rpix;
-	gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
-				  (pmap->numPixelsGreen[client] + (c << g)) *
-				  sizeof(Pixel));
-	if (gpix)
-	    pmap->clientPixelsGreen[client] = gpix;
-	bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
-				  (pmap->numPixelsBlue[client] + (c << b)) *
-				  sizeof(Pixel));
-	if (bpix)
-	    pmap->clientPixelsBlue[client] = bpix;
-    }
-
-    if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
-    {
-	if (okR)
-	    for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
-		pmap->red[*ppix].refcnt = 0;
-	if (okG)
-	    for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
-		pmap->green[*ppix].refcnt = 0;
-	if (okB)
-	    for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
-		pmap->blue[*ppix].refcnt = 0;
-	free(ppixBlue);
-	free(ppixGreen);
-	free(ppixRed);
-	return BadAlloc;
-    }
-
-    *prmask <<= pmap->pVisual->offsetRed;
-    *pgmask <<= pmap->pVisual->offsetGreen;
-    *pbmask <<= pmap->pVisual->offsetBlue;
-
-    ppix = rpix + pmap->numPixelsRed[client];
-    for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
-    {
-	*ppix++ = *p;
-	if(p < ppixRed + c)
-	    *pDst++ |= *p << pmap->pVisual->offsetRed;
-    }
-    pmap->numPixelsRed[client] += npixR;
-    pmap->freeRed -= npixR;
-
-    ppix = gpix + pmap->numPixelsGreen[client];
-    for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
-    {
-	*ppix++ = *p;
-	if(p < ppixGreen + c)
-	    *pDst++ |= *p << pmap->pVisual->offsetGreen;
-    }
-    pmap->numPixelsGreen[client] += npixG;
-    pmap->freeGreen -= npixG;
-
-    ppix = bpix + pmap->numPixelsBlue[client];
-    for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
-    {
-	*ppix++ = *p;
-	if(p < ppixBlue + c)
-	    *pDst++ |= *p << pmap->pVisual->offsetBlue;
-    }
-    pmap->numPixelsBlue[client] += npixB;
-    pmap->freeBlue -= npixB;
-
-
-    for (pDst = pixels; pDst < pixels + c; pDst++)
-	*pDst |= ALPHAMASK(pmap->pVisual);
-
-    free(ppixBlue);
-    free(ppixGreen);
-    free(ppixRed);
-
-    return Success;
-}
-
-static int
-AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig, 
-             Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
-{
-    Pixel	*ppix, *p, *pDst, *ppixTemp;
-    int		npix;
-    Bool	ok;
-
-    npix = c << r;
-    if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
-	return BadAlloc;
-    if(!(ppixTemp = malloc(npix * sizeof(Pixel))))
-	return BadAlloc;
-    ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
-
-    if (ok)
-    {
-
-	/* all the allocated pixels are added to the client pixel list,
-	 * but only the unique ones are returned to the client */
-	ppix = (Pixel *)realloc(pmap->clientPixelsRed[client],
-			 (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
-	if (!ppix)
-	{
-	    for (p = ppixTemp; p < ppixTemp + npix; p++)
-		pmap->red[*p].refcnt = 0;
-	    return BadAlloc;
-	}
-	pmap->clientPixelsRed[client] = ppix;
-	ppix += pmap->numPixelsRed[client];
-	*pppixFirst = ppix;
-	pDst = pixels;
-	for (p = ppixTemp; p < ppixTemp + npix; p++)
-	{
-	    *ppix++ = *p;
-	    if(p < ppixTemp + c)
-	        *pDst++ = *p;
-	}
-	pmap->numPixelsRed[client] += npix;
-	pmap->freeRed -= npix;
-    }
-    free(ppixTemp);
-    return ok ? Success : BadAlloc;
-}
-
-/* Allocates count << planes pixels from colormap pmap for client. If
- * contig, then the plane mask is made of consecutive bits.  Returns
- * all count << pixels in the array pixels. The first count of those
- * pixels are the unique pixels.  *pMask has the mask to Or with the
- * unique pixels to get the rest of them.
- *
- * Returns True iff all pixels could be allocated 
- * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
- * (see AllocShared for why we care)
- */
-static Bool
-AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes, 
-         Bool contig, Pixel *pixels, Pixel *pMask)
-{
-    EntryPtr	ent;
-    Pixel	pixel, base, entries, maxp, save;
-    int		dplanes, found;
-    Pixel	*ppix;
-    Pixel	mask;
-    Pixel	finalmask;
-
-    dplanes = pmap->pVisual->nplanes;
-
-    /* Easy case.  Allocate pixels only */
-    if (planes == 0)
-    {
-        /* allocate writable entries */
-	ppix = pixels;
-        ent = pentFirst;
-        pixel = 0;
-        while (--count >= 0)
-	{
-            /* Just find count unallocated cells */
-    	    while (ent->refcnt)
-	    {
-    	        ent++;
-    	        pixel++;
-    	    }
-    	    ent->refcnt = AllocPrivate;
-    	    *ppix++ = pixel;
-	    ent->fShared = FALSE;
-        }
-        *pMask = 0;
-        return TRUE;
-    }
-    else if (planes > dplanes)
-    {
-	return FALSE;
-    }
-
-    /* General case count pixels * 2 ^ planes cells to be allocated */
-
-    /* make room for new pixels */
-    ent = pentFirst;
-
-    /* first try for contiguous planes, since it's fastest */
-    for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
-         --dplanes >= 0;
-         mask += mask, base += base)
-    {
-        ppix = pixels;
-        found = 0;
-        pixel = 0;
-        entries = pmap->pVisual->ColormapEntries - mask;
-        while (pixel < entries)
-	{
-    	    save = pixel;
-    	    maxp = pixel + mask + base;
-    	    /* check if all are free */
-    	    while (pixel != maxp && ent[pixel].refcnt == 0)
-    	        pixel += base;
-	    if (pixel == maxp)
-		{
-		    /* this one works */
-		    *ppix++ = save;
-		    found++;
-		    if (found == count)
-		    {
-			/* found enough, allocate them all */
-			while (--count >= 0)
-			{
-			    pixel = pixels[count];
-			    maxp = pixel + mask;
-			    while (1)
-			    {
-				ent[pixel].refcnt = AllocPrivate;
-				ent[pixel].fShared = FALSE;
-				if (pixel == maxp)
-				    break;
-				pixel += base;
-				*ppix++ = pixel;
-			    }
-			}
-			*pMask = mask;
-			return TRUE;
-		    }
-		}
-    	    pixel = save + 1;
-    	    if (pixel & mask)
-    	        pixel += mask;
-        }
-    }
-
-    dplanes = pmap->pVisual->nplanes;
-    if (contig || planes == 1 || dplanes < 3)
-	return FALSE;
-
-    /* this will be very slow for large maps, need a better algorithm */
-
-    /*
-       we can generate the smallest and largest numbers that fits in dplanes
-       bits and contain exactly planes bits set as follows. First, we need to
-       check that it is possible to generate such a mask at all.
-       (Non-contiguous masks need one more bit than contiguous masks). Then
-       the smallest such mask consists of the rightmost planes-1 bits set, then
-       a zero, then a one in position planes + 1. The formula is
-         (3 << (planes-1)) -1
-       The largest such masks consists of the leftmost planes-1 bits set, then
-       a zero, then a one bit in position dplanes-planes-1. If dplanes is
-       smaller than 32 (the number of bits in a word) then the formula is:
-         (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
-       If dplanes = 32, then we can't calculate (1<<dplanes) and we have
-       to use:
-         ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
-	  
-	  << Thank you, Loretta>>>
-
-    */
-
-    finalmask =
-        (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
-	  (((Pixel)1)<<(dplanes-planes-1));
-    for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
-    {
-        /* next 3 magic statements count number of ones (HAKMEM #169) */
-        pixel = (mask >> 1) & 033333333333;
-        pixel = mask - pixel - ((pixel >> 1) & 033333333333);
-        if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
-    	    continue;
-        ppix = pixels;
-        found = 0;
-        entries = pmap->pVisual->ColormapEntries - mask;
-        base = lowbit (mask);
-        for (pixel = 0; pixel < entries; pixel++)
-	{
-	    if (pixel & mask)
-	        continue;
-	    maxp = 0;
-	    /* check if all are free */
-	    while (ent[pixel + maxp].refcnt == 0)
-	    {
-		GetNextBitsOrBreak(maxp, mask, base);
-	    }
-	    if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
-		continue;
-	    /* this one works */
-	    *ppix++ = pixel;
-	    found++;
-	    if (found < count)
-		continue;
-	    /* found enough, allocate them all */
-	    while (--count >= 0)
-	    {
-		pixel = (pixels)[count];
-		maxp = 0;
-		while (1)
-		{
-		    ent[pixel + maxp].refcnt = AllocPrivate;
-		    ent[pixel + maxp].fShared = FALSE;
-		    GetNextBitsOrBreak(maxp, mask, base);
-		    *ppix++ = pixel + maxp;
-		}
-	    }
-
-	    *pMask = mask;
-	    return TRUE;
-	}
-    }
-    return FALSE;
-}
-
-/**
- *
- *  \param ppixFirst  First of the client's new pixels
- */
-static Bool
-AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b, 
-             Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
-{
-    Pixel	*pptr, *cptr;
-    int		npix, z, npixClientNew, npixShared;
-    Pixel	basemask, base, bits, common;
-    SHAREDCOLOR *pshared, **ppshared, **psharedList;
-
-    npixClientNew = c << (r + g + b);
-    npixShared = (c << r) + (c << g) + (c << b);
-    psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *));
-    if (!psharedList)
-	return FALSE;
-    ppshared = psharedList;
-    for (z = npixShared; --z >= 0; )
-    {
-	if (!(ppshared[z] = malloc(sizeof(SHAREDCOLOR))))
-	{
-	    for (z++ ; z < npixShared; z++)
-		free(ppshared[z]);
-	    return FALSE;
-	}
-    }
-    for(pptr = ppix, npix = c; --npix >= 0; pptr++)
-    {
-	basemask = ~(gmask | bmask);
-	common = *pptr & basemask;
-	if (rmask)
-	{
-	    bits = 0;
-	    base = lowbit (rmask);
-	    while(1)
-	    {
-		pshared = *ppshared++;
-		pshared->refcnt = 1 << (g + b);
-		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-		{
-		    if ((*cptr & basemask) == (common | bits))
-		    {
-			pmap->red[*cptr].fShared = TRUE;
-			pmap->red[*cptr].co.shco.red = pshared;
-		    }
-		}
-		GetNextBitsOrBreak(bits, rmask, base);
-	    }
-	}
-	else
-	{
-	    pshared = *ppshared++;
-	    pshared->refcnt = 1 << (g + b);
-	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-	    {
-		if ((*cptr & basemask) == common)
-		{
-		    pmap->red[*cptr].fShared = TRUE;
-		    pmap->red[*cptr].co.shco.red = pshared;
-		}
-	    }
-	}
-	basemask = ~(rmask | bmask);
-	common = *pptr & basemask;
-	if (gmask)
-	{
-	    bits = 0;
-	    base = lowbit (gmask);
-	    while(1)
-	    {
-		pshared = *ppshared++;
-		pshared->refcnt = 1 << (r + b);
-		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-		{
-		    if ((*cptr & basemask) == (common | bits))
-		    {
-			pmap->red[*cptr].co.shco.green = pshared;
-		    }
-		}
-		GetNextBitsOrBreak(bits, gmask, base);
-	    }
-	}
-	else
-	{
-	    pshared = *ppshared++;
-	    pshared->refcnt = 1 << (g + b);
-	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-	    {
-		if ((*cptr & basemask) == common)
-		{
-		    pmap->red[*cptr].co.shco.green = pshared;
-		}
-	    }
-	}
-	basemask = ~(rmask | gmask);
-	common = *pptr & basemask;
-	if (bmask)
-	{
-	    bits = 0;
-	    base = lowbit (bmask);
-	    while(1)
-	    {
-		pshared = *ppshared++;
-		pshared->refcnt = 1 << (r + g);
-		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-		{
-		    if ((*cptr & basemask) == (common | bits))
-		    {
-			pmap->red[*cptr].co.shco.blue = pshared;
-		    }
-		}
-		GetNextBitsOrBreak(bits, bmask, base);
-	    }
-	}
-	else
-	{
-	    pshared = *ppshared++;
-	    pshared->refcnt = 1 << (g + b);
-	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
-	    {
-		if ((*cptr & basemask) == common)
-		{
-		    pmap->red[*cptr].co.shco.blue = pshared;
-		}
-	    }
-	}
-    }
-    free(psharedList);
-    return TRUE;
-}
-
-
-/** FreeColors
- * Free colors and/or cells (probably slow for large numbers) 
- */
-int
-FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
-{
-    int		rval, result, class;
-    Pixel	rmask;
-
-    class = pmap->class;
-    if (pmap->flags & AllAllocated)
-	return BadAccess;
-    if ((class | DynamicClass) == DirectColor)
-    {
-	rmask = mask & RGBMASK(pmap->pVisual);
-        result = FreeCo(pmap, client, REDMAP, count, pixels,
-			mask & pmap->pVisual->redMask);
-	/* If any of the three calls fails, we must report that, if more
-	 * than one fails, it's ok that we report the last one */
-        rval = FreeCo(pmap, client, GREENMAP, count, pixels,
-		      mask & pmap->pVisual->greenMask);
-	if(rval != Success)
-	    result = rval;
-	rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
-		      mask & pmap->pVisual->blueMask);
-	if(rval != Success)
-	    result = rval;
-    }
-    else
-    {
-	rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
-        result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
-    }
-    if ((mask != rmask) && count)
-    {
-	clients[client]->errorValue = *pixels | mask;
-	result = BadValue;
-    }
-    /* XXX should worry about removing any RT_CMAPENTRY resource */
-    return result;
-}
-
-/**
- * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
- * which the client has allocated in channel colormap cells of pmap.
- * doesn't change newpixels if it doesn't need to 
- *
- *  \param pmap   which colormap head
- *  \param color  which sub-map, eg, RED, BLUE, PSEUDO
- *  \param npixIn number of pixels passed in
- *  \param ppixIn number of base pixels
- *  \param mask   mask client gave us
- */
-static int
-FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
-{
-    Pixel	*ppixClient, pixTest;
-    int		npixClient, npixNew, npix;
-    Pixel	bits, base, cmask, rgbbad;
-    Pixel	*pptr, *cptr;
-    int 	n, zapped;
-    int		errVal = Success;
-    int		offset, numents;
-
-    if (npixIn == 0)
-        return errVal;
-    bits = 0;
-    zapped = 0;
-    base = lowbit (mask);
-
-    switch(color)
-    {
-      case REDMAP:
-	cmask = pmap->pVisual->redMask;
-	rgbbad = ~RGBMASK(pmap->pVisual);
-	offset = pmap->pVisual->offsetRed;
-	numents = (cmask >> offset) + 1;
-	ppixClient = pmap->clientPixelsRed[client];
-	npixClient = pmap->numPixelsRed[client];
-	break;
-      case GREENMAP:
-	cmask = pmap->pVisual->greenMask;
-	rgbbad = ~RGBMASK(pmap->pVisual);
-	offset = pmap->pVisual->offsetGreen;
-	numents = (cmask >> offset) + 1;
-	ppixClient = pmap->clientPixelsGreen[client];
-	npixClient = pmap->numPixelsGreen[client];
-	break;
-      case BLUEMAP:
-	cmask = pmap->pVisual->blueMask;
-	rgbbad = ~RGBMASK(pmap->pVisual);
-	offset = pmap->pVisual->offsetBlue;
-	numents = (cmask >> offset) + 1;
-	ppixClient = pmap->clientPixelsBlue[client];
-	npixClient = pmap->numPixelsBlue[client];
-	break;
-      default:	/* so compiler can see that everything gets initialized */
-      case PSEUDOMAP:
-	cmask = ~((Pixel)0);
-	rgbbad = 0;
-	offset = 0;
-	numents = pmap->pVisual->ColormapEntries;
-	ppixClient = pmap->clientPixelsRed[client];
-	npixClient = pmap->numPixelsRed[client];
-	break;
-    }
-
-
-    /* zap all pixels which match */
-    while (1)
-    {
-        /* go through pixel list */
-        for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
-	{
-	    pixTest = ((*pptr | bits) & cmask) >> offset;
-	    if ((pixTest >= numents) || (*pptr & rgbbad))
-	    {
-		clients[client]->errorValue = *pptr | bits;
-		errVal = BadValue;
-		continue;
-	    }
-
-	    /* find match in client list */
-	    for (cptr = ppixClient, npix = npixClient;
-	         --npix >= 0 && *cptr != pixTest;
-		 cptr++) ;
-
-	    if (npix >= 0)
-	    {
-		if (pmap->class & DynamicClass)
-		{
-		    FreeCell(pmap, pixTest, color);
-		}
-		*cptr = ~((Pixel)0);
-		zapped++;
-	    }
-	    else
-		errVal = BadAccess;
-	}
-        /* generate next bits value */
-	GetNextBitsOrBreak(bits, mask, base);
-    }
-
-    /* delete freed pixels from client pixel list */
-    if (zapped)
-    {
-        npixNew = npixClient - zapped;
-        if (npixNew)
-	{
-	    /* Since the list can only get smaller, we can do a copy in
-	     * place and then realloc to a smaller size */
-    	    pptr = cptr = ppixClient;
-
-	    /* If we have all the new pixels, we don't have to examine the
-	     * rest of the old ones */
-	    for(npix = 0; npix < npixNew; cptr++)
-	    {
-    	        if (*cptr != ~((Pixel)0))
-		{
-    		    *pptr++ = *cptr;
-		    npix++;
-    	        }
-    	    }
-	    pptr = (Pixel *)realloc(ppixClient, npixNew * sizeof(Pixel));
-	    if (pptr)
-		ppixClient = pptr;
-	    npixClient = npixNew;
-        }
-	else
-	{
-	    npixClient = 0;
-	    free(ppixClient);
-    	    ppixClient = (Pixel *)NULL;
-	}
-	switch(color)
-	{
-	  case PSEUDOMAP:
-	  case REDMAP:
-	    pmap->clientPixelsRed[client] = ppixClient;
-	    pmap->numPixelsRed[client] = npixClient;
-	    break;
-	  case GREENMAP:
-	    pmap->clientPixelsGreen[client] = ppixClient;
-	    pmap->numPixelsGreen[client] = npixClient;
-	    break;
-	  case BLUEMAP:
-	    pmap->clientPixelsBlue[client] = ppixClient;
-	    pmap->numPixelsBlue[client] = npixClient;
-	    break;
-	}
-    }
-    return errVal;
-}
-
-
-
-/* Redefine color values */
-int
-StoreColors (ColormapPtr pmap, int count, xColorItem *defs, ClientPtr client)
-{
-    Pixel 	pix;
-    xColorItem *pdef;
-    EntryPtr 	pent, pentT, pentLast;
-    VisualPtr	pVisual;
-    SHAREDCOLOR		*pred, *pgreen, *pblue;
-    int			n, ChgRed, ChgGreen, ChgBlue, idef;
-    int			class, errVal = Success;
-    int			ok;
-
-
-    class = pmap->class;
-    if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
-    {
-	return BadAccess;
-    }
-    pVisual = pmap->pVisual;
-
-    idef = 0;
-    if((class | DynamicClass) == DirectColor)
-    {
-	int numred, numgreen, numblue;
-	Pixel rgbbad;
-
-	numred = NUMRED(pVisual);
-	numgreen = NUMGREEN(pVisual);
-	numblue = NUMBLUE(pVisual);
-	rgbbad = ~RGBMASK(pVisual);
-        for (pdef = defs, n = 0; n < count; pdef++, n++)
-	{
-	    ok = TRUE;
-            (*pmap->pScreen->ResolveColor)
-	        (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
-
-	    if (pdef->pixel & rgbbad)
-	    {
-		errVal = BadValue;
-		client->errorValue = pdef->pixel;
-		continue;
-	    }
-	    pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
-	    if (pix >= numred)
-	    {
-		errVal = BadValue;
-		ok = FALSE;
-	    }
-	    else if (pmap->red[pix].refcnt != AllocPrivate)
-	    {
-		errVal = BadAccess;
-		ok = FALSE;
-	    }
-	    else if (pdef->flags & DoRed)
-	    {
-		pmap->red[pix].co.local.red = pdef->red;
-	    }
-	    else
-	    {
-		pdef->red = pmap->red[pix].co.local.red;
-	    }
-
-	    pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
-	    if (pix >= numgreen)
-	    {
-		errVal = BadValue;
-		ok = FALSE;
-	    }
-	    else if (pmap->green[pix].refcnt != AllocPrivate)
-	    {
-		errVal = BadAccess;
-		ok = FALSE;
-	    }
-	    else if (pdef->flags & DoGreen)
-	    {
-		pmap->green[pix].co.local.green = pdef->green;
-	    }
-	    else
-	    {
-		pdef->green = pmap->green[pix].co.local.green;
-	    }
-
-	    pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
-	    if (pix >= numblue)
-	    {
-		errVal = BadValue;
-		ok = FALSE;
-	    }
-	    else if (pmap->blue[pix].refcnt != AllocPrivate)
-	    {
-		errVal = BadAccess;
-		ok = FALSE;
-	    }
-	    else if (pdef->flags & DoBlue)
-	    {
-		pmap->blue[pix].co.local.blue = pdef->blue;
-	    }
-	    else
-	    {
-		pdef->blue = pmap->blue[pix].co.local.blue;
-	    }
-	    /* If this is an o.k. entry, then it gets added to the list
-	     * to be sent to the hardware.  If not, skip it.  Once we've
-	     * skipped one, we have to copy all the others.
-	     */
-	    if(ok)
-	    {
-		if(idef != n)
-		    defs[idef] = defs[n];
-		idef++;
-	    } else
-		client->errorValue = pdef->pixel;
-	}
-    }
-    else
-    {
-        for (pdef = defs, n = 0; n < count; pdef++, n++)
-	{
-
-	    ok = TRUE;
-	    if (pdef->pixel >= pVisual->ColormapEntries)
-	    {
-		client->errorValue = pdef->pixel;
-	        errVal = BadValue;
-		ok = FALSE;
-	    }
-	    else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
-	    {
-		errVal = BadAccess;
-		ok = FALSE;
-	    }
-
-	    /* If this is an o.k. entry, then it gets added to the list
-	     * to be sent to the hardware.  If not, skip it.  Once we've
-	     * skipped one, we have to copy all the others.
-	     */
-	    if(ok)
-	    {
-		if(idef != n)
-		    defs[idef] = defs[n];
-		idef++;
-	    }
-	    else
-		continue;
-
-            (*pmap->pScreen->ResolveColor)
-	        (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
-
-	    pent = &pmap->red[pdef->pixel];
-
-	    if(pdef->flags & DoRed)
-	    {
-		if(pent->fShared)
-		{
-		    pent->co.shco.red->color = pdef->red;
-		    if (pent->co.shco.red->refcnt > 1)
-			ok = FALSE;
-		}
-		else
-		    pent->co.local.red = pdef->red;
-	    }
-	    else
-	    {
-		if(pent->fShared)
-		    pdef->red = pent->co.shco.red->color;
-		else
-		    pdef->red = pent->co.local.red;
-	    }
-	    if(pdef->flags & DoGreen)
-	    {
-		if(pent->fShared)
-		{
-		    pent->co.shco.green->color = pdef->green;
-		    if (pent->co.shco.green->refcnt > 1)
-			ok = FALSE;
-		}
-		else
-		    pent->co.local.green = pdef->green;
-	    }
-	    else
-	    {
-		if(pent->fShared)
-		    pdef->green = pent->co.shco.green->color;
-		else
-		    pdef->green = pent->co.local.green;
-	    }
-	    if(pdef->flags & DoBlue)
-	    {
-		if(pent->fShared)
-		{
-		    pent->co.shco.blue->color = pdef->blue;
-		    if (pent->co.shco.blue->refcnt > 1)
-			ok = FALSE;
-		}
-		else
-		    pent->co.local.blue = pdef->blue;
-	    }
-	    else
-	    {
-		if(pent->fShared)
-		    pdef->blue = pent->co.shco.blue->color;
-		else
-		    pdef->blue = pent->co.local.blue;
-	    }
-
-	    if(!ok)
-	    {
-                /* have to run through the colormap and change anybody who
-		 * shares this value */
-	        pred = pent->co.shco.red;
-	        pgreen = pent->co.shco.green;
-	        pblue = pent->co.shco.blue;
-	        ChgRed = pdef->flags & DoRed;
-	        ChgGreen = pdef->flags & DoGreen;
-	        ChgBlue = pdef->flags & DoBlue;
-	        pentLast = pmap->red + pVisual->ColormapEntries;
-
-	        for(pentT = pmap->red; pentT < pentLast; pentT++)
-		{
-		    if(pentT->fShared && (pentT != pent))
-		    {
-			xColorItem	defChg;
-
-			/* There are, alas, devices in this world too dumb
-			 * to read their own hardware colormaps.  Sick, but
-			 * true.  So we're going to be really nice and load
-			 * the xColorItem with the proper value for all the
-			 * fields.  We will only set the flags for those
-			 * fields that actually change.  Smart devices can
-			 * arrange to change only those fields.  Dumb devices
-			 * can rest assured that we have provided for them,
-			 * and can change all three fields */
-
-			defChg.flags = 0;
-			if(ChgRed && pentT->co.shco.red == pred)
-			{
-			    defChg.flags |= DoRed;
-			}
-			if(ChgGreen && pentT->co.shco.green == pgreen)
-			{
-			    defChg.flags |= DoGreen;
-			}
-			if(ChgBlue && pentT->co.shco.blue == pblue)
-			{
-			    defChg.flags |= DoBlue;
-			}
-			if(defChg.flags != 0)
-			{
-			    defChg.pixel = pentT - pmap->red;
-			    defChg.red = pentT->co.shco.red->color;
-			    defChg.green = pentT->co.shco.green->color;
-			    defChg.blue = pentT->co.shco.blue->color;
-			    (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
-			}
-		    }
-		}
-
-	    }
-	}
-    }
-    /* Note that we use idef, the count of acceptable entries, and not
-     * count, the count of proposed entries */
-    if (idef != 0)
-	( *pmap->pScreen->StoreColors) (pmap, idef, defs);
-    return errVal;
-}
-
-int
-IsMapInstalled(Colormap map, WindowPtr pWin)
-{
-    Colormap	*pmaps;
-    int		imap, nummaps, found;
-
-    pmaps = malloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap));
-    if(!pmaps)
-	return FALSE;
-    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
-        (pWin->drawable.pScreen, pmaps);
-    found = FALSE;
-    for(imap = 0; imap < nummaps; imap++)
-    {
-	if(pmaps[imap] == map)
-	{
-	    found = TRUE;
-	    break;
-	}
-    }
-    free(pmaps);
-    return found;
-}
-
-struct colormap_lookup_data {
-    ScreenPtr pScreen;
-    VisualPtr visuals;
-};
-
-static void _colormap_find_resource(pointer value, XID id,
-				    pointer cdata)
-{
-    struct colormap_lookup_data *cmap_data = cdata;
-    VisualPtr visuals = cmap_data->visuals;
-    ScreenPtr pScreen = cmap_data->pScreen;
-    ColormapPtr cmap = value;
-    int j;
-
-    if (pScreen != cmap->pScreen)
-	return;
-
-    j = cmap->pVisual - pScreen->visuals;
-    cmap->pVisual = &visuals[j];
-}
-
-/* something has realloced the visuals, instead of breaking
-   ABI fix it up here - glx and compsite did this wrong */
-Bool
-ResizeVisualArray(ScreenPtr pScreen, int new_visual_count,
-		  DepthPtr depth)
-{
-    struct colormap_lookup_data cdata;
-    int numVisuals;
-    VisualPtr visuals;
-    XID *vids, vid;
-    int first_new_vid, first_new_visual, i;
-
-    first_new_vid = depth->numVids;
-    first_new_visual = pScreen->numVisuals;
-
-    vids = realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
-    if (!vids)
-        return FALSE;
-
-    /* its realloced now no going back if we fail the next one */
-    depth->vids = vids;
-
-    numVisuals = pScreen->numVisuals + new_visual_count;
-    visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
-    if (!visuals) {
-	return FALSE;
-    }
-
-    cdata.visuals = visuals;
-    cdata.pScreen = pScreen;
-    FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata);
-
-    pScreen->visuals = visuals;
-
-    for (i = 0; i < new_visual_count; i++) {
-	vid = FakeClientID(0);
-	pScreen->visuals[first_new_visual + i].vid = vid;
-	vids[first_new_vid + i] = vid;
-    }
-
-    depth->numVids += new_visual_count;
-    pScreen->numVisuals += new_visual_count;
-
-    return TRUE;
-}
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "misc.h"
+#include "dix.h"
+#include "dixstruct.h"
+#include "colormapst.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "windowstr.h"
+#include "privates.h"
+#include "xace.h"
+
+static Pixel FindBestPixel(
+    EntryPtr /*pentFirst*/,
+    int /*size*/,
+    xrgb * /*prgb*/,
+    int /*channel*/
+);
+
+static int AllComp(
+    EntryPtr /*pent*/,
+    xrgb * /*prgb*/
+);
+
+static int RedComp(
+    EntryPtr /*pent*/,
+    xrgb * /*prgb*/
+);
+
+static int GreenComp(
+    EntryPtr /*pent*/,
+    xrgb * /*prgb*/
+);
+
+static int BlueComp(
+    EntryPtr /*pent*/,
+    xrgb * /*prgb*/
+);
+
+static void FreePixels(
+    ColormapPtr /*pmap*/,
+    int /*client*/
+);
+
+static void CopyFree(
+    int /*channel*/,
+    int /*client*/,
+    ColormapPtr /*pmapSrc*/,
+    ColormapPtr /*pmapDst*/
+);
+
+static void FreeCell(
+    ColormapPtr /*pmap*/,
+    Pixel /*i*/,
+    int /*channel*/
+);
+
+static void UpdateColors(
+    ColormapPtr /*pmap*/
+);
+
+static int AllocDirect(
+    int /*client*/,
+    ColormapPtr /*pmap*/,
+    int /*c*/,
+    int /*r*/,
+    int /*g*/,
+    int /*b*/,
+    Bool /*contig*/,
+    Pixel * /*pixels*/,
+    Pixel * /*prmask*/,
+    Pixel * /*pgmask*/,
+    Pixel * /*pbmask*/
+);
+
+static int AllocPseudo(
+    int /*client*/,
+    ColormapPtr /*pmap*/,
+    int /*c*/,
+    int /*r*/,
+    Bool /*contig*/,
+    Pixel * /*pixels*/,
+    Pixel * /*pmask*/,
+    Pixel ** /*pppixFirst*/
+);
+
+static Bool AllocCP(
+    ColormapPtr /*pmap*/,
+    EntryPtr /*pentFirst*/,
+    int /*count*/,
+    int /*planes*/,
+    Bool /*contig*/,
+    Pixel * /*pixels*/,
+    Pixel * /*pMask*/
+);
+
+static Bool AllocShared(
+    ColormapPtr /*pmap*/,
+    Pixel * /*ppix*/,
+    int /*c*/,
+    int /*r*/,
+    int /*g*/,
+    int /*b*/,
+    Pixel /*rmask*/,
+    Pixel /*gmask*/,
+    Pixel /*bmask*/,
+    Pixel * /*ppixFirst*/
+);
+
+static int FreeCo(
+    ColormapPtr /*pmap*/,
+    int /*client*/,
+    int /*color*/,
+    int /*npixIn*/,
+    Pixel * /*ppixIn*/,
+    Pixel /*mask*/
+);
+
+static int   TellNoMap(
+    WindowPtr	/*pwin*/,
+    Colormap 	* /*pmid*/
+);
+
+static void FindColorInRootCmap (
+    ColormapPtr	/* pmap */,
+    EntryPtr	/* pentFirst */,
+    int		/* size */,
+    xrgb*	/* prgb */,
+    Pixel*	/* pPixel */,
+    int		/* channel */,
+    ColorCompareProcPtr /* comp */
+);
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+#if COMPOSITE
+#define ALPHAMASK(vis)	((vis)->nplanes < 32 ? 0 : \
+			 (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
+#else
+#define ALPHAMASK(vis)	0
+#endif
+
+#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
+
+/* GetNextBitsOrBreak(bits, mask, base)  -- 
+ * (Suggestion: First read the macro, then read this explanation.
+ *
+ * Either generate the next value to OR in to a pixel or break out of this
+ * while loop 
+ *
+ * This macro is used when we're trying to generate all 2^n combinations of
+ * bits in mask.  What we're doing here is counting in binary, except that
+ * the bits we use to count may not be contiguous.  This macro will be
+ * called 2^n times, returning a different value in bits each time. Then
+ * it will cause us to break out of a surrounding loop. (It will always be
+ * called from within a while loop.)
+ * On call: mask is the value we want to find all the combinations for
+ * base has 1 bit set where the least significant bit of mask is set
+ *
+ * For example,if mask is 01010, base should be 0010 and we count like this:
+ * 00010 (see this isn't so hard), 
+ *     then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
+ *      we add that to bits getting (0100 + 0100) =
+ * 01000 for our next value.
+ *      then we add 0010 to get 
+ * 01010 and we're done (easy as 1, 2, 3)
+ */
+#define GetNextBitsOrBreak(bits, mask, base)	\
+	    if((bits) == (mask)) 		\
+		break;		 		\
+	    (bits) += (base);		 	\
+	    while((bits) & ~(mask))		\
+		(bits) += ((bits) & ~(mask));	
+/* ID of server as client */
+#define SERVER_ID	0
+
+typedef struct _colorResource
+{
+	Colormap	mid;
+	int		client;
+} colorResource;
+
+/* Invariants:
+ * refcnt == 0 means entry is empty
+ * refcnt > 0 means entry is useable by many clients, so it can't be changed
+ * refcnt == AllocPrivate means entry owned by one client only
+ * fShared should only be set if refcnt == AllocPrivate, and only in red map
+ */
+
+
+/** 
+ * Create and initialize the color map 
+ * 
+ * \param mid    resource to use for this colormap
+ * \param alloc  1 iff all entries are allocated writable
+ */
+int
+CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, 
+                ColormapPtr *ppcmap, int alloc, int client)
+{
+    int		class, size;
+    unsigned long sizebytes;
+    ColormapPtr	pmap;
+    EntryPtr	pent;
+    int		i;
+    Pixel	*ppix, **pptr;
+
+    class = pVisual->class;
+    if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
+	return BadMatch;
+
+    size = pVisual->ColormapEntries;
+    sizebytes = (size * sizeof(Entry)) +
+		(MAXCLIENTS * sizeof(Pixel *)) +
+		(MAXCLIENTS * sizeof(int));
+    if ((class | DynamicClass) == DirectColor)
+	sizebytes *= 3;
+    sizebytes += sizeof(ColormapRec);
+    if (mid == pScreen->defColormap) {
+	pmap = malloc(sizebytes);
+	if (!pmap)
+	    return BadAlloc;
+	if (!dixAllocatePrivates(&pmap->devPrivates, PRIVATE_COLORMAP)) {
+	    free (pmap);
+	    return BadAlloc;
+	}
+    } else {
+	pmap = _dixAllocateObjectWithPrivates(sizebytes, sizebytes,
+					      offsetof(ColormapRec, devPrivates), PRIVATE_COLORMAP);
+	if (!pmap)
+	    return BadAlloc;
+    }
+#if defined(_XSERVER64)
+    pmap->pad0 = 0;
+    pmap->pad1 = 0;
+#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
+    pmap->pad2 = 0;
+#endif
+#endif
+    pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));    
+    sizebytes = size * sizeof(Entry);
+    pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
+    pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
+				 (MAXCLIENTS * sizeof(Pixel *)));
+    pmap->mid = mid;
+    pmap->flags = 0; 	/* start out with all flags clear */
+    if(mid == pScreen->defColormap)
+	pmap->flags |= IsDefault;
+    pmap->pScreen = pScreen;
+    pmap->pVisual = pVisual;
+    pmap->class = class;
+    if ((class | DynamicClass) == DirectColor)
+	size = NUMRED(pVisual);
+    pmap->freeRed = size;
+    memset((char *) pmap->red, 0, (int)sizebytes);
+    memset((char *) pmap->numPixelsRed, 0, MAXCLIENTS * sizeof(int));
+    for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
+	*pptr = (Pixel *)NULL;
+    if (alloc == AllocAll)
+    {
+	if (class & DynamicClass)
+	    pmap->flags |= AllAllocated;
+	for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
+	    pent->refcnt = AllocPrivate;
+	pmap->freeRed = 0;
+	ppix = malloc(size * sizeof(Pixel));
+	if (!ppix)
+	{
+	    free(pmap);
+	    return BadAlloc;
+	}
+	pmap->clientPixelsRed[client] = ppix;
+	for(i = 0; i < size; i++)
+	    ppix[i] = i;
+	pmap->numPixelsRed[client] = size;
+    }
+
+    if ((class | DynamicClass) == DirectColor)
+    {
+	pmap->freeGreen = NUMGREEN(pVisual);
+	pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
+				 (MAXCLIENTS * sizeof(int)));
+	pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
+	pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
+				       (MAXCLIENTS * sizeof(Pixel *)));
+	pmap->freeBlue = NUMBLUE(pVisual);
+	pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
+				(MAXCLIENTS * sizeof(int)));
+	pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
+	pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
+				      (MAXCLIENTS * sizeof(Pixel *)));
+
+	memset((char *) pmap->green, 0, (int)sizebytes);
+	memset((char *) pmap->blue, 0, (int)sizebytes);
+
+	memmove((char *) pmap->clientPixelsGreen,
+		(char *) pmap->clientPixelsRed,
+	      MAXCLIENTS * sizeof(Pixel *));
+	memmove((char *) pmap->clientPixelsBlue,
+		(char *) pmap->clientPixelsRed,
+	      MAXCLIENTS * sizeof(Pixel *));
+	memset((char *) pmap->numPixelsGreen, 0, MAXCLIENTS * sizeof(int));
+	memset((char *) pmap->numPixelsBlue, 0, MAXCLIENTS * sizeof(int));
+
+	/* If every cell is allocated, mark its refcnt */
+	if (alloc == AllocAll)
+	{
+	    size = pmap->freeGreen;
+	    for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
+		pent->refcnt = AllocPrivate;
+	    pmap->freeGreen = 0;
+	    ppix = malloc(size * sizeof(Pixel));
+	    if (!ppix)
+	    {
+		free(pmap->clientPixelsRed[client]);
+		free(pmap);
+		return BadAlloc;
+	    }
+	    pmap->clientPixelsGreen[client] = ppix;
+	    for(i = 0; i < size; i++)
+		ppix[i] = i;
+	    pmap->numPixelsGreen[client] = size;
+
+	    size = pmap->freeBlue;
+	    for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
+		pent->refcnt = AllocPrivate;
+	    pmap->freeBlue = 0;
+	    ppix = malloc(size * sizeof(Pixel));
+	    if (!ppix)
+	    {
+		free(pmap->clientPixelsGreen[client]);
+		free(pmap->clientPixelsRed[client]);
+		free(pmap);
+		return BadAlloc;
+	    }
+	    pmap->clientPixelsBlue[client] = ppix;
+	    for(i = 0; i < size; i++)
+		ppix[i] = i;
+	    pmap->numPixelsBlue[client] = size;
+	}
+    }
+    pmap->flags |= BeingCreated;
+
+    if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
+	return BadAlloc;
+
+    /*  
+     * Security creation/labeling check
+     */
+    i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP,
+		 pmap, RT_NONE, NULL, DixCreateAccess);
+    if (i != Success) {
+	FreeResource(mid, RT_NONE);
+	return i;
+    }
+
+    /* If the device wants a chance to initialize the colormap in any way,
+     * this is it.  In specific, if this is a Static colormap, this is the
+     * time to fill in the colormap's values */
+    if (!(*pScreen->CreateColormap)(pmap))
+    {
+	FreeResource (mid, RT_NONE);
+	return BadAlloc;
+    }
+    pmap->flags &= ~BeingCreated;
+    *ppcmap = pmap;
+    return Success;
+}
+
+/**
+ *
+ * \param value  must conform to DeleteType
+ */
+int
+FreeColormap (pointer value, XID mid)
+{
+    int	i;
+    EntryPtr pent;
+    ColormapPtr	pmap = (ColormapPtr)value;
+
+    if(CLIENT_ID(mid) != SERVER_ID)
+    {
+        (*pmap->pScreen->UninstallColormap) (pmap);
+        WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
+    }
+
+    /* This is the device's chance to undo anything it needs to, especially
+     * to free any storage it allocated */
+    (*pmap->pScreen->DestroyColormap)(pmap);
+
+    if(pmap->clientPixelsRed)
+    {
+	for(i = 0; i < MAXCLIENTS; i++)
+	    free(pmap->clientPixelsRed[i]);
+    }
+
+    if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
+    {
+	for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
+	    pent >= pmap->red;
+	    pent--)
+	{
+	    if(pent->fShared)
+	    {
+		if (--pent->co.shco.red->refcnt == 0)
+		    free(pent->co.shco.red);
+		if (--pent->co.shco.green->refcnt == 0)
+		    free(pent->co.shco.green);
+		if (--pent->co.shco.blue->refcnt == 0)
+		    free(pent->co.shco.blue);
+	    }
+	}
+    }
+    if((pmap->class | DynamicClass) == DirectColor)
+    {
+        for(i = 0; i < MAXCLIENTS; i++)
+	{
+            free(pmap->clientPixelsGreen[i]);
+            free(pmap->clientPixelsBlue[i]);
+        }
+    }
+
+    if (pmap->flags & IsDefault) {
+	dixFreePrivates(pmap->devPrivates, PRIVATE_COLORMAP);
+	free(pmap);
+    } else
+	dixFreeObjectWithPrivates(pmap, PRIVATE_COLORMAP);
+    return Success;
+}
+
+/* Tell window that pmid has disappeared */
+static int
+TellNoMap (WindowPtr pwin, Colormap *pmid)
+{
+    xEvent 	xE;
+
+    if (wColormap(pwin) == *pmid)
+    {
+	/* This should be call to DeliverEvent */
+	xE.u.u.type = ColormapNotify;
+	xE.u.colormap.window = pwin->drawable.id;
+	xE.u.colormap.colormap = None;
+	xE.u.colormap.new = TRUE;
+	xE.u.colormap.state = ColormapUninstalled;
+#ifdef PANORAMIX
+        if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
+#endif
+	   DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+	if (pwin->optional) {
+	    pwin->optional->colormap = None;
+	    CheckWindowOptionalNeed (pwin);
+	}
+    }
+
+    return WT_WALKCHILDREN;
+}
+
+/* Tell window that pmid got uninstalled */
+int
+TellLostMap (WindowPtr pwin, pointer value)
+{
+    Colormap 	*pmid = (Colormap *)value;
+    xEvent 	xE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+	return WT_STOPWALKING;
+#endif
+    if (wColormap(pwin) == *pmid)
+    {
+	/* This should be call to DeliverEvent */
+	xE.u.u.type = ColormapNotify;
+	xE.u.colormap.window = pwin->drawable.id;
+	xE.u.colormap.colormap = *pmid;
+	xE.u.colormap.new = FALSE;
+	xE.u.colormap.state = ColormapUninstalled;
+	DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+    }
+
+    return WT_WALKCHILDREN;
+}
+
+/* Tell window that pmid got installed */
+int
+TellGainedMap (WindowPtr pwin, pointer value)
+{
+    Colormap 	*pmid = (Colormap *)value;
+    xEvent 	xE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+	return WT_STOPWALKING;
+#endif
+    if (wColormap (pwin) == *pmid)
+    {
+	/* This should be call to DeliverEvent */
+	xE.u.u.type = ColormapNotify;
+	xE.u.colormap.window = pwin->drawable.id;
+	xE.u.colormap.colormap = *pmid;
+	xE.u.colormap.new = FALSE;
+	xE.u.colormap.state = ColormapInstalled;
+	DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+    }
+
+    return WT_WALKCHILDREN;
+}
+
+  
+int
+CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
+{
+    ColormapPtr	pmap = (ColormapPtr) NULL;
+    int		result, alloc, size;
+    Colormap	midSrc;
+    ScreenPtr	pScreen;
+    VisualPtr	pVisual;
+
+    pScreen = pSrc->pScreen;
+    pVisual = pSrc->pVisual;
+    midSrc = pSrc->mid;
+    alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
+            AllocAll : AllocNone;
+    size = pVisual->ColormapEntries;
+
+    /* If the create returns non-0, it failed */
+    result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
+    if(result != Success)
+        return result;
+    if(alloc == AllocAll)
+    {
+	memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
+	if((pmap->class | DynamicClass) == DirectColor)
+	{
+	    memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
+	    memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
+	}
+	pSrc->flags &= ~AllAllocated;
+	FreePixels(pSrc, client);
+	UpdateColors(pmap);
+	return Success;
+    }
+
+    CopyFree(REDMAP, client, pSrc, pmap);
+    if ((pmap->class | DynamicClass) == DirectColor)
+    {
+	CopyFree(GREENMAP, client, pSrc, pmap);
+	CopyFree(BLUEMAP, client, pSrc, pmap);
+    }
+    if (pmap->class & DynamicClass)
+	UpdateColors(pmap);
+    /* XXX should worry about removing any RT_CMAPENTRY resource */
+    return Success;
+}
+
+/* Helper routine for freeing large numbers of cells from a map */
+static void
+CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
+{
+    int		z, npix;
+    EntryPtr	pentSrcFirst, pentDstFirst;
+    EntryPtr	pentSrc, pentDst;
+    Pixel	*ppix;
+    int		nalloc;
+
+    switch(channel)
+    {
+      default:	/* so compiler can see that everything gets initialized */
+      case REDMAP:
+	ppix = (pmapSrc->clientPixelsRed)[client];
+	npix = (pmapSrc->numPixelsRed)[client];
+	pentSrcFirst = pmapSrc->red;
+	pentDstFirst = pmapDst->red;
+	break;
+      case GREENMAP:
+	ppix = (pmapSrc->clientPixelsGreen)[client];
+	npix = (pmapSrc->numPixelsGreen)[client];
+	pentSrcFirst = pmapSrc->green;
+	pentDstFirst = pmapDst->green;
+	break;
+      case BLUEMAP:
+	ppix = (pmapSrc->clientPixelsBlue)[client];
+	npix = (pmapSrc->numPixelsBlue)[client];
+	pentSrcFirst = pmapSrc->blue;
+	pentDstFirst = pmapDst->blue;
+	break;
+    }
+    nalloc = 0;
+    if (pmapSrc->class & DynamicClass)
+    {
+	for(z = npix; --z >= 0; ppix++)
+	{
+	    /* Copy entries */
+	    pentSrc = pentSrcFirst + *ppix;
+	    pentDst = pentDstFirst + *ppix;
+	    if (pentDst->refcnt > 0)
+	    {
+		pentDst->refcnt++;
+	    }
+	    else
+	    {
+		*pentDst = *pentSrc;
+		nalloc++;
+		if (pentSrc->refcnt > 0)
+		    pentDst->refcnt = 1;
+		else
+		    pentSrc->fShared = FALSE;
+	    }
+	    FreeCell(pmapSrc, *ppix, channel);
+	}
+    }
+
+    /* Note that FreeCell has already fixed pmapSrc->free{Color} */
+    switch(channel)
+    {
+      case REDMAP:
+        pmapDst->freeRed -= nalloc;
+        (pmapDst->clientPixelsRed)[client] =
+	    (pmapSrc->clientPixelsRed)[client];
+        (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
+        (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
+        (pmapSrc->numPixelsRed)[client] = 0;
+	break;
+      case GREENMAP:
+        pmapDst->freeGreen -= nalloc;
+        (pmapDst->clientPixelsGreen)[client] =
+	    (pmapSrc->clientPixelsGreen)[client];
+        (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
+        (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
+        (pmapSrc->numPixelsGreen)[client] = 0;
+	break;
+      case BLUEMAP:
+        pmapDst->freeBlue -= nalloc;
+        pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
+        pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
+        pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
+        pmapSrc->numPixelsBlue[client] = 0;
+	break;
+    }
+}
+
+/* Free the ith entry in a color map.  Must handle freeing of
+ * colors allocated through AllocColorPlanes */
+static void
+FreeCell (ColormapPtr pmap, Pixel i, int channel)
+{
+    EntryPtr pent;
+    int	*pCount;
+
+
+    switch (channel)
+    {
+      default:	/* so compiler can see that everything gets initialized */
+      case PSEUDOMAP:
+      case REDMAP:
+          pent = (EntryPtr) &pmap->red[i];
+	  pCount = &pmap->freeRed;
+	  break;
+      case GREENMAP:
+          pent = (EntryPtr) &pmap->green[i];
+	  pCount = &pmap->freeGreen;
+	  break;
+      case BLUEMAP:
+          pent = (EntryPtr) &pmap->blue[i];
+	  pCount = &pmap->freeBlue;
+	  break;
+    }
+    /* If it's not privately allocated and it's not time to free it, just
+     * decrement the count */
+    if (pent->refcnt > 1)
+	pent->refcnt--;
+    else
+    {
+        /* If the color type is shared, find the sharedcolor. If decremented
+         * refcnt is 0, free the shared cell. */
+        if (pent->fShared)
+	{
+	    if(--pent->co.shco.red->refcnt == 0)
+		free(pent->co.shco.red);
+	    if(--pent->co.shco.green->refcnt == 0)
+		free(pent->co.shco.green);
+	    if(--pent->co.shco.blue->refcnt == 0)
+		free(pent->co.shco.blue);
+	    pent->fShared = FALSE;
+	}
+	pent->refcnt = 0;
+	*pCount += 1;
+    }
+}
+
+static void
+UpdateColors (ColormapPtr pmap)
+{
+    xColorItem		*defs;
+    xColorItem *pdef;
+    EntryPtr 	pent;
+    VisualPtr	pVisual;
+    int			i, n, size;
+
+    pVisual = pmap->pVisual;
+    size = pVisual->ColormapEntries;
+    defs = malloc(size * sizeof(xColorItem));
+    if (!defs)
+	return;
+    n = 0;
+    pdef = defs;
+    if (pmap->class == DirectColor)
+    {
+        for (i = 0; i < size; i++)
+	{
+	    if (!pmap->red[i].refcnt &&
+		!pmap->green[i].refcnt &&
+		!pmap->blue[i].refcnt)
+		continue;
+	    pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
+			  ((Pixel)i << pVisual->offsetGreen) |
+			  ((Pixel)i << pVisual->offsetBlue);
+	    pdef->red = pmap->red[i].co.local.red;
+	    pdef->green = pmap->green[i].co.local.green;
+	    pdef->blue = pmap->blue[i].co.local.blue;
+	    pdef->flags = DoRed|DoGreen|DoBlue;
+	    pdef++;
+	    n++;
+	}
+    }
+    else
+    {
+        for (i = 0, pent = pmap->red; i < size; i++, pent++)
+	{
+	    if (!pent->refcnt)
+		continue;
+	    pdef->pixel = i;
+	    if(pent->fShared)
+	    {
+		pdef->red = pent->co.shco.red->color;
+		pdef->green = pent->co.shco.green->color;
+		pdef->blue = pent->co.shco.blue->color;
+	    }
+	    else
+	    {
+		pdef->red = pent->co.local.red;
+		pdef->green = pent->co.local.green;
+		pdef->blue = pent->co.local.blue;
+	    }
+	    pdef->flags = DoRed|DoGreen|DoBlue;
+	    pdef++;
+	    n++;
+	}
+    }
+    if (n)
+	(*pmap->pScreen->StoreColors)(pmap, n, defs);
+    free(defs);
+}
+
+/* Get a read-only color from a ColorMap (probably slow for large maps)
+ * Returns by changing the value in pred, pgreen, pblue and pPix
+ */
+int
+AllocColor (ColormapPtr pmap, 
+            unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, 
+            Pixel *pPix, int client)
+{
+    Pixel	pixR, pixG, pixB;
+    int		entries;
+    xrgb	rgb;
+    int		class;
+    VisualPtr	pVisual;
+    int		npix;
+    Pixel	*ppix;
+
+    pVisual = pmap->pVisual;
+    (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
+    rgb.red = *pred;
+    rgb.green = *pgreen;
+    rgb.blue = *pblue;
+    class = pmap->class;
+    entries = pVisual->ColormapEntries;
+
+    /* If the colormap is being created, then we want to be able to change
+     * the colormap, even if it's a static type. Otherwise, we'd never be
+     * able to initialize static colormaps
+     */
+    if(pmap->flags & BeingCreated)
+	class |= DynamicClass;
+
+    /* If this is one of the static storage classes, and we're not initializing
+     * it, the best we can do is to find the closest color entry to the
+     * requested one and return that.
+     */
+    switch (class) {
+    case StaticColor:
+    case StaticGray:
+	/* Look up all three components in the same pmap */
+	*pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+	*pred = pmap->red[pixR].co.local.red;
+	*pgreen = pmap->red[pixR].co.local.green;
+	*pblue = pmap->red[pixR].co.local.blue;
+	npix = pmap->numPixelsRed[client];
+	ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+				  (npix + 1) * sizeof(Pixel));
+	if (!ppix)
+	    return BadAlloc;
+	ppix[npix] = pixR;
+	pmap->clientPixelsRed[client] = ppix;
+	pmap->numPixelsRed[client]++;
+	break;
+
+    case TrueColor:
+	/* Look up each component in its own map, then OR them together */
+	pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+	pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+	pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+	*pPix = (pixR << pVisual->offsetRed) |
+		(pixG << pVisual->offsetGreen) |
+		(pixB << pVisual->offsetBlue) |
+		ALPHAMASK(pVisual);
+	
+	*pred = pmap->red[pixR].co.local.red;
+	*pgreen = pmap->green[pixG].co.local.green;
+	*pblue = pmap->blue[pixB].co.local.blue;
+	npix = pmap->numPixelsRed[client];
+	ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+				  (npix + 1) * sizeof(Pixel));
+	if (!ppix)
+	    return BadAlloc;
+	ppix[npix] = pixR;
+	pmap->clientPixelsRed[client] = ppix;
+	npix = pmap->numPixelsGreen[client];
+	ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+				  (npix + 1) * sizeof(Pixel));
+	if (!ppix)
+	    return BadAlloc;
+	ppix[npix] = pixG;
+	pmap->clientPixelsGreen[client] = ppix;
+	npix = pmap->numPixelsBlue[client];
+	ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+				  (npix + 1) * sizeof(Pixel));
+	if (!ppix)
+	    return BadAlloc;
+	ppix[npix] = pixB;
+	pmap->clientPixelsBlue[client] = ppix;
+	pmap->numPixelsRed[client]++;
+	pmap->numPixelsGreen[client]++;
+	pmap->numPixelsBlue[client]++;
+	break;
+
+    case GrayScale:
+    case PseudoColor:
+	if (pmap->mid != pmap->pScreen->defColormap &&
+	    pmap->pVisual->vid == pmap->pScreen->rootVisual)
+	{
+	    ColormapPtr prootmap;
+	    dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+				    RT_COLORMAP, clients[client], DixReadAccess);
+
+	    if (pmap->class == prootmap->class)
+		FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, 
+			pPix, PSEUDOMAP, AllComp);
+	}
+	if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
+		      client, AllComp) != Success)
+	    return BadAlloc;
+        break;
+
+    case DirectColor:
+	if (pmap->mid != pmap->pScreen->defColormap &&
+	    pmap->pVisual->vid == pmap->pScreen->rootVisual)
+	{
+	    ColormapPtr prootmap;
+	    dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+				    RT_COLORMAP, clients[client], DixReadAccess);
+
+	    if (pmap->class == prootmap->class)
+	    {
+		pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; 
+		FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, 
+			&pixR, REDMAP, RedComp);
+		pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; 
+		FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb, 
+			&pixG, GREENMAP, GreenComp);
+		pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; 
+		FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb, 
+			&pixB, BLUEMAP, BlueComp);
+		*pPix = pixR | pixG | pixB;
+	    }
+	}
+
+	pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; 
+	if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+		      client, RedComp) != Success)
+	    return BadAlloc;
+	pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; 
+	if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+		      GREENMAP, client, GreenComp) != Success)
+	{
+	    (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+	    return BadAlloc;
+	}
+	pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; 
+	if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+		      client, BlueComp) != Success)
+	{
+	    (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
+	    (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+	    return BadAlloc;
+	}
+	*pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
+
+	break;
+    }
+
+    /* if this is the client's first pixel in this colormap, tell the
+     * resource manager that the client has pixels in this colormap which
+     * should be freed when the client dies */
+    if ((pmap->numPixelsRed[client] == 1) &&
+	(CLIENT_ID(pmap->mid) != client) &&
+	!(pmap->flags & BeingCreated))
+    {
+	colorResource	*pcr;
+
+	pcr = malloc(sizeof(colorResource));
+	if (!pcr)
+	{
+	    (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
+	    return BadAlloc;
+	}
+	pcr->mid = pmap->mid;
+	pcr->client = client;
+	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+	    return BadAlloc;
+    }
+    return Success;
+}
+
+/*
+ * FakeAllocColor -- fake an AllocColor request by
+ * returning a free pixel if availible, otherwise returning
+ * the closest matching pixel.  This is used by the mi
+ * software sprite code to recolor cursors.  A nice side-effect
+ * is that this routine will never return failure.
+ */
+
+void
+FakeAllocColor (ColormapPtr pmap, xColorItem *item)
+{
+    Pixel pixR, pixG, pixB;
+    Pixel temp;
+    int	entries;
+    xrgb rgb;
+    int	class;
+    VisualPtr pVisual;
+
+    pVisual = pmap->pVisual;
+    rgb.red = item->red;
+    rgb.green = item->green;
+    rgb.blue = item->blue;
+    (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
+    class = pmap->class;
+    entries = pVisual->ColormapEntries;
+
+    switch (class) {
+    case GrayScale:
+    case PseudoColor:
+	temp = 0;
+	item->pixel = 0;
+	if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
+		      -1, AllComp) == Success) {
+	    item->pixel = temp;
+	    break;
+	}
+	/* fall through ... */
+    case StaticColor:
+    case StaticGray:
+	item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+	break;
+
+    case DirectColor:
+	/* Look up each component in its own map, then OR them together */
+	pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed; 
+	pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen; 
+	pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue; 
+	if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+		      -1, RedComp) != Success)
+	    pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
+			<< pVisual->offsetRed;
+	if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+		      GREENMAP, -1, GreenComp) != Success)
+	    pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
+				 GREENMAP) << pVisual->offsetGreen;
+	if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+		      -1, BlueComp) != Success)
+	    pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
+			<< pVisual->offsetBlue;
+	item->pixel = pixR | pixG | pixB;
+	break;
+
+    case TrueColor:
+	/* Look up each component in its own map, then OR them together */
+	pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+	pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+	pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+	item->pixel = (pixR << pVisual->offsetRed) |
+		      (pixG << pVisual->offsetGreen) |
+		      (pixB << pVisual->offsetBlue);
+	break;
+    }
+}
+
+/* free a pixel value obtained from FakeAllocColor */
+void
+FakeFreeColor(ColormapPtr pmap, Pixel pixel)
+{
+    VisualPtr pVisual;
+    Pixel pixR, pixG, pixB;
+
+    switch (pmap->class) {
+    case GrayScale:
+    case PseudoColor:
+	if (pmap->red[pixel].refcnt == AllocTemporary)
+	    pmap->red[pixel].refcnt = 0;
+	break;
+    case DirectColor:
+	pVisual = pmap->pVisual;
+	pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed; 
+	pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; 
+	pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; 
+	if (pmap->red[pixR].refcnt == AllocTemporary)
+	    pmap->red[pixR].refcnt = 0;
+	if (pmap->green[pixG].refcnt == AllocTemporary)
+	    pmap->green[pixG].refcnt = 0;
+	if (pmap->blue[pixB].refcnt == AllocTemporary)
+	    pmap->blue[pixB].refcnt = 0;
+	break;
+    }
+}
+
+typedef unsigned short	BigNumUpper;
+typedef unsigned long	BigNumLower;
+
+#define BIGNUMLOWERBITS	24
+#define BIGNUMUPPERBITS	16
+#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
+#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
+#define UPPERPART(i)	((i) >> BIGNUMLOWERBITS)
+#define LOWERPART(i)	((i) & (BIGNUMLOWER - 1))
+
+typedef struct _bignum {
+    BigNumUpper	upper;
+    BigNumLower	lower;
+} BigNumRec, *BigNumPtr;
+
+#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
+			    ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
+
+#define UnsignedToBigNum(u,r)	(((r)->upper = UPPERPART(u)), \
+				 ((r)->lower = LOWERPART(u)))
+
+#define MaxBigNum(r)		(((r)->upper = BIGNUMUPPER-1), \
+				 ((r)->lower = BIGNUMLOWER-1))
+
+static void
+BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
+{
+    BigNumLower	lower, carry = 0;
+
+    lower = x->lower + y->lower;
+    if (lower >= BIGNUMLOWER) {
+	lower -= BIGNUMLOWER;
+	carry = 1;
+    }
+    r->lower = lower;
+    r->upper = x->upper + y->upper + carry;
+}
+
+static Pixel
+FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
+{
+    EntryPtr	pent;
+    Pixel	pixel, final;
+    long	dr, dg, db;
+    unsigned long   sq;
+    BigNumRec	minval, sum, temp;
+
+    final = 0;
+    MaxBigNum(&minval);
+    /* look for the minimal difference */
+    for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
+    {
+	dr = dg = db = 0;
+	switch(channel)
+	{
+	  case PSEUDOMAP:
+	      dg = (long) pent->co.local.green - prgb->green;
+	      db = (long) pent->co.local.blue - prgb->blue;
+	  case REDMAP:
+	      dr = (long) pent->co.local.red - prgb->red;
+	      break;
+	  case GREENMAP:
+	      dg = (long) pent->co.local.green - prgb->green;
+	      break;
+	  case BLUEMAP:
+	      db = (long) pent->co.local.blue - prgb->blue;
+	      break;
+	}
+	sq = dr * dr;
+	UnsignedToBigNum (sq, &sum);
+	sq = dg * dg;
+	UnsignedToBigNum (sq, &temp);
+	BigNumAdd (&sum, &temp, &sum);
+	sq = db * db;
+	UnsignedToBigNum (sq, &temp);
+	BigNumAdd (&sum, &temp, &sum);
+	if (BigNumGreater (&minval, &sum))
+	{
+	    final = pixel;
+	    minval = sum;
+	}
+    }
+    return final;
+}
+
+static void
+FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size, 
+                     xrgb *prgb, Pixel *pPixel, int channel, 
+                     ColorCompareProcPtr comp)
+{
+    EntryPtr    pent;
+    Pixel	pixel;
+    int         count;
+
+    if ((pixel = *pPixel) >= size)
+	pixel = 0;
+    for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
+    {
+	if (pent->refcnt > 0 && (*comp) (pent, prgb))
+	{
+	    switch (channel)
+	    {
+	    case REDMAP:
+		pixel <<= pmap->pVisual->offsetRed;
+		break;
+	    case GREENMAP:
+		pixel <<= pmap->pVisual->offsetGreen;
+		break;
+	    case BLUEMAP:
+		pixel <<= pmap->pVisual->offsetBlue;
+		break;
+	    default: /* PSEUDOMAP */
+		break;
+	    }
+	    *pPixel = pixel;
+	}
+    }
+}
+
+/* Tries to find a color in pmap that exactly matches the one requested in prgb
+ * if it can't it allocates one.
+ * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
+ * load *pPixel with that value, otherwise set it to 0
+ */
+int
+FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb, 
+           Pixel *pPixel, int channel, int client, 
+           ColorCompareProcPtr comp)
+{
+    EntryPtr	pent;
+    Bool	foundFree;
+    Pixel	pixel, Free = 0;
+    int		npix, count, *nump = NULL;
+    Pixel	**pixp = NULL, *ppix;
+    xColorItem	def;
+
+    foundFree = FALSE;
+
+    if((pixel = *pPixel) >= size)
+	pixel = 0;
+    /* see if there is a match, and also look for a free entry */
+    for (pent = pentFirst + pixel, count = size; --count >= 0; )
+    {
+        if (pent->refcnt > 0)
+	{
+    	    if ((*comp) (pent, prgb))
+	    {
+		if (client >= 0)
+		    pent->refcnt++;
+		*pPixel = pixel;
+		switch(channel)
+		{
+		  case REDMAP:
+		    *pPixel <<= pmap->pVisual->offsetRed;
+		  case PSEUDOMAP:
+		    break;
+		  case GREENMAP:
+		    *pPixel <<= pmap->pVisual->offsetGreen;
+		    break;
+		  case BLUEMAP:
+		    *pPixel <<= pmap->pVisual->offsetBlue;
+		    break;
+		}
+		goto gotit;
+    	    }
+        }
+	else if (!foundFree && pent->refcnt == 0)
+	{
+	    Free = pixel;
+	    foundFree = TRUE;
+	    /* If we're initializing the colormap, then we are looking for
+	     * the first free cell we can find, not to minimize the number
+	     * of entries we use.  So don't look any further. */
+	    if(pmap->flags & BeingCreated)
+		break;
+	}
+	pixel++;
+	if(pixel >= size)
+	{
+	    pent = pentFirst;
+	    pixel = 0;
+	}
+	else
+	    pent++;
+    }
+
+    /* If we got here, we didn't find a match.  If we also didn't find
+     * a free entry, we're out of luck.  Otherwise, we'll usurp a free
+     * entry and fill it in */
+    if (!foundFree)
+	return BadAlloc;
+    pent = pentFirst + Free;
+    pent->fShared = FALSE;
+    pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
+
+    switch (channel)
+    {
+      case PSEUDOMAP:
+        pent->co.local.red = prgb->red;
+        pent->co.local.green = prgb->green;
+        pent->co.local.blue = prgb->blue;
+        def.red = prgb->red;
+	def.green = prgb->green;
+	def.blue = prgb->blue;
+	def.flags = (DoRed|DoGreen|DoBlue);
+	if (client >= 0)
+	    pmap->freeRed--;
+	def.pixel = Free;
+	break;
+
+      case REDMAP:
+        pent->co.local.red = prgb->red;
+        def.red = prgb->red;
+	def.green = pmap->green[0].co.local.green;
+	def.blue = pmap->blue[0].co.local.blue;
+	def.flags = DoRed;
+	if (client >= 0)
+	    pmap->freeRed--;
+	def.pixel = Free << pmap->pVisual->offsetRed;
+	break;
+
+      case GREENMAP:
+	pent->co.local.green = prgb->green;
+	def.red = pmap->red[0].co.local.red;
+        def.green = prgb->green;
+	def.blue = pmap->blue[0].co.local.blue;
+	def.flags = DoGreen;
+	if (client >= 0)
+	    pmap->freeGreen--;
+	def.pixel = Free << pmap->pVisual->offsetGreen;
+	break;
+
+      case BLUEMAP:
+	pent->co.local.blue = prgb->blue;
+	def.red = pmap->red[0].co.local.red;
+	def.green = pmap->green[0].co.local.green;
+	def.blue = prgb->blue;
+	def.flags = DoBlue;
+	if (client >= 0)
+	    pmap->freeBlue--;
+	def.pixel = Free << pmap->pVisual->offsetBlue;
+	break;
+    }
+    (*pmap->pScreen->StoreColors) (pmap, 1, &def);
+    pixel = Free;	
+    *pPixel = def.pixel;
+
+gotit:
+    if (pmap->flags & BeingCreated || client == -1)
+	return Success;
+    /* Now remember the pixel, for freeing later */
+    switch (channel)
+    {
+      case PSEUDOMAP:
+      case REDMAP:
+	nump = pmap->numPixelsRed;
+	pixp = pmap->clientPixelsRed;
+	break;
+
+      case GREENMAP:
+	nump = pmap->numPixelsGreen;
+	pixp = pmap->clientPixelsGreen;
+	break;
+
+      case BLUEMAP:
+	nump = pmap->numPixelsBlue;
+	pixp = pmap->clientPixelsBlue;
+	break;
+    }
+    npix = nump[client];
+    ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel));
+    if (!ppix)
+    {
+	pent->refcnt--;
+	if (!pent->fShared)
+	    switch (channel)
+	    {
+	      case PSEUDOMAP:
+	      case REDMAP:
+		pmap->freeRed++;
+		break;
+	      case GREENMAP:
+		pmap->freeGreen++;
+		break;
+	      case BLUEMAP:
+		pmap->freeBlue++;
+		break;
+	    }
+	return BadAlloc;
+    }
+    ppix[npix] = pixel;
+    pixp[client] = ppix;
+    nump[client]++;
+
+    return Success;
+}
+
+/* Comparison functions -- passed to FindColor to determine if an
+ * entry is already the color we're looking for or not */
+static int
+AllComp (EntryPtr pent, xrgb *prgb)
+{
+    if((pent->co.local.red == prgb->red) &&
+       (pent->co.local.green == prgb->green) &&
+       (pent->co.local.blue == prgb->blue) )
+       return 1;
+    return 0;
+}
+
+static int
+RedComp (EntryPtr pent, xrgb *prgb)
+{
+    if (pent->co.local.red == prgb->red) 
+	return 1;
+    return 0;
+}
+
+static int
+GreenComp (EntryPtr pent, xrgb *prgb)
+{
+    if (pent->co.local.green == prgb->green) 
+	return 1;
+    return 0;
+}
+
+static int
+BlueComp (EntryPtr pent, xrgb *prgb)
+{
+    if (pent->co.local.blue == prgb->blue) 
+	return 1;
+    return 0;
+}
+
+
+/* Read the color value of a cell */
+
+int
+QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList, ClientPtr client)
+{
+    Pixel	*ppix, pixel;
+    xrgb	*prgb;
+    VisualPtr	pVisual;
+    EntryPtr	pent;
+    Pixel	i;
+    int		errVal = Success;
+
+    pVisual = pmap->pVisual;
+    if ((pmap->class | DynamicClass) == DirectColor)
+    {
+	int numred, numgreen, numblue;
+	Pixel rgbbad;
+
+	numred = NUMRED(pVisual);
+	numgreen = NUMGREEN(pVisual);
+	numblue = NUMBLUE(pVisual);
+	rgbbad = ~RGBMASK(pVisual);
+	for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+	{
+	    pixel = *ppix;
+	    if (pixel & rgbbad) {
+		client->errorValue = pixel;
+		errVal =  BadValue;
+		continue;
+	    }
+	    i  = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+	    if (i >= numred)
+	    {
+		client->errorValue = pixel;
+		errVal =  BadValue;
+		continue;
+	    }
+	    prgb->red = pmap->red[i].co.local.red;
+	    i  = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+	    if (i >= numgreen)
+	    {
+		client->errorValue = pixel;
+		errVal =  BadValue;
+		continue;
+	    }
+	    prgb->green = pmap->green[i].co.local.green;
+	    i  = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+	    if (i >= numblue)
+	    {
+		client->errorValue = pixel;
+		errVal =  BadValue;
+		continue;
+	    }
+	    prgb->blue = pmap->blue[i].co.local.blue;
+	}
+    }
+    else
+    {
+	for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+	{
+	    pixel = *ppix;
+	    if (pixel >= pVisual->ColormapEntries)
+	    {
+		client->errorValue = pixel;
+		errVal = BadValue;
+	    }
+	    else
+	    {
+		pent = (EntryPtr)&pmap->red[pixel];
+		if (pent->fShared)
+		{
+		    prgb->red = pent->co.shco.red->color;
+		    prgb->green = pent->co.shco.green->color;
+		    prgb->blue = pent->co.shco.blue->color;
+		}
+		else
+		{
+		    prgb->red = pent->co.local.red;
+		    prgb->green = pent->co.local.green;
+		    prgb->blue = pent->co.local.blue;
+		}
+	    }
+	}
+    }
+    return errVal;
+}
+
+static void
+FreePixels(ColormapPtr pmap, int client)
+{
+    Pixel *ppix, *ppixStart;
+    int n;
+    int	class;
+
+    class = pmap->class;
+    ppixStart = pmap->clientPixelsRed[client];
+    if (class & DynamicClass)
+    {
+	n = pmap->numPixelsRed[client];
+	for (ppix = ppixStart; --n >= 0; )
+	{
+	    FreeCell(pmap, *ppix, REDMAP);
+	    ppix++;
+	}
+    }
+
+    free(ppixStart);
+    pmap->clientPixelsRed[client] = (Pixel *) NULL;
+    pmap->numPixelsRed[client] = 0;
+    if ((class | DynamicClass) == DirectColor) 
+    {
+        ppixStart = pmap->clientPixelsGreen[client];
+	if (class & DynamicClass)
+	    for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
+		FreeCell(pmap, *ppix++, GREENMAP);
+	free(ppixStart);
+	pmap->clientPixelsGreen[client] = (Pixel *) NULL;
+	pmap->numPixelsGreen[client] = 0;
+
+        ppixStart = pmap->clientPixelsBlue[client];
+	if (class & DynamicClass)
+	    for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
+		FreeCell(pmap, *ppix++, BLUEMAP);
+	free(ppixStart);
+	pmap->clientPixelsBlue[client] = (Pixel *) NULL;
+	pmap->numPixelsBlue[client] = 0;
+    }
+}
+
+/** 
+ * Frees all of a client's colors and cells.
+ *
+ *  \param value  must conform to DeleteType
+ *  \unused fakeid
+ */
+int
+FreeClientPixels (pointer value, XID fakeid)
+{
+    pointer pmap;
+    colorResource *pcr = value;
+    int rc;
+
+    rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient,
+				 DixRemoveAccess);
+    if (rc == Success)
+	FreePixels((ColormapPtr)pmap, pcr->client);
+    free(pcr);
+    return Success;
+}
+
+int
+AllocColorCells (int client, ColormapPtr pmap, int colors, int planes, 
+                 Bool contig, Pixel *ppix, Pixel *masks)
+{
+    Pixel	rmask, gmask, bmask, *ppixFirst, r, g, b;
+    int		n, class;
+    int		ok;
+    int		oldcount;
+    colorResource *pcr = (colorResource *)NULL;
+
+    class = pmap->class;
+    if (!(class & DynamicClass))
+	return BadAlloc; /* Shouldn't try on this type */
+    oldcount = pmap->numPixelsRed[client];
+    if (pmap->class == DirectColor)
+	oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+    if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+    {
+	pcr = malloc(sizeof(colorResource));
+	if (!pcr)
+	    return BadAlloc;
+    }
+
+    if (pmap->class == DirectColor)
+    {
+        ok = AllocDirect (client, pmap, colors, planes, planes, planes,
+			  contig, ppix, &rmask, &gmask, &bmask);
+	if(ok == Success)
+	{
+	    for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
+	    {
+		while(!(rmask & r))
+		    r += r;
+		while(!(gmask & g))
+		    g += g;
+		while(!(bmask & b))
+		    b += b;
+		*masks++ = r | g | b;
+	    }
+	}
+    }
+    else
+    {
+        ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
+			  &ppixFirst);
+	if(ok == Success)
+	{
+	    for (r = 1, n = planes; --n >= 0; r += r)
+	    {
+		while(!(rmask & r))
+		    r += r;
+		*masks++ = r;
+	    }
+	}
+    }
+
+    /* if this is the client's first pixels in this colormap, tell the
+     * resource manager that the client has pixels in this colormap which
+     * should be freed when the client dies */
+    if ((ok == Success) && pcr)
+    {
+	pcr->mid = pmap->mid;
+	pcr->client = client;
+	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+	    ok = BadAlloc;
+    } else free(pcr);
+
+    return ok;
+}
+
+
+int
+AllocColorPlanes (int client, ColormapPtr pmap, int colors, 
+                  int r, int g, int b, Bool contig, Pixel *pixels, 
+                  Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+    int		ok;
+    Pixel	mask, *ppixFirst;
+    Pixel shift;
+    int i;
+    int		class;
+    int		oldcount;
+    colorResource *pcr = (colorResource *)NULL;
+
+    class = pmap->class;
+    if (!(class & DynamicClass))
+	return BadAlloc; /* Shouldn't try on this type */
+    oldcount = pmap->numPixelsRed[client];
+    if (class == DirectColor)
+	oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+    if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+    {
+	pcr = malloc(sizeof(colorResource));
+	if (!pcr)
+	    return BadAlloc;
+    }
+
+    if (class == DirectColor)
+    {
+        ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
+			  prmask, pgmask, pbmask);
+    }
+    else
+    {
+	/* Allocate the proper pixels */
+	/* XXX This is sort of bad, because of contig is set, we force all
+	 * r + g + b bits to be contiguous.  Should only force contiguity
+	 * per mask 
+	 */
+        ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
+			  &mask, &ppixFirst);
+
+	if(ok == Success)
+	{
+	    /* now split that mask into three */
+	    *prmask = *pgmask = *pbmask = 0;
+	    shift = 1;
+	    for (i = r; --i >= 0; shift += shift)
+	    {
+		while (!(mask & shift))
+		    shift += shift;
+		*prmask |= shift;
+	    }
+	    for (i = g; --i >= 0; shift += shift)
+	    {
+		while (!(mask & shift))
+		    shift += shift;
+		*pgmask |= shift;
+	    }
+	    for (i = b; --i >= 0; shift += shift)
+	    {
+		while (!(mask & shift))
+		    shift += shift;
+		*pbmask |= shift;
+	    }
+
+	    /* set up the shared color cells */
+	    if (!AllocShared(pmap, pixels, colors, r, g, b,
+			     *prmask, *pgmask, *pbmask, ppixFirst))
+	    {
+		(void)FreeColors(pmap, client, colors, pixels, mask);
+		ok = BadAlloc;
+	    }
+	}
+    }
+
+    /* if this is the client's first pixels in this colormap, tell the
+     * resource manager that the client has pixels in this colormap which
+     * should be freed when the client dies */
+    if ((ok == Success) && pcr)
+    {
+	pcr->mid = pmap->mid;
+	pcr->client = client;
+	if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+	    ok = BadAlloc;
+    } else free(pcr);
+
+    return ok;
+}
+
+static int
+AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig, 
+             Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+    Pixel	*ppixRed, *ppixGreen, *ppixBlue;
+    Pixel	*ppix, *pDst, *p;
+    int		npix, npixR, npixG, npixB;
+    Bool	okR, okG, okB;
+    Pixel	*rpix = 0, *gpix = 0, *bpix = 0;
+
+    npixR = c << r;
+    npixG = c << g;
+    npixB = c << b;
+    if ((r >= 32) || (g >= 32) || (b >= 32) ||
+	(npixR > pmap->freeRed) || (npixR < c) ||
+	(npixG > pmap->freeGreen) || (npixG < c) ||
+	(npixB > pmap->freeBlue) || (npixB < c))
+	return BadAlloc;
+
+    /* start out with empty pixels */
+    for(p = pixels; p < pixels + c; p++)
+	*p = 0;
+
+    ppixRed = malloc(npixR * sizeof(Pixel));
+    ppixGreen = malloc(npixG * sizeof(Pixel));
+    ppixBlue = malloc(npixB * sizeof(Pixel));
+    if (!ppixRed || !ppixGreen || !ppixBlue)
+    {
+	free(ppixBlue);
+	free(ppixGreen);
+	free(ppixRed);
+	return BadAlloc;
+    }
+
+    okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
+    okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
+    okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
+
+    if (okR && okG && okB)
+    {
+	rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+				  (pmap->numPixelsRed[client] + (c << r)) *
+				  sizeof(Pixel));
+	if (rpix)
+	    pmap->clientPixelsRed[client] = rpix;
+	gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+				  (pmap->numPixelsGreen[client] + (c << g)) *
+				  sizeof(Pixel));
+	if (gpix)
+	    pmap->clientPixelsGreen[client] = gpix;
+	bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+				  (pmap->numPixelsBlue[client] + (c << b)) *
+				  sizeof(Pixel));
+	if (bpix)
+	    pmap->clientPixelsBlue[client] = bpix;
+    }
+
+    if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
+    {
+	if (okR)
+	    for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
+		pmap->red[*ppix].refcnt = 0;
+	if (okG)
+	    for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
+		pmap->green[*ppix].refcnt = 0;
+	if (okB)
+	    for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
+		pmap->blue[*ppix].refcnt = 0;
+	free(ppixBlue);
+	free(ppixGreen);
+	free(ppixRed);
+	return BadAlloc;
+    }
+
+    *prmask <<= pmap->pVisual->offsetRed;
+    *pgmask <<= pmap->pVisual->offsetGreen;
+    *pbmask <<= pmap->pVisual->offsetBlue;
+
+    ppix = rpix + pmap->numPixelsRed[client];
+    for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
+    {
+	*ppix++ = *p;
+	if(p < ppixRed + c)
+	    *pDst++ |= *p << pmap->pVisual->offsetRed;
+    }
+    pmap->numPixelsRed[client] += npixR;
+    pmap->freeRed -= npixR;
+
+    ppix = gpix + pmap->numPixelsGreen[client];
+    for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
+    {
+	*ppix++ = *p;
+	if(p < ppixGreen + c)
+	    *pDst++ |= *p << pmap->pVisual->offsetGreen;
+    }
+    pmap->numPixelsGreen[client] += npixG;
+    pmap->freeGreen -= npixG;
+
+    ppix = bpix + pmap->numPixelsBlue[client];
+    for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
+    {
+	*ppix++ = *p;
+	if(p < ppixBlue + c)
+	    *pDst++ |= *p << pmap->pVisual->offsetBlue;
+    }
+    pmap->numPixelsBlue[client] += npixB;
+    pmap->freeBlue -= npixB;
+
+
+    for (pDst = pixels; pDst < pixels + c; pDst++)
+	*pDst |= ALPHAMASK(pmap->pVisual);
+
+    free(ppixBlue);
+    free(ppixGreen);
+    free(ppixRed);
+
+    return Success;
+}
+
+static int
+AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig, 
+             Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
+{
+    Pixel	*ppix, *p, *pDst, *ppixTemp;
+    int		npix;
+    Bool	ok;
+
+    npix = c << r;
+    if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
+	return BadAlloc;
+    if(!(ppixTemp = malloc(npix * sizeof(Pixel))))
+	return BadAlloc;
+    ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
+
+    if (ok)
+    {
+
+	/* all the allocated pixels are added to the client pixel list,
+	 * but only the unique ones are returned to the client */
+	ppix = (Pixel *)realloc(pmap->clientPixelsRed[client],
+			 (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
+	if (!ppix)
+	{
+	    for (p = ppixTemp; p < ppixTemp + npix; p++)
+		pmap->red[*p].refcnt = 0;
+	    free(ppixTemp);
+	    return BadAlloc;
+	}
+	pmap->clientPixelsRed[client] = ppix;
+	ppix += pmap->numPixelsRed[client];
+	*pppixFirst = ppix;
+	pDst = pixels;
+	for (p = ppixTemp; p < ppixTemp + npix; p++)
+	{
+	    *ppix++ = *p;
+	    if(p < ppixTemp + c)
+	        *pDst++ = *p;
+	}
+	pmap->numPixelsRed[client] += npix;
+	pmap->freeRed -= npix;
+    }
+    free(ppixTemp);
+    return ok ? Success : BadAlloc;
+}
+
+/* Allocates count << planes pixels from colormap pmap for client. If
+ * contig, then the plane mask is made of consecutive bits.  Returns
+ * all count << pixels in the array pixels. The first count of those
+ * pixels are the unique pixels.  *pMask has the mask to Or with the
+ * unique pixels to get the rest of them.
+ *
+ * Returns True iff all pixels could be allocated 
+ * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
+ * (see AllocShared for why we care)
+ */
+static Bool
+AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes, 
+         Bool contig, Pixel *pixels, Pixel *pMask)
+{
+    EntryPtr	ent;
+    Pixel	pixel, base, entries, maxp, save;
+    int		dplanes, found;
+    Pixel	*ppix;
+    Pixel	mask;
+    Pixel	finalmask;
+
+    dplanes = pmap->pVisual->nplanes;
+
+    /* Easy case.  Allocate pixels only */
+    if (planes == 0)
+    {
+        /* allocate writable entries */
+	ppix = pixels;
+        ent = pentFirst;
+        pixel = 0;
+        while (--count >= 0)
+	{
+            /* Just find count unallocated cells */
+    	    while (ent->refcnt)
+	    {
+    	        ent++;
+    	        pixel++;
+    	    }
+    	    ent->refcnt = AllocPrivate;
+    	    *ppix++ = pixel;
+	    ent->fShared = FALSE;
+        }
+        *pMask = 0;
+        return TRUE;
+    }
+    else if (planes > dplanes)
+    {
+	return FALSE;
+    }
+
+    /* General case count pixels * 2 ^ planes cells to be allocated */
+
+    /* make room for new pixels */
+    ent = pentFirst;
+
+    /* first try for contiguous planes, since it's fastest */
+    for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
+         --dplanes >= 0;
+         mask += mask, base += base)
+    {
+        ppix = pixels;
+        found = 0;
+        pixel = 0;
+        entries = pmap->pVisual->ColormapEntries - mask;
+        while (pixel < entries)
+	{
+    	    save = pixel;
+    	    maxp = pixel + mask + base;
+    	    /* check if all are free */
+    	    while (pixel != maxp && ent[pixel].refcnt == 0)
+    	        pixel += base;
+	    if (pixel == maxp)
+		{
+		    /* this one works */
+		    *ppix++ = save;
+		    found++;
+		    if (found == count)
+		    {
+			/* found enough, allocate them all */
+			while (--count >= 0)
+			{
+			    pixel = pixels[count];
+			    maxp = pixel + mask;
+			    while (1)
+			    {
+				ent[pixel].refcnt = AllocPrivate;
+				ent[pixel].fShared = FALSE;
+				if (pixel == maxp)
+				    break;
+				pixel += base;
+				*ppix++ = pixel;
+			    }
+			}
+			*pMask = mask;
+			return TRUE;
+		    }
+		}
+    	    pixel = save + 1;
+    	    if (pixel & mask)
+    	        pixel += mask;
+        }
+    }
+
+    dplanes = pmap->pVisual->nplanes;
+    if (contig || planes == 1 || dplanes < 3)
+	return FALSE;
+
+    /* this will be very slow for large maps, need a better algorithm */
+
+    /*
+       we can generate the smallest and largest numbers that fits in dplanes
+       bits and contain exactly planes bits set as follows. First, we need to
+       check that it is possible to generate such a mask at all.
+       (Non-contiguous masks need one more bit than contiguous masks). Then
+       the smallest such mask consists of the rightmost planes-1 bits set, then
+       a zero, then a one in position planes + 1. The formula is
+         (3 << (planes-1)) -1
+       The largest such masks consists of the leftmost planes-1 bits set, then
+       a zero, then a one bit in position dplanes-planes-1. If dplanes is
+       smaller than 32 (the number of bits in a word) then the formula is:
+         (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
+       If dplanes = 32, then we can't calculate (1<<dplanes) and we have
+       to use:
+         ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
+	  
+	  << Thank you, Loretta>>>
+
+    */
+
+    finalmask =
+        (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
+	  (((Pixel)1)<<(dplanes-planes-1));
+    for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
+    {
+        /* next 3 magic statements count number of ones (HAKMEM #169) */
+        pixel = (mask >> 1) & 033333333333;
+        pixel = mask - pixel - ((pixel >> 1) & 033333333333);
+        if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
+    	    continue;
+        ppix = pixels;
+        found = 0;
+        entries = pmap->pVisual->ColormapEntries - mask;
+        base = lowbit (mask);
+        for (pixel = 0; pixel < entries; pixel++)
+	{
+	    if (pixel & mask)
+	        continue;
+	    maxp = 0;
+	    /* check if all are free */
+	    while (ent[pixel + maxp].refcnt == 0)
+	    {
+		GetNextBitsOrBreak(maxp, mask, base);
+	    }
+	    if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
+		continue;
+	    /* this one works */
+	    *ppix++ = pixel;
+	    found++;
+	    if (found < count)
+		continue;
+	    /* found enough, allocate them all */
+	    while (--count >= 0)
+	    {
+		pixel = (pixels)[count];
+		maxp = 0;
+		while (1)
+		{
+		    ent[pixel + maxp].refcnt = AllocPrivate;
+		    ent[pixel + maxp].fShared = FALSE;
+		    GetNextBitsOrBreak(maxp, mask, base);
+		    *ppix++ = pixel + maxp;
+		}
+	    }
+
+	    *pMask = mask;
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/**
+ *
+ *  \param ppixFirst  First of the client's new pixels
+ */
+static Bool
+AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b, 
+             Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
+{
+    Pixel	*pptr, *cptr;
+    int		npix, z, npixClientNew, npixShared;
+    Pixel	basemask, base, bits, common;
+    SHAREDCOLOR *pshared, **ppshared, **psharedList;
+
+    npixClientNew = c << (r + g + b);
+    npixShared = (c << r) + (c << g) + (c << b);
+    psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *));
+    if (!psharedList)
+	return FALSE;
+    ppshared = psharedList;
+    for (z = npixShared; --z >= 0; )
+    {
+	if (!(ppshared[z] = malloc(sizeof(SHAREDCOLOR))))
+	{
+	    for (z++ ; z < npixShared; z++)
+		free(ppshared[z]);
+	    free(psharedList);
+	    return FALSE;
+	}
+    }
+    for(pptr = ppix, npix = c; --npix >= 0; pptr++)
+    {
+	basemask = ~(gmask | bmask);
+	common = *pptr & basemask;
+	if (rmask)
+	{
+	    bits = 0;
+	    base = lowbit (rmask);
+	    while(1)
+	    {
+		pshared = *ppshared++;
+		pshared->refcnt = 1 << (g + b);
+		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+		{
+		    if ((*cptr & basemask) == (common | bits))
+		    {
+			pmap->red[*cptr].fShared = TRUE;
+			pmap->red[*cptr].co.shco.red = pshared;
+		    }
+		}
+		GetNextBitsOrBreak(bits, rmask, base);
+	    }
+	}
+	else
+	{
+	    pshared = *ppshared++;
+	    pshared->refcnt = 1 << (g + b);
+	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+	    {
+		if ((*cptr & basemask) == common)
+		{
+		    pmap->red[*cptr].fShared = TRUE;
+		    pmap->red[*cptr].co.shco.red = pshared;
+		}
+	    }
+	}
+	basemask = ~(rmask | bmask);
+	common = *pptr & basemask;
+	if (gmask)
+	{
+	    bits = 0;
+	    base = lowbit (gmask);
+	    while(1)
+	    {
+		pshared = *ppshared++;
+		pshared->refcnt = 1 << (r + b);
+		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+		{
+		    if ((*cptr & basemask) == (common | bits))
+		    {
+			pmap->red[*cptr].co.shco.green = pshared;
+		    }
+		}
+		GetNextBitsOrBreak(bits, gmask, base);
+	    }
+	}
+	else
+	{
+	    pshared = *ppshared++;
+	    pshared->refcnt = 1 << (g + b);
+	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+	    {
+		if ((*cptr & basemask) == common)
+		{
+		    pmap->red[*cptr].co.shco.green = pshared;
+		}
+	    }
+	}
+	basemask = ~(rmask | gmask);
+	common = *pptr & basemask;
+	if (bmask)
+	{
+	    bits = 0;
+	    base = lowbit (bmask);
+	    while(1)
+	    {
+		pshared = *ppshared++;
+		pshared->refcnt = 1 << (r + g);
+		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+		{
+		    if ((*cptr & basemask) == (common | bits))
+		    {
+			pmap->red[*cptr].co.shco.blue = pshared;
+		    }
+		}
+		GetNextBitsOrBreak(bits, bmask, base);
+	    }
+	}
+	else
+	{
+	    pshared = *ppshared++;
+	    pshared->refcnt = 1 << (g + b);
+	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+	    {
+		if ((*cptr & basemask) == common)
+		{
+		    pmap->red[*cptr].co.shco.blue = pshared;
+		}
+	    }
+	}
+    }
+    free(psharedList);
+    return TRUE;
+}
+
+
+/** FreeColors
+ * Free colors and/or cells (probably slow for large numbers) 
+ */
+int
+FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
+{
+    int		rval, result, class;
+    Pixel	rmask;
+
+    class = pmap->class;
+    if (pmap->flags & AllAllocated)
+	return BadAccess;
+    if ((class | DynamicClass) == DirectColor)
+    {
+	rmask = mask & RGBMASK(pmap->pVisual);
+        result = FreeCo(pmap, client, REDMAP, count, pixels,
+			mask & pmap->pVisual->redMask);
+	/* If any of the three calls fails, we must report that, if more
+	 * than one fails, it's ok that we report the last one */
+        rval = FreeCo(pmap, client, GREENMAP, count, pixels,
+		      mask & pmap->pVisual->greenMask);
+	if(rval != Success)
+	    result = rval;
+	rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
+		      mask & pmap->pVisual->blueMask);
+	if(rval != Success)
+	    result = rval;
+    }
+    else
+    {
+	rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
+        result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
+    }
+    if ((mask != rmask) && count)
+    {
+	clients[client]->errorValue = *pixels | mask;
+	result = BadValue;
+    }
+    /* XXX should worry about removing any RT_CMAPENTRY resource */
+    return result;
+}
+
+/**
+ * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
+ * which the client has allocated in channel colormap cells of pmap.
+ * doesn't change newpixels if it doesn't need to 
+ *
+ *  \param pmap   which colormap head
+ *  \param color  which sub-map, eg, RED, BLUE, PSEUDO
+ *  \param npixIn number of pixels passed in
+ *  \param ppixIn number of base pixels
+ *  \param mask   mask client gave us
+ */
+static int
+FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
+{
+    Pixel	*ppixClient, pixTest;
+    int		npixClient, npixNew, npix;
+    Pixel	bits, base, cmask, rgbbad;
+    Pixel	*pptr, *cptr;
+    int 	n, zapped;
+    int		errVal = Success;
+    int		offset, numents;
+
+    if (npixIn == 0)
+        return errVal;
+    bits = 0;
+    zapped = 0;
+    base = lowbit (mask);
+
+    switch(color)
+    {
+      case REDMAP:
+	cmask = pmap->pVisual->redMask;
+	rgbbad = ~RGBMASK(pmap->pVisual);
+	offset = pmap->pVisual->offsetRed;
+	numents = (cmask >> offset) + 1;
+	ppixClient = pmap->clientPixelsRed[client];
+	npixClient = pmap->numPixelsRed[client];
+	break;
+      case GREENMAP:
+	cmask = pmap->pVisual->greenMask;
+	rgbbad = ~RGBMASK(pmap->pVisual);
+	offset = pmap->pVisual->offsetGreen;
+	numents = (cmask >> offset) + 1;
+	ppixClient = pmap->clientPixelsGreen[client];
+	npixClient = pmap->numPixelsGreen[client];
+	break;
+      case BLUEMAP:
+	cmask = pmap->pVisual->blueMask;
+	rgbbad = ~RGBMASK(pmap->pVisual);
+	offset = pmap->pVisual->offsetBlue;
+	numents = (cmask >> offset) + 1;
+	ppixClient = pmap->clientPixelsBlue[client];
+	npixClient = pmap->numPixelsBlue[client];
+	break;
+      default:	/* so compiler can see that everything gets initialized */
+      case PSEUDOMAP:
+	cmask = ~((Pixel)0);
+	rgbbad = 0;
+	offset = 0;
+	numents = pmap->pVisual->ColormapEntries;
+	ppixClient = pmap->clientPixelsRed[client];
+	npixClient = pmap->numPixelsRed[client];
+	break;
+    }
+
+
+    /* zap all pixels which match */
+    while (1)
+    {
+        /* go through pixel list */
+        for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
+	{
+	    pixTest = ((*pptr | bits) & cmask) >> offset;
+	    if ((pixTest >= numents) || (*pptr & rgbbad))
+	    {
+		clients[client]->errorValue = *pptr | bits;
+		errVal = BadValue;
+		continue;
+	    }
+
+	    /* find match in client list */
+	    for (cptr = ppixClient, npix = npixClient;
+	         --npix >= 0 && *cptr != pixTest;
+		 cptr++) ;
+
+	    if (npix >= 0)
+	    {
+		if (pmap->class & DynamicClass)
+		{
+		    FreeCell(pmap, pixTest, color);
+		}
+		*cptr = ~((Pixel)0);
+		zapped++;
+	    }
+	    else
+		errVal = BadAccess;
+	}
+        /* generate next bits value */
+	GetNextBitsOrBreak(bits, mask, base);
+    }
+
+    /* delete freed pixels from client pixel list */
+    if (zapped)
+    {
+        npixNew = npixClient - zapped;
+        if (npixNew)
+	{
+	    /* Since the list can only get smaller, we can do a copy in
+	     * place and then realloc to a smaller size */
+    	    pptr = cptr = ppixClient;
+
+	    /* If we have all the new pixels, we don't have to examine the
+	     * rest of the old ones */
+	    for(npix = 0; npix < npixNew; cptr++)
+	    {
+    	        if (*cptr != ~((Pixel)0))
+		{
+    		    *pptr++ = *cptr;
+		    npix++;
+    	        }
+    	    }
+	    pptr = (Pixel *)realloc(ppixClient, npixNew * sizeof(Pixel));
+	    if (pptr)
+		ppixClient = pptr;
+	    npixClient = npixNew;
+        }
+	else
+	{
+	    npixClient = 0;
+	    free(ppixClient);
+    	    ppixClient = (Pixel *)NULL;
+	}
+	switch(color)
+	{
+	  case PSEUDOMAP:
+	  case REDMAP:
+	    pmap->clientPixelsRed[client] = ppixClient;
+	    pmap->numPixelsRed[client] = npixClient;
+	    break;
+	  case GREENMAP:
+	    pmap->clientPixelsGreen[client] = ppixClient;
+	    pmap->numPixelsGreen[client] = npixClient;
+	    break;
+	  case BLUEMAP:
+	    pmap->clientPixelsBlue[client] = ppixClient;
+	    pmap->numPixelsBlue[client] = npixClient;
+	    break;
+	}
+    }
+    return errVal;
+}
+
+
+
+/* Redefine color values */
+int
+StoreColors (ColormapPtr pmap, int count, xColorItem *defs, ClientPtr client)
+{
+    Pixel 	pix;
+    xColorItem *pdef;
+    EntryPtr 	pent, pentT, pentLast;
+    VisualPtr	pVisual;
+    SHAREDCOLOR		*pred, *pgreen, *pblue;
+    int			n, ChgRed, ChgGreen, ChgBlue, idef;
+    int			class, errVal = Success;
+    int			ok;
+
+
+    class = pmap->class;
+    if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
+    {
+	return BadAccess;
+    }
+    pVisual = pmap->pVisual;
+
+    idef = 0;
+    if((class | DynamicClass) == DirectColor)
+    {
+	int numred, numgreen, numblue;
+	Pixel rgbbad;
+
+	numred = NUMRED(pVisual);
+	numgreen = NUMGREEN(pVisual);
+	numblue = NUMBLUE(pVisual);
+	rgbbad = ~RGBMASK(pVisual);
+        for (pdef = defs, n = 0; n < count; pdef++, n++)
+	{
+	    ok = TRUE;
+            (*pmap->pScreen->ResolveColor)
+	        (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+	    if (pdef->pixel & rgbbad)
+	    {
+		errVal = BadValue;
+		client->errorValue = pdef->pixel;
+		continue;
+	    }
+	    pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
+	    if (pix >= numred)
+	    {
+		errVal = BadValue;
+		ok = FALSE;
+	    }
+	    else if (pmap->red[pix].refcnt != AllocPrivate)
+	    {
+		errVal = BadAccess;
+		ok = FALSE;
+	    }
+	    else if (pdef->flags & DoRed)
+	    {
+		pmap->red[pix].co.local.red = pdef->red;
+	    }
+	    else
+	    {
+		pdef->red = pmap->red[pix].co.local.red;
+	    }
+
+	    pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+	    if (pix >= numgreen)
+	    {
+		errVal = BadValue;
+		ok = FALSE;
+	    }
+	    else if (pmap->green[pix].refcnt != AllocPrivate)
+	    {
+		errVal = BadAccess;
+		ok = FALSE;
+	    }
+	    else if (pdef->flags & DoGreen)
+	    {
+		pmap->green[pix].co.local.green = pdef->green;
+	    }
+	    else
+	    {
+		pdef->green = pmap->green[pix].co.local.green;
+	    }
+
+	    pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+	    if (pix >= numblue)
+	    {
+		errVal = BadValue;
+		ok = FALSE;
+	    }
+	    else if (pmap->blue[pix].refcnt != AllocPrivate)
+	    {
+		errVal = BadAccess;
+		ok = FALSE;
+	    }
+	    else if (pdef->flags & DoBlue)
+	    {
+		pmap->blue[pix].co.local.blue = pdef->blue;
+	    }
+	    else
+	    {
+		pdef->blue = pmap->blue[pix].co.local.blue;
+	    }
+	    /* If this is an o.k. entry, then it gets added to the list
+	     * to be sent to the hardware.  If not, skip it.  Once we've
+	     * skipped one, we have to copy all the others.
+	     */
+	    if(ok)
+	    {
+		if(idef != n)
+		    defs[idef] = defs[n];
+		idef++;
+	    } else
+		client->errorValue = pdef->pixel;
+	}
+    }
+    else
+    {
+        for (pdef = defs, n = 0; n < count; pdef++, n++)
+	{
+
+	    ok = TRUE;
+	    if (pdef->pixel >= pVisual->ColormapEntries)
+	    {
+		client->errorValue = pdef->pixel;
+	        errVal = BadValue;
+		ok = FALSE;
+	    }
+	    else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
+	    {
+		errVal = BadAccess;
+		ok = FALSE;
+	    }
+
+	    /* If this is an o.k. entry, then it gets added to the list
+	     * to be sent to the hardware.  If not, skip it.  Once we've
+	     * skipped one, we have to copy all the others.
+	     */
+	    if(ok)
+	    {
+		if(idef != n)
+		    defs[idef] = defs[n];
+		idef++;
+	    }
+	    else
+		continue;
+
+            (*pmap->pScreen->ResolveColor)
+	        (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+	    pent = &pmap->red[pdef->pixel];
+
+	    if(pdef->flags & DoRed)
+	    {
+		if(pent->fShared)
+		{
+		    pent->co.shco.red->color = pdef->red;
+		    if (pent->co.shco.red->refcnt > 1)
+			ok = FALSE;
+		}
+		else
+		    pent->co.local.red = pdef->red;
+	    }
+	    else
+	    {
+		if(pent->fShared)
+		    pdef->red = pent->co.shco.red->color;
+		else
+		    pdef->red = pent->co.local.red;
+	    }
+	    if(pdef->flags & DoGreen)
+	    {
+		if(pent->fShared)
+		{
+		    pent->co.shco.green->color = pdef->green;
+		    if (pent->co.shco.green->refcnt > 1)
+			ok = FALSE;
+		}
+		else
+		    pent->co.local.green = pdef->green;
+	    }
+	    else
+	    {
+		if(pent->fShared)
+		    pdef->green = pent->co.shco.green->color;
+		else
+		    pdef->green = pent->co.local.green;
+	    }
+	    if(pdef->flags & DoBlue)
+	    {
+		if(pent->fShared)
+		{
+		    pent->co.shco.blue->color = pdef->blue;
+		    if (pent->co.shco.blue->refcnt > 1)
+			ok = FALSE;
+		}
+		else
+		    pent->co.local.blue = pdef->blue;
+	    }
+	    else
+	    {
+		if(pent->fShared)
+		    pdef->blue = pent->co.shco.blue->color;
+		else
+		    pdef->blue = pent->co.local.blue;
+	    }
+
+	    if(!ok)
+	    {
+                /* have to run through the colormap and change anybody who
+		 * shares this value */
+	        pred = pent->co.shco.red;
+	        pgreen = pent->co.shco.green;
+	        pblue = pent->co.shco.blue;
+	        ChgRed = pdef->flags & DoRed;
+	        ChgGreen = pdef->flags & DoGreen;
+	        ChgBlue = pdef->flags & DoBlue;
+	        pentLast = pmap->red + pVisual->ColormapEntries;
+
+	        for(pentT = pmap->red; pentT < pentLast; pentT++)
+		{
+		    if(pentT->fShared && (pentT != pent))
+		    {
+			xColorItem	defChg;
+
+			/* There are, alas, devices in this world too dumb
+			 * to read their own hardware colormaps.  Sick, but
+			 * true.  So we're going to be really nice and load
+			 * the xColorItem with the proper value for all the
+			 * fields.  We will only set the flags for those
+			 * fields that actually change.  Smart devices can
+			 * arrange to change only those fields.  Dumb devices
+			 * can rest assured that we have provided for them,
+			 * and can change all three fields */
+
+			defChg.flags = 0;
+			if(ChgRed && pentT->co.shco.red == pred)
+			{
+			    defChg.flags |= DoRed;
+			}
+			if(ChgGreen && pentT->co.shco.green == pgreen)
+			{
+			    defChg.flags |= DoGreen;
+			}
+			if(ChgBlue && pentT->co.shco.blue == pblue)
+			{
+			    defChg.flags |= DoBlue;
+			}
+			if(defChg.flags != 0)
+			{
+			    defChg.pixel = pentT - pmap->red;
+			    defChg.red = pentT->co.shco.red->color;
+			    defChg.green = pentT->co.shco.green->color;
+			    defChg.blue = pentT->co.shco.blue->color;
+			    (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
+			}
+		    }
+		}
+
+	    }
+	}
+    }
+    /* Note that we use idef, the count of acceptable entries, and not
+     * count, the count of proposed entries */
+    if (idef != 0)
+	( *pmap->pScreen->StoreColors) (pmap, idef, defs);
+    return errVal;
+}
+
+int
+IsMapInstalled(Colormap map, WindowPtr pWin)
+{
+    Colormap	*pmaps;
+    int		imap, nummaps, found;
+
+    pmaps = malloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap));
+    if(!pmaps)
+	return FALSE;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, pmaps);
+    found = FALSE;
+    for(imap = 0; imap < nummaps; imap++)
+    {
+	if(pmaps[imap] == map)
+	{
+	    found = TRUE;
+	    break;
+	}
+    }
+    free(pmaps);
+    return found;
+}
+
+struct colormap_lookup_data {
+    ScreenPtr pScreen;
+    VisualPtr visuals;
+};
+
+static void _colormap_find_resource(pointer value, XID id,
+				    pointer cdata)
+{
+    struct colormap_lookup_data *cmap_data = cdata;
+    VisualPtr visuals = cmap_data->visuals;
+    ScreenPtr pScreen = cmap_data->pScreen;
+    ColormapPtr cmap = value;
+    int j;
+
+    if (pScreen != cmap->pScreen)
+	return;
+
+    j = cmap->pVisual - pScreen->visuals;
+    cmap->pVisual = &visuals[j];
+}
+
+/* something has realloced the visuals, instead of breaking
+   ABI fix it up here - glx and compsite did this wrong */
+Bool
+ResizeVisualArray(ScreenPtr pScreen, int new_visual_count,
+		  DepthPtr depth)
+{
+    struct colormap_lookup_data cdata;
+    int numVisuals;
+    VisualPtr visuals;
+    XID *vids, vid;
+    int first_new_vid, first_new_visual, i;
+
+    first_new_vid = depth->numVids;
+    first_new_visual = pScreen->numVisuals;
+
+    vids = realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
+    if (!vids)
+        return FALSE;
+
+    /* its realloced now no going back if we fail the next one */
+    depth->vids = vids;
+
+    numVisuals = pScreen->numVisuals + new_visual_count;
+    visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
+    if (!visuals) {
+	return FALSE;
+    }
+
+    cdata.visuals = visuals;
+    cdata.pScreen = pScreen;
+    FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata);
+
+    pScreen->visuals = visuals;
+
+    for (i = 0; i < new_visual_count; i++) {
+	vid = FakeClientID(0);
+	pScreen->visuals[first_new_visual + i].vid = vid;
+	vids[first_new_vid + i] = vid;
+    }
+
+    depth->numVids += new_visual_count;
+    pScreen->numVisuals += new_visual_count;
+
+    return TRUE;
+}
diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c
index d8f15290b..fbac124da 100644
--- a/xorg-server/dix/dixfonts.c
+++ b/xorg-server/dix/dixfonts.c
@@ -66,16 +66,10 @@ Equipment Corporation.
 #include "dixfont.h"
 #include "xace.h"
 
-#ifdef DEBUG
-#include	<stdio.h>
-#endif
-
 #ifdef XF86BIGFONT
 #include "xf86bigfontsrv.h"
 #endif
 
-#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
-
 extern pointer fosNaturalParams;
 extern FontPtr defaultFont;
 
@@ -391,14 +385,6 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna
     int         i;
     FontPtr     cached = (FontPtr)0;
 
-#ifdef FONTDEBUG
-    char *f;
-    f = malloc(lenfname + 1);
-    memmove(f, pfontname, lenfname);
-    f[lenfname] = '\0';
-    ErrorF("[dix] OpenFont: fontname is \"%s\"\n", f);
-    free(f);
-#endif
     if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
 	return BadName;
     if (patternCache)
@@ -1829,8 +1815,10 @@ SetDefaultFontPath(char *path)
     /* get enough for string, plus values -- use up commas */
     len = strlen(temp_path) + 1;
     nump = cp = newpath = malloc(len);
-    if (!newpath)
+    if (!newpath) {
+	free(temp_path);
 	return BadAlloc;
+    }
     pp = (unsigned char *) temp_path;
     cp++;
     while (*pp) {
diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c
index d5ac54796..a5fe0a9cc 100644
--- a/xorg-server/dix/eventconvert.c
+++ b/xorg-server/dix/eventconvert.c
@@ -1,770 +1,767 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 NONINFRINGEMENT.  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.
- *
- */
-
-/**
- * @file eventconvert.c
- * This file contains event conversion routines from InternalEvent to the
- * matching protocol events.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdint.h>
-#include <X11/X.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/extensions/XI2proto.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2.h>
-
-#include "dix.h"
-#include "inputstr.h"
-#include "misc.h"
-#include "eventstr.h"
-#include "exglobals.h"
-#include "eventconvert.h"
-#include "xiquerydevice.h"
-#include "xkbsrv.h"
-
-
-static int countValuators(DeviceEvent *ev, int *first);
-static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
-static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
-static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
-static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
-static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
-
-/* Do not use, read comments below */
-BOOL EventIsKeyRepeat(xEvent *event);
-
-/**
- * Hack to allow detectable autorepeat for core and XI1 events.
- * The sequence number is unused until we send to the client and can be
- * misused to store data. More or less, anyway.
- *
- * Do not use this. It may change any time without warning, eat your babies
- * and piss on your cat.
- */
-static void
-EventSetKeyRepeatFlag(xEvent *event, BOOL on)
-{
-    event->u.u.sequenceNumber = on;
-}
-
-/**
- * Check if the event was marked as a repeat event before.
- * NOTE: This is a nasty hack and should NOT be used by anyone else but
- * TryClientEvents.
- */
-BOOL
-EventIsKeyRepeat(xEvent *event)
-{
-    return !!event->u.u.sequenceNumber;
-}
-
-/**
- * Convert the given event to the respective core event.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no core equivalent.
- *
- * @param[in] event The event to convert into a core event.
- * @param[in] core The memory location to store the core event at.
- * @return Success or the matching error code.
- */
-int
-EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
-{
-    xEvent *core = NULL;
-    int count = 0;
-    int ret = BadImplementation;
-
-    switch(event->any.type)
-    {
-        case ET_Motion:
-            {
-                DeviceEvent *e = &event->device_event;
-                /* Don't create core motion event if neither x nor y are
-                 * present */
-                if (!BitIsOn(e->valuators.mask, 0) &&
-                    !BitIsOn(e->valuators.mask, 1))
-                {
-                    ret = BadMatch;
-                    goto out;
-                }
-            }
-            /* fallthrough */
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-            {
-                DeviceEvent *e = &event->device_event;
-
-                if (e->detail.key > 0xFF)
-                {
-                    ret = BadMatch;
-                    goto out;
-                }
-
-                core = calloc(1, sizeof(*core));
-                if (!core)
-                    return BadAlloc;
-                count = 1;
-                core->u.u.type = e->type - ET_KeyPress + KeyPress;
-                core->u.u.detail = e->detail.key & 0xFF;
-                core->u.keyButtonPointer.time = e->time;
-                core->u.keyButtonPointer.rootX = e->root_x;
-                core->u.keyButtonPointer.rootY = e->root_y;
-                core->u.keyButtonPointer.state = e->corestate;
-                core->u.keyButtonPointer.root = e->root;
-                EventSetKeyRepeatFlag(core,
-                                      (e->type == ET_KeyPress &&
-                                       e->key_repeat));
-                ret = Success;
-            }
-            break;
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            ret = BadMatch;
-            goto out;
-        default:
-            /* XXX: */
-            ErrorF("[dix] EventToCore: Not implemented yet \n");
-            ret = BadImplementation;
-    }
-
-out:
-    *core_out = core;
-    *count_out = count;
-    return ret;
-}
-
-/**
- * Convert the given event to the respective XI 1.x event and store it in
- * xi. xi is allocated on demand and must be freed by the caller.
- * count returns the number of events in xi. If count is 1, and the type of
- * xi is GenericEvent, then xi may be larger than 32 bytes.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no XI equivalent.
- *
- * @param[in] ev The event to convert into an XI 1 event.
- * @param[out] xi Future memory location for the XI event.
- * @param[out] count Number of elements in xi.
- *
- * @return Success or the error code.
- */
-int
-EventToXI(InternalEvent *ev, xEvent **xi, int *count)
-{
-    switch (ev->any.type)
-    {
-        case ET_Motion:
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-            return eventToKeyButtonPointer(&ev->device_event, xi, count);
-        case ET_DeviceChanged:
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            *count = 0;
-            *xi = NULL;
-            return BadMatch;
-        default:
-            break;
-    }
-
-    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
-    return BadImplementation;
-}
-
-/**
- * Convert the given event to the respective XI 2.x event and store it in xi.
- * xi is allocated on demand and must be freed by the caller.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no XI2 equivalent.
- *
- * @param[in] ev The event to convert into an XI2 event
- * @param[out] xi Future memory location for the XI2 event.
- *
- * @return Success or the error code.
- */
-int
-EventToXI2(InternalEvent *ev, xEvent **xi)
-{
-    switch (ev->any.type)
-    {
-        /* Enter/FocusIn are for grabs. We don't need an actual event, since
-         * the real events delivered are triggered elsewhere */
-        case ET_Enter:
-        case ET_FocusIn:
-            *xi = NULL;
-            return Success;
-        case ET_Motion:
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-            return eventToDeviceEvent(&ev->device_event, xi);
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-            *xi = NULL;
-            return BadMatch;
-        case ET_DeviceChanged:
-            return eventToDeviceChanged(&ev->changed_event, xi);
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            return eventToRawEvent(&ev->raw_event, xi);
-        default:
-            break;
-    }
-
-    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
-    return BadImplementation;
-}
-
-static int
-eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
-{
-    int num_events;
-    int first; /* dummy */
-    deviceKeyButtonPointer *kbp;
-
-    /* Sorry, XI 1.x protocol restrictions. */
-    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
-    {
-        *count = 0;
-        return Success;
-    }
-
-    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
-    if (num_events <= 0)
-    {
-        switch (ev->type)
-        {
-            case ET_KeyPress:
-            case ET_KeyRelease:
-            case ET_ButtonPress:
-            case ET_ButtonRelease:
-                /* no axes is ok */
-                break;
-            case ET_Motion:
-            case ET_ProximityIn:
-            case ET_ProximityOut:
-                *count = 0;
-                return BadMatch;
-	    default:
-		*count = 0;
-		return BadImplementation;
-        }
-    }
-
-    num_events++; /* the actual event event */
-
-    *xi = calloc(num_events, sizeof(xEvent));
-    if (!(*xi))
-    {
-        return BadAlloc;
-    }
-
-    kbp           = (deviceKeyButtonPointer*)(*xi);
-    kbp->detail   = ev->detail.button;
-    kbp->time     = ev->time;
-    kbp->root     = ev->root;
-    kbp->root_x   = ev->root_x;
-    kbp->root_y   = ev->root_y;
-    kbp->deviceid = ev->deviceid;
-    kbp->state    = ev->corestate;
-    EventSetKeyRepeatFlag((xEvent*)kbp,
-                          (ev->type == ET_KeyPress && ev->key_repeat));
-
-    if (num_events > 1)
-        kbp->deviceid |= MORE_EVENTS;
-
-    switch(ev->type)
-    {
-        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
-        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
-        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
-        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
-        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
-        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
-        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
-        default:
-            break;
-    }
-
-    if (num_events > 1)
-    {
-        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
-    }
-
-    *count = num_events;
-    return Success;
-}
-
-
-/**
- * Set first to the first valuator in the event ev and return the number of
- * valuators from first to the last set valuator.
- */
-static int
-countValuators(DeviceEvent *ev, int *first)
-{
-    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
-    int i;
-
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            if (first_valuator == -1)
-                first_valuator = i;
-            last_valuator = i;
-        }
-    }
-
-    if (first_valuator != -1)
-    {
-        num_valuators = last_valuator - first_valuator + 1;
-        *first = first_valuator;
-    }
-
-    return num_valuators;
-}
-
-static int
-getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
-{
-    int i;
-    int state = 0;
-    int first_valuator, num_valuators;
-
-
-    num_valuators = countValuators(ev, &first_valuator);
-    if (num_valuators > 0)
-    {
-        DeviceIntPtr dev = NULL;
-        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
-        /* State needs to be assembled BEFORE the device is updated. */
-        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
-        state |= (dev && dev->button) ? (dev->button->state) : 0;
-    }
-
-    /* FIXME: non-continuous valuator data in internal events*/
-    for (i = 0; i < num_valuators; i += 6, xv++) {
-        xv->type = DeviceValuator;
-        xv->first_valuator = first_valuator + i;
-        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
-        xv->deviceid = ev->deviceid;
-        xv->device_state = state;
-        switch (xv->num_valuators) {
-        case 6:
-            xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
-        case 5:
-            xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
-        case 4:
-            xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
-        case 3:
-            xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
-        case 2:
-            xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
-        case 1:
-            xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
-        }
-
-        if (i + 6 < num_valuators)
-            xv->deviceid |= MORE_EVENTS;
-    }
-
-    return (num_valuators + 5) / 6;
-}
-
-
-static int
-appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
-{
-    uint32_t *kc;
-    int i;
-
-    info->type = XIKeyClass;
-    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
-    info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
-    info->sourceid = dce->sourceid;
-
-    kc = (uint32_t*)&info[1];
-    for (i = 0; i < info->num_keycodes; i++)
-        *kc++ = i + dce->keys.min_keycode;
-
-    return info->length * 4;
-}
-
-static int
-appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
-{
-    unsigned char *bits;
-    int mask_len;
-
-    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
-
-    info->type = XIButtonClass;
-    info->num_buttons = dce->buttons.num_buttons;
-    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
-                   info->num_buttons + mask_len;
-    info->sourceid = dce->sourceid;
-
-    bits = (unsigned char*)&info[1];
-    memset(bits, 0, mask_len * 4);
-    /* FIXME: is_down? */
-
-    bits += mask_len * 4;
-    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
-
-    return info->length * 4;
-}
-
-static int
-appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
-{
-    info->type = XIValuatorClass;
-    info->length = sizeof(xXIValuatorInfo)/4;
-    info->label = dce->valuators[axisnumber].name;
-    info->min.integral = dce->valuators[axisnumber].min;
-    info->min.frac = 0;
-    info->max.integral = dce->valuators[axisnumber].max;
-    info->max.frac = 0;
-    /* FIXME: value */
-    info->value.integral = 0;
-    info->value.frac = 0;
-    info->resolution = dce->valuators[axisnumber].resolution;
-    info->number = axisnumber;
-    info->mode = dce->valuators[axisnumber].mode;
-    info->sourceid = dce->sourceid;
-
-    return info->length * 4;
-}
-
-static int
-eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
-{
-    xXIDeviceChangedEvent *dcce;
-    int len = sizeof(xXIDeviceChangedEvent);
-    int nkeys;
-    char *ptr;
-
-    if (dce->buttons.num_buttons)
-    {
-        len += sizeof(xXIButtonInfo);
-        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
-        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
-    }
-    if (dce->num_valuators)
-        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
-
-    nkeys = (dce->keys.max_keycode > 0) ?
-                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
-    if (nkeys > 0)
-    {
-        len += sizeof(xXIKeyInfo);
-        len += sizeof(CARD32) * nkeys; /* keycodes */
-    }
-
-    dcce = calloc(1, len);
-    if (!dcce)
-    {
-        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
-        return BadAlloc;
-    }
-
-    dcce->type         = GenericEvent;
-    dcce->extension    = IReqCode;
-    dcce->evtype       = XI_DeviceChanged;
-    dcce->time         = dce->time;
-    dcce->deviceid     = dce->deviceid;
-    dcce->sourceid     = dce->sourceid;
-    dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
-    dcce->num_classes  = 0;
-    dcce->length = bytes_to_int32(len - sizeof(xEvent));
-
-    ptr = (char*)&dcce[1];
-    if (dce->buttons.num_buttons)
-    {
-        dcce->num_classes++;
-        ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
-    }
-
-    if (nkeys)
-    {
-        dcce->num_classes++;
-        ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
-    }
-
-    if (dce->num_valuators)
-    {
-        int i;
-
-        dcce->num_classes += dce->num_valuators;
-        for (i = 0; i < dce->num_valuators; i++)
-            ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
-    }
-
-    *xi = (xEvent*)dcce;
-
-    return Success;
-}
-
-static int count_bits(unsigned char* ptr, int len)
-{
-    int bits = 0;
-    unsigned int i;
-    unsigned char x;
-
-    for (i = 0; i < len; i++)
-    {
-        x = ptr[i];
-        while(x > 0)
-        {
-            bits += (x & 0x1);
-            x >>= 1;
-        }
-    }
-    return bits;
-}
-
-static int
-eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
-{
-    int len = sizeof(xXIDeviceEvent);
-    xXIDeviceEvent *xde;
-    int i, btlen, vallen;
-    char *ptr;
-    FP3232 *axisval;
-
-    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
-     * with MAX_VALUATORS below */
-    /* btlen is in 4 byte units */
-    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
-    len += btlen * 4; /* buttonmask len */
-
-
-    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
-    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
-    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
-    len += vallen * 4; /* valuators mask */
-
-    *xi = calloc(1, len);
-    xde = (xXIDeviceEvent*)*xi;
-    xde->type           = GenericEvent;
-    xde->extension      = IReqCode;
-    xde->evtype         = GetXI2Type((InternalEvent*)ev);
-    xde->time           = ev->time;
-    xde->length         = bytes_to_int32(len - sizeof(xEvent));
-    xde->detail         = ev->detail.button;
-    xde->root           = ev->root;
-    xde->buttons_len    = btlen;
-    xde->valuators_len  = vallen;
-    xde->deviceid       = ev->deviceid;
-    xde->sourceid       = ev->sourceid;
-    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
-    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
-
-    if (ev->key_repeat)
-        xde->flags      |= XIKeyRepeat;
-
-    xde->mods.base_mods         = ev->mods.base;
-    xde->mods.latched_mods      = ev->mods.latched;
-    xde->mods.locked_mods       = ev->mods.locked;
-    xde->mods.effective_mods    = ev->mods.effective;
-
-    xde->group.base_group       = ev->group.base;
-    xde->group.latched_group    = ev->group.latched;
-    xde->group.locked_group     = ev->group.locked;
-    xde->group.effective_group  = ev->group.effective;
-
-    ptr = (char*)&xde[1];
-    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
-    {
-        if (BitIsOn(ev->buttons, i))
-            SetBit(ptr, i);
-    }
-
-    ptr += xde->buttons_len * 4;
-    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            SetBit(ptr, i);
-            axisval->integral = ev->valuators.data[i];
-            axisval->frac = ev->valuators.data_frac[i];
-            axisval++;
-        }
-    }
-
-    return Success;
-}
-
-static int
-eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
-{
-    xXIRawEvent* raw;
-    int vallen, nvals;
-    int i, len = sizeof(xXIRawEvent);
-    char *ptr;
-    FP3232 *axisval;
-
-    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
-    len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
-                                    raw, once processed */
-    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
-    len += vallen * 4; /* valuators mask */
-
-    *xi = calloc(1, len);
-    raw = (xXIRawEvent*)*xi;
-    raw->type           = GenericEvent;
-    raw->extension      = IReqCode;
-    raw->evtype         = GetXI2Type((InternalEvent*)ev);
-    raw->time           = ev->time;
-    raw->length         = bytes_to_int32(len - sizeof(xEvent));
-    raw->detail         = ev->detail.button;
-    raw->deviceid       = ev->deviceid;
-    raw->valuators_len  = vallen;
-
-    ptr = (char*)&raw[1];
-    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            SetBit(ptr, i);
-            axisval->integral = ev->valuators.data[i];
-            axisval->frac = ev->valuators.data_frac[i];
-            (axisval + nvals)->integral = ev->valuators.data_raw[i];
-            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
-            axisval++;
-        }
-    }
-
-    return Success;
-}
-
-/**
- * Return the corresponding core type for the given event or 0 if no core
- * equivalent exists.
- */
-int
-GetCoreType(InternalEvent *event)
-{
-    int coretype = 0;
-    switch(event->any.type)
-    {
-        case ET_Motion:         coretype = MotionNotify;  break;
-        case ET_ButtonPress:    coretype = ButtonPress;   break;
-        case ET_ButtonRelease:  coretype = ButtonRelease; break;
-        case ET_KeyPress:       coretype = KeyPress;      break;
-        case ET_KeyRelease:     coretype = KeyRelease;    break;
-        default:
-            break;
-    }
-    return coretype;
-}
-
-/**
- * Return the corresponding XI 1.x type for the given event or 0 if no
- * equivalent exists.
- */
-int
-GetXIType(InternalEvent *event)
-{
-    int xitype = 0;
-    switch(event->any.type)
-    {
-        case ET_Motion:         xitype = DeviceMotionNotify;  break;
-        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
-        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
-        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
-        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
-        case ET_ProximityIn:    xitype = ProximityIn;         break;
-        case ET_ProximityOut:   xitype = ProximityOut;        break;
-        default:
-            break;
-    }
-    return xitype;
-}
-
-/**
- * Return the corresponding XI 2.x type for the given event or 0 if no
- * equivalent exists.
- */
-int
-GetXI2Type(InternalEvent *event)
-{
-    int xi2type = 0;
-
-    switch(event->any.type)
-    {
-        case ET_Motion:         xi2type = XI_Motion;           break;
-        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
-        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
-        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
-        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
-        case ET_Enter:          xi2type = XI_Enter;            break;
-        case ET_Leave:          xi2type = XI_Leave;            break;
-        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
-        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
-        case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
-        case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
-        case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
-        case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
-        case ET_RawMotion:      xi2type = XI_RawMotion;        break;
-        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
-        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
-        default:
-            break;
-    }
-    return xi2type;
-}
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 NONINFRINGEMENT.  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.
+ *
+ */
+
+/**
+ * @file eventconvert.c
+ * This file contains event conversion routines from InternalEvent to the
+ * matching protocol events.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <X11/X.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+
+#include "dix.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "eventstr.h"
+#include "exglobals.h"
+#include "eventconvert.h"
+#include "xiquerydevice.h"
+#include "xkbsrv.h"
+
+
+static int countValuators(DeviceEvent *ev, int *first);
+static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
+static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
+static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
+static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
+static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
+
+/* Do not use, read comments below */
+BOOL EventIsKeyRepeat(xEvent *event);
+
+/**
+ * Hack to allow detectable autorepeat for core and XI1 events.
+ * The sequence number is unused until we send to the client and can be
+ * misused to store data. More or less, anyway.
+ *
+ * Do not use this. It may change any time without warning, eat your babies
+ * and piss on your cat.
+ */
+static void
+EventSetKeyRepeatFlag(xEvent *event, BOOL on)
+{
+    event->u.u.sequenceNumber = on;
+}
+
+/**
+ * Check if the event was marked as a repeat event before.
+ * NOTE: This is a nasty hack and should NOT be used by anyone else but
+ * TryClientEvents.
+ */
+BOOL
+EventIsKeyRepeat(xEvent *event)
+{
+    return !!event->u.u.sequenceNumber;
+}
+
+/**
+ * Convert the given event to the respective core event.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no core equivalent.
+ *
+ * @param[in] event The event to convert into a core event.
+ * @param[in] core The memory location to store the core event at.
+ * @return Success or the matching error code.
+ */
+int
+EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
+{
+    xEvent *core = NULL;
+    int count = 0;
+    int ret = BadImplementation;
+
+    switch(event->any.type)
+    {
+        case ET_Motion:
+            {
+                DeviceEvent *e = &event->device_event;
+                /* Don't create core motion event if neither x nor y are
+                 * present */
+                if (!BitIsOn(e->valuators.mask, 0) &&
+                    !BitIsOn(e->valuators.mask, 1))
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
+            }
+            /* fallthrough */
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            {
+                DeviceEvent *e = &event->device_event;
+
+                if (e->detail.key > 0xFF)
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
+
+                core = calloc(1, sizeof(*core));
+                if (!core)
+                    return BadAlloc;
+                count = 1;
+                core->u.u.type = e->type - ET_KeyPress + KeyPress;
+                core->u.u.detail = e->detail.key & 0xFF;
+                core->u.keyButtonPointer.time = e->time;
+                core->u.keyButtonPointer.rootX = e->root_x;
+                core->u.keyButtonPointer.rootY = e->root_y;
+                core->u.keyButtonPointer.state = e->corestate;
+                core->u.keyButtonPointer.root = e->root;
+                EventSetKeyRepeatFlag(core,
+                                      (e->type == ET_KeyPress &&
+                                       e->key_repeat));
+                ret = Success;
+            }
+            break;
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            ret = BadMatch;
+            goto out;
+        default:
+            /* XXX: */
+            ErrorF("[dix] EventToCore: Not implemented yet \n");
+            ret = BadImplementation;
+    }
+
+out:
+    *core_out = core;
+    *count_out = count;
+    return ret;
+}
+
+/**
+ * Convert the given event to the respective XI 1.x event and store it in
+ * xi. xi is allocated on demand and must be freed by the caller.
+ * count returns the number of events in xi. If count is 1, and the type of
+ * xi is GenericEvent, then xi may be larger than 32 bytes.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI equivalent.
+ *
+ * @param[in] ev The event to convert into an XI 1 event.
+ * @param[out] xi Future memory location for the XI event.
+ * @param[out] count Number of elements in xi.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI(InternalEvent *ev, xEvent **xi, int *count)
+{
+    switch (ev->any.type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            return eventToKeyButtonPointer(&ev->device_event, xi, count);
+        case ET_DeviceChanged:
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            *count = 0;
+            *xi = NULL;
+            return BadMatch;
+        default:
+            break;
+    }
+
+    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
+    return BadImplementation;
+}
+
+/**
+ * Convert the given event to the respective XI 2.x event and store it in xi.
+ * xi is allocated on demand and must be freed by the caller.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI2 equivalent.
+ *
+ * @param[in] ev The event to convert into an XI2 event
+ * @param[out] xi Future memory location for the XI2 event.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI2(InternalEvent *ev, xEvent **xi)
+{
+    switch (ev->any.type)
+    {
+        /* Enter/FocusIn are for grabs. We don't need an actual event, since
+         * the real events delivered are triggered elsewhere */
+        case ET_Enter:
+        case ET_FocusIn:
+            *xi = NULL;
+            return Success;
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            return eventToDeviceEvent(&ev->device_event, xi);
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            *xi = NULL;
+            return BadMatch;
+        case ET_DeviceChanged:
+            return eventToDeviceChanged(&ev->changed_event, xi);
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            return eventToRawEvent(&ev->raw_event, xi);
+        default:
+            break;
+    }
+
+    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
+    return BadImplementation;
+}
+
+static int
+eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
+{
+    int num_events;
+    int first; /* dummy */
+    deviceKeyButtonPointer *kbp;
+
+    /* Sorry, XI 1.x protocol restrictions. */
+    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
+    {
+        *count = 0;
+        return Success;
+    }
+
+    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
+    if (num_events <= 0)
+    {
+        switch (ev->type)
+        {
+            case ET_KeyPress:
+            case ET_KeyRelease:
+            case ET_ButtonPress:
+            case ET_ButtonRelease:
+                /* no axes is ok */
+                break;
+            case ET_Motion:
+            case ET_ProximityIn:
+            case ET_ProximityOut:
+                *count = 0;
+                return BadMatch;
+	    default:
+		*count = 0;
+		return BadImplementation;
+        }
+    }
+
+    num_events++; /* the actual event event */
+
+    *xi = calloc(num_events, sizeof(xEvent));
+    if (!(*xi))
+    {
+        return BadAlloc;
+    }
+
+    kbp           = (deviceKeyButtonPointer*)(*xi);
+    kbp->detail   = ev->detail.button;
+    kbp->time     = ev->time;
+    kbp->root     = ev->root;
+    kbp->root_x   = ev->root_x;
+    kbp->root_y   = ev->root_y;
+    kbp->deviceid = ev->deviceid;
+    kbp->state    = ev->corestate;
+    EventSetKeyRepeatFlag((xEvent*)kbp,
+                          (ev->type == ET_KeyPress && ev->key_repeat));
+
+    if (num_events > 1)
+        kbp->deviceid |= MORE_EVENTS;
+
+    switch(ev->type)
+    {
+        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
+        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
+        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
+        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
+        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
+        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
+        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
+        default:
+            break;
+    }
+
+    if (num_events > 1)
+    {
+        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
+    }
+
+    *count = num_events;
+    return Success;
+}
+
+
+/**
+ * Set first to the first valuator in the event ev and return the number of
+ * valuators from first to the last set valuator.
+ */
+static int
+countValuators(DeviceEvent *ev, int *first)
+{
+    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
+    int i;
+
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            if (first_valuator == -1)
+                first_valuator = i;
+            last_valuator = i;
+        }
+    }
+
+    if (first_valuator != -1)
+    {
+        num_valuators = last_valuator - first_valuator + 1;
+        *first = first_valuator;
+    }
+
+    return num_valuators;
+}
+
+static int
+getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
+{
+    int i;
+    int state = 0;
+    int first_valuator, num_valuators;
+    DeviceIntPtr dev = NULL;
+
+
+    num_valuators = countValuators(ev, &first_valuator);
+    if (num_valuators > 0)
+    {
+        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
+        /* State needs to be assembled BEFORE the device is updated. */
+        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
+        state |= (dev && dev->button) ? (dev->button->state) : 0;
+    }
+
+    for (i = 0; i < num_valuators; i += 6, xv++) {
+        INT32 *valuators = &xv->valuator0; // Treat all 6 vals as an array
+        int j;
+
+        xv->type = DeviceValuator;
+        xv->first_valuator = first_valuator + i;
+        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
+        xv->deviceid = ev->deviceid;
+        xv->device_state = state;
+
+        for (j = 0; j < xv->num_valuators; j++) {
+            if (BitIsOn(ev->valuators.mask, xv->first_valuator + j))
+                valuators[j] = ev->valuators.data[xv->first_valuator + j];
+            else if (dev->valuator->axes[xv->first_valuator + j].mode == Absolute)
+                valuators[j] = dev->valuator->axisVal[xv->first_valuator + j];
+            else
+                valuators[j] = 0;
+        }
+
+        if (i + 6 < num_valuators)
+            xv->deviceid |= MORE_EVENTS;
+    }
+
+    return (num_valuators + 5) / 6;
+}
+
+
+static int
+appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
+{
+    uint32_t *kc;
+    int i;
+
+    info->type = XIKeyClass;
+    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
+    info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
+    info->sourceid = dce->sourceid;
+
+    kc = (uint32_t*)&info[1];
+    for (i = 0; i < info->num_keycodes; i++)
+        *kc++ = i + dce->keys.min_keycode;
+
+    return info->length * 4;
+}
+
+static int
+appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
+{
+    unsigned char *bits;
+    int mask_len;
+
+    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+
+    info->type = XIButtonClass;
+    info->num_buttons = dce->buttons.num_buttons;
+    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
+                   info->num_buttons + mask_len;
+    info->sourceid = dce->sourceid;
+
+    bits = (unsigned char*)&info[1];
+    memset(bits, 0, mask_len * 4);
+    /* FIXME: is_down? */
+
+    bits += mask_len * 4;
+    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
+
+    return info->length * 4;
+}
+
+static int
+appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
+{
+    info->type = XIValuatorClass;
+    info->length = sizeof(xXIValuatorInfo)/4;
+    info->label = dce->valuators[axisnumber].name;
+    info->min.integral = dce->valuators[axisnumber].min;
+    info->min.frac = 0;
+    info->max.integral = dce->valuators[axisnumber].max;
+    info->max.frac = 0;
+    /* FIXME: value */
+    info->value.integral = 0;
+    info->value.frac = 0;
+    info->resolution = dce->valuators[axisnumber].resolution;
+    info->number = axisnumber;
+    info->mode = dce->valuators[axisnumber].mode;
+    info->sourceid = dce->sourceid;
+
+    return info->length * 4;
+}
+
+static int
+eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
+{
+    xXIDeviceChangedEvent *dcce;
+    int len = sizeof(xXIDeviceChangedEvent);
+    int nkeys;
+    char *ptr;
+
+    if (dce->buttons.num_buttons)
+    {
+        len += sizeof(xXIButtonInfo);
+        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
+        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+    }
+    if (dce->num_valuators)
+        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
+
+    nkeys = (dce->keys.max_keycode > 0) ?
+                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
+    if (nkeys > 0)
+    {
+        len += sizeof(xXIKeyInfo);
+        len += sizeof(CARD32) * nkeys; /* keycodes */
+    }
+
+    dcce = calloc(1, len);
+    if (!dcce)
+    {
+        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
+        return BadAlloc;
+    }
+
+    dcce->type         = GenericEvent;
+    dcce->extension    = IReqCode;
+    dcce->evtype       = XI_DeviceChanged;
+    dcce->time         = dce->time;
+    dcce->deviceid     = dce->deviceid;
+    dcce->sourceid     = dce->sourceid;
+    dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
+    dcce->num_classes  = 0;
+    dcce->length = bytes_to_int32(len - sizeof(xEvent));
+
+    ptr = (char*)&dcce[1];
+    if (dce->buttons.num_buttons)
+    {
+        dcce->num_classes++;
+        ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
+    }
+
+    if (nkeys)
+    {
+        dcce->num_classes++;
+        ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
+    }
+
+    if (dce->num_valuators)
+    {
+        int i;
+
+        dcce->num_classes += dce->num_valuators;
+        for (i = 0; i < dce->num_valuators; i++)
+            ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
+    }
+
+    *xi = (xEvent*)dcce;
+
+    return Success;
+}
+
+static int count_bits(unsigned char* ptr, int len)
+{
+    int bits = 0;
+    unsigned int i;
+    unsigned char x;
+
+    for (i = 0; i < len; i++)
+    {
+        x = ptr[i];
+        while(x > 0)
+        {
+            bits += (x & 0x1);
+            x >>= 1;
+        }
+    }
+    return bits;
+}
+
+static int
+eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
+{
+    int len = sizeof(xXIDeviceEvent);
+    xXIDeviceEvent *xde;
+    int i, btlen, vallen;
+    char *ptr;
+    FP3232 *axisval;
+
+    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
+     * with MAX_VALUATORS below */
+    /* btlen is in 4 byte units */
+    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
+    len += btlen * 4; /* buttonmask len */
+
+
+    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
+    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
+    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+    len += vallen * 4; /* valuators mask */
+
+    *xi = calloc(1, len);
+    xde = (xXIDeviceEvent*)*xi;
+    xde->type           = GenericEvent;
+    xde->extension      = IReqCode;
+    xde->evtype         = GetXI2Type((InternalEvent*)ev);
+    xde->time           = ev->time;
+    xde->length         = bytes_to_int32(len - sizeof(xEvent));
+    xde->detail         = ev->detail.button;
+    xde->root           = ev->root;
+    xde->buttons_len    = btlen;
+    xde->valuators_len  = vallen;
+    xde->deviceid       = ev->deviceid;
+    xde->sourceid       = ev->sourceid;
+    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
+    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
+
+    if (ev->key_repeat)
+        xde->flags      |= XIKeyRepeat;
+
+    xde->mods.base_mods         = ev->mods.base;
+    xde->mods.latched_mods      = ev->mods.latched;
+    xde->mods.locked_mods       = ev->mods.locked;
+    xde->mods.effective_mods    = ev->mods.effective;
+
+    xde->group.base_group       = ev->group.base;
+    xde->group.latched_group    = ev->group.latched;
+    xde->group.locked_group     = ev->group.locked;
+    xde->group.effective_group  = ev->group.effective;
+
+    ptr = (char*)&xde[1];
+    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
+    {
+        if (BitIsOn(ev->buttons, i))
+            SetBit(ptr, i);
+    }
+
+    ptr += xde->buttons_len * 4;
+    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
+            axisval++;
+        }
+    }
+
+    return Success;
+}
+
+static int
+eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
+{
+    xXIRawEvent* raw;
+    int vallen, nvals;
+    int i, len = sizeof(xXIRawEvent);
+    char *ptr;
+    FP3232 *axisval;
+
+    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
+    len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
+                                    raw, once processed */
+    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+    len += vallen * 4; /* valuators mask */
+
+    *xi = calloc(1, len);
+    raw = (xXIRawEvent*)*xi;
+    raw->type           = GenericEvent;
+    raw->extension      = IReqCode;
+    raw->evtype         = GetXI2Type((InternalEvent*)ev);
+    raw->time           = ev->time;
+    raw->length         = bytes_to_int32(len - sizeof(xEvent));
+    raw->detail         = ev->detail.button;
+    raw->deviceid       = ev->deviceid;
+    raw->valuators_len  = vallen;
+
+    ptr = (char*)&raw[1];
+    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
+            (axisval + nvals)->integral = ev->valuators.data_raw[i];
+            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
+            axisval++;
+        }
+    }
+
+    return Success;
+}
+
+/**
+ * Return the corresponding core type for the given event or 0 if no core
+ * equivalent exists.
+ */
+int
+GetCoreType(InternalEvent *event)
+{
+    int coretype = 0;
+    switch(event->any.type)
+    {
+        case ET_Motion:         coretype = MotionNotify;  break;
+        case ET_ButtonPress:    coretype = ButtonPress;   break;
+        case ET_ButtonRelease:  coretype = ButtonRelease; break;
+        case ET_KeyPress:       coretype = KeyPress;      break;
+        case ET_KeyRelease:     coretype = KeyRelease;    break;
+        default:
+            break;
+    }
+    return coretype;
+}
+
+/**
+ * Return the corresponding XI 1.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXIType(InternalEvent *event)
+{
+    int xitype = 0;
+    switch(event->any.type)
+    {
+        case ET_Motion:         xitype = DeviceMotionNotify;  break;
+        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
+        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
+        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
+        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
+        case ET_ProximityIn:    xitype = ProximityIn;         break;
+        case ET_ProximityOut:   xitype = ProximityOut;        break;
+        default:
+            break;
+    }
+    return xitype;
+}
+
+/**
+ * Return the corresponding XI 2.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXI2Type(InternalEvent *event)
+{
+    int xi2type = 0;
+
+    switch(event->any.type)
+    {
+        case ET_Motion:         xi2type = XI_Motion;           break;
+        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
+        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
+        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
+        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
+        case ET_Enter:          xi2type = XI_Enter;            break;
+        case ET_Leave:          xi2type = XI_Leave;            break;
+        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
+        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
+        case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
+        case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
+        case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
+        case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
+        case ET_RawMotion:      xi2type = XI_RawMotion;        break;
+        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
+        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
+        default:
+            break;
+    }
+    return xi2type;
+}
diff --git a/xorg-server/dix/extension.c b/xorg-server/dix/extension.c
index b7f5c9c8c..c7bbac5ff 100644
--- a/xorg-server/dix/extension.c
+++ b/xorg-server/dix/extension.c
@@ -1,361 +1,360 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "gcstruct.h"
-#include "scrnintstr.h"
-#include "dispatch.h"
-#include "privates.h"
-#include "registry.h"
-#include "xace.h"
-
-#define LAST_EVENT  128
-#define LAST_ERROR 255
-
-static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
-
-int lastEvent = EXTENSION_EVENT_BASE;
-static int lastError = FirstExtensionError;
-static unsigned int NumExtensions = 0;
-
-ExtensionEntry *
-AddExtension(char *name, int NumEvents, int NumErrors, 
-	     int (*MainProc)(ClientPtr c1), 
-	     int (*SwappedMainProc)(ClientPtr c2), 
-	     void (*CloseDownProc)(ExtensionEntry *e), 
-	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
-{
-    int i;
-    ExtensionEntry *ext, **newexts;
-
-    if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
-        return((ExtensionEntry *) NULL);
-    if ((lastEvent + NumEvents > LAST_EVENT) || 
-	        (unsigned)(lastError + NumErrors > LAST_ERROR)) {
-        LogMessage(X_ERROR, "Not enabling extension %s: maximum number of "
-                   "events or errors exceeded.\n", name);
-        return((ExtensionEntry *) NULL);
-    }
-
-    ext = calloc(sizeof (ExtensionEntry), 1);
-    if (!ext)
-	return NULL;
-    if (!dixAllocatePrivates(&ext->devPrivates, PRIVATE_EXTENSION)) {
-	free(ext);
-	return NULL;
-    }
-    ext->name = strdup(name);
-    ext->num_aliases = 0;
-    ext->aliases = (char **)NULL;
-    if (!ext->name)
-    {
-	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
-	free(ext);
-	return((ExtensionEntry *) NULL);
-    }
-    i = NumExtensions;
-    newexts = (ExtensionEntry **) realloc(extensions,
-					   (i + 1) * sizeof(ExtensionEntry *));
-    if (!newexts)
-    {
-	free(ext->name);
-	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
-	free(ext);
-	return((ExtensionEntry *) NULL);
-    }
-    NumExtensions++;
-    extensions = newexts;
-    extensions[i] = ext;
-    ext->index = i;
-    ext->base = i + EXTENSION_BASE;
-    ext->CloseDown = CloseDownProc;
-    ext->MinorOpcode = MinorOpcodeProc;
-    ProcVector[i + EXTENSION_BASE] = MainProc;
-    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
-    if (NumEvents)
-    {
-        ext->eventBase = lastEvent;
-	ext->eventLast = lastEvent + NumEvents;
-	lastEvent += NumEvents;
-    }
-    else
-    {
-        ext->eventBase = 0;
-        ext->eventLast = 0;
-    }
-    if (NumErrors)
-    {
-        ext->errorBase = lastError;
-	ext->errorLast = lastError + NumErrors;
-	lastError += NumErrors;
-    }
-    else
-    {
-        ext->errorBase = 0;
-        ext->errorLast = 0;
-    }
-
-    RegisterExtensionNames(ext);
-    return ext;
-}
-
-Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
-{
-    char *name;
-    char **aliases;
-
-    if (!ext)
-        return FALSE ;
-    aliases = (char **)realloc(ext->aliases,
-				(ext->num_aliases + 1) * sizeof(char *));
-    if (!aliases)
-	return FALSE;
-    ext->aliases = aliases;
-    name = strdup(alias);
-    if (!name)
-	return FALSE;
-    ext->aliases[ext->num_aliases] = name;
-    ext->num_aliases++;
-    return TRUE;
-}
-
-static int
-FindExtension(char *extname, int len)
-{
-    int i, j;
-
-    for (i=0; i<NumExtensions; i++)
-    {
-	if ((strlen(extensions[i]->name) == len) &&
-	    !strncmp(extname, extensions[i]->name, len))
-	    break;
-	for (j = extensions[i]->num_aliases; --j >= 0;)
-	{
-	    if ((strlen(extensions[i]->aliases[j]) == len) &&
-		!strncmp(extname, extensions[i]->aliases[j], len))
-		break;
-	}
-	if (j >= 0) break;
-    }
-    return ((i == NumExtensions) ? -1 : i);
-}
-
-/*
- * CheckExtension returns the extensions[] entry for the requested
- * extension name.  Maybe this could just return a Bool instead?
- */
-ExtensionEntry *
-CheckExtension(const char *extname)
-{
-    int n;
-
-    n = FindExtension((char*)extname, strlen(extname));
-    if (n != -1)
-	return extensions[n];
-    else
-	return NULL;
-}
-
-/*
- * Added as part of Xace.
- */
-ExtensionEntry *
-GetExtensionEntry(int major)
-{    
-    if (major < EXTENSION_BASE)
-	return NULL;
-    major -= EXTENSION_BASE;
-    if (major >= NumExtensions)
-	return NULL;
-    return extensions[major];
-}
-
-unsigned short
-StandardMinorOpcode(ClientPtr client)
-{
-    return ((xReq *)client->requestBuffer)->data;
-}
-
-unsigned short
-MinorOpcodeOfRequest(ClientPtr client)
-{
-    unsigned char major;
-
-    major = ((xReq *)client->requestBuffer)->reqType;
-    if (major < EXTENSION_BASE)
-	return 0;
-    major -= EXTENSION_BASE;
-    if (major >= NumExtensions)
-	return 0;
-    return (*extensions[major]->MinorOpcode)(client);
-}
-
-void
-CloseDownExtensions(void)
-{
-    int i,j;
-
-    for (i = NumExtensions - 1; i >= 0; i--)
-    {
-	if (extensions[i]->CloseDown)
-	    extensions[i]->CloseDown(extensions[i]);
-	NumExtensions = i;
-	free(extensions[i]->name);
-	for (j = extensions[i]->num_aliases; --j >= 0;)
-	    free(extensions[i]->aliases[j]);
-	free(extensions[i]->aliases);
-	dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION);
-	free(extensions[i]);
-    }
-    free(extensions);
-    extensions = (ExtensionEntry **)NULL;
-    lastEvent = EXTENSION_EVENT_BASE;
-    lastError = FirstExtensionError;
-}
-
-int
-ProcQueryExtension(ClientPtr client)
-{
-    xQueryExtensionReply reply;
-    int i;
-    REQUEST(xQueryExtensionReq);
-
-    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
-
-    memset(&reply, 0, sizeof(xQueryExtensionReply));
-    reply.type = X_Reply;
-    reply.length = 0;
-    reply.major_opcode = 0;
-    reply.sequenceNumber = client->sequence;
-
-    if ( ! NumExtensions )
-        reply.present = xFalse;
-    else
-    {
-	i = FindExtension((char *)&stuff[1], stuff->nbytes);
-        if (i < 0 || XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
-            reply.present = xFalse;
-        else
-        {            
-            reply.present = xTrue;
-	    reply.major_opcode = extensions[i]->base;
-	    reply.first_event = extensions[i]->eventBase;
-	    reply.first_error = extensions[i]->errorBase;
-	}
-    }
-    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
-    return Success;
-}
-
-int
-ProcListExtensions(ClientPtr client)
-{
-    xListExtensionsReply reply;
-    char *bufptr, *buffer;
-    int total_length = 0;
-
-    REQUEST_SIZE_MATCH(xReq);
-
-    memset(&reply, 0, sizeof(xListExtensionsReply));
-    reply.type = X_Reply;
-    reply.nExtensions = 0;
-    reply.length = 0;
-    reply.sequenceNumber = client->sequence;
-    buffer = NULL;
-
-    if ( NumExtensions )
-    {
-        int i, j;
-
-        for (i=0;  i<NumExtensions; i++)
-	{
-	    /* call callbacks to find out whether to show extension */
-	    if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
-		continue;
-
-	    total_length += strlen(extensions[i]->name) + 1;
-	    reply.nExtensions += 1 + extensions[i]->num_aliases;
-	    for (j = extensions[i]->num_aliases; --j >= 0;)
-		total_length += strlen(extensions[i]->aliases[j]) + 1;
-	}
-        reply.length = bytes_to_int32(total_length);
-	buffer = bufptr = malloc(total_length);
-	if (!buffer)
-	    return BadAlloc;
-        for (i=0;  i<NumExtensions; i++)
-        {
-	    int len;
-	    if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
-		continue;
-
-            *bufptr++ = len = strlen(extensions[i]->name);
-	    memmove(bufptr, extensions[i]->name,  len);
-	    bufptr += len;
-	    for (j = extensions[i]->num_aliases; --j >= 0;)
-	    {
-		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
-		memmove(bufptr, extensions[i]->aliases[j],  len);
-		bufptr += len;
-	    }
-	}
-    }
-    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
-    if (reply.length)
-    {
-        WriteToClient(client, total_length, buffer);
-        free(buffer);
-    }
-    return Success;
-}
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#include "privates.h"
+#include "registry.h"
+#include "xace.h"
+
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR)) {
+        LogMessage(X_ERROR, "Not enabling extension %s: maximum number of "
+                   "events or errors exceeded.\n", name);
+        return((ExtensionEntry *) NULL);
+    }
+
+    ext = calloc(sizeof (ExtensionEntry), 1);
+    if (!ext)
+	return NULL;
+    if (!dixAllocatePrivates(&ext->devPrivates, PRIVATE_EXTENSION)) {
+	free(ext);
+	return NULL;
+    }
+    ext->name = strdup(name);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
+	free(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) realloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	free(ext->name);
+	dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
+	free(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+
+    RegisterExtensionNames(ext);
+    return ext;
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+    char *name;
+    char **aliases;
+
+    if (!ext)
+        return FALSE ;
+    aliases = (char **)realloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = strdup(alias);
+    if (!name)
+	return FALSE;
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+    return TRUE;
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+/*
+ * Added as part of Xace.
+ */
+ExtensionEntry *
+GetExtensionEntry(int major)
+{    
+    if (major < EXTENSION_BASE)
+	return NULL;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return NULL;
+    return extensions[major];
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions(void)
+{
+    int i,j;
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	if (extensions[i]->CloseDown)
+	    extensions[i]->CloseDown(extensions[i]);
+	NumExtensions = i;
+	free(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    free(extensions[i]->aliases[j]);
+	free(extensions[i]->aliases);
+	dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION);
+	free(extensions[i]);
+    }
+    free(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+}
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+    memset(&reply, 0, sizeof(xQueryExtensionReply));
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0 || XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return Success;
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    memset(&reply, 0, sizeof(xListExtensionsReply));
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+	    /* call callbacks to find out whether to show extension */
+	    if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
+		continue;
+
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = bytes_to_int32(total_length);
+	buffer = bufptr = malloc(total_length);
+	if (!buffer)
+	    return BadAlloc;
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+	    if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
+		continue;
+
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+        WriteToClient(client, total_length, buffer);
+
+    free(buffer);
+    return Success;
+}
-- 
cgit v1.2.3