1 
2 #ifdef HAVE_DIX_CONFIG_H
3 #include <dix-config.h>
4 #endif
5 
6 #include <X11/X.h>
7 #include "scrnintstr.h"
8 #include <X11/extensions/shapeproto.h>
9 #include "validate.h"
10 #include "windowstr.h"
11 #include "mi.h"
12 #include "gcstruct.h"
13 #include "regionstr.h"
14 #include "privates.h"
15 #include "mivalidate.h"
16 #include "mioverlay.h"
17 #include "migc.h"
18 
19 #include "globals.h"
20 
21 typedef struct {
22     RegionRec exposed;
23     RegionRec borderExposed;
24     RegionPtr borderVisible;
25     DDXPointRec oldAbsCorner;
26 } miOverlayValDataRec, *miOverlayValDataPtr;
27 
28 typedef struct _TreeRec {
29     WindowPtr pWin;
30     struct _TreeRec *parent;
31     struct _TreeRec *firstChild;
32     struct _TreeRec *lastChild;
33     struct _TreeRec *prevSib;
34     struct _TreeRec *nextSib;
35     RegionRec borderClip;
36     RegionRec clipList;
37     unsigned visibility;
38     miOverlayValDataPtr valdata;
39 } miOverlayTreeRec, *miOverlayTreePtr;
40 
41 typedef struct {
42     miOverlayTreePtr tree;
43 } miOverlayWindowRec, *miOverlayWindowPtr;
44 
45 typedef struct {
46     CloseScreenProcPtr CloseScreen;
47     CreateWindowProcPtr CreateWindow;
48     DestroyWindowProcPtr DestroyWindow;
49     UnrealizeWindowProcPtr UnrealizeWindow;
50     RealizeWindowProcPtr RealizeWindow;
51     miOverlayTransFunc MakeTransparent;
52     miOverlayInOverlayFunc InOverlay;
53     Bool underlayMarked;
54     Bool copyUnderlay;
55 } miOverlayScreenRec, *miOverlayScreenPtr;
56 
57 static DevPrivateKeyRec miOverlayWindowKeyRec;
58 
59 #define miOverlayWindowKey (&miOverlayWindowKeyRec)
60 static DevPrivateKeyRec miOverlayScreenKeyRec;
61 
62 #define miOverlayScreenKey (&miOverlayScreenKeyRec)
63 
64 static void RebuildTree(WindowPtr);
65 static Bool HasUnderlayChildren(WindowPtr);
66 static void MarkUnderlayWindow(WindowPtr);
67 static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
68 
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);
83 static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
84                                   unsigned int, WindowPtr);
85 static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
86 
87 static void miOverlaySetShape(WindowPtr, int);
88 static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
89 
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)
96 
97 #define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
98 #define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
99 
100 #define MARK_OVERLAY(w) miMarkWindow(w)
101 #define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
102 
103 #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
104                                     HasBorder(w) && \
105                                     (w)->backgroundState == ParentRelative)
106 
107 Bool
miInitOverlay(ScreenPtr pScreen,miOverlayInOverlayFunc inOverlayFunc,miOverlayTransFunc transFunc)108 miInitOverlay(ScreenPtr pScreen,
109               miOverlayInOverlayFunc inOverlayFunc,
110               miOverlayTransFunc transFunc)
111 {
112     miOverlayScreenPtr pScreenPriv;
113 
114     if (!inOverlayFunc || !transFunc)
115         return FALSE;
116 
117     if (!dixRegisterPrivateKey
118         (&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec)))
119         return FALSE;
120 
121     if (!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0))
122         return FALSE;
123 
124     if (!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
125         return FALSE;
126 
127     dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
128 
129     pScreenPriv->InOverlay = inOverlayFunc;
130     pScreenPriv->MakeTransparent = transFunc;
131     pScreenPriv->underlayMarked = FALSE;
132 
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;
138 
139     pScreen->CloseScreen = miOverlayCloseScreen;
140     pScreen->CreateWindow = miOverlayCreateWindow;
141     pScreen->DestroyWindow = miOverlayDestroyWindow;
142     pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
143     pScreen->RealizeWindow = miOverlayRealizeWindow;
144 
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;
158 
159     return TRUE;
160 }
161 
162 static Bool
miOverlayCloseScreen(ScreenPtr pScreen)163 miOverlayCloseScreen(ScreenPtr pScreen)
164 {
165     miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
166 
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;
172 
173     free(pScreenPriv);
174 
175     return (*pScreen->CloseScreen) (pScreen);
176 }
177 
178 static Bool
miOverlayCreateWindow(WindowPtr pWin)179 miOverlayCreateWindow(WindowPtr pWin)
180 {
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;
185     Bool result = TRUE;
186 
187     pWinPriv->tree = NULL;
188 
189     if (!pWin->parent || !((*pScreenPriv->InOverlay) (pWin))) {
190         if (!(pTree = (miOverlayTreePtr) calloc(1, sizeof(miOverlayTreeRec))))
191             return FALSE;
192     }
193 
194     if (pScreenPriv->CreateWindow) {
195         pScreen->CreateWindow = pScreenPriv->CreateWindow;
196         result = (*pScreen->CreateWindow) (pWin);
197         pScreen->CreateWindow = miOverlayCreateWindow;
198     }
199 
200     if (pTree) {
201         if (result) {
202             pTree->pWin = pWin;
203             pTree->visibility = VisibilityNotViewable;
204             pWinPriv->tree = pTree;
205             if (pWin->parent) {
206                 RegionNull(&(pTree->borderClip));
207                 RegionNull(&(pTree->clipList));
208                 RebuildTree(pWin);
209             }
210             else {
211                 BoxRec fullBox;
212 
213                 fullBox.x1 = 0;
214                 fullBox.y1 = 0;
215                 fullBox.x2 = pScreen->width;
216                 fullBox.y2 = pScreen->height;
217                 RegionInit(&(pTree->borderClip), &fullBox, 1);
218                 RegionInit(&(pTree->clipList), &fullBox, 1);
219             }
220         }
221         else
222             free(pTree);
223     }
224 
225     return TRUE;
226 }
227 
228 static Bool
miOverlayDestroyWindow(WindowPtr pWin)229 miOverlayDestroyWindow(WindowPtr pWin)
230 {
231     ScreenPtr pScreen = pWin->drawable.pScreen;
232     miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
233     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
234     Bool result = TRUE;
235 
236     if (pTree) {
237         if (pTree->prevSib)
238             pTree->prevSib->nextSib = pTree->nextSib;
239         else if (pTree->parent)
240             pTree->parent->firstChild = pTree->nextSib;
241 
242         if (pTree->nextSib)
243             pTree->nextSib->prevSib = pTree->prevSib;
244         else if (pTree->parent)
245             pTree->parent->lastChild = pTree->prevSib;
246 
247         RegionUninit(&(pTree->borderClip));
248         RegionUninit(&(pTree->clipList));
249         free(pTree);
250     }
251 
252     if (pScreenPriv->DestroyWindow) {
253         pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
254         result = (*pScreen->DestroyWindow) (pWin);
255         pScreen->DestroyWindow = miOverlayDestroyWindow;
256     }
257 
258     return result;
259 }
260 
261 static Bool
miOverlayUnrealizeWindow(WindowPtr pWin)262 miOverlayUnrealizeWindow(WindowPtr pWin)
263 {
264     ScreenPtr pScreen = pWin->drawable.pScreen;
265     miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
266     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
267     Bool result = TRUE;
268 
269     if (pTree)
270         pTree->visibility = VisibilityNotViewable;
271 
272     if (pScreenPriv->UnrealizeWindow) {
273         pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
274         result = (*pScreen->UnrealizeWindow) (pWin);
275         pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
276     }
277 
278     return result;
279 }
280 
281 static Bool
miOverlayRealizeWindow(WindowPtr pWin)282 miOverlayRealizeWindow(WindowPtr pWin)
283 {
284     ScreenPtr pScreen = pWin->drawable.pScreen;
285     miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
286     Bool result = TRUE;
287 
288     if (pScreenPriv->RealizeWindow) {
289         pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
290         result = (*pScreen->RealizeWindow) (pWin);
291         pScreen->RealizeWindow = miOverlayRealizeWindow;
292     }
293 
294     /* we only need to catch the root window realization */
295 
296     if (result && !pWin->parent && !((*pScreenPriv->InOverlay) (pWin))) {
297         BoxRec box;
298 
299         box.x1 = box.y1 = 0;
300         box.x2 = pWin->drawable.width;
301         box.y2 = pWin->drawable.height;
302         (*pScreenPriv->MakeTransparent) (pScreen, 1, &box);
303     }
304 
305     return result;
306 }
307 
308 static void
miOverlayReparentWindow(WindowPtr pWin,WindowPtr pPriorParent)309 miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
310 {
311     if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
312         /* This could probably be more optimal */
313         RebuildTree(pWin->drawable.pScreen->root->firstChild);
314     }
315 }
316 
317 static void
miOverlayRestackWindow(WindowPtr pWin,WindowPtr oldNextSib)318 miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
319 {
320     if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
321         /* This could probably be more optimal */
322         RebuildTree(pWin);
323     }
324 }
325 
326 static Bool
miOverlayMarkOverlappedWindows(WindowPtr pWin,WindowPtr pFirst,WindowPtr * pLayerWin)327 miOverlayMarkOverlappedWindows(WindowPtr pWin,
328                                WindowPtr pFirst, WindowPtr *pLayerWin)
329 {
330     WindowPtr pChild, pLast;
331     Bool overMarked, underMarked, doUnderlay, markAll;
332     miOverlayTreePtr pTree = NULL, tLast, tChild;
333     BoxPtr box;
334 
335     overMarked = underMarked = markAll = FALSE;
336 
337     if (pLayerWin)
338         *pLayerWin = pWin;      /* hah! */
339 
340     doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin));
341 
342     box = RegionExtents(&pWin->borderSize);
343 
344     if ((pChild = pFirst)) {
345         pLast = pChild->parent->lastChild;
346         while (1) {
347             if (pChild == pWin)
348                 markAll = TRUE;
349 
350             if (doUnderlay && IN_UNDERLAY(pChild))
351                 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
352 
353             if (pChild->viewable) {
354                 if (RegionBroken(&pChild->winSize))
355                     SetWinSize(pChild);
356                 if (RegionBroken(&pChild->borderSize))
357                     SetBorderSize(pChild);
358 
359                 if (markAll || RegionContainsRect(&pChild->borderSize, box)) {
360                     MARK_OVERLAY(pChild);
361                     overMarked = TRUE;
362                     if (doUnderlay && IN_UNDERLAY(pChild)) {
363                         MARK_UNDERLAY(pChild);
364                         underMarked = TRUE;
365                     }
366                     if (pChild->firstChild) {
367                         pChild = pChild->firstChild;
368                         continue;
369                     }
370                 }
371             }
372             while (!pChild->nextSib && (pChild != pLast)) {
373                 pChild = pChild->parent;
374                 if (doUnderlay && IN_UNDERLAY(pChild))
375                     pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
376             }
377 
378             if (pChild == pWin)
379                 markAll = FALSE;
380 
381             if (pChild == pLast)
382                 break;
383 
384             pChild = pChild->nextSib;
385         }
386         if (overMarked)
387             MARK_OVERLAY(pWin->parent);
388     }
389 
390     if (doUnderlay && !pTree) {
391         if (!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) {
392             pChild = pWin->lastChild;
393             while (1) {
394                 if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)))
395                     break;
396 
397                 if (pChild->lastChild) {
398                     pChild = pChild->lastChild;
399                     continue;
400                 }
401 
402                 while (!pChild->prevSib)
403                     pChild = pChild->parent;
404 
405                 pChild = pChild->prevSib;
406             }
407         }
408     }
409 
410     if (pTree && pTree->nextSib) {
411         tChild = pTree->parent->lastChild;
412         tLast = pTree->nextSib;
413 
414         while (1) {
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);
420 
421                 if (RegionContainsRect(&(tChild->pWin->borderSize), box)) {
422                     MARK_UNDERLAY(tChild->pWin);
423                     underMarked = TRUE;
424                 }
425             }
426 
427             if (tChild->lastChild) {
428                 tChild = tChild->lastChild;
429                 continue;
430             }
431 
432             while (!tChild->prevSib && (tChild != tLast))
433                 tChild = tChild->parent;
434 
435             if (tChild == tLast)
436                 break;
437 
438             tChild = tChild->prevSib;
439         }
440     }
441 
442     if (underMarked) {
443         ScreenPtr pScreen = pWin->drawable.pScreen;
444 
445         MARK_UNDERLAY(pTree->parent->pWin);
446         MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE;
447     }
448 
449     return underMarked || overMarked;
450 }
451 
452 static void
miOverlayComputeClips(WindowPtr pParent,RegionPtr universe,VTKind kind,RegionPtr exposed)453 miOverlayComputeClips(WindowPtr pParent,
454                       RegionPtr universe, VTKind kind, RegionPtr exposed)
455 {
456     ScreenPtr pScreen = pParent->drawable.pScreen;
457     int oldVis, newVis, dx, dy;
458     BoxRec borderSize;
459     RegionPtr borderVisible;
460     RegionRec childUniverse, childUnion;
461     miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent);
462     miOverlayTreePtr tChild;
463     Bool overlap;
464 
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);
469     if (dx > 32767)
470         dx = 32767;
471     borderSize.x2 = dx;
472     dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
473         wBorderWidth(pParent);
474     if (dy > 32767)
475         dy = 32767;
476     borderSize.y2 = dy;
477 
478     oldVis = tParent->visibility;
479     switch (RegionContainsRect(universe, &borderSize)) {
480     case rgnIN:
481         newVis = VisibilityUnobscured;
482         break;
483     case rgnPART:
484         newVis = VisibilityPartiallyObscured;
485         {
486             RegionPtr pBounding;
487 
488             if ((pBounding = wBoundingShape(pParent))) {
489                 switch (miShapedWindowIn(universe, pBounding,
490                                          &borderSize,
491                                          pParent->drawable.x,
492                                          pParent->drawable.y)) {
493                 case rgnIN:
494                     newVis = VisibilityUnobscured;
495                     break;
496                 case rgnOUT:
497                     newVis = VisibilityFullyObscured;
498                     break;
499                 }
500             }
501         }
502         break;
503     default:
504         newVis = VisibilityFullyObscured;
505         break;
506     }
507     tParent->visibility = newVis;
508 
509     dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x;
510     dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y;
511 
512     switch (kind) {
513     case VTMap:
514     case VTStack:
515     case VTUnmap:
516         break;
517     case VTMove:
518         if ((oldVis == newVis) &&
519             ((oldVis == VisibilityFullyObscured) ||
520              (oldVis == VisibilityUnobscured))) {
521             tChild = tParent;
522             while (1) {
523                 if (tChild->pWin->viewable) {
524                     if (tChild->visibility != VisibilityFullyObscured) {
525                         RegionTranslate(&tChild->borderClip, dx, dy);
526                         RegionTranslate(&tChild->clipList, dx, dy);
527 
528                         tChild->pWin->drawable.serialNumber =
529                             NEXT_SERIAL_NUMBER;
530                         if (pScreen->ClipNotify)
531                             (*pScreen->ClipNotify) (tChild->pWin, dx, dy);
532                     }
533                     if (tChild->valdata) {
534                         RegionNull(&tChild->valdata->borderExposed);
535                         if (HasParentRelativeBorder(tChild->pWin)) {
536                             RegionSubtract(&tChild->valdata->borderExposed,
537                                            &tChild->borderClip,
538                                            &tChild->pWin->winSize);
539                         }
540                         RegionNull(&tChild->valdata->exposed);
541                     }
542                     if (tChild->firstChild) {
543                         tChild = tChild->firstChild;
544                         continue;
545                     }
546                 }
547                 while (!tChild->nextSib && (tChild != tParent))
548                     tChild = tChild->parent;
549                 if (tChild == tParent)
550                     break;
551                 tChild = tChild->nextSib;
552             }
553             return;
554         }
555         /* fall through */
556     default:
557         if (dx || dy) {
558             RegionTranslate(&tParent->borderClip, dx, dy);
559             RegionTranslate(&tParent->clipList, dx, dy);
560         }
561         break;
562     case VTBroken:
563         RegionEmpty(&tParent->borderClip);
564         RegionEmpty(&tParent->clipList);
565         break;
566     }
567 
568     borderVisible = tParent->valdata->borderVisible;
569     RegionNull(&tParent->valdata->borderExposed);
570     RegionNull(&tParent->valdata->exposed);
571 
572     if (HasBorder(pParent)) {
573         if (borderVisible) {
574             RegionSubtract(exposed, universe, borderVisible);
575             RegionDestroy(borderVisible);
576         }
577         else
578             RegionSubtract(exposed, universe, &tParent->borderClip);
579 
580         if (HasParentRelativeBorder(pParent) && (dx || dy))
581             RegionSubtract(&tParent->valdata->borderExposed,
582                            universe, &pParent->winSize);
583         else
584             RegionSubtract(&tParent->valdata->borderExposed,
585                            exposed, &pParent->winSize);
586 
587         RegionCopy(&tParent->borderClip, universe);
588         RegionIntersect(universe, universe, &pParent->winSize);
589     }
590     else
591         RegionCopy(&tParent->borderClip, universe);
592 
593     if ((tChild = tParent->firstChild) && pParent->mapped) {
594         RegionNull(&childUniverse);
595         RegionNull(&childUnion);
596 
597         for (; tChild; tChild = tChild->nextSib) {
598             if (tChild->pWin->viewable)
599                 RegionAppend(&childUnion, &tChild->pWin->borderSize);
600         }
601 
602         RegionValidate(&childUnion, &overlap);
603 
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,
610                                           kind, exposed);
611                 }
612                 if (overlap)
613                     RegionSubtract(universe, universe,
614                                    &tChild->pWin->borderSize);
615             }
616         }
617         if (!overlap)
618             RegionSubtract(universe, universe, &childUnion);
619         RegionUninit(&childUnion);
620         RegionUninit(&childUniverse);
621     }
622 
623     if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) {
624         RegionCopy(&tParent->valdata->exposed, universe);
625     }
626     else if (newVis != VisibilityFullyObscured &&
627              newVis != VisibilityNotViewable) {
628         RegionSubtract(&tParent->valdata->exposed,
629                        universe, &tParent->clipList);
630     }
631 
632     /* HACK ALERT - copying contents of regions, instead of regions */
633     {
634         RegionRec tmp;
635 
636         tmp = tParent->clipList;
637         tParent->clipList = *universe;
638         *universe = tmp;
639     }
640 
641     pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
642 
643     if (pScreen->ClipNotify)
644         (*pScreen->ClipNotify) (pParent, dx, dy);
645 }
646 
647 static void
miOverlayMarkWindow(WindowPtr pWin)648 miOverlayMarkWindow(WindowPtr pWin)
649 {
650     miOverlayTreePtr pTree = NULL;
651     WindowPtr pChild, pGrandChild;
652 
653     miMarkWindow(pWin);
654 
655     /* look for UnmapValdata among immediate children */
656 
657     if (!(pChild = pWin->firstChild))
658         return;
659 
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;
665                 continue;
666             }
667             else {
668                 if (!(pGrandChild = pChild->firstChild))
669                     continue;
670 
671                 while (1) {
672                     if (IN_UNDERLAY(pGrandChild)) {
673                         pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild);
674                         pTree->valdata = (miOverlayValDataPtr) UnmapValData;
675                     }
676                     else if (pGrandChild->firstChild) {
677                         pGrandChild = pGrandChild->firstChild;
678                         continue;
679                     }
680 
681                     while (!pGrandChild->nextSib && (pGrandChild != pChild))
682                         pGrandChild = pGrandChild->parent;
683 
684                     if (pChild == pGrandChild)
685                         break;
686 
687                     pGrandChild = pGrandChild->nextSib;
688                 }
689             }
690         }
691     }
692 
693     if (pTree) {
694         MARK_UNDERLAY(pTree->parent->pWin);
695         MIOVERLAY_GET_SCREEN_PRIVATE(pWin->drawable.pScreen)->underlayMarked =
696             TRUE;
697     }
698 }
699 
700 static void
miOverlayMarkUnrealizedWindow(WindowPtr pChild,WindowPtr pWin,Bool fromConfigure)701 miOverlayMarkUnrealizedWindow(WindowPtr pChild,
702                               WindowPtr pWin, Bool fromConfigure)
703 {
704     if ((pChild != pWin) || fromConfigure) {
705         miOverlayTreePtr pTree;
706 
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);
715             }
716         }
717     }
718 }
719 
720 static int
miOverlayValidateTree(WindowPtr pParent,WindowPtr pChild,VTKind kind)721 miOverlayValidateTree(WindowPtr pParent, WindowPtr pChild,      /* first child effected */
722                       VTKind kind)
723 {
724     ScreenPtr pScreen = pParent->drawable.pScreen;
725     miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
726     RegionRec totalClip, childClip, exposed;
727     miOverlayTreePtr tParent, tChild, tWin;
728     Bool overlap;
729     WindowPtr newParent;
730 
731     if (!pPriv->underlayMarked)
732         goto SKIP_UNDERLAY;
733 
734     if (!pChild)
735         pChild = pParent->firstChild;
736 
737     RegionNull(&totalClip);
738     RegionNull(&childClip);
739     RegionNull(&exposed);
740 
741     newParent = pParent;
742 
743     while (IN_OVERLAY(newParent))
744         newParent = newParent->parent;
745 
746     tParent = MIOVERLAY_GET_WINDOW_TREE(newParent);
747 
748     if (IN_UNDERLAY(pChild))
749         tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
750     else
751         tChild = tParent->firstChild;
752 
753     if (RegionBroken(&tParent->clipList) && !RegionBroken(&tParent->borderClip)) {
754         kind = VTBroken;
755         RegionCopy(&totalClip, &tParent->borderClip);
756         RegionIntersect(&totalClip, &totalClip, &tParent->pWin->winSize);
757 
758         for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
759             if (tWin->pWin->viewable)
760                 RegionSubtract(&totalClip, &totalClip, &tWin->pWin->borderSize);
761         }
762         RegionEmpty(&tParent->clipList);
763     }
764     else {
765         for (tWin = tChild; tWin; tWin = tWin->nextSib) {
766             if (tWin->valdata)
767                 RegionAppend(&totalClip, &tWin->borderClip);
768         }
769         RegionValidate(&totalClip, &overlap);
770     }
771 
772     if (kind != VTStack)
773         RegionUnion(&totalClip, &totalClip, &tParent->clipList);
774 
775     for (tWin = tChild; tWin; tWin = tWin->nextSib) {
776         if (tWin->valdata) {
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);
782             }
783             else {              /* Means we are unmapping */
784                 RegionEmpty(&tWin->clipList);
785                 RegionEmpty(&tWin->borderClip);
786                 tWin->valdata = NULL;
787             }
788         }
789     }
790 
791     RegionUninit(&childClip);
792 
793     if (!((*pPriv->InOverlay) (newParent))) {
794         RegionNull(&tParent->valdata->exposed);
795         RegionNull(&tParent->valdata->borderExposed);
796     }
797 
798     switch (kind) {
799     case VTStack:
800         break;
801     default:
802         if (!((*pPriv->InOverlay) (newParent)))
803             RegionSubtract(&tParent->valdata->exposed, &totalClip,
804                            &tParent->clipList);
805         /* fall through */
806     case VTMap:
807         RegionCopy(&tParent->clipList, &totalClip);
808         if (!((*pPriv->InOverlay) (newParent)))
809             newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
810         break;
811     }
812 
813     RegionUninit(&totalClip);
814     RegionUninit(&exposed);
815 
816  SKIP_UNDERLAY:
817 
818     miValidateTree(pParent, pChild, kind);
819 
820     return 1;
821 }
822 
823 static void
miOverlayHandleExposures(WindowPtr pWin)824 miOverlayHandleExposures(WindowPtr pWin)
825 {
826     ScreenPtr pScreen = pWin->drawable.pScreen;
827     miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
828     WindowPtr pChild;
829     ValidatePtr val;
830     WindowExposuresProcPtr WindowExposures;
831 
832     WindowExposures = pWin->drawable.pScreen->WindowExposures;
833     if (pPriv->underlayMarked) {
834         miOverlayTreePtr pTree;
835         miOverlayValDataPtr mival;
836 
837         pChild = pWin;
838         while (IN_OVERLAY(pChild))
839             pChild = pChild->parent;
840 
841         pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
842 
843         while (1) {
844             if ((mival = pTree->valdata)) {
845                 if (!((*pPriv->InOverlay) (pTree->pWin))) {
846                     if (RegionNotEmpty(&mival->borderExposed)) {
847                         pScreen->PaintWindow(pTree->pWin, &mival->borderExposed,
848                                              PW_BORDER);
849                     }
850                     RegionUninit(&mival->borderExposed);
851 
852                     (*WindowExposures) (pTree->pWin, &mival->exposed);
853                     RegionUninit(&mival->exposed);
854                 }
855                 free(mival);
856                 pTree->valdata = NULL;
857                 if (pTree->firstChild) {
858                     pTree = pTree->firstChild;
859                     continue;
860                 }
861             }
862             while (!pTree->nextSib && (pTree->pWin != pChild))
863                 pTree = pTree->parent;
864             if (pTree->pWin == pChild)
865                 break;
866             pTree = pTree->nextSib;
867         }
868         pPriv->underlayMarked = FALSE;
869     }
870 
871     pChild = pWin;
872     while (1) {
873         if ((val = pChild->valdata)) {
874             if (!((*pPriv->InOverlay) (pChild))) {
875                 RegionUnion(&val->after.exposed, &val->after.exposed,
876                             &val->after.borderExposed);
877 
878                 if (RegionNotEmpty(&val->after.exposed)) {
879                     (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))
880                         (pScreen, RegionNumRects(&val->after.exposed),
881                          RegionRects(&val->after.exposed));
882                 }
883             }
884             else {
885                 if (RegionNotEmpty(&val->after.borderExposed)) {
886                     pScreen->PaintWindow(pChild, &val->after.borderExposed,
887                                          PW_BORDER);
888                 }
889                 (*WindowExposures) (pChild, &val->after.exposed);
890             }
891             RegionUninit(&val->after.borderExposed);
892             RegionUninit(&val->after.exposed);
893             free(val);
894             pChild->valdata = NULL;
895             if (pChild->firstChild) {
896                 pChild = pChild->firstChild;
897                 continue;
898             }
899         }
900         while (!pChild->nextSib && (pChild != pWin))
901             pChild = pChild->parent;
902         if (pChild == pWin)
903             break;
904         pChild = pChild->nextSib;
905     }
906 }
907 
908 static void
miOverlayMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pNextSib,VTKind kind)909 miOverlayMoveWindow(WindowPtr pWin,
910                     int x, int y, WindowPtr pNextSib, VTKind kind)
911 {
912     ScreenPtr pScreen = pWin->drawable.pScreen;
913     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
914     WindowPtr pParent, windowToValidate;
915     Bool WasViewable = (Bool) (pWin->viewable);
916     short bw;
917     RegionRec overReg, underReg;
918     DDXPointRec oldpt;
919 
920     if (!(pParent = pWin->parent))
921         return;
922     bw = wBorderWidth(pWin);
923 
924     oldpt.x = pWin->drawable.x;
925     oldpt.y = pWin->drawable.y;
926     if (WasViewable) {
927         RegionNull(&overReg);
928         RegionNull(&underReg);
929         if (pTree) {
930             RegionCopy(&overReg, &pWin->borderClip);
931             RegionCopy(&underReg, &pTree->borderClip);
932         }
933         else {
934             RegionCopy(&overReg, &pWin->borderClip);
935             CollectUnderlayChildrenRegions(pWin, &underReg);
936         }
937         (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
938     }
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;
943 
944     SetWinSize(pWin);
945     SetBorderSize(pWin);
946 
947     (*pScreen->PositionWindow) (pWin, x, y);
948 
949     windowToValidate = MoveWindowInStack(pWin, pNextSib);
950 
951     ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
952 
953     if (WasViewable) {
954         miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
955 
956         (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL);
957 
958         (*pScreen->ValidateTree) (pWin->parent, NullWindow, kind);
959         if (RegionNotEmpty(&underReg)) {
960             pPriv->copyUnderlay = TRUE;
961             (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &underReg);
962         }
963         RegionUninit(&underReg);
964         if (RegionNotEmpty(&overReg)) {
965             pPriv->copyUnderlay = FALSE;
966             (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &overReg);
967         }
968         RegionUninit(&overReg);
969         (*pScreen->HandleExposures) (pWin->parent);
970 
971         if (pScreen->PostValidateTree)
972             (*pScreen->PostValidateTree) (pWin->parent, NullWindow, kind);
973     }
974     if (pWin->realized)
975         WindowsRestructured();
976 }
977 
978 #ifndef RECTLIMIT
979 #define RECTLIMIT 25
980 #endif
981 
982 static void
miOverlayWindowExposures(WindowPtr pWin,RegionPtr prgn)983 miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn)
984 {
985     RegionPtr exposures = prgn;
986     ScreenPtr pScreen = pWin->drawable.pScreen;
987 
988     if (prgn && !RegionNil(prgn)) {
989         RegionRec expRec;
990         int clientInterested =
991             (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask;
992         if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) {
993             miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
994             BoxRec box;
995 
996             box = *RegionExtents(prgn);
997             exposures = &expRec;
998             RegionInit(exposures, &box, 1);
999             RegionReset(prgn, &box);
1000             /* This is the only reason why we are replacing mi's version
1001                of this file */
1002 
1003             if (!((*pPriv->InOverlay) (pWin))) {
1004                 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1005 
1006                 RegionIntersect(prgn, prgn, &pTree->clipList);
1007             }
1008             else
1009                 RegionIntersect(prgn, prgn, &pWin->clipList);
1010         }
1011         pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND);
1012         if (clientInterested)
1013             miSendExposures(pWin, exposures,
1014                             pWin->drawable.x, pWin->drawable.y);
1015         if (exposures == &expRec)
1016             RegionUninit(exposures);
1017         RegionEmpty(prgn);
1018     }
1019 }
1020 
1021 typedef struct {
1022     RegionPtr over;
1023     RegionPtr under;
1024 } miOverlayTwoRegions;
1025 
1026 static int
miOverlayRecomputeExposures(WindowPtr pWin,void * value)1027 miOverlayRecomputeExposures(WindowPtr pWin, void *value)
1028 {
1029     miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value;
1030     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1031 
1032     if (pWin->valdata) {
1033         /*
1034          * compute exposed regions of this window
1035          */
1036         RegionSubtract(&pWin->valdata->after.exposed,
1037                        &pWin->clipList, pValid->over);
1038         /*
1039          * compute exposed regions of the border
1040          */
1041         RegionSubtract(&pWin->valdata->after.borderExposed,
1042                        &pWin->borderClip, &pWin->winSize);
1043         RegionSubtract(&pWin->valdata->after.borderExposed,
1044                        &pWin->valdata->after.borderExposed, pValid->over);
1045     }
1046 
1047     if (pTree && pTree->valdata) {
1048         RegionSubtract(&pTree->valdata->exposed,
1049                        &pTree->clipList, pValid->under);
1050         RegionSubtract(&pTree->valdata->borderExposed,
1051                        &pTree->borderClip, &pWin->winSize);
1052         RegionSubtract(&pTree->valdata->borderExposed,
1053                        &pTree->valdata->borderExposed, pValid->under);
1054     }
1055     else if (!pWin->valdata)
1056         return WT_NOMATCH;
1057 
1058     return WT_WALKCHILDREN;
1059 }
1060 
1061 static void
miOverlayResizeWindow(WindowPtr pWin,int x,int y,unsigned int w,unsigned int h,WindowPtr pSib)1062 miOverlayResizeWindow(WindowPtr pWin,
1063                       int x, int y,
1064                       unsigned int w, unsigned int h, WindowPtr pSib)
1065 {
1066     ScreenPtr pScreen = pWin->drawable.pScreen;
1067     WindowPtr pParent;
1068     miOverlayTreePtr tChild, pTree;
1069     Bool WasViewable = (Bool) (pWin->viewable);
1070     unsigned short width = pWin->drawable.width;
1071     unsigned short height = pWin->drawable.height;
1072     short oldx = pWin->drawable.x;
1073     short oldy = pWin->drawable.y;
1074     int bw = wBorderWidth(pWin);
1075     short dw, dh;
1076     DDXPointRec oldpt;
1077     RegionPtr oldRegion = NULL, oldRegion2 = NULL;
1078     WindowPtr pFirstChange;
1079     WindowPtr pChild;
1080     RegionPtr gravitate[StaticGravity + 1];
1081     RegionPtr gravitate2[StaticGravity + 1];
1082     unsigned g;
1083     int nx, ny;                 /* destination x,y */
1084     int newx, newy;             /* new inner window position */
1085     RegionPtr pRegion = NULL;
1086     RegionPtr destClip, destClip2;
1087     RegionPtr oldWinClip = NULL, oldWinClip2 = NULL;
1088     RegionPtr borderVisible = NullRegion;
1089     RegionPtr borderVisible2 = NullRegion;
1090     Bool shrunk = FALSE;        /* shrunk in an inner dimension */
1091     Bool moved = FALSE;         /* window position changed */
1092     Bool doUnderlay;
1093 
1094     /* if this is a root window, can't be resized */
1095     if (!(pParent = pWin->parent))
1096         return;
1097 
1098     pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1099     doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
1100     newx = pParent->drawable.x + x + bw;
1101     newy = pParent->drawable.y + y + bw;
1102     if (WasViewable) {
1103         /*
1104          * save the visible region of the window
1105          */
1106         oldRegion = RegionCreate(NullBox, 1);
1107         RegionCopy(oldRegion, &pWin->winSize);
1108         if (doUnderlay) {
1109             oldRegion2 = RegionCreate(NullBox, 1);
1110             RegionCopy(oldRegion2, &pWin->winSize);
1111         }
1112 
1113         /*
1114          * categorize child windows into regions to be moved
1115          */
1116         for (g = 0; g <= StaticGravity; g++)
1117             gravitate[g] = gravitate2[g] = NULL;
1118         for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
1119             g = pChild->winGravity;
1120             if (g != UnmapGravity) {
1121                 if (!gravitate[g])
1122                     gravitate[g] = RegionCreate(NullBox, 1);
1123                 RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip);
1124 
1125                 if (doUnderlay) {
1126                     if (!gravitate2[g])
1127                         gravitate2[g] = RegionCreate(NullBox, 0);
1128 
1129                     if ((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
1130                         RegionUnion(gravitate2[g],
1131                                     gravitate2[g], &tChild->borderClip);
1132                     }
1133                     else
1134                         CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
1135                 }
1136             }
1137             else {
1138                 UnmapWindow(pChild, TRUE);
1139             }
1140         }
1141         (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
1142 
1143         oldWinClip = oldWinClip2 = NULL;
1144         if (pWin->bitGravity != ForgetGravity) {
1145             oldWinClip = RegionCreate(NullBox, 1);
1146             RegionCopy(oldWinClip, &pWin->clipList);
1147             if (pTree) {
1148                 oldWinClip2 = RegionCreate(NullBox, 1);
1149                 RegionCopy(oldWinClip2, &pTree->clipList);
1150             }
1151         }
1152         /*
1153          * if the window is changing size, borderExposed
1154          * can't be computed correctly without some help.
1155          */
1156         if (pWin->drawable.height > h || pWin->drawable.width > w)
1157             shrunk = TRUE;
1158 
1159         if (newx != oldx || newy != oldy)
1160             moved = TRUE;
1161 
1162         if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
1163             HasBorder(pWin)) {
1164             borderVisible = RegionCreate(NullBox, 1);
1165             if (pTree)
1166                 borderVisible2 = RegionCreate(NullBox, 1);
1167             /* for tiled borders, we punt and draw the whole thing */
1168             if (pWin->borderIsPixel || !moved) {
1169                 if (shrunk || moved)
1170                     RegionSubtract(borderVisible,
1171                                    &pWin->borderClip, &pWin->winSize);
1172                 else
1173                     RegionCopy(borderVisible, &pWin->borderClip);
1174                 if (pTree) {
1175                     if (shrunk || moved)
1176                         RegionSubtract(borderVisible,
1177                                        &pTree->borderClip, &pWin->winSize);
1178                     else
1179                         RegionCopy(borderVisible, &pTree->borderClip);
1180                 }
1181             }
1182         }
1183     }
1184     pWin->origin.x = x + bw;
1185     pWin->origin.y = y + bw;
1186     pWin->drawable.height = h;
1187     pWin->drawable.width = w;
1188 
1189     x = pWin->drawable.x = newx;
1190     y = pWin->drawable.y = newy;
1191 
1192     SetWinSize(pWin);
1193     SetBorderSize(pWin);
1194 
1195     dw = (int) w - (int) width;
1196     dh = (int) h - (int) height;
1197     ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
1198 
1199     /* let the hardware adjust background and border pixmaps, if any */
1200     (*pScreen->PositionWindow) (pWin, x, y);
1201 
1202     pFirstChange = MoveWindowInStack(pWin, pSib);
1203 
1204     if (WasViewable) {
1205         pRegion = RegionCreate(NullBox, 1);
1206 
1207         (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL);
1208 
1209         pWin->valdata->before.resized = TRUE;
1210         pWin->valdata->before.borderVisible = borderVisible;
1211         if (pTree)
1212             pTree->valdata->borderVisible = borderVisible2;
1213 
1214         (*pScreen->ValidateTree) (pWin->parent, pFirstChange, VTOther);
1215         /*
1216          * the entire window is trashed unless bitGravity
1217          * recovers portions of it
1218          */
1219         RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
1220         if (pTree)
1221             RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
1222     }
1223 
1224     GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
1225 
1226     if (WasViewable) {
1227         miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
1228         miOverlayTwoRegions TwoRegions;
1229 
1230         /* avoid the border */
1231         if (HasBorder(pWin)) {
1232             int offx, offy, dx, dy;
1233 
1234             /* kruft to avoid double translates for each gravity */
1235             offx = 0;
1236             offy = 0;
1237             for (g = 0; g <= StaticGravity; g++) {
1238                 if (!gravitate[g] && !gravitate2[g])
1239                     continue;
1240 
1241                 /* align winSize to gravitate[g].
1242                  * winSize is in new coordinates,
1243                  * gravitate[g] is still in old coordinates */
1244                 GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
1245 
1246                 dx = (oldx - nx) - offx;
1247                 dy = (oldy - ny) - offy;
1248                 if (dx || dy) {
1249                     RegionTranslate(&pWin->winSize, dx, dy);
1250                     offx += dx;
1251                     offy += dy;
1252                 }
1253                 if (gravitate[g])
1254                     RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize);
1255                 if (gravitate2[g])
1256                     RegionIntersect(gravitate2[g], gravitate2[g],
1257                                     &pWin->winSize);
1258             }
1259             /* get winSize back where it belongs */
1260             if (offx || offy)
1261                 RegionTranslate(&pWin->winSize, -offx, -offy);
1262         }
1263         /*
1264          * add screen bits to the appropriate bucket
1265          */
1266 
1267         if (oldWinClip2) {
1268             RegionCopy(pRegion, oldWinClip2);
1269             RegionTranslate(pRegion, nx - oldx, ny - oldy);
1270             RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
1271 
1272             for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
1273                 if (gravitate2[g])
1274                     RegionSubtract(oldWinClip2, oldWinClip2, gravitate2[g]);
1275             }
1276             RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
1277             g = pWin->bitGravity;
1278             if (!gravitate2[g])
1279                 gravitate2[g] = oldWinClip2;
1280             else {
1281                 RegionUnion(gravitate2[g], gravitate2[g], oldWinClip2);
1282                 RegionDestroy(oldWinClip2);
1283             }
1284         }
1285 
1286         if (oldWinClip) {
1287             /*
1288              * clip to new clipList
1289              */
1290             RegionCopy(pRegion, oldWinClip);
1291             RegionTranslate(pRegion, nx - oldx, ny - oldy);
1292             RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
1293             /*
1294              * don't step on any gravity bits which will be copied after this
1295              * region.  Note -- this assumes that the regions will be copied
1296              * in gravity order.
1297              */
1298             for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
1299                 if (gravitate[g])
1300                     RegionSubtract(oldWinClip, oldWinClip, gravitate[g]);
1301             }
1302             RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
1303             g = pWin->bitGravity;
1304             if (!gravitate[g])
1305                 gravitate[g] = oldWinClip;
1306             else {
1307                 RegionUnion(gravitate[g], gravitate[g], oldWinClip);
1308                 RegionDestroy(oldWinClip);
1309             }
1310         }
1311 
1312         /*
1313          * move the bits on the screen
1314          */
1315 
1316         destClip = destClip2 = NULL;
1317 
1318         for (g = 0; g <= StaticGravity; g++) {
1319             if (!gravitate[g] && !gravitate2[g])
1320                 continue;
1321 
1322             GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
1323 
1324             oldpt.x = oldx + (x - nx);
1325             oldpt.y = oldy + (y - ny);
1326 
1327             /* Note that gravitate[g] is *translated* by CopyWindow */
1328 
1329             /* only copy the remaining useful bits */
1330 
1331             if (gravitate[g])
1332                 RegionIntersect(gravitate[g], gravitate[g], oldRegion);
1333             if (gravitate2[g])
1334                 RegionIntersect(gravitate2[g], gravitate2[g], oldRegion2);
1335 
1336             /* clip to not overwrite already copied areas */
1337 
1338             if (destClip && gravitate[g]) {
1339                 RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
1340                 RegionSubtract(gravitate[g], gravitate[g], destClip);
1341                 RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
1342             }
1343             if (destClip2 && gravitate2[g]) {
1344                 RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
1345                 RegionSubtract(gravitate2[g], gravitate2[g], destClip2);
1346                 RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
1347             }
1348 
1349             /* and move those bits */
1350 
1351             if (oldpt.x != x || oldpt.y != y) {
1352                 if (gravitate2[g]) {
1353                     pPriv->copyUnderlay = TRUE;
1354                     (*pScreen->CopyWindow) (pWin, oldpt, gravitate2[g]);
1355                 }
1356                 if (gravitate[g]) {
1357                     pPriv->copyUnderlay = FALSE;
1358                     (*pScreen->CopyWindow) (pWin, oldpt, gravitate[g]);
1359                 }
1360             }
1361 
1362             /* remove any overwritten bits from the remaining useful bits */
1363 
1364             if (gravitate[g])
1365                 RegionSubtract(oldRegion, oldRegion, gravitate[g]);
1366             if (gravitate2[g])
1367                 RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
1368 
1369             /*
1370              * recompute exposed regions of child windows
1371              */
1372 
1373             for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
1374                 if (pChild->winGravity != g)
1375                     continue;
1376 
1377                 TwoRegions.over = gravitate[g];
1378                 TwoRegions.under = gravitate2[g];
1379 
1380                 TraverseTree(pChild, miOverlayRecomputeExposures,
1381                              (void *) (&TwoRegions));
1382             }
1383 
1384             /*
1385              * remove the successfully copied regions of the
1386              * window from its exposed region
1387              */
1388 
1389             if (g == pWin->bitGravity) {
1390                 if (gravitate[g])
1391                     RegionSubtract(&pWin->valdata->after.exposed,
1392                                    &pWin->valdata->after.exposed, gravitate[g]);
1393                 if (gravitate2[g] && pTree)
1394                     RegionSubtract(&pTree->valdata->exposed,
1395                                    &pTree->valdata->exposed, gravitate2[g]);
1396             }
1397             if (gravitate[g]) {
1398                 if (!destClip)
1399                     destClip = gravitate[g];
1400                 else {
1401                     RegionUnion(destClip, destClip, gravitate[g]);
1402                     RegionDestroy(gravitate[g]);
1403                 }
1404             }
1405             if (gravitate2[g]) {
1406                 if (!destClip2)
1407                     destClip2 = gravitate2[g];
1408                 else {
1409                     RegionUnion(destClip2, destClip2, gravitate2[g]);
1410                     RegionDestroy(gravitate2[g]);
1411                 }
1412             }
1413         }
1414 
1415         RegionDestroy(pRegion);
1416         RegionDestroy(oldRegion);
1417         if (doUnderlay)
1418             RegionDestroy(oldRegion2);
1419         if (destClip)
1420             RegionDestroy(destClip);
1421         if (destClip2)
1422             RegionDestroy(destClip2);
1423         (*pScreen->HandleExposures) (pWin->parent);
1424         if (pScreen->PostValidateTree)
1425             (*pScreen->PostValidateTree) (pWin->parent, pFirstChange, VTOther);
1426     }
1427     if (pWin->realized)
1428         WindowsRestructured();
1429 }
1430 
1431 static void
miOverlaySetShape(WindowPtr pWin,int kind)1432 miOverlaySetShape(WindowPtr pWin, int kind)
1433 {
1434     Bool WasViewable = (Bool) (pWin->viewable);
1435     ScreenPtr pScreen = pWin->drawable.pScreen;
1436 
1437     if (kind != ShapeInput) {
1438         if (WasViewable) {
1439             (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
1440 
1441             if (HasBorder(pWin)) {
1442                 RegionPtr borderVisible;
1443 
1444                 borderVisible = RegionCreate(NullBox, 1);
1445                 RegionSubtract(borderVisible,
1446                                &pWin->borderClip, &pWin->winSize);
1447                 pWin->valdata->before.borderVisible = borderVisible;
1448                 pWin->valdata->before.resized = TRUE;
1449                 if (IN_UNDERLAY(pWin)) {
1450                     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1451                     RegionPtr borderVisible2;
1452 
1453                     borderVisible2 = RegionCreate(NULL, 1);
1454                     RegionSubtract(borderVisible2,
1455                                    &pTree->borderClip, &pWin->winSize);
1456                     pTree->valdata->borderVisible = borderVisible2;
1457                 }
1458             }
1459         }
1460 
1461         SetWinSize(pWin);
1462         SetBorderSize(pWin);
1463 
1464         ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
1465 
1466         if (WasViewable) {
1467             (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
1468             (*pScreen->ValidateTree) (pWin->parent, NullWindow, VTOther);
1469             (*pScreen->HandleExposures) (pWin->parent);
1470             if (pScreen->PostValidateTree)
1471                 (*pScreen->PostValidateTree) (pWin->parent, NullWindow,
1472                                               VTOther);
1473         }
1474     }
1475     if (pWin->realized)
1476         WindowsRestructured();
1477     CheckCursorConfinement(pWin);
1478 }
1479 
1480 static void
miOverlayChangeBorderWidth(WindowPtr pWin,unsigned int width)1481 miOverlayChangeBorderWidth(WindowPtr pWin, unsigned int width)
1482 {
1483     int oldwidth;
1484     ScreenPtr pScreen;
1485     Bool WasViewable = (Bool) (pWin->viewable);
1486     Bool HadBorder;
1487 
1488     oldwidth = wBorderWidth(pWin);
1489     if (oldwidth == width)
1490         return;
1491     HadBorder = HasBorder(pWin);
1492     pScreen = pWin->drawable.pScreen;
1493     if (WasViewable && (width < oldwidth))
1494         (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
1495 
1496     pWin->borderWidth = width;
1497     SetBorderSize(pWin);
1498 
1499     if (WasViewable) {
1500         if (width > oldwidth) {
1501             (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
1502 
1503             if (HadBorder) {
1504                 RegionPtr borderVisible;
1505 
1506                 borderVisible = RegionCreate(NULL, 1);
1507                 RegionSubtract(borderVisible,
1508                                &pWin->borderClip, &pWin->winSize);
1509                 pWin->valdata->before.borderVisible = borderVisible;
1510                 if (IN_UNDERLAY(pWin)) {
1511                     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1512                     RegionPtr borderVisible2;
1513 
1514                     borderVisible2 = RegionCreate(NULL, 1);
1515                     RegionSubtract(borderVisible2,
1516                                    &pTree->borderClip, &pWin->winSize);
1517                     pTree->valdata->borderVisible = borderVisible2;
1518                 }
1519             }
1520         }
1521         (*pScreen->ValidateTree) (pWin->parent, pWin, VTOther);
1522         (*pScreen->HandleExposures) (pWin->parent);
1523 
1524         if (pScreen->PostValidateTree)
1525             (*pScreen->PostValidateTree) (pWin->parent, pWin, VTOther);
1526     }
1527     if (pWin->realized)
1528         WindowsRestructured();
1529 }
1530 
1531 /*  We need this as an addition since the xf86 common code doesn't
1532     know about the second tree which is static to this file.  */
1533 
1534 void
miOverlaySetRootClip(ScreenPtr pScreen,Bool enable)1535 miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
1536 {
1537     WindowPtr pRoot = pScreen->root;
1538     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
1539 
1540     MARK_UNDERLAY(pRoot);
1541 
1542     if (enable) {
1543         BoxRec box;
1544 
1545         box.x1 = 0;
1546         box.y1 = 0;
1547         box.x2 = pScreen->width;
1548         box.y2 = pScreen->height;
1549 
1550         RegionReset(&pTree->borderClip, &box);
1551     }
1552     else
1553         RegionEmpty(&pTree->borderClip);
1554 
1555     RegionBreak(&pTree->clipList);
1556 }
1557 
1558 static void
miOverlayClearToBackground(WindowPtr pWin,int x,int y,int w,int h,Bool generateExposures)1559 miOverlayClearToBackground(WindowPtr pWin,
1560                            int x, int y, int w, int h, Bool generateExposures)
1561 {
1562     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1563     BoxRec box;
1564     RegionRec reg;
1565     ScreenPtr pScreen = pWin->drawable.pScreen;
1566     miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
1567     RegionPtr clipList;
1568     BoxPtr extents;
1569     int x1, y1, x2, y2;
1570 
1571     x1 = pWin->drawable.x + x;
1572     y1 = pWin->drawable.y + y;
1573     if (w)
1574         x2 = x1 + (int) w;
1575     else
1576         x2 = x1 + (int) pWin->drawable.width - (int) x;
1577     if (h)
1578         y2 = y1 + h;
1579     else
1580         y2 = y1 + (int) pWin->drawable.height - (int) y;
1581 
1582     clipList = ((*pScreenPriv->InOverlay) (pWin)) ? &pWin->clipList :
1583         &pTree->clipList;
1584 
1585     extents = RegionExtents(clipList);
1586 
1587     if (x1 < extents->x1)
1588         x1 = extents->x1;
1589     if (x2 > extents->x2)
1590         x2 = extents->x2;
1591     if (y1 < extents->y1)
1592         y1 = extents->y1;
1593     if (y2 > extents->y2)
1594         y2 = extents->y2;
1595 
1596     if (x2 <= x1 || y2 <= y1)
1597         x2 = x1 = y2 = y1 = 0;
1598 
1599     box.x1 = x1;
1600     box.x2 = x2;
1601     box.y1 = y1;
1602     box.y2 = y2;
1603 
1604     RegionInit(&reg, &box, 1);
1605 
1606     RegionIntersect(&reg, &reg, clipList);
1607     if (generateExposures)
1608         (*pScreen->WindowExposures) (pWin, &reg);
1609     else if (pWin->backgroundState != None)
1610         pScreen->PaintWindow(pWin, &reg, PW_BACKGROUND);
1611     RegionUninit(&reg);
1612 }
1613 
1614 /****************************************************************/
1615 
1616 /* not used */
1617 Bool
miOverlayGetPrivateClips(WindowPtr pWin,RegionPtr * borderClip,RegionPtr * clipList)1618 miOverlayGetPrivateClips(WindowPtr pWin,
1619                          RegionPtr *borderClip, RegionPtr *clipList)
1620 {
1621     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1622 
1623     if (pTree) {
1624         *borderClip = &(pTree->borderClip);
1625         *clipList = &(pTree->clipList);
1626         return TRUE;
1627     }
1628 
1629     *borderClip = *clipList = NULL;
1630 
1631     return FALSE;
1632 }
1633 
1634 void
miOverlaySetTransFunction(ScreenPtr pScreen,miOverlayTransFunc transFunc)1635 miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc)
1636 {
1637     MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
1638 }
1639 
1640 Bool
miOverlayCopyUnderlay(ScreenPtr pScreen)1641 miOverlayCopyUnderlay(ScreenPtr pScreen)
1642 {
1643     return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
1644 }
1645 
1646 void
miOverlayComputeCompositeClip(GCPtr pGC,WindowPtr pWin)1647 miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
1648 {
1649     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1650     RegionPtr pregWin;
1651     Bool freeTmpClip, freeCompClip;
1652 
1653     if (!pTree) {
1654         miComputeCompositeClip(pGC, &pWin->drawable);
1655         return;
1656     }
1657 
1658     if (pGC->subWindowMode == IncludeInferiors) {
1659         pregWin = RegionCreate(NullBox, 1);
1660         freeTmpClip = TRUE;
1661         if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
1662             !HasSaverWindow(pGC->pScreen)) {
1663             RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize);
1664         }
1665     }
1666     else {
1667         pregWin = &pTree->clipList;
1668         freeTmpClip = FALSE;
1669     }
1670     freeCompClip = pGC->freeCompClip;
1671     if (!pGC->clientClip) {
1672         if (freeCompClip)
1673             RegionDestroy(pGC->pCompositeClip);
1674         pGC->pCompositeClip = pregWin;
1675         pGC->freeCompClip = freeTmpClip;
1676     }
1677     else {
1678         RegionTranslate(pGC->clientClip,
1679                         pWin->drawable.x + pGC->clipOrg.x,
1680                         pWin->drawable.y + pGC->clipOrg.y);
1681 
1682         if (freeCompClip) {
1683             RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
1684             if (freeTmpClip)
1685                 RegionDestroy(pregWin);
1686         }
1687         else if (freeTmpClip) {
1688             RegionIntersect(pregWin, pregWin, pGC->clientClip);
1689             pGC->pCompositeClip = pregWin;
1690         }
1691         else {
1692             pGC->pCompositeClip = RegionCreate(NullBox, 0);
1693             RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
1694         }
1695         pGC->freeCompClip = TRUE;
1696         RegionTranslate(pGC->clientClip,
1697                         -(pWin->drawable.x + pGC->clipOrg.x),
1698                         -(pWin->drawable.y + pGC->clipOrg.y));
1699     }
1700 }
1701 
1702 Bool
miOverlayCollectUnderlayRegions(WindowPtr pWin,RegionPtr * region)1703 miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region)
1704 {
1705     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1706 
1707     if (pTree) {
1708         *region = &pTree->borderClip;
1709         return FALSE;
1710     }
1711 
1712     *region = RegionCreate(NullBox, 0);
1713 
1714     CollectUnderlayChildrenRegions(pWin, *region);
1715 
1716     return TRUE;
1717 }
1718 
1719 static miOverlayTreePtr
DoLeaf(WindowPtr pWin,miOverlayTreePtr parent,miOverlayTreePtr prevSib)1720 DoLeaf(WindowPtr pWin, miOverlayTreePtr parent, miOverlayTreePtr prevSib)
1721 {
1722     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1723 
1724     pTree->parent = parent;
1725     pTree->firstChild = NULL;
1726     pTree->lastChild = NULL;
1727     pTree->prevSib = prevSib;
1728     pTree->nextSib = NULL;
1729 
1730     if (prevSib)
1731         prevSib->nextSib = pTree;
1732 
1733     if (!parent->firstChild)
1734         parent->firstChild = parent->lastChild = pTree;
1735     else if (parent->lastChild == prevSib)
1736         parent->lastChild = pTree;
1737 
1738     return pTree;
1739 }
1740 
1741 static void
RebuildTree(WindowPtr pWin)1742 RebuildTree(WindowPtr pWin)
1743 {
1744     miOverlayTreePtr parent, prevSib, tChild;
1745     WindowPtr pChild;
1746 
1747     prevSib = tChild = NULL;
1748 
1749     pWin = pWin->parent;
1750 
1751     while (IN_OVERLAY(pWin))
1752         pWin = pWin->parent;
1753 
1754     parent = MIOVERLAY_GET_WINDOW_TREE(pWin);
1755 
1756     pChild = pWin->firstChild;
1757     parent->firstChild = parent->lastChild = NULL;
1758 
1759     while (1) {
1760         if (IN_UNDERLAY(pChild))
1761             prevSib = tChild = DoLeaf(pChild, parent, prevSib);
1762 
1763         if (pChild->firstChild) {
1764             if (IN_UNDERLAY(pChild)) {
1765                 parent = tChild;
1766                 prevSib = NULL;
1767             }
1768             pChild = pChild->firstChild;
1769             continue;
1770         }
1771 
1772         while (!pChild->nextSib) {
1773             pChild = pChild->parent;
1774             if (pChild == pWin)
1775                 return;
1776             if (IN_UNDERLAY(pChild)) {
1777                 prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
1778                 parent = tChild->parent;
1779             }
1780         }
1781 
1782         pChild = pChild->nextSib;
1783     }
1784 }
1785 
1786 static Bool
HasUnderlayChildren(WindowPtr pWin)1787 HasUnderlayChildren(WindowPtr pWin)
1788 {
1789     WindowPtr pChild;
1790 
1791     if (!(pChild = pWin->firstChild))
1792         return FALSE;
1793 
1794     while (1) {
1795         if (IN_UNDERLAY(pChild))
1796             return TRUE;
1797 
1798         if (pChild->firstChild) {
1799             pChild = pChild->firstChild;
1800             continue;
1801         }
1802 
1803         while (!pChild->nextSib && (pWin != pChild))
1804             pChild = pChild->parent;
1805 
1806         if (pChild == pWin)
1807             break;
1808 
1809         pChild = pChild->nextSib;
1810     }
1811 
1812     return FALSE;
1813 }
1814 
1815 static Bool
CollectUnderlayChildrenRegions(WindowPtr pWin,RegionPtr pReg)1816 CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
1817 {
1818     WindowPtr pChild;
1819     miOverlayTreePtr pTree;
1820     Bool hasUnderlay;
1821 
1822     if (!(pChild = pWin->firstChild))
1823         return FALSE;
1824 
1825     hasUnderlay = FALSE;
1826 
1827     while (1) {
1828         if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
1829             RegionAppend(pReg, &pTree->borderClip);
1830             hasUnderlay = TRUE;
1831         }
1832         else if (pChild->firstChild) {
1833             pChild = pChild->firstChild;
1834             continue;
1835         }
1836 
1837         while (!pChild->nextSib && (pWin != pChild))
1838             pChild = pChild->parent;
1839 
1840         if (pChild == pWin)
1841             break;
1842 
1843         pChild = pChild->nextSib;
1844     }
1845 
1846     if (hasUnderlay) {
1847         Bool overlap;
1848 
1849         RegionValidate(pReg, &overlap);
1850     }
1851 
1852     return hasUnderlay;
1853 }
1854 
1855 static void
MarkUnderlayWindow(WindowPtr pWin)1856 MarkUnderlayWindow(WindowPtr pWin)
1857 {
1858     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
1859 
1860     if (pTree->valdata)
1861         return;
1862     pTree->valdata =
1863         (miOverlayValDataPtr) xnfalloc(sizeof(miOverlayValDataRec));
1864     pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
1865     pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
1866     pTree->valdata->borderVisible = NullRegion;
1867 }
1868