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') |
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 | ||||
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) (&miOverlayWindowKeyRec) | |||
60 | static DevPrivateKeyRec miOverlayScreenKeyRec; | |||
61 | ||||
62 | #define miOverlayScreenKey(&miOverlayScreenKeyRec) (&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) 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 | ||||
107 | Bool | |||
108 | miInitOverlay(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 | ||||
162 | static Bool | |||
163 | miOverlayCloseScreen(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 | ||||
178 | static Bool | |||
179 | miOverlayCreateWindow(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 | ||||
228 | static Bool | |||
229 | miOverlayDestroyWindow(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 | ||||
261 | static Bool | |||
262 | miOverlayUnrealizeWindow(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 | ||||
281 | static Bool | |||
282 | miOverlayRealizeWindow(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 | ||||
308 | static void | |||
309 | miOverlayReparentWindow(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 | ||||
317 | static void | |||
318 | miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib) | |||
319 | { | |||
320 | if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree) || HasUnderlayChildren(pWin)) { | |||
| ||||
321 | /* This could probably be more optimal */ | |||
322 | RebuildTree(pWin); | |||
323 | } | |||
324 | } | |||
325 | ||||
326 | static Bool | |||
327 | miOverlayMarkOverlappedWindows(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 | ||||
452 | static void | |||
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)(((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 | ||||
647 | static void | |||
648 | miOverlayMarkWindow(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 | ||||
700 | static void | |||
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)(((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 | ||||
720 | static int | |||
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)((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 | ||||
823 | static void | |||
824 | miOverlayHandleExposures(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 | ||||
907 | static void | |||
908 | miOverlayMoveWindow(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 | ||||
981 | static void | |||
982 | miOverlayWindowExposures(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 | ||||
1020 | typedef struct { | |||
1021 | RegionPtr over; | |||
1022 | RegionPtr under; | |||
1023 | } miOverlayTwoRegions; | |||
1024 | ||||
1025 | static int | |||
1026 | miOverlayRecomputeExposures(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 | ||||
1060 | static void | |||
1061 | miOverlayResizeWindow(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 | ||||
1430 | static void | |||
1431 | miOverlaySetShape(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 | ||||
1479 | static void | |||
1480 | miOverlayChangeBorderWidth(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 | ||||
1533 | void | |||
1534 | miOverlaySetRootClip(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 | ||||
1557 | static void | |||
1558 | miOverlayClearToBackground(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(®, &box, 1); | |||
1604 | ||||
1605 | RegionIntersect(®, ®, clipList); | |||
1606 | if (generateExposures) | |||
1607 | (*pScreen->WindowExposures) (pWin, ®); | |||
1608 | else if (pWin->backgroundState != None0L) | |||
1609 | miPaintWindow(pWin, ®, PW_BACKGROUND0); | |||
1610 | RegionUninit(®); | |||
1611 | } | |||
1612 | ||||
1613 | /****************************************************************/ | |||
1614 | ||||
1615 | /* not used */ | |||
1616 | Bool | |||
1617 | miOverlayGetPrivateClips(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 | ||||
1633 | void | |||
1634 | miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc) | |||
1635 | { | |||
1636 | MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec)))->MakeTransparent = transFunc; | |||
1637 | } | |||
1638 | ||||
1639 | Bool | |||
1640 | miOverlayCopyUnderlay(ScreenPtr pScreen) | |||
1641 | { | |||
1642 | return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec)))->copyUnderlay; | |||
1643 | } | |||
1644 | ||||
1645 | void | |||
1646 | miOverlayComputeCompositeClip(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 | ||||
1701 | Bool | |||
1702 | miOverlayCollectUnderlayRegions(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 | ||||
1718 | static miOverlayTreePtr | |||
1719 | DoLeaf(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) | |||
1730 | prevSib->nextSib = pTree; | |||
1731 | ||||
1732 | if (!parent->firstChild) | |||
| ||||
1733 | parent->firstChild = parent->lastChild = pTree; | |||
1734 | else if (parent->lastChild == prevSib) | |||
1735 | parent->lastChild = pTree; | |||
1736 | ||||
1737 | return pTree; | |||
1738 | } | |||
1739 | ||||
1740 | static void | |||
1741 | RebuildTree(WindowPtr pWin) | |||
1742 | { | |||
1743 | miOverlayTreePtr parent, prevSib, tChild; | |||
1744 | WindowPtr pChild; | |||
1745 | ||||
1746 | prevSib = tChild = NULL((void*)0); | |||
1747 | ||||
1748 | pWin = pWin->parent; | |||
1749 | ||||
1750 | while (IN_OVERLAY(pWin)!(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) | |||
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) { | |||
1759 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) | |||
1760 | prevSib = tChild = DoLeaf(pChild, parent, prevSib); | |||
1761 | ||||
1762 | if (pChild->firstChild) { | |||
1763 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) { | |||
1764 | parent = tChild; | |||
1765 | prevSib = NULL((void*)0); | |||
1766 | } | |||
1767 | pChild = pChild->firstChild; | |||
1768 | continue; | |||
1769 | } | |||
1770 | ||||
1771 | while (!pChild->nextSib) { | |||
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 | ||||
1785 | static Bool | |||
1786 | HasUnderlayChildren(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 | ||||
1814 | static Bool | |||
1815 | CollectUnderlayChildrenRegions(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 | ||||
1854 | static void | |||
1855 | MarkUnderlayWindow(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 | } |