xref: /OK3568_Linux_fs/external/xserver/mi/miwindow.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun 
2*4882a593Smuzhiyun /***********************************************************
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun Copyright 1987, 1998  The Open Group
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
7*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
8*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
9*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
10*4882a593Smuzhiyun documentation.
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
13*4882a593Smuzhiyun all copies or substantial portions of the Software.
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
23*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
24*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun                         All Rights Reserved
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this software and its
31*4882a593Smuzhiyun documentation for any purpose and without fee is hereby granted,
32*4882a593Smuzhiyun provided that the above copyright notice appear in all copies and that
33*4882a593Smuzhiyun both that copyright notice and this permission notice appear in
34*4882a593Smuzhiyun supporting documentation, and that the name of Digital not be
35*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution of the
36*4882a593Smuzhiyun software without specific, written prior permission.
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39*4882a593Smuzhiyun ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40*4882a593Smuzhiyun DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41*4882a593Smuzhiyun ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43*4882a593Smuzhiyun ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44*4882a593Smuzhiyun SOFTWARE.
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun ******************************************************************/
47*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
48*4882a593Smuzhiyun #include <dix-config.h>
49*4882a593Smuzhiyun #endif
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #include <X11/X.h>
52*4882a593Smuzhiyun #include <X11/extensions/shapeconst.h>
53*4882a593Smuzhiyun #include "regionstr.h"
54*4882a593Smuzhiyun #include "region.h"
55*4882a593Smuzhiyun #include "mi.h"
56*4882a593Smuzhiyun #include "windowstr.h"
57*4882a593Smuzhiyun #include "scrnintstr.h"
58*4882a593Smuzhiyun #include "pixmapstr.h"
59*4882a593Smuzhiyun #include "mivalidate.h"
60*4882a593Smuzhiyun #include "inputstr.h"
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun void
miClearToBackground(WindowPtr pWin,int x,int y,int w,int h,Bool generateExposures)63*4882a593Smuzhiyun miClearToBackground(WindowPtr pWin,
64*4882a593Smuzhiyun                     int x, int y, int w, int h, Bool generateExposures)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun     BoxRec box;
67*4882a593Smuzhiyun     RegionRec reg;
68*4882a593Smuzhiyun     BoxPtr extents;
69*4882a593Smuzhiyun     int x1, y1, x2, y2;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun     /* compute everything using ints to avoid overflow */
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun     x1 = pWin->drawable.x + x;
74*4882a593Smuzhiyun     y1 = pWin->drawable.y + y;
75*4882a593Smuzhiyun     if (w)
76*4882a593Smuzhiyun         x2 = x1 + (int) w;
77*4882a593Smuzhiyun     else
78*4882a593Smuzhiyun         x2 = x1 + (int) pWin->drawable.width - (int) x;
79*4882a593Smuzhiyun     if (h)
80*4882a593Smuzhiyun         y2 = y1 + h;
81*4882a593Smuzhiyun     else
82*4882a593Smuzhiyun         y2 = y1 + (int) pWin->drawable.height - (int) y;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun     extents = &pWin->clipList.extents;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun     /* clip the resulting rectangle to the window clipList extents.  This
87*4882a593Smuzhiyun      * makes sure that the result will fit in a box, given that the
88*4882a593Smuzhiyun      * screen is < 32768 on a side.
89*4882a593Smuzhiyun      */
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun     if (x1 < extents->x1)
92*4882a593Smuzhiyun         x1 = extents->x1;
93*4882a593Smuzhiyun     if (x2 > extents->x2)
94*4882a593Smuzhiyun         x2 = extents->x2;
95*4882a593Smuzhiyun     if (y1 < extents->y1)
96*4882a593Smuzhiyun         y1 = extents->y1;
97*4882a593Smuzhiyun     if (y2 > extents->y2)
98*4882a593Smuzhiyun         y2 = extents->y2;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun     if (x2 <= x1 || y2 <= y1) {
101*4882a593Smuzhiyun         x2 = x1 = 0;
102*4882a593Smuzhiyun         y2 = y1 = 0;
103*4882a593Smuzhiyun     }
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun     box.x1 = x1;
106*4882a593Smuzhiyun     box.x2 = x2;
107*4882a593Smuzhiyun     box.y1 = y1;
108*4882a593Smuzhiyun     box.y2 = y2;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun     RegionInit(&reg, &box, 1);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun     RegionIntersect(&reg, &reg, &pWin->clipList);
113*4882a593Smuzhiyun     if (generateExposures)
114*4882a593Smuzhiyun         (*pWin->drawable.pScreen->WindowExposures) (pWin, &reg);
115*4882a593Smuzhiyun     else if (pWin->backgroundState != None)
116*4882a593Smuzhiyun         pWin->drawable.pScreen->PaintWindow(pWin, &reg, PW_BACKGROUND);
117*4882a593Smuzhiyun     RegionUninit(&reg);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun void
miMarkWindow(WindowPtr pWin)121*4882a593Smuzhiyun miMarkWindow(WindowPtr pWin)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun     ValidatePtr val;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun     if (pWin->valdata)
126*4882a593Smuzhiyun         return;
127*4882a593Smuzhiyun     val = (ValidatePtr) xnfalloc(sizeof(ValidateRec));
128*4882a593Smuzhiyun     val->before.oldAbsCorner.x = pWin->drawable.x;
129*4882a593Smuzhiyun     val->before.oldAbsCorner.y = pWin->drawable.y;
130*4882a593Smuzhiyun     val->before.borderVisible = NullRegion;
131*4882a593Smuzhiyun     val->before.resized = FALSE;
132*4882a593Smuzhiyun     pWin->valdata = val;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun Bool
miMarkOverlappedWindows(WindowPtr pWin,WindowPtr pFirst,WindowPtr * ppLayerWin)136*4882a593Smuzhiyun miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun     BoxPtr box;
139*4882a593Smuzhiyun     WindowPtr pChild, pLast;
140*4882a593Smuzhiyun     Bool anyMarked = FALSE;
141*4882a593Smuzhiyun     MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun     /* single layered systems are easy */
144*4882a593Smuzhiyun     if (ppLayerWin)
145*4882a593Smuzhiyun         *ppLayerWin = pWin;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun     if (pWin == pFirst) {
148*4882a593Smuzhiyun         /* Blindly mark pWin and all of its inferiors.   This is a slight
149*4882a593Smuzhiyun          * overkill if there are mapped windows that outside pWin's border,
150*4882a593Smuzhiyun          * but it's better than wasting time on RectIn checks.
151*4882a593Smuzhiyun          */
152*4882a593Smuzhiyun         pChild = pWin;
153*4882a593Smuzhiyun         while (1) {
154*4882a593Smuzhiyun             if (pChild->viewable) {
155*4882a593Smuzhiyun                 if (RegionBroken(&pChild->winSize))
156*4882a593Smuzhiyun                     SetWinSize(pChild);
157*4882a593Smuzhiyun                 if (RegionBroken(&pChild->borderSize))
158*4882a593Smuzhiyun                     SetBorderSize(pChild);
159*4882a593Smuzhiyun                 (*MarkWindow) (pChild);
160*4882a593Smuzhiyun                 if (pChild->firstChild) {
161*4882a593Smuzhiyun                     pChild = pChild->firstChild;
162*4882a593Smuzhiyun                     continue;
163*4882a593Smuzhiyun                 }
164*4882a593Smuzhiyun             }
165*4882a593Smuzhiyun             while (!pChild->nextSib && (pChild != pWin))
166*4882a593Smuzhiyun                 pChild = pChild->parent;
167*4882a593Smuzhiyun             if (pChild == pWin)
168*4882a593Smuzhiyun                 break;
169*4882a593Smuzhiyun             pChild = pChild->nextSib;
170*4882a593Smuzhiyun         }
171*4882a593Smuzhiyun         anyMarked = TRUE;
172*4882a593Smuzhiyun         pFirst = pFirst->nextSib;
173*4882a593Smuzhiyun     }
174*4882a593Smuzhiyun     if ((pChild = pFirst)) {
175*4882a593Smuzhiyun         box = RegionExtents(&pWin->borderSize);
176*4882a593Smuzhiyun         pLast = pChild->parent->lastChild;
177*4882a593Smuzhiyun         while (1) {
178*4882a593Smuzhiyun             if (pChild->viewable) {
179*4882a593Smuzhiyun                 if (RegionBroken(&pChild->winSize))
180*4882a593Smuzhiyun                     SetWinSize(pChild);
181*4882a593Smuzhiyun                 if (RegionBroken(&pChild->borderSize))
182*4882a593Smuzhiyun                     SetBorderSize(pChild);
183*4882a593Smuzhiyun                 if (RegionContainsRect(&pChild->borderSize, box)) {
184*4882a593Smuzhiyun                     (*MarkWindow) (pChild);
185*4882a593Smuzhiyun                     anyMarked = TRUE;
186*4882a593Smuzhiyun                     if (pChild->firstChild) {
187*4882a593Smuzhiyun                         pChild = pChild->firstChild;
188*4882a593Smuzhiyun                         continue;
189*4882a593Smuzhiyun                     }
190*4882a593Smuzhiyun                 }
191*4882a593Smuzhiyun             }
192*4882a593Smuzhiyun             while (!pChild->nextSib && (pChild != pLast))
193*4882a593Smuzhiyun                 pChild = pChild->parent;
194*4882a593Smuzhiyun             if (pChild == pLast)
195*4882a593Smuzhiyun                 break;
196*4882a593Smuzhiyun             pChild = pChild->nextSib;
197*4882a593Smuzhiyun         }
198*4882a593Smuzhiyun     }
199*4882a593Smuzhiyun     if (anyMarked)
200*4882a593Smuzhiyun         (*MarkWindow) (pWin->parent);
201*4882a593Smuzhiyun     return anyMarked;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun /*****
205*4882a593Smuzhiyun  *  miHandleValidateExposures(pWin)
206*4882a593Smuzhiyun  *    starting at pWin, draw background in any windows that have exposure
207*4882a593Smuzhiyun  *    regions, translate the regions, restore any backing store,
208*4882a593Smuzhiyun  *    and then send any regions still exposed to the client
209*4882a593Smuzhiyun  *****/
210*4882a593Smuzhiyun void
miHandleValidateExposures(WindowPtr pWin)211*4882a593Smuzhiyun miHandleValidateExposures(WindowPtr pWin)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun     WindowPtr pChild;
214*4882a593Smuzhiyun     ValidatePtr val;
215*4882a593Smuzhiyun     WindowExposuresProcPtr WindowExposures;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun     pChild = pWin;
218*4882a593Smuzhiyun     WindowExposures = pChild->drawable.pScreen->WindowExposures;
219*4882a593Smuzhiyun     while (1) {
220*4882a593Smuzhiyun         if ((val = pChild->valdata)) {
221*4882a593Smuzhiyun             if (RegionNotEmpty(&val->after.borderExposed))
222*4882a593Smuzhiyun                 pWin->drawable.pScreen->PaintWindow(pChild,
223*4882a593Smuzhiyun                                                     &val->after.borderExposed,
224*4882a593Smuzhiyun                                                     PW_BORDER);
225*4882a593Smuzhiyun             RegionUninit(&val->after.borderExposed);
226*4882a593Smuzhiyun             (*WindowExposures) (pChild, &val->after.exposed);
227*4882a593Smuzhiyun             RegionUninit(&val->after.exposed);
228*4882a593Smuzhiyun             free(val);
229*4882a593Smuzhiyun             pChild->valdata = NULL;
230*4882a593Smuzhiyun             if (pChild->firstChild) {
231*4882a593Smuzhiyun                 pChild = pChild->firstChild;
232*4882a593Smuzhiyun                 continue;
233*4882a593Smuzhiyun             }
234*4882a593Smuzhiyun         }
235*4882a593Smuzhiyun         while (!pChild->nextSib && (pChild != pWin))
236*4882a593Smuzhiyun             pChild = pChild->parent;
237*4882a593Smuzhiyun         if (pChild == pWin)
238*4882a593Smuzhiyun             break;
239*4882a593Smuzhiyun         pChild = pChild->nextSib;
240*4882a593Smuzhiyun     }
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun void
miMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pNextSib,VTKind kind)244*4882a593Smuzhiyun miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun     WindowPtr pParent;
247*4882a593Smuzhiyun     Bool WasViewable = (Bool) (pWin->viewable);
248*4882a593Smuzhiyun     short bw;
249*4882a593Smuzhiyun     RegionPtr oldRegion = NULL;
250*4882a593Smuzhiyun     DDXPointRec oldpt;
251*4882a593Smuzhiyun     Bool anyMarked = FALSE;
252*4882a593Smuzhiyun     ScreenPtr pScreen;
253*4882a593Smuzhiyun     WindowPtr windowToValidate;
254*4882a593Smuzhiyun     WindowPtr pLayerWin;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun     /* if this is a root window, can't be moved */
257*4882a593Smuzhiyun     if (!(pParent = pWin->parent))
258*4882a593Smuzhiyun         return;
259*4882a593Smuzhiyun     pScreen = pWin->drawable.pScreen;
260*4882a593Smuzhiyun     bw = wBorderWidth(pWin);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun     oldpt.x = pWin->drawable.x;
263*4882a593Smuzhiyun     oldpt.y = pWin->drawable.y;
264*4882a593Smuzhiyun     if (WasViewable) {
265*4882a593Smuzhiyun         oldRegion = RegionCreate(NullBox, 1);
266*4882a593Smuzhiyun         RegionCopy(oldRegion, &pWin->borderClip);
267*4882a593Smuzhiyun         anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
268*4882a593Smuzhiyun     }
269*4882a593Smuzhiyun     pWin->origin.x = x + (int) bw;
270*4882a593Smuzhiyun     pWin->origin.y = y + (int) bw;
271*4882a593Smuzhiyun     x = pWin->drawable.x = pParent->drawable.x + x + (int) bw;
272*4882a593Smuzhiyun     y = pWin->drawable.y = pParent->drawable.y + y + (int) bw;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun     SetWinSize(pWin);
275*4882a593Smuzhiyun     SetBorderSize(pWin);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun     (*pScreen->PositionWindow) (pWin, x, y);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun     windowToValidate = MoveWindowInStack(pWin, pNextSib);
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun     ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun     if (WasViewable) {
284*4882a593Smuzhiyun         if (pLayerWin == pWin)
285*4882a593Smuzhiyun             anyMarked |= (*pScreen->MarkOverlappedWindows)
286*4882a593Smuzhiyun                 (pWin, windowToValidate, NULL);
287*4882a593Smuzhiyun         else
288*4882a593Smuzhiyun             anyMarked |= (*pScreen->MarkOverlappedWindows)
289*4882a593Smuzhiyun                 (pWin, pLayerWin, NULL);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun         if (anyMarked) {
292*4882a593Smuzhiyun             (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, kind);
293*4882a593Smuzhiyun             (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, oldRegion);
294*4882a593Smuzhiyun             RegionDestroy(oldRegion);
295*4882a593Smuzhiyun             /* XXX need to retile border if ParentRelative origin */
296*4882a593Smuzhiyun             (*pScreen->HandleExposures) (pLayerWin->parent);
297*4882a593Smuzhiyun             if (pScreen->PostValidateTree)
298*4882a593Smuzhiyun                 (*pScreen->PostValidateTree) (pLayerWin->parent, NULL, kind);
299*4882a593Smuzhiyun         }
300*4882a593Smuzhiyun     }
301*4882a593Smuzhiyun     if (pWin->realized)
302*4882a593Smuzhiyun         WindowsRestructured();
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun /*
306*4882a593Smuzhiyun  * pValid is a region of the screen which has been
307*4882a593Smuzhiyun  * successfully copied -- recomputed exposed regions for affected windows
308*4882a593Smuzhiyun  */
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun static int
miRecomputeExposures(WindowPtr pWin,void * value)311*4882a593Smuzhiyun miRecomputeExposures(WindowPtr pWin, void *value)
312*4882a593Smuzhiyun {                               /* must conform to VisitWindowProcPtr */
313*4882a593Smuzhiyun     RegionPtr pValid = (RegionPtr) value;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun     if (pWin->valdata) {
316*4882a593Smuzhiyun #ifdef COMPOSITE
317*4882a593Smuzhiyun         /*
318*4882a593Smuzhiyun          * Redirected windows are not affected by parent window
319*4882a593Smuzhiyun          * gravity manipulations, so don't recompute their
320*4882a593Smuzhiyun          * exposed areas here.
321*4882a593Smuzhiyun          */
322*4882a593Smuzhiyun         if (pWin->redirectDraw != RedirectDrawNone)
323*4882a593Smuzhiyun             return WT_DONTWALKCHILDREN;
324*4882a593Smuzhiyun #endif
325*4882a593Smuzhiyun         /*
326*4882a593Smuzhiyun          * compute exposed regions of this window
327*4882a593Smuzhiyun          */
328*4882a593Smuzhiyun         RegionSubtract(&pWin->valdata->after.exposed, &pWin->clipList, pValid);
329*4882a593Smuzhiyun         /*
330*4882a593Smuzhiyun          * compute exposed regions of the border
331*4882a593Smuzhiyun          */
332*4882a593Smuzhiyun         RegionSubtract(&pWin->valdata->after.borderExposed,
333*4882a593Smuzhiyun                        &pWin->borderClip, &pWin->winSize);
334*4882a593Smuzhiyun         RegionSubtract(&pWin->valdata->after.borderExposed,
335*4882a593Smuzhiyun                        &pWin->valdata->after.borderExposed, pValid);
336*4882a593Smuzhiyun         return WT_WALKCHILDREN;
337*4882a593Smuzhiyun     }
338*4882a593Smuzhiyun     return WT_NOMATCH;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun void
miResizeWindow(WindowPtr pWin,int x,int y,unsigned int w,unsigned int h,WindowPtr pSib)342*4882a593Smuzhiyun miResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h,
343*4882a593Smuzhiyun                WindowPtr pSib)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun     WindowPtr pParent;
346*4882a593Smuzhiyun     Bool WasViewable = (Bool) (pWin->viewable);
347*4882a593Smuzhiyun     unsigned short width = pWin->drawable.width, height = pWin->drawable.height;
348*4882a593Smuzhiyun     short oldx = pWin->drawable.x, oldy = pWin->drawable.y;
349*4882a593Smuzhiyun     int bw = wBorderWidth(pWin);
350*4882a593Smuzhiyun     short dw, dh;
351*4882a593Smuzhiyun     DDXPointRec oldpt;
352*4882a593Smuzhiyun     RegionPtr oldRegion = NULL;
353*4882a593Smuzhiyun     Bool anyMarked = FALSE;
354*4882a593Smuzhiyun     ScreenPtr pScreen;
355*4882a593Smuzhiyun     WindowPtr pFirstChange;
356*4882a593Smuzhiyun     WindowPtr pChild;
357*4882a593Smuzhiyun     RegionPtr gravitate[StaticGravity + 1];
358*4882a593Smuzhiyun     unsigned g;
359*4882a593Smuzhiyun     int nx, ny;                 /* destination x,y */
360*4882a593Smuzhiyun     int newx, newy;             /* new inner window position */
361*4882a593Smuzhiyun     RegionPtr pRegion = NULL;
362*4882a593Smuzhiyun     RegionPtr destClip;         /* portions of destination already written */
363*4882a593Smuzhiyun     RegionPtr oldWinClip = NULL;        /* old clip list for window */
364*4882a593Smuzhiyun     RegionPtr borderVisible = NullRegion;       /* visible area of the border */
365*4882a593Smuzhiyun     Bool shrunk = FALSE;        /* shrunk in an inner dimension */
366*4882a593Smuzhiyun     Bool moved = FALSE;         /* window position changed */
367*4882a593Smuzhiyun     WindowPtr pLayerWin;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun     /* if this is a root window, can't be resized */
370*4882a593Smuzhiyun     if (!(pParent = pWin->parent))
371*4882a593Smuzhiyun         return;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun     pScreen = pWin->drawable.pScreen;
374*4882a593Smuzhiyun     newx = pParent->drawable.x + x + bw;
375*4882a593Smuzhiyun     newy = pParent->drawable.y + y + bw;
376*4882a593Smuzhiyun     if (WasViewable) {
377*4882a593Smuzhiyun         anyMarked = FALSE;
378*4882a593Smuzhiyun         /*
379*4882a593Smuzhiyun          * save the visible region of the window
380*4882a593Smuzhiyun          */
381*4882a593Smuzhiyun         oldRegion = RegionCreate(NullBox, 1);
382*4882a593Smuzhiyun         RegionCopy(oldRegion, &pWin->winSize);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun         /*
385*4882a593Smuzhiyun          * categorize child windows into regions to be moved
386*4882a593Smuzhiyun          */
387*4882a593Smuzhiyun         for (g = 0; g <= StaticGravity; g++)
388*4882a593Smuzhiyun             gravitate[g] = (RegionPtr) NULL;
389*4882a593Smuzhiyun         for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
390*4882a593Smuzhiyun             g = pChild->winGravity;
391*4882a593Smuzhiyun             if (g != UnmapGravity) {
392*4882a593Smuzhiyun                 if (!gravitate[g])
393*4882a593Smuzhiyun                     gravitate[g] = RegionCreate(NullBox, 1);
394*4882a593Smuzhiyun                 RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip);
395*4882a593Smuzhiyun             }
396*4882a593Smuzhiyun             else {
397*4882a593Smuzhiyun                 UnmapWindow(pChild, TRUE);
398*4882a593Smuzhiyun                 anyMarked = TRUE;
399*4882a593Smuzhiyun             }
400*4882a593Smuzhiyun         }
401*4882a593Smuzhiyun         anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun         oldWinClip = NULL;
404*4882a593Smuzhiyun         if (pWin->bitGravity != ForgetGravity) {
405*4882a593Smuzhiyun             oldWinClip = RegionCreate(NullBox, 1);
406*4882a593Smuzhiyun             RegionCopy(oldWinClip, &pWin->clipList);
407*4882a593Smuzhiyun         }
408*4882a593Smuzhiyun         /*
409*4882a593Smuzhiyun          * if the window is changing size, borderExposed
410*4882a593Smuzhiyun          * can't be computed correctly without some help.
411*4882a593Smuzhiyun          */
412*4882a593Smuzhiyun         if (pWin->drawable.height > h || pWin->drawable.width > w)
413*4882a593Smuzhiyun             shrunk = TRUE;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun         if (newx != oldx || newy != oldy)
416*4882a593Smuzhiyun             moved = TRUE;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun         if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
419*4882a593Smuzhiyun             HasBorder(pWin)) {
420*4882a593Smuzhiyun             borderVisible = RegionCreate(NullBox, 1);
421*4882a593Smuzhiyun             /* for tiled borders, we punt and draw the whole thing */
422*4882a593Smuzhiyun             if (pWin->borderIsPixel || !moved) {
423*4882a593Smuzhiyun                 if (shrunk || moved)
424*4882a593Smuzhiyun                     RegionSubtract(borderVisible,
425*4882a593Smuzhiyun                                    &pWin->borderClip, &pWin->winSize);
426*4882a593Smuzhiyun                 else
427*4882a593Smuzhiyun                     RegionCopy(borderVisible, &pWin->borderClip);
428*4882a593Smuzhiyun             }
429*4882a593Smuzhiyun         }
430*4882a593Smuzhiyun     }
431*4882a593Smuzhiyun     pWin->origin.x = x + bw;
432*4882a593Smuzhiyun     pWin->origin.y = y + bw;
433*4882a593Smuzhiyun     pWin->drawable.height = h;
434*4882a593Smuzhiyun     pWin->drawable.width = w;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun     x = pWin->drawable.x = newx;
437*4882a593Smuzhiyun     y = pWin->drawable.y = newy;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun     SetWinSize(pWin);
440*4882a593Smuzhiyun     SetBorderSize(pWin);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun     dw = (int) w - (int) width;
443*4882a593Smuzhiyun     dh = (int) h - (int) height;
444*4882a593Smuzhiyun     ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun     /* let the hardware adjust background and border pixmaps, if any */
447*4882a593Smuzhiyun     (*pScreen->PositionWindow) (pWin, x, y);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun     pFirstChange = MoveWindowInStack(pWin, pSib);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun     if (WasViewable) {
452*4882a593Smuzhiyun         pRegion = RegionCreate(NullBox, 1);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun         if (pLayerWin == pWin)
455*4882a593Smuzhiyun             anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange,
456*4882a593Smuzhiyun                                                             NULL);
457*4882a593Smuzhiyun         else
458*4882a593Smuzhiyun             anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin,
459*4882a593Smuzhiyun                                                             NULL);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun         if (pWin->valdata) {
462*4882a593Smuzhiyun             pWin->valdata->before.resized = TRUE;
463*4882a593Smuzhiyun             pWin->valdata->before.borderVisible = borderVisible;
464*4882a593Smuzhiyun         }
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun         if (anyMarked)
467*4882a593Smuzhiyun             (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, VTOther);
468*4882a593Smuzhiyun         /*
469*4882a593Smuzhiyun          * the entire window is trashed unless bitGravity
470*4882a593Smuzhiyun          * recovers portions of it
471*4882a593Smuzhiyun          */
472*4882a593Smuzhiyun         RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
473*4882a593Smuzhiyun     }
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun     GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun     if (WasViewable) {
478*4882a593Smuzhiyun         /* avoid the border */
479*4882a593Smuzhiyun         if (HasBorder(pWin)) {
480*4882a593Smuzhiyun             int offx, offy, dx, dy;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun             /* kruft to avoid double translates for each gravity */
483*4882a593Smuzhiyun             offx = 0;
484*4882a593Smuzhiyun             offy = 0;
485*4882a593Smuzhiyun             for (g = 0; g <= StaticGravity; g++) {
486*4882a593Smuzhiyun                 if (!gravitate[g])
487*4882a593Smuzhiyun                     continue;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun                 /* align winSize to gravitate[g].
490*4882a593Smuzhiyun                  * winSize is in new coordinates,
491*4882a593Smuzhiyun                  * gravitate[g] is still in old coordinates */
492*4882a593Smuzhiyun                 GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun                 dx = (oldx - nx) - offx;
495*4882a593Smuzhiyun                 dy = (oldy - ny) - offy;
496*4882a593Smuzhiyun                 if (dx || dy) {
497*4882a593Smuzhiyun                     RegionTranslate(&pWin->winSize, dx, dy);
498*4882a593Smuzhiyun                     offx += dx;
499*4882a593Smuzhiyun                     offy += dy;
500*4882a593Smuzhiyun                 }
501*4882a593Smuzhiyun                 RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize);
502*4882a593Smuzhiyun             }
503*4882a593Smuzhiyun             /* get winSize back where it belongs */
504*4882a593Smuzhiyun             if (offx || offy)
505*4882a593Smuzhiyun                 RegionTranslate(&pWin->winSize, -offx, -offy);
506*4882a593Smuzhiyun         }
507*4882a593Smuzhiyun         /*
508*4882a593Smuzhiyun          * add screen bits to the appropriate bucket
509*4882a593Smuzhiyun          */
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun         if (oldWinClip) {
512*4882a593Smuzhiyun             /*
513*4882a593Smuzhiyun              * clip to new clipList
514*4882a593Smuzhiyun              */
515*4882a593Smuzhiyun             RegionCopy(pRegion, oldWinClip);
516*4882a593Smuzhiyun             RegionTranslate(pRegion, nx - oldx, ny - oldy);
517*4882a593Smuzhiyun             RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
518*4882a593Smuzhiyun             /*
519*4882a593Smuzhiyun              * don't step on any gravity bits which will be copied after this
520*4882a593Smuzhiyun              * region.  Note -- this assumes that the regions will be copied
521*4882a593Smuzhiyun              * in gravity order.
522*4882a593Smuzhiyun              */
523*4882a593Smuzhiyun             for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
524*4882a593Smuzhiyun                 if (gravitate[g])
525*4882a593Smuzhiyun                     RegionSubtract(oldWinClip, oldWinClip, gravitate[g]);
526*4882a593Smuzhiyun             }
527*4882a593Smuzhiyun             RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
528*4882a593Smuzhiyun             g = pWin->bitGravity;
529*4882a593Smuzhiyun             if (!gravitate[g])
530*4882a593Smuzhiyun                 gravitate[g] = oldWinClip;
531*4882a593Smuzhiyun             else {
532*4882a593Smuzhiyun                 RegionUnion(gravitate[g], gravitate[g], oldWinClip);
533*4882a593Smuzhiyun                 RegionDestroy(oldWinClip);
534*4882a593Smuzhiyun             }
535*4882a593Smuzhiyun         }
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun         /*
538*4882a593Smuzhiyun          * move the bits on the screen
539*4882a593Smuzhiyun          */
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun         destClip = NULL;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun         for (g = 0; g <= StaticGravity; g++) {
544*4882a593Smuzhiyun             if (!gravitate[g])
545*4882a593Smuzhiyun                 continue;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun             GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun             oldpt.x = oldx + (x - nx);
550*4882a593Smuzhiyun             oldpt.y = oldy + (y - ny);
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun             /* Note that gravitate[g] is *translated* by CopyWindow */
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun             /* only copy the remaining useful bits */
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun             RegionIntersect(gravitate[g], gravitate[g], oldRegion);
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun             /* clip to not overwrite already copied areas */
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun             if (destClip) {
561*4882a593Smuzhiyun                 RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
562*4882a593Smuzhiyun                 RegionSubtract(gravitate[g], gravitate[g], destClip);
563*4882a593Smuzhiyun                 RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
564*4882a593Smuzhiyun             }
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun             /* and move those bits */
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun             if (oldpt.x != x || oldpt.y != y
569*4882a593Smuzhiyun #ifdef COMPOSITE
570*4882a593Smuzhiyun                 || pWin->redirectDraw
571*4882a593Smuzhiyun #endif
572*4882a593Smuzhiyun                 ) {
573*4882a593Smuzhiyun                 (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt,
574*4882a593Smuzhiyun                                                        gravitate[g]);
575*4882a593Smuzhiyun             }
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun             /* remove any overwritten bits from the remaining useful bits */
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun             RegionSubtract(oldRegion, oldRegion, gravitate[g]);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun             /*
582*4882a593Smuzhiyun              * recompute exposed regions of child windows
583*4882a593Smuzhiyun              */
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun             for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
586*4882a593Smuzhiyun                 if (pChild->winGravity != g)
587*4882a593Smuzhiyun                     continue;
588*4882a593Smuzhiyun                 RegionIntersect(pRegion, &pChild->borderClip, gravitate[g]);
589*4882a593Smuzhiyun                 TraverseTree(pChild, miRecomputeExposures, (void *) pRegion);
590*4882a593Smuzhiyun             }
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun             /*
593*4882a593Smuzhiyun              * remove the successfully copied regions of the
594*4882a593Smuzhiyun              * window from its exposed region
595*4882a593Smuzhiyun              */
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun             if (g == pWin->bitGravity)
598*4882a593Smuzhiyun                 RegionSubtract(&pWin->valdata->after.exposed,
599*4882a593Smuzhiyun                                &pWin->valdata->after.exposed, gravitate[g]);
600*4882a593Smuzhiyun             if (!destClip)
601*4882a593Smuzhiyun                 destClip = gravitate[g];
602*4882a593Smuzhiyun             else {
603*4882a593Smuzhiyun                 RegionUnion(destClip, destClip, gravitate[g]);
604*4882a593Smuzhiyun                 RegionDestroy(gravitate[g]);
605*4882a593Smuzhiyun             }
606*4882a593Smuzhiyun         }
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun         RegionDestroy(oldRegion);
609*4882a593Smuzhiyun         RegionDestroy(pRegion);
610*4882a593Smuzhiyun         if (destClip)
611*4882a593Smuzhiyun             RegionDestroy(destClip);
612*4882a593Smuzhiyun         if (anyMarked) {
613*4882a593Smuzhiyun             (*pScreen->HandleExposures) (pLayerWin->parent);
614*4882a593Smuzhiyun             if (pScreen->PostValidateTree)
615*4882a593Smuzhiyun                 (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange,
616*4882a593Smuzhiyun                                               VTOther);
617*4882a593Smuzhiyun         }
618*4882a593Smuzhiyun     }
619*4882a593Smuzhiyun     if (pWin->realized)
620*4882a593Smuzhiyun         WindowsRestructured();
621*4882a593Smuzhiyun }
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun WindowPtr
miGetLayerWindow(WindowPtr pWin)624*4882a593Smuzhiyun miGetLayerWindow(WindowPtr pWin)
625*4882a593Smuzhiyun {
626*4882a593Smuzhiyun     return pWin->firstChild;
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun /******
630*4882a593Smuzhiyun  *
631*4882a593Smuzhiyun  * miSetShape
632*4882a593Smuzhiyun  *    The border/window shape has changed.  Recompute winSize/borderSize
633*4882a593Smuzhiyun  *    and send appropriate exposure events
634*4882a593Smuzhiyun  */
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun void
miSetShape(WindowPtr pWin,int kind)637*4882a593Smuzhiyun miSetShape(WindowPtr pWin, int kind)
638*4882a593Smuzhiyun {
639*4882a593Smuzhiyun     Bool WasViewable = (Bool) (pWin->viewable);
640*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
641*4882a593Smuzhiyun     Bool anyMarked = FALSE;
642*4882a593Smuzhiyun     WindowPtr pLayerWin;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun     if (kind != ShapeInput) {
645*4882a593Smuzhiyun         if (WasViewable) {
646*4882a593Smuzhiyun             anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
647*4882a593Smuzhiyun                                                            &pLayerWin);
648*4882a593Smuzhiyun             if (pWin->valdata) {
649*4882a593Smuzhiyun                 if (HasBorder(pWin)) {
650*4882a593Smuzhiyun                     RegionPtr borderVisible;
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun                     borderVisible = RegionCreate(NullBox, 1);
653*4882a593Smuzhiyun                     RegionSubtract(borderVisible,
654*4882a593Smuzhiyun                                    &pWin->borderClip, &pWin->winSize);
655*4882a593Smuzhiyun                     pWin->valdata->before.borderVisible = borderVisible;
656*4882a593Smuzhiyun                 }
657*4882a593Smuzhiyun                 pWin->valdata->before.resized = TRUE;
658*4882a593Smuzhiyun             }
659*4882a593Smuzhiyun         }
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun         SetWinSize(pWin);
662*4882a593Smuzhiyun         SetBorderSize(pWin);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun         ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun         if (WasViewable) {
667*4882a593Smuzhiyun             anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun             if (anyMarked) {
670*4882a593Smuzhiyun                 (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow,
671*4882a593Smuzhiyun                                           VTOther);
672*4882a593Smuzhiyun                 (*pScreen->HandleExposures) (pLayerWin->parent);
673*4882a593Smuzhiyun                 if (pScreen->PostValidateTree)
674*4882a593Smuzhiyun                     (*pScreen->PostValidateTree) (pLayerWin->parent, NULL,
675*4882a593Smuzhiyun                                                   VTOther);
676*4882a593Smuzhiyun             }
677*4882a593Smuzhiyun         }
678*4882a593Smuzhiyun     }
679*4882a593Smuzhiyun     if (pWin->realized)
680*4882a593Smuzhiyun         WindowsRestructured();
681*4882a593Smuzhiyun     CheckCursorConfinement(pWin);
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun /* Keeps the same inside(!) origin */
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun void
miChangeBorderWidth(WindowPtr pWin,unsigned int width)687*4882a593Smuzhiyun miChangeBorderWidth(WindowPtr pWin, unsigned int width)
688*4882a593Smuzhiyun {
689*4882a593Smuzhiyun     int oldwidth;
690*4882a593Smuzhiyun     Bool anyMarked = FALSE;
691*4882a593Smuzhiyun     ScreenPtr pScreen;
692*4882a593Smuzhiyun     Bool WasViewable = (Bool) (pWin->viewable);
693*4882a593Smuzhiyun     Bool HadBorder;
694*4882a593Smuzhiyun     WindowPtr pLayerWin;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun     oldwidth = wBorderWidth(pWin);
697*4882a593Smuzhiyun     if (oldwidth == width)
698*4882a593Smuzhiyun         return;
699*4882a593Smuzhiyun     HadBorder = HasBorder(pWin);
700*4882a593Smuzhiyun     pScreen = pWin->drawable.pScreen;
701*4882a593Smuzhiyun     if (WasViewable && width < oldwidth)
702*4882a593Smuzhiyun         anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun     pWin->borderWidth = width;
705*4882a593Smuzhiyun     SetBorderSize(pWin);
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun     if (WasViewable) {
708*4882a593Smuzhiyun         if (width > oldwidth) {
709*4882a593Smuzhiyun             anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
710*4882a593Smuzhiyun                                                            &pLayerWin);
711*4882a593Smuzhiyun             /*
712*4882a593Smuzhiyun              * save the old border visible region to correctly compute
713*4882a593Smuzhiyun              * borderExposed.
714*4882a593Smuzhiyun              */
715*4882a593Smuzhiyun             if (pWin->valdata && HadBorder) {
716*4882a593Smuzhiyun                 RegionPtr borderVisible;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun                 borderVisible = RegionCreate(NULL, 1);
719*4882a593Smuzhiyun                 RegionSubtract(borderVisible,
720*4882a593Smuzhiyun                                &pWin->borderClip, &pWin->winSize);
721*4882a593Smuzhiyun                 pWin->valdata->before.borderVisible = borderVisible;
722*4882a593Smuzhiyun             }
723*4882a593Smuzhiyun         }
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun         if (anyMarked) {
726*4882a593Smuzhiyun             (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
727*4882a593Smuzhiyun             (*pScreen->HandleExposures) (pLayerWin->parent);
728*4882a593Smuzhiyun             if (pScreen->PostValidateTree)
729*4882a593Smuzhiyun                 (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin,
730*4882a593Smuzhiyun                                               VTOther);
731*4882a593Smuzhiyun         }
732*4882a593Smuzhiyun     }
733*4882a593Smuzhiyun     if (pWin->realized)
734*4882a593Smuzhiyun         WindowsRestructured();
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun void
miMarkUnrealizedWindow(WindowPtr pChild,WindowPtr pWin,Bool fromConfigure)738*4882a593Smuzhiyun miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure)
739*4882a593Smuzhiyun {
740*4882a593Smuzhiyun     if ((pChild != pWin) || fromConfigure) {
741*4882a593Smuzhiyun         RegionEmpty(&pChild->clipList);
742*4882a593Smuzhiyun         if (pChild->drawable.pScreen->ClipNotify)
743*4882a593Smuzhiyun             (*pChild->drawable.pScreen->ClipNotify) (pChild, 0, 0);
744*4882a593Smuzhiyun         RegionEmpty(&pChild->borderClip);
745*4882a593Smuzhiyun     }
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun WindowPtr
miSpriteTrace(SpritePtr pSprite,int x,int y)749*4882a593Smuzhiyun miSpriteTrace(SpritePtr pSprite, int x, int y)
750*4882a593Smuzhiyun {
751*4882a593Smuzhiyun     WindowPtr pWin;
752*4882a593Smuzhiyun     BoxRec box;
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun     pWin = DeepestSpriteWin(pSprite)->firstChild;
755*4882a593Smuzhiyun     while (pWin) {
756*4882a593Smuzhiyun         if ((pWin->mapped) &&
757*4882a593Smuzhiyun             (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
758*4882a593Smuzhiyun             (x < pWin->drawable.x + (int) pWin->drawable.width +
759*4882a593Smuzhiyun              wBorderWidth(pWin)) &&
760*4882a593Smuzhiyun             (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
761*4882a593Smuzhiyun             (y < pWin->drawable.y + (int) pWin->drawable.height +
762*4882a593Smuzhiyun              wBorderWidth(pWin))
763*4882a593Smuzhiyun             /* When a window is shaped, a further check
764*4882a593Smuzhiyun              * is made to see if the point is inside
765*4882a593Smuzhiyun              * borderSize
766*4882a593Smuzhiyun              */
767*4882a593Smuzhiyun             && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
768*4882a593Smuzhiyun             && (!wInputShape(pWin) ||
769*4882a593Smuzhiyun                 RegionContainsPoint(wInputShape(pWin),
770*4882a593Smuzhiyun                                     x - pWin->drawable.x,
771*4882a593Smuzhiyun                                     y - pWin->drawable.y, &box))
772*4882a593Smuzhiyun             /* In rootless mode windows may be offscreen, even when
773*4882a593Smuzhiyun              * they're in X's stack. (E.g. if the native window system
774*4882a593Smuzhiyun              * implements some form of virtual desktop system).
775*4882a593Smuzhiyun              */
776*4882a593Smuzhiyun             && !pWin->unhittable) {
777*4882a593Smuzhiyun             if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
778*4882a593Smuzhiyun                 pSprite->spriteTraceSize += 10;
779*4882a593Smuzhiyun                 pSprite->spriteTrace = reallocarray(pSprite->spriteTrace,
780*4882a593Smuzhiyun                                                     pSprite->spriteTraceSize,
781*4882a593Smuzhiyun                                                     sizeof(WindowPtr));
782*4882a593Smuzhiyun             }
783*4882a593Smuzhiyun             pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
784*4882a593Smuzhiyun             pWin = pWin->firstChild;
785*4882a593Smuzhiyun         }
786*4882a593Smuzhiyun         else
787*4882a593Smuzhiyun             pWin = pWin->nextSib;
788*4882a593Smuzhiyun     }
789*4882a593Smuzhiyun     return DeepestSpriteWin(pSprite);
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun /**
793*4882a593Smuzhiyun  * Traversed from the root window to the window at the position x/y. While
794*4882a593Smuzhiyun  * traversing, it sets up the traversal history in the spriteTrace array.
795*4882a593Smuzhiyun  * After completing, the spriteTrace history is set in the following way:
796*4882a593Smuzhiyun  *   spriteTrace[0] ... root window
797*4882a593Smuzhiyun  *   spriteTrace[1] ... top level window that encloses x/y
798*4882a593Smuzhiyun  *       ...
799*4882a593Smuzhiyun  *   spriteTrace[spriteTraceGood - 1] ... window at x/y
800*4882a593Smuzhiyun  *
801*4882a593Smuzhiyun  * @returns the window at the given coordinates.
802*4882a593Smuzhiyun  */
803*4882a593Smuzhiyun WindowPtr
miXYToWindow(ScreenPtr pScreen,SpritePtr pSprite,int x,int y)804*4882a593Smuzhiyun miXYToWindow(ScreenPtr pScreen, SpritePtr pSprite, int x, int y)
805*4882a593Smuzhiyun {
806*4882a593Smuzhiyun     pSprite->spriteTraceGood = 1;       /* root window still there */
807*4882a593Smuzhiyun     return miSpriteTrace(pSprite, x, y);
808*4882a593Smuzhiyun }
809