xserver: Branch 'master' - 3 commits

Keith Packard keithp at kemper.freedesktop.org
Tue Jun 22 12:31:06 PDT 2010


 configure.ac                 |    2 
 hw/xfree86/loader/sdksyms.sh |    1 
 hw/xfree86/xaa/xaaOverlay.c  |   29 
 include/list.h               |    6 
 mi/Makefile.am               |    4 
 mi/mioverlay.c               | 1946 +++++++++++++++++++++++++++++++++++++++++++
 mi/mioverlay.h               |   32 
 7 files changed, 2014 insertions(+), 6 deletions(-)

New commits:
commit a68a101a730df7f73421555e381a50b074607c5e
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Jun 22 12:13:26 2010 -0700

    Bump to 1.8.99.903 -- 1.9 RC3
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 95a9444..1a1f2d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.8.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.8.99.903, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2010-06-22"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit 2c0159d21788b16607e6ebe4571b57fe78545c2a
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Mon Jun 14 09:25:22 2010 -0400

    list.h: Fix list_for_each_entry_safe()
    
    Can't use next as a macro argument since we're accessing the .next field
    of struct list.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/list.h b/include/list.h
index 89dc29d..4ce20a8 100644
--- a/include/list.h
+++ b/include/list.h
@@ -94,10 +94,10 @@ list_is_empty(struct list *head)
 	 &pos->member != (head);					\
 	 pos = __container_of(pos->member.next, pos, member))
 
-#define list_for_each_entry_safe(pos, next, head, member)		\
+#define list_for_each_entry_safe(pos, tmp, head, member)		\
     for (pos = __container_of((head)->next, pos, member),		\
-	 next = __container_of(pos->member.next, pos, member);		\
+	 tmp = __container_of(pos->member.next, pos, member);		\
 	 &pos->member != (head);					\
-	 pos = next, next = __container_of(next->member.next, next, member))
+	 pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
 
 #endif
commit e2918b67395a48397bf7db545584cc2d4f4e7ccf
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Jun 22 12:11:20 2010 -0700

    Revert "mi: Remove unused overlay support"
    
    This reverts commit 9120e58556014e514eef9dfe43cdea4b74dc66ae.
    
     Whoops, please revert this patch -- overlay is in use in nvidia drivers,
     and it's too late in release cycle to remove it.
    
     I feel really sorry that I kept this patch in my tree. I will submit
    another one, removing only XAA overlay hooks which are not used at all.

diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh
index 4245031..13c5ae5 100755
--- a/hw/xfree86/loader/sdksyms.sh
+++ b/hw/xfree86/loader/sdksyms.sh
@@ -231,6 +231,7 @@ cat > sdksyms.c << EOF
 #include "miwideline.h"
 #include "mistruct.h"
 #include "mifpoly.h"
+#include "mioverlay.h"
 
 
 /* randr/Makefile.am */
diff --git a/hw/xfree86/xaa/xaaOverlay.c b/hw/xfree86/xaa/xaaOverlay.c
index 58c4a58..4b52bf6 100644
--- a/hw/xfree86/xaa/xaaOverlay.c
+++ b/hw/xfree86/xaa/xaaOverlay.c
@@ -16,6 +16,7 @@
 #include "xaawrap.h"
 #include "gcstruct.h"
 #include "pixmapstr.h"
+#include "mioverlay.h"
 
 #ifdef PANORAMIX
 #include "panoramiX.h"
@@ -36,6 +37,7 @@ XAACopyWindow8_32(
     ScreenPtr pScreen = pWin->drawable.pScreen;
     XAAInfoRecPtr infoRec = 
 	GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+    Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
     RegionPtr borderClip = &pWin->borderClip;
     Bool freeReg = FALSE;
 
@@ -54,6 +56,9 @@ XAACopyWindow8_32(
 
     pwinRoot = pScreen->root;
 
+    if(doUnderlay)
+	freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);
+
     RegionNull(&rgnDst);
 
     dx = ptOldOrg.x - pWin->drawable.x;
@@ -76,7 +81,7 @@ XAACopyWindow8_32(
 	ppt++; pbox++;
     }
     
-    infoRec->ScratchGC.planemask = 0xff000000;
+    infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
     infoRec->ScratchGC.alu = GXcopy;
 
     XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
@@ -88,6 +93,25 @@ XAACopyWindow8_32(
 	RegionDestroy(borderClip);
 }
 
+static void
+XAASetColorKey8_32(
+    ScreenPtr pScreen,
+    int nbox,
+    BoxPtr pbox
+){
+    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+    ScrnInfoPtr pScrn = infoRec->pScrn;
+
+    /* I'm counting on writes being clipped away while switched away.
+       If this isn't going to be true then I need to be wrapping instead. */
+    if(!infoRec->pScrn->vtSema) return;
+
+    (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy, 
+					0xff000000, nbox, pbox);
+  
+    SET_SYNC_FLAG(infoRec);
+}
+
 void
 XAASetupOverlay8_32Planar(ScreenPtr pScreen)
 {
@@ -96,6 +120,9 @@ XAASetupOverlay8_32Planar(ScreenPtr pScreen)
 
     pScreen->CopyWindow = XAACopyWindow8_32;
 
+    if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
+	miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);
+
     infoRec->FullPlanemask = ~0;
     for(i = 0; i < 32; i++) /* haven't thought about this much */
 	infoRec->FullPlanemasks[i] = ~0;
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 8319226..f6dabda 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -3,7 +3,7 @@ noinst_LTLIBRARIES = libmi.la
 if XORG
 sdk_HEADERS = micmap.h miline.h mipointer.h mi.h mibstore.h \
               migc.h mipointrst.h mizerarc.h micoord.h mifillarc.h \
-              mispans.h miwideline.h mistruct.h mifpoly.h
+              mispans.h miwideline.h mistruct.h mifpoly.h mioverlay.h
 endif
 
 AM_CFLAGS = $(DIX_CFLAGS)
@@ -33,6 +33,8 @@ libmi_la_SOURCES = 	\
 	migc.h		\
 	miglblt.c	\
 	miline.h	\
+	mioverlay.c	\
+	mioverlay.h	\
 	mipointer.c	\
 	mipointer.h	\
 	mipointrst.h	\
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
new file mode 100644
index 0000000..766c5e7
--- /dev/null
+++ b/mi/mioverlay.c
@@ -0,0 +1,1946 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include <X11/extensions/shapeproto.h>
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "privates.h"
+#include "mivalidate.h"
+#include "mioverlay.h"
+#include "migc.h"
+
+#include "globals.h"
+
+
+typedef struct {
+   RegionRec 	exposed;
+   RegionRec	borderExposed;
+   RegionPtr	borderVisible;
+   DDXPointRec	oldAbsCorner;
+} miOverlayValDataRec, *miOverlayValDataPtr;
+
+typedef struct _TreeRec {
+   WindowPtr		pWin;
+   struct _TreeRec 	*parent;
+   struct _TreeRec 	*firstChild; 
+   struct _TreeRec 	*lastChild; 
+   struct _TreeRec 	*prevSib; 
+   struct _TreeRec 	*nextSib;
+   RegionRec 		borderClip;
+   RegionRec 		clipList;
+   unsigned		visibility;
+   miOverlayValDataPtr  valdata;
+} miOverlayTreeRec, *miOverlayTreePtr;
+
+typedef struct {
+   miOverlayTreePtr	tree;
+} miOverlayWindowRec, *miOverlayWindowPtr;
+
+typedef struct {
+   CloseScreenProcPtr   	CloseScreen;
+   CreateWindowProcPtr  	CreateWindow;
+   DestroyWindowProcPtr 	DestroyWindow;
+   UnrealizeWindowProcPtr	UnrealizeWindow;
+   RealizeWindowProcPtr		RealizeWindow;
+   miOverlayTransFunc		MakeTransparent;
+   miOverlayInOverlayFunc	InOverlay;
+   Bool				underlayMarked;
+   Bool				copyUnderlay;
+} miOverlayScreenRec, *miOverlayScreenPtr;
+
+static DevPrivateKeyRec miOverlayWindowKeyRec;
+#define miOverlayWindowKey (&miOverlayWindowKeyRec)
+static DevPrivateKeyRec miOverlayScreenKeyRec;
+#define miOverlayScreenKey (&miOverlayScreenKeyRec)
+
+static void RebuildTree(WindowPtr);
+static Bool HasUnderlayChildren(WindowPtr);
+static void MarkUnderlayWindow(WindowPtr);
+static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
+
+static Bool miOverlayCloseScreen(int, ScreenPtr);
+static Bool miOverlayCreateWindow(WindowPtr);
+static Bool miOverlayDestroyWindow(WindowPtr);
+static Bool miOverlayUnrealizeWindow(WindowPtr);
+static Bool miOverlayRealizeWindow(WindowPtr);
+static void miOverlayMarkWindow(WindowPtr);
+static void miOverlayReparentWindow(WindowPtr, WindowPtr);
+static void miOverlayRestackWindow(WindowPtr, WindowPtr);
+static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr*);
+static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool);
+static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind);
+static void miOverlayHandleExposures(WindowPtr);
+static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind);
+static void miOverlayWindowExposures(WindowPtr, RegionPtr, RegionPtr);
+static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
+					unsigned int, WindowPtr);
+static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
+
+static void miOverlaySetShape(WindowPtr, int);
+static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
+
+#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
+	dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
+#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
+	dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
+#define MIOVERLAY_GET_WINDOW_TREE(pWin) \
+	(MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
+
+#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
+#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
+
+#define MARK_OVERLAY(w) miMarkWindow(w)
+#define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+                                    HasBorder(w) && \
+                                    (w)->backgroundState == ParentRelative)
+
+Bool
+miInitOverlay(
+    ScreenPtr pScreen, 
+    miOverlayInOverlayFunc inOverlayFunc,
+    miOverlayTransFunc transFunc
+){
+    miOverlayScreenPtr	pScreenPriv;
+
+    if(!inOverlayFunc || !transFunc) return FALSE;
+
+    if(!dixRegisterPrivateKey(&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec)))
+	return FALSE;
+
+    if(!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0))
+	return FALSE;
+
+    if(!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
+	return FALSE;
+
+    dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
+
+    pScreenPriv->InOverlay = inOverlayFunc;
+    pScreenPriv->MakeTransparent = transFunc;
+    pScreenPriv->underlayMarked = FALSE;
+
+
+    pScreenPriv->CloseScreen = pScreen->CloseScreen;
+    pScreenPriv->CreateWindow = pScreen->CreateWindow;
+    pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+    pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
+    pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
+
+    pScreen->CloseScreen = miOverlayCloseScreen;
+    pScreen->CreateWindow = miOverlayCreateWindow;
+    pScreen->DestroyWindow = miOverlayDestroyWindow;
+    pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+    pScreen->RealizeWindow = miOverlayRealizeWindow;
+
+    pScreen->ReparentWindow = miOverlayReparentWindow;
+    pScreen->RestackWindow = miOverlayRestackWindow;
+    pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows;
+    pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow;
+    pScreen->ValidateTree = miOverlayValidateTree;
+    pScreen->HandleExposures = miOverlayHandleExposures;
+    pScreen->MoveWindow = miOverlayMoveWindow;
+    pScreen->WindowExposures = miOverlayWindowExposures;
+    pScreen->ResizeWindow = miOverlayResizeWindow;
+    pScreen->MarkWindow = miOverlayMarkWindow;
+    pScreen->ClearToBackground = miOverlayClearToBackground;
+    pScreen->SetShape = miOverlaySetShape;
+    pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth;
+
+    return TRUE;
+}
+
+
+static Bool 
+miOverlayCloseScreen(int i, ScreenPtr pScreen)
+{
+   miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+
+   pScreen->CloseScreen = pScreenPriv->CloseScreen; 
+   pScreen->CreateWindow = pScreenPriv->CreateWindow;
+   pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+   pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+   pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+
+   free(pScreenPriv);
+
+   return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+
+static Bool 
+miOverlayCreateWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin);
+    miOverlayTreePtr pTree = NULL;
+    Bool result = TRUE;
+
+    pWinPriv->tree = NULL;
+
+    if(!pWin->parent || !((*pScreenPriv->InOverlay)(pWin))) {
+	if(!(pTree = (miOverlayTreePtr)calloc(1, sizeof(miOverlayTreeRec))))
+	   return FALSE;
+    }
+
+    if(pScreenPriv->CreateWindow) {
+	pScreen->CreateWindow = pScreenPriv->CreateWindow;
+	result = (*pScreen->CreateWindow)(pWin);
+	pScreen->CreateWindow = miOverlayCreateWindow;
+    }
+	
+    if (pTree) {
+	if(result) {
+	    pTree->pWin = pWin;
+	    pTree->visibility = VisibilityNotViewable;
+	    pWinPriv->tree = pTree;
+	    if(pWin->parent) {
+		RegionNull(&(pTree->borderClip));
+		RegionNull(&(pTree->clipList));
+		RebuildTree(pWin);
+	    } else {
+		BoxRec fullBox;
+		fullBox.x1 = 0;
+		fullBox.y1 = 0;
+		fullBox.x2 = pScreen->width;
+		fullBox.y2 = pScreen->height;
+		RegionInit(&(pTree->borderClip), &fullBox, 1);
+		RegionInit(&(pTree->clipList), &fullBox, 1);
+	    }
+	} else free(pTree);
+    }
+
+    return TRUE;
+}
+
+
+static Bool 
+miOverlayDestroyWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    Bool result = TRUE;
+
+    if (pTree) {
+	if(pTree->prevSib)
+	   pTree->prevSib->nextSib = pTree->nextSib;
+	else if(pTree->parent)
+	   pTree->parent->firstChild = pTree->nextSib;
+
+	if(pTree->nextSib)
+	   pTree->nextSib->prevSib = pTree->prevSib;
+	else if(pTree->parent)
+	   pTree->parent->lastChild = pTree->prevSib;
+
+	RegionUninit(&(pTree->borderClip));
+	RegionUninit(&(pTree->clipList));
+	free(pTree);
+    }
+
+    if(pScreenPriv->DestroyWindow) {
+	pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+	result = (*pScreen->DestroyWindow)(pWin);
+	pScreen->DestroyWindow = miOverlayDestroyWindow;
+    }
+
+    return result;
+}
+
+static Bool 
+miOverlayUnrealizeWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    Bool result = TRUE;
+
+    if(pTree) pTree->visibility = VisibilityNotViewable;
+
+    if(pScreenPriv->UnrealizeWindow) {
+	pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+	result = (*pScreen->UnrealizeWindow)(pWin);
+	pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+    }
+
+    return result;
+}
+
+
+static Bool 
+miOverlayRealizeWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    Bool result = TRUE;
+
+    if(pScreenPriv->RealizeWindow) {
+	pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+	result = (*pScreen->RealizeWindow)(pWin);
+	pScreen->RealizeWindow = miOverlayRealizeWindow;
+    }
+
+    /* we only need to catch the root window realization */
+
+    if(result && !pWin->parent && !((*pScreenPriv->InOverlay)(pWin)))
+    {
+	BoxRec box;
+	box.x1 = box.y1 = 0;
+	box.x2 = pWin->drawable.width;
+	box.y2 = pWin->drawable.height;
+	(*pScreenPriv->MakeTransparent)(pScreen, 1, &box);
+    }
+
+    return result;
+}
+
+
+static void 
+miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
+{
+    if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+	/* This could probably be more optimal */
+	RebuildTree(pWin->drawable.pScreen->root->firstChild);
+    }	
+}
+
+static void 
+miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
+{
+    if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+	/* This could probably be more optimal */
+	RebuildTree(pWin);
+    }	
+}
+
+
+static Bool
+miOverlayMarkOverlappedWindows(
+    WindowPtr pWin,
+    WindowPtr pFirst,
+    WindowPtr *pLayerWin
+){
+    WindowPtr pChild, pLast;
+    Bool overMarked, underMarked, doUnderlay, markAll;
+    miOverlayTreePtr pTree = NULL, tLast, tChild;
+    BoxPtr box;
+    
+    overMarked = underMarked = markAll = FALSE;
+
+    if(pLayerWin) *pLayerWin = pWin; /* hah! */
+
+    doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin));
+
+    box = RegionExtents(&pWin->borderSize);
+
+    if((pChild = pFirst)) {
+	pLast = pChild->parent->lastChild;
+	while (1) {
+	    if (pChild == pWin) markAll = TRUE;
+
+	    if(doUnderlay && IN_UNDERLAY(pChild))
+		pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+	    if(pChild->viewable) {
+                if (RegionBroken(&pChild->winSize))
+                    SetWinSize (pChild);
+                if (RegionBroken(&pChild->borderSize))
+		    SetBorderSize (pChild);
+
+	    	if (markAll || 
+		    RegionContainsRect(&pChild->borderSize, box))
+		{
+		    MARK_OVERLAY(pChild);
+		    overMarked = TRUE;
+		    if(doUnderlay && IN_UNDERLAY(pChild)) {
+			MARK_UNDERLAY(pChild);
+			underMarked = TRUE;
+		    }
+		    if (pChild->firstChild) {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast)) {
+		pChild = pChild->parent;
+		if(doUnderlay && IN_UNDERLAY(pChild))
+		    pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+	    }
+
+	    if(pChild == pWin) markAll = FALSE;
+
+	    if (pChild == pLast) break;
+
+	    pChild = pChild->nextSib;
+	}
+	if(overMarked)
+	    MARK_OVERLAY(pWin->parent);
+    } 
+
+    if(doUnderlay && !pTree) {
+	if(!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) {
+ 	    pChild = pWin->lastChild;
+	    while(1) {
+		if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)))
+		    break;
+
+		if(pChild->lastChild) {
+		    pChild = pChild->lastChild;
+		    continue;
+		}
+
+		while(!pChild->prevSib) pChild = pChild->parent;
+
+		pChild = pChild->prevSib;
+	    }
+	}
+    }
+   
+    if(pTree && pTree->nextSib) {
+	tChild = pTree->parent->lastChild;
+	tLast = pTree->nextSib;	
+
+	while(1) {
+	    if(tChild->pWin->viewable) { 
+                if (RegionBroken(&tChild->pWin->winSize))
+                    SetWinSize (tChild->pWin);
+                if (RegionBroken(&tChild->pWin->borderSize))
+		    SetBorderSize (tChild->pWin);
+
+		if(RegionContainsRect(&(tChild->pWin->borderSize), box))
+	        {
+		    MARK_UNDERLAY(tChild->pWin);
+		    underMarked = TRUE;
+	        }
+	    }
+
+	    if(tChild->lastChild) {
+		tChild = tChild->lastChild;
+		continue;
+	    }
+
+	    while(!tChild->prevSib && (tChild != tLast))
+		tChild = tChild->parent;
+
+	    if(tChild == tLast) break;
+
+	    tChild = tChild->prevSib;
+	}
+    }
+
+    if(underMarked) {
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+	MARK_UNDERLAY(pTree->parent->pWin);
+	MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE;	
+    }
+
+    return underMarked || overMarked;
+}
+
+
+static void
+miOverlayComputeClips(
+    WindowPtr pParent, 
+    RegionPtr universe,
+    VTKind kind,
+    RegionPtr exposed
+){
+    ScreenPtr pScreen = pParent->drawable.pScreen;
+    int oldVis, newVis, dx, dy;
+    BoxRec borderSize;
+    RegionPtr borderVisible;
+    RegionRec childUniverse, childUnion;
+    miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent);
+    miOverlayTreePtr tChild;
+    Bool overlap;
+
+    borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+    borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+    dx = (int) pParent->drawable.x + (int) pParent->drawable.width + 
+						wBorderWidth(pParent);
+    if (dx > 32767) dx = 32767;
+    borderSize.x2 = dx;
+    dy = (int) pParent->drawable.y + (int) pParent->drawable.height + 
+						wBorderWidth(pParent);
+    if (dy > 32767) dy = 32767;
+    borderSize.y2 = dy;
+  
+    oldVis = tParent->visibility;
+    switch (RegionContainsRect(universe, &borderSize)) {
+	case rgnIN:
+	    newVis = VisibilityUnobscured;
+	    break;
+	case rgnPART:
+	    newVis = VisibilityPartiallyObscured;
+	    {
+		RegionPtr   pBounding;
+
+		if ((pBounding = wBoundingShape (pParent))) {
+		    switch (miShapedWindowIn (universe, pBounding,
+					      &borderSize,
+					      pParent->drawable.x,
+ 					      pParent->drawable.y))
+		    {
+		    case rgnIN:
+			newVis = VisibilityUnobscured;
+			break;
+		    case rgnOUT:
+			newVis = VisibilityFullyObscured;
+			break;
+		    }
+		}
+	    }
+	    break;
+	default:
+	    newVis = VisibilityFullyObscured;
+	    break;
+    }
+    tParent->visibility = newVis;
+
+    dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x;
+    dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y;
+
+    switch (kind) {
+    case VTMap:
+    case VTStack:
+    case VTUnmap:
+	break;
+    case VTMove:
+	if ((oldVis == newVis) &&
+	    ((oldVis == VisibilityFullyObscured) ||
+	     (oldVis == VisibilityUnobscured)))
+	{
+	    tChild = tParent;
+	    while (1) {
+		if (tChild->pWin->viewable) {
+		    if (tChild->visibility != VisibilityFullyObscured) {
+			RegionTranslate(&tChild->borderClip, dx, dy);
+			RegionTranslate(&tChild->clipList, dx, dy);
+		
+			tChild->pWin->drawable.serialNumber = 
+							 NEXT_SERIAL_NUMBER;
+                        if (pScreen->ClipNotify)
+                            (* pScreen->ClipNotify) (tChild->pWin, dx, dy);
+		    }
+		    if (tChild->valdata) {
+			RegionNull(&tChild->valdata->borderExposed);
+			if (HasParentRelativeBorder(tChild->pWin)){
+			    RegionSubtract(&tChild->valdata->borderExposed,
+					   &tChild->borderClip,
+					   &tChild->pWin->winSize);
+			}
+			RegionNull(&tChild->valdata->exposed);
+		    }
+		    if (tChild->firstChild) {
+			tChild = tChild->firstChild;
+			continue;
+		    }
+		}
+		while (!tChild->nextSib && (tChild != tParent))
+		    tChild = tChild->parent;
+		if (tChild == tParent)
+		    break;
+		tChild = tChild->nextSib;
+	    }
+	    return;
+	}
+	/* fall through */
+    default:
+    	if (dx || dy)  {
+	    RegionTranslate(&tParent->borderClip, dx, dy);
+	    RegionTranslate(&tParent->clipList, dx, dy);
+    	} 
+	break;
+    case VTBroken:
+	RegionEmpty(&tParent->borderClip);
+	RegionEmpty(&tParent->clipList);
+	break;
+    }
+
+    borderVisible = tParent->valdata->borderVisible;
+    RegionNull(&tParent->valdata->borderExposed);
+    RegionNull(&tParent->valdata->exposed);
+
+    if (HasBorder (pParent)) {
+    	if (borderVisible) {
+	    RegionSubtract(exposed, universe, borderVisible);
+	    RegionDestroy(borderVisible);
+    	} else
+	    RegionSubtract(exposed, universe, &tParent->borderClip);
+
+	if (HasParentRelativeBorder(pParent) && (dx || dy))
+	    RegionSubtract(&tParent->valdata->borderExposed,
+				  universe, &pParent->winSize);
+	else
+	    RegionSubtract(&tParent->valdata->borderExposed,
+			       exposed, &pParent->winSize);
+
+	RegionCopy(&tParent->borderClip, universe);
+	RegionIntersect(universe, universe, &pParent->winSize);
+    }
+    else
+	RegionCopy(&tParent->borderClip, universe);
+
+    if ((tChild = tParent->firstChild) && pParent->mapped) {
+	RegionNull(&childUniverse);
+	RegionNull(&childUnion);
+
+	for (; tChild; tChild = tChild->nextSib) {
+	    if (tChild->pWin->viewable)
+		RegionAppend(&childUnion, &tChild->pWin->borderSize);
+	}
+
+	RegionValidate(&childUnion, &overlap);
+
+	for (tChild = tParent->firstChild;
+	     tChild;
+	     tChild = tChild->nextSib)
+ 	{
+	    if (tChild->pWin->viewable) {
+		if (tChild->valdata) {
+		    RegionIntersect(&childUniverse, universe,
+					    &tChild->pWin->borderSize);
+		    miOverlayComputeClips (tChild->pWin, &childUniverse, 
+						kind, exposed);
+		}
+		if (overlap)
+		    RegionSubtract(universe, universe,
+					  &tChild->pWin->borderSize);
+	    }
+	}
+	if (!overlap)
+	    RegionSubtract(universe, universe, &childUnion);
+	RegionUninit(&childUnion);
+	RegionUninit(&childUniverse);
+    } 
+
+    if (oldVis == VisibilityFullyObscured ||
+	oldVis == VisibilityNotViewable)
+    {
+	RegionCopy(&tParent->valdata->exposed, universe);
+    }
+    else if (newVis != VisibilityFullyObscured &&
+	     newVis != VisibilityNotViewable)
+    {
+	RegionSubtract(&tParent->valdata->exposed,
+			       universe, &tParent->clipList);
+    }
+    
+    /* HACK ALERT - copying contents of regions, instead of regions */
+    {
+	RegionRec   tmp;
+
+	tmp = tParent->clipList;
+	tParent->clipList = *universe;
+	*universe = tmp;
+    }
+
+    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    if (pScreen->ClipNotify)
+        (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+
+static void 
+miOverlayMarkWindow(WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = NULL;
+    WindowPtr pChild, pGrandChild;
+   
+    miMarkWindow(pWin);
+
+    /* look for UnmapValdata among immediate children */
+
+    if(!(pChild = pWin->firstChild)) return;
+
+    for( ; pChild; pChild = pChild->nextSib) {
+	if(pChild->valdata == UnmapValData) {
+	    if(IN_UNDERLAY(pChild)) {
+		pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+		pTree->valdata = (miOverlayValDataPtr)UnmapValData; 
+		continue;
+	    } else {	
+	        if(!(pGrandChild = pChild->firstChild))
+		   continue;
+
+		while(1) {
+		    if(IN_UNDERLAY(pGrandChild)) {
+			pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild);
+			pTree->valdata = (miOverlayValDataPtr)UnmapValData; 
+		    } else if(pGrandChild->firstChild) {	
+			pGrandChild = pGrandChild->firstChild;
+			continue;
+		    }
+
+		    while(!pGrandChild->nextSib && (pGrandChild != pChild))
+			pGrandChild = pGrandChild->parent;
+
+		    if(pChild == pGrandChild) break;
+		
+		    pGrandChild = pGrandChild->nextSib;
+		}
+	    }
+        }
+    }
+
+    if(pTree) {
+	MARK_UNDERLAY(pTree->parent->pWin);
+	MIOVERLAY_GET_SCREEN_PRIVATE(
+		pWin->drawable.pScreen)->underlayMarked = TRUE;
+    }
+}
+
+static void
+miOverlayMarkUnrealizedWindow(
+    WindowPtr pChild,
+    WindowPtr pWin,
+    Bool fromConfigure
+){
+    if ((pChild != pWin) || fromConfigure) {
+	miOverlayTreePtr pTree;
+
+        RegionEmpty(&pChild->clipList);
+        if (pChild->drawable.pScreen->ClipNotify)
+            (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+        RegionEmpty(&pChild->borderClip);
+	if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+	    if(pTree->valdata != (miOverlayValDataPtr)UnmapValData) {
+		RegionEmpty(&pTree->clipList);
+		RegionEmpty(&pTree->borderClip);
+	    }
+	}
+    }
+}
+
+
+static int 
+miOverlayValidateTree(
+    WindowPtr pParent,
+    WindowPtr pChild,   /* first child effected */
+    VTKind    kind
+){
+    ScreenPtr pScreen = pParent->drawable.pScreen;
+    miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    RegionRec totalClip, childClip, exposed;
+    miOverlayTreePtr tParent, tChild, tWin;
+    Bool overlap;
+    WindowPtr newParent;
+
+    if(!pPriv->underlayMarked)
+	goto SKIP_UNDERLAY;
+
+    if (!pChild) pChild = pParent->firstChild;
+
+    RegionNull(&totalClip);
+    RegionNull(&childClip);
+    RegionNull(&exposed);
+
+    newParent = pParent;
+
+    while(IN_OVERLAY(newParent))
+    	newParent = newParent->parent;
+
+    tParent = MIOVERLAY_GET_WINDOW_TREE(newParent);
+
+    if(IN_UNDERLAY(pChild))
+	tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+    else
+	tChild = tParent->firstChild;
+
+    if (RegionBroken(&tParent->clipList) &&
+        !RegionBroken(&tParent->borderClip))
+    {
+	kind = VTBroken;
+	RegionCopy(&totalClip, &tParent->borderClip);
+	RegionIntersect(&totalClip, &totalClip,
+						 &tParent->pWin->winSize);
+        
+        for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
+            if (tWin->pWin->viewable)
+                RegionSubtract(&totalClip, &totalClip,
+					&tWin->pWin->borderSize);
+        }        
+        RegionEmpty(&tParent->clipList);
+    } else {
+	for(tWin = tChild; tWin; tWin = tWin->nextSib) {
+	    if(tWin->valdata)
+		RegionAppend(&totalClip, &tWin->borderClip);
+	}
+	RegionValidate(&totalClip, &overlap);
+    }
+
+    if(kind != VTStack)
+	RegionUnion(&totalClip, &totalClip, &tParent->clipList);
+	
+    for(tWin = tChild; tWin; tWin = tWin->nextSib) {
+	if(tWin->valdata) {
+	    if(tWin->pWin->viewable) {
+		RegionIntersect(&childClip, &totalClip,
+					&tWin->pWin->borderSize);
+		miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed);
+		RegionSubtract(&totalClip, &totalClip,
+					&tWin->pWin->borderSize);
+	    } else {  /* Means we are unmapping */
+                RegionEmpty(&tWin->clipList);
+                RegionEmpty(&tWin->borderClip);
+		tWin->valdata = NULL;
+	    }
+	}
+    }
+
+    RegionUninit(&childClip);
+
+    if(!((*pPriv->InOverlay)(newParent))) {
+	RegionNull(&tParent->valdata->exposed);
+	RegionNull(&tParent->valdata->borderExposed);
+    }
+
+    switch (kind) {
+    case VTStack:
+	break;
+    default:
+    	if(!((*pPriv->InOverlay)(newParent))) 
+	    RegionSubtract(&tParent->valdata->exposed, &totalClip,
+						&tParent->clipList);
+	/* fall through */
+    case VTMap:
+	RegionCopy(&tParent->clipList, &totalClip);
+    	if(!((*pPriv->InOverlay)(newParent))) 
+	    newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	break;
+    }
+
+    RegionUninit(&totalClip);
+    RegionUninit(&exposed);
+
+SKIP_UNDERLAY:
+
+    miValidateTree(pParent, pChild, kind);
+
+    return 1;
+}
+
+
+static void
+miOverlayHandleExposures(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    WindowPtr pChild;
+    ValidatePtr val;
+    void (* WindowExposures)(WindowPtr, RegionPtr, RegionPtr);
+
+    WindowExposures = pWin->drawable.pScreen->WindowExposures;
+    if(pPriv->underlayMarked) {
+	miOverlayTreePtr pTree;
+	miOverlayValDataPtr mival;
+
+	pChild = pWin;
+	while(IN_OVERLAY(pChild))
+	    pChild = pChild->parent;
+
+	pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+	while (1) {
+	    if((mival = pTree->valdata)) {
+		if(!((*pPriv->InOverlay)(pTree->pWin))) {
+		    if (RegionNotEmpty(&mival->borderExposed)) {
+			miPaintWindow(pTree->pWin, &mival->borderExposed,
+				      PW_BORDER);
+		    }
+		    RegionUninit(&mival->borderExposed);
+
+		    (*WindowExposures)(pTree->pWin,&mival->exposed,NullRegion);
+		    RegionUninit(&mival->exposed);
+		}
+		free(mival);
+		pTree->valdata = NULL;
+		if (pTree->firstChild) {
+		    pTree = pTree->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pTree->nextSib && (pTree->pWin != pChild))
+	    	pTree = pTree->parent;
+	    if (pTree->pWin == pChild)
+		break;
+	    pTree = pTree->nextSib;
+        }
+	pPriv->underlayMarked = FALSE;
+    }
+
+    pChild = pWin;
+    while (1) {
+	if ( (val = pChild->valdata) ) {
+	    if(!((*pPriv->InOverlay)(pChild))) {
+		RegionUnion(&val->after.exposed, &val->after.exposed,
+			&val->after.borderExposed);
+
+		if (RegionNotEmpty(&val->after.exposed)) {
+		   (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))(
+				pScreen, 
+				RegionNumRects(&val->after.exposed),
+				RegionRects(&val->after.exposed));
+		}
+	    } else {
+		if (RegionNotEmpty(&val->after.borderExposed)) {
+			miPaintWindow(pChild, &val->after.borderExposed,
+				      PW_BORDER);
+		}
+		(*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    }
+	    RegionUninit(&val->after.borderExposed);
+	    RegionUninit(&val->after.exposed);
+	    free(val);
+	    pChild->valdata = NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+
+static void
+miOverlayMoveWindow(
+    WindowPtr pWin,
+    int x,
+    int y,
+    WindowPtr pNextSib,
+    VTKind kind
+){
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    WindowPtr pParent, windowToValidate;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionRec overReg, underReg;
+    DDXPointRec oldpt;
+
+    if (!(pParent = pWin->parent))
+       return ;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable) {
+	RegionNull(&overReg);
+	RegionNull(&underReg);
+	if(pTree) {
+	    RegionCopy(&overReg, &pWin->borderClip);
+	    RegionCopy(&underReg, &pTree->borderClip);
+        } else {
+	    RegionCopy(&overReg, &pWin->borderClip);
+	    CollectUnderlayChildrenRegions(pWin, &underReg);
+	}
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable) {
+	miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+	(*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL);
+
+
+	(*pScreen->ValidateTree)(pWin->parent, NullWindow, kind);
+	if(RegionNotEmpty(&underReg)) {
+	    pPriv->copyUnderlay = TRUE;
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &underReg);
+	}
+	RegionUninit(&underReg);
+	if(RegionNotEmpty(&overReg)) {
+	    pPriv->copyUnderlay = FALSE;
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &overReg);
+	}
+	RegionUninit(&overReg);
+	(*pScreen->HandleExposures)(pWin->parent);
+
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25
+#endif
+
+static void 
+miOverlayWindowExposures(
+    WindowPtr pWin,
+    RegionPtr prgn,
+    RegionPtr other_exposed
+){
+    RegionPtr   exposures = prgn;
+
+    if ((prgn && !RegionNil(prgn)) ||
+	(exposures && !RegionNil(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) &
+		 	    ExposureMask;
+	if (other_exposed) {
+	    if (exposures) {
+		RegionUnion(other_exposed, exposures, other_exposed);
+		if (exposures != prgn)
+		    RegionDestroy(exposures);
+	    }
+	    exposures = other_exposed;
+	}
+	if (clientInterested && exposures && 
+	   (RegionNumRects(exposures) > RECTLIMIT))
+	{
+	    ScreenPtr pScreen = pWin->drawable.pScreen;
+            miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+	    BoxRec box;
+
+	    box = *RegionExtents(exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		RegionInit(exposures, &box, 1);
+		RegionReset(prgn, &box);
+	    } else {
+		RegionReset(exposures, &box);
+		RegionUnion(prgn, prgn, exposures);
+	    }
+	    /* This is the only reason why we are replacing mi's version
+               of this file */
+	    
+	    if(!((*pPriv->InOverlay)(pWin))) {
+		miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+		RegionIntersect(prgn, prgn, &pTree->clipList);
+	    } else
+		RegionIntersect(prgn, prgn, &pWin->clipList);
+	}
+	if (prgn && !RegionNil(prgn))
+	    miPaintWindow(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !RegionNil(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec) {
+	    RegionUninit(exposures);
+	} 
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    RegionDestroy(exposures);
+	if (prgn)
+	    RegionEmpty(prgn);
+    }
+    else if (exposures && exposures != prgn)
+	RegionDestroy(exposures);
+}
+
+
+typedef struct {
+   RegionPtr over;
+   RegionPtr under;
+} miOverlayTwoRegions; 
+
+static int
+miOverlayRecomputeExposures (
+    WindowPtr	pWin,
+    pointer	value 
+){
+    miOverlayTwoRegions	*pValid = (miOverlayTwoRegions*)value;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if (pWin->valdata) {
+	/*
+	 * compute exposed regions of this window
+	 */
+	RegionSubtract(&pWin->valdata->after.exposed,
+			&pWin->clipList, pValid->over);
+	/*
+	 * compute exposed regions of the border
+	 */
+	RegionSubtract(&pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	RegionSubtract(&pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid->over);
+    } 
+
+    if(pTree && pTree->valdata) {
+	RegionSubtract(&pTree->valdata->exposed,
+			&pTree->clipList, pValid->under);
+	RegionSubtract(&pTree->valdata->borderExposed,
+			     &pTree->borderClip, &pWin->winSize);
+	RegionSubtract(&pTree->valdata->borderExposed,
+			     &pTree->valdata->borderExposed, pValid->under);    
+    } else if (!pWin->valdata)
+	return WT_NOMATCH;
+
+    return WT_WALKCHILDREN;
+}
+
+static void
+miOverlayResizeWindow(
+    WindowPtr pWin,
+    int x, int y,
+    unsigned int w, unsigned int h,
+    WindowPtr pSib
+){
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pParent;
+    miOverlayTreePtr tChild, pTree;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width;
+    unsigned short height = pWin->drawable.height;
+    short oldx = pWin->drawable.x;
+    short oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL, oldRegion2 = NULL;
+    WindowPtr pFirstChange;
+    WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    RegionPtr	gravitate2[StaticGravity + 1];
+    unsigned 	g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip, destClip2;
+    RegionPtr	oldWinClip = NULL, oldWinClip2 = NULL;	
+    RegionPtr	borderVisible = NullRegion; 
+    RegionPtr	borderVisible2 = NullRegion; 
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+    Bool	doUnderlay;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = RegionCreate(NullBox, 1);
+	RegionCopy(oldRegion, &pWin->winSize);
+	if(doUnderlay) {
+	    oldRegion2 = RegionCreate(NullBox, 1);
+	    RegionCopy(oldRegion2, &pWin->winSize);
+	}
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = gravitate2[g] = NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity) {
+		if (!gravitate[g])
+		    gravitate[g] = RegionCreate(NullBox, 1);
+		RegionUnion(gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+		
+		if(doUnderlay) {
+		    if (!gravitate2[g])
+			gravitate2[g] = RegionCreate(NullBox, 0);
+		
+		    if((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+		        RegionUnion(gravitate2[g],
+				   gravitate2[g], &tChild->borderClip);
+		    } else 
+			CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
+		}
+	    } else {
+		UnmapWindow(pChild, TRUE);
+	    }
+	}
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+
+	oldWinClip = oldWinClip2 = NULL;
+	if (pWin->bitGravity != ForgetGravity) {
+	    oldWinClip = RegionCreate(NullBox, 1);
+	    RegionCopy(oldWinClip, &pWin->clipList);
+	    if(pTree) {
+		oldWinClip2 = RegionCreate(NullBox, 1);
+		RegionCopy(oldWinClip2, &pTree->clipList);
+	    }
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = RegionCreate(NullBox, 1);
+	    if(pTree)
+		borderVisible2 = RegionCreate(NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    RegionSubtract(borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    RegionCopy(borderVisible,
+					    &pWin->borderClip);
+		if(pTree) {
+		    if (shrunk || moved)
+			RegionSubtract(borderVisible,
+					  &pTree->borderClip,
+					  &pWin->winSize);
+		    else
+			RegionCopy(borderVisible,
+					    &pTree->borderClip);
+		}
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable) {
+	pRegion = RegionCreate(NullBox, 1);
+
+	(*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL);
+
+	pWin->valdata->before.resized = TRUE;
+	pWin->valdata->before.borderVisible = borderVisible;
+	if(pTree)
+	    pTree->valdata->borderVisible = borderVisible2;
+
+
+	(*pScreen->ValidateTree)(pWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
+	if(pTree)
+	    RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (WasViewable) {
+	miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+	miOverlayTwoRegions TwoRegions;
+
+	/* avoid the border */
+	if (HasBorder (pWin)) {
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++) {
+		if (!gravitate[g] && !gravitate2[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy) {
+		    RegionTranslate(&pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		if(gravitate[g])
+		    RegionIntersect(gravitate[g], gravitate[g],
+				 &pWin->winSize);
+		if(gravitate2[g])
+		    RegionIntersect(gravitate2[g], gravitate2[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		RegionTranslate(&pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip2)
+	{
+	    RegionCopy(pRegion, oldWinClip2);
+	    RegionTranslate(pRegion, nx - oldx, ny - oldy);
+	    RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
+
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+		if (gravitate2[g])
+		    RegionSubtract(oldWinClip2, oldWinClip2,
+					gravitate2[g]);
+	    }
+	    RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate2[g])
+		gravitate2[g] = oldWinClip2;
+	    else {
+		RegionUnion(gravitate2[g],gravitate2[g],oldWinClip2);
+		RegionDestroy(oldWinClip2);
+	    }
+	}
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    RegionCopy(pRegion, oldWinClip);
+	    RegionTranslate(pRegion, nx - oldx, ny - oldy);
+	    RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+		if (gravitate[g])
+		    RegionSubtract(oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else {
+		RegionUnion(gravitate[g], gravitate[g], oldWinClip);
+		RegionDestroy(oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = destClip2 = NULL;
+
+	for (g = 0; g <= StaticGravity; g++) {
+	    if (!gravitate[g] && !gravitate2[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    if(gravitate[g])
+		RegionIntersect(gravitate[g],
+				 gravitate[g], oldRegion);
+	    if(gravitate2[g])
+		RegionIntersect(gravitate2[g],
+				 gravitate2[g], oldRegion2);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip && gravitate[g]) {
+		RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
+		RegionSubtract(gravitate[g], gravitate[g], destClip);
+		RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
+	    }
+	    if (destClip2 && gravitate2[g]) {
+		RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
+		RegionSubtract(gravitate2[g],gravitate2[g],destClip2);
+		RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y) {
+		if(gravitate2[g]) {
+		    pPriv->copyUnderlay = TRUE;
+		    (*pScreen->CopyWindow)(pWin, oldpt, gravitate2[g]);
+		}
+		if(gravitate[g]) {
+		    pPriv->copyUnderlay = FALSE;
+		    (*pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+		}
+	    }
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    if(gravitate[g])
+		RegionSubtract(oldRegion, oldRegion, gravitate[g]);
+	    if(gravitate2[g])
+		RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+		if (pChild->winGravity != g)
+		    continue;
+
+		TwoRegions.over = gravitate[g];
+		TwoRegions.under = gravitate2[g];
+
+		TraverseTree (pChild, miOverlayRecomputeExposures, 
+					(pointer)(&TwoRegions));
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity) {
+		if(gravitate[g])
+		    RegionSubtract(&pWin->valdata->after.exposed,
+				&pWin->valdata->after.exposed, gravitate[g]);
+		if(gravitate2[g] && pTree) 
+		    RegionSubtract(&pTree->valdata->exposed,
+				&pTree->valdata->exposed, gravitate2[g]);
+	    }
+	    if(gravitate[g]) {
+		if (!destClip)
+		    destClip = gravitate[g];
+		else {
+		    RegionUnion(destClip, destClip, gravitate[g]);
+		    RegionDestroy(gravitate[g]);
+		}
+	    }
+	    if(gravitate2[g]) {
+		if (!destClip2)
+		    destClip2 = gravitate2[g];
+		else {
+		    RegionUnion(destClip2, destClip2, gravitate2[g]);
+		    RegionDestroy(gravitate2[g]);
+		}
+	    }
+	}
+
+	RegionDestroy(pRegion);
+	RegionDestroy(oldRegion);
+	if(doUnderlay)
+	    RegionDestroy(oldRegion2);
+	if (destClip)
+	    RegionDestroy(destClip);
+	if (destClip2)
+	    RegionDestroy(destClip2);
+	(*pScreen->HandleExposures)(pWin->parent);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pWin->parent, pFirstChange, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+static void
+miOverlaySetShape(WindowPtr pWin, int kind)
+{
+    Bool        WasViewable = (Bool)(pWin->viewable);
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+
+    if (kind != ShapeInput) {
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+            if (HasBorder (pWin)) {
+                RegionPtr borderVisible;
+
+                borderVisible = RegionCreate(NullBox, 1);
+                RegionSubtract(borderVisible,
+                                        &pWin->borderClip, &pWin->winSize);
+                pWin->valdata->before.borderVisible = borderVisible;
+                pWin->valdata->before.resized = TRUE;
+                if(IN_UNDERLAY(pWin)) {
+                    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+                    RegionPtr borderVisible2;
+
+                    borderVisible2 = RegionCreate(NULL, 1);
+                    RegionSubtract(borderVisible2,
+                                        &pTree->borderClip, &pWin->winSize);
+                    pTree->valdata->borderVisible = borderVisible2;
+                }
+            }
+        }
+
+        SetWinSize (pWin);
+        SetBorderSize (pWin);
+
+        ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+
+            (*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
+        }
+
+        if (WasViewable) {
+            (*pScreen->HandleExposures)(pWin->parent);
+            if (pScreen->PostValidateTree)
+                (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
+        }
+    }
+    if (pWin->realized)
+        WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+
+
+
+static void
+miOverlayChangeBorderWidth(
+    WindowPtr pWin,
+    unsigned int width
+){
+    int oldwidth;
+    ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    if (WasViewable && (width < oldwidth))
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable) {
+	if (width > oldwidth) {
+	    (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+	    if (HadBorder) {
+		RegionPtr   borderVisible;
+		borderVisible = RegionCreate(NULL, 1);
+		RegionSubtract(borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+		if(IN_UNDERLAY(pWin)) {
+		    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+		    RegionPtr borderVisible2;
+
+		    borderVisible2 = RegionCreate(NULL, 1);
+		    RegionSubtract(borderVisible2,
+				      &pTree->borderClip, &pWin->winSize);
+		    pTree->valdata->borderVisible = borderVisible2;
+		}
+	    }
+	}
+	(*pScreen->ValidateTree)(pWin->parent, pWin, VTOther);
+	(*pScreen->HandleExposures)(pWin->parent);
+
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pWin->parent, pWin, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*  We need this as an addition since the xf86 common code doesn't
+    know about the second tree which is static to this file.  */
+
+void
+miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
+{
+    WindowPtr pRoot = pScreen->root;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
+
+    MARK_UNDERLAY(pRoot);
+
+    if(enable) {
+	BoxRec box;
+	
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pScreen->width;
+	box.y2 = pScreen->height;
+
+	RegionReset(&pTree->borderClip, &box);
+    } else 
+	RegionEmpty(&pTree->borderClip);
+
+    RegionBreak(&pTree->clipList);
+}
+
+static void 
+miOverlayClearToBackground(
+    WindowPtr pWin,
+    int x, int y,
+    int w, int h,
+    Bool generateExposures
+)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    BoxRec box;
+    RegionRec reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    RegionPtr clipList;
+    BoxPtr  extents;
+    int     x1, y1, x2, y2;
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;    
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    clipList = ((*pScreenPriv->InOverlay)(pWin)) ? &pWin->clipList :
+                                                 &pTree->clipList;
+
+    extents = RegionExtents(clipList);
+    
+    if (x1 < extents->x1) x1 = extents->x1;
+    if (x2 > extents->x2) x2 = extents->x2;
+    if (y1 < extents->y1) y1 = extents->y1;
+    if (y2 > extents->y2) y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1) 
+        x2 = x1 = y2 = y1 = 0;
+
+    box.x1 = x1; box.x2 = x2;
+    box.y1 = y1; box.y2 = y2;
+
+    RegionInit(&reg, &box, 1);
+
+    RegionIntersect(&reg, &reg, clipList);
+    if (generateExposures)
+        (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+	miPaintWindow(pWin, &reg, PW_BACKGROUND);
+    RegionUninit(&reg);
+    if (pBSReg)
+        RegionDestroy(pBSReg);
+}
+
+
+/****************************************************************/
+
+/* not used */
+Bool
+miOverlayGetPrivateClips(
+    WindowPtr pWin,
+    RegionPtr *borderClip,
+    RegionPtr *clipList
+){
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+	
+    if(pTree) {
+ 	*borderClip = &(pTree->borderClip);
+	*clipList = &(pTree->clipList);
+	return TRUE;
+    }
+
+    *borderClip = *clipList = NULL;
+
+    return FALSE;
+}
+
+void
+miOverlaySetTransFunction (
+   ScreenPtr pScreen, 
+   miOverlayTransFunc transFunc
+){
+    MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
+}
+
+Bool
+miOverlayCopyUnderlay(ScreenPtr pScreen)
+{
+    return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
+}
+
+void
+miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    RegionPtr       pregWin;
+    Bool            freeTmpClip, freeCompClip;
+
+    if(!pTree) {
+	miComputeCompositeClip(pGC, &pWin->drawable);
+	return;
+    }
+
+    if (pGC->subWindowMode == IncludeInferiors) {
+	pregWin = RegionCreate(NullBox, 1);
+	freeTmpClip = TRUE;
+	if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
+		!HasSaverWindow (pGC->pScreen))
+	{
+            RegionIntersect(pregWin,&pTree->borderClip,&pWin->winSize);
+	}
+    } else {
+	pregWin = &pTree->clipList;
+	freeTmpClip = FALSE;
+    }
+    freeCompClip = pGC->freeCompClip;
+    if (pGC->clientClipType == CT_NONE) {
+	if (freeCompClip) 
+	    RegionDestroy(pGC->pCompositeClip);
+	pGC->pCompositeClip = pregWin;
+	pGC->freeCompClip = freeTmpClip;
+    } else {
+	RegionTranslate(pGC->clientClip,
+				pWin->drawable.x + pGC->clipOrg.x,
+				pWin->drawable.y + pGC->clipOrg.y);
+
+	if (freeCompClip) {
+	    RegionIntersect(pGC->pCompositeClip,
+					    pregWin, pGC->clientClip);
+	    if (freeTmpClip)
+		RegionDestroy(pregWin);
+	} else if (freeTmpClip) {
+	    RegionIntersect(pregWin, pregWin, pGC->clientClip);
+	    pGC->pCompositeClip = pregWin;
+	} else {
+	    pGC->pCompositeClip = RegionCreate(NullBox, 0);
+	    RegionIntersect(pGC->pCompositeClip,
+				       pregWin, pGC->clientClip);
+	}
+	pGC->freeCompClip = TRUE;
+	RegionTranslate(pGC->clientClip,
+				-(pWin->drawable.x + pGC->clipOrg.x),
+				-(pWin->drawable.y + pGC->clipOrg.y));
+    }
+}
+
+Bool
+miOverlayCollectUnderlayRegions(
+    WindowPtr pWin,
+    RegionPtr *region
+){
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if(pTree) {
+	*region = &pTree->borderClip;
+	return FALSE;
+    }
+
+    *region = RegionCreate(NullBox, 0);
+    
+    CollectUnderlayChildrenRegions(pWin, *region);
+
+    return TRUE;
+}
+
+
+static miOverlayTreePtr
+DoLeaf(
+    WindowPtr pWin, 
+    miOverlayTreePtr parent, 
+    miOverlayTreePtr prevSib
+){
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    
+    pTree->parent = parent;
+    pTree->firstChild = NULL;
+    pTree->lastChild = NULL;
+    pTree->prevSib = prevSib;
+    pTree->nextSib = NULL;
+
+    if(prevSib)
+	prevSib->nextSib = pTree;
+
+    if(!parent->firstChild)
+	parent->firstChild = parent->lastChild = pTree;
+    else if(parent->lastChild == prevSib)
+	parent->lastChild = pTree;
+   
+    return pTree;
+}
+
+static void 
+RebuildTree(WindowPtr pWin)
+{
+    miOverlayTreePtr parent, prevSib, tChild;
+    WindowPtr pChild;
+
+    prevSib = tChild = NULL;
+
+    pWin = pWin->parent;
+
+    while(IN_OVERLAY(pWin))
+	pWin = pWin->parent;
+
+    parent = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    pChild = pWin->firstChild;
+    parent->firstChild = parent->lastChild = NULL;
+
+    while(1) {
+	if(IN_UNDERLAY(pChild))
+	   prevSib = tChild = DoLeaf(pChild, parent, prevSib);
+
+	if(pChild->firstChild) {
+	    if(IN_UNDERLAY(pChild)) {
+		parent = tChild;
+		prevSib = NULL;
+	    }
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+
+	while(!pChild->nextSib) {
+	    pChild = pChild->parent;
+	    if(pChild == pWin) return;
+	    if(IN_UNDERLAY(pChild)) {
+		prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+		parent = tChild->parent;
+	    }
+	}
+
+	pChild = pChild->nextSib;
+    }
+}
+
+
+static Bool
+HasUnderlayChildren(WindowPtr pWin)
+{
+    WindowPtr pChild;
+
+    if(!(pChild = pWin->firstChild)) 
+	return FALSE;
+
+    while(1) {
+	if(IN_UNDERLAY(pChild))
+	   return TRUE;
+
+	if(pChild->firstChild) {
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+
+	while(!pChild->nextSib && (pWin != pChild))
+	    pChild = pChild->parent;
+
+	if(pChild == pWin) break;
+
+	pChild = pChild->nextSib;
+    }
+
+    return FALSE;
+}
+
+
+static Bool
+CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
+{
+    WindowPtr pChild;
+    miOverlayTreePtr pTree;
+    Bool hasUnderlay;
+
+    if(!(pChild = pWin->firstChild)) 
+	return FALSE;
+
+    hasUnderlay = FALSE;
+
+    while(1) {
+	if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+	    RegionAppend(pReg, &pTree->borderClip);
+	    hasUnderlay = TRUE;
+	} else
+	if(pChild->firstChild) {
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+
+	while(!pChild->nextSib && (pWin != pChild))
+	    pChild = pChild->parent;
+
+	if(pChild == pWin) break;
+
+	pChild = pChild->nextSib;
+    }
+
+    if(hasUnderlay) {
+	Bool overlap;
+	RegionValidate(pReg, &overlap);
+    } 
+
+    return hasUnderlay;
+}
+
+
+static void 
+MarkUnderlayWindow(WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if(pTree->valdata) return;
+    pTree->valdata = (miOverlayValDataPtr)xnfalloc(sizeof(miOverlayValDataRec));
+    pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
+    pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
+    pTree->valdata->borderVisible = NullRegion;
+}
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
new file mode 100644
index 0000000..dca65ad
--- /dev/null
+++ b/mi/mioverlay.h
@@ -0,0 +1,32 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef __MIOVERLAY_H
+#define __MIOVERLAY_H
+
+typedef void (*miOverlayTransFunc)(ScreenPtr, int, BoxPtr);
+typedef Bool (*miOverlayInOverlayFunc)(WindowPtr);
+
+extern _X_EXPORT Bool
+miInitOverlay(
+   ScreenPtr pScreen, 
+   miOverlayInOverlayFunc inOverlay,
+   miOverlayTransFunc trans
+);
+
+extern _X_EXPORT Bool
+miOverlayGetPrivateClips(
+    WindowPtr pWin,
+    RegionPtr *borderClip,
+    RegionPtr *clipList
+);
+
+extern _X_EXPORT Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr*);
+extern _X_EXPORT void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
+extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr);
+extern _X_EXPORT void miOverlaySetTransFunction(ScreenPtr, miOverlayTransFunc);
+extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool);
+
+#endif /* __MIOVERLAY_H */


More information about the xorg-commit mailing list