Bug Summary

File:mi/mioverlay.c
Location:line 1732, column 10
Description:Access to field 'firstChild' results in a dereference of a null pointer (loaded from variable 'parent')

Annotated Source Code

1
2#ifdef HAVE_DIX_CONFIG_H1
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
21typedef struct {
22 RegionRec exposed;
23 RegionRec borderExposed;
24 RegionPtr borderVisible;
25 DDXPointRec oldAbsCorner;
26} miOverlayValDataRec, *miOverlayValDataPtr;
27
28typedef 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
41typedef struct {
42 miOverlayTreePtr tree;
43} miOverlayWindowRec, *miOverlayWindowPtr;
44
45typedef 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
57static DevPrivateKeyRec miOverlayWindowKeyRec;
58
59#define miOverlayWindowKey(&miOverlayWindowKeyRec) (&miOverlayWindowKeyRec)
60static DevPrivateKeyRec miOverlayScreenKeyRec;
61
62#define miOverlayScreenKey(&miOverlayScreenKeyRec) (&miOverlayScreenKeyRec)
63
64static void RebuildTree(WindowPtr);
65static Bool HasUnderlayChildren(WindowPtr);
66static void MarkUnderlayWindow(WindowPtr);
67static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
68
69static Bool miOverlayCloseScreen(ScreenPtr);
70static Bool miOverlayCreateWindow(WindowPtr);
71static Bool miOverlayDestroyWindow(WindowPtr);
72static Bool miOverlayUnrealizeWindow(WindowPtr);
73static Bool miOverlayRealizeWindow(WindowPtr);
74static void miOverlayMarkWindow(WindowPtr);
75static void miOverlayReparentWindow(WindowPtr, WindowPtr);
76static void miOverlayRestackWindow(WindowPtr, WindowPtr);
77static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr *);
78static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool);
79static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind);
80static void miOverlayHandleExposures(WindowPtr);
81static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind);
82static void miOverlayWindowExposures(WindowPtr, RegionPtr);
83static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
84 unsigned int, WindowPtr);
85static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
86
87static void miOverlaySetShape(WindowPtr, int);
88static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
89
90#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
((miOverlayScreenPtr) \
91 dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey(&miOverlayScreenKeyRec)))
92#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin)((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))
((miOverlayWindowPtr) \
93 dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey(&miOverlayWindowKeyRec)))
94#define MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
\
95 (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))
->tree)
96
97#define IN_UNDERLAY(w)(((miOverlayWindowPtr) dixLookupPrivate(&(w)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
MIOVERLAY_GET_WINDOW_TREE(w)(((miOverlayWindowPtr) dixLookupPrivate(&(w)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
98#define IN_OVERLAY(w)!(((miOverlayWindowPtr) dixLookupPrivate(&(w)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
!MIOVERLAY_GET_WINDOW_TREE(w)(((miOverlayWindowPtr) dixLookupPrivate(&(w)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
99
100#define MARK_OVERLAY(w)miMarkWindow(w) miMarkWindow(w)
101#define MARK_UNDERLAY(w)MarkUnderlayWindow(w) MarkUnderlayWindow(w)
102
103#define HasParentRelativeBorder(w)(!(w)->borderIsPixel && ((w)->borderWidth || ((
w)->optional ? (w)->optional->clipShape : ((void*)0)
)) && (w)->backgroundState == 1L)
(!(w)->borderIsPixel && \
104 HasBorder(w)((w)->borderWidth || ((w)->optional ? (w)->optional->
clipShape : ((void*)0)))
&& \
105 (w)->backgroundState == ParentRelative1L)
106
107Bool
108miInitOverlay(ScreenPtr pScreen,
109 miOverlayInOverlayFunc inOverlayFunc,
110 miOverlayTransFunc transFunc)
111{
112 miOverlayScreenPtr pScreenPriv;
113
114 if (!inOverlayFunc || !transFunc)
115 return FALSE0;
116
117 if (!dixRegisterPrivateKey
118 (&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec)))
119 return FALSE0;
120
121 if (!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0))
122 return FALSE0;
123
124 if (!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
125 return FALSE0;
126
127 dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey(&miOverlayScreenKeyRec), pScreenPriv);
128
129 pScreenPriv->InOverlay = inOverlayFunc;
130 pScreenPriv->MakeTransparent = transFunc;
131 pScreenPriv->underlayMarked = FALSE0;
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 TRUE1;
160}
161
162static Bool
163miOverlayCloseScreen(ScreenPtr pScreen)
164{
165 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
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
178static Bool
179miOverlayCreateWindow(WindowPtr pWin)
180{
181 ScreenPtr pScreen = pWin->drawable.pScreen;
182 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
183 miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin)((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))
;
184 miOverlayTreePtr pTree = NULL((void*)0);
185 Bool result = TRUE1;
186
187 pWinPriv->tree = NULL((void*)0);
188
189 if (!pWin->parent || !((*pScreenPriv->InOverlay) (pWin))) {
190 if (!(pTree = (miOverlayTreePtr) calloc(1, sizeof(miOverlayTreeRec))))
191 return FALSE0;
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 = VisibilityNotViewable3;
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 TRUE1;
226}
227
228static Bool
229miOverlayDestroyWindow(WindowPtr pWin)
230{
231 ScreenPtr pScreen = pWin->drawable.pScreen;
232 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
233 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
234 Bool result = TRUE1;
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
261static Bool
262miOverlayUnrealizeWindow(WindowPtr pWin)
263{
264 ScreenPtr pScreen = pWin->drawable.pScreen;
265 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
266 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
267 Bool result = TRUE1;
268
269 if (pTree)
270 pTree->visibility = VisibilityNotViewable3;
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
281static Bool
282miOverlayRealizeWindow(WindowPtr pWin)
283{
284 ScreenPtr pScreen = pWin->drawable.pScreen;
285 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
286 Bool result = TRUE1;
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
308static void
309miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
310{
311 if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
|| HasUnderlayChildren(pWin)) {
312 /* This could probably be more optimal */
313 RebuildTree(pWin->drawable.pScreen->root->firstChild);
314 }
315}
316
317static void
318miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
319{
320 if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
|| HasUnderlayChildren(pWin)) {
1
Taking true branch
321 /* This could probably be more optimal */
322 RebuildTree(pWin);
2
Calling 'RebuildTree'
323 }
324}
325
326static Bool
327miOverlayMarkOverlappedWindows(WindowPtr pWin,
328 WindowPtr pFirst, WindowPtr *pLayerWin)
329{
330 WindowPtr pChild, pLast;
331 Bool overMarked, underMarked, doUnderlay, markAll;
332 miOverlayTreePtr pTree = NULL((void*)0), tLast, tChild;
333 BoxPtr box;
334
335 overMarked = underMarked = markAll = FALSE0;
336
337 if (pLayerWin)
338 *pLayerWin = pWin; /* hah! */
339
340 doUnderlay = (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
|| 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 = TRUE1;
349
350 if (doUnderlay && IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
351 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
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)miMarkWindow(pChild);
361 overMarked = TRUE1;
362 if (doUnderlay && IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
363 MARK_UNDERLAY(pChild)MarkUnderlayWindow(pChild);
364 underMarked = TRUE1;
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)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
375 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
376 }
377
378 if (pChild == pWin)
379 markAll = FALSE0;
380
381 if (pChild == pLast)
382 break;
383
384 pChild = pChild->nextSib;
385 }
386 if (overMarked)
387 MARK_OVERLAY(pWin->parent)miMarkWindow(pWin->parent);
388 }
389
390 if (doUnderlay && !pTree) {
391 if (!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)) {
392 pChild = pWin->lastChild;
393 while (1) {
394 if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
))
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)MarkUnderlayWindow(tChild->pWin);
423 underMarked = TRUE1;
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)MarkUnderlayWindow(pTree->parent->pWin);
446 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
->underlayMarked = TRUE1;
447 }
448
449 return underMarked || overMarked;
450}
451
452static void
453miOverlayComputeClips(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)(((miOverlayWindowPtr) dixLookupPrivate(&(pParent)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
462 miOverlayTreePtr tChild;
463 Bool overlap;
464
465 borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent)((int) (pParent)->borderWidth);
466 borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent)((int) (pParent)->borderWidth);
467 dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
468 wBorderWidth(pParent)((int) (pParent)->borderWidth);
469 if (dx > 32767)
470 dx = 32767;
471 borderSize.x2 = dx;
472 dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
473 wBorderWidth(pParent)((int) (pParent)->borderWidth);
474 if (dy > 32767)
475 dy = 32767;
476 borderSize.y2 = dy;
477
478 oldVis = tParent->visibility;
479 switch (RegionContainsRect(universe, &borderSize)) {
480 case rgnIN1:
481 newVis = VisibilityUnobscured0;
482 break;
483 case rgnPART2:
484 newVis = VisibilityPartiallyObscured1;
485 {
486 RegionPtr pBounding;
487
488 if ((pBounding = wBoundingShape(pParent)((pParent)->optional ? (pParent)->optional->boundingShape
: ((void*)0))
)) {
489 switch (miShapedWindowIn(universe, pBounding,
490 &borderSize,
491 pParent->drawable.x,
492 pParent->drawable.y)) {
493 case rgnIN1:
494 newVis = VisibilityUnobscured0;
495 break;
496 case rgnOUT0:
497 newVis = VisibilityFullyObscured2;
498 break;
499 }
500 }
501 }
502 break;
503 default:
504 newVis = VisibilityFullyObscured2;
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 == VisibilityFullyObscured2) ||
520 (oldVis == VisibilityUnobscured0))) {
521 tChild = tParent;
522 while (1) {
523 if (tChild->pWin->viewable) {
524 if (tChild->visibility != VisibilityFullyObscured2) {
525 RegionTranslate(&tChild->borderClip, dx, dy);
526 RegionTranslate(&tChild->clipList, dx, dy);
527
528 tChild->pWin->drawable.serialNumber =
529 NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber
= 1): globalSerialNumber)
;
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)(!(tChild->pWin)->borderIsPixel && ((tChild->
pWin)->borderWidth || ((tChild->pWin)->optional ? (tChild
->pWin)->optional->clipShape : ((void*)0))) &&
(tChild->pWin)->backgroundState == 1L)
) {
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)((pParent)->borderWidth || ((pParent)->optional ? (pParent
)->optional->clipShape : ((void*)0)))
) {
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)(!(pParent)->borderIsPixel && ((pParent)->borderWidth
|| ((pParent)->optional ? (pParent)->optional->clipShape
: ((void*)0))) && (pParent)->backgroundState == 1L
)
&& (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 == VisibilityFullyObscured2 || oldVis == VisibilityNotViewable3) {
624 RegionCopy(&tParent->valdata->exposed, universe);
625 }
626 else if (newVis != VisibilityFullyObscured2 &&
627 newVis != VisibilityNotViewable3) {
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((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber
= 1): globalSerialNumber)
;
642
643 if (pScreen->ClipNotify)
644 (*pScreen->ClipNotify) (pParent, dx, dy);
645}
646
647static void
648miOverlayMarkWindow(WindowPtr pWin)
649{
650 miOverlayTreePtr pTree = NULL((void*)0);
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((ValidatePtr)1)) {
662 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
663 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
664 pTree->valdata = (miOverlayValDataPtr) UnmapValData((ValidatePtr)1);
665 continue;
666 }
667 else {
668 if (!(pGrandChild = pChild->firstChild))
669 continue;
670
671 while (1) {
672 if (IN_UNDERLAY(pGrandChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pGrandChild)->
devPrivates, (&miOverlayWindowKeyRec)))->tree)
) {
673 pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pGrandChild)->
devPrivates, (&miOverlayWindowKeyRec)))->tree)
;
674 pTree->valdata = (miOverlayValDataPtr) UnmapValData((ValidatePtr)1);
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)MarkUnderlayWindow(pTree->parent->pWin);
695 MIOVERLAY_GET_SCREEN_PRIVATE(pWin->drawable.pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pWin->drawable
.pScreen)->devPrivates, (&miOverlayScreenKeyRec)))
->underlayMarked =
696 TRUE1;
697 }
698}
699
700static void
701miOverlayMarkUnrealizedWindow(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)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)) {
712 if (pTree->valdata != (miOverlayValDataPtr) UnmapValData((ValidatePtr)1)) {
713 RegionEmpty(&pTree->clipList);
714 RegionEmpty(&pTree->borderClip);
715 }
716 }
717 }
718}
719
720static int
721miOverlayValidateTree(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)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
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)!(((miOverlayWindowPtr) dixLookupPrivate(&(newParent)->
devPrivates, (&miOverlayWindowKeyRec)))->tree)
)
744 newParent = newParent->parent;
745
746 tParent = MIOVERLAY_GET_WINDOW_TREE(newParent)(((miOverlayWindowPtr) dixLookupPrivate(&(newParent)->
devPrivates, (&miOverlayWindowKeyRec)))->tree)
;
747
748 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
749 tChild = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
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((void*)0);
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((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber
= 1): globalSerialNumber)
;
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
823static void
824miOverlayHandleExposures(WindowPtr pWin)
825{
826 ScreenPtr pScreen = pWin->drawable.pScreen;
827 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
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)!(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
839 pChild = pChild->parent;
840
841 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
842
843 while (1) {
844 if ((mival = pTree->valdata)) {
845 if (!((*pPriv->InOverlay) (pTree->pWin))) {
846 if (RegionNotEmpty(&mival->borderExposed)) {
847 miPaintWindow(pTree->pWin, &mival->borderExposed,
848 PW_BORDER1);
849 }
850 RegionUninit(&mival->borderExposed);
851
852 (*WindowExposures) (pTree->pWin, &mival->exposed);
853 RegionUninit(&mival->exposed);
854 }
855 free(mival);
856 pTree->valdata = NULL((void*)0);
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 = FALSE0;
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)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
->MakeTransparent))
880 (pScreen, RegionNumRects(&val->after.exposed),
881 RegionRects(&val->after.exposed));
882 }
883 }
884 else {
885 if (RegionNotEmpty(&val->after.borderExposed)) {
886 miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER1);
887 }
888 (*WindowExposures) (pChild, &val->after.exposed);
889 }
890 RegionUninit(&val->after.borderExposed);
891 RegionUninit(&val->after.exposed);
892 free(val);
893 pChild->valdata = NULL((void*)0);
894 if (pChild->firstChild) {
895 pChild = pChild->firstChild;
896 continue;
897 }
898 }
899 while (!pChild->nextSib && (pChild != pWin))
900 pChild = pChild->parent;
901 if (pChild == pWin)
902 break;
903 pChild = pChild->nextSib;
904 }
905}
906
907static void
908miOverlayMoveWindow(WindowPtr pWin,
909 int x, int y, WindowPtr pNextSib, VTKind kind)
910{
911 ScreenPtr pScreen = pWin->drawable.pScreen;
912 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
913 WindowPtr pParent, windowToValidate;
914 Bool WasViewable = (Bool) (pWin->viewable);
915 short bw;
916 RegionRec overReg, underReg;
917 DDXPointRec oldpt;
918
919 if (!(pParent = pWin->parent))
920 return;
921 bw = wBorderWidth(pWin)((int) (pWin)->borderWidth);
922
923 oldpt.x = pWin->drawable.x;
924 oldpt.y = pWin->drawable.y;
925 if (WasViewable) {
926 RegionNull(&overReg);
927 RegionNull(&underReg);
928 if (pTree) {
929 RegionCopy(&overReg, &pWin->borderClip);
930 RegionCopy(&underReg, &pTree->borderClip);
931 }
932 else {
933 RegionCopy(&overReg, &pWin->borderClip);
934 CollectUnderlayChildrenRegions(pWin, &underReg);
935 }
936 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
937 }
938 pWin->origin.x = x + (int) bw;
939 pWin->origin.y = y + (int) bw;
940 x = pWin->drawable.x = pParent->drawable.x + x + (int) bw;
941 y = pWin->drawable.y = pParent->drawable.y + y + (int) bw;
942
943 SetWinSize(pWin);
944 SetBorderSize(pWin);
945
946 (*pScreen->PositionWindow) (pWin, x, y);
947
948 windowToValidate = MoveWindowInStack(pWin, pNextSib);
949
950 ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
951
952 if (WasViewable) {
953 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
954
955 (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL((void*)0));
956
957 (*pScreen->ValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), kind);
958 if (RegionNotEmpty(&underReg)) {
959 pPriv->copyUnderlay = TRUE1;
960 (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &underReg);
961 }
962 RegionUninit(&underReg);
963 if (RegionNotEmpty(&overReg)) {
964 pPriv->copyUnderlay = FALSE0;
965 (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &overReg);
966 }
967 RegionUninit(&overReg);
968 (*pScreen->HandleExposures) (pWin->parent);
969
970 if (pScreen->PostValidateTree)
971 (*pScreen->PostValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), kind);
972 }
973 if (pWin->realized)
974 WindowsRestructured();
975}
976
977#ifndef RECTLIMIT25
978#define RECTLIMIT25 25
979#endif
980
981static void
982miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn)
983{
984 RegionPtr exposures = prgn;
985
986 if (prgn && !RegionNil(prgn)) {
987 RegionRec expRec;
988 int clientInterested =
989 (pWin->eventMask | wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks
: 0)
) & ExposureMask(1L<<15);
990 if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT25)) {
991 ScreenPtr pScreen = pWin->drawable.pScreen;
992 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
993 BoxRec box;
994
995 box = *RegionExtents(prgn);
996 exposures = &expRec;
997 RegionInit(exposures, &box, 1);
998 RegionReset(prgn, &box);
999 /* This is the only reason why we are replacing mi's version
1000 of this file */
1001
1002 if (!((*pPriv->InOverlay) (pWin))) {
1003 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1004
1005 RegionIntersect(prgn, prgn, &pTree->clipList);
1006 }
1007 else
1008 RegionIntersect(prgn, prgn, &pWin->clipList);
1009 }
1010 miPaintWindow(pWin, prgn, PW_BACKGROUND0);
1011 if (clientInterested)
1012 miSendExposures(pWin, exposures,
1013 pWin->drawable.x, pWin->drawable.y);
1014 if (exposures == &expRec)
1015 RegionUninit(exposures);
1016 RegionEmpty(prgn);
1017 }
1018}
1019
1020typedef struct {
1021 RegionPtr over;
1022 RegionPtr under;
1023} miOverlayTwoRegions;
1024
1025static int
1026miOverlayRecomputeExposures(WindowPtr pWin, void *value)
1027{
1028 miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value;
1029 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1030
1031 if (pWin->valdata) {
1032 /*
1033 * compute exposed regions of this window
1034 */
1035 RegionSubtract(&pWin->valdata->after.exposed,
1036 &pWin->clipList, pValid->over);
1037 /*
1038 * compute exposed regions of the border
1039 */
1040 RegionSubtract(&pWin->valdata->after.borderExposed,
1041 &pWin->borderClip, &pWin->winSize);
1042 RegionSubtract(&pWin->valdata->after.borderExposed,
1043 &pWin->valdata->after.borderExposed, pValid->over);
1044 }
1045
1046 if (pTree && pTree->valdata) {
1047 RegionSubtract(&pTree->valdata->exposed,
1048 &pTree->clipList, pValid->under);
1049 RegionSubtract(&pTree->valdata->borderExposed,
1050 &pTree->borderClip, &pWin->winSize);
1051 RegionSubtract(&pTree->valdata->borderExposed,
1052 &pTree->valdata->borderExposed, pValid->under);
1053 }
1054 else if (!pWin->valdata)
1055 return WT_NOMATCH3;
1056
1057 return WT_WALKCHILDREN1;
1058}
1059
1060static void
1061miOverlayResizeWindow(WindowPtr pWin,
1062 int x, int y,
1063 unsigned int w, unsigned int h, WindowPtr pSib)
1064{
1065 ScreenPtr pScreen = pWin->drawable.pScreen;
1066 WindowPtr pParent;
1067 miOverlayTreePtr tChild, pTree;
1068 Bool WasViewable = (Bool) (pWin->viewable);
1069 unsigned short width = pWin->drawable.width;
1070 unsigned short height = pWin->drawable.height;
1071 short oldx = pWin->drawable.x;
1072 short oldy = pWin->drawable.y;
1073 int bw = wBorderWidth(pWin)((int) (pWin)->borderWidth);
1074 short dw, dh;
1075 DDXPointRec oldpt;
1076 RegionPtr oldRegion = NULL((void*)0), oldRegion2 = NULL((void*)0);
1077 WindowPtr pFirstChange;
1078 WindowPtr pChild;
1079 RegionPtr gravitate[StaticGravity10 + 1];
1080 RegionPtr gravitate2[StaticGravity10 + 1];
1081 unsigned g;
1082 int nx, ny; /* destination x,y */
1083 int newx, newy; /* new inner window position */
1084 RegionPtr pRegion = NULL((void*)0);
1085 RegionPtr destClip, destClip2;
1086 RegionPtr oldWinClip = NULL((void*)0), oldWinClip2 = NULL((void*)0);
1087 RegionPtr borderVisible = NullRegion((RegionPtr)0);
1088 RegionPtr borderVisible2 = NullRegion((RegionPtr)0);
1089 Bool shrunk = FALSE0; /* shrunk in an inner dimension */
1090 Bool moved = FALSE0; /* window position changed */
1091 Bool doUnderlay;
1092
1093 /* if this is a root window, can't be resized */
1094 if (!(pParent = pWin->parent))
1095 return;
1096
1097 pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1098 doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
1099 newx = pParent->drawable.x + x + bw;
1100 newy = pParent->drawable.y + y + bw;
1101 if (WasViewable) {
1102 /*
1103 * save the visible region of the window
1104 */
1105 oldRegion = RegionCreate(NullBox((BoxPtr)0), 1);
1106 RegionCopy(oldRegion, &pWin->winSize);
1107 if (doUnderlay) {
1108 oldRegion2 = RegionCreate(NullBox((BoxPtr)0), 1);
1109 RegionCopy(oldRegion2, &pWin->winSize);
1110 }
1111
1112 /*
1113 * categorize child windows into regions to be moved
1114 */
1115 for (g = 0; g <= StaticGravity10; g++)
1116 gravitate[g] = gravitate2[g] = NULL((void*)0);
1117 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
1118 g = pChild->winGravity;
1119 if (g != UnmapGravity0) {
1120 if (!gravitate[g])
1121 gravitate[g] = RegionCreate(NullBox((BoxPtr)0), 1);
1122 RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip);
1123
1124 if (doUnderlay) {
1125 if (!gravitate2[g])
1126 gravitate2[g] = RegionCreate(NullBox((BoxPtr)0), 0);
1127
1128 if ((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)) {
1129 RegionUnion(gravitate2[g],
1130 gravitate2[g], &tChild->borderClip);
1131 }
1132 else
1133 CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
1134 }
1135 }
1136 else {
1137 UnmapWindow(pChild, TRUE1);
1138 }
1139 }
1140 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
1141
1142 oldWinClip = oldWinClip2 = NULL((void*)0);
1143 if (pWin->bitGravity != ForgetGravity0) {
1144 oldWinClip = RegionCreate(NullBox((BoxPtr)0), 1);
1145 RegionCopy(oldWinClip, &pWin->clipList);
1146 if (pTree) {
1147 oldWinClip2 = RegionCreate(NullBox((BoxPtr)0), 1);
1148 RegionCopy(oldWinClip2, &pTree->clipList);
1149 }
1150 }
1151 /*
1152 * if the window is changing size, borderExposed
1153 * can't be computed correctly without some help.
1154 */
1155 if (pWin->drawable.height > h || pWin->drawable.width > w)
1156 shrunk = TRUE1;
1157
1158 if (newx != oldx || newy != oldy)
1159 moved = TRUE1;
1160
1161 if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
1162 HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)->
optional->clipShape : ((void*)0)))
) {
1163 borderVisible = RegionCreate(NullBox((BoxPtr)0), 1);
1164 if (pTree)
1165 borderVisible2 = RegionCreate(NullBox((BoxPtr)0), 1);
1166 /* for tiled borders, we punt and draw the whole thing */
1167 if (pWin->borderIsPixel || !moved) {
1168 if (shrunk || moved)
1169 RegionSubtract(borderVisible,
1170 &pWin->borderClip, &pWin->winSize);
1171 else
1172 RegionCopy(borderVisible, &pWin->borderClip);
1173 if (pTree) {
1174 if (shrunk || moved)
1175 RegionSubtract(borderVisible,
1176 &pTree->borderClip, &pWin->winSize);
1177 else
1178 RegionCopy(borderVisible, &pTree->borderClip);
1179 }
1180 }
1181 }
1182 }
1183 pWin->origin.x = x + bw;
1184 pWin->origin.y = y + bw;
1185 pWin->drawable.height = h;
1186 pWin->drawable.width = w;
1187
1188 x = pWin->drawable.x = newx;
1189 y = pWin->drawable.y = newy;
1190
1191 SetWinSize(pWin);
1192 SetBorderSize(pWin);
1193
1194 dw = (int) w - (int) width;
1195 dh = (int) h - (int) height;
1196 ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
1197
1198 /* let the hardware adjust background and border pixmaps, if any */
1199 (*pScreen->PositionWindow) (pWin, x, y);
1200
1201 pFirstChange = MoveWindowInStack(pWin, pSib);
1202
1203 if (WasViewable) {
1204 pRegion = RegionCreate(NullBox((BoxPtr)0), 1);
1205
1206 (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL((void*)0));
1207
1208 pWin->valdata->before.resized = TRUE1;
1209 pWin->valdata->before.borderVisible = borderVisible;
1210 if (pTree)
1211 pTree->valdata->borderVisible = borderVisible2;
1212
1213 (*pScreen->ValidateTree) (pWin->parent, pFirstChange, VTOther);
1214 /*
1215 * the entire window is trashed unless bitGravity
1216 * recovers portions of it
1217 */
1218 RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
1219 if (pTree)
1220 RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
1221 }
1222
1223 GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
1224
1225 if (WasViewable) {
1226 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
1227 miOverlayTwoRegions TwoRegions;
1228
1229 /* avoid the border */
1230 if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)->
optional->clipShape : ((void*)0)))
) {
1231 int offx, offy, dx, dy;
1232
1233 /* kruft to avoid double translates for each gravity */
1234 offx = 0;
1235 offy = 0;
1236 for (g = 0; g <= StaticGravity10; g++) {
1237 if (!gravitate[g] && !gravitate2[g])
1238 continue;
1239
1240 /* align winSize to gravitate[g].
1241 * winSize is in new coordinates,
1242 * gravitate[g] is still in old coordinates */
1243 GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
1244
1245 dx = (oldx - nx) - offx;
1246 dy = (oldy - ny) - offy;
1247 if (dx || dy) {
1248 RegionTranslate(&pWin->winSize, dx, dy);
1249 offx += dx;
1250 offy += dy;
1251 }
1252 if (gravitate[g])
1253 RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize);
1254 if (gravitate2[g])
1255 RegionIntersect(gravitate2[g], gravitate2[g],
1256 &pWin->winSize);
1257 }
1258 /* get winSize back where it belongs */
1259 if (offx || offy)
1260 RegionTranslate(&pWin->winSize, -offx, -offy);
1261 }
1262 /*
1263 * add screen bits to the appropriate bucket
1264 */
1265
1266 if (oldWinClip2) {
1267 RegionCopy(pRegion, oldWinClip2);
1268 RegionTranslate(pRegion, nx - oldx, ny - oldy);
1269 RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
1270
1271 for (g = pWin->bitGravity + 1; g <= StaticGravity10; g++) {
1272 if (gravitate2[g])
1273 RegionSubtract(oldWinClip2, oldWinClip2, gravitate2[g]);
1274 }
1275 RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
1276 g = pWin->bitGravity;
1277 if (!gravitate2[g])
1278 gravitate2[g] = oldWinClip2;
1279 else {
1280 RegionUnion(gravitate2[g], gravitate2[g], oldWinClip2);
1281 RegionDestroy(oldWinClip2);
1282 }
1283 }
1284
1285 if (oldWinClip) {
1286 /*
1287 * clip to new clipList
1288 */
1289 RegionCopy(pRegion, oldWinClip);
1290 RegionTranslate(pRegion, nx - oldx, ny - oldy);
1291 RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
1292 /*
1293 * don't step on any gravity bits which will be copied after this
1294 * region. Note -- this assumes that the regions will be copied
1295 * in gravity order.
1296 */
1297 for (g = pWin->bitGravity + 1; g <= StaticGravity10; g++) {
1298 if (gravitate[g])
1299 RegionSubtract(oldWinClip, oldWinClip, gravitate[g]);
1300 }
1301 RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
1302 g = pWin->bitGravity;
1303 if (!gravitate[g])
1304 gravitate[g] = oldWinClip;
1305 else {
1306 RegionUnion(gravitate[g], gravitate[g], oldWinClip);
1307 RegionDestroy(oldWinClip);
1308 }
1309 }
1310
1311 /*
1312 * move the bits on the screen
1313 */
1314
1315 destClip = destClip2 = NULL((void*)0);
1316
1317 for (g = 0; g <= StaticGravity10; g++) {
1318 if (!gravitate[g] && !gravitate2[g])
1319 continue;
1320
1321 GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
1322
1323 oldpt.x = oldx + (x - nx);
1324 oldpt.y = oldy + (y - ny);
1325
1326 /* Note that gravitate[g] is *translated* by CopyWindow */
1327
1328 /* only copy the remaining useful bits */
1329
1330 if (gravitate[g])
1331 RegionIntersect(gravitate[g], gravitate[g], oldRegion);
1332 if (gravitate2[g])
1333 RegionIntersect(gravitate2[g], gravitate2[g], oldRegion2);
1334
1335 /* clip to not overwrite already copied areas */
1336
1337 if (destClip && gravitate[g]) {
1338 RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
1339 RegionSubtract(gravitate[g], gravitate[g], destClip);
1340 RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
1341 }
1342 if (destClip2 && gravitate2[g]) {
1343 RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
1344 RegionSubtract(gravitate2[g], gravitate2[g], destClip2);
1345 RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
1346 }
1347
1348 /* and move those bits */
1349
1350 if (oldpt.x != x || oldpt.y != y) {
1351 if (gravitate2[g]) {
1352 pPriv->copyUnderlay = TRUE1;
1353 (*pScreen->CopyWindow) (pWin, oldpt, gravitate2[g]);
1354 }
1355 if (gravitate[g]) {
1356 pPriv->copyUnderlay = FALSE0;
1357 (*pScreen->CopyWindow) (pWin, oldpt, gravitate[g]);
1358 }
1359 }
1360
1361 /* remove any overwritten bits from the remaining useful bits */
1362
1363 if (gravitate[g])
1364 RegionSubtract(oldRegion, oldRegion, gravitate[g]);
1365 if (gravitate2[g])
1366 RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
1367
1368 /*
1369 * recompute exposed regions of child windows
1370 */
1371
1372 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
1373 if (pChild->winGravity != g)
1374 continue;
1375
1376 TwoRegions.over = gravitate[g];
1377 TwoRegions.under = gravitate2[g];
1378
1379 TraverseTree(pChild, miOverlayRecomputeExposures,
1380 (void *) (&TwoRegions));
1381 }
1382
1383 /*
1384 * remove the successfully copied regions of the
1385 * window from its exposed region
1386 */
1387
1388 if (g == pWin->bitGravity) {
1389 if (gravitate[g])
1390 RegionSubtract(&pWin->valdata->after.exposed,
1391 &pWin->valdata->after.exposed, gravitate[g]);
1392 if (gravitate2[g] && pTree)
1393 RegionSubtract(&pTree->valdata->exposed,
1394 &pTree->valdata->exposed, gravitate2[g]);
1395 }
1396 if (gravitate[g]) {
1397 if (!destClip)
1398 destClip = gravitate[g];
1399 else {
1400 RegionUnion(destClip, destClip, gravitate[g]);
1401 RegionDestroy(gravitate[g]);
1402 }
1403 }
1404 if (gravitate2[g]) {
1405 if (!destClip2)
1406 destClip2 = gravitate2[g];
1407 else {
1408 RegionUnion(destClip2, destClip2, gravitate2[g]);
1409 RegionDestroy(gravitate2[g]);
1410 }
1411 }
1412 }
1413
1414 RegionDestroy(pRegion);
1415 RegionDestroy(oldRegion);
1416 if (doUnderlay)
1417 RegionDestroy(oldRegion2);
1418 if (destClip)
1419 RegionDestroy(destClip);
1420 if (destClip2)
1421 RegionDestroy(destClip2);
1422 (*pScreen->HandleExposures) (pWin->parent);
1423 if (pScreen->PostValidateTree)
1424 (*pScreen->PostValidateTree) (pWin->parent, pFirstChange, VTOther);
1425 }
1426 if (pWin->realized)
1427 WindowsRestructured();
1428}
1429
1430static void
1431miOverlaySetShape(WindowPtr pWin, int kind)
1432{
1433 Bool WasViewable = (Bool) (pWin->viewable);
1434 ScreenPtr pScreen = pWin->drawable.pScreen;
1435
1436 if (kind != ShapeInput2) {
1437 if (WasViewable) {
1438 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
1439
1440 if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)->
optional->clipShape : ((void*)0)))
) {
1441 RegionPtr borderVisible;
1442
1443 borderVisible = RegionCreate(NullBox((BoxPtr)0), 1);
1444 RegionSubtract(borderVisible,
1445 &pWin->borderClip, &pWin->winSize);
1446 pWin->valdata->before.borderVisible = borderVisible;
1447 pWin->valdata->before.resized = TRUE1;
1448 if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
1449 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1450 RegionPtr borderVisible2;
1451
1452 borderVisible2 = RegionCreate(NULL((void*)0), 1);
1453 RegionSubtract(borderVisible2,
1454 &pTree->borderClip, &pWin->winSize);
1455 pTree->valdata->borderVisible = borderVisible2;
1456 }
1457 }
1458 }
1459
1460 SetWinSize(pWin);
1461 SetBorderSize(pWin);
1462
1463 ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
1464
1465 if (WasViewable) {
1466 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
1467 (*pScreen->ValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), VTOther);
1468 (*pScreen->HandleExposures) (pWin->parent);
1469 if (pScreen->PostValidateTree)
1470 (*pScreen->PostValidateTree) (pWin->parent, NullWindow((WindowPtr) 0),
1471 VTOther);
1472 }
1473 }
1474 if (pWin->realized)
1475 WindowsRestructured();
1476 CheckCursorConfinement(pWin);
1477}
1478
1479static void
1480miOverlayChangeBorderWidth(WindowPtr pWin, unsigned int width)
1481{
1482 int oldwidth;
1483 ScreenPtr pScreen;
1484 Bool WasViewable = (Bool) (pWin->viewable);
1485 Bool HadBorder;
1486
1487 oldwidth = wBorderWidth(pWin)((int) (pWin)->borderWidth);
1488 if (oldwidth == width)
1489 return;
1490 HadBorder = HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)->
optional->clipShape : ((void*)0)))
;
1491 pScreen = pWin->drawable.pScreen;
1492 if (WasViewable && (width < oldwidth))
1493 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
1494
1495 pWin->borderWidth = width;
1496 SetBorderSize(pWin);
1497
1498 if (WasViewable) {
1499 if (width > oldwidth) {
1500 (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0));
1501
1502 if (HadBorder) {
1503 RegionPtr borderVisible;
1504
1505 borderVisible = RegionCreate(NULL((void*)0), 1);
1506 RegionSubtract(borderVisible,
1507 &pWin->borderClip, &pWin->winSize);
1508 pWin->valdata->before.borderVisible = borderVisible;
1509 if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
1510 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1511 RegionPtr borderVisible2;
1512
1513 borderVisible2 = RegionCreate(NULL((void*)0), 1);
1514 RegionSubtract(borderVisible2,
1515 &pTree->borderClip, &pWin->winSize);
1516 pTree->valdata->borderVisible = borderVisible2;
1517 }
1518 }
1519 }
1520 (*pScreen->ValidateTree) (pWin->parent, pWin, VTOther);
1521 (*pScreen->HandleExposures) (pWin->parent);
1522
1523 if (pScreen->PostValidateTree)
1524 (*pScreen->PostValidateTree) (pWin->parent, pWin, VTOther);
1525 }
1526 if (pWin->realized)
1527 WindowsRestructured();
1528}
1529
1530/* We need this as an addition since the xf86 common code doesn't
1531 know about the second tree which is static to this file. */
1532
1533void
1534miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
1535{
1536 WindowPtr pRoot = pScreen->root;
1537 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot)(((miOverlayWindowPtr) dixLookupPrivate(&(pRoot)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1538
1539 MARK_UNDERLAY(pRoot)MarkUnderlayWindow(pRoot);
1540
1541 if (enable) {
1542 BoxRec box;
1543
1544 box.x1 = 0;
1545 box.y1 = 0;
1546 box.x2 = pScreen->width;
1547 box.y2 = pScreen->height;
1548
1549 RegionReset(&pTree->borderClip, &box);
1550 }
1551 else
1552 RegionEmpty(&pTree->borderClip);
1553
1554 RegionBreak(&pTree->clipList);
1555}
1556
1557static void
1558miOverlayClearToBackground(WindowPtr pWin,
1559 int x, int y, int w, int h, Bool generateExposures)
1560{
1561 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1562 BoxRec box;
1563 RegionRec reg;
1564 ScreenPtr pScreen = pWin->drawable.pScreen;
1565 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
;
1566 RegionPtr clipList;
1567 BoxPtr extents;
1568 int x1, y1, x2, y2;
1569
1570 x1 = pWin->drawable.x + x;
1571 y1 = pWin->drawable.y + y;
1572 if (w)
1573 x2 = x1 + (int) w;
1574 else
1575 x2 = x1 + (int) pWin->drawable.width - (int) x;
1576 if (h)
1577 y2 = y1 + h;
1578 else
1579 y2 = y1 + (int) pWin->drawable.height - (int) y;
1580
1581 clipList = ((*pScreenPriv->InOverlay) (pWin)) ? &pWin->clipList :
1582 &pTree->clipList;
1583
1584 extents = RegionExtents(clipList);
1585
1586 if (x1 < extents->x1)
1587 x1 = extents->x1;
1588 if (x2 > extents->x2)
1589 x2 = extents->x2;
1590 if (y1 < extents->y1)
1591 y1 = extents->y1;
1592 if (y2 > extents->y2)
1593 y2 = extents->y2;
1594
1595 if (x2 <= x1 || y2 <= y1)
1596 x2 = x1 = y2 = y1 = 0;
1597
1598 box.x1 = x1;
1599 box.x2 = x2;
1600 box.y1 = y1;
1601 box.y2 = y2;
1602
1603 RegionInit(&reg, &box, 1);
1604
1605 RegionIntersect(&reg, &reg, clipList);
1606 if (generateExposures)
1607 (*pScreen->WindowExposures) (pWin, &reg);
1608 else if (pWin->backgroundState != None0L)
1609 miPaintWindow(pWin, &reg, PW_BACKGROUND0);
1610 RegionUninit(&reg);
1611}
1612
1613/****************************************************************/
1614
1615/* not used */
1616Bool
1617miOverlayGetPrivateClips(WindowPtr pWin,
1618 RegionPtr *borderClip, RegionPtr *clipList)
1619{
1620 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1621
1622 if (pTree) {
1623 *borderClip = &(pTree->borderClip);
1624 *clipList = &(pTree->clipList);
1625 return TRUE1;
1626 }
1627
1628 *borderClip = *clipList = NULL((void*)0);
1629
1630 return FALSE0;
1631}
1632
1633void
1634miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc)
1635{
1636 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
->MakeTransparent = transFunc;
1637}
1638
1639Bool
1640miOverlayCopyUnderlay(ScreenPtr pScreen)
1641{
1642 return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates
, (&miOverlayScreenKeyRec)))
->copyUnderlay;
1643}
1644
1645void
1646miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
1647{
1648 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1649 RegionPtr pregWin;
1650 Bool freeTmpClip, freeCompClip;
1651
1652 if (!pTree) {
1653 miComputeCompositeClip(pGC, &pWin->drawable);
1654 return;
1655 }
1656
1657 if (pGC->subWindowMode == IncludeInferiors1) {
1658 pregWin = RegionCreate(NullBox((BoxPtr)0), 1);
1659 freeTmpClip = TRUE1;
1660 if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON0) ||
1661 !HasSaverWindow(pGC->pScreen)(pGC->pScreen->screensaver.pWindow != ((WindowPtr) 0))) {
1662 RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize);
1663 }
1664 }
1665 else {
1666 pregWin = &pTree->clipList;
1667 freeTmpClip = FALSE0;
1668 }
1669 freeCompClip = pGC->freeCompClip;
1670 if (!pGC->clientClip) {
1671 if (freeCompClip)
1672 RegionDestroy(pGC->pCompositeClip);
1673 pGC->pCompositeClip = pregWin;
1674 pGC->freeCompClip = freeTmpClip;
1675 }
1676 else {
1677 RegionTranslate(pGC->clientClip,
1678 pWin->drawable.x + pGC->clipOrg.x,
1679 pWin->drawable.y + pGC->clipOrg.y);
1680
1681 if (freeCompClip) {
1682 RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
1683 if (freeTmpClip)
1684 RegionDestroy(pregWin);
1685 }
1686 else if (freeTmpClip) {
1687 RegionIntersect(pregWin, pregWin, pGC->clientClip);
1688 pGC->pCompositeClip = pregWin;
1689 }
1690 else {
1691 pGC->pCompositeClip = RegionCreate(NullBox((BoxPtr)0), 0);
1692 RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
1693 }
1694 pGC->freeCompClip = TRUE1;
1695 RegionTranslate(pGC->clientClip,
1696 -(pWin->drawable.x + pGC->clipOrg.x),
1697 -(pWin->drawable.y + pGC->clipOrg.y));
1698 }
1699}
1700
1701Bool
1702miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region)
1703{
1704 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1705
1706 if (pTree) {
1707 *region = &pTree->borderClip;
1708 return FALSE0;
1709 }
1710
1711 *region = RegionCreate(NullBox((BoxPtr)0), 0);
1712
1713 CollectUnderlayChildrenRegions(pWin, *region);
1714
1715 return TRUE1;
1716}
1717
1718static miOverlayTreePtr
1719DoLeaf(WindowPtr pWin, miOverlayTreePtr parent, miOverlayTreePtr prevSib)
1720{
1721 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1722
1723 pTree->parent = parent;
1724 pTree->firstChild = NULL((void*)0);
1725 pTree->lastChild = NULL((void*)0);
1726 pTree->prevSib = prevSib;
1727 pTree->nextSib = NULL((void*)0);
1728
1729 if (prevSib)
19
Taking false branch
1730 prevSib->nextSib = pTree;
1731
1732 if (!parent->firstChild)
20
Access to field 'firstChild' results in a dereference of a null pointer (loaded from variable 'parent')
1733 parent->firstChild = parent->lastChild = pTree;
1734 else if (parent->lastChild == prevSib)
1735 parent->lastChild = pTree;
1736
1737 return pTree;
1738}
1739
1740static void
1741RebuildTree(WindowPtr pWin)
1742{
1743 miOverlayTreePtr parent, prevSib, tChild;
1744 WindowPtr pChild;
1745
1746 prevSib = tChild = NULL((void*)0);
3
Null pointer value stored to 'tChild'
1747
1748 pWin = pWin->parent;
1749
1750 while (IN_OVERLAY(pWin)!(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
4
Loop condition is false. Execution continues on line 1753
1751 pWin = pWin->parent;
1752
1753 parent = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1754
1755 pChild = pWin->firstChild;
1756 parent->firstChild = parent->lastChild = NULL((void*)0);
1757
1758 while (1) {
5
Loop condition is true. Entering loop body
9
Loop condition is true. Entering loop body
15
Loop condition is true. Entering loop body
1759 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
6
Taking false branch
10
Taking false branch
16
Taking true branch
1760 prevSib = tChild = DoLeaf(pChild, parent, prevSib);
17
Passing null pointer value via 2nd parameter 'parent'
18
Calling 'DoLeaf'
1761
1762 if (pChild->firstChild) {
7
Taking false branch
11
Taking true branch
1763 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
12
Taking true branch
1764 parent = tChild;
13
Null pointer value stored to 'parent'
1765 prevSib = NULL((void*)0);
1766 }
1767 pChild = pChild->firstChild;
1768 continue;
14
Execution continues on line 1758
1769 }
1770
1771 while (!pChild->nextSib) {
8
Loop condition is false. Execution continues on line 1781
1772 pChild = pChild->parent;
1773 if (pChild == pWin)
1774 return;
1775 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
) {
1776 prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1777 parent = tChild->parent;
1778 }
1779 }
1780
1781 pChild = pChild->nextSib;
1782 }
1783}
1784
1785static Bool
1786HasUnderlayChildren(WindowPtr pWin)
1787{
1788 WindowPtr pChild;
1789
1790 if (!(pChild = pWin->firstChild))
1791 return FALSE0;
1792
1793 while (1) {
1794 if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)
1795 return TRUE1;
1796
1797 if (pChild->firstChild) {
1798 pChild = pChild->firstChild;
1799 continue;
1800 }
1801
1802 while (!pChild->nextSib && (pWin != pChild))
1803 pChild = pChild->parent;
1804
1805 if (pChild == pWin)
1806 break;
1807
1808 pChild = pChild->nextSib;
1809 }
1810
1811 return FALSE0;
1812}
1813
1814static Bool
1815CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
1816{
1817 WindowPtr pChild;
1818 miOverlayTreePtr pTree;
1819 Bool hasUnderlay;
1820
1821 if (!(pChild = pWin->firstChild))
1822 return FALSE0;
1823
1824 hasUnderlay = FALSE0;
1825
1826 while (1) {
1827 if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
)) {
1828 RegionAppend(pReg, &pTree->borderClip);
1829 hasUnderlay = TRUE1;
1830 }
1831 else if (pChild->firstChild) {
1832 pChild = pChild->firstChild;
1833 continue;
1834 }
1835
1836 while (!pChild->nextSib && (pWin != pChild))
1837 pChild = pChild->parent;
1838
1839 if (pChild == pWin)
1840 break;
1841
1842 pChild = pChild->nextSib;
1843 }
1844
1845 if (hasUnderlay) {
1846 Bool overlap;
1847
1848 RegionValidate(pReg, &overlap);
1849 }
1850
1851 return hasUnderlay;
1852}
1853
1854static void
1855MarkUnderlayWindow(WindowPtr pWin)
1856{
1857 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates
, (&miOverlayWindowKeyRec)))->tree)
;
1858
1859 if (pTree->valdata)
1860 return;
1861 pTree->valdata =
1862 (miOverlayValDataPtr) xnfalloc(sizeof(miOverlayValDataRec))XNFalloc((unsigned long)(sizeof(miOverlayValDataRec)));
1863 pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
1864 pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
1865 pTree->valdata->borderVisible = NullRegion((RegionPtr)0);
1866}