1 /*
2 * mivaltree.c --
3 * Functions for recalculating window clip lists. Main function
4 * is miValidateTree.
5 *
6
7 Copyright 1987, 1988, 1989, 1998 The Open Group
8
9 Permission to use, copy, modify, distribute, and sell this software and its
10 documentation for any purpose is hereby granted without fee, provided that
11 the above copyright notice appear in all copies and that both that
12 copyright notice and this permission notice appear in supporting
13 documentation.
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 Except as contained in this notice, the name of The Open Group shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings
27 in this Software without prior written authorization from The Open Group.
28
29 *
30 * Copyright 1987, 1988, 1989 by
31 * Digital Equipment Corporation, Maynard, Massachusetts,
32 *
33 * All Rights Reserved
34 *
35 * Permission to use, copy, modify, and distribute this software and its
36 * documentation for any purpose and without fee is hereby granted,
37 * provided that the above copyright notice appear in all copies and that
38 * both that copyright notice and this permission notice appear in
39 * supporting documentation, and that the name of Digital not be
40 * used in advertising or publicity pertaining to distribution of the
41 * software without specific, written prior permission.
42 *
43 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
44 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
45 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
46 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
47 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
48 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 * SOFTWARE.
50 *
51 ******************************************************************/
52
53 /* The panoramix components contained the following notice */
54 /*****************************************************************
55
56 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
57
58 Permission is hereby granted, free of charge, to any person obtaining a copy
59 of this software and associated documentation files (the "Software"), to deal
60 in the Software without restriction, including without limitation the rights
61 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62 copies of the Software.
63
64 The above copyright notice and this permission notice shall be included in
65 all copies or substantial portions of the Software.
66
67 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
70 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
71 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
72 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
73 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
74
75 Except as contained in this notice, the name of Digital Equipment Corporation
76 shall not be used in advertising or otherwise to promote the sale, use or other
77 dealings in this Software without prior written authorization from Digital
78 Equipment Corporation.
79
80 ******************************************************************/
81
82 /*
83 * Aug '86: Susan Angebranndt -- original code
84 * July '87: Adam de Boor -- substantially modified and commented
85 * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
86 * In particular, much improved code for window mapping and
87 * circulating.
88 * Bob Scheifler -- avoid miComputeClips for unmapped windows,
89 * valdata changes
90 */
91 #ifdef HAVE_DIX_CONFIG_H
92 #include <dix-config.h>
93 #endif
94
95 #include <X11/X.h>
96 #include "scrnintstr.h"
97 #include "validate.h"
98 #include "windowstr.h"
99 #include "mi.h"
100 #include "regionstr.h"
101 #include "mivalidate.h"
102 #include "globals.h"
103 #ifdef COMPOSITE
104 #include "compint.h"
105 #endif
106
107 /*
108 * Compute the visibility of a shaped window
109 */
110 int
miShapedWindowIn(RegionPtr universe,RegionPtr bounding,BoxPtr rect,int x,int y)111 miShapedWindowIn(RegionPtr universe, RegionPtr bounding,
112 BoxPtr rect, int x, int y)
113 {
114 BoxRec box;
115 BoxPtr boundBox;
116 int nbox;
117 Bool someIn, someOut;
118 int t, x1, y1, x2, y2;
119
120 nbox = RegionNumRects(bounding);
121 boundBox = RegionRects(bounding);
122 someIn = someOut = FALSE;
123 x1 = rect->x1;
124 y1 = rect->y1;
125 x2 = rect->x2;
126 y2 = rect->y2;
127 while (nbox--) {
128 if ((t = boundBox->x1 + x) < x1)
129 t = x1;
130 box.x1 = t;
131 if ((t = boundBox->y1 + y) < y1)
132 t = y1;
133 box.y1 = t;
134 if ((t = boundBox->x2 + x) > x2)
135 t = x2;
136 box.x2 = t;
137 if ((t = boundBox->y2 + y) > y2)
138 t = y2;
139 box.y2 = t;
140 if (box.x1 > box.x2)
141 box.x2 = box.x1;
142 if (box.y1 > box.y2)
143 box.y2 = box.y1;
144 switch (RegionContainsRect(universe, &box)) {
145 case rgnIN:
146 if (someOut)
147 return rgnPART;
148 someIn = TRUE;
149 break;
150 case rgnOUT:
151 if (someIn)
152 return rgnPART;
153 someOut = TRUE;
154 break;
155 default:
156 return rgnPART;
157 }
158 boundBox++;
159 }
160 if (someIn)
161 return rgnIN;
162 return rgnOUT;
163 }
164
165 /*
166 * Manual redirected windows are treated as transparent; they do not obscure
167 * siblings or parent windows
168 */
169
170 #ifdef COMPOSITE
171 #define TreatAsTransparent(w) ((w)->redirectDraw == RedirectDrawManual)
172 #else
173 #define TreatAsTransparent(w) FALSE
174 #endif
175
176 #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
177 HasBorder(w) && \
178 (w)->backgroundState == ParentRelative)
179
180 /*
181 *-----------------------------------------------------------------------
182 * miComputeClips --
183 * Recompute the clipList, borderClip, exposed and borderExposed
184 * regions for pParent and its children. Only viewable windows are
185 * taken into account.
186 *
187 * Results:
188 * None.
189 *
190 * Side Effects:
191 * clipList, borderClip, exposed and borderExposed are altered.
192 * A VisibilityNotify event may be generated on the parent window.
193 *
194 *-----------------------------------------------------------------------
195 */
196 static void
miComputeClips(WindowPtr pParent,ScreenPtr pScreen,RegionPtr universe,VTKind kind,RegionPtr exposed)197 miComputeClips(WindowPtr pParent,
198 ScreenPtr pScreen,
199 RegionPtr universe, VTKind kind, RegionPtr exposed)
200 { /* for intermediate calculations */
201 int dx, dy;
202 RegionRec childUniverse;
203 WindowPtr pChild;
204 int oldVis, newVis;
205 BoxRec borderSize;
206 RegionRec childUnion;
207 Bool overlap;
208 RegionPtr borderVisible;
209
210 /*
211 * Figure out the new visibility of this window.
212 * The extent of the universe should be the same as the extent of
213 * the borderSize region. If the window is unobscured, this rectangle
214 * will be completely inside the universe (the universe will cover it
215 * completely). If the window is completely obscured, none of the
216 * universe will cover the rectangle.
217 */
218 borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
219 borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
220 dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
221 wBorderWidth(pParent);
222 if (dx > 32767)
223 dx = 32767;
224 borderSize.x2 = dx;
225 dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
226 wBorderWidth(pParent);
227 if (dy > 32767)
228 dy = 32767;
229 borderSize.y2 = dy;
230
231 #ifdef COMPOSITE
232 /*
233 * In redirected drawing case, reset universe to borderSize
234 */
235 if (pParent->redirectDraw != RedirectDrawNone) {
236 if (TreatAsTransparent(pParent))
237 RegionEmpty(universe);
238 compSetRedirectBorderClip (pParent, universe);
239 RegionCopy(universe, &pParent->borderSize);
240 }
241 #endif
242
243 oldVis = pParent->visibility;
244 switch (RegionContainsRect(universe, &borderSize)) {
245 case rgnIN:
246 newVis = VisibilityUnobscured;
247 break;
248 case rgnPART:
249 newVis = VisibilityPartiallyObscured;
250 {
251 RegionPtr pBounding;
252
253 if ((pBounding = wBoundingShape(pParent))) {
254 switch (miShapedWindowIn(universe, pBounding,
255 &borderSize,
256 pParent->drawable.x,
257 pParent->drawable.y)) {
258 case rgnIN:
259 newVis = VisibilityUnobscured;
260 break;
261 case rgnOUT:
262 newVis = VisibilityFullyObscured;
263 break;
264 }
265 }
266 }
267 break;
268 default:
269 newVis = VisibilityFullyObscured;
270 break;
271 }
272 pParent->visibility = newVis;
273 if (oldVis != newVis &&
274 ((pParent->
275 eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
276 SendVisibilityNotify(pParent);
277
278 dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
279 dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
280
281 /*
282 * avoid computations when dealing with simple operations
283 */
284
285 switch (kind) {
286 case VTMap:
287 case VTStack:
288 case VTUnmap:
289 break;
290 case VTMove:
291 if ((oldVis == newVis) &&
292 ((oldVis == VisibilityFullyObscured) ||
293 (oldVis == VisibilityUnobscured))) {
294 pChild = pParent;
295 while (1) {
296 if (pChild->viewable) {
297 if (pChild->visibility != VisibilityFullyObscured) {
298 RegionTranslate(&pChild->borderClip, dx, dy);
299 RegionTranslate(&pChild->clipList, dx, dy);
300 pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
301 if (pScreen->ClipNotify)
302 (*pScreen->ClipNotify) (pChild, dx, dy);
303
304 }
305 if (pChild->valdata) {
306 RegionNull(&pChild->valdata->after.borderExposed);
307 if (HasParentRelativeBorder(pChild)) {
308 RegionSubtract(&pChild->valdata->after.
309 borderExposed, &pChild->borderClip,
310 &pChild->winSize);
311 }
312 RegionNull(&pChild->valdata->after.exposed);
313 }
314 if (pChild->firstChild) {
315 pChild = pChild->firstChild;
316 continue;
317 }
318 }
319 while (!pChild->nextSib && (pChild != pParent))
320 pChild = pChild->parent;
321 if (pChild == pParent)
322 break;
323 pChild = pChild->nextSib;
324 }
325 return;
326 }
327 /* fall through */
328 default:
329 /*
330 * To calculate exposures correctly, we have to translate the old
331 * borderClip and clipList regions to the window's new location so there
332 * is a correspondence between pieces of the new and old clipping regions.
333 */
334 if (dx || dy) {
335 /*
336 * We translate the old clipList because that will be exposed or copied
337 * if gravity is right.
338 */
339 RegionTranslate(&pParent->borderClip, dx, dy);
340 RegionTranslate(&pParent->clipList, dx, dy);
341 }
342 break;
343 case VTBroken:
344 RegionEmpty(&pParent->borderClip);
345 RegionEmpty(&pParent->clipList);
346 break;
347 }
348
349 borderVisible = pParent->valdata->before.borderVisible;
350 RegionNull(&pParent->valdata->after.borderExposed);
351 RegionNull(&pParent->valdata->after.exposed);
352
353 /*
354 * Since the borderClip must not be clipped by the children, we do
355 * the border exposure first...
356 *
357 * 'universe' is the window's borderClip. To figure the exposures, remove
358 * the area that used to be exposed from the new.
359 * This leaves a region of pieces that weren't exposed before.
360 */
361
362 if (HasBorder(pParent)) {
363 if (borderVisible) {
364 /*
365 * when the border changes shape, the old visible portions
366 * of the border will be saved by DIX in borderVisible --
367 * use that region and destroy it
368 */
369 RegionSubtract(exposed, universe, borderVisible);
370 RegionDestroy(borderVisible);
371 }
372 else {
373 RegionSubtract(exposed, universe, &pParent->borderClip);
374 }
375 if (HasParentRelativeBorder(pParent) && (dx || dy))
376 RegionSubtract(&pParent->valdata->after.borderExposed,
377 universe, &pParent->winSize);
378 else
379 RegionSubtract(&pParent->valdata->after.borderExposed,
380 exposed, &pParent->winSize);
381
382 RegionCopy(&pParent->borderClip, universe);
383
384 /*
385 * To get the right clipList for the parent, and to make doubly sure
386 * that no child overlaps the parent's border, we remove the parent's
387 * border from the universe before proceeding.
388 */
389
390 RegionIntersect(universe, universe, &pParent->winSize);
391 }
392 else
393 RegionCopy(&pParent->borderClip, universe);
394
395 if ((pChild = pParent->firstChild) && pParent->mapped) {
396 RegionNull(&childUniverse);
397 RegionNull(&childUnion);
398 if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
399 ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
400 (pChild->drawable.x < pParent->lastChild->drawable.x))) {
401 for (; pChild; pChild = pChild->nextSib) {
402 if (pChild->viewable && !TreatAsTransparent(pChild))
403 RegionAppend(&childUnion, &pChild->borderSize);
404 }
405 }
406 else {
407 for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) {
408 if (pChild->viewable && !TreatAsTransparent(pChild))
409 RegionAppend(&childUnion, &pChild->borderSize);
410 }
411 }
412 RegionValidate(&childUnion, &overlap);
413
414 for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) {
415 if (pChild->viewable) {
416 /*
417 * If the child is viewable, we want to remove its extents
418 * from the current universe, but we only re-clip it if
419 * it's been marked.
420 */
421 if (pChild->valdata) {
422 /*
423 * Figure out the new universe from the child's
424 * perspective and recurse.
425 */
426 RegionIntersect(&childUniverse,
427 universe, &pChild->borderSize);
428 miComputeClips(pChild, pScreen, &childUniverse, kind,
429 exposed);
430 }
431 /*
432 * Once the child has been processed, we remove its extents
433 * from the current universe, thus denying its space to any
434 * other sibling.
435 */
436 if (overlap && !TreatAsTransparent(pChild))
437 RegionSubtract(universe, universe, &pChild->borderSize);
438 }
439 }
440 if (!overlap)
441 RegionSubtract(universe, universe, &childUnion);
442 RegionUninit(&childUnion);
443 RegionUninit(&childUniverse);
444 } /* if any children */
445
446 /*
447 * 'universe' now contains the new clipList for the parent window.
448 *
449 * To figure the exposure of the window we subtract the old clip from the
450 * new, just as for the border.
451 */
452
453 if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) {
454 RegionCopy(&pParent->valdata->after.exposed, universe);
455 }
456 else if (newVis != VisibilityFullyObscured &&
457 newVis != VisibilityNotViewable) {
458 RegionSubtract(&pParent->valdata->after.exposed,
459 universe, &pParent->clipList);
460 }
461
462 /* HACK ALERT - copying contents of regions, instead of regions */
463 {
464 RegionRec tmp;
465
466 tmp = pParent->clipList;
467 pParent->clipList = *universe;
468 *universe = tmp;
469 }
470
471 #ifdef NOTDEF
472 RegionCopy(&pParent->clipList, universe);
473 #endif
474
475 pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
476
477 if (pScreen->ClipNotify)
478 (*pScreen->ClipNotify) (pParent, dx, dy);
479 }
480
481 static void
miTreeObscured(WindowPtr pParent)482 miTreeObscured(WindowPtr pParent)
483 {
484 WindowPtr pChild;
485 int oldVis;
486
487 pChild = pParent;
488 while (1) {
489 if (pChild->viewable) {
490 oldVis = pChild->visibility;
491 if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
492 ((pChild->
493 eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
494 SendVisibilityNotify(pChild);
495 if (pChild->firstChild) {
496 pChild = pChild->firstChild;
497 continue;
498 }
499 }
500 while (!pChild->nextSib && (pChild != pParent))
501 pChild = pChild->parent;
502 if (pChild == pParent)
503 break;
504 pChild = pChild->nextSib;
505 }
506 }
507
508 static RegionPtr
getBorderClip(WindowPtr pWin)509 getBorderClip(WindowPtr pWin)
510 {
511 #ifdef COMPOSITE
512 if (pWin->redirectDraw != RedirectDrawNone)
513 return compGetRedirectBorderClip(pWin);
514 else
515 #endif
516 return &pWin->borderClip;
517 }
518
519 /*
520 *-----------------------------------------------------------------------
521 * miValidateTree --
522 * Recomputes the clip list for pParent and all its inferiors.
523 *
524 * Results:
525 * Always returns 1.
526 *
527 * Side Effects:
528 * The clipList, borderClip, exposed, and borderExposed regions for
529 * each marked window are altered.
530 *
531 * Notes:
532 * This routine assumes that all affected windows have been marked
533 * (valdata created) and their winSize and borderSize regions
534 * adjusted to correspond to their new positions. The borderClip and
535 * clipList regions should not have been touched.
536 *
537 * The top-most level is treated differently from all lower levels
538 * because pParent is unchanged. For the top level, we merge the
539 * regions taken up by the marked children back into the clipList
540 * for pParent, thus forming a region from which the marked children
541 * can claim their areas. For lower levels, where the old clipList
542 * and borderClip are invalid, we can't do this and have to do the
543 * extra operations done in miComputeClips, but this is much faster
544 * e.g. when only one child has moved...
545 *
546 *-----------------------------------------------------------------------
547 */
548 /*ARGSUSED*/ int
miValidateTree(WindowPtr pParent,WindowPtr pChild,VTKind kind)549 miValidateTree(WindowPtr pParent, /* Parent to validate */
550 WindowPtr pChild, /* First child of pParent that was
551 * affected */
552 VTKind kind /* What kind of configuration caused call */
553 )
554 {
555 RegionRec totalClip; /* Total clipping region available to
556 * the marked children. pParent's clipList
557 * merged with the borderClips of all
558 * the marked children. */
559 RegionRec childClip; /* The new borderClip for the current
560 * child */
561 RegionRec childUnion; /* the space covered by borderSize for
562 * all marked children */
563 RegionRec exposed; /* For intermediate calculations */
564 ScreenPtr pScreen;
565 WindowPtr pWin;
566 Bool overlap;
567 int viewvals;
568 Bool forward;
569
570 pScreen = pParent->drawable.pScreen;
571 if (pChild == NullWindow)
572 pChild = pParent->firstChild;
573
574 RegionNull(&childClip);
575 RegionNull(&exposed);
576
577 /*
578 * compute the area of the parent window occupied
579 * by the marked children + the parent itself. This
580 * is the area which can be divied up among the marked
581 * children in their new configuration.
582 */
583 RegionNull(&totalClip);
584 viewvals = 0;
585 if (RegionBroken(&pParent->clipList) && !RegionBroken(&pParent->borderClip)) {
586 kind = VTBroken;
587 /*
588 * When rebuilding clip lists after out of memory,
589 * assume everything is busted.
590 */
591 forward = TRUE;
592 RegionCopy(&totalClip, &pParent->borderClip);
593 RegionIntersect(&totalClip, &totalClip, &pParent->winSize);
594
595 for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) {
596 if (pWin->viewable && !TreatAsTransparent(pWin))
597 RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
598 }
599 for (pWin = pChild; pWin; pWin = pWin->nextSib)
600 if (pWin->valdata && pWin->viewable)
601 viewvals++;
602
603 RegionEmpty(&pParent->clipList);
604 }
605 else {
606 if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
607 ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
608 (pChild->drawable.x < pParent->lastChild->drawable.x))) {
609 forward = TRUE;
610 for (pWin = pChild; pWin; pWin = pWin->nextSib) {
611 if (pWin->valdata) {
612 RegionAppend(&totalClip, getBorderClip(pWin));
613 if (pWin->viewable)
614 viewvals++;
615 }
616 }
617 }
618 else {
619 forward = FALSE;
620 pWin = pParent->lastChild;
621 while (1) {
622 if (pWin->valdata) {
623 RegionAppend(&totalClip, getBorderClip(pWin));
624 if (pWin->viewable)
625 viewvals++;
626 }
627 if (pWin == pChild)
628 break;
629 pWin = pWin->prevSib;
630 }
631 }
632 RegionValidate(&totalClip, &overlap);
633 }
634
635 /*
636 * Now go through the children of the root and figure their new
637 * borderClips from the totalClip, passing that off to miComputeClips
638 * to handle recursively. Once that's done, we remove the child
639 * from the totalClip to clip any siblings below it.
640 */
641
642 overlap = TRUE;
643 if (kind != VTStack) {
644 RegionUnion(&totalClip, &totalClip, &pParent->clipList);
645 if (viewvals > 1) {
646 /*
647 * precompute childUnion to discover whether any of them
648 * overlap. This seems redundant, but performance studies
649 * have demonstrated that the cost of this loop is
650 * lower than the cost of multiple Subtracts in the
651 * loop below.
652 */
653 RegionNull(&childUnion);
654 if (forward) {
655 for (pWin = pChild; pWin; pWin = pWin->nextSib)
656 if (pWin->valdata && pWin->viewable &&
657 !TreatAsTransparent(pWin))
658 RegionAppend(&childUnion, &pWin->borderSize);
659 }
660 else {
661 pWin = pParent->lastChild;
662 while (1) {
663 if (pWin->valdata && pWin->viewable &&
664 !TreatAsTransparent(pWin))
665 RegionAppend(&childUnion, &pWin->borderSize);
666 if (pWin == pChild)
667 break;
668 pWin = pWin->prevSib;
669 }
670 }
671 RegionValidate(&childUnion, &overlap);
672 if (overlap)
673 RegionUninit(&childUnion);
674 }
675 }
676
677 for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) {
678 if (pWin->viewable) {
679 if (pWin->valdata) {
680 RegionIntersect(&childClip, &totalClip, &pWin->borderSize);
681 miComputeClips(pWin, pScreen, &childClip, kind, &exposed);
682 if (overlap && !TreatAsTransparent(pWin)) {
683 RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
684 }
685 }
686 else if (pWin->visibility == VisibilityNotViewable) {
687 miTreeObscured(pWin);
688 }
689 }
690 else {
691 if (pWin->valdata) {
692 RegionEmpty(&pWin->clipList);
693 if (pScreen->ClipNotify)
694 (*pScreen->ClipNotify) (pWin, 0, 0);
695 RegionEmpty(&pWin->borderClip);
696 pWin->valdata = NULL;
697 }
698 }
699 }
700
701 RegionUninit(&childClip);
702 if (!overlap) {
703 RegionSubtract(&totalClip, &totalClip, &childUnion);
704 RegionUninit(&childUnion);
705 }
706
707 RegionNull(&pParent->valdata->after.exposed);
708 RegionNull(&pParent->valdata->after.borderExposed);
709
710 /*
711 * each case below is responsible for updating the
712 * clipList and serial number for the parent window
713 */
714
715 switch (kind) {
716 case VTStack:
717 break;
718 default:
719 /*
720 * totalClip contains the new clipList for the parent. Figure out
721 * exposures and obscures as per miComputeClips and reset the parent's
722 * clipList.
723 */
724 RegionSubtract(&pParent->valdata->after.exposed,
725 &totalClip, &pParent->clipList);
726 /* fall through */
727 case VTMap:
728 RegionCopy(&pParent->clipList, &totalClip);
729 pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
730 break;
731 }
732
733 RegionUninit(&totalClip);
734 RegionUninit(&exposed);
735 if (pScreen->ClipNotify)
736 (*pScreen->ClipNotify) (pParent, 0, 0);
737 return 1;
738 }
739