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