File: | mi/mioverlay.c |
Location: | line 1733, 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 | pScreen->PaintWindow(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 | pScreen->PaintWindow(pChild, &val->after.borderExposed, | |||
887 | PW_BORDER1); | |||
888 | } | |||
889 | (*WindowExposures) (pChild, &val->after.exposed); | |||
890 | } | |||
891 | RegionUninit(&val->after.borderExposed); | |||
892 | RegionUninit(&val->after.exposed); | |||
893 | free(val); | |||
894 | pChild->valdata = NULL((void*)0); | |||
895 | if (pChild->firstChild) { | |||
896 | pChild = pChild->firstChild; | |||
897 | continue; | |||
898 | } | |||
899 | } | |||
900 | while (!pChild->nextSib && (pChild != pWin)) | |||
901 | pChild = pChild->parent; | |||
902 | if (pChild == pWin) | |||
903 | break; | |||
904 | pChild = pChild->nextSib; | |||
905 | } | |||
906 | } | |||
907 | ||||
908 | static void | |||
909 | miOverlayMoveWindow(WindowPtr pWin, | |||
910 | int x, int y, WindowPtr pNextSib, VTKind kind) | |||
911 | { | |||
912 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||
913 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
914 | WindowPtr pParent, windowToValidate; | |||
915 | Bool WasViewable = (Bool) (pWin->viewable); | |||
916 | short bw; | |||
917 | RegionRec overReg, underReg; | |||
918 | DDXPointRec oldpt; | |||
919 | ||||
920 | if (!(pParent = pWin->parent)) | |||
921 | return; | |||
922 | bw = wBorderWidth(pWin)((int) (pWin)->borderWidth); | |||
923 | ||||
924 | oldpt.x = pWin->drawable.x; | |||
925 | oldpt.y = pWin->drawable.y; | |||
926 | if (WasViewable) { | |||
927 | RegionNull(&overReg); | |||
928 | RegionNull(&underReg); | |||
929 | if (pTree) { | |||
930 | RegionCopy(&overReg, &pWin->borderClip); | |||
931 | RegionCopy(&underReg, &pTree->borderClip); | |||
932 | } | |||
933 | else { | |||
934 | RegionCopy(&overReg, &pWin->borderClip); | |||
935 | CollectUnderlayChildrenRegions(pWin, &underReg); | |||
936 | } | |||
937 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
938 | } | |||
939 | pWin->origin.x = x + (int) bw; | |||
940 | pWin->origin.y = y + (int) bw; | |||
941 | x = pWin->drawable.x = pParent->drawable.x + x + (int) bw; | |||
942 | y = pWin->drawable.y = pParent->drawable.y + y + (int) bw; | |||
943 | ||||
944 | SetWinSize(pWin); | |||
945 | SetBorderSize(pWin); | |||
946 | ||||
947 | (*pScreen->PositionWindow) (pWin, x, y); | |||
948 | ||||
949 | windowToValidate = MoveWindowInStack(pWin, pNextSib); | |||
950 | ||||
951 | ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); | |||
952 | ||||
953 | if (WasViewable) { | |||
954 | miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec))); | |||
955 | ||||
956 | (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL((void*)0)); | |||
957 | ||||
958 | (*pScreen->ValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), kind); | |||
959 | if (RegionNotEmpty(&underReg)) { | |||
960 | pPriv->copyUnderlay = TRUE1; | |||
961 | (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &underReg); | |||
962 | } | |||
963 | RegionUninit(&underReg); | |||
964 | if (RegionNotEmpty(&overReg)) { | |||
965 | pPriv->copyUnderlay = FALSE0; | |||
966 | (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &overReg); | |||
967 | } | |||
968 | RegionUninit(&overReg); | |||
969 | (*pScreen->HandleExposures) (pWin->parent); | |||
970 | ||||
971 | if (pScreen->PostValidateTree) | |||
972 | (*pScreen->PostValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), kind); | |||
973 | } | |||
974 | if (pWin->realized) | |||
975 | WindowsRestructured(); | |||
976 | } | |||
977 | ||||
978 | #ifndef RECTLIMIT25 | |||
979 | #define RECTLIMIT25 25 | |||
980 | #endif | |||
981 | ||||
982 | static void | |||
983 | miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn) | |||
984 | { | |||
985 | RegionPtr exposures = prgn; | |||
986 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||
987 | ||||
988 | if (prgn && !RegionNil(prgn)) { | |||
989 | RegionRec expRec; | |||
990 | int clientInterested = | |||
991 | (pWin->eventMask | wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & ExposureMask(1L<<15); | |||
992 | if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT25)) { | |||
993 | miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec))); | |||
994 | BoxRec box; | |||
995 | ||||
996 | box = *RegionExtents(prgn); | |||
997 | exposures = &expRec; | |||
998 | RegionInit(exposures, &box, 1); | |||
999 | RegionReset(prgn, &box); | |||
1000 | /* This is the only reason why we are replacing mi's version | |||
1001 | of this file */ | |||
1002 | ||||
1003 | if (!((*pPriv->InOverlay) (pWin))) { | |||
1004 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1005 | ||||
1006 | RegionIntersect(prgn, prgn, &pTree->clipList); | |||
1007 | } | |||
1008 | else | |||
1009 | RegionIntersect(prgn, prgn, &pWin->clipList); | |||
1010 | } | |||
1011 | pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND0); | |||
1012 | if (clientInterested) | |||
1013 | miSendExposures(pWin, exposures, | |||
1014 | pWin->drawable.x, pWin->drawable.y); | |||
1015 | if (exposures == &expRec) | |||
1016 | RegionUninit(exposures); | |||
1017 | RegionEmpty(prgn); | |||
1018 | } | |||
1019 | } | |||
1020 | ||||
1021 | typedef struct { | |||
1022 | RegionPtr over; | |||
1023 | RegionPtr under; | |||
1024 | } miOverlayTwoRegions; | |||
1025 | ||||
1026 | static int | |||
1027 | miOverlayRecomputeExposures(WindowPtr pWin, void *value) | |||
1028 | { | |||
1029 | miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value; | |||
1030 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1031 | ||||
1032 | if (pWin->valdata) { | |||
1033 | /* | |||
1034 | * compute exposed regions of this window | |||
1035 | */ | |||
1036 | RegionSubtract(&pWin->valdata->after.exposed, | |||
1037 | &pWin->clipList, pValid->over); | |||
1038 | /* | |||
1039 | * compute exposed regions of the border | |||
1040 | */ | |||
1041 | RegionSubtract(&pWin->valdata->after.borderExposed, | |||
1042 | &pWin->borderClip, &pWin->winSize); | |||
1043 | RegionSubtract(&pWin->valdata->after.borderExposed, | |||
1044 | &pWin->valdata->after.borderExposed, pValid->over); | |||
1045 | } | |||
1046 | ||||
1047 | if (pTree && pTree->valdata) { | |||
1048 | RegionSubtract(&pTree->valdata->exposed, | |||
1049 | &pTree->clipList, pValid->under); | |||
1050 | RegionSubtract(&pTree->valdata->borderExposed, | |||
1051 | &pTree->borderClip, &pWin->winSize); | |||
1052 | RegionSubtract(&pTree->valdata->borderExposed, | |||
1053 | &pTree->valdata->borderExposed, pValid->under); | |||
1054 | } | |||
1055 | else if (!pWin->valdata) | |||
1056 | return WT_NOMATCH3; | |||
1057 | ||||
1058 | return WT_WALKCHILDREN1; | |||
1059 | } | |||
1060 | ||||
1061 | static void | |||
1062 | miOverlayResizeWindow(WindowPtr pWin, | |||
1063 | int x, int y, | |||
1064 | unsigned int w, unsigned int h, WindowPtr pSib) | |||
1065 | { | |||
1066 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||
1067 | WindowPtr pParent; | |||
1068 | miOverlayTreePtr tChild, pTree; | |||
1069 | Bool WasViewable = (Bool) (pWin->viewable); | |||
1070 | unsigned short width = pWin->drawable.width; | |||
1071 | unsigned short height = pWin->drawable.height; | |||
1072 | short oldx = pWin->drawable.x; | |||
1073 | short oldy = pWin->drawable.y; | |||
1074 | int bw = wBorderWidth(pWin)((int) (pWin)->borderWidth); | |||
1075 | short dw, dh; | |||
1076 | DDXPointRec oldpt; | |||
1077 | RegionPtr oldRegion = NULL((void*)0), oldRegion2 = NULL((void*)0); | |||
1078 | WindowPtr pFirstChange; | |||
1079 | WindowPtr pChild; | |||
1080 | RegionPtr gravitate[StaticGravity10 + 1]; | |||
1081 | RegionPtr gravitate2[StaticGravity10 + 1]; | |||
1082 | unsigned g; | |||
1083 | int nx, ny; /* destination x,y */ | |||
1084 | int newx, newy; /* new inner window position */ | |||
1085 | RegionPtr pRegion = NULL((void*)0); | |||
1086 | RegionPtr destClip, destClip2; | |||
1087 | RegionPtr oldWinClip = NULL((void*)0), oldWinClip2 = NULL((void*)0); | |||
1088 | RegionPtr borderVisible = NullRegion((RegionPtr)0); | |||
1089 | RegionPtr borderVisible2 = NullRegion((RegionPtr)0); | |||
1090 | Bool shrunk = FALSE0; /* shrunk in an inner dimension */ | |||
1091 | Bool moved = FALSE0; /* window position changed */ | |||
1092 | Bool doUnderlay; | |||
1093 | ||||
1094 | /* if this is a root window, can't be resized */ | |||
1095 | if (!(pParent = pWin->parent)) | |||
1096 | return; | |||
1097 | ||||
1098 | pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1099 | doUnderlay = ((pTree) || HasUnderlayChildren(pWin)); | |||
1100 | newx = pParent->drawable.x + x + bw; | |||
1101 | newy = pParent->drawable.y + y + bw; | |||
1102 | if (WasViewable) { | |||
1103 | /* | |||
1104 | * save the visible region of the window | |||
1105 | */ | |||
1106 | oldRegion = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1107 | RegionCopy(oldRegion, &pWin->winSize); | |||
1108 | if (doUnderlay) { | |||
1109 | oldRegion2 = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1110 | RegionCopy(oldRegion2, &pWin->winSize); | |||
1111 | } | |||
1112 | ||||
1113 | /* | |||
1114 | * categorize child windows into regions to be moved | |||
1115 | */ | |||
1116 | for (g = 0; g <= StaticGravity10; g++) | |||
1117 | gravitate[g] = gravitate2[g] = NULL((void*)0); | |||
1118 | for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { | |||
1119 | g = pChild->winGravity; | |||
1120 | if (g != UnmapGravity0) { | |||
1121 | if (!gravitate[g]) | |||
1122 | gravitate[g] = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1123 | RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip); | |||
1124 | ||||
1125 | if (doUnderlay) { | |||
1126 | if (!gravitate2[g]) | |||
1127 | gravitate2[g] = RegionCreate(NullBox((BoxPtr)0), 0); | |||
1128 | ||||
1129 | if ((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree))) { | |||
1130 | RegionUnion(gravitate2[g], | |||
1131 | gravitate2[g], &tChild->borderClip); | |||
1132 | } | |||
1133 | else | |||
1134 | CollectUnderlayChildrenRegions(pChild, gravitate2[g]); | |||
1135 | } | |||
1136 | } | |||
1137 | else { | |||
1138 | UnmapWindow(pChild, TRUE1); | |||
1139 | } | |||
1140 | } | |||
1141 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
1142 | ||||
1143 | oldWinClip = oldWinClip2 = NULL((void*)0); | |||
1144 | if (pWin->bitGravity != ForgetGravity0) { | |||
1145 | oldWinClip = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1146 | RegionCopy(oldWinClip, &pWin->clipList); | |||
1147 | if (pTree) { | |||
1148 | oldWinClip2 = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1149 | RegionCopy(oldWinClip2, &pTree->clipList); | |||
1150 | } | |||
1151 | } | |||
1152 | /* | |||
1153 | * if the window is changing size, borderExposed | |||
1154 | * can't be computed correctly without some help. | |||
1155 | */ | |||
1156 | if (pWin->drawable.height > h || pWin->drawable.width > w) | |||
1157 | shrunk = TRUE1; | |||
1158 | ||||
1159 | if (newx != oldx || newy != oldy) | |||
1160 | moved = TRUE1; | |||
1161 | ||||
1162 | if ((pWin->drawable.height != h || pWin->drawable.width != w) && | |||
1163 | HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { | |||
1164 | borderVisible = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1165 | if (pTree) | |||
1166 | borderVisible2 = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1167 | /* for tiled borders, we punt and draw the whole thing */ | |||
1168 | if (pWin->borderIsPixel || !moved) { | |||
1169 | if (shrunk || moved) | |||
1170 | RegionSubtract(borderVisible, | |||
1171 | &pWin->borderClip, &pWin->winSize); | |||
1172 | else | |||
1173 | RegionCopy(borderVisible, &pWin->borderClip); | |||
1174 | if (pTree) { | |||
1175 | if (shrunk || moved) | |||
1176 | RegionSubtract(borderVisible, | |||
1177 | &pTree->borderClip, &pWin->winSize); | |||
1178 | else | |||
1179 | RegionCopy(borderVisible, &pTree->borderClip); | |||
1180 | } | |||
1181 | } | |||
1182 | } | |||
1183 | } | |||
1184 | pWin->origin.x = x + bw; | |||
1185 | pWin->origin.y = y + bw; | |||
1186 | pWin->drawable.height = h; | |||
1187 | pWin->drawable.width = w; | |||
1188 | ||||
1189 | x = pWin->drawable.x = newx; | |||
1190 | y = pWin->drawable.y = newy; | |||
1191 | ||||
1192 | SetWinSize(pWin); | |||
1193 | SetBorderSize(pWin); | |||
1194 | ||||
1195 | dw = (int) w - (int) width; | |||
1196 | dh = (int) h - (int) height; | |||
1197 | ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); | |||
1198 | ||||
1199 | /* let the hardware adjust background and border pixmaps, if any */ | |||
1200 | (*pScreen->PositionWindow) (pWin, x, y); | |||
1201 | ||||
1202 | pFirstChange = MoveWindowInStack(pWin, pSib); | |||
1203 | ||||
1204 | if (WasViewable) { | |||
1205 | pRegion = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1206 | ||||
1207 | (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL((void*)0)); | |||
1208 | ||||
1209 | pWin->valdata->before.resized = TRUE1; | |||
1210 | pWin->valdata->before.borderVisible = borderVisible; | |||
1211 | if (pTree) | |||
1212 | pTree->valdata->borderVisible = borderVisible2; | |||
1213 | ||||
1214 | (*pScreen->ValidateTree) (pWin->parent, pFirstChange, VTOther); | |||
1215 | /* | |||
1216 | * the entire window is trashed unless bitGravity | |||
1217 | * recovers portions of it | |||
1218 | */ | |||
1219 | RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); | |||
1220 | if (pTree) | |||
1221 | RegionCopy(&pTree->valdata->exposed, &pTree->clipList); | |||
1222 | } | |||
1223 | ||||
1224 | GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); | |||
1225 | ||||
1226 | if (WasViewable) { | |||
1227 | miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec))); | |||
1228 | miOverlayTwoRegions TwoRegions; | |||
1229 | ||||
1230 | /* avoid the border */ | |||
1231 | if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { | |||
1232 | int offx, offy, dx, dy; | |||
1233 | ||||
1234 | /* kruft to avoid double translates for each gravity */ | |||
1235 | offx = 0; | |||
1236 | offy = 0; | |||
1237 | for (g = 0; g <= StaticGravity10; g++) { | |||
1238 | if (!gravitate[g] && !gravitate2[g]) | |||
1239 | continue; | |||
1240 | ||||
1241 | /* align winSize to gravitate[g]. | |||
1242 | * winSize is in new coordinates, | |||
1243 | * gravitate[g] is still in old coordinates */ | |||
1244 | GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); | |||
1245 | ||||
1246 | dx = (oldx - nx) - offx; | |||
1247 | dy = (oldy - ny) - offy; | |||
1248 | if (dx || dy) { | |||
1249 | RegionTranslate(&pWin->winSize, dx, dy); | |||
1250 | offx += dx; | |||
1251 | offy += dy; | |||
1252 | } | |||
1253 | if (gravitate[g]) | |||
1254 | RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize); | |||
1255 | if (gravitate2[g]) | |||
1256 | RegionIntersect(gravitate2[g], gravitate2[g], | |||
1257 | &pWin->winSize); | |||
1258 | } | |||
1259 | /* get winSize back where it belongs */ | |||
1260 | if (offx || offy) | |||
1261 | RegionTranslate(&pWin->winSize, -offx, -offy); | |||
1262 | } | |||
1263 | /* | |||
1264 | * add screen bits to the appropriate bucket | |||
1265 | */ | |||
1266 | ||||
1267 | if (oldWinClip2) { | |||
1268 | RegionCopy(pRegion, oldWinClip2); | |||
1269 | RegionTranslate(pRegion, nx - oldx, ny - oldy); | |||
1270 | RegionIntersect(oldWinClip2, pRegion, &pTree->clipList); | |||
1271 | ||||
1272 | for (g = pWin->bitGravity + 1; g <= StaticGravity10; g++) { | |||
1273 | if (gravitate2[g]) | |||
1274 | RegionSubtract(oldWinClip2, oldWinClip2, gravitate2[g]); | |||
1275 | } | |||
1276 | RegionTranslate(oldWinClip2, oldx - nx, oldy - ny); | |||
1277 | g = pWin->bitGravity; | |||
1278 | if (!gravitate2[g]) | |||
1279 | gravitate2[g] = oldWinClip2; | |||
1280 | else { | |||
1281 | RegionUnion(gravitate2[g], gravitate2[g], oldWinClip2); | |||
1282 | RegionDestroy(oldWinClip2); | |||
1283 | } | |||
1284 | } | |||
1285 | ||||
1286 | if (oldWinClip) { | |||
1287 | /* | |||
1288 | * clip to new clipList | |||
1289 | */ | |||
1290 | RegionCopy(pRegion, oldWinClip); | |||
1291 | RegionTranslate(pRegion, nx - oldx, ny - oldy); | |||
1292 | RegionIntersect(oldWinClip, pRegion, &pWin->clipList); | |||
1293 | /* | |||
1294 | * don't step on any gravity bits which will be copied after this | |||
1295 | * region. Note -- this assumes that the regions will be copied | |||
1296 | * in gravity order. | |||
1297 | */ | |||
1298 | for (g = pWin->bitGravity + 1; g <= StaticGravity10; g++) { | |||
1299 | if (gravitate[g]) | |||
1300 | RegionSubtract(oldWinClip, oldWinClip, gravitate[g]); | |||
1301 | } | |||
1302 | RegionTranslate(oldWinClip, oldx - nx, oldy - ny); | |||
1303 | g = pWin->bitGravity; | |||
1304 | if (!gravitate[g]) | |||
1305 | gravitate[g] = oldWinClip; | |||
1306 | else { | |||
1307 | RegionUnion(gravitate[g], gravitate[g], oldWinClip); | |||
1308 | RegionDestroy(oldWinClip); | |||
1309 | } | |||
1310 | } | |||
1311 | ||||
1312 | /* | |||
1313 | * move the bits on the screen | |||
1314 | */ | |||
1315 | ||||
1316 | destClip = destClip2 = NULL((void*)0); | |||
1317 | ||||
1318 | for (g = 0; g <= StaticGravity10; g++) { | |||
1319 | if (!gravitate[g] && !gravitate2[g]) | |||
1320 | continue; | |||
1321 | ||||
1322 | GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); | |||
1323 | ||||
1324 | oldpt.x = oldx + (x - nx); | |||
1325 | oldpt.y = oldy + (y - ny); | |||
1326 | ||||
1327 | /* Note that gravitate[g] is *translated* by CopyWindow */ | |||
1328 | ||||
1329 | /* only copy the remaining useful bits */ | |||
1330 | ||||
1331 | if (gravitate[g]) | |||
1332 | RegionIntersect(gravitate[g], gravitate[g], oldRegion); | |||
1333 | if (gravitate2[g]) | |||
1334 | RegionIntersect(gravitate2[g], gravitate2[g], oldRegion2); | |||
1335 | ||||
1336 | /* clip to not overwrite already copied areas */ | |||
1337 | ||||
1338 | if (destClip && gravitate[g]) { | |||
1339 | RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); | |||
1340 | RegionSubtract(gravitate[g], gravitate[g], destClip); | |||
1341 | RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); | |||
1342 | } | |||
1343 | if (destClip2 && gravitate2[g]) { | |||
1344 | RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y); | |||
1345 | RegionSubtract(gravitate2[g], gravitate2[g], destClip2); | |||
1346 | RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y); | |||
1347 | } | |||
1348 | ||||
1349 | /* and move those bits */ | |||
1350 | ||||
1351 | if (oldpt.x != x || oldpt.y != y) { | |||
1352 | if (gravitate2[g]) { | |||
1353 | pPriv->copyUnderlay = TRUE1; | |||
1354 | (*pScreen->CopyWindow) (pWin, oldpt, gravitate2[g]); | |||
1355 | } | |||
1356 | if (gravitate[g]) { | |||
1357 | pPriv->copyUnderlay = FALSE0; | |||
1358 | (*pScreen->CopyWindow) (pWin, oldpt, gravitate[g]); | |||
1359 | } | |||
1360 | } | |||
1361 | ||||
1362 | /* remove any overwritten bits from the remaining useful bits */ | |||
1363 | ||||
1364 | if (gravitate[g]) | |||
1365 | RegionSubtract(oldRegion, oldRegion, gravitate[g]); | |||
1366 | if (gravitate2[g]) | |||
1367 | RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]); | |||
1368 | ||||
1369 | /* | |||
1370 | * recompute exposed regions of child windows | |||
1371 | */ | |||
1372 | ||||
1373 | for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { | |||
1374 | if (pChild->winGravity != g) | |||
1375 | continue; | |||
1376 | ||||
1377 | TwoRegions.over = gravitate[g]; | |||
1378 | TwoRegions.under = gravitate2[g]; | |||
1379 | ||||
1380 | TraverseTree(pChild, miOverlayRecomputeExposures, | |||
1381 | (void *) (&TwoRegions)); | |||
1382 | } | |||
1383 | ||||
1384 | /* | |||
1385 | * remove the successfully copied regions of the | |||
1386 | * window from its exposed region | |||
1387 | */ | |||
1388 | ||||
1389 | if (g == pWin->bitGravity) { | |||
1390 | if (gravitate[g]) | |||
1391 | RegionSubtract(&pWin->valdata->after.exposed, | |||
1392 | &pWin->valdata->after.exposed, gravitate[g]); | |||
1393 | if (gravitate2[g] && pTree) | |||
1394 | RegionSubtract(&pTree->valdata->exposed, | |||
1395 | &pTree->valdata->exposed, gravitate2[g]); | |||
1396 | } | |||
1397 | if (gravitate[g]) { | |||
1398 | if (!destClip) | |||
1399 | destClip = gravitate[g]; | |||
1400 | else { | |||
1401 | RegionUnion(destClip, destClip, gravitate[g]); | |||
1402 | RegionDestroy(gravitate[g]); | |||
1403 | } | |||
1404 | } | |||
1405 | if (gravitate2[g]) { | |||
1406 | if (!destClip2) | |||
1407 | destClip2 = gravitate2[g]; | |||
1408 | else { | |||
1409 | RegionUnion(destClip2, destClip2, gravitate2[g]); | |||
1410 | RegionDestroy(gravitate2[g]); | |||
1411 | } | |||
1412 | } | |||
1413 | } | |||
1414 | ||||
1415 | RegionDestroy(pRegion); | |||
1416 | RegionDestroy(oldRegion); | |||
1417 | if (doUnderlay) | |||
1418 | RegionDestroy(oldRegion2); | |||
1419 | if (destClip) | |||
1420 | RegionDestroy(destClip); | |||
1421 | if (destClip2) | |||
1422 | RegionDestroy(destClip2); | |||
1423 | (*pScreen->HandleExposures) (pWin->parent); | |||
1424 | if (pScreen->PostValidateTree) | |||
1425 | (*pScreen->PostValidateTree) (pWin->parent, pFirstChange, VTOther); | |||
1426 | } | |||
1427 | if (pWin->realized) | |||
1428 | WindowsRestructured(); | |||
1429 | } | |||
1430 | ||||
1431 | static void | |||
1432 | miOverlaySetShape(WindowPtr pWin, int kind) | |||
1433 | { | |||
1434 | Bool WasViewable = (Bool) (pWin->viewable); | |||
1435 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||
1436 | ||||
1437 | if (kind != ShapeInput2) { | |||
1438 | if (WasViewable) { | |||
1439 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
1440 | ||||
1441 | if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { | |||
1442 | RegionPtr borderVisible; | |||
1443 | ||||
1444 | borderVisible = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1445 | RegionSubtract(borderVisible, | |||
1446 | &pWin->borderClip, &pWin->winSize); | |||
1447 | pWin->valdata->before.borderVisible = borderVisible; | |||
1448 | pWin->valdata->before.resized = TRUE1; | |||
1449 | if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) { | |||
1450 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1451 | RegionPtr borderVisible2; | |||
1452 | ||||
1453 | borderVisible2 = RegionCreate(NULL((void*)0), 1); | |||
1454 | RegionSubtract(borderVisible2, | |||
1455 | &pTree->borderClip, &pWin->winSize); | |||
1456 | pTree->valdata->borderVisible = borderVisible2; | |||
1457 | } | |||
1458 | } | |||
1459 | } | |||
1460 | ||||
1461 | SetWinSize(pWin); | |||
1462 | SetBorderSize(pWin); | |||
1463 | ||||
1464 | ResizeChildrenWinSize(pWin, 0, 0, 0, 0); | |||
1465 | ||||
1466 | if (WasViewable) { | |||
1467 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
1468 | (*pScreen->ValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), VTOther); | |||
1469 | (*pScreen->HandleExposures) (pWin->parent); | |||
1470 | if (pScreen->PostValidateTree) | |||
1471 | (*pScreen->PostValidateTree) (pWin->parent, NullWindow((WindowPtr) 0), | |||
1472 | VTOther); | |||
1473 | } | |||
1474 | } | |||
1475 | if (pWin->realized) | |||
1476 | WindowsRestructured(); | |||
1477 | CheckCursorConfinement(pWin); | |||
1478 | } | |||
1479 | ||||
1480 | static void | |||
1481 | miOverlayChangeBorderWidth(WindowPtr pWin, unsigned int width) | |||
1482 | { | |||
1483 | int oldwidth; | |||
1484 | ScreenPtr pScreen; | |||
1485 | Bool WasViewable = (Bool) (pWin->viewable); | |||
1486 | Bool HadBorder; | |||
1487 | ||||
1488 | oldwidth = wBorderWidth(pWin)((int) (pWin)->borderWidth); | |||
1489 | if (oldwidth == width) | |||
1490 | return; | |||
1491 | HadBorder = HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0))); | |||
1492 | pScreen = pWin->drawable.pScreen; | |||
1493 | if (WasViewable && (width < oldwidth)) | |||
1494 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
1495 | ||||
1496 | pWin->borderWidth = width; | |||
1497 | SetBorderSize(pWin); | |||
1498 | ||||
1499 | if (WasViewable) { | |||
1500 | if (width > oldwidth) { | |||
1501 | (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL((void*)0)); | |||
1502 | ||||
1503 | if (HadBorder) { | |||
1504 | RegionPtr borderVisible; | |||
1505 | ||||
1506 | borderVisible = RegionCreate(NULL((void*)0), 1); | |||
1507 | RegionSubtract(borderVisible, | |||
1508 | &pWin->borderClip, &pWin->winSize); | |||
1509 | pWin->valdata->before.borderVisible = borderVisible; | |||
1510 | if (IN_UNDERLAY(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) { | |||
1511 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1512 | RegionPtr borderVisible2; | |||
1513 | ||||
1514 | borderVisible2 = RegionCreate(NULL((void*)0), 1); | |||
1515 | RegionSubtract(borderVisible2, | |||
1516 | &pTree->borderClip, &pWin->winSize); | |||
1517 | pTree->valdata->borderVisible = borderVisible2; | |||
1518 | } | |||
1519 | } | |||
1520 | } | |||
1521 | (*pScreen->ValidateTree) (pWin->parent, pWin, VTOther); | |||
1522 | (*pScreen->HandleExposures) (pWin->parent); | |||
1523 | ||||
1524 | if (pScreen->PostValidateTree) | |||
1525 | (*pScreen->PostValidateTree) (pWin->parent, pWin, VTOther); | |||
1526 | } | |||
1527 | if (pWin->realized) | |||
1528 | WindowsRestructured(); | |||
1529 | } | |||
1530 | ||||
1531 | /* We need this as an addition since the xf86 common code doesn't | |||
1532 | know about the second tree which is static to this file. */ | |||
1533 | ||||
1534 | void | |||
1535 | miOverlaySetRootClip(ScreenPtr pScreen, Bool enable) | |||
1536 | { | |||
1537 | WindowPtr pRoot = pScreen->root; | |||
1538 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot)(((miOverlayWindowPtr) dixLookupPrivate(&(pRoot)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1539 | ||||
1540 | MARK_UNDERLAY(pRoot)MarkUnderlayWindow(pRoot); | |||
1541 | ||||
1542 | if (enable) { | |||
1543 | BoxRec box; | |||
1544 | ||||
1545 | box.x1 = 0; | |||
1546 | box.y1 = 0; | |||
1547 | box.x2 = pScreen->width; | |||
1548 | box.y2 = pScreen->height; | |||
1549 | ||||
1550 | RegionReset(&pTree->borderClip, &box); | |||
1551 | } | |||
1552 | else | |||
1553 | RegionEmpty(&pTree->borderClip); | |||
1554 | ||||
1555 | RegionBreak(&pTree->clipList); | |||
1556 | } | |||
1557 | ||||
1558 | static void | |||
1559 | miOverlayClearToBackground(WindowPtr pWin, | |||
1560 | int x, int y, int w, int h, Bool generateExposures) | |||
1561 | { | |||
1562 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1563 | BoxRec box; | |||
1564 | RegionRec reg; | |||
1565 | ScreenPtr pScreen = pWin->drawable.pScreen; | |||
1566 | miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec))); | |||
1567 | RegionPtr clipList; | |||
1568 | BoxPtr extents; | |||
1569 | int x1, y1, x2, y2; | |||
1570 | ||||
1571 | x1 = pWin->drawable.x + x; | |||
1572 | y1 = pWin->drawable.y + y; | |||
1573 | if (w) | |||
1574 | x2 = x1 + (int) w; | |||
1575 | else | |||
1576 | x2 = x1 + (int) pWin->drawable.width - (int) x; | |||
1577 | if (h) | |||
1578 | y2 = y1 + h; | |||
1579 | else | |||
1580 | y2 = y1 + (int) pWin->drawable.height - (int) y; | |||
1581 | ||||
1582 | clipList = ((*pScreenPriv->InOverlay) (pWin)) ? &pWin->clipList : | |||
1583 | &pTree->clipList; | |||
1584 | ||||
1585 | extents = RegionExtents(clipList); | |||
1586 | ||||
1587 | if (x1 < extents->x1) | |||
1588 | x1 = extents->x1; | |||
1589 | if (x2 > extents->x2) | |||
1590 | x2 = extents->x2; | |||
1591 | if (y1 < extents->y1) | |||
1592 | y1 = extents->y1; | |||
1593 | if (y2 > extents->y2) | |||
1594 | y2 = extents->y2; | |||
1595 | ||||
1596 | if (x2 <= x1 || y2 <= y1) | |||
1597 | x2 = x1 = y2 = y1 = 0; | |||
1598 | ||||
1599 | box.x1 = x1; | |||
1600 | box.x2 = x2; | |||
1601 | box.y1 = y1; | |||
1602 | box.y2 = y2; | |||
1603 | ||||
1604 | RegionInit(®, &box, 1); | |||
1605 | ||||
1606 | RegionIntersect(®, ®, clipList); | |||
1607 | if (generateExposures) | |||
1608 | (*pScreen->WindowExposures) (pWin, ®); | |||
1609 | else if (pWin->backgroundState != None0L) | |||
1610 | pScreen->PaintWindow(pWin, ®, PW_BACKGROUND0); | |||
1611 | RegionUninit(®); | |||
1612 | } | |||
1613 | ||||
1614 | /****************************************************************/ | |||
1615 | ||||
1616 | /* not used */ | |||
1617 | Bool | |||
1618 | miOverlayGetPrivateClips(WindowPtr pWin, | |||
1619 | RegionPtr *borderClip, RegionPtr *clipList) | |||
1620 | { | |||
1621 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1622 | ||||
1623 | if (pTree) { | |||
1624 | *borderClip = &(pTree->borderClip); | |||
1625 | *clipList = &(pTree->clipList); | |||
1626 | return TRUE1; | |||
1627 | } | |||
1628 | ||||
1629 | *borderClip = *clipList = NULL((void*)0); | |||
1630 | ||||
1631 | return FALSE0; | |||
1632 | } | |||
1633 | ||||
1634 | void | |||
1635 | miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc) | |||
1636 | { | |||
1637 | MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec)))->MakeTransparent = transFunc; | |||
1638 | } | |||
1639 | ||||
1640 | Bool | |||
1641 | miOverlayCopyUnderlay(ScreenPtr pScreen) | |||
1642 | { | |||
1643 | return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)((miOverlayScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates , (&miOverlayScreenKeyRec)))->copyUnderlay; | |||
1644 | } | |||
1645 | ||||
1646 | void | |||
1647 | miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin) | |||
1648 | { | |||
1649 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1650 | RegionPtr pregWin; | |||
1651 | Bool freeTmpClip, freeCompClip; | |||
1652 | ||||
1653 | if (!pTree) { | |||
1654 | miComputeCompositeClip(pGC, &pWin->drawable); | |||
1655 | return; | |||
1656 | } | |||
1657 | ||||
1658 | if (pGC->subWindowMode == IncludeInferiors1) { | |||
1659 | pregWin = RegionCreate(NullBox((BoxPtr)0), 1); | |||
1660 | freeTmpClip = TRUE1; | |||
1661 | if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON0) || | |||
1662 | !HasSaverWindow(pGC->pScreen)(pGC->pScreen->screensaver.pWindow != ((WindowPtr) 0))) { | |||
1663 | RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize); | |||
1664 | } | |||
1665 | } | |||
1666 | else { | |||
1667 | pregWin = &pTree->clipList; | |||
1668 | freeTmpClip = FALSE0; | |||
1669 | } | |||
1670 | freeCompClip = pGC->freeCompClip; | |||
1671 | if (!pGC->clientClip) { | |||
1672 | if (freeCompClip) | |||
1673 | RegionDestroy(pGC->pCompositeClip); | |||
1674 | pGC->pCompositeClip = pregWin; | |||
1675 | pGC->freeCompClip = freeTmpClip; | |||
1676 | } | |||
1677 | else { | |||
1678 | RegionTranslate(pGC->clientClip, | |||
1679 | pWin->drawable.x + pGC->clipOrg.x, | |||
1680 | pWin->drawable.y + pGC->clipOrg.y); | |||
1681 | ||||
1682 | if (freeCompClip) { | |||
1683 | RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); | |||
1684 | if (freeTmpClip) | |||
1685 | RegionDestroy(pregWin); | |||
1686 | } | |||
1687 | else if (freeTmpClip) { | |||
1688 | RegionIntersect(pregWin, pregWin, pGC->clientClip); | |||
1689 | pGC->pCompositeClip = pregWin; | |||
1690 | } | |||
1691 | else { | |||
1692 | pGC->pCompositeClip = RegionCreate(NullBox((BoxPtr)0), 0); | |||
1693 | RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); | |||
1694 | } | |||
1695 | pGC->freeCompClip = TRUE1; | |||
1696 | RegionTranslate(pGC->clientClip, | |||
1697 | -(pWin->drawable.x + pGC->clipOrg.x), | |||
1698 | -(pWin->drawable.y + pGC->clipOrg.y)); | |||
1699 | } | |||
1700 | } | |||
1701 | ||||
1702 | Bool | |||
1703 | miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region) | |||
1704 | { | |||
1705 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1706 | ||||
1707 | if (pTree) { | |||
1708 | *region = &pTree->borderClip; | |||
1709 | return FALSE0; | |||
1710 | } | |||
1711 | ||||
1712 | *region = RegionCreate(NullBox((BoxPtr)0), 0); | |||
1713 | ||||
1714 | CollectUnderlayChildrenRegions(pWin, *region); | |||
1715 | ||||
1716 | return TRUE1; | |||
1717 | } | |||
1718 | ||||
1719 | static miOverlayTreePtr | |||
1720 | DoLeaf(WindowPtr pWin, miOverlayTreePtr parent, miOverlayTreePtr prevSib) | |||
1721 | { | |||
1722 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1723 | ||||
1724 | pTree->parent = parent; | |||
1725 | pTree->firstChild = NULL((void*)0); | |||
1726 | pTree->lastChild = NULL((void*)0); | |||
1727 | pTree->prevSib = prevSib; | |||
1728 | pTree->nextSib = NULL((void*)0); | |||
1729 | ||||
1730 | if (prevSib) | |||
1731 | prevSib->nextSib = pTree; | |||
1732 | ||||
1733 | if (!parent->firstChild) | |||
| ||||
1734 | parent->firstChild = parent->lastChild = pTree; | |||
1735 | else if (parent->lastChild == prevSib) | |||
1736 | parent->lastChild = pTree; | |||
1737 | ||||
1738 | return pTree; | |||
1739 | } | |||
1740 | ||||
1741 | static void | |||
1742 | RebuildTree(WindowPtr pWin) | |||
1743 | { | |||
1744 | miOverlayTreePtr parent, prevSib, tChild; | |||
1745 | WindowPtr pChild; | |||
1746 | ||||
1747 | prevSib = tChild = NULL((void*)0); | |||
1748 | ||||
1749 | pWin = pWin->parent; | |||
1750 | ||||
1751 | while (IN_OVERLAY(pWin)!(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) | |||
1752 | pWin = pWin->parent; | |||
1753 | ||||
1754 | parent = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1755 | ||||
1756 | pChild = pWin->firstChild; | |||
1757 | parent->firstChild = parent->lastChild = NULL((void*)0); | |||
1758 | ||||
1759 | while (1) { | |||
1760 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) | |||
1761 | prevSib = tChild = DoLeaf(pChild, parent, prevSib); | |||
1762 | ||||
1763 | if (pChild->firstChild) { | |||
1764 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) { | |||
1765 | parent = tChild; | |||
1766 | prevSib = NULL((void*)0); | |||
1767 | } | |||
1768 | pChild = pChild->firstChild; | |||
1769 | continue; | |||
1770 | } | |||
1771 | ||||
1772 | while (!pChild->nextSib) { | |||
1773 | pChild = pChild->parent; | |||
1774 | if (pChild == pWin) | |||
1775 | return; | |||
1776 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) { | |||
1777 | prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1778 | parent = tChild->parent; | |||
1779 | } | |||
1780 | } | |||
1781 | ||||
1782 | pChild = pChild->nextSib; | |||
1783 | } | |||
1784 | } | |||
1785 | ||||
1786 | static Bool | |||
1787 | HasUnderlayChildren(WindowPtr pWin) | |||
1788 | { | |||
1789 | WindowPtr pChild; | |||
1790 | ||||
1791 | if (!(pChild = pWin->firstChild)) | |||
1792 | return FALSE0; | |||
1793 | ||||
1794 | while (1) { | |||
1795 | if (IN_UNDERLAY(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree)) | |||
1796 | return TRUE1; | |||
1797 | ||||
1798 | if (pChild->firstChild) { | |||
1799 | pChild = pChild->firstChild; | |||
1800 | continue; | |||
1801 | } | |||
1802 | ||||
1803 | while (!pChild->nextSib && (pWin != pChild)) | |||
1804 | pChild = pChild->parent; | |||
1805 | ||||
1806 | if (pChild == pWin) | |||
1807 | break; | |||
1808 | ||||
1809 | pChild = pChild->nextSib; | |||
1810 | } | |||
1811 | ||||
1812 | return FALSE0; | |||
1813 | } | |||
1814 | ||||
1815 | static Bool | |||
1816 | CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg) | |||
1817 | { | |||
1818 | WindowPtr pChild; | |||
1819 | miOverlayTreePtr pTree; | |||
1820 | Bool hasUnderlay; | |||
1821 | ||||
1822 | if (!(pChild = pWin->firstChild)) | |||
1823 | return FALSE0; | |||
1824 | ||||
1825 | hasUnderlay = FALSE0; | |||
1826 | ||||
1827 | while (1) { | |||
1828 | if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)(((miOverlayWindowPtr) dixLookupPrivate(&(pChild)->devPrivates , (&miOverlayWindowKeyRec)))->tree))) { | |||
1829 | RegionAppend(pReg, &pTree->borderClip); | |||
1830 | hasUnderlay = TRUE1; | |||
1831 | } | |||
1832 | else if (pChild->firstChild) { | |||
1833 | pChild = pChild->firstChild; | |||
1834 | continue; | |||
1835 | } | |||
1836 | ||||
1837 | while (!pChild->nextSib && (pWin != pChild)) | |||
1838 | pChild = pChild->parent; | |||
1839 | ||||
1840 | if (pChild == pWin) | |||
1841 | break; | |||
1842 | ||||
1843 | pChild = pChild->nextSib; | |||
1844 | } | |||
1845 | ||||
1846 | if (hasUnderlay) { | |||
1847 | Bool overlap; | |||
1848 | ||||
1849 | RegionValidate(pReg, &overlap); | |||
1850 | } | |||
1851 | ||||
1852 | return hasUnderlay; | |||
1853 | } | |||
1854 | ||||
1855 | static void | |||
1856 | MarkUnderlayWindow(WindowPtr pWin) | |||
1857 | { | |||
1858 | miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin)(((miOverlayWindowPtr) dixLookupPrivate(&(pWin)->devPrivates , (&miOverlayWindowKeyRec)))->tree); | |||
1859 | ||||
1860 | if (pTree->valdata) | |||
1861 | return; | |||
1862 | pTree->valdata = | |||
1863 | (miOverlayValDataPtr) xnfalloc(sizeof(miOverlayValDataRec))XNFalloc((unsigned long)(sizeof(miOverlayValDataRec))); | |||
1864 | pTree->valdata->oldAbsCorner.x = pWin->drawable.x; | |||
1865 | pTree->valdata->oldAbsCorner.y = pWin->drawable.y; | |||
1866 | pTree->valdata->borderVisible = NullRegion((RegionPtr)0); | |||
1867 | } |