1706f2543Smrg/* 2706f2543Smrg * Calculate window clip lists for rootless mode 3706f2543Smrg * 4706f2543Smrg * This file is very closely based on mivaltree.c. 5706f2543Smrg */ 6706f2543Smrg 7706f2543Smrg/* 8706f2543Smrg * mivaltree.c -- 9706f2543Smrg * Functions for recalculating window clip lists. Main function 10706f2543Smrg * is miValidateTree. 11706f2543Smrg * 12706f2543Smrg 13706f2543SmrgCopyright 1987, 1988, 1989, 1998 The Open Group 14706f2543Smrg 15706f2543SmrgAll Rights Reserved. 16706f2543Smrg 17706f2543SmrgThe above copyright notice and this permission notice shall be included in 18706f2543Smrgall copies or substantial portions of the Software. 19706f2543Smrg 20706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 24706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 25706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26706f2543Smrg 27706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 28706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 29706f2543Smrgin this Software without prior written authorization from The Open Group. 30706f2543Smrg 31706f2543Smrg * 32706f2543Smrg * Copyright 1987, 1988, 1989 by 33706f2543Smrg * Digital Equipment Corporation, Maynard, Massachusetts, 34706f2543Smrg * 35706f2543Smrg * All Rights Reserved 36706f2543Smrg * 37706f2543Smrg * Permission to use, copy, modify, and distribute this software and its 38706f2543Smrg * documentation for any purpose and without fee is hereby granted, 39706f2543Smrg * provided that the above copyright notice appear in all copies and that 40706f2543Smrg * both that copyright notice and this permission notice appear in 41706f2543Smrg * supporting documentation, and that the name of Digital not be 42706f2543Smrg * used in advertising or publicity pertaining to distribution of the 43706f2543Smrg * software without specific, written prior permission. 44706f2543Smrg * 45706f2543Smrg * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 46706f2543Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 47706f2543Smrg * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 48706f2543Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 49706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 50706f2543Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 51706f2543Smrg * SOFTWARE. 52706f2543Smrg * 53706f2543Smrg ******************************************************************/ 54706f2543Smrg 55706f2543Smrg/* The panoramix components contained the following notice */ 56706f2543Smrg/***************************************************************** 57706f2543Smrg 58706f2543SmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 59706f2543Smrg 60706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 61706f2543Smrgof this software and associated documentation files (the "Software"), to deal 62706f2543Smrgin the Software without restriction, including without limitation the rights 63706f2543Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 64706f2543Smrgcopies of the Software. 65706f2543Smrg 66706f2543SmrgThe above copyright notice and this permission notice shall be included in 67706f2543Smrgall copies or substantial portions of the Software. 68706f2543Smrg 69706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 70706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 71706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 72706f2543SmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 73706f2543SmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 74706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 75706f2543SmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 76706f2543Smrg 77706f2543SmrgExcept as contained in this notice, the name of Digital Equipment Corporation 78706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use or other 79706f2543Smrgdealings in this Software without prior written authorization from Digital 80706f2543SmrgEquipment Corporation. 81706f2543Smrg 82706f2543Smrg******************************************************************/ 83706f2543Smrg /* 84706f2543Smrg * Aug '86: Susan Angebranndt -- original code 85706f2543Smrg * July '87: Adam de Boor -- substantially modified and commented 86706f2543Smrg * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible. 87706f2543Smrg * In particular, much improved code for window mapping and 88706f2543Smrg * circulating. 89706f2543Smrg * Bob Scheifler -- avoid miComputeClips for unmapped windows, 90706f2543Smrg * valdata changes 91706f2543Smrg */ 92706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 93706f2543Smrg#include <dix-config.h> 94706f2543Smrg#endif 95706f2543Smrg 96706f2543Smrg#include <stddef.h> /* For NULL */ 97706f2543Smrg#include <X11/X.h> 98706f2543Smrg#include "scrnintstr.h" 99706f2543Smrg#include "validate.h" 100706f2543Smrg#include "windowstr.h" 101706f2543Smrg#include "mi.h" 102706f2543Smrg#include "regionstr.h" 103706f2543Smrg#include "mivalidate.h" 104706f2543Smrg 105706f2543Smrg#include "globals.h" 106706f2543Smrg 107706f2543Smrgint RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind); 108706f2543Smrg 109706f2543Smrg/* 110706f2543Smrg * Compute the visibility of a shaped window 111706f2543Smrg */ 112706f2543Smrgstatic int 113706f2543SmrgRootlessShapedWindowIn (RegionPtr universe, 114706f2543Smrg RegionPtr bounding, BoxPtr rect, int x, int y) 115706f2543Smrg{ 116706f2543Smrg BoxRec box; 117706f2543Smrg register BoxPtr boundBox; 118706f2543Smrg int nbox; 119706f2543Smrg Bool someIn, someOut; 120706f2543Smrg register int t, x1, y1, x2, y2; 121706f2543Smrg 122706f2543Smrg nbox = RegionNumRects (bounding); 123706f2543Smrg boundBox = RegionRects (bounding); 124706f2543Smrg someIn = someOut = FALSE; 125706f2543Smrg x1 = rect->x1; 126706f2543Smrg y1 = rect->y1; 127706f2543Smrg x2 = rect->x2; 128706f2543Smrg y2 = rect->y2; 129706f2543Smrg while (nbox--) 130706f2543Smrg { 131706f2543Smrg if ((t = boundBox->x1 + x) < x1) 132706f2543Smrg t = x1; 133706f2543Smrg box.x1 = t; 134706f2543Smrg if ((t = boundBox->y1 + y) < y1) 135706f2543Smrg t = y1; 136706f2543Smrg box.y1 = t; 137706f2543Smrg if ((t = boundBox->x2 + x) > x2) 138706f2543Smrg t = x2; 139706f2543Smrg box.x2 = t; 140706f2543Smrg if ((t = boundBox->y2 + y) > y2) 141706f2543Smrg t = y2; 142706f2543Smrg box.y2 = t; 143706f2543Smrg if (box.x1 > box.x2) 144706f2543Smrg box.x2 = box.x1; 145706f2543Smrg if (box.y1 > box.y2) 146706f2543Smrg box.y2 = box.y1; 147706f2543Smrg switch (RegionContainsRect(universe, &box)) 148706f2543Smrg { 149706f2543Smrg case rgnIN: 150706f2543Smrg if (someOut) 151706f2543Smrg return rgnPART; 152706f2543Smrg someIn = TRUE; 153706f2543Smrg break; 154706f2543Smrg case rgnOUT: 155706f2543Smrg if (someIn) 156706f2543Smrg return rgnPART; 157706f2543Smrg someOut = TRUE; 158706f2543Smrg break; 159706f2543Smrg default: 160706f2543Smrg return rgnPART; 161706f2543Smrg } 162706f2543Smrg boundBox++; 163706f2543Smrg } 164706f2543Smrg if (someIn) 165706f2543Smrg return rgnIN; 166706f2543Smrg return rgnOUT; 167706f2543Smrg} 168706f2543Smrg 169706f2543Smrg#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ 170706f2543Smrg HasBorder(w) && \ 171706f2543Smrg (w)->backgroundState == ParentRelative) 172706f2543Smrg 173706f2543Smrg 174706f2543Smrg/* 175706f2543Smrg *----------------------------------------------------------------------- 176706f2543Smrg * RootlessComputeClips -- 177706f2543Smrg * Recompute the clipList, borderClip, exposed and borderExposed 178706f2543Smrg * regions for pParent and its children. Only viewable windows are 179706f2543Smrg * taken into account. 180706f2543Smrg * 181706f2543Smrg * Results: 182706f2543Smrg * None. 183706f2543Smrg * 184706f2543Smrg * Side Effects: 185706f2543Smrg * clipList, borderClip, exposed and borderExposed are altered. 186706f2543Smrg * A VisibilityNotify event may be generated on the parent window. 187706f2543Smrg * 188706f2543Smrg *----------------------------------------------------------------------- 189706f2543Smrg */ 190706f2543Smrgstatic void 191706f2543SmrgRootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, 192706f2543Smrg RegionPtr universe, VTKind kind, RegionPtr exposed) 193706f2543Smrg{ 194706f2543Smrg int dx, 195706f2543Smrg dy; 196706f2543Smrg RegionRec childUniverse; 197706f2543Smrg register WindowPtr pChild; 198706f2543Smrg int oldVis, newVis; 199706f2543Smrg BoxRec borderSize; 200706f2543Smrg RegionRec childUnion; 201706f2543Smrg Bool overlap; 202706f2543Smrg RegionPtr borderVisible; 203706f2543Smrg Bool resized; 204706f2543Smrg /* 205706f2543Smrg * Figure out the new visibility of this window. 206706f2543Smrg * The extent of the universe should be the same as the extent of 207706f2543Smrg * the borderSize region. If the window is unobscured, this rectangle 208706f2543Smrg * will be completely inside the universe (the universe will cover it 209706f2543Smrg * completely). If the window is completely obscured, none of the 210706f2543Smrg * universe will cover the rectangle. 211706f2543Smrg */ 212706f2543Smrg borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); 213706f2543Smrg borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); 214706f2543Smrg dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); 215706f2543Smrg if (dx > 32767) 216706f2543Smrg dx = 32767; 217706f2543Smrg borderSize.x2 = dx; 218706f2543Smrg dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); 219706f2543Smrg if (dy > 32767) 220706f2543Smrg dy = 32767; 221706f2543Smrg borderSize.y2 = dy; 222706f2543Smrg 223706f2543Smrg oldVis = pParent->visibility; 224706f2543Smrg switch (RegionContainsRect(universe, &borderSize)) 225706f2543Smrg { 226706f2543Smrg case rgnIN: 227706f2543Smrg newVis = VisibilityUnobscured; 228706f2543Smrg break; 229706f2543Smrg case rgnPART: 230706f2543Smrg newVis = VisibilityPartiallyObscured; 231706f2543Smrg { 232706f2543Smrg RegionPtr pBounding; 233706f2543Smrg 234706f2543Smrg if ((pBounding = wBoundingShape (pParent))) 235706f2543Smrg { 236706f2543Smrg switch (RootlessShapedWindowIn (universe, 237706f2543Smrg pBounding, &borderSize, 238706f2543Smrg pParent->drawable.x, 239706f2543Smrg pParent->drawable.y)) 240706f2543Smrg { 241706f2543Smrg case rgnIN: 242706f2543Smrg newVis = VisibilityUnobscured; 243706f2543Smrg break; 244706f2543Smrg case rgnOUT: 245706f2543Smrg newVis = VisibilityFullyObscured; 246706f2543Smrg break; 247706f2543Smrg } 248706f2543Smrg } 249706f2543Smrg } 250706f2543Smrg break; 251706f2543Smrg default: 252706f2543Smrg newVis = VisibilityFullyObscured; 253706f2543Smrg break; 254706f2543Smrg } 255706f2543Smrg 256706f2543Smrg pParent->visibility = newVis; 257706f2543Smrg if (oldVis != newVis && 258706f2543Smrg ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) 259706f2543Smrg SendVisibilityNotify(pParent); 260706f2543Smrg 261706f2543Smrg dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; 262706f2543Smrg dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; 263706f2543Smrg 264706f2543Smrg /* 265706f2543Smrg * avoid computations when dealing with simple operations 266706f2543Smrg */ 267706f2543Smrg 268706f2543Smrg switch (kind) { 269706f2543Smrg case VTMap: 270706f2543Smrg case VTStack: 271706f2543Smrg case VTUnmap: 272706f2543Smrg break; 273706f2543Smrg case VTMove: 274706f2543Smrg if ((oldVis == newVis) && 275706f2543Smrg ((oldVis == VisibilityFullyObscured) || 276706f2543Smrg (oldVis == VisibilityUnobscured))) 277706f2543Smrg { 278706f2543Smrg pChild = pParent; 279706f2543Smrg while (1) 280706f2543Smrg { 281706f2543Smrg if (pChild->viewable) 282706f2543Smrg { 283706f2543Smrg if (pChild->visibility != VisibilityFullyObscured) 284706f2543Smrg { 285706f2543Smrg RegionTranslate(&pChild->borderClip, 286706f2543Smrg dx, dy); 287706f2543Smrg RegionTranslate(&pChild->clipList, 288706f2543Smrg dx, dy); 289706f2543Smrg pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; 290706f2543Smrg if (pScreen->ClipNotify) 291706f2543Smrg (* pScreen->ClipNotify) (pChild, dx, dy); 292706f2543Smrg 293706f2543Smrg } 294706f2543Smrg if (pChild->valdata) 295706f2543Smrg { 296706f2543Smrg RegionNull(&pChild->valdata->after.borderExposed); 297706f2543Smrg if (HasParentRelativeBorder(pChild)) 298706f2543Smrg { 299706f2543Smrg RegionSubtract(&pChild->valdata->after.borderExposed, 300706f2543Smrg &pChild->borderClip, 301706f2543Smrg &pChild->winSize); 302706f2543Smrg } 303706f2543Smrg RegionNull(&pChild->valdata->after.exposed); 304706f2543Smrg } 305706f2543Smrg if (pChild->firstChild) 306706f2543Smrg { 307706f2543Smrg pChild = pChild->firstChild; 308706f2543Smrg continue; 309706f2543Smrg } 310706f2543Smrg } 311706f2543Smrg while (!pChild->nextSib && (pChild != pParent)) 312706f2543Smrg pChild = pChild->parent; 313706f2543Smrg if (pChild == pParent) 314706f2543Smrg break; 315706f2543Smrg pChild = pChild->nextSib; 316706f2543Smrg } 317706f2543Smrg return; 318706f2543Smrg } 319706f2543Smrg /* fall through */ 320706f2543Smrg default: 321706f2543Smrg /* 322706f2543Smrg * To calculate exposures correctly, we have to translate the old 323706f2543Smrg * borderClip and clipList regions to the window's new location so there 324706f2543Smrg * is a correspondence between pieces of the new and old clipping regions. 325706f2543Smrg */ 326706f2543Smrg if (dx || dy) 327706f2543Smrg { 328706f2543Smrg /* 329706f2543Smrg * We translate the old clipList because that will be exposed or copied 330706f2543Smrg * if gravity is right. 331706f2543Smrg */ 332706f2543Smrg RegionTranslate(&pParent->borderClip, dx, dy); 333706f2543Smrg RegionTranslate(&pParent->clipList, dx, dy); 334706f2543Smrg } 335706f2543Smrg break; 336706f2543Smrg case VTBroken: 337706f2543Smrg RegionEmpty(&pParent->borderClip); 338706f2543Smrg RegionEmpty(&pParent->clipList); 339706f2543Smrg break; 340706f2543Smrg } 341706f2543Smrg 342706f2543Smrg borderVisible = pParent->valdata->before.borderVisible; 343706f2543Smrg resized = pParent->valdata->before.resized; 344706f2543Smrg RegionNull(&pParent->valdata->after.borderExposed); 345706f2543Smrg RegionNull(&pParent->valdata->after.exposed); 346706f2543Smrg 347706f2543Smrg /* 348706f2543Smrg * Since the borderClip must not be clipped by the children, we do 349706f2543Smrg * the border exposure first... 350706f2543Smrg * 351706f2543Smrg * 'universe' is the window's borderClip. To figure the exposures, remove 352706f2543Smrg * the area that used to be exposed from the new. 353706f2543Smrg * This leaves a region of pieces that weren't exposed before. 354706f2543Smrg */ 355706f2543Smrg 356706f2543Smrg if (HasBorder (pParent)) 357706f2543Smrg { 358706f2543Smrg if (borderVisible) 359706f2543Smrg { 360706f2543Smrg /* 361706f2543Smrg * when the border changes shape, the old visible portions 362706f2543Smrg * of the border will be saved by DIX in borderVisible -- 363706f2543Smrg * use that region and destroy it 364706f2543Smrg */ 365706f2543Smrg RegionSubtract(exposed, universe, borderVisible); 366706f2543Smrg RegionDestroy(borderVisible); 367706f2543Smrg } 368706f2543Smrg else 369706f2543Smrg { 370706f2543Smrg RegionSubtract(exposed, universe, &pParent->borderClip); 371706f2543Smrg } 372706f2543Smrg if (HasParentRelativeBorder(pParent) && (dx || dy)) { 373706f2543Smrg RegionSubtract(&pParent->valdata->after.borderExposed, 374706f2543Smrg universe, 375706f2543Smrg &pParent->winSize); 376706f2543Smrg } else { 377706f2543Smrg RegionSubtract(&pParent->valdata->after.borderExposed, 378706f2543Smrg exposed, &pParent->winSize); 379706f2543Smrg } 380706f2543Smrg 381706f2543Smrg RegionCopy(&pParent->borderClip, universe); 382706f2543Smrg 383706f2543Smrg /* 384706f2543Smrg * To get the right clipList for the parent, and to make doubly sure 385706f2543Smrg * that no child overlaps the parent's border, we remove the parent's 386706f2543Smrg * border from the universe before proceeding. 387706f2543Smrg */ 388706f2543Smrg 389706f2543Smrg RegionIntersect(universe, universe, &pParent->winSize); 390706f2543Smrg } 391706f2543Smrg else 392706f2543Smrg RegionCopy(&pParent->borderClip, universe); 393706f2543Smrg 394706f2543Smrg if ((pChild = pParent->firstChild) && pParent->mapped) 395706f2543Smrg { 396706f2543Smrg RegionNull(&childUniverse); 397706f2543Smrg RegionNull(&childUnion); 398706f2543Smrg if ((pChild->drawable.y < pParent->lastChild->drawable.y) || 399706f2543Smrg ((pChild->drawable.y == pParent->lastChild->drawable.y) && 400706f2543Smrg (pChild->drawable.x < pParent->lastChild->drawable.x))) 401706f2543Smrg { 402706f2543Smrg for (; pChild; pChild = pChild->nextSib) 403706f2543Smrg { 404706f2543Smrg if (pChild->viewable) 405706f2543Smrg RegionAppend(&childUnion, &pChild->borderSize); 406706f2543Smrg } 407706f2543Smrg } 408706f2543Smrg else 409706f2543Smrg { 410706f2543Smrg for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) 411706f2543Smrg { 412706f2543Smrg if (pChild->viewable) 413706f2543Smrg RegionAppend(&childUnion, &pChild->borderSize); 414706f2543Smrg } 415706f2543Smrg } 416706f2543Smrg RegionValidate(&childUnion, &overlap); 417706f2543Smrg 418706f2543Smrg for (pChild = pParent->firstChild; 419706f2543Smrg pChild; 420706f2543Smrg pChild = pChild->nextSib) 421706f2543Smrg { 422706f2543Smrg if (pChild->viewable) { 423706f2543Smrg /* 424706f2543Smrg * If the child is viewable, we want to remove its extents 425706f2543Smrg * from the current universe, but we only re-clip it if 426706f2543Smrg * it's been marked. 427706f2543Smrg */ 428706f2543Smrg if (pChild->valdata) { 429706f2543Smrg /* 430706f2543Smrg * Figure out the new universe from the child's 431706f2543Smrg * perspective and recurse. 432706f2543Smrg */ 433706f2543Smrg RegionIntersect(&childUniverse, 434706f2543Smrg universe, 435706f2543Smrg &pChild->borderSize); 436706f2543Smrg RootlessComputeClips (pChild, pScreen, &childUniverse, 437706f2543Smrg kind, exposed); 438706f2543Smrg } 439706f2543Smrg /* 440706f2543Smrg * Once the child has been processed, we remove its extents 441706f2543Smrg * from the current universe, thus denying its space to any 442706f2543Smrg * other sibling. 443706f2543Smrg */ 444706f2543Smrg if (overlap) 445706f2543Smrg RegionSubtract(universe, universe, 446706f2543Smrg &pChild->borderSize); 447706f2543Smrg } 448706f2543Smrg } 449706f2543Smrg if (!overlap) 450706f2543Smrg RegionSubtract(universe, universe, &childUnion); 451706f2543Smrg RegionUninit(&childUnion); 452706f2543Smrg RegionUninit(&childUniverse); 453706f2543Smrg } /* if any children */ 454706f2543Smrg 455706f2543Smrg /* 456706f2543Smrg * 'universe' now contains the new clipList for the parent window. 457706f2543Smrg * 458706f2543Smrg * To figure the exposure of the window we subtract the old clip from the 459706f2543Smrg * new, just as for the border. 460706f2543Smrg */ 461706f2543Smrg 462706f2543Smrg if (oldVis == VisibilityFullyObscured || 463706f2543Smrg oldVis == VisibilityNotViewable) 464706f2543Smrg { 465706f2543Smrg RegionCopy(&pParent->valdata->after.exposed, universe); 466706f2543Smrg } 467706f2543Smrg else if (newVis != VisibilityFullyObscured && 468706f2543Smrg newVis != VisibilityNotViewable) 469706f2543Smrg { 470706f2543Smrg RegionSubtract(&pParent->valdata->after.exposed, 471706f2543Smrg universe, &pParent->clipList); 472706f2543Smrg } 473706f2543Smrg 474706f2543Smrg /* HACK ALERT - copying contents of regions, instead of regions */ 475706f2543Smrg { 476706f2543Smrg RegionRec tmp; 477706f2543Smrg 478706f2543Smrg tmp = pParent->clipList; 479706f2543Smrg pParent->clipList = *universe; 480706f2543Smrg *universe = tmp; 481706f2543Smrg } 482706f2543Smrg 483706f2543Smrg#ifdef NOTDEF 484706f2543Smrg RegionCopy(&pParent->clipList, universe); 485706f2543Smrg#endif 486706f2543Smrg 487706f2543Smrg pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; 488706f2543Smrg 489706f2543Smrg if (pScreen->ClipNotify) 490706f2543Smrg (* pScreen->ClipNotify) (pParent, dx, dy); 491706f2543Smrg} 492706f2543Smrg 493706f2543Smrgstatic void 494706f2543SmrgRootlessTreeObscured(WindowPtr pParent) 495706f2543Smrg{ 496706f2543Smrg register WindowPtr pChild; 497706f2543Smrg register int oldVis; 498706f2543Smrg 499706f2543Smrg pChild = pParent; 500706f2543Smrg while (1) 501706f2543Smrg { 502706f2543Smrg if (pChild->viewable) 503706f2543Smrg { 504706f2543Smrg oldVis = pChild->visibility; 505706f2543Smrg if (oldVis != (pChild->visibility = VisibilityFullyObscured) && 506706f2543Smrg ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) 507706f2543Smrg SendVisibilityNotify(pChild); 508706f2543Smrg if (pChild->firstChild) 509706f2543Smrg { 510706f2543Smrg pChild = pChild->firstChild; 511706f2543Smrg continue; 512706f2543Smrg } 513706f2543Smrg } 514706f2543Smrg while (!pChild->nextSib && (pChild != pParent)) 515706f2543Smrg pChild = pChild->parent; 516706f2543Smrg if (pChild == pParent) 517706f2543Smrg break; 518706f2543Smrg pChild = pChild->nextSib; 519706f2543Smrg } 520706f2543Smrg} 521706f2543Smrg 522706f2543Smrg/* 523706f2543Smrg *----------------------------------------------------------------------- 524706f2543Smrg * RootlessMiValidateTree -- 525706f2543Smrg * Recomputes the clip list for pParent and all its inferiors. 526706f2543Smrg * 527706f2543Smrg * Results: 528706f2543Smrg * Always returns 1. 529706f2543Smrg * 530706f2543Smrg * Side Effects: 531706f2543Smrg * The clipList, borderClip, exposed, and borderExposed regions for 532706f2543Smrg * each marked window are altered. 533706f2543Smrg * 534706f2543Smrg * Notes: 535706f2543Smrg * This routine assumes that all affected windows have been marked 536706f2543Smrg * (valdata created) and their winSize and borderSize regions 537706f2543Smrg * adjusted to correspond to their new positions. The borderClip and 538706f2543Smrg * clipList regions should not have been touched. 539706f2543Smrg * 540706f2543Smrg * The top-most level is treated differently from all lower levels 541706f2543Smrg * because pParent is unchanged. For the top level, we merge the 542706f2543Smrg * regions taken up by the marked children back into the clipList 543706f2543Smrg * for pParent, thus forming a region from which the marked children 544706f2543Smrg * can claim their areas. For lower levels, where the old clipList 545706f2543Smrg * and borderClip are invalid, we can't do this and have to do the 546706f2543Smrg * extra operations done in miComputeClips, but this is much faster 547706f2543Smrg * e.g. when only one child has moved... 548706f2543Smrg * 549706f2543Smrg *----------------------------------------------------------------------- 550706f2543Smrg */ 551706f2543Smrg/* 552706f2543Smrg Quartz version: used for validate from root in rootless mode. 553706f2543Smrg We need to make sure top-level windows don't clip each other, 554706f2543Smrg and that top-level windows aren't clipped to the root window. 555706f2543Smrg*/ 556706f2543Smrg/*ARGSUSED*/ 557706f2543Smrg// fixme this is ugly 558706f2543Smrg// Xprint/ValTree.c doesn't work, but maybe that method can? 559706f2543Smrgint 560706f2543SmrgRootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */ 561706f2543Smrg WindowPtr pChild, /* First child of pRoot that was 562706f2543Smrg * affected */ 563706f2543Smrg VTKind kind /* What kind of configuration caused call */) 564706f2543Smrg{ 565706f2543Smrg RegionRec childClip; /* The new borderClip for the current 566706f2543Smrg * child */ 567706f2543Smrg RegionRec exposed; /* For intermediate calculations */ 568706f2543Smrg register ScreenPtr pScreen; 569706f2543Smrg register WindowPtr pWin; 570706f2543Smrg 571706f2543Smrg pScreen = pRoot->drawable.pScreen; 572706f2543Smrg if (pChild == NullWindow) 573706f2543Smrg pChild = pRoot->firstChild; 574706f2543Smrg 575706f2543Smrg RegionNull(&childClip); 576706f2543Smrg RegionNull(&exposed); 577706f2543Smrg 578706f2543Smrg if (RegionBroken(&pRoot->clipList) && 579706f2543Smrg !RegionBroken(&pRoot->borderClip)) 580706f2543Smrg { 581706f2543Smrg // fixme this might not work, but hopefully doesn't happen anyway. 582706f2543Smrg kind = VTBroken; 583706f2543Smrg RegionEmpty(&pRoot->clipList); 584706f2543Smrg ErrorF("ValidateTree: BUSTED!\n"); 585706f2543Smrg } 586706f2543Smrg 587706f2543Smrg /* 588706f2543Smrg * Recursively compute the clips for all children of the root. 589706f2543Smrg * They don't clip against each other or the root itself, so 590706f2543Smrg * childClip is always reset to that child's size. 591706f2543Smrg */ 592706f2543Smrg 593706f2543Smrg for (pWin = pChild; 594706f2543Smrg pWin != NullWindow; 595706f2543Smrg pWin = pWin->nextSib) 596706f2543Smrg { 597706f2543Smrg if (pWin->viewable) { 598706f2543Smrg if (pWin->valdata) { 599706f2543Smrg RegionCopy(&childClip, &pWin->borderSize); 600706f2543Smrg RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed); 601706f2543Smrg } else if (pWin->visibility == VisibilityNotViewable) { 602706f2543Smrg RootlessTreeObscured(pWin); 603706f2543Smrg } 604706f2543Smrg } else { 605706f2543Smrg if (pWin->valdata) { 606706f2543Smrg RegionEmpty(&pWin->clipList); 607706f2543Smrg if (pScreen->ClipNotify) 608706f2543Smrg (* pScreen->ClipNotify) (pWin, 0, 0); 609706f2543Smrg RegionEmpty(&pWin->borderClip); 610706f2543Smrg pWin->valdata = NULL; 611706f2543Smrg } 612706f2543Smrg } 613706f2543Smrg } 614706f2543Smrg 615706f2543Smrg RegionUninit(&childClip); 616706f2543Smrg 617706f2543Smrg /* The root is never clipped by its children, so nothing on the root 618706f2543Smrg is ever exposed by moving or mapping its children. */ 619706f2543Smrg RegionNull(&pRoot->valdata->after.exposed); 620706f2543Smrg RegionNull(&pRoot->valdata->after.borderExposed); 621706f2543Smrg 622706f2543Smrg return 1; 623706f2543Smrg} 624