2079 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			2079 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $XFree86: xc/programs/Xserver/mi/mioverlay.c,v 3.15tsi Exp $ */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include "scrnintstr.h"
 | |
| #include "validate.h"
 | |
| #include "windowstr.h"
 | |
| #include "mi.h"
 | |
| #include "gcstruct.h"
 | |
| #include "regionstr.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 unsigned long miOverlayGeneration = 0;
 | |
| int miOverlayWindowIndex = -1;
 | |
| int miOverlayScreenIndex = -1;
 | |
| 
 | |
| 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);
 | |
| 
 | |
| #ifdef SHAPE
 | |
| static void miOverlaySetShape(WindowPtr);
 | |
| #endif
 | |
| static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
 | |
| 
 | |
| #define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) \
 | |
| 	((miOverlayScreenPtr)((pScreen)->devPrivates[miOverlayScreenIndex].ptr))
 | |
| #define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) \
 | |
| 	((miOverlayWindowPtr)((pWin)->devPrivates[miOverlayWindowIndex].ptr))
 | |
| #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)
 | |
| 
 | |
| _X_EXPORT Bool
 | |
| miInitOverlay(
 | |
|     ScreenPtr pScreen, 
 | |
|     miOverlayInOverlayFunc inOverlayFunc,
 | |
|     miOverlayTransFunc transFunc
 | |
| ){
 | |
|     miOverlayScreenPtr	pScreenPriv;
 | |
| 
 | |
|     if(!inOverlayFunc || !transFunc) return FALSE;
 | |
| 
 | |
|     if(miOverlayGeneration != serverGeneration) {
 | |
| 	if(((miOverlayScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
 | |
| 	   ((miOverlayWindowIndex = AllocateWindowPrivateIndex()) < 0))
 | |
| 	    return FALSE;
 | |
| 	
 | |
| 	miOverlayGeneration = serverGeneration;
 | |
|     }
 | |
| 
 | |
|     if(!AllocateWindowPrivate(pScreen, miOverlayWindowIndex,
 | |
| 				sizeof(miOverlayWindowRec)))
 | |
| 	return FALSE;
 | |
| 
 | |
|     if(!(pScreenPriv = xalloc(sizeof(miOverlayScreenRec))))
 | |
| 	return FALSE;
 | |
| 
 | |
|     pScreen->devPrivates[miOverlayScreenIndex].ptr = (pointer)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;
 | |
| #ifdef SHAPE
 | |
|     pScreen->SetShape = miOverlaySetShape;
 | |
| #endif
 | |
|     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;
 | |
| 
 | |
|    xfree(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)xcalloc(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) {
 | |
| 		REGION_NULL(pScreen, &(pTree->borderClip));
 | |
| 		REGION_NULL(pScreen, &(pTree->clipList));
 | |
| 		RebuildTree(pWin);
 | |
| 	    } else {
 | |
| 		BoxRec fullBox;
 | |
| 		fullBox.x1 = 0;
 | |
| 		fullBox.y1 = 0;
 | |
| 		fullBox.x2 = pScreen->width;
 | |
| 		fullBox.y2 = pScreen->height;
 | |
| 		REGION_INIT(pScreen, &(pTree->borderClip), &fullBox, 1);
 | |
| 		REGION_INIT(pScreen, &(pTree->clipList), &fullBox, 1);
 | |
| 	    }
 | |
| 	} else xfree(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;
 | |
| 
 | |
| 	REGION_UNINIT(pScreen, &(pTree->borderClip));
 | |
| 	REGION_UNINIT(pScreen, &(pTree->clipList));
 | |
| 	xfree(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(WindowTable[pWin->drawable.pScreen->myNum]->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
 | |
| ){
 | |
|     ScreenPtr pScreen = pWin->drawable.pScreen;
 | |
|     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 = REGION_EXTENTS(pScreen, &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 (REGION_BROKEN (pScreen, &pChild->winSize))
 | |
|                     SetWinSize (pChild);
 | |
|                 if (REGION_BROKEN (pScreen, &pChild->borderSize))
 | |
| 		    SetBorderSize (pChild);
 | |
| 
 | |
| 	    	if (markAll || 
 | |
| 		    RECT_IN_REGION(pScreen, &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 (REGION_BROKEN (pScreen, &tChild->pWin->winSize))
 | |
|                     SetWinSize (tChild->pWin);
 | |
|                 if (REGION_BROKEN (pScreen, &tChild->pWin->borderSize))
 | |
| 		    SetBorderSize (tChild->pWin);
 | |
| 
 | |
| 		if(RECT_IN_REGION(pScreen, &(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) {
 | |
| 	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 (RECT_IN_REGION( pScreen, universe, &borderSize)) {
 | |
| 	case rgnIN:
 | |
| 	    newVis = VisibilityUnobscured;
 | |
| 	    break;
 | |
| 	case rgnPART:
 | |
| 	    newVis = VisibilityPartiallyObscured;
 | |
| #ifdef SHAPE
 | |
| 	    {
 | |
| 		RegionPtr   pBounding;
 | |
| 
 | |
| 		if ((pBounding = wBoundingShape (pParent))) {
 | |
| 		    switch (miShapedWindowIn (pScreen, universe, pBounding,
 | |
| 					      &borderSize,
 | |
| 					      pParent->drawable.x,
 | |
|  					      pParent->drawable.y))
 | |
| 		    {
 | |
| 		    case rgnIN:
 | |
| 			newVis = VisibilityUnobscured;
 | |
| 			break;
 | |
| 		    case rgnOUT:
 | |
| 			newVis = VisibilityFullyObscured;
 | |
| 			break;
 | |
| 		    }
 | |
| 		}
 | |
| 	    }
 | |
| #endif
 | |
| 	    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) {
 | |
| 			REGION_TRANSLATE( pScreen, &tChild->borderClip, dx, dy);
 | |
| 			REGION_TRANSLATE( pScreen, &tChild->clipList, dx, dy);
 | |
| 		
 | |
| 			tChild->pWin->drawable.serialNumber = 
 | |
| 							 NEXT_SERIAL_NUMBER;
 | |
|                         if (pScreen->ClipNotify)
 | |
|                             (* pScreen->ClipNotify) (tChild->pWin, dx, dy);
 | |
| 		    }
 | |
| 		    if (tChild->valdata) {
 | |
| 			REGION_NULL(pScreen, &tChild->valdata->borderExposed);
 | |
| 			if (HasParentRelativeBorder(tChild->pWin)){
 | |
| 			    REGION_SUBTRACT(pScreen,
 | |
| 					 &tChild->valdata->borderExposed,
 | |
| 					 &tChild->borderClip,
 | |
| 					 &tChild->pWin->winSize);
 | |
| 			}
 | |
| 			REGION_NULL(pScreen, &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)  {
 | |
| 	    REGION_TRANSLATE( pScreen, &tParent->borderClip, dx, dy);
 | |
| 	    REGION_TRANSLATE( pScreen, &tParent->clipList, dx, dy);
 | |
|     	} 
 | |
| 	break;
 | |
|     case VTBroken:
 | |
| 	REGION_EMPTY (pScreen, &tParent->borderClip);
 | |
| 	REGION_EMPTY (pScreen, &tParent->clipList);
 | |
| 	break;
 | |
|     }
 | |
| 
 | |
|     borderVisible = tParent->valdata->borderVisible;
 | |
|     REGION_NULL(pScreen, &tParent->valdata->borderExposed);
 | |
|     REGION_NULL(pScreen, &tParent->valdata->exposed);
 | |
| 
 | |
|     if (HasBorder (pParent)) {
 | |
|     	if (borderVisible) {
 | |
| 	    REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
 | |
| 	    REGION_DESTROY( pScreen, borderVisible);
 | |
|     	} else
 | |
| 	    REGION_SUBTRACT( pScreen, exposed, universe, &tParent->borderClip);
 | |
| 
 | |
| 	if (HasParentRelativeBorder(pParent) && (dx || dy))
 | |
| 	    REGION_SUBTRACT( pScreen, &tParent->valdata->borderExposed,
 | |
| 				  universe, &pParent->winSize);
 | |
| 	else
 | |
| 	    REGION_SUBTRACT( pScreen, &tParent->valdata->borderExposed,
 | |
| 			       exposed, &pParent->winSize);
 | |
| 
 | |
|     	REGION_COPY( pScreen, &tParent->borderClip, universe);    
 | |
|     	REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
 | |
|     }
 | |
|     else
 | |
|     	REGION_COPY( pScreen, &tParent->borderClip, universe);
 | |
| 
 | |
|     if ((tChild = tParent->firstChild) && pParent->mapped) {
 | |
| 	REGION_NULL(pScreen, &childUniverse);
 | |
| 	REGION_NULL(pScreen, &childUnion);
 | |
| 
 | |
| 	for (; tChild; tChild = tChild->nextSib) {
 | |
| 	    if (tChild->pWin->viewable)
 | |
| 		REGION_APPEND( pScreen, &childUnion, &tChild->pWin->borderSize);
 | |
| 	}
 | |
| 
 | |
| 	REGION_VALIDATE( pScreen, &childUnion, &overlap);
 | |
| 
 | |
| 	for (tChild = tParent->firstChild;
 | |
| 	     tChild;
 | |
| 	     tChild = tChild->nextSib)
 | |
|  	{
 | |
| 	    if (tChild->pWin->viewable) {
 | |
| 		if (tChild->valdata) {
 | |
| 		    REGION_INTERSECT( pScreen, &childUniverse, universe,
 | |
| 					    &tChild->pWin->borderSize);
 | |
| 		    miOverlayComputeClips (tChild->pWin, &childUniverse, 
 | |
| 						kind, exposed);
 | |
| 		}
 | |
| 		if (overlap)
 | |
| 		    REGION_SUBTRACT( pScreen, universe, universe,
 | |
| 					  &tChild->pWin->borderSize);
 | |
| 	    }
 | |
| 	}
 | |
| 	if (!overlap)
 | |
| 	    REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
 | |
| 	REGION_UNINIT( pScreen, &childUnion);
 | |
| 	REGION_UNINIT( pScreen, &childUniverse);
 | |
|     } 
 | |
| 
 | |
|     if (oldVis == VisibilityFullyObscured ||
 | |
| 	oldVis == VisibilityNotViewable)
 | |
|     {
 | |
| 	REGION_COPY( pScreen, &tParent->valdata->exposed, universe);
 | |
|     }
 | |
|     else if (newVis != VisibilityFullyObscured &&
 | |
| 	     newVis != VisibilityNotViewable)
 | |
|     {
 | |
|     	REGION_SUBTRACT( pScreen, &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;
 | |
| 
 | |
|         REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
 | |
|         if (pChild->drawable.pScreen->ClipNotify)
 | |
|             (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
 | |
|         REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
 | |
| 	if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
 | |
| 	    if(pTree->valdata != (miOverlayValDataPtr)UnmapValData) {
 | |
| 		REGION_EMPTY(pChild->drawable.pScreen, &pTree->clipList);
 | |
| 		REGION_EMPTY(pChild->drawable.pScreen, &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;
 | |
| 
 | |
|     REGION_NULL(pScreen, &totalClip);
 | |
|     REGION_NULL(pScreen, &childClip);
 | |
|     REGION_NULL(pScreen, &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 (REGION_BROKEN (pScreen, &tParent->clipList) &&
 | |
|         !REGION_BROKEN (pScreen, &tParent->borderClip))
 | |
|     {
 | |
| 	kind = VTBroken;
 | |
| 	REGION_COPY (pScreen, &totalClip, &tParent->borderClip);
 | |
| 	REGION_INTERSECT (pScreen, &totalClip, &totalClip,
 | |
| 						 &tParent->pWin->winSize);
 | |
|         
 | |
|         for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
 | |
|             if (tWin->pWin->viewable)
 | |
|                 REGION_SUBTRACT (pScreen, &totalClip, &totalClip, 
 | |
| 					&tWin->pWin->borderSize);
 | |
|         }        
 | |
|         REGION_EMPTY (pScreen, &tParent->clipList);
 | |
|     } else {
 | |
| 	for(tWin = tChild; tWin; tWin = tWin->nextSib) {
 | |
| 	    if(tWin->valdata)
 | |
| 		REGION_APPEND(pScreen, &totalClip, &tWin->borderClip);
 | |
| 	}
 | |
| 	REGION_VALIDATE(pScreen, &totalClip, &overlap);
 | |
|     }
 | |
| 
 | |
|     if(kind != VTStack)
 | |
| 	REGION_UNION(pScreen, &totalClip, &totalClip, &tParent->clipList);
 | |
| 	
 | |
|     for(tWin = tChild; tWin; tWin = tWin->nextSib) {
 | |
| 	if(tWin->valdata) {
 | |
| 	    if(tWin->pWin->viewable) {
 | |
| 		REGION_INTERSECT(pScreen, &childClip, &totalClip,
 | |
| 					&tWin->pWin->borderSize);
 | |
| 		miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed);
 | |
| 		REGION_SUBTRACT(pScreen, &totalClip, &totalClip,
 | |
| 					&tWin->pWin->borderSize);
 | |
| 	    } else {  /* Means we are unmapping */
 | |
|                 REGION_EMPTY(pScreen, &tWin->clipList);
 | |
|                 REGION_EMPTY( pScreen, &tWin->borderClip);
 | |
| 		tWin->valdata = NULL;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     REGION_UNINIT(pScreen, &childClip);
 | |
| 
 | |
|     if(!((*pPriv->InOverlay)(newParent))) {
 | |
| 	REGION_NULL(pScreen, &tParent->valdata->exposed);
 | |
| 	REGION_NULL(pScreen, &tParent->valdata->borderExposed);
 | |
|     }
 | |
| 
 | |
|     switch (kind) {
 | |
|     case VTStack:
 | |
| 	break;
 | |
|     default:
 | |
|     	if(!((*pPriv->InOverlay)(newParent))) 
 | |
| 	    REGION_SUBTRACT(pScreen, &tParent->valdata->exposed, &totalClip, 
 | |
| 						&tParent->clipList);
 | |
| 	/* fall through */
 | |
|     case VTMap:
 | |
| 	REGION_COPY( pScreen, &tParent->clipList, &totalClip);
 | |
|     	if(!((*pPriv->InOverlay)(newParent))) 
 | |
| 	    newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 | |
| 	break;
 | |
|     }
 | |
| 
 | |
|     REGION_UNINIT( pScreen, &totalClip);
 | |
|     REGION_UNINIT( pScreen, &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 (REGION_NOTEMPTY(pScreen, &mival->borderExposed))
 | |
| 			(*pWin->drawable.pScreen->PaintWindowBorder)(
 | |
| 				pTree->pWin, &mival->borderExposed, PW_BORDER);
 | |
| 		    REGION_UNINIT(pScreen, &mival->borderExposed);
 | |
| 
 | |
| 		    (*WindowExposures)(pTree->pWin,&mival->exposed,NullRegion);
 | |
| 		    REGION_UNINIT(pScreen, &mival->exposed);
 | |
| 		}
 | |
| 		xfree(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))) {
 | |
| 		REGION_UNION(pScreen, &val->after.exposed, &val->after.exposed,
 | |
| 			&val->after.borderExposed);
 | |
| 
 | |
| 		if (REGION_NOTEMPTY(pScreen, &val->after.exposed)) {
 | |
| 		   (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))(
 | |
| 				pScreen, 
 | |
| 				REGION_NUM_RECTS(&val->after.exposed),
 | |
| 				REGION_RECTS(&val->after.exposed));
 | |
| 		}
 | |
| 	    } else {
 | |
| 		if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
 | |
| 		    (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
 | |
| 						    &val->after.borderExposed,
 | |
| 						    PW_BORDER);
 | |
| 		(*WindowExposures)(pChild, &val->after.exposed, NullRegion);
 | |
| 	    }
 | |
| 	    REGION_UNINIT(pScreen, &val->after.borderExposed);
 | |
| 	    REGION_UNINIT(pScreen, &val->after.exposed);
 | |
| 	    xfree(val);
 | |
| 	    pChild->valdata = (ValidatePtr)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;
 | |
| #ifdef DO_SAVE_UNDERS
 | |
|     Bool dosave = FALSE;
 | |
| #endif
 | |
| 
 | |
|     if (!(pParent = pWin->parent))
 | |
|        return ;
 | |
|     bw = wBorderWidth (pWin);
 | |
| 
 | |
|     oldpt.x = pWin->drawable.x;
 | |
|     oldpt.y = pWin->drawable.y;
 | |
|     if (WasViewable) {
 | |
| 	REGION_NULL(pScreen, &overReg);
 | |
| 	REGION_NULL(pScreen, &underReg);
 | |
| 	if(pTree) {
 | |
| 	    REGION_COPY(pScreen, &overReg, &pWin->borderClip);
 | |
| 	    REGION_COPY(pScreen, &underReg, &pTree->borderClip);
 | |
|         } else {
 | |
| 	    REGION_COPY(pScreen, &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);
 | |
| 
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (DO_SAVE_UNDERS(pWin))
 | |
| 	    dosave = (*pScreen->ChangeSaveUnder)(pWin, windowToValidate);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 
 | |
| 	(*pScreen->ValidateTree)(pWin->parent, NullWindow, kind);
 | |
| 	if(REGION_NOTEMPTY(pScreen, &underReg)) {
 | |
| 	    pPriv->copyUnderlay = TRUE;
 | |
| 	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &underReg);
 | |
| 	}
 | |
| 	REGION_UNINIT(pScreen, &underReg);
 | |
| 	if(REGION_NOTEMPTY(pScreen, &overReg)) {
 | |
| 	    pPriv->copyUnderlay = FALSE;
 | |
| 	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &overReg);
 | |
| 	}
 | |
| 	REGION_UNINIT(pScreen, &overReg);
 | |
| 	(*pScreen->HandleExposures)(pWin->parent);
 | |
| 
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (dosave)
 | |
| 	    (*pScreen->PostChangeSaveUnder)(pWin, windowToValidate);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 	if (pScreen->PostValidateTree)
 | |
| 	    (*pScreen->PostValidateTree)(pWin->parent, NullWindow, kind);
 | |
|     }
 | |
|     if (pWin->realized)
 | |
| 	WindowsRestructured ();
 | |
| }
 | |
| 
 | |
| #ifndef RECTLIMIT
 | |
| #define RECTLIMIT 25
 | |
| #endif
 | |
| 
 | |
| static void 
 | |
| miOverlayWindowExposures(
 | |
|     WindowPtr pWin,
 | |
|     register RegionPtr prgn,
 | |
|     RegionPtr other_exposed
 | |
| ){
 | |
|     RegionPtr   exposures = prgn;
 | |
|     ScreenPtr pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     if (pWin->backStorage && prgn)
 | |
| 	exposures = (*pScreen->RestoreAreas)(pWin, prgn);
 | |
|     if ((prgn && !REGION_NIL(prgn)) || 
 | |
| 	(exposures && !REGION_NIL(exposures)) || other_exposed)
 | |
|     {
 | |
| 	RegionRec   expRec;
 | |
| 	int	    clientInterested;
 | |
| 
 | |
| 	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) &
 | |
| 		 	    ExposureMask;
 | |
| 	if (other_exposed) {
 | |
| 	    if (exposures) {
 | |
| 		REGION_UNION(pScreen, other_exposed, exposures, other_exposed);
 | |
| 		if (exposures != prgn)
 | |
| 		    REGION_DESTROY(pScreen, exposures);
 | |
| 	    }
 | |
| 	    exposures = other_exposed;
 | |
| 	}
 | |
| 	if (clientInterested && exposures && 
 | |
| 	   (REGION_NUM_RECTS(exposures) > RECTLIMIT))
 | |
| 	{
 | |
|             miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
 | |
| 	    BoxRec box;
 | |
| 
 | |
| 	    box = *REGION_EXTENTS(pScreen, exposures);
 | |
| 	    if (exposures == prgn) {
 | |
| 		exposures = &expRec;
 | |
| 		REGION_INIT(pScreen, exposures, &box, 1);
 | |
| 		REGION_RESET(pScreen, prgn, &box);
 | |
| 	    } else {
 | |
| 		REGION_RESET(pScreen, exposures, &box);
 | |
| 		REGION_UNION(pScreen, 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);
 | |
| 		REGION_INTERSECT(pScreen, prgn, prgn, &pTree->clipList);
 | |
| 	    } else
 | |
| 		REGION_INTERSECT(pScreen, prgn, prgn, &pWin->clipList);
 | |
| 
 | |
| 	    /* need to clear out new areas of backing store, too */
 | |
| 	    if (pWin->backStorage)
 | |
| 		(void) (*pScreen->ClearBackingStore)(
 | |
| 					     pWin,
 | |
| 					     box.x1 - pWin->drawable.x,
 | |
| 					     box.y1 - pWin->drawable.y,
 | |
| 					     box.x2 - box.x1,
 | |
| 					     box.y2 - box.y1,
 | |
| 					     FALSE);
 | |
| 	}
 | |
| 	if (prgn && !REGION_NIL(prgn))
 | |
| 	    (*pScreen->PaintWindowBackground)(
 | |
| 			pWin, prgn, PW_BACKGROUND);
 | |
| 	if (clientInterested && exposures && !REGION_NIL(exposures))
 | |
| 	    miSendExposures(pWin, exposures,
 | |
| 			    pWin->drawable.x, pWin->drawable.y);
 | |
| 	if (exposures == &expRec) {
 | |
| 	    REGION_UNINIT(pScreen, exposures);
 | |
| 	} 
 | |
| 	else if (exposures && exposures != prgn && exposures != other_exposed)
 | |
| 	    REGION_DESTROY(pScreen, exposures);
 | |
| 	if (prgn)
 | |
| 	    REGION_EMPTY(pScreen, prgn);
 | |
|     }
 | |
|     else if (exposures && exposures != prgn)
 | |
| 	REGION_DESTROY(pScreen, exposures);
 | |
| }
 | |
| 
 | |
| 
 | |
| typedef struct {
 | |
|    RegionPtr over;
 | |
|    RegionPtr under;
 | |
| } miOverlayTwoRegions; 
 | |
| 
 | |
| static int
 | |
| miOverlayRecomputeExposures (
 | |
|     WindowPtr	pWin,
 | |
|     pointer	value 
 | |
| ){
 | |
|     register ScreenPtr pScreen;
 | |
|     miOverlayTwoRegions	*pValid = (miOverlayTwoRegions*)value;
 | |
|     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
 | |
| 
 | |
|     /* This prevents warning about pScreen not being used. */
 | |
|     pWin->drawable.pScreen = pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     if (pWin->valdata) {
 | |
| 	/*
 | |
| 	 * compute exposed regions of this window
 | |
| 	 */
 | |
| 	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
 | |
| 			&pWin->clipList, pValid->over);
 | |
| 	/*
 | |
| 	 * compute exposed regions of the border
 | |
| 	 */
 | |
| 	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
 | |
| 			     &pWin->borderClip, &pWin->winSize);
 | |
| 	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
 | |
| 			     &pWin->valdata->after.borderExposed, pValid->over);
 | |
|     } 
 | |
| 
 | |
|     if(pTree && pTree->valdata) {
 | |
| 	REGION_SUBTRACT(pScreen, &pTree->valdata->exposed,
 | |
| 			&pTree->clipList, pValid->under);
 | |
| 	REGION_SUBTRACT(pScreen, &pTree->valdata->borderExposed,
 | |
| 			     &pTree->borderClip, &pWin->winSize);
 | |
| 	REGION_SUBTRACT(pScreen, &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;
 | |
|     register WindowPtr pChild;
 | |
|     RegionPtr	gravitate[StaticGravity + 1];
 | |
|     RegionPtr	gravitate2[StaticGravity + 1];
 | |
|     register 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; 
 | |
|     RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
 | |
|     Bool	shrunk = FALSE; /* shrunk in an inner dimension */
 | |
|     Bool	moved = FALSE;	/* window position changed */
 | |
| #ifdef DO_SAVE_UNDERS
 | |
|     Bool	dosave = FALSE;
 | |
| #endif
 | |
|     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 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
 | |
| 	if(doUnderlay) {
 | |
| 	    oldRegion2 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    REGION_COPY(pScreen, 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] = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 		REGION_UNION(pScreen, gravitate[g],
 | |
| 				   gravitate[g], &pChild->borderClip);
 | |
| 		
 | |
| 		if(doUnderlay) {
 | |
| 		    if (!gravitate2[g])
 | |
| 			gravitate2[g] = REGION_CREATE(pScreen, NullBox, 0);
 | |
| 		
 | |
| 		    if((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
 | |
| 		        REGION_UNION(pScreen, 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 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
 | |
| 	    if(pTree) {
 | |
| 		oldWinClip2 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 		REGION_COPY(pScreen, 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 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    if(pTree)
 | |
| 		borderVisible2 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    /* for tiled borders, we punt and draw the whole thing */
 | |
| 	    if (pWin->borderIsPixel || !moved)
 | |
| 	    {
 | |
| 		if (shrunk || moved)
 | |
| 		    REGION_SUBTRACT(pScreen, borderVisible,
 | |
| 					  &pWin->borderClip,
 | |
| 					  &pWin->winSize);
 | |
| 		else
 | |
| 		    REGION_COPY(pScreen, borderVisible,
 | |
| 					    &pWin->borderClip);
 | |
| 		if(pTree) {
 | |
| 		    if (shrunk || moved)
 | |
| 			REGION_SUBTRACT(pScreen, borderVisible,
 | |
| 					  &pTree->borderClip,
 | |
| 					  &pWin->winSize);
 | |
| 		    else
 | |
| 			REGION_COPY(pScreen, 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 = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	if (pWin->backStorage)
 | |
| 	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
 | |
| 
 | |
| 	(*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL);
 | |
| 
 | |
| 	pWin->valdata->before.resized = TRUE;
 | |
| 	pWin->valdata->before.borderVisible = borderVisible;
 | |
| 	if(pTree)
 | |
| 	    pTree->valdata->borderVisible = borderVisible2;
 | |
| 
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (DO_SAVE_UNDERS(pWin))
 | |
| 	    dosave = (*pScreen->ChangeSaveUnder)(pWin, pFirstChange);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 
 | |
| 	(*pScreen->ValidateTree)(pWin->parent, pFirstChange, VTOther);
 | |
| 	/*
 | |
| 	 * the entire window is trashed unless bitGravity
 | |
| 	 * recovers portions of it
 | |
| 	 */
 | |
| 	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
 | |
| 	if(pTree)
 | |
| 	    REGION_COPY(pScreen, &pTree->valdata->exposed, &pTree->clipList);
 | |
|     }
 | |
| 
 | |
|     GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
 | |
| 
 | |
|     if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) {
 | |
| 	if (!WasViewable)
 | |
| 	    pRegion = &pWin->clipList; /* a convenient empty region */
 | |
| 	if (pWin->bitGravity == ForgetGravity)
 | |
| 	    bsExposed = (*pScreen->TranslateBackingStore)
 | |
| 				(pWin, 0, 0, NullRegion, oldx, oldy);
 | |
| 	else
 | |
| 	    bsExposed = (*pScreen->TranslateBackingStore)
 | |
| 			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
 | |
|     }
 | |
| 
 | |
|     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) {
 | |
| 		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
 | |
| 		    offx += dx;
 | |
| 		    offy += dy;
 | |
| 		}
 | |
| 		if(gravitate[g])
 | |
| 		    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
 | |
| 				 &pWin->winSize);
 | |
| 		if(gravitate2[g])
 | |
| 		    REGION_INTERSECT(pScreen, gravitate2[g], gravitate2[g],
 | |
| 				 &pWin->winSize);
 | |
| 	    }
 | |
| 	    /* get winSize back where it belongs */
 | |
| 	    if (offx || offy)
 | |
| 		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
 | |
| 	}
 | |
| 	/*
 | |
| 	 * add screen bits to the appropriate bucket
 | |
| 	 */
 | |
| 
 | |
| 	if (oldWinClip2)
 | |
| 	{
 | |
| 	    REGION_COPY(pScreen, pRegion, oldWinClip2);
 | |
| 	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
 | |
| 	    REGION_INTERSECT(pScreen, oldWinClip2, pRegion, &pTree->clipList);
 | |
| 
 | |
| 	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
 | |
| 		if (gravitate2[g])
 | |
| 		    REGION_SUBTRACT(pScreen, oldWinClip2, oldWinClip2,
 | |
| 					gravitate2[g]);
 | |
| 	    }
 | |
| 	    REGION_TRANSLATE(pScreen, oldWinClip2, oldx - nx, oldy - ny);
 | |
| 	    g = pWin->bitGravity;
 | |
| 	    if (!gravitate2[g])
 | |
| 		gravitate2[g] = oldWinClip2;
 | |
| 	    else {
 | |
| 		REGION_UNION(pScreen,gravitate2[g],gravitate2[g],oldWinClip2);
 | |
| 		REGION_DESTROY(pScreen, oldWinClip2);
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	if (oldWinClip)
 | |
| 	{
 | |
| 	    /*
 | |
| 	     * clip to new clipList
 | |
| 	     */
 | |
| 	    REGION_COPY(pScreen, pRegion, oldWinClip);
 | |
| 	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
 | |
| 	    REGION_INTERSECT(pScreen, 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])
 | |
| 		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
 | |
| 					gravitate[g]);
 | |
| 	    }
 | |
| 	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
 | |
| 	    g = pWin->bitGravity;
 | |
| 	    if (!gravitate[g])
 | |
| 		gravitate[g] = oldWinClip;
 | |
| 	    else {
 | |
| 		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
 | |
| 		REGION_DESTROY(pScreen, 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])
 | |
| 		REGION_INTERSECT(pScreen, gravitate[g], 
 | |
| 				 gravitate[g], oldRegion);
 | |
| 	    if(gravitate2[g])
 | |
| 		REGION_INTERSECT(pScreen, gravitate2[g], 
 | |
| 				 gravitate2[g], oldRegion2);
 | |
| 
 | |
| 	    /* clip to not overwrite already copied areas */
 | |
| 
 | |
| 	    if (destClip && gravitate[g]) {
 | |
| 		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
 | |
| 		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
 | |
| 		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
 | |
| 	    }
 | |
| 	    if (destClip2 && gravitate2[g]) {
 | |
| 		REGION_TRANSLATE(pScreen, destClip2, oldpt.x - x, oldpt.y - y);
 | |
| 		REGION_SUBTRACT(pScreen,gravitate2[g],gravitate2[g],destClip2);
 | |
| 		REGION_TRANSLATE(pScreen, destClip2, x - oldpt.x, y - oldpt.y);
 | |
| 	    }
 | |
| 
 | |
| 	    /* and move those bits */
 | |
| 
 | |
| 	    if (oldpt.x != x || oldpt.y != y) {
 | |
| 		if(gravitate2[g]) {
 | |
| 		    pPriv->copyUnderlay = TRUE;
 | |
| 		    (*pWin->drawable.pScreen->CopyWindow)(
 | |
| 						pWin, oldpt, gravitate2[g]);
 | |
| 		}
 | |
| 		if(gravitate[g]) {
 | |
| 		    pPriv->copyUnderlay = FALSE;
 | |
| 		    (*pWin->drawable.pScreen->CopyWindow)(
 | |
| 						pWin, oldpt, gravitate[g]);
 | |
| 		}
 | |
| 	    }
 | |
| 
 | |
| 	    /* remove any overwritten bits from the remaining useful bits */
 | |
| 
 | |
| 	    if(gravitate[g])
 | |
| 		REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
 | |
| 	    if(gravitate2[g])
 | |
| 		REGION_SUBTRACT(pScreen, 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])
 | |
| 		    REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
 | |
| 				&pWin->valdata->after.exposed, gravitate[g]);
 | |
| 		if(gravitate2[g] && pTree) 
 | |
| 		    REGION_SUBTRACT(pScreen, &pTree->valdata->exposed,
 | |
| 				&pTree->valdata->exposed, gravitate2[g]);
 | |
| 	    }
 | |
| 	    if(gravitate[g]) {
 | |
| 		if (!destClip)
 | |
| 		    destClip = gravitate[g];
 | |
| 		else {
 | |
| 		    REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
 | |
| 		    REGION_DESTROY(pScreen, gravitate[g]);
 | |
| 		}
 | |
| 	    }
 | |
| 	    if(gravitate2[g]) {
 | |
| 		if (!destClip2)
 | |
| 		    destClip2 = gravitate2[g];
 | |
| 		else {
 | |
| 		    REGION_UNION(pScreen, destClip2, destClip2, gravitate2[g]);
 | |
| 		    REGION_DESTROY(pScreen, gravitate2[g]);
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	REGION_DESTROY(pScreen, pRegion);
 | |
| 	REGION_DESTROY(pScreen, oldRegion);
 | |
| 	if(doUnderlay)
 | |
| 	    REGION_DESTROY(pScreen, oldRegion2);
 | |
| 	if (destClip)
 | |
| 	    REGION_DESTROY(pScreen, destClip);
 | |
| 	if (destClip2)
 | |
| 	    REGION_DESTROY(pScreen, destClip2);
 | |
| 	if (bsExposed) {
 | |
| 	    RegionPtr	valExposed = NullRegion;
 | |
| 
 | |
| 	    if (pWin->valdata)
 | |
| 		valExposed = &pWin->valdata->after.exposed;
 | |
| 	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
 | |
| 	    if (valExposed)
 | |
| 		REGION_EMPTY(pScreen, valExposed);
 | |
| 	    REGION_DESTROY(pScreen, bsExposed);
 | |
| 	}
 | |
| 	(*pScreen->HandleExposures)(pWin->parent);
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (dosave)
 | |
| 	    (*pScreen->PostChangeSaveUnder)(pWin, pFirstChange);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 	if (pScreen->PostValidateTree)
 | |
| 	    (*pScreen->PostValidateTree)(pWin->parent, pFirstChange, VTOther);
 | |
|     }
 | |
|     else if (bsExposed) {
 | |
| 	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
 | |
| 	REGION_DESTROY(pScreen, bsExposed);
 | |
|     }
 | |
|     if (pWin->realized)
 | |
| 	WindowsRestructured ();
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifdef SHAPE
 | |
| static void
 | |
| miOverlaySetShape(WindowPtr pWin)
 | |
| {
 | |
|     Bool	WasViewable = (Bool)(pWin->viewable);
 | |
|     ScreenPtr 	pScreen = pWin->drawable.pScreen;
 | |
|     RegionPtr	pOldClip = NULL, bsExposed;
 | |
| #ifdef DO_SAVE_UNDERS
 | |
|     Bool	dosave = FALSE;
 | |
| #endif
 | |
| 
 | |
|     if (WasViewable) {
 | |
| 	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
 | |
| 
 | |
| 	if (HasBorder (pWin)) {
 | |
| 	    RegionPtr borderVisible;
 | |
| 
 | |
| 	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    REGION_SUBTRACT(pScreen, 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 = REGION_CREATE(pScreen, NULL, 1);
 | |
| 		REGION_SUBTRACT(pScreen, borderVisible2,
 | |
| 				      &pTree->borderClip, &pWin->winSize);
 | |
| 		pTree->valdata->borderVisible = borderVisible2;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     SetWinSize (pWin);
 | |
|     SetBorderSize (pWin);
 | |
| 
 | |
|     ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
 | |
| 
 | |
|     if (WasViewable) {
 | |
| 	if (pWin->backStorage) {
 | |
| 	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
 | |
| 	}
 | |
| 
 | |
| 	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
 | |
| 
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (DO_SAVE_UNDERS(pWin))
 | |
| 	    dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 
 | |
| 	(*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
 | |
|     }
 | |
| 
 | |
|     if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) {
 | |
| 	if (!WasViewable)
 | |
| 	    pOldClip = &pWin->clipList; /* a convenient empty region */
 | |
| 	bsExposed = (*pScreen->TranslateBackingStore)
 | |
| 			     (pWin, 0, 0, pOldClip,
 | |
| 			      pWin->drawable.x, pWin->drawable.y);
 | |
| 	if (WasViewable)
 | |
| 	    REGION_DESTROY(pScreen, pOldClip);
 | |
| 	if (bsExposed)
 | |
| 	{
 | |
| 	    RegionPtr	valExposed = NullRegion;
 | |
|     
 | |
| 	    if (pWin->valdata)
 | |
| 		valExposed = &pWin->valdata->after.exposed;
 | |
| 	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
 | |
| 	    if (valExposed)
 | |
| 		REGION_EMPTY(pScreen, valExposed);
 | |
| 	    REGION_DESTROY(pScreen, bsExposed);
 | |
| 	}
 | |
|     }
 | |
|     if (WasViewable) {
 | |
| 	(*pScreen->HandleExposures)(pWin->parent);
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (dosave)
 | |
| 	    (*pScreen->PostChangeSaveUnder)(pWin, pWin);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 	if (pScreen->PostValidateTree)
 | |
| 	    (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
 | |
|     }
 | |
|     if (pWin->realized)
 | |
| 	WindowsRestructured ();
 | |
|     CheckCursorConfinement(pWin);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| 
 | |
| static void
 | |
| miOverlayChangeBorderWidth(
 | |
|     WindowPtr pWin,
 | |
|     unsigned int width
 | |
| ){
 | |
|     int oldwidth;
 | |
|     register ScreenPtr pScreen;
 | |
|     Bool WasViewable = (Bool)(pWin->viewable);
 | |
|     Bool HadBorder;
 | |
| #ifdef DO_SAVE_UNDERS
 | |
|     Bool	dosave = FALSE;
 | |
| #endif
 | |
| 
 | |
|     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 = REGION_CREATE(pScreen, NULL, 1);
 | |
| 		REGION_SUBTRACT(pScreen, borderVisible,
 | |
| 				      &pWin->borderClip, &pWin->winSize);
 | |
| 		pWin->valdata->before.borderVisible = borderVisible;
 | |
| 		if(IN_UNDERLAY(pWin)) {
 | |
| 		    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
 | |
| 		    RegionPtr borderVisible2;
 | |
| 
 | |
| 		    borderVisible2 = REGION_CREATE(pScreen, NULL, 1);
 | |
| 		    REGION_SUBTRACT(pScreen, borderVisible2,
 | |
| 				      &pTree->borderClip, &pWin->winSize);
 | |
| 		    pTree->valdata->borderVisible = borderVisible2;
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (DO_SAVE_UNDERS(pWin))
 | |
| 	    dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 	(*pScreen->ValidateTree)(pWin->parent, pWin, VTOther);
 | |
| 	(*pScreen->HandleExposures)(pWin->parent);
 | |
| 
 | |
| #ifdef DO_SAVE_UNDERS
 | |
| 	if (dosave)
 | |
| 	    (*pScreen->PostChangeSaveUnder)(pWin, pWin->nextSib);
 | |
| #endif /* DO_SAVE_UNDERS */
 | |
| 	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.  */
 | |
| 
 | |
| _X_EXPORT void
 | |
| miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
 | |
| {
 | |
|     WindowPtr pRoot = WindowTable[pScreen->myNum];
 | |
|     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;
 | |
| 
 | |
| 	REGION_RESET(pScreen, &pTree->borderClip, &box);
 | |
|     } else 
 | |
| 	REGION_EMPTY(pScreen, &pTree->borderClip);
 | |
| 
 | |
|     REGION_BREAK(pScreen, &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 = REGION_EXTENTS(pScreen, 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;
 | |
| 
 | |
|     REGION_INIT(pScreen, ®, &box, 1);
 | |
|     if (pWin->backStorage) {
 | |
|         pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
 | |
|                                                  generateExposures);
 | |
|     }
 | |
| 
 | |
|     REGION_INTERSECT(pScreen, ®, ®, clipList);
 | |
|     if (generateExposures)
 | |
|         (*pScreen->WindowExposures)(pWin, ®, pBSReg);
 | |
|     else if (pWin->backgroundState != None)
 | |
|         (*pScreen->PaintWindowBackground)(pWin, ®, PW_BACKGROUND);
 | |
|     REGION_UNINIT(pScreen, ®);
 | |
|     if (pBSReg)
 | |
|         REGION_DESTROY(pScreen, pBSReg);
 | |
| }
 | |
| 
 | |
| 
 | |
| /****************************************************************/
 | |
| 
 | |
| /* not used */
 | |
| _X_EXPORT 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;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void 
 | |
| miOverlaySetTransFunction (
 | |
|    ScreenPtr pScreen, 
 | |
|    miOverlayTransFunc transFunc
 | |
| ){
 | |
|     MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
 | |
| }
 | |
| 
 | |
| _X_EXPORT Bool 
 | |
| miOverlayCopyUnderlay(ScreenPtr pScreen)
 | |
| {
 | |
|     return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
 | |
| {
 | |
|     ScreenPtr       pScreen = pGC->pScreen;
 | |
|     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
 | |
|     RegionPtr       pregWin;
 | |
|     Bool            freeTmpClip, freeCompClip;
 | |
| 
 | |
|     if(!pTree) {
 | |
| 	miComputeCompositeClip(pGC, &pWin->drawable);
 | |
| 	return;
 | |
|     }
 | |
| 
 | |
|     if (pGC->subWindowMode == IncludeInferiors) {
 | |
| 	pregWin = REGION_CREATE(pScreen, NullBox, 1);
 | |
| 	freeTmpClip = TRUE;
 | |
| 	if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
 | |
| 		!HasSaverWindow (pScreen->myNum))
 | |
| 	{
 | |
|             REGION_INTERSECT(pScreen,pregWin,&pTree->borderClip,&pWin->winSize);
 | |
| 	}
 | |
|     } else {
 | |
| 	pregWin = &pTree->clipList;
 | |
| 	freeTmpClip = FALSE;
 | |
|     }
 | |
|     freeCompClip = pGC->freeCompClip;
 | |
|     if (pGC->clientClipType == CT_NONE) {
 | |
| 	if (freeCompClip) 
 | |
| 	    REGION_DESTROY(pScreen, pGC->pCompositeClip);
 | |
| 	pGC->pCompositeClip = pregWin;
 | |
| 	pGC->freeCompClip = freeTmpClip;
 | |
|     } else {
 | |
| 	REGION_TRANSLATE(pScreen, pGC->clientClip,
 | |
| 				pWin->drawable.x + pGC->clipOrg.x,
 | |
| 				pWin->drawable.y + pGC->clipOrg.y);
 | |
| 
 | |
| 	if (freeCompClip) {
 | |
| 	    REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
 | |
| 					    pregWin, pGC->clientClip);
 | |
| 	    if (freeTmpClip)
 | |
| 		REGION_DESTROY(pScreen, pregWin);
 | |
| 	} else if (freeTmpClip) {
 | |
| 	    REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
 | |
| 	    pGC->pCompositeClip = pregWin;
 | |
| 	} else {
 | |
| 	    pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
 | |
| 	    REGION_INTERSECT(pScreen, pGC->pCompositeClip,
 | |
| 				       pregWin, pGC->clientClip);
 | |
| 	}
 | |
| 	pGC->freeCompClip = TRUE;
 | |
| 	REGION_TRANSLATE(pScreen, pGC->clientClip,
 | |
| 				-(pWin->drawable.x + pGC->clipOrg.x),
 | |
| 				-(pWin->drawable.y + pGC->clipOrg.y));
 | |
|     }
 | |
| }
 | |
| 
 | |
| _X_EXPORT Bool
 | |
| miOverlayCollectUnderlayRegions(
 | |
|     WindowPtr pWin,
 | |
|     RegionPtr *region
 | |
| ){
 | |
|     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
 | |
| 
 | |
|     if(pTree) {
 | |
| 	*region = &pTree->borderClip;
 | |
| 	return FALSE;
 | |
|     }
 | |
| 
 | |
|     *region = REGION_CREATE(pWin->drawable.pScreen, 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))) {
 | |
| 	    REGION_APPEND(pScreen, 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;
 | |
| 	REGION_VALIDATE(pScreen, 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;
 | |
| }
 |