1 /***********************************************************
3 Copyright (c) 1987 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
31 Permission to use, copy, modify, and distribute this software and its
32 documentation for any purpose and without fee is hereby granted,
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 ******************************************************************/
48 /* $XConsortium: miwindow.c,v 5.16 94/04/17 20:28:03 dpw Exp $ */
50 #include "miscstruct.h"
53 #include "windowstr.h"
54 #include "scrnintstr.h"
55 #include "pixmapstr.h"
56 #include "mivalidate.h"
59 miClearToBackground(pWin, x, y, w, h, generateExposures)
63 Bool generateExposures;
67 RegionPtr pBSReg = NullRegion;
72 /* compute everything using ints to avoid overflow */
74 x1 = pWin->drawable.x + x;
75 y1 = pWin->drawable.y + y;
79 x2 = x1 + (int) pWin->drawable.width - (int) x;
83 y2 = y1 + (int) pWin->drawable.height - (int) y;
85 extents = &pWin->clipList.extents;
87 /* clip the resulting rectangle to the window clipList extents. This
88 * makes sure that the result will fit in a box, given that the
89 * screen is < 32768 on a side.
101 if (x2 <= x1 || y2 <= y1)
112 pScreen = pWin->drawable.pScreen;
113 REGION_INIT(pScreen, ®, &box, 1);
114 if (pWin->backStorage)
117 * If the window has backing-store on, call through the
118 * ClearToBackground vector to handle the special semantics
119 * (i.e. things backing store is to be cleared out and
120 * an Expose event is to be generated for those areas in backing
121 * store if generateExposures is TRUE).
123 pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
127 REGION_INTERSECT(pScreen, ®, ®, &pWin->clipList);
128 if (generateExposures)
129 (*pScreen->WindowExposures)(pWin, ®, pBSReg);
130 else if (pWin->backgroundState != None)
131 (*pScreen->PaintWindowBackground)(pWin, ®, PW_BACKGROUND);
132 REGION_UNINIT(pScreen, ®);
134 REGION_DESTROY(pScreen, pBSReg);
138 * For SaveUnders using backing-store. The idea is that when a window is mapped
139 * with saveUnder set TRUE, any windows it obscures will have its backing
140 * store turned on setting the DIXsaveUnder bit,
141 * The backing-store code must be written to allow for this
145 *-----------------------------------------------------------------------
146 * miCheckSubSaveUnder --
147 * Check all the inferiors of a window for coverage by saveUnder
148 * windows. Called from ChangeSaveUnder and CheckSaveUnder.
149 * This code is very inefficient.
152 * TRUE if any windows need to have backing-store removed.
155 * Windows may have backing-store turned on or off.
157 *-----------------------------------------------------------------------
160 miCheckSubSaveUnder(pParent, pFirst, pRegion)
161 register WindowPtr pParent; /* Parent to check */
162 WindowPtr pFirst; /* first reconfigured window */
163 RegionPtr pRegion; /* Initial area obscured by saveUnder */
165 register WindowPtr pChild; /* Current child */
166 register ScreenPtr pScreen; /* Screen to use */
167 RegionRec SubRegion; /* Area of children obscured */
168 Bool res = FALSE; /* result */
169 Bool subInited=FALSE;/* SubRegion initialized */
171 pScreen = pParent->drawable.pScreen;
172 if ( (pChild = pParent->firstChild) )
175 * build region above first changed window
178 for (; pChild != pFirst; pChild = pChild->nextSib)
179 if (pChild->viewable && pChild->saveUnder)
180 REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
183 * check region below and including first changed window
186 for (; pChild; pChild = pChild->nextSib)
188 if (pChild->viewable)
191 * don't save under nephew/niece windows;
192 * use a separate region
195 if (pChild->firstChild)
199 REGION_INIT(pScreen, &SubRegion, NullBox, 0);
202 REGION_COPY(pScreen, &SubRegion, pRegion);
203 res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
208 res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
212 if (pChild->saveUnder)
213 REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
218 REGION_UNINIT(pScreen, &SubRegion);
222 * Check the state of this window. DIX save unders are
223 * enabled for viewable windows with some client expressing
224 * exposure interest and which intersect the save under region
227 if (pParent->viewable &&
228 ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
229 REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
230 RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen,
231 &pParent->borderSize)) != rgnOUT)
233 if (!pParent->DIXsaveUnder)
235 pParent->DIXsaveUnder = TRUE;
236 (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
241 if (pParent->DIXsaveUnder)
244 pParent->DIXsaveUnder = FALSE;
252 *-----------------------------------------------------------------------
253 * miChangeSaveUnder --
254 * Change the save-under state of a tree of windows. Called when
255 * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
258 * TRUE if any windows need to have backing-store removed (which
259 * means that PostChangeSaveUnder needs to be called later to
263 * Windows may have backing-store turned on or off.
265 *-----------------------------------------------------------------------
268 miChangeSaveUnder(pWin, first)
269 register WindowPtr pWin;
270 WindowPtr first; /* First window to check.
271 * Used when pWin was restacked */
273 RegionRec rgn; /* Area obscured by saveUnder windows */
274 register ScreenPtr pScreen;
277 if (!deltaSaveUndersViewable && !numSaveUndersViewable)
279 numSaveUndersViewable += deltaSaveUndersViewable;
280 deltaSaveUndersViewable = 0;
281 pScreen = pWin->drawable.pScreen;
282 REGION_INIT(pScreen, &rgn, NullBox, 1);
283 res = miCheckSubSaveUnder (pWin->parent,
284 pWin->saveUnder ? first : pWin->nextSib,
286 REGION_UNINIT(pScreen, &rgn);
291 *-----------------------------------------------------------------------
292 * miPostChangeSaveUnder --
293 * Actually turn backing-store off for those windows that no longer
294 * need to have it on.
300 * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
303 *-----------------------------------------------------------------------
306 miPostChangeSaveUnder(pWin, pFirst)
310 register WindowPtr pParent, pChild;
311 ChangeWindowAttributesProcPtr ChangeWindowAttributes;
313 if (!(pParent = pWin->parent))
315 ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
316 if (!pParent->DIXsaveUnder &&
317 (pParent->backingStore == NotUseful) && pParent->backStorage)
318 (*ChangeWindowAttributes)(pParent, CWBackingStore);
319 if (!(pChild = pFirst))
323 if (!pChild->DIXsaveUnder &&
324 (pChild->backingStore == NotUseful) && pChild->backStorage)
325 (*ChangeWindowAttributes)(pChild, CWBackingStore);
326 if (pChild->firstChild)
328 pChild = pChild->firstChild;
331 while (!pChild->nextSib)
333 pChild = pChild->parent;
334 if (pChild == pParent)
337 pChild = pChild->nextSib;
343 register WindowPtr pWin;
345 register ValidatePtr val;
349 val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
350 val->before.oldAbsCorner.x = pWin->drawable.x;
351 val->before.oldAbsCorner.y = pWin->drawable.y;
352 val->before.borderVisible = NullRegion;
353 val->before.resized = FALSE;
358 miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
361 WindowPtr *ppLayerWin;
364 register WindowPtr pChild, pLast;
365 Bool anyMarked = FALSE;
366 void (* MarkWindow)() = pWin->drawable.pScreen->MarkWindow;
367 ScreenPtr pScreen = pWin->drawable.pScreen;
369 /* single layered systems are easy */
370 if (ppLayerWin) *ppLayerWin = pWin;
374 /* Blindly mark pWin and all of its inferiors. This is a slight
375 * overkill if there are mapped windows that outside pWin's border,
376 * but it's better than wasting time on RectIn checks.
381 if (pChild->viewable)
383 (* MarkWindow)(pChild);
384 if (pChild->firstChild)
386 pChild = pChild->firstChild;
390 while (!pChild->nextSib && (pChild != pWin))
391 pChild = pChild->parent;
394 pChild = pChild->nextSib;
397 pFirst = pFirst->nextSib;
399 if ( (pChild = pFirst) )
401 box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
402 pLast = pChild->parent->lastChild;
405 if (pChild->viewable && RECT_IN_REGION(pScreen, &pChild->borderSize,
408 (* MarkWindow)(pChild);
410 if (pChild->firstChild)
412 pChild = pChild->firstChild;
416 while (!pChild->nextSib && (pChild != pLast))
417 pChild = pChild->parent;
420 pChild = pChild->nextSib;
424 (* MarkWindow)(pWin->parent);
429 * miHandleValidateExposures(pWin)
430 * starting at pWin, draw background in any windows that have exposure
431 * regions, translate the regions, restore any backing store,
432 * and then send any regions still exposed to the client
435 miHandleValidateExposures(pWin)
438 register WindowPtr pChild;
439 register ValidatePtr val;
440 ScreenPtr pScreen = pWin->drawable.pScreen;
441 void (* WindowExposures)();
444 WindowExposures = pChild->drawable.pScreen->WindowExposures;
447 if ( (val = pChild->valdata) )
449 if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
450 (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
451 &val->after.borderExposed,
453 REGION_UNINIT(pScreen, &val->after.borderExposed);
454 (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
455 REGION_UNINIT(pScreen, &val->after.exposed);
457 pChild->valdata = (ValidatePtr)NULL;
458 if (pChild->firstChild)
460 pChild = pChild->firstChild;
464 while (!pChild->nextSib && (pChild != pWin))
465 pChild = pChild->parent;
468 pChild = pChild->nextSib;
473 miMoveWindow(pWin, x, y, pNextSib, kind)
474 register WindowPtr pWin;
480 Bool WasViewable = (Bool)(pWin->viewable);
485 register ScreenPtr pScreen;
486 WindowPtr windowToValidate;
487 #ifdef DO_SAVE_UNDERS
492 /* if this is a root window, can't be moved */
493 if (!(pParent = pWin->parent))
495 pScreen = pWin->drawable.pScreen;
496 bw = wBorderWidth (pWin);
498 oldpt.x = pWin->drawable.x;
499 oldpt.y = pWin->drawable.y;
502 oldRegion = REGION_CREATE(pScreen, NullBox, 1);
503 REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
504 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
506 pWin->origin.x = x + (int)bw;
507 pWin->origin.y = y + (int)bw;
508 x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
509 y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
512 SetBorderSize (pWin);
514 (*pScreen->PositionWindow)(pWin, x, y);
516 windowToValidate = MoveWindowInStack(pWin, pNextSib);
518 ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
522 if (pLayerWin == pWin)
523 anyMarked |= (*pScreen->MarkOverlappedWindows)
524 (pWin, windowToValidate, (WindowPtr *)NULL);
526 anyMarked |= (*pScreen->MarkOverlappedWindows)
527 (pWin, pLayerWin, (WindowPtr *)NULL);
529 #ifdef DO_SAVE_UNDERS
530 if (DO_SAVE_UNDERS(pWin))
532 dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
534 #endif /* DO_SAVE_UNDERS */
538 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
539 (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
540 REGION_DESTROY(pScreen, oldRegion);
541 /* XXX need to retile border if ParentRelative origin */
542 (*pScreen->HandleExposures)(pLayerWin->parent);
544 #ifdef DO_SAVE_UNDERS
546 (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
547 #endif /* DO_SAVE_UNDERS */
548 if (anyMarked && pScreen->PostValidateTree)
549 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
552 WindowsRestructured ();
557 * pValid is a region of the screen which has been
558 * successfully copied -- recomputed exposed regions for affected windows
562 miRecomputeExposures (pWin, value)
563 register WindowPtr pWin;
564 pointer value; /* must conform to VisitWindowProcPtr */
566 register ScreenPtr pScreen;
567 RegionPtr pValid = (RegionPtr)value;
571 pScreen = pWin->drawable.pScreen;
573 * compute exposed regions of this window
575 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
576 &pWin->clipList, pValid);
578 * compute exposed regions of the border
580 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
581 &pWin->borderClip, &pWin->winSize);
582 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
583 &pWin->valdata->after.borderExposed, pValid);
584 return WT_WALKCHILDREN;
590 miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
591 register WindowPtr pWin;
597 Bool WasViewable = (Bool)(pWin->viewable);
598 unsigned short width = pWin->drawable.width,
599 height = pWin->drawable.height;
600 short oldx = pWin->drawable.x,
601 oldy = pWin->drawable.y;
602 int bw = wBorderWidth (pWin);
607 register ScreenPtr pScreen;
608 WindowPtr pFirstChange;
609 register WindowPtr pChild;
610 RegionPtr gravitate[StaticGravity + 1];
612 int nx, ny; /* destination x,y */
613 int newx, newy; /* new inner window position */
615 RegionPtr destClip; /* portions of destination already written */
616 RegionPtr oldWinClip; /* old clip list for window */
617 RegionPtr borderVisible = NullRegion; /* visible area of the border */
618 RegionPtr bsExposed = NullRegion; /* backing store exposures */
619 Bool shrunk = FALSE; /* shrunk in an inner dimension */
620 Bool moved = FALSE; /* window position changed */
621 #ifdef DO_SAVE_UNDERS
626 /* if this is a root window, can't be resized */
627 if (!(pParent = pWin->parent))
630 pScreen = pWin->drawable.pScreen;
631 newx = pParent->drawable.x + x + bw;
632 newy = pParent->drawable.y + y + bw;
637 * save the visible region of the window
639 oldRegion = REGION_CREATE(pScreen, NullBox, 1);
640 REGION_COPY(pScreen, oldRegion, &pWin->winSize);
643 * categorize child windows into regions to be moved
645 for (g = 0; g <= StaticGravity; g++)
646 gravitate[g] = (RegionPtr) NULL;
647 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
649 g = pChild->winGravity;
650 if (g != UnmapGravity)
653 gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
654 REGION_UNION(pScreen, gravitate[g],
655 gravitate[g], &pChild->borderClip);
659 UnmapWindow(pChild, TRUE);
663 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
667 if (pWin->bitGravity != ForgetGravity)
669 oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
670 REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
673 * if the window is changing size, borderExposed
674 * can't be computed correctly without some help.
676 if (pWin->drawable.height > h || pWin->drawable.width > w)
679 if (newx != oldx || newy != oldy)
682 if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
685 borderVisible = REGION_CREATE(pScreen, NullBox, 1);
686 /* for tiled borders, we punt and draw the whole thing */
687 if (pWin->borderIsPixel || !moved)
690 REGION_SUBTRACT(pScreen, borderVisible,
694 REGION_COPY(pScreen, borderVisible,
699 pWin->origin.x = x + bw;
700 pWin->origin.y = y + bw;
701 pWin->drawable.height = h;
702 pWin->drawable.width = w;
704 x = pWin->drawable.x = newx;
705 y = pWin->drawable.y = newy;
708 SetBorderSize (pWin);
710 dw = (int)w - (int)width;
711 dh = (int)h - (int)height;
712 ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
714 /* let the hardware adjust background and border pixmaps, if any */
715 (*pScreen->PositionWindow)(pWin, x, y);
717 pFirstChange = MoveWindowInStack(pWin, pSib);
721 pRegion = REGION_CREATE(pScreen, NullBox, 1);
722 if (pWin->backStorage)
723 REGION_COPY(pScreen, pRegion, &pWin->clipList);
725 if (pLayerWin == pWin)
726 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
729 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
734 pWin->valdata->before.resized = TRUE;
735 pWin->valdata->before.borderVisible = borderVisible;
738 #ifdef DO_SAVE_UNDERS
739 if (DO_SAVE_UNDERS(pWin))
741 dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
743 #endif /* DO_SAVE_UNDERS */
746 (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
748 * the entire window is trashed unless bitGravity
749 * recovers portions of it
751 REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
754 GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
756 if (pWin->backStorage &&
757 ((pWin->backingStore == Always) || WasViewable))
760 pRegion = &pWin->clipList; /* a convenient empty region */
761 if (pWin->bitGravity == ForgetGravity)
762 bsExposed = (*pScreen->TranslateBackingStore)
763 (pWin, 0, 0, NullRegion, oldx, oldy);
766 bsExposed = (*pScreen->TranslateBackingStore)
767 (pWin, nx - x, ny - y, pRegion, oldx, oldy);
773 /* avoid the border */
774 if (HasBorder (pWin))
776 int offx, offy, dx, dy;
778 /* kruft to avoid double translates for each gravity */
781 for (g = 0; g <= StaticGravity; g++)
786 /* align winSize to gravitate[g].
787 * winSize is in new coordinates,
788 * gravitate[g] is still in old coordinates */
789 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
791 dx = (oldx - nx) - offx;
792 dy = (oldy - ny) - offy;
795 REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
799 REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
802 /* get winSize back where it belongs */
804 REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
807 * add screen bits to the appropriate bucket
813 * clip to new clipList
815 REGION_COPY(pScreen, pRegion, oldWinClip);
816 REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
817 REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
819 * don't step on any gravity bits which will be copied after this
820 * region. Note -- this assumes that the regions will be copied
823 for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
826 REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
829 REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
830 g = pWin->bitGravity;
832 gravitate[g] = oldWinClip;
835 REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
836 REGION_DESTROY(pScreen, oldWinClip);
841 * move the bits on the screen
846 for (g = 0; g <= StaticGravity; g++)
851 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
853 oldpt.x = oldx + (x - nx);
854 oldpt.y = oldy + (y - ny);
856 /* Note that gravitate[g] is *translated* by CopyWindow */
858 /* only copy the remaining useful bits */
860 REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
862 /* clip to not overwrite already copied areas */
865 REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
866 REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
867 REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
870 /* and move those bits */
872 if (oldpt.x != x || oldpt.y != y)
873 (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
875 /* remove any overwritten bits from the remaining useful bits */
877 REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
880 * recompute exposed regions of child windows
883 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
885 if (pChild->winGravity != g)
887 REGION_INTERSECT(pScreen, pRegion,
888 &pChild->borderClip, gravitate[g]);
889 TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
893 * remove the successfully copied regions of the
894 * window from its exposed region
897 if (g == pWin->bitGravity)
898 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
899 &pWin->valdata->after.exposed, gravitate[g]);
901 destClip = gravitate[g];
904 REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
905 REGION_DESTROY(pScreen, gravitate[g]);
909 REGION_DESTROY(pScreen, oldRegion);
910 REGION_DESTROY(pScreen, pRegion);
912 REGION_DESTROY(pScreen, destClip);
915 RegionPtr valExposed = NullRegion;
918 valExposed = &pWin->valdata->after.exposed;
919 (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
921 REGION_EMPTY(pScreen, valExposed);
922 REGION_DESTROY(pScreen, bsExposed);
925 (*pScreen->HandleExposures)(pLayerWin->parent);
926 #ifdef DO_SAVE_UNDERS
929 (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
931 #endif /* DO_SAVE_UNDERS */
932 if (anyMarked && pScreen->PostValidateTree)
933 (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
938 (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
939 REGION_DESTROY(pScreen, bsExposed);
942 WindowsRestructured ();
946 miGetLayerWindow(pWin)
949 return pWin->firstChild;
956 * The border/window shape has changed. Recompute winSize/borderSize
957 * and send appropriate exposure events
962 register WindowPtr pWin;
964 Bool WasViewable = (Bool)(pWin->viewable);
965 register ScreenPtr pScreen = pWin->drawable.pScreen;
967 WindowPtr pParent = pWin->parent;
968 RegionPtr pOldClip, bsExposed;
969 #ifdef DO_SAVE_UNDERS
976 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
980 if (HasBorder (pWin))
982 RegionPtr borderVisible;
984 borderVisible = REGION_CREATE(pScreen, NullBox, 1);
985 REGION_SUBTRACT(pScreen, borderVisible,
986 &pWin->borderClip, &pWin->winSize);
987 pWin->valdata->before.borderVisible = borderVisible;
989 pWin->valdata->before.resized = TRUE;
994 SetBorderSize (pWin);
996 ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
1000 if (pWin->backStorage)
1002 pOldClip = REGION_CREATE(pScreen, NullBox, 1);
1003 REGION_COPY(pScreen, pOldClip, &pWin->clipList);
1006 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
1009 #ifdef DO_SAVE_UNDERS
1010 if (DO_SAVE_UNDERS(pWin))
1012 dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
1014 #endif /* DO_SAVE_UNDERS */
1017 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
1020 if (pWin->backStorage &&
1021 ((pWin->backingStore == Always) || WasViewable))
1024 pOldClip = &pWin->clipList; /* a convenient empty region */
1025 bsExposed = (*pScreen->TranslateBackingStore)
1026 (pWin, 0, 0, pOldClip,
1027 pWin->drawable.x, pWin->drawable.y);
1029 REGION_DESTROY(pScreen, pOldClip);
1032 RegionPtr valExposed = NullRegion;
1035 valExposed = &pWin->valdata->after.exposed;
1036 (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
1038 REGION_EMPTY(pScreen, valExposed);
1039 REGION_DESTROY(pScreen, bsExposed);
1045 (*pScreen->HandleExposures)(pLayerWin->parent);
1046 #ifdef DO_SAVE_UNDERS
1048 (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
1049 #endif /* DO_SAVE_UNDERS */
1050 if (anyMarked && pScreen->PostValidateTree)
1051 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
1054 WindowsRestructured ();
1055 CheckCursorConfinement(pWin);
1059 /* Keeps the same inside(!) origin */
1062 miChangeBorderWidth(pWin, width)
1063 register WindowPtr pWin;
1069 register ScreenPtr pScreen;
1070 Bool WasViewable = (Bool)(pWin->viewable);
1072 #ifdef DO_SAVE_UNDERS
1073 Bool dosave = FALSE;
1075 WindowPtr pLayerWin;
1077 oldwidth = wBorderWidth (pWin);
1078 if (oldwidth == width)
1080 HadBorder = HasBorder(pWin);
1081 pScreen = pWin->drawable.pScreen;
1082 pParent = pWin->parent;
1083 if (WasViewable && width < oldwidth)
1084 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
1086 pWin->borderWidth = width;
1087 SetBorderSize (pWin);
1091 if (width > oldwidth)
1093 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
1096 * save the old border visible region to correctly compute
1099 if (pWin->valdata && HadBorder)
1101 RegionPtr borderVisible;
1102 borderVisible = REGION_CREATE(pScreen, NULL, 1);
1103 REGION_SUBTRACT(pScreen, borderVisible,
1104 &pWin->borderClip, &pWin->winSize);
1105 pWin->valdata->before.borderVisible = borderVisible;
1108 #ifdef DO_SAVE_UNDERS
1109 if (DO_SAVE_UNDERS(pWin))
1111 dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
1113 #endif /* DO_SAVE_UNDERS */
1117 (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
1118 (*pScreen->HandleExposures)(pLayerWin->parent);
1120 #ifdef DO_SAVE_UNDERS
1122 (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
1123 #endif /* DO_SAVE_UNDERS */
1124 if (anyMarked && pScreen->PostValidateTree)
1125 (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
1129 WindowsRestructured ();
1133 miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
1138 if ((pChild != pWin) || fromConfigure)
1140 REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
1141 if (pChild->drawable.pScreen->ClipNotify)
1142 (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
1143 REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);