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(®, &box, 1);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun RegionIntersect(®, ®, &pWin->clipList);
113*4882a593Smuzhiyun if (generateExposures)
114*4882a593Smuzhiyun (*pWin->drawable.pScreen->WindowExposures) (pWin, ®);
115*4882a593Smuzhiyun else if (pWin->backgroundState != None)
116*4882a593Smuzhiyun pWin->drawable.pScreen->PaintWindow(pWin, ®, PW_BACKGROUND);
117*4882a593Smuzhiyun RegionUninit(®);
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