1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Calculate window clip lists for rootless mode
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * This file is very closely based on mivaltree.c.
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun /*
8*4882a593Smuzhiyun * mivaltree.c --
9*4882a593Smuzhiyun * Functions for recalculating window clip lists. Main function
10*4882a593Smuzhiyun * is miValidateTree.
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun Copyright 1987, 1988, 1989, 1998 The Open Group
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun All Rights Reserved.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
18*4882a593Smuzhiyun all copies or substantial portions of the Software.
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
28*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
29*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun * Copyright 1987, 1988, 1989 by
33*4882a593Smuzhiyun * Digital Equipment Corporation, Maynard, Massachusetts,
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun * All Rights Reserved
36*4882a593Smuzhiyun *
37*4882a593Smuzhiyun * Permission to use, copy, modify, and distribute this software and its
38*4882a593Smuzhiyun * documentation for any purpose and without fee is hereby granted,
39*4882a593Smuzhiyun * provided that the above copyright notice appear in all copies and that
40*4882a593Smuzhiyun * both that copyright notice and this permission notice appear in
41*4882a593Smuzhiyun * supporting documentation, and that the name of Digital not be
42*4882a593Smuzhiyun * used in advertising or publicity pertaining to distribution of the
43*4882a593Smuzhiyun * software without specific, written prior permission.
44*4882a593Smuzhiyun *
45*4882a593Smuzhiyun * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
46*4882a593Smuzhiyun * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
47*4882a593Smuzhiyun * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
48*4882a593Smuzhiyun * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
49*4882a593Smuzhiyun * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
50*4882a593Smuzhiyun * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51*4882a593Smuzhiyun * SOFTWARE.
52*4882a593Smuzhiyun *
53*4882a593Smuzhiyun ******************************************************************/
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* The panoramix components contained the following notice */
56*4882a593Smuzhiyun /*****************************************************************
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy
61*4882a593Smuzhiyun of this software and associated documentation files (the "Software"), to deal
62*4882a593Smuzhiyun in the Software without restriction, including without limitation the rights
63*4882a593Smuzhiyun to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64*4882a593Smuzhiyun copies of the Software.
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
67*4882a593Smuzhiyun all copies or substantial portions of the Software.
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
70*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
71*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
72*4882a593Smuzhiyun DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
73*4882a593Smuzhiyun BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
74*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
75*4882a593Smuzhiyun IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun Except as contained in this notice, the name of Digital Equipment Corporation
78*4882a593Smuzhiyun shall not be used in advertising or otherwise to promote the sale, use or other
79*4882a593Smuzhiyun dealings in this Software without prior written authorization from Digital
80*4882a593Smuzhiyun Equipment Corporation.
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun ******************************************************************/
83*4882a593Smuzhiyun /*
84*4882a593Smuzhiyun * Aug '86: Susan Angebranndt -- original code
85*4882a593Smuzhiyun * July '87: Adam de Boor -- substantially modified and commented
86*4882a593Smuzhiyun * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
87*4882a593Smuzhiyun * In particular, much improved code for window mapping and
88*4882a593Smuzhiyun * circulating.
89*4882a593Smuzhiyun * Bob Scheifler -- avoid miComputeClips for unmapped windows,
90*4882a593Smuzhiyun * valdata changes
91*4882a593Smuzhiyun */
92*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
93*4882a593Smuzhiyun #include <dix-config.h>
94*4882a593Smuzhiyun #endif
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun #include <stddef.h> /* For NULL */
97*4882a593Smuzhiyun #include <X11/X.h>
98*4882a593Smuzhiyun #include "scrnintstr.h"
99*4882a593Smuzhiyun #include "validate.h"
100*4882a593Smuzhiyun #include "windowstr.h"
101*4882a593Smuzhiyun #include "mi.h"
102*4882a593Smuzhiyun #include "regionstr.h"
103*4882a593Smuzhiyun #include "mivalidate.h"
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun #include "globals.h"
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, VTKind kind);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
110*4882a593Smuzhiyun HasBorder(w) && \
111*4882a593Smuzhiyun (w)->backgroundState == ParentRelative)
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun *-----------------------------------------------------------------------
115*4882a593Smuzhiyun * RootlessComputeClips --
116*4882a593Smuzhiyun * Recompute the clipList, borderClip, exposed and borderExposed
117*4882a593Smuzhiyun * regions for pParent and its children. Only viewable windows are
118*4882a593Smuzhiyun * taken into account.
119*4882a593Smuzhiyun *
120*4882a593Smuzhiyun * Results:
121*4882a593Smuzhiyun * None.
122*4882a593Smuzhiyun *
123*4882a593Smuzhiyun * Side Effects:
124*4882a593Smuzhiyun * clipList, borderClip, exposed and borderExposed are altered.
125*4882a593Smuzhiyun * A VisibilityNotify event may be generated on the parent window.
126*4882a593Smuzhiyun *
127*4882a593Smuzhiyun *-----------------------------------------------------------------------
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun static void
RootlessComputeClips(WindowPtr pParent,ScreenPtr pScreen,RegionPtr universe,VTKind kind,RegionPtr exposed)130*4882a593Smuzhiyun RootlessComputeClips(WindowPtr pParent, ScreenPtr pScreen,
131*4882a593Smuzhiyun RegionPtr universe, VTKind kind, RegionPtr exposed)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun int dx, dy;
134*4882a593Smuzhiyun RegionRec childUniverse;
135*4882a593Smuzhiyun register WindowPtr pChild;
136*4882a593Smuzhiyun int oldVis, newVis;
137*4882a593Smuzhiyun BoxRec borderSize;
138*4882a593Smuzhiyun RegionRec childUnion;
139*4882a593Smuzhiyun Bool overlap;
140*4882a593Smuzhiyun RegionPtr borderVisible;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /*
143*4882a593Smuzhiyun * Figure out the new visibility of this window.
144*4882a593Smuzhiyun * The extent of the universe should be the same as the extent of
145*4882a593Smuzhiyun * the borderSize region. If the window is unobscured, this rectangle
146*4882a593Smuzhiyun * will be completely inside the universe (the universe will cover it
147*4882a593Smuzhiyun * completely). If the window is completely obscured, none of the
148*4882a593Smuzhiyun * universe will cover the rectangle.
149*4882a593Smuzhiyun */
150*4882a593Smuzhiyun borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
151*4882a593Smuzhiyun borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
152*4882a593Smuzhiyun dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
153*4882a593Smuzhiyun wBorderWidth(pParent);
154*4882a593Smuzhiyun if (dx > 32767)
155*4882a593Smuzhiyun dx = 32767;
156*4882a593Smuzhiyun borderSize.x2 = dx;
157*4882a593Smuzhiyun dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
158*4882a593Smuzhiyun wBorderWidth(pParent);
159*4882a593Smuzhiyun if (dy > 32767)
160*4882a593Smuzhiyun dy = 32767;
161*4882a593Smuzhiyun borderSize.y2 = dy;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun oldVis = pParent->visibility;
164*4882a593Smuzhiyun switch (RegionContainsRect(universe, &borderSize)) {
165*4882a593Smuzhiyun case rgnIN:
166*4882a593Smuzhiyun newVis = VisibilityUnobscured;
167*4882a593Smuzhiyun break;
168*4882a593Smuzhiyun case rgnPART:
169*4882a593Smuzhiyun newVis = VisibilityPartiallyObscured;
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun RegionPtr pBounding;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if ((pBounding = wBoundingShape(pParent))) {
174*4882a593Smuzhiyun switch (miShapedWindowIn(universe, pBounding, &borderSize,
175*4882a593Smuzhiyun pParent->drawable.x,
176*4882a593Smuzhiyun pParent->drawable.y)) {
177*4882a593Smuzhiyun case rgnIN:
178*4882a593Smuzhiyun newVis = VisibilityUnobscured;
179*4882a593Smuzhiyun break;
180*4882a593Smuzhiyun case rgnOUT:
181*4882a593Smuzhiyun newVis = VisibilityFullyObscured;
182*4882a593Smuzhiyun break;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun break;
187*4882a593Smuzhiyun default:
188*4882a593Smuzhiyun newVis = VisibilityFullyObscured;
189*4882a593Smuzhiyun break;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun pParent->visibility = newVis;
193*4882a593Smuzhiyun if (oldVis != newVis &&
194*4882a593Smuzhiyun ((pParent->
195*4882a593Smuzhiyun eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
196*4882a593Smuzhiyun SendVisibilityNotify(pParent);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
199*4882a593Smuzhiyun dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /*
202*4882a593Smuzhiyun * avoid computations when dealing with simple operations
203*4882a593Smuzhiyun */
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun switch (kind) {
206*4882a593Smuzhiyun case VTMap:
207*4882a593Smuzhiyun case VTStack:
208*4882a593Smuzhiyun case VTUnmap:
209*4882a593Smuzhiyun break;
210*4882a593Smuzhiyun case VTMove:
211*4882a593Smuzhiyun if ((oldVis == newVis) &&
212*4882a593Smuzhiyun ((oldVis == VisibilityFullyObscured) ||
213*4882a593Smuzhiyun (oldVis == VisibilityUnobscured))) {
214*4882a593Smuzhiyun pChild = pParent;
215*4882a593Smuzhiyun while (1) {
216*4882a593Smuzhiyun if (pChild->viewable) {
217*4882a593Smuzhiyun if (pChild->visibility != VisibilityFullyObscured) {
218*4882a593Smuzhiyun RegionTranslate(&pChild->borderClip, dx, dy);
219*4882a593Smuzhiyun RegionTranslate(&pChild->clipList, dx, dy);
220*4882a593Smuzhiyun pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
221*4882a593Smuzhiyun if (pScreen->ClipNotify)
222*4882a593Smuzhiyun (*pScreen->ClipNotify) (pChild, dx, dy);
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun if (pChild->valdata) {
226*4882a593Smuzhiyun RegionNull(&pChild->valdata->after.borderExposed);
227*4882a593Smuzhiyun if (HasParentRelativeBorder(pChild)) {
228*4882a593Smuzhiyun RegionSubtract(&pChild->valdata->after.
229*4882a593Smuzhiyun borderExposed, &pChild->borderClip,
230*4882a593Smuzhiyun &pChild->winSize);
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun RegionNull(&pChild->valdata->after.exposed);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun if (pChild->firstChild) {
235*4882a593Smuzhiyun pChild = pChild->firstChild;
236*4882a593Smuzhiyun continue;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pParent))
240*4882a593Smuzhiyun pChild = pChild->parent;
241*4882a593Smuzhiyun if (pChild == pParent)
242*4882a593Smuzhiyun break;
243*4882a593Smuzhiyun pChild = pChild->nextSib;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun return;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun /* fall through */
248*4882a593Smuzhiyun default:
249*4882a593Smuzhiyun /*
250*4882a593Smuzhiyun * To calculate exposures correctly, we have to translate the old
251*4882a593Smuzhiyun * borderClip and clipList regions to the window's new location so there
252*4882a593Smuzhiyun * is a correspondence between pieces of the new and old clipping regions.
253*4882a593Smuzhiyun */
254*4882a593Smuzhiyun if (dx || dy) {
255*4882a593Smuzhiyun /*
256*4882a593Smuzhiyun * We translate the old clipList because that will be exposed or copied
257*4882a593Smuzhiyun * if gravity is right.
258*4882a593Smuzhiyun */
259*4882a593Smuzhiyun RegionTranslate(&pParent->borderClip, dx, dy);
260*4882a593Smuzhiyun RegionTranslate(&pParent->clipList, dx, dy);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun break;
263*4882a593Smuzhiyun case VTBroken:
264*4882a593Smuzhiyun RegionEmpty(&pParent->borderClip);
265*4882a593Smuzhiyun RegionEmpty(&pParent->clipList);
266*4882a593Smuzhiyun break;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun borderVisible = pParent->valdata->before.borderVisible;
270*4882a593Smuzhiyun RegionNull(&pParent->valdata->after.borderExposed);
271*4882a593Smuzhiyun RegionNull(&pParent->valdata->after.exposed);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /*
274*4882a593Smuzhiyun * Since the borderClip must not be clipped by the children, we do
275*4882a593Smuzhiyun * the border exposure first...
276*4882a593Smuzhiyun *
277*4882a593Smuzhiyun * 'universe' is the window's borderClip. To figure the exposures, remove
278*4882a593Smuzhiyun * the area that used to be exposed from the new.
279*4882a593Smuzhiyun * This leaves a region of pieces that weren't exposed before.
280*4882a593Smuzhiyun */
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun if (HasBorder(pParent)) {
283*4882a593Smuzhiyun if (borderVisible) {
284*4882a593Smuzhiyun /*
285*4882a593Smuzhiyun * when the border changes shape, the old visible portions
286*4882a593Smuzhiyun * of the border will be saved by DIX in borderVisible --
287*4882a593Smuzhiyun * use that region and destroy it
288*4882a593Smuzhiyun */
289*4882a593Smuzhiyun RegionSubtract(exposed, universe, borderVisible);
290*4882a593Smuzhiyun RegionDestroy(borderVisible);
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun else {
293*4882a593Smuzhiyun RegionSubtract(exposed, universe, &pParent->borderClip);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun if (HasParentRelativeBorder(pParent) && (dx || dy)) {
296*4882a593Smuzhiyun RegionSubtract(&pParent->valdata->after.borderExposed,
297*4882a593Smuzhiyun universe, &pParent->winSize);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun else {
300*4882a593Smuzhiyun RegionSubtract(&pParent->valdata->after.borderExposed,
301*4882a593Smuzhiyun exposed, &pParent->winSize);
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun RegionCopy(&pParent->borderClip, universe);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun /*
307*4882a593Smuzhiyun * To get the right clipList for the parent, and to make doubly sure
308*4882a593Smuzhiyun * that no child overlaps the parent's border, we remove the parent's
309*4882a593Smuzhiyun * border from the universe before proceeding.
310*4882a593Smuzhiyun */
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun RegionIntersect(universe, universe, &pParent->winSize);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun else
315*4882a593Smuzhiyun RegionCopy(&pParent->borderClip, universe);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if ((pChild = pParent->firstChild) && pParent->mapped) {
318*4882a593Smuzhiyun RegionNull(&childUniverse);
319*4882a593Smuzhiyun RegionNull(&childUnion);
320*4882a593Smuzhiyun if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
321*4882a593Smuzhiyun ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
322*4882a593Smuzhiyun (pChild->drawable.x < pParent->lastChild->drawable.x))) {
323*4882a593Smuzhiyun for (; pChild; pChild = pChild->nextSib) {
324*4882a593Smuzhiyun if (pChild->viewable)
325*4882a593Smuzhiyun RegionAppend(&childUnion, &pChild->borderSize);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun else {
329*4882a593Smuzhiyun for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) {
330*4882a593Smuzhiyun if (pChild->viewable)
331*4882a593Smuzhiyun RegionAppend(&childUnion, &pChild->borderSize);
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun RegionValidate(&childUnion, &overlap);
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) {
337*4882a593Smuzhiyun if (pChild->viewable) {
338*4882a593Smuzhiyun /*
339*4882a593Smuzhiyun * If the child is viewable, we want to remove its extents
340*4882a593Smuzhiyun * from the current universe, but we only re-clip it if
341*4882a593Smuzhiyun * it's been marked.
342*4882a593Smuzhiyun */
343*4882a593Smuzhiyun if (pChild->valdata) {
344*4882a593Smuzhiyun /*
345*4882a593Smuzhiyun * Figure out the new universe from the child's
346*4882a593Smuzhiyun * perspective and recurse.
347*4882a593Smuzhiyun */
348*4882a593Smuzhiyun RegionIntersect(&childUniverse,
349*4882a593Smuzhiyun universe, &pChild->borderSize);
350*4882a593Smuzhiyun RootlessComputeClips(pChild, pScreen, &childUniverse,
351*4882a593Smuzhiyun kind, exposed);
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun * Once the child has been processed, we remove its extents
355*4882a593Smuzhiyun * from the current universe, thus denying its space to any
356*4882a593Smuzhiyun * other sibling.
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun if (overlap)
359*4882a593Smuzhiyun RegionSubtract(universe, universe, &pChild->borderSize);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun if (!overlap)
363*4882a593Smuzhiyun RegionSubtract(universe, universe, &childUnion);
364*4882a593Smuzhiyun RegionUninit(&childUnion);
365*4882a593Smuzhiyun RegionUninit(&childUniverse);
366*4882a593Smuzhiyun } /* if any children */
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /*
369*4882a593Smuzhiyun * 'universe' now contains the new clipList for the parent window.
370*4882a593Smuzhiyun *
371*4882a593Smuzhiyun * To figure the exposure of the window we subtract the old clip from the
372*4882a593Smuzhiyun * new, just as for the border.
373*4882a593Smuzhiyun */
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) {
376*4882a593Smuzhiyun RegionCopy(&pParent->valdata->after.exposed, universe);
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun else if (newVis != VisibilityFullyObscured &&
379*4882a593Smuzhiyun newVis != VisibilityNotViewable) {
380*4882a593Smuzhiyun RegionSubtract(&pParent->valdata->after.exposed,
381*4882a593Smuzhiyun universe, &pParent->clipList);
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* HACK ALERT - copying contents of regions, instead of regions */
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun RegionRec tmp;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun tmp = pParent->clipList;
389*4882a593Smuzhiyun pParent->clipList = *universe;
390*4882a593Smuzhiyun *universe = tmp;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun #ifdef NOTDEF
394*4882a593Smuzhiyun RegionCopy(&pParent->clipList, universe);
395*4882a593Smuzhiyun #endif
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun if (pScreen->ClipNotify)
400*4882a593Smuzhiyun (*pScreen->ClipNotify) (pParent, dx, dy);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun static void
RootlessTreeObscured(WindowPtr pParent)404*4882a593Smuzhiyun RootlessTreeObscured(WindowPtr pParent)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun register WindowPtr pChild;
407*4882a593Smuzhiyun register int oldVis;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun pChild = pParent;
410*4882a593Smuzhiyun while (1) {
411*4882a593Smuzhiyun if (pChild->viewable) {
412*4882a593Smuzhiyun oldVis = pChild->visibility;
413*4882a593Smuzhiyun if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
414*4882a593Smuzhiyun ((pChild->
415*4882a593Smuzhiyun eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
416*4882a593Smuzhiyun SendVisibilityNotify(pChild);
417*4882a593Smuzhiyun if (pChild->firstChild) {
418*4882a593Smuzhiyun pChild = pChild->firstChild;
419*4882a593Smuzhiyun continue;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pParent))
423*4882a593Smuzhiyun pChild = pChild->parent;
424*4882a593Smuzhiyun if (pChild == pParent)
425*4882a593Smuzhiyun break;
426*4882a593Smuzhiyun pChild = pChild->nextSib;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /*
431*4882a593Smuzhiyun *-----------------------------------------------------------------------
432*4882a593Smuzhiyun * RootlessMiValidateTree --
433*4882a593Smuzhiyun * Recomputes the clip list for pParent and all its inferiors.
434*4882a593Smuzhiyun *
435*4882a593Smuzhiyun * Results:
436*4882a593Smuzhiyun * Always returns 1.
437*4882a593Smuzhiyun *
438*4882a593Smuzhiyun * Side Effects:
439*4882a593Smuzhiyun * The clipList, borderClip, exposed, and borderExposed regions for
440*4882a593Smuzhiyun * each marked window are altered.
441*4882a593Smuzhiyun *
442*4882a593Smuzhiyun * Notes:
443*4882a593Smuzhiyun * This routine assumes that all affected windows have been marked
444*4882a593Smuzhiyun * (valdata created) and their winSize and borderSize regions
445*4882a593Smuzhiyun * adjusted to correspond to their new positions. The borderClip and
446*4882a593Smuzhiyun * clipList regions should not have been touched.
447*4882a593Smuzhiyun *
448*4882a593Smuzhiyun * The top-most level is treated differently from all lower levels
449*4882a593Smuzhiyun * because pParent is unchanged. For the top level, we merge the
450*4882a593Smuzhiyun * regions taken up by the marked children back into the clipList
451*4882a593Smuzhiyun * for pParent, thus forming a region from which the marked children
452*4882a593Smuzhiyun * can claim their areas. For lower levels, where the old clipList
453*4882a593Smuzhiyun * and borderClip are invalid, we can't do this and have to do the
454*4882a593Smuzhiyun * extra operations done in miComputeClips, but this is much faster
455*4882a593Smuzhiyun * e.g. when only one child has moved...
456*4882a593Smuzhiyun *
457*4882a593Smuzhiyun *-----------------------------------------------------------------------
458*4882a593Smuzhiyun */
459*4882a593Smuzhiyun /*
460*4882a593Smuzhiyun Quartz version: used for validate from root in rootless mode.
461*4882a593Smuzhiyun We need to make sure top-level windows don't clip each other,
462*4882a593Smuzhiyun and that top-level windows aren't clipped to the root window.
463*4882a593Smuzhiyun */
464*4882a593Smuzhiyun /*ARGSUSED*/
465*4882a593Smuzhiyun // fixme this is ugly
466*4882a593Smuzhiyun // Xprint/ValTree.c doesn't work, but maybe that method can?
467*4882a593Smuzhiyun int
RootlessMiValidateTree(WindowPtr pRoot,WindowPtr pChild,VTKind kind)468*4882a593Smuzhiyun RootlessMiValidateTree(WindowPtr pRoot, /* Parent to validate */
469*4882a593Smuzhiyun WindowPtr pChild, /* First child of pRoot that was
470*4882a593Smuzhiyun * affected */
471*4882a593Smuzhiyun VTKind kind /* What kind of configuration caused call */
472*4882a593Smuzhiyun )
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun RegionRec childClip; /* The new borderClip for the current
475*4882a593Smuzhiyun * child */
476*4882a593Smuzhiyun RegionRec exposed; /* For intermediate calculations */
477*4882a593Smuzhiyun register ScreenPtr pScreen;
478*4882a593Smuzhiyun register WindowPtr pWin;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun pScreen = pRoot->drawable.pScreen;
481*4882a593Smuzhiyun if (pChild == NullWindow)
482*4882a593Smuzhiyun pChild = pRoot->firstChild;
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun RegionNull(&childClip);
485*4882a593Smuzhiyun RegionNull(&exposed);
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun if (RegionBroken(&pRoot->clipList) && !RegionBroken(&pRoot->borderClip)) {
488*4882a593Smuzhiyun // fixme this might not work, but hopefully doesn't happen anyway.
489*4882a593Smuzhiyun kind = VTBroken;
490*4882a593Smuzhiyun RegionNull(&pRoot->clipList);
491*4882a593Smuzhiyun ErrorF("ValidateTree: BUSTED!\n");
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /*
495*4882a593Smuzhiyun * Recursively compute the clips for all children of the root.
496*4882a593Smuzhiyun * They don't clip against each other or the root itself, so
497*4882a593Smuzhiyun * childClip is always reset to that child's size.
498*4882a593Smuzhiyun */
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) {
501*4882a593Smuzhiyun if (pWin->viewable) {
502*4882a593Smuzhiyun if (pWin->valdata) {
503*4882a593Smuzhiyun RegionCopy(&childClip, &pWin->borderSize);
504*4882a593Smuzhiyun RootlessComputeClips(pWin, pScreen, &childClip, kind, &exposed);
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun else if (pWin->visibility == VisibilityNotViewable) {
507*4882a593Smuzhiyun RootlessTreeObscured(pWin);
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun else {
511*4882a593Smuzhiyun if (pWin->valdata) {
512*4882a593Smuzhiyun RegionEmpty(&pWin->clipList);
513*4882a593Smuzhiyun if (pScreen->ClipNotify)
514*4882a593Smuzhiyun (*pScreen->ClipNotify) (pWin, 0, 0);
515*4882a593Smuzhiyun RegionEmpty(&pWin->borderClip);
516*4882a593Smuzhiyun pWin->valdata = NULL;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun RegionUninit(&childClip);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun /* The root is never clipped by its children, so nothing on the root
524*4882a593Smuzhiyun is ever exposed by moving or mapping its children. */
525*4882a593Smuzhiyun RegionNull(&pRoot->valdata->after.exposed);
526*4882a593Smuzhiyun RegionNull(&pRoot->valdata->after.borderExposed);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun return 1;
529*4882a593Smuzhiyun }
530