2 #ifdef HAVE_DIX_CONFIG_H
3 #include <dix-config.h>
7 #include "scrnintstr.h"
8 #include <X11/extensions/shapeproto.h>
10 #include "windowstr.h"
13 #include "regionstr.h"
15 #include "mivalidate.h"
16 #include "mioverlay.h"
23 RegionRec borderExposed
;
24 RegionPtr borderVisible
;
25 DDXPointRec oldAbsCorner
;
26 } miOverlayValDataRec
, *miOverlayValDataPtr
;
28 typedef struct _TreeRec
{
30 struct _TreeRec
*parent
;
31 struct _TreeRec
*firstChild
;
32 struct _TreeRec
*lastChild
;
33 struct _TreeRec
*prevSib
;
34 struct _TreeRec
*nextSib
;
38 miOverlayValDataPtr valdata
;
39 } miOverlayTreeRec
, *miOverlayTreePtr
;
42 miOverlayTreePtr tree
;
43 } miOverlayWindowRec
, *miOverlayWindowPtr
;
46 CloseScreenProcPtr CloseScreen
;
47 CreateWindowProcPtr CreateWindow
;
48 DestroyWindowProcPtr DestroyWindow
;
49 UnrealizeWindowProcPtr UnrealizeWindow
;
50 RealizeWindowProcPtr RealizeWindow
;
51 miOverlayTransFunc MakeTransparent
;
52 miOverlayInOverlayFunc InOverlay
;
55 } miOverlayScreenRec
, *miOverlayScreenPtr
;
57 static DevPrivateKeyRec miOverlayWindowKeyRec
;
59 #define miOverlayWindowKey (&miOverlayWindowKeyRec)
60 static DevPrivateKeyRec miOverlayScreenKeyRec
;
62 #define miOverlayScreenKey (&miOverlayScreenKeyRec)
64 static void RebuildTree(WindowPtr
);
65 static Bool
HasUnderlayChildren(WindowPtr
);
66 static void MarkUnderlayWindow(WindowPtr
);
67 static Bool
CollectUnderlayChildrenRegions(WindowPtr
, RegionPtr
);
69 static Bool
miOverlayCloseScreen(ScreenPtr
);
70 static Bool
miOverlayCreateWindow(WindowPtr
);
71 static Bool
miOverlayDestroyWindow(WindowPtr
);
72 static Bool
miOverlayUnrealizeWindow(WindowPtr
);
73 static Bool
miOverlayRealizeWindow(WindowPtr
);
74 static void miOverlayMarkWindow(WindowPtr
);
75 static void miOverlayReparentWindow(WindowPtr
, WindowPtr
);
76 static void miOverlayRestackWindow(WindowPtr
, WindowPtr
);
77 static Bool
miOverlayMarkOverlappedWindows(WindowPtr
, WindowPtr
, WindowPtr
*);
78 static void miOverlayMarkUnrealizedWindow(WindowPtr
, WindowPtr
, Bool
);
79 static int miOverlayValidateTree(WindowPtr
, WindowPtr
, VTKind
);
80 static void miOverlayHandleExposures(WindowPtr
);
81 static void miOverlayMoveWindow(WindowPtr
, int, int, WindowPtr
, VTKind
);
82 static void miOverlayWindowExposures(WindowPtr
, RegionPtr
, RegionPtr
);
83 static void miOverlayResizeWindow(WindowPtr
, int, int, unsigned int,
84 unsigned int, WindowPtr
);
85 static void miOverlayClearToBackground(WindowPtr
, int, int, int, int, Bool
);
87 static void miOverlaySetShape(WindowPtr
, int);
88 static void miOverlayChangeBorderWidth(WindowPtr
, unsigned int);
90 #define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
91 dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
92 #define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
93 dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
94 #define MIOVERLAY_GET_WINDOW_TREE(pWin) \
95 (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
97 #define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
98 #define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
100 #define MARK_OVERLAY(w) miMarkWindow(w)
101 #define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
103 #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
105 (w)->backgroundState == ParentRelative)
108 miInitOverlay(ScreenPtr pScreen
,
109 miOverlayInOverlayFunc inOverlayFunc
,
110 miOverlayTransFunc transFunc
)
112 miOverlayScreenPtr pScreenPriv
;
114 if (!inOverlayFunc
|| !transFunc
)
117 if (!dixRegisterPrivateKey
118 (&miOverlayWindowKeyRec
, PRIVATE_WINDOW
, sizeof(miOverlayWindowRec
)))
121 if (!dixRegisterPrivateKey(&miOverlayScreenKeyRec
, PRIVATE_SCREEN
, 0))
124 if (!(pScreenPriv
= malloc(sizeof(miOverlayScreenRec
))))
127 dixSetPrivate(&pScreen
->devPrivates
, miOverlayScreenKey
, pScreenPriv
);
129 pScreenPriv
->InOverlay
= inOverlayFunc
;
130 pScreenPriv
->MakeTransparent
= transFunc
;
131 pScreenPriv
->underlayMarked
= FALSE
;
133 pScreenPriv
->CloseScreen
= pScreen
->CloseScreen
;
134 pScreenPriv
->CreateWindow
= pScreen
->CreateWindow
;
135 pScreenPriv
->DestroyWindow
= pScreen
->DestroyWindow
;
136 pScreenPriv
->UnrealizeWindow
= pScreen
->UnrealizeWindow
;
137 pScreenPriv
->RealizeWindow
= pScreen
->RealizeWindow
;
139 pScreen
->CloseScreen
= miOverlayCloseScreen
;
140 pScreen
->CreateWindow
= miOverlayCreateWindow
;
141 pScreen
->DestroyWindow
= miOverlayDestroyWindow
;
142 pScreen
->UnrealizeWindow
= miOverlayUnrealizeWindow
;
143 pScreen
->RealizeWindow
= miOverlayRealizeWindow
;
145 pScreen
->ReparentWindow
= miOverlayReparentWindow
;
146 pScreen
->RestackWindow
= miOverlayRestackWindow
;
147 pScreen
->MarkOverlappedWindows
= miOverlayMarkOverlappedWindows
;
148 pScreen
->MarkUnrealizedWindow
= miOverlayMarkUnrealizedWindow
;
149 pScreen
->ValidateTree
= miOverlayValidateTree
;
150 pScreen
->HandleExposures
= miOverlayHandleExposures
;
151 pScreen
->MoveWindow
= miOverlayMoveWindow
;
152 pScreen
->WindowExposures
= miOverlayWindowExposures
;
153 pScreen
->ResizeWindow
= miOverlayResizeWindow
;
154 pScreen
->MarkWindow
= miOverlayMarkWindow
;
155 pScreen
->ClearToBackground
= miOverlayClearToBackground
;
156 pScreen
->SetShape
= miOverlaySetShape
;
157 pScreen
->ChangeBorderWidth
= miOverlayChangeBorderWidth
;
163 miOverlayCloseScreen(ScreenPtr pScreen
)
165 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
167 pScreen
->CloseScreen
= pScreenPriv
->CloseScreen
;
168 pScreen
->CreateWindow
= pScreenPriv
->CreateWindow
;
169 pScreen
->DestroyWindow
= pScreenPriv
->DestroyWindow
;
170 pScreen
->UnrealizeWindow
= pScreenPriv
->UnrealizeWindow
;
171 pScreen
->RealizeWindow
= pScreenPriv
->RealizeWindow
;
175 return (*pScreen
->CloseScreen
) (pScreen
);
179 miOverlayCreateWindow(WindowPtr pWin
)
181 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
182 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
183 miOverlayWindowPtr pWinPriv
= MIOVERLAY_GET_WINDOW_PRIVATE(pWin
);
184 miOverlayTreePtr pTree
= NULL
;
187 pWinPriv
->tree
= NULL
;
189 if (!pWin
->parent
|| !((*pScreenPriv
->InOverlay
) (pWin
))) {
190 if (!(pTree
= (miOverlayTreePtr
) calloc(1, sizeof(miOverlayTreeRec
))))
194 if (pScreenPriv
->CreateWindow
) {
195 pScreen
->CreateWindow
= pScreenPriv
->CreateWindow
;
196 result
= (*pScreen
->CreateWindow
) (pWin
);
197 pScreen
->CreateWindow
= miOverlayCreateWindow
;
203 pTree
->visibility
= VisibilityNotViewable
;
204 pWinPriv
->tree
= pTree
;
206 RegionNull(&(pTree
->borderClip
));
207 RegionNull(&(pTree
->clipList
));
215 fullBox
.x2
= pScreen
->width
;
216 fullBox
.y2
= pScreen
->height
;
217 RegionInit(&(pTree
->borderClip
), &fullBox
, 1);
218 RegionInit(&(pTree
->clipList
), &fullBox
, 1);
229 miOverlayDestroyWindow(WindowPtr pWin
)
231 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
232 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
233 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
238 pTree
->prevSib
->nextSib
= pTree
->nextSib
;
239 else if (pTree
->parent
)
240 pTree
->parent
->firstChild
= pTree
->nextSib
;
243 pTree
->nextSib
->prevSib
= pTree
->prevSib
;
244 else if (pTree
->parent
)
245 pTree
->parent
->lastChild
= pTree
->prevSib
;
247 RegionUninit(&(pTree
->borderClip
));
248 RegionUninit(&(pTree
->clipList
));
252 if (pScreenPriv
->DestroyWindow
) {
253 pScreen
->DestroyWindow
= pScreenPriv
->DestroyWindow
;
254 result
= (*pScreen
->DestroyWindow
) (pWin
);
255 pScreen
->DestroyWindow
= miOverlayDestroyWindow
;
262 miOverlayUnrealizeWindow(WindowPtr pWin
)
264 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
265 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
266 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
270 pTree
->visibility
= VisibilityNotViewable
;
272 if (pScreenPriv
->UnrealizeWindow
) {
273 pScreen
->UnrealizeWindow
= pScreenPriv
->UnrealizeWindow
;
274 result
= (*pScreen
->UnrealizeWindow
) (pWin
);
275 pScreen
->UnrealizeWindow
= miOverlayUnrealizeWindow
;
282 miOverlayRealizeWindow(WindowPtr pWin
)
284 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
285 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
288 if (pScreenPriv
->RealizeWindow
) {
289 pScreen
->RealizeWindow
= pScreenPriv
->RealizeWindow
;
290 result
= (*pScreen
->RealizeWindow
) (pWin
);
291 pScreen
->RealizeWindow
= miOverlayRealizeWindow
;
294 /* we only need to catch the root window realization */
296 if (result
&& !pWin
->parent
&& !((*pScreenPriv
->InOverlay
) (pWin
))) {
300 box
.x2
= pWin
->drawable
.width
;
301 box
.y2
= pWin
->drawable
.height
;
302 (*pScreenPriv
->MakeTransparent
) (pScreen
, 1, &box
);
309 miOverlayReparentWindow(WindowPtr pWin
, WindowPtr pPriorParent
)
311 if (IN_UNDERLAY(pWin
) || HasUnderlayChildren(pWin
)) {
312 /* This could probably be more optimal */
313 RebuildTree(pWin
->drawable
.pScreen
->root
->firstChild
);
318 miOverlayRestackWindow(WindowPtr pWin
, WindowPtr oldNextSib
)
320 if (IN_UNDERLAY(pWin
) || HasUnderlayChildren(pWin
)) {
321 /* This could probably be more optimal */
327 miOverlayMarkOverlappedWindows(WindowPtr pWin
,
328 WindowPtr pFirst
, WindowPtr
*pLayerWin
)
330 WindowPtr pChild
, pLast
;
331 Bool overMarked
, underMarked
, doUnderlay
, markAll
;
332 miOverlayTreePtr pTree
= NULL
, tLast
, tChild
;
335 overMarked
= underMarked
= markAll
= FALSE
;
338 *pLayerWin
= pWin
; /* hah! */
340 doUnderlay
= (IN_UNDERLAY(pWin
) || HasUnderlayChildren(pWin
));
342 box
= RegionExtents(&pWin
->borderSize
);
344 if ((pChild
= pFirst
)) {
345 pLast
= pChild
->parent
->lastChild
;
350 if (doUnderlay
&& IN_UNDERLAY(pChild
))
351 pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
353 if (pChild
->viewable
) {
354 if (RegionBroken(&pChild
->winSize
))
356 if (RegionBroken(&pChild
->borderSize
))
357 SetBorderSize(pChild
);
359 if (markAll
|| RegionContainsRect(&pChild
->borderSize
, box
)) {
360 MARK_OVERLAY(pChild
);
362 if (doUnderlay
&& IN_UNDERLAY(pChild
)) {
363 MARK_UNDERLAY(pChild
);
366 if (pChild
->firstChild
) {
367 pChild
= pChild
->firstChild
;
372 while (!pChild
->nextSib
&& (pChild
!= pLast
)) {
373 pChild
= pChild
->parent
;
374 if (doUnderlay
&& IN_UNDERLAY(pChild
))
375 pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
384 pChild
= pChild
->nextSib
;
387 MARK_OVERLAY(pWin
->parent
);
390 if (doUnderlay
&& !pTree
) {
391 if (!(pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
))) {
392 pChild
= pWin
->lastChild
;
394 if ((pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
)))
397 if (pChild
->lastChild
) {
398 pChild
= pChild
->lastChild
;
402 while (!pChild
->prevSib
)
403 pChild
= pChild
->parent
;
405 pChild
= pChild
->prevSib
;
410 if (pTree
&& pTree
->nextSib
) {
411 tChild
= pTree
->parent
->lastChild
;
412 tLast
= pTree
->nextSib
;
415 if (tChild
->pWin
->viewable
) {
416 if (RegionBroken(&tChild
->pWin
->winSize
))
417 SetWinSize(tChild
->pWin
);
418 if (RegionBroken(&tChild
->pWin
->borderSize
))
419 SetBorderSize(tChild
->pWin
);
421 if (RegionContainsRect(&(tChild
->pWin
->borderSize
), box
)) {
422 MARK_UNDERLAY(tChild
->pWin
);
427 if (tChild
->lastChild
) {
428 tChild
= tChild
->lastChild
;
432 while (!tChild
->prevSib
&& (tChild
!= tLast
))
433 tChild
= tChild
->parent
;
438 tChild
= tChild
->prevSib
;
443 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
445 MARK_UNDERLAY(pTree
->parent
->pWin
);
446 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
)->underlayMarked
= TRUE
;
449 return underMarked
|| overMarked
;
453 miOverlayComputeClips(WindowPtr pParent
,
454 RegionPtr universe
, VTKind kind
, RegionPtr exposed
)
456 ScreenPtr pScreen
= pParent
->drawable
.pScreen
;
457 int oldVis
, newVis
, dx
, dy
;
459 RegionPtr borderVisible
;
460 RegionRec childUniverse
, childUnion
;
461 miOverlayTreePtr tParent
= MIOVERLAY_GET_WINDOW_TREE(pParent
);
462 miOverlayTreePtr tChild
;
465 borderSize
.x1
= pParent
->drawable
.x
- wBorderWidth(pParent
);
466 borderSize
.y1
= pParent
->drawable
.y
- wBorderWidth(pParent
);
467 dx
= (int) pParent
->drawable
.x
+ (int) pParent
->drawable
.width
+
468 wBorderWidth(pParent
);
472 dy
= (int) pParent
->drawable
.y
+ (int) pParent
->drawable
.height
+
473 wBorderWidth(pParent
);
478 oldVis
= tParent
->visibility
;
479 switch (RegionContainsRect(universe
, &borderSize
)) {
481 newVis
= VisibilityUnobscured
;
484 newVis
= VisibilityPartiallyObscured
;
488 if ((pBounding
= wBoundingShape(pParent
))) {
489 switch (miShapedWindowIn(universe
, pBounding
,
492 pParent
->drawable
.y
)) {
494 newVis
= VisibilityUnobscured
;
497 newVis
= VisibilityFullyObscured
;
504 newVis
= VisibilityFullyObscured
;
507 tParent
->visibility
= newVis
;
509 dx
= pParent
->drawable
.x
- tParent
->valdata
->oldAbsCorner
.x
;
510 dy
= pParent
->drawable
.y
- tParent
->valdata
->oldAbsCorner
.y
;
518 if ((oldVis
== newVis
) &&
519 ((oldVis
== VisibilityFullyObscured
) ||
520 (oldVis
== VisibilityUnobscured
))) {
523 if (tChild
->pWin
->viewable
) {
524 if (tChild
->visibility
!= VisibilityFullyObscured
) {
525 RegionTranslate(&tChild
->borderClip
, dx
, dy
);
526 RegionTranslate(&tChild
->clipList
, dx
, dy
);
528 tChild
->pWin
->drawable
.serialNumber
=
530 if (pScreen
->ClipNotify
)
531 (*pScreen
->ClipNotify
) (tChild
->pWin
, dx
, dy
);
533 if (tChild
->valdata
) {
534 RegionNull(&tChild
->valdata
->borderExposed
);
535 if (HasParentRelativeBorder(tChild
->pWin
)) {
536 RegionSubtract(&tChild
->valdata
->borderExposed
,
538 &tChild
->pWin
->winSize
);
540 RegionNull(&tChild
->valdata
->exposed
);
542 if (tChild
->firstChild
) {
543 tChild
= tChild
->firstChild
;
547 while (!tChild
->nextSib
&& (tChild
!= tParent
))
548 tChild
= tChild
->parent
;
549 if (tChild
== tParent
)
551 tChild
= tChild
->nextSib
;
558 RegionTranslate(&tParent
->borderClip
, dx
, dy
);
559 RegionTranslate(&tParent
->clipList
, dx
, dy
);
563 RegionEmpty(&tParent
->borderClip
);
564 RegionEmpty(&tParent
->clipList
);
568 borderVisible
= tParent
->valdata
->borderVisible
;
569 RegionNull(&tParent
->valdata
->borderExposed
);
570 RegionNull(&tParent
->valdata
->exposed
);
572 if (HasBorder(pParent
)) {
574 RegionSubtract(exposed
, universe
, borderVisible
);
575 RegionDestroy(borderVisible
);
578 RegionSubtract(exposed
, universe
, &tParent
->borderClip
);
580 if (HasParentRelativeBorder(pParent
) && (dx
|| dy
))
581 RegionSubtract(&tParent
->valdata
->borderExposed
,
582 universe
, &pParent
->winSize
);
584 RegionSubtract(&tParent
->valdata
->borderExposed
,
585 exposed
, &pParent
->winSize
);
587 RegionCopy(&tParent
->borderClip
, universe
);
588 RegionIntersect(universe
, universe
, &pParent
->winSize
);
591 RegionCopy(&tParent
->borderClip
, universe
);
593 if ((tChild
= tParent
->firstChild
) && pParent
->mapped
) {
594 RegionNull(&childUniverse
);
595 RegionNull(&childUnion
);
597 for (; tChild
; tChild
= tChild
->nextSib
) {
598 if (tChild
->pWin
->viewable
)
599 RegionAppend(&childUnion
, &tChild
->pWin
->borderSize
);
602 RegionValidate(&childUnion
, &overlap
);
604 for (tChild
= tParent
->firstChild
; tChild
; tChild
= tChild
->nextSib
) {
605 if (tChild
->pWin
->viewable
) {
606 if (tChild
->valdata
) {
607 RegionIntersect(&childUniverse
, universe
,
608 &tChild
->pWin
->borderSize
);
609 miOverlayComputeClips(tChild
->pWin
, &childUniverse
,
613 RegionSubtract(universe
, universe
,
614 &tChild
->pWin
->borderSize
);
618 RegionSubtract(universe
, universe
, &childUnion
);
619 RegionUninit(&childUnion
);
620 RegionUninit(&childUniverse
);
623 if (oldVis
== VisibilityFullyObscured
|| oldVis
== VisibilityNotViewable
) {
624 RegionCopy(&tParent
->valdata
->exposed
, universe
);
626 else if (newVis
!= VisibilityFullyObscured
&&
627 newVis
!= VisibilityNotViewable
) {
628 RegionSubtract(&tParent
->valdata
->exposed
,
629 universe
, &tParent
->clipList
);
632 /* HACK ALERT - copying contents of regions, instead of regions */
636 tmp
= tParent
->clipList
;
637 tParent
->clipList
= *universe
;
641 pParent
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
643 if (pScreen
->ClipNotify
)
644 (*pScreen
->ClipNotify
) (pParent
, dx
, dy
);
648 miOverlayMarkWindow(WindowPtr pWin
)
650 miOverlayTreePtr pTree
= NULL
;
651 WindowPtr pChild
, pGrandChild
;
655 /* look for UnmapValdata among immediate children */
657 if (!(pChild
= pWin
->firstChild
))
660 for (; pChild
; pChild
= pChild
->nextSib
) {
661 if (pChild
->valdata
== UnmapValData
) {
662 if (IN_UNDERLAY(pChild
)) {
663 pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
664 pTree
->valdata
= (miOverlayValDataPtr
) UnmapValData
;
668 if (!(pGrandChild
= pChild
->firstChild
))
672 if (IN_UNDERLAY(pGrandChild
)) {
673 pTree
= MIOVERLAY_GET_WINDOW_TREE(pGrandChild
);
674 pTree
->valdata
= (miOverlayValDataPtr
) UnmapValData
;
676 else if (pGrandChild
->firstChild
) {
677 pGrandChild
= pGrandChild
->firstChild
;
681 while (!pGrandChild
->nextSib
&& (pGrandChild
!= pChild
))
682 pGrandChild
= pGrandChild
->parent
;
684 if (pChild
== pGrandChild
)
687 pGrandChild
= pGrandChild
->nextSib
;
694 MARK_UNDERLAY(pTree
->parent
->pWin
);
695 MIOVERLAY_GET_SCREEN_PRIVATE(pWin
->drawable
.pScreen
)->underlayMarked
=
701 miOverlayMarkUnrealizedWindow(WindowPtr pChild
,
702 WindowPtr pWin
, Bool fromConfigure
)
704 if ((pChild
!= pWin
) || fromConfigure
) {
705 miOverlayTreePtr pTree
;
707 RegionEmpty(&pChild
->clipList
);
708 if (pChild
->drawable
.pScreen
->ClipNotify
)
709 (*pChild
->drawable
.pScreen
->ClipNotify
) (pChild
, 0, 0);
710 RegionEmpty(&pChild
->borderClip
);
711 if ((pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
))) {
712 if (pTree
->valdata
!= (miOverlayValDataPtr
) UnmapValData
) {
713 RegionEmpty(&pTree
->clipList
);
714 RegionEmpty(&pTree
->borderClip
);
721 miOverlayValidateTree(WindowPtr pParent
, WindowPtr pChild
, /* first child effected */
724 ScreenPtr pScreen
= pParent
->drawable
.pScreen
;
725 miOverlayScreenPtr pPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
726 RegionRec totalClip
, childClip
, exposed
;
727 miOverlayTreePtr tParent
, tChild
, tWin
;
731 if (!pPriv
->underlayMarked
)
735 pChild
= pParent
->firstChild
;
737 RegionNull(&totalClip
);
738 RegionNull(&childClip
);
739 RegionNull(&exposed
);
743 while (IN_OVERLAY(newParent
))
744 newParent
= newParent
->parent
;
746 tParent
= MIOVERLAY_GET_WINDOW_TREE(newParent
);
748 if (IN_UNDERLAY(pChild
))
749 tChild
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
751 tChild
= tParent
->firstChild
;
753 if (RegionBroken(&tParent
->clipList
) && !RegionBroken(&tParent
->borderClip
)) {
755 RegionCopy(&totalClip
, &tParent
->borderClip
);
756 RegionIntersect(&totalClip
, &totalClip
, &tParent
->pWin
->winSize
);
758 for (tWin
= tParent
->firstChild
; tWin
!= tChild
; tWin
= tWin
->nextSib
) {
759 if (tWin
->pWin
->viewable
)
760 RegionSubtract(&totalClip
, &totalClip
, &tWin
->pWin
->borderSize
);
762 RegionEmpty(&tParent
->clipList
);
765 for (tWin
= tChild
; tWin
; tWin
= tWin
->nextSib
) {
767 RegionAppend(&totalClip
, &tWin
->borderClip
);
769 RegionValidate(&totalClip
, &overlap
);
773 RegionUnion(&totalClip
, &totalClip
, &tParent
->clipList
);
775 for (tWin
= tChild
; tWin
; tWin
= tWin
->nextSib
) {
777 if (tWin
->pWin
->viewable
) {
778 RegionIntersect(&childClip
, &totalClip
,
779 &tWin
->pWin
->borderSize
);
780 miOverlayComputeClips(tWin
->pWin
, &childClip
, kind
, &exposed
);
781 RegionSubtract(&totalClip
, &totalClip
, &tWin
->pWin
->borderSize
);
783 else { /* Means we are unmapping */
784 RegionEmpty(&tWin
->clipList
);
785 RegionEmpty(&tWin
->borderClip
);
786 tWin
->valdata
= NULL
;
791 RegionUninit(&childClip
);
793 if (!((*pPriv
->InOverlay
) (newParent
))) {
794 RegionNull(&tParent
->valdata
->exposed
);
795 RegionNull(&tParent
->valdata
->borderExposed
);
802 if (!((*pPriv
->InOverlay
) (newParent
)))
803 RegionSubtract(&tParent
->valdata
->exposed
, &totalClip
,
807 RegionCopy(&tParent
->clipList
, &totalClip
);
808 if (!((*pPriv
->InOverlay
) (newParent
)))
809 newParent
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
813 RegionUninit(&totalClip
);
814 RegionUninit(&exposed
);
818 miValidateTree(pParent
, pChild
, kind
);
824 miOverlayHandleExposures(WindowPtr pWin
)
826 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
827 miOverlayScreenPtr pPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
830 void (*WindowExposures
) (WindowPtr
, RegionPtr
, RegionPtr
);
832 WindowExposures
= pWin
->drawable
.pScreen
->WindowExposures
;
833 if (pPriv
->underlayMarked
) {
834 miOverlayTreePtr pTree
;
835 miOverlayValDataPtr mival
;
838 while (IN_OVERLAY(pChild
))
839 pChild
= pChild
->parent
;
841 pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
844 if ((mival
= pTree
->valdata
)) {
845 if (!((*pPriv
->InOverlay
) (pTree
->pWin
))) {
846 if (RegionNotEmpty(&mival
->borderExposed
)) {
847 miPaintWindow(pTree
->pWin
, &mival
->borderExposed
,
850 RegionUninit(&mival
->borderExposed
);
852 (*WindowExposures
) (pTree
->pWin
, &mival
->exposed
,
854 RegionUninit(&mival
->exposed
);
857 pTree
->valdata
= NULL
;
858 if (pTree
->firstChild
) {
859 pTree
= pTree
->firstChild
;
863 while (!pTree
->nextSib
&& (pTree
->pWin
!= pChild
))
864 pTree
= pTree
->parent
;
865 if (pTree
->pWin
== pChild
)
867 pTree
= pTree
->nextSib
;
869 pPriv
->underlayMarked
= FALSE
;
874 if ((val
= pChild
->valdata
)) {
875 if (!((*pPriv
->InOverlay
) (pChild
))) {
876 RegionUnion(&val
->after
.exposed
, &val
->after
.exposed
,
877 &val
->after
.borderExposed
);
879 if (RegionNotEmpty(&val
->after
.exposed
)) {
880 (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
)->MakeTransparent
))
881 (pScreen
, RegionNumRects(&val
->after
.exposed
),
882 RegionRects(&val
->after
.exposed
));
886 if (RegionNotEmpty(&val
->after
.borderExposed
)) {
887 miPaintWindow(pChild
, &val
->after
.borderExposed
, PW_BORDER
);
889 (*WindowExposures
) (pChild
, &val
->after
.exposed
, NullRegion
);
891 RegionUninit(&val
->after
.borderExposed
);
892 RegionUninit(&val
->after
.exposed
);
894 pChild
->valdata
= NULL
;
895 if (pChild
->firstChild
) {
896 pChild
= pChild
->firstChild
;
900 while (!pChild
->nextSib
&& (pChild
!= pWin
))
901 pChild
= pChild
->parent
;
904 pChild
= pChild
->nextSib
;
909 miOverlayMoveWindow(WindowPtr pWin
,
910 int x
, int y
, WindowPtr pNextSib
, VTKind kind
)
912 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
913 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
914 WindowPtr pParent
, windowToValidate
;
915 Bool WasViewable
= (Bool
) (pWin
->viewable
);
917 RegionRec overReg
, underReg
;
920 if (!(pParent
= pWin
->parent
))
922 bw
= wBorderWidth(pWin
);
924 oldpt
.x
= pWin
->drawable
.x
;
925 oldpt
.y
= pWin
->drawable
.y
;
927 RegionNull(&overReg
);
928 RegionNull(&underReg
);
930 RegionCopy(&overReg
, &pWin
->borderClip
);
931 RegionCopy(&underReg
, &pTree
->borderClip
);
934 RegionCopy(&overReg
, &pWin
->borderClip
);
935 CollectUnderlayChildrenRegions(pWin
, &underReg
);
937 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
939 pWin
->origin
.x
= x
+ (int) bw
;
940 pWin
->origin
.y
= y
+ (int) bw
;
941 x
= pWin
->drawable
.x
= pParent
->drawable
.x
+ x
+ (int) bw
;
942 y
= pWin
->drawable
.y
= pParent
->drawable
.y
+ y
+ (int) bw
;
947 (*pScreen
->PositionWindow
) (pWin
, x
, y
);
949 windowToValidate
= MoveWindowInStack(pWin
, pNextSib
);
951 ResizeChildrenWinSize(pWin
, x
- oldpt
.x
, y
- oldpt
.y
, 0, 0);
954 miOverlayScreenPtr pPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
956 (*pScreen
->MarkOverlappedWindows
) (pWin
, windowToValidate
, NULL
);
958 (*pScreen
->ValidateTree
) (pWin
->parent
, NullWindow
, kind
);
959 if (RegionNotEmpty(&underReg
)) {
960 pPriv
->copyUnderlay
= TRUE
;
961 (*pWin
->drawable
.pScreen
->CopyWindow
) (pWin
, oldpt
, &underReg
);
963 RegionUninit(&underReg
);
964 if (RegionNotEmpty(&overReg
)) {
965 pPriv
->copyUnderlay
= FALSE
;
966 (*pWin
->drawable
.pScreen
->CopyWindow
) (pWin
, oldpt
, &overReg
);
968 RegionUninit(&overReg
);
969 (*pScreen
->HandleExposures
) (pWin
->parent
);
971 if (pScreen
->PostValidateTree
)
972 (*pScreen
->PostValidateTree
) (pWin
->parent
, NullWindow
, kind
);
975 WindowsRestructured();
983 miOverlayWindowExposures(WindowPtr pWin
,
984 RegionPtr prgn
, RegionPtr other_exposed
)
986 RegionPtr exposures
= prgn
;
988 if ((prgn
&& !RegionNil(prgn
)) ||
989 (exposures
&& !RegionNil(exposures
)) || other_exposed
) {
991 int clientInterested
;
993 clientInterested
= (pWin
->eventMask
| wOtherEventMasks(pWin
)) &
997 RegionUnion(other_exposed
, exposures
, other_exposed
);
998 if (exposures
!= prgn
)
999 RegionDestroy(exposures
);
1001 exposures
= other_exposed
;
1003 if (clientInterested
&& exposures
&&
1004 (RegionNumRects(exposures
) > RECTLIMIT
)) {
1005 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1006 miOverlayScreenPtr pPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
1009 box
= *RegionExtents(exposures
);
1010 if (exposures
== prgn
) {
1011 exposures
= &expRec
;
1012 RegionInit(exposures
, &box
, 1);
1013 RegionReset(prgn
, &box
);
1016 RegionReset(exposures
, &box
);
1017 RegionUnion(prgn
, prgn
, exposures
);
1019 /* This is the only reason why we are replacing mi's version
1022 if (!((*pPriv
->InOverlay
) (pWin
))) {
1023 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1025 RegionIntersect(prgn
, prgn
, &pTree
->clipList
);
1028 RegionIntersect(prgn
, prgn
, &pWin
->clipList
);
1030 if (prgn
&& !RegionNil(prgn
))
1031 miPaintWindow(pWin
, prgn
, PW_BACKGROUND
);
1032 if (clientInterested
&& exposures
&& !RegionNil(exposures
))
1033 miSendExposures(pWin
, exposures
,
1034 pWin
->drawable
.x
, pWin
->drawable
.y
);
1035 if (exposures
== &expRec
) {
1036 RegionUninit(exposures
);
1038 else if (exposures
&& exposures
!= prgn
&& exposures
!= other_exposed
)
1039 RegionDestroy(exposures
);
1043 else if (exposures
&& exposures
!= prgn
)
1044 RegionDestroy(exposures
);
1050 } miOverlayTwoRegions
;
1053 miOverlayRecomputeExposures(WindowPtr pWin
, pointer value
)
1055 miOverlayTwoRegions
*pValid
= (miOverlayTwoRegions
*) value
;
1056 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1058 if (pWin
->valdata
) {
1060 * compute exposed regions of this window
1062 RegionSubtract(&pWin
->valdata
->after
.exposed
,
1063 &pWin
->clipList
, pValid
->over
);
1065 * compute exposed regions of the border
1067 RegionSubtract(&pWin
->valdata
->after
.borderExposed
,
1068 &pWin
->borderClip
, &pWin
->winSize
);
1069 RegionSubtract(&pWin
->valdata
->after
.borderExposed
,
1070 &pWin
->valdata
->after
.borderExposed
, pValid
->over
);
1073 if (pTree
&& pTree
->valdata
) {
1074 RegionSubtract(&pTree
->valdata
->exposed
,
1075 &pTree
->clipList
, pValid
->under
);
1076 RegionSubtract(&pTree
->valdata
->borderExposed
,
1077 &pTree
->borderClip
, &pWin
->winSize
);
1078 RegionSubtract(&pTree
->valdata
->borderExposed
,
1079 &pTree
->valdata
->borderExposed
, pValid
->under
);
1081 else if (!pWin
->valdata
)
1084 return WT_WALKCHILDREN
;
1088 miOverlayResizeWindow(WindowPtr pWin
,
1090 unsigned int w
, unsigned int h
, WindowPtr pSib
)
1092 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1094 miOverlayTreePtr tChild
, pTree
;
1095 Bool WasViewable
= (Bool
) (pWin
->viewable
);
1096 unsigned short width
= pWin
->drawable
.width
;
1097 unsigned short height
= pWin
->drawable
.height
;
1098 short oldx
= pWin
->drawable
.x
;
1099 short oldy
= pWin
->drawable
.y
;
1100 int bw
= wBorderWidth(pWin
);
1103 RegionPtr oldRegion
= NULL
, oldRegion2
= NULL
;
1104 WindowPtr pFirstChange
;
1106 RegionPtr gravitate
[StaticGravity
+ 1];
1107 RegionPtr gravitate2
[StaticGravity
+ 1];
1109 int nx
, ny
; /* destination x,y */
1110 int newx
, newy
; /* new inner window position */
1111 RegionPtr pRegion
= NULL
;
1112 RegionPtr destClip
, destClip2
;
1113 RegionPtr oldWinClip
= NULL
, oldWinClip2
= NULL
;
1114 RegionPtr borderVisible
= NullRegion
;
1115 RegionPtr borderVisible2
= NullRegion
;
1116 Bool shrunk
= FALSE
; /* shrunk in an inner dimension */
1117 Bool moved
= FALSE
; /* window position changed */
1120 /* if this is a root window, can't be resized */
1121 if (!(pParent
= pWin
->parent
))
1124 pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1125 doUnderlay
= ((pTree
) || HasUnderlayChildren(pWin
));
1126 newx
= pParent
->drawable
.x
+ x
+ bw
;
1127 newy
= pParent
->drawable
.y
+ y
+ bw
;
1130 * save the visible region of the window
1132 oldRegion
= RegionCreate(NullBox
, 1);
1133 RegionCopy(oldRegion
, &pWin
->winSize
);
1135 oldRegion2
= RegionCreate(NullBox
, 1);
1136 RegionCopy(oldRegion2
, &pWin
->winSize
);
1140 * categorize child windows into regions to be moved
1142 for (g
= 0; g
<= StaticGravity
; g
++)
1143 gravitate
[g
] = gravitate2
[g
] = NULL
;
1144 for (pChild
= pWin
->firstChild
; pChild
; pChild
= pChild
->nextSib
) {
1145 g
= pChild
->winGravity
;
1146 if (g
!= UnmapGravity
) {
1148 gravitate
[g
] = RegionCreate(NullBox
, 1);
1149 RegionUnion(gravitate
[g
], gravitate
[g
], &pChild
->borderClip
);
1153 gravitate2
[g
] = RegionCreate(NullBox
, 0);
1155 if ((tChild
= MIOVERLAY_GET_WINDOW_TREE(pChild
))) {
1156 RegionUnion(gravitate2
[g
],
1157 gravitate2
[g
], &tChild
->borderClip
);
1160 CollectUnderlayChildrenRegions(pChild
, gravitate2
[g
]);
1164 UnmapWindow(pChild
, TRUE
);
1167 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
1169 oldWinClip
= oldWinClip2
= NULL
;
1170 if (pWin
->bitGravity
!= ForgetGravity
) {
1171 oldWinClip
= RegionCreate(NullBox
, 1);
1172 RegionCopy(oldWinClip
, &pWin
->clipList
);
1174 oldWinClip2
= RegionCreate(NullBox
, 1);
1175 RegionCopy(oldWinClip2
, &pTree
->clipList
);
1179 * if the window is changing size, borderExposed
1180 * can't be computed correctly without some help.
1182 if (pWin
->drawable
.height
> h
|| pWin
->drawable
.width
> w
)
1185 if (newx
!= oldx
|| newy
!= oldy
)
1188 if ((pWin
->drawable
.height
!= h
|| pWin
->drawable
.width
!= w
) &&
1190 borderVisible
= RegionCreate(NullBox
, 1);
1192 borderVisible2
= RegionCreate(NullBox
, 1);
1193 /* for tiled borders, we punt and draw the whole thing */
1194 if (pWin
->borderIsPixel
|| !moved
) {
1195 if (shrunk
|| moved
)
1196 RegionSubtract(borderVisible
,
1197 &pWin
->borderClip
, &pWin
->winSize
);
1199 RegionCopy(borderVisible
, &pWin
->borderClip
);
1201 if (shrunk
|| moved
)
1202 RegionSubtract(borderVisible
,
1203 &pTree
->borderClip
, &pWin
->winSize
);
1205 RegionCopy(borderVisible
, &pTree
->borderClip
);
1210 pWin
->origin
.x
= x
+ bw
;
1211 pWin
->origin
.y
= y
+ bw
;
1212 pWin
->drawable
.height
= h
;
1213 pWin
->drawable
.width
= w
;
1215 x
= pWin
->drawable
.x
= newx
;
1216 y
= pWin
->drawable
.y
= newy
;
1219 SetBorderSize(pWin
);
1221 dw
= (int) w
- (int) width
;
1222 dh
= (int) h
- (int) height
;
1223 ResizeChildrenWinSize(pWin
, x
- oldx
, y
- oldy
, dw
, dh
);
1225 /* let the hardware adjust background and border pixmaps, if any */
1226 (*pScreen
->PositionWindow
) (pWin
, x
, y
);
1228 pFirstChange
= MoveWindowInStack(pWin
, pSib
);
1231 pRegion
= RegionCreate(NullBox
, 1);
1233 (*pScreen
->MarkOverlappedWindows
) (pWin
, pFirstChange
, NULL
);
1235 pWin
->valdata
->before
.resized
= TRUE
;
1236 pWin
->valdata
->before
.borderVisible
= borderVisible
;
1238 pTree
->valdata
->borderVisible
= borderVisible2
;
1240 (*pScreen
->ValidateTree
) (pWin
->parent
, pFirstChange
, VTOther
);
1242 * the entire window is trashed unless bitGravity
1243 * recovers portions of it
1245 RegionCopy(&pWin
->valdata
->after
.exposed
, &pWin
->clipList
);
1247 RegionCopy(&pTree
->valdata
->exposed
, &pTree
->clipList
);
1250 GravityTranslate(x
, y
, oldx
, oldy
, dw
, dh
, pWin
->bitGravity
, &nx
, &ny
);
1253 miOverlayScreenPtr pPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
1254 miOverlayTwoRegions TwoRegions
;
1256 /* avoid the border */
1257 if (HasBorder(pWin
)) {
1258 int offx
, offy
, dx
, dy
;
1260 /* kruft to avoid double translates for each gravity */
1263 for (g
= 0; g
<= StaticGravity
; g
++) {
1264 if (!gravitate
[g
] && !gravitate2
[g
])
1267 /* align winSize to gravitate[g].
1268 * winSize is in new coordinates,
1269 * gravitate[g] is still in old coordinates */
1270 GravityTranslate(x
, y
, oldx
, oldy
, dw
, dh
, g
, &nx
, &ny
);
1272 dx
= (oldx
- nx
) - offx
;
1273 dy
= (oldy
- ny
) - offy
;
1275 RegionTranslate(&pWin
->winSize
, dx
, dy
);
1280 RegionIntersect(gravitate
[g
], gravitate
[g
], &pWin
->winSize
);
1282 RegionIntersect(gravitate2
[g
], gravitate2
[g
],
1285 /* get winSize back where it belongs */
1287 RegionTranslate(&pWin
->winSize
, -offx
, -offy
);
1290 * add screen bits to the appropriate bucket
1294 RegionCopy(pRegion
, oldWinClip2
);
1295 RegionTranslate(pRegion
, nx
- oldx
, ny
- oldy
);
1296 RegionIntersect(oldWinClip2
, pRegion
, &pTree
->clipList
);
1298 for (g
= pWin
->bitGravity
+ 1; g
<= StaticGravity
; g
++) {
1300 RegionSubtract(oldWinClip2
, oldWinClip2
, gravitate2
[g
]);
1302 RegionTranslate(oldWinClip2
, oldx
- nx
, oldy
- ny
);
1303 g
= pWin
->bitGravity
;
1305 gravitate2
[g
] = oldWinClip2
;
1307 RegionUnion(gravitate2
[g
], gravitate2
[g
], oldWinClip2
);
1308 RegionDestroy(oldWinClip2
);
1314 * clip to new clipList
1316 RegionCopy(pRegion
, oldWinClip
);
1317 RegionTranslate(pRegion
, nx
- oldx
, ny
- oldy
);
1318 RegionIntersect(oldWinClip
, pRegion
, &pWin
->clipList
);
1320 * don't step on any gravity bits which will be copied after this
1321 * region. Note -- this assumes that the regions will be copied
1324 for (g
= pWin
->bitGravity
+ 1; g
<= StaticGravity
; g
++) {
1326 RegionSubtract(oldWinClip
, oldWinClip
, gravitate
[g
]);
1328 RegionTranslate(oldWinClip
, oldx
- nx
, oldy
- ny
);
1329 g
= pWin
->bitGravity
;
1331 gravitate
[g
] = oldWinClip
;
1333 RegionUnion(gravitate
[g
], gravitate
[g
], oldWinClip
);
1334 RegionDestroy(oldWinClip
);
1339 * move the bits on the screen
1342 destClip
= destClip2
= NULL
;
1344 for (g
= 0; g
<= StaticGravity
; g
++) {
1345 if (!gravitate
[g
] && !gravitate2
[g
])
1348 GravityTranslate(x
, y
, oldx
, oldy
, dw
, dh
, g
, &nx
, &ny
);
1350 oldpt
.x
= oldx
+ (x
- nx
);
1351 oldpt
.y
= oldy
+ (y
- ny
);
1353 /* Note that gravitate[g] is *translated* by CopyWindow */
1355 /* only copy the remaining useful bits */
1358 RegionIntersect(gravitate
[g
], gravitate
[g
], oldRegion
);
1360 RegionIntersect(gravitate2
[g
], gravitate2
[g
], oldRegion2
);
1362 /* clip to not overwrite already copied areas */
1364 if (destClip
&& gravitate
[g
]) {
1365 RegionTranslate(destClip
, oldpt
.x
- x
, oldpt
.y
- y
);
1366 RegionSubtract(gravitate
[g
], gravitate
[g
], destClip
);
1367 RegionTranslate(destClip
, x
- oldpt
.x
, y
- oldpt
.y
);
1369 if (destClip2
&& gravitate2
[g
]) {
1370 RegionTranslate(destClip2
, oldpt
.x
- x
, oldpt
.y
- y
);
1371 RegionSubtract(gravitate2
[g
], gravitate2
[g
], destClip2
);
1372 RegionTranslate(destClip2
, x
- oldpt
.x
, y
- oldpt
.y
);
1375 /* and move those bits */
1377 if (oldpt
.x
!= x
|| oldpt
.y
!= y
) {
1378 if (gravitate2
[g
]) {
1379 pPriv
->copyUnderlay
= TRUE
;
1380 (*pScreen
->CopyWindow
) (pWin
, oldpt
, gravitate2
[g
]);
1383 pPriv
->copyUnderlay
= FALSE
;
1384 (*pScreen
->CopyWindow
) (pWin
, oldpt
, gravitate
[g
]);
1388 /* remove any overwritten bits from the remaining useful bits */
1391 RegionSubtract(oldRegion
, oldRegion
, gravitate
[g
]);
1393 RegionSubtract(oldRegion2
, oldRegion2
, gravitate2
[g
]);
1396 * recompute exposed regions of child windows
1399 for (pChild
= pWin
->firstChild
; pChild
; pChild
= pChild
->nextSib
) {
1400 if (pChild
->winGravity
!= g
)
1403 TwoRegions
.over
= gravitate
[g
];
1404 TwoRegions
.under
= gravitate2
[g
];
1406 TraverseTree(pChild
, miOverlayRecomputeExposures
,
1407 (pointer
) (&TwoRegions
));
1411 * remove the successfully copied regions of the
1412 * window from its exposed region
1415 if (g
== pWin
->bitGravity
) {
1417 RegionSubtract(&pWin
->valdata
->after
.exposed
,
1418 &pWin
->valdata
->after
.exposed
, gravitate
[g
]);
1419 if (gravitate2
[g
] && pTree
)
1420 RegionSubtract(&pTree
->valdata
->exposed
,
1421 &pTree
->valdata
->exposed
, gravitate2
[g
]);
1425 destClip
= gravitate
[g
];
1427 RegionUnion(destClip
, destClip
, gravitate
[g
]);
1428 RegionDestroy(gravitate
[g
]);
1431 if (gravitate2
[g
]) {
1433 destClip2
= gravitate2
[g
];
1435 RegionUnion(destClip2
, destClip2
, gravitate2
[g
]);
1436 RegionDestroy(gravitate2
[g
]);
1441 RegionDestroy(pRegion
);
1442 RegionDestroy(oldRegion
);
1444 RegionDestroy(oldRegion2
);
1446 RegionDestroy(destClip
);
1448 RegionDestroy(destClip2
);
1449 (*pScreen
->HandleExposures
) (pWin
->parent
);
1450 if (pScreen
->PostValidateTree
)
1451 (*pScreen
->PostValidateTree
) (pWin
->parent
, pFirstChange
, VTOther
);
1454 WindowsRestructured();
1458 miOverlaySetShape(WindowPtr pWin
, int kind
)
1460 Bool WasViewable
= (Bool
) (pWin
->viewable
);
1461 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1463 if (kind
!= ShapeInput
) {
1465 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
1467 if (HasBorder(pWin
)) {
1468 RegionPtr borderVisible
;
1470 borderVisible
= RegionCreate(NullBox
, 1);
1471 RegionSubtract(borderVisible
,
1472 &pWin
->borderClip
, &pWin
->winSize
);
1473 pWin
->valdata
->before
.borderVisible
= borderVisible
;
1474 pWin
->valdata
->before
.resized
= TRUE
;
1475 if (IN_UNDERLAY(pWin
)) {
1476 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1477 RegionPtr borderVisible2
;
1479 borderVisible2
= RegionCreate(NULL
, 1);
1480 RegionSubtract(borderVisible2
,
1481 &pTree
->borderClip
, &pWin
->winSize
);
1482 pTree
->valdata
->borderVisible
= borderVisible2
;
1488 SetBorderSize(pWin
);
1490 ResizeChildrenWinSize(pWin
, 0, 0, 0, 0);
1493 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
1495 (*pScreen
->ValidateTree
) (pWin
->parent
, NullWindow
, VTOther
);
1499 (*pScreen
->HandleExposures
) (pWin
->parent
);
1500 if (pScreen
->PostValidateTree
)
1501 (*pScreen
->PostValidateTree
) (pWin
->parent
, NullWindow
,
1506 WindowsRestructured();
1507 CheckCursorConfinement(pWin
);
1511 miOverlayChangeBorderWidth(WindowPtr pWin
, unsigned int width
)
1515 Bool WasViewable
= (Bool
) (pWin
->viewable
);
1518 oldwidth
= wBorderWidth(pWin
);
1519 if (oldwidth
== width
)
1521 HadBorder
= HasBorder(pWin
);
1522 pScreen
= pWin
->drawable
.pScreen
;
1523 if (WasViewable
&& (width
< oldwidth
))
1524 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
1526 pWin
->borderWidth
= width
;
1527 SetBorderSize(pWin
);
1530 if (width
> oldwidth
) {
1531 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
, NULL
);
1534 RegionPtr borderVisible
;
1536 borderVisible
= RegionCreate(NULL
, 1);
1537 RegionSubtract(borderVisible
,
1538 &pWin
->borderClip
, &pWin
->winSize
);
1539 pWin
->valdata
->before
.borderVisible
= borderVisible
;
1540 if (IN_UNDERLAY(pWin
)) {
1541 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1542 RegionPtr borderVisible2
;
1544 borderVisible2
= RegionCreate(NULL
, 1);
1545 RegionSubtract(borderVisible2
,
1546 &pTree
->borderClip
, &pWin
->winSize
);
1547 pTree
->valdata
->borderVisible
= borderVisible2
;
1551 (*pScreen
->ValidateTree
) (pWin
->parent
, pWin
, VTOther
);
1552 (*pScreen
->HandleExposures
) (pWin
->parent
);
1554 if (pScreen
->PostValidateTree
)
1555 (*pScreen
->PostValidateTree
) (pWin
->parent
, pWin
, VTOther
);
1558 WindowsRestructured();
1561 /* We need this as an addition since the xf86 common code doesn't
1562 know about the second tree which is static to this file. */
1565 miOverlaySetRootClip(ScreenPtr pScreen
, Bool enable
)
1567 WindowPtr pRoot
= pScreen
->root
;
1568 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pRoot
);
1570 MARK_UNDERLAY(pRoot
);
1577 box
.x2
= pScreen
->width
;
1578 box
.y2
= pScreen
->height
;
1580 RegionReset(&pTree
->borderClip
, &box
);
1583 RegionEmpty(&pTree
->borderClip
);
1585 RegionBreak(&pTree
->clipList
);
1589 miOverlayClearToBackground(WindowPtr pWin
,
1590 int x
, int y
, int w
, int h
, Bool generateExposures
)
1592 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1595 RegionPtr pBSReg
= NullRegion
;
1596 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1597 miOverlayScreenPtr pScreenPriv
= MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
);
1602 x1
= pWin
->drawable
.x
+ x
;
1603 y1
= pWin
->drawable
.y
+ y
;
1607 x2
= x1
+ (int) pWin
->drawable
.width
- (int) x
;
1611 y2
= y1
+ (int) pWin
->drawable
.height
- (int) y
;
1613 clipList
= ((*pScreenPriv
->InOverlay
) (pWin
)) ? &pWin
->clipList
:
1616 extents
= RegionExtents(clipList
);
1618 if (x1
< extents
->x1
)
1620 if (x2
> extents
->x2
)
1622 if (y1
< extents
->y1
)
1624 if (y2
> extents
->y2
)
1627 if (x2
<= x1
|| y2
<= y1
)
1628 x2
= x1
= y2
= y1
= 0;
1635 RegionInit(®
, &box
, 1);
1637 RegionIntersect(®
, ®
, clipList
);
1638 if (generateExposures
)
1639 (*pScreen
->WindowExposures
) (pWin
, ®
, pBSReg
);
1640 else if (pWin
->backgroundState
!= None
)
1641 miPaintWindow(pWin
, ®
, PW_BACKGROUND
);
1644 RegionDestroy(pBSReg
);
1647 /****************************************************************/
1651 miOverlayGetPrivateClips(WindowPtr pWin
,
1652 RegionPtr
*borderClip
, RegionPtr
*clipList
)
1654 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1657 *borderClip
= &(pTree
->borderClip
);
1658 *clipList
= &(pTree
->clipList
);
1662 *borderClip
= *clipList
= NULL
;
1668 miOverlaySetTransFunction(ScreenPtr pScreen
, miOverlayTransFunc transFunc
)
1670 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
)->MakeTransparent
= transFunc
;
1674 miOverlayCopyUnderlay(ScreenPtr pScreen
)
1676 return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen
)->copyUnderlay
;
1680 miOverlayComputeCompositeClip(GCPtr pGC
, WindowPtr pWin
)
1682 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1684 Bool freeTmpClip
, freeCompClip
;
1687 miComputeCompositeClip(pGC
, &pWin
->drawable
);
1691 if (pGC
->subWindowMode
== IncludeInferiors
) {
1692 pregWin
= RegionCreate(NullBox
, 1);
1694 if (pWin
->parent
|| (screenIsSaved
!= SCREEN_SAVER_ON
) ||
1695 !HasSaverWindow(pGC
->pScreen
)) {
1696 RegionIntersect(pregWin
, &pTree
->borderClip
, &pWin
->winSize
);
1700 pregWin
= &pTree
->clipList
;
1701 freeTmpClip
= FALSE
;
1703 freeCompClip
= pGC
->freeCompClip
;
1704 if (pGC
->clientClipType
== CT_NONE
) {
1706 RegionDestroy(pGC
->pCompositeClip
);
1707 pGC
->pCompositeClip
= pregWin
;
1708 pGC
->freeCompClip
= freeTmpClip
;
1711 RegionTranslate(pGC
->clientClip
,
1712 pWin
->drawable
.x
+ pGC
->clipOrg
.x
,
1713 pWin
->drawable
.y
+ pGC
->clipOrg
.y
);
1716 RegionIntersect(pGC
->pCompositeClip
, pregWin
, pGC
->clientClip
);
1718 RegionDestroy(pregWin
);
1720 else if (freeTmpClip
) {
1721 RegionIntersect(pregWin
, pregWin
, pGC
->clientClip
);
1722 pGC
->pCompositeClip
= pregWin
;
1725 pGC
->pCompositeClip
= RegionCreate(NullBox
, 0);
1726 RegionIntersect(pGC
->pCompositeClip
, pregWin
, pGC
->clientClip
);
1728 pGC
->freeCompClip
= TRUE
;
1729 RegionTranslate(pGC
->clientClip
,
1730 -(pWin
->drawable
.x
+ pGC
->clipOrg
.x
),
1731 -(pWin
->drawable
.y
+ pGC
->clipOrg
.y
));
1736 miOverlayCollectUnderlayRegions(WindowPtr pWin
, RegionPtr
*region
)
1738 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1741 *region
= &pTree
->borderClip
;
1745 *region
= RegionCreate(NullBox
, 0);
1747 CollectUnderlayChildrenRegions(pWin
, *region
);
1752 static miOverlayTreePtr
1753 DoLeaf(WindowPtr pWin
, miOverlayTreePtr parent
, miOverlayTreePtr prevSib
)
1755 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1757 pTree
->parent
= parent
;
1758 pTree
->firstChild
= NULL
;
1759 pTree
->lastChild
= NULL
;
1760 pTree
->prevSib
= prevSib
;
1761 pTree
->nextSib
= NULL
;
1764 prevSib
->nextSib
= pTree
;
1766 if (!parent
->firstChild
)
1767 parent
->firstChild
= parent
->lastChild
= pTree
;
1768 else if (parent
->lastChild
== prevSib
)
1769 parent
->lastChild
= pTree
;
1775 RebuildTree(WindowPtr pWin
)
1777 miOverlayTreePtr parent
, prevSib
, tChild
;
1780 prevSib
= tChild
= NULL
;
1782 pWin
= pWin
->parent
;
1784 while (IN_OVERLAY(pWin
))
1785 pWin
= pWin
->parent
;
1787 parent
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1789 pChild
= pWin
->firstChild
;
1790 parent
->firstChild
= parent
->lastChild
= NULL
;
1793 if (IN_UNDERLAY(pChild
))
1794 prevSib
= tChild
= DoLeaf(pChild
, parent
, prevSib
);
1796 if (pChild
->firstChild
) {
1797 if (IN_UNDERLAY(pChild
)) {
1801 pChild
= pChild
->firstChild
;
1805 while (!pChild
->nextSib
) {
1806 pChild
= pChild
->parent
;
1809 if (IN_UNDERLAY(pChild
)) {
1810 prevSib
= tChild
= MIOVERLAY_GET_WINDOW_TREE(pChild
);
1811 parent
= tChild
->parent
;
1815 pChild
= pChild
->nextSib
;
1820 HasUnderlayChildren(WindowPtr pWin
)
1824 if (!(pChild
= pWin
->firstChild
))
1828 if (IN_UNDERLAY(pChild
))
1831 if (pChild
->firstChild
) {
1832 pChild
= pChild
->firstChild
;
1836 while (!pChild
->nextSib
&& (pWin
!= pChild
))
1837 pChild
= pChild
->parent
;
1842 pChild
= pChild
->nextSib
;
1849 CollectUnderlayChildrenRegions(WindowPtr pWin
, RegionPtr pReg
)
1852 miOverlayTreePtr pTree
;
1855 if (!(pChild
= pWin
->firstChild
))
1858 hasUnderlay
= FALSE
;
1861 if ((pTree
= MIOVERLAY_GET_WINDOW_TREE(pChild
))) {
1862 RegionAppend(pReg
, &pTree
->borderClip
);
1865 else if (pChild
->firstChild
) {
1866 pChild
= pChild
->firstChild
;
1870 while (!pChild
->nextSib
&& (pWin
!= pChild
))
1871 pChild
= pChild
->parent
;
1876 pChild
= pChild
->nextSib
;
1882 RegionValidate(pReg
, &overlap
);
1889 MarkUnderlayWindow(WindowPtr pWin
)
1891 miOverlayTreePtr pTree
= MIOVERLAY_GET_WINDOW_TREE(pWin
);
1896 (miOverlayValDataPtr
) xnfalloc(sizeof(miOverlayValDataRec
));
1897 pTree
->valdata
->oldAbsCorner
.x
= pWin
->drawable
.x
;
1898 pTree
->valdata
->oldAbsCorner
.y
= pWin
->drawable
.y
;
1899 pTree
->valdata
->borderVisible
= NullRegion
;