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