/* * RootlessMarkOverlappedWindows * MarkOverlappedWindows is modified to ignore overlapping * top-level windows. */ static Bool RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) { RegionRec saveRoot; Bool result; ScreenPtr pScreen = pWin->drawable.pScreen; SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); HUGE_ROOT(pWin); if (IsRoot(pWin)) { // root - mark nothing RL_DEBUG_MSG("is root not marking "); result = FALSE; } else if (! IsTopLevel(pWin)) { // not top-level window - mark normally result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); } else { //top-level window - mark children ONLY - NO overlaps with sibs (?) // This code copied from miMarkOverlappedWindows() register WindowPtr pChild; Bool anyMarked = FALSE; MarkWindowProcPtr MarkWindow = pScreen->MarkWindow; RL_DEBUG_MSG("is top level! "); /* single layered systems are easy */ if (ppLayerWin) *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight * overkill if there are mapped windows that outside pWin's border, * but it's better than wasting time on RectIn checks. */ pChild = pWin; while (1) { if (pChild->viewable) { if (RegionBroken(&pChild->winSize)) SetWinSize (pChild); if (RegionBroken(&pChild->borderSize)) SetBorderSize (pChild); (* MarkWindow)(pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } anyMarked = TRUE; pFirst = pFirst->nextSib; } if (anyMarked) (* MarkWindow)(pWin->parent); result = anyMarked; } NORMAL_ROOT(pWin); SCREEN_WRAP(pScreen, MarkOverlappedWindows); RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n"); return result; }
Bool miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) { BoxPtr box; WindowPtr pChild, pLast; Bool anyMarked = FALSE; MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; /* single layered systems are easy */ if (ppLayerWin) *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight * overkill if there are mapped windows that outside pWin's border, * but it's better than wasting time on RectIn checks. */ pChild = pWin; while (1) { if (pChild->viewable) { if (RegionBroken(&pChild->winSize)) SetWinSize(pChild); if (RegionBroken(&pChild->borderSize)) SetBorderSize(pChild); (*MarkWindow) (pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } anyMarked = TRUE; pFirst = pFirst->nextSib; } if ((pChild = pFirst)) { box = RegionExtents(&pWin->borderSize); pLast = pChild->parent->lastChild; while (1) { if (pChild->viewable) { if (RegionBroken(&pChild->winSize)) SetWinSize(pChild); if (RegionBroken(&pChild->borderSize)) SetBorderSize(pChild); if (RegionContainsRect(&pChild->borderSize, box)) { (*MarkWindow) (pChild); anyMarked = TRUE; if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } } while (!pChild->nextSib && (pChild != pLast)) pChild = pChild->parent; if (pChild == pLast) break; pChild = pChild->nextSib; } } if (anyMarked) (*MarkWindow) (pWin->parent); return anyMarked; }
/*ARGSUSED*/ int miValidateTree ( WindowPtr pParent, /* Parent to validate */ WindowPtr pChild, /* First child of pParent that was * affected */ VTKind kind /* What kind of configuration caused call */ ) { RegionRec totalClip; /* Total clipping region available to * the marked children. pParent's clipList * merged with the borderClips of all * the marked children. */ RegionRec childClip; /* The new borderClip for the current * child */ RegionRec childUnion; /* the space covered by borderSize for * all marked children */ RegionRec exposed; /* For intermediate calculations */ ScreenPtr pScreen; WindowPtr pWin; Bool overlap; int viewvals; Bool forward; pScreen = pParent->drawable.pScreen; if (pChild == NullWindow) pChild = pParent->firstChild; RegionNull(&childClip); RegionNull(&exposed); /* * compute the area of the parent window occupied * by the marked children + the parent itself. This * is the area which can be divied up among the marked * children in their new configuration. */ RegionNull(&totalClip); viewvals = 0; if (RegionBroken(&pParent->clipList) && !RegionBroken(&pParent->borderClip)) { kind = VTBroken; /* * When rebuilding clip lists after out of memory, * assume everything is busted. */ forward = TRUE; RegionCopy(&totalClip, &pParent->borderClip); RegionIntersect(&totalClip, &totalClip, &pParent->winSize); for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) { if (pWin->viewable && !TreatAsTransparent (pWin)) RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); } for (pWin = pChild; pWin; pWin = pWin->nextSib) if (pWin->valdata && pWin->viewable) viewvals++; RegionEmpty(&pParent->clipList); } else { if ((pChild->drawable.y < pParent->lastChild->drawable.y) || ((pChild->drawable.y == pParent->lastChild->drawable.y) && (pChild->drawable.x < pParent->lastChild->drawable.x))) { forward = TRUE; for (pWin = pChild; pWin; pWin = pWin->nextSib) { if (pWin->valdata) { RegionPtr pBorderClip = &pWin->borderClip; #ifdef COMPOSITE if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) pBorderClip = (*miGetRedirectBorderClipProc)(pWin); #endif RegionAppend(&totalClip, pBorderClip ); if (pWin->viewable) viewvals++; } } } else { forward = FALSE; pWin = pParent->lastChild; while (1) { if (pWin->valdata) { RegionPtr pBorderClip = &pWin->borderClip; #ifdef COMPOSITE if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) pBorderClip = (*miGetRedirectBorderClipProc)(pWin); #endif RegionAppend(&totalClip, pBorderClip ); if (pWin->viewable) viewvals++; } if (pWin == pChild) break; pWin = pWin->prevSib; } } RegionValidate(&totalClip, &overlap); } /* * Now go through the children of the root and figure their new * borderClips from the totalClip, passing that off to miComputeClips * to handle recursively. Once that's done, we remove the child * from the totalClip to clip any siblings below it. */ overlap = TRUE; if (kind != VTStack) { RegionUnion(&totalClip, &totalClip, &pParent->clipList); if (viewvals > 1) { /* * precompute childUnion to discover whether any of them * overlap. This seems redundant, but performance studies * have demonstrated that the cost of this loop is * lower than the cost of multiple Subtracts in the * loop below. */ RegionNull(&childUnion); if (forward) { for (pWin = pChild; pWin; pWin = pWin->nextSib) if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) RegionAppend(&childUnion, &pWin->borderSize); } else { pWin = pParent->lastChild; while (1) { if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) RegionAppend(&childUnion, &pWin->borderSize); if (pWin == pChild) break; pWin = pWin->prevSib; } } RegionValidate(&childUnion, &overlap); if (overlap) RegionUninit(&childUnion); } } for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) { if (pWin->viewable) { if (pWin->valdata) { RegionIntersect(&childClip, &totalClip, &pWin->borderSize); miComputeClips (pWin, pScreen, &childClip, kind, &exposed); if (overlap && !TreatAsTransparent (pWin)) { RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); } } else if (pWin->visibility == VisibilityNotViewable) { miTreeObscured(pWin); } } else { if (pWin->valdata) { RegionEmpty(&pWin->clipList); if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pWin, 0, 0); RegionEmpty(&pWin->borderClip); pWin->valdata = NULL; } } } RegionUninit(&childClip); if (!overlap) { RegionSubtract(&totalClip, &totalClip, &childUnion); RegionUninit(&childUnion); } RegionNull(&pParent->valdata->after.exposed); RegionNull(&pParent->valdata->after.borderExposed); /* * each case below is responsible for updating the * clipList and serial number for the parent window */ switch (kind) { case VTStack: break; default: /* * totalClip contains the new clipList for the parent. Figure out * exposures and obscures as per miComputeClips and reset the parent's * clipList. */ RegionSubtract(&pParent->valdata->after.exposed, &totalClip, &pParent->clipList); /* fall through */ case VTMap: RegionCopy(&pParent->clipList, &totalClip); pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; break; } RegionUninit(&totalClip); RegionUninit(&exposed); if (pScreen->ClipNotify) (*pScreen->ClipNotify) (pParent, 0, 0); return 1; }
// fixme this is ugly // Xprint/ValTree.c doesn't work, but maybe that method can? int RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */ WindowPtr pChild, /* First child of pRoot that was * affected */ VTKind kind /* What kind of configuration caused call */) { RegionRec childClip; /* The new borderClip for the current * child */ RegionRec exposed; /* For intermediate calculations */ register ScreenPtr pScreen; register WindowPtr pWin; pScreen = pRoot->drawable.pScreen; if (pChild == NullWindow) pChild = pRoot->firstChild; RegionNull(&childClip); RegionNull(&exposed); if (RegionBroken(&pRoot->clipList) && !RegionBroken(&pRoot->borderClip)) { // fixme this might not work, but hopefully doesn't happen anyway. kind = VTBroken; RegionEmpty(&pRoot->clipList); ErrorF("ValidateTree: BUSTED!\n"); } /* * Recursively compute the clips for all children of the root. * They don't clip against each other or the root itself, so * childClip is always reset to that child's size. */ for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) { if (pWin->viewable) { if (pWin->valdata) { RegionCopy(&childClip, &pWin->borderSize); RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed); } else if (pWin->visibility == VisibilityNotViewable) { RootlessTreeObscured(pWin); } } else { if (pWin->valdata) { RegionEmpty(&pWin->clipList); if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pWin, 0, 0); RegionEmpty(&pWin->borderClip); pWin->valdata = NULL; } } } RegionUninit(&childClip); /* The root is never clipped by its children, so nothing on the root is ever exposed by moving or mapping its children. */ RegionNull(&pRoot->valdata->after.exposed); RegionNull(&pRoot->valdata->after.borderExposed); return 1; }