File: | dix/window.c |
Location: | line 223, column 15 |
Description: | Value stored to 'pScreen' during its initialization is never read |
1 | /* |
2 | |
3 | Copyright (c) 2006, Red Hat, Inc. |
4 | |
5 | Permission is hereby granted, free of charge, to any person obtaining a |
6 | copy of this software and associated documentation files (the "Software"), |
7 | to deal in the Software without restriction, including without limitation |
8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | and/or sell copies of the Software, and to permit persons to whom the |
10 | Software is furnished to do so, subject to the following conditions: |
11 | |
12 | The above copyright notice and this permission notice (including the next |
13 | paragraph) shall be included in all copies or substantial portions of the |
14 | Software. |
15 | |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
22 | DEALINGS IN THE SOFTWARE. |
23 | |
24 | Copyright 1987, 1998 The Open Group |
25 | |
26 | Permission to use, copy, modify, distribute, and sell this software and its |
27 | documentation for any purpose is hereby granted without fee, provided that |
28 | the above copyright notice appear in all copies and that both that |
29 | copyright notice and this permission notice appear in supporting |
30 | documentation. |
31 | |
32 | The above copyright notice and this permission notice shall be included |
33 | in all copies or substantial portions of the Software. |
34 | |
35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
36 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
37 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
38 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR |
39 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
40 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
41 | OTHER DEALINGS IN THE SOFTWARE. |
42 | |
43 | Except as contained in this notice, the name of The Open Group shall |
44 | not be used in advertising or otherwise to promote the sale, use or |
45 | other dealings in this Software without prior written authorization |
46 | from The Open Group. |
47 | |
48 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, |
49 | |
50 | All Rights Reserved |
51 | |
52 | Permission to use, copy, modify, and distribute this software and its |
53 | documentation for any purpose and without fee is hereby granted, |
54 | provided that the above copyright notice appear in all copies and that |
55 | both that copyright notice and this permission notice appear in |
56 | supporting documentation, and that the name of Digital not be |
57 | used in advertising or publicity pertaining to distribution of the |
58 | software without specific, written prior permission. |
59 | |
60 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
61 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
62 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
63 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
64 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
65 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
66 | SOFTWARE. |
67 | |
68 | */ |
69 | |
70 | /* The panoramix components contained the following notice */ |
71 | /***************************************************************** |
72 | |
73 | Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. |
74 | |
75 | Permission is hereby granted, free of charge, to any person obtaining a copy |
76 | of this software and associated documentation files (the "Software"), to deal |
77 | in the Software without restriction, including without limitation the rights |
78 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
79 | copies of the Software. |
80 | |
81 | The above copyright notice and this permission notice shall be included in |
82 | all copies or substantial portions of the Software. |
83 | |
84 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
85 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
86 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
87 | DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, |
88 | BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, |
89 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR |
90 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
91 | |
92 | Except as contained in this notice, the name of Digital Equipment Corporation |
93 | shall not be used in advertising or otherwise to promote the sale, use or other |
94 | dealings in this Software without prior written authorization from Digital |
95 | Equipment Corporation. |
96 | |
97 | ******************************************************************/ |
98 | |
99 | #ifdef HAVE_DIX_CONFIG_H1 |
100 | #include <dix-config.h> |
101 | #endif |
102 | |
103 | #include "misc.h" |
104 | #include "scrnintstr.h" |
105 | #include "os.h" |
106 | #include "regionstr.h" |
107 | #include "validate.h" |
108 | #include "windowstr.h" |
109 | #include "propertyst.h" |
110 | #include "input.h" |
111 | #include "inputstr.h" |
112 | #include "resource.h" |
113 | #include "colormapst.h" |
114 | #include "cursorstr.h" |
115 | #include "dixstruct.h" |
116 | #include "gcstruct.h" |
117 | #include "servermd.h" |
118 | #include "mivalidate.h" |
119 | #ifdef PANORAMIX1 |
120 | #include "panoramiX.h" |
121 | #include "panoramiXsrv.h" |
122 | #endif |
123 | #include "dixevents.h" |
124 | #include "globals.h" |
125 | #include "mi.h" /* miPaintWindow */ |
126 | #ifdef COMPOSITE |
127 | #include "compint.h" |
128 | #endif |
129 | #include "selection.h" |
130 | |
131 | #include "privates.h" |
132 | #include "xace.h" |
133 | #include "exevents.h" |
134 | |
135 | #include <X11/Xatom.h> /* must come after server includes */ |
136 | |
137 | /****** |
138 | * Window stuff for server |
139 | * |
140 | * CreateRootWindow, CreateWindow, ChangeWindowAttributes, |
141 | * GetWindowAttributes, DeleteWindow, DestroySubWindows, |
142 | * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, |
143 | * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, |
144 | * ChangeWindowDeviceCursor |
145 | ******/ |
146 | |
147 | Bool bgNoneRoot = FALSE0; |
148 | |
149 | static unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 }; |
150 | static unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 }; |
151 | |
152 | static Bool WindowParentHasDeviceCursor(WindowPtr pWin, |
153 | DeviceIntPtr pDev, CursorPtr pCurs); |
154 | static Bool |
155 | |
156 | WindowSeekDeviceCursor(WindowPtr pWin, |
157 | DeviceIntPtr pDev, |
158 | DevCursNodePtr * pNode, DevCursNodePtr * pPrev); |
159 | |
160 | int screenIsSaved = SCREEN_SAVER_OFF1; |
161 | |
162 | static Bool TileScreenSaver(ScreenPtr pScreen, int kind); |
163 | |
164 | #define INPUTONLY_LEGAL_MASK((1L<<5) | (1L<<11) | (1L<<12) | (1L<< 9) | (1L<<14) ) (CWWinGravity(1L<<5) | CWEventMask(1L<<11) | \ |
165 | CWDontPropagate(1L<<12) | CWOverrideRedirect(1L<<9) | CWCursor(1L<<14) ) |
166 | |
167 | #define BOXES_OVERLAP(b1, b2)(!( ((b1)->x2 <= (b2)->x1) || ( ((b1)->x1 >= ( b2)->x2)) || ( ((b1)->y2 <= (b2)->y1)) || ( ((b1) ->y1 >= (b2)->y2)) ) ) \ |
168 | (!( ((b1)->x2 <= (b2)->x1) || \ |
169 | ( ((b1)->x1 >= (b2)->x2)) || \ |
170 | ( ((b1)->y2 <= (b2)->y1)) || \ |
171 | ( ((b1)->y1 >= (b2)->y2)) ) ) |
172 | |
173 | #define RedirectSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<20)) \ |
174 | ((pWin->eventMask|wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & SubstructureRedirectMask(1L<<20)) |
175 | |
176 | #define SubSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<19)) \ |
177 | ((pWin->eventMask|wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & SubstructureNotifyMask(1L<<19)) |
178 | |
179 | #define StrSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) \ |
180 | ((pWin->eventMask|wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & StructureNotifyMask(1L<<17)) |
181 | |
182 | #define SubStrSend(pWin,pParent)(((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || ((pParent ->eventMask|((pParent)->optional ? (pParent)->optional ->otherEventMasks : 0)) & (1L<<19))) (StrSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || SubSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<19))) |
183 | |
184 | #ifdef COMPOSITE |
185 | static const char *overlay_win_name = "<composite overlay>"; |
186 | #endif |
187 | |
188 | static const char * |
189 | get_window_name(WindowPtr pWin) |
190 | { |
191 | #define WINDOW_NAME_BUF_LEN 512 |
192 | PropertyPtr prop; |
193 | static char buf[WINDOW_NAME_BUF_LEN]; |
194 | int len; |
195 | |
196 | #ifdef COMPOSITE |
197 | CompScreenPtr comp_screen = GetCompScreen(pWin->drawable.pScreen); |
198 | |
199 | if (comp_screen && pWin == comp_screen->pOverlayWin) |
200 | return overlay_win_name; |
201 | #endif |
202 | |
203 | for (prop = wUserProps(pWin)((pWin)->optional ? (pWin)->optional->userProps : (( void*)0)); prop; prop = prop->next) { |
204 | if (prop->propertyName == XA_WM_NAME((Atom) 39) && prop->type == XA_STRING((Atom) 31) && |
205 | prop->data) { |
206 | len = min(prop->size, WINDOW_NAME_BUF_LEN - 1)(((prop->size) < (WINDOW_NAME_BUF_LEN - 1)) ? (prop-> size) : (WINDOW_NAME_BUF_LEN - 1)); |
207 | memcpy(buf, prop->data, len)__builtin___memcpy_chk (buf, prop->data, len, __builtin_object_size (buf, 0)); |
208 | buf[len] = '\0'; |
209 | return buf; |
210 | } |
211 | } |
212 | |
213 | return NULL((void*)0); |
214 | #undef WINDOW_NAME_BUF_LEN |
215 | } |
216 | |
217 | static void |
218 | log_window_info(WindowPtr pWin, int depth) |
219 | { |
220 | int i; |
221 | const char *win_name, *visibility; |
222 | BoxPtr rects; |
223 | ScreenPtr pScreen = pWin->drawable.pScreen; |
Value stored to 'pScreen' during its initialization is never read | |
224 | |
225 | for (i = 0; i < (depth << 2); i++) |
226 | ErrorF(" "); |
227 | |
228 | win_name = get_window_name(pWin); |
229 | ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]", |
230 | (unsigned) pWin->drawable.id, |
231 | win_name ? win_name : "no name", |
232 | pWin->drawable.x, pWin->drawable.y, |
233 | pWin->drawable.x + pWin->drawable.width, |
234 | pWin->drawable.y + pWin->drawable.height); |
235 | |
236 | if (pWin->overrideRedirect) |
237 | ErrorF(" (override redirect)"); |
238 | #ifdef COMPOSITE |
239 | if (pWin->redirectDraw) |
240 | ErrorF(" (%s compositing: pixmap %x)", |
241 | (pWin->redirectDraw == RedirectDrawAutomatic1) ? |
242 | "automatic" : "manual", |
243 | (unsigned) pScreen->GetWindowPixmap(pWin)->drawable.id); |
244 | #endif |
245 | |
246 | switch (pWin->visibility) { |
247 | case VisibilityUnobscured0: |
248 | visibility = "unobscured"; |
249 | break; |
250 | case VisibilityPartiallyObscured1: |
251 | visibility = "partially obscured"; |
252 | break; |
253 | case VisibilityFullyObscured2: |
254 | visibility = "fully obscured"; |
255 | break; |
256 | case VisibilityNotViewable3: |
257 | visibility = "unviewable"; |
258 | break; |
259 | } |
260 | ErrorF(", %s", visibility); |
261 | |
262 | if (REGION_NOTEMPTY(pScreen, &pWin->clipList)RegionNotEmpty(&pWin->clipList)) { |
263 | ErrorF(", clip list:"); |
264 | rects = REGION_RECTSRegionRects(&pWin->clipList); |
265 | for (i = 0; i < REGION_NUM_RECTSRegionNumRects(&pWin->clipList); i++) |
266 | ErrorF(" [(%d, %d) to (%d, %d)]", |
267 | rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); |
268 | ErrorF("; extents [(%d, %d) to (%d, %d)]", |
269 | pWin->clipList.extents.x1, pWin->clipList.extents.y1, |
270 | pWin->clipList.extents.x2, pWin->clipList.extents.y2); |
271 | } |
272 | |
273 | ErrorF("\n"); |
274 | } |
275 | |
276 | void |
277 | PrintWindowTree(void) |
278 | { |
279 | int scrnum, depth; |
280 | ScreenPtr pScreen; |
281 | WindowPtr pWin; |
282 | |
283 | for (scrnum = 0; scrnum < screenInfo.numScreens; scrnum++) { |
284 | pScreen = screenInfo.screens[scrnum]; |
285 | ErrorF("[dix] Dumping windows for screen %d (pixmap %x):\n", scrnum, |
286 | (unsigned) pScreen->GetScreenPixmap(pScreen)->drawable.id); |
287 | pWin = pScreen->root; |
288 | depth = 1; |
289 | while (pWin) { |
290 | log_window_info(pWin, depth); |
291 | if (pWin->firstChild) { |
292 | pWin = pWin->firstChild; |
293 | depth++; |
294 | continue; |
295 | } |
296 | while (pWin && !pWin->nextSib) { |
297 | pWin = pWin->parent; |
298 | depth--; |
299 | } |
300 | if (!pWin) |
301 | break; |
302 | pWin = pWin->nextSib; |
303 | } |
304 | } |
305 | } |
306 | |
307 | int |
308 | TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, void *data) |
309 | { |
310 | int result; |
311 | WindowPtr pChild; |
312 | |
313 | if (!(pChild = pWin)) |
314 | return WT_NOMATCH3; |
315 | while (1) { |
316 | result = (*func) (pChild, data); |
317 | if (result == WT_STOPWALKING0) |
318 | return WT_STOPWALKING0; |
319 | if ((result == WT_WALKCHILDREN1) && pChild->firstChild) { |
320 | pChild = pChild->firstChild; |
321 | continue; |
322 | } |
323 | while (!pChild->nextSib && (pChild != pWin)) |
324 | pChild = pChild->parent; |
325 | if (pChild == pWin) |
326 | break; |
327 | pChild = pChild->nextSib; |
328 | } |
329 | return WT_NOMATCH3; |
330 | } |
331 | |
332 | /***** |
333 | * WalkTree |
334 | * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on |
335 | * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, |
336 | * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING |
337 | * exit WalkTree. Does depth-first traverse. |
338 | *****/ |
339 | |
340 | int |
341 | WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void *data) |
342 | { |
343 | return (TraverseTree(pScreen->root, func, data)); |
344 | } |
345 | |
346 | /* hack for forcing backing store on all windows */ |
347 | int defaultBackingStore = NotUseful0; |
348 | |
349 | /* hack to force no backing store */ |
350 | Bool disableBackingStore = FALSE0; |
351 | Bool enableBackingStore = FALSE0; |
352 | |
353 | static void |
354 | SetWindowToDefaults(WindowPtr pWin) |
355 | { |
356 | pWin->prevSib = NullWindow((WindowPtr) 0); |
357 | pWin->firstChild = NullWindow((WindowPtr) 0); |
358 | pWin->lastChild = NullWindow((WindowPtr) 0); |
359 | |
360 | pWin->valdata = NULL((void*)0); |
361 | pWin->optional = NULL((void*)0); |
362 | pWin->cursorIsNone = TRUE1; |
363 | |
364 | pWin->backingStore = NotUseful0; |
365 | pWin->backStorage = 0; |
366 | |
367 | pWin->mapped = FALSE0; /* off */ |
368 | pWin->realized = FALSE0; /* off */ |
369 | pWin->viewable = FALSE0; |
370 | pWin->visibility = VisibilityNotViewable3; |
371 | pWin->overrideRedirect = FALSE0; |
372 | pWin->saveUnder = FALSE0; |
373 | |
374 | pWin->bitGravity = ForgetGravity0; |
375 | pWin->winGravity = NorthWestGravity1; |
376 | |
377 | pWin->eventMask = 0; |
378 | pWin->deliverableEvents = 0; |
379 | pWin->dontPropagate = 0; |
380 | pWin->forcedBS = FALSE0; |
381 | pWin->redirectDraw = RedirectDrawNone0; |
382 | pWin->forcedBG = FALSE0; |
383 | |
384 | #ifdef ROOTLESS1 |
385 | pWin->rootlessUnhittable = FALSE0; |
386 | #endif |
387 | |
388 | #ifdef COMPOSITE |
389 | pWin->damagedDescendants = FALSE0; |
390 | #endif |
391 | } |
392 | |
393 | static void |
394 | MakeRootTile(WindowPtr pWin) |
395 | { |
396 | ScreenPtr pScreen = pWin->drawable.pScreen; |
397 | GCPtr pGC; |
398 | unsigned char back[128]; |
399 | int len = BitmapBytePad(sizeof(long))(((int)((sizeof(long)) + 32 - 1) >> 5) << 2); |
400 | unsigned char *from, *to; |
401 | int i, j; |
402 | |
403 | pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4, |
404 | pScreen->rootDepth, 0); |
405 | |
406 | pWin->backgroundState = BackgroundPixmap3L; |
407 | pGC = GetScratchGC(pScreen->rootDepth, pScreen); |
408 | if (!pWin->background.pixmap || !pGC) |
409 | FatalError("could not create root tile"); |
410 | |
411 | { |
412 | ChangeGCVal attributes[2]; |
413 | |
414 | attributes[0].val = pScreen->whitePixel; |
415 | attributes[1].val = pScreen->blackPixel; |
416 | |
417 | (void) ChangeGC(NullClient((ClientPtr) 0), pGC, GCForeground(1L<<2) | GCBackground(1L<<3), |
418 | attributes); |
419 | } |
420 | |
421 | ValidateGC((DrawablePtr) pWin->background.pixmap, pGC); |
422 | |
423 | from = (screenInfo.bitmapBitOrder == LSBFirst0) ? _back_lsb : _back_msb; |
424 | to = back; |
425 | |
426 | for (i = 4; i > 0; i--, from++) |
427 | for (j = len; j > 0; j--) |
428 | *to++ = *from; |
429 | |
430 | (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1, |
431 | 0, 0, len, 4, 0, XYBitmap0, (char *) back); |
432 | |
433 | FreeScratchGC(pGC); |
434 | |
435 | } |
436 | |
437 | /***** |
438 | * CreateRootWindow |
439 | * Makes a window at initialization time for specified screen |
440 | *****/ |
441 | |
442 | Bool |
443 | CreateRootWindow(ScreenPtr pScreen) |
444 | { |
445 | WindowPtr pWin; |
446 | BoxRec box; |
447 | PixmapFormatRec *format; |
448 | |
449 | pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW)_dixAllocateScreenObjectWithPrivates(pScreen, sizeof(WindowRec ), sizeof(WindowRec), __builtin_offsetof(WindowRec, devPrivates ), PRIVATE_WINDOW); |
450 | if (!pWin) |
451 | return FALSE0; |
452 | |
453 | pScreen->screensaver.pWindow = NULL((void*)0); |
454 | pScreen->screensaver.wid = FakeClientID(0); |
455 | pScreen->screensaver.ExternalScreenSaver = NULL((void*)0); |
456 | screenIsSaved = SCREEN_SAVER_OFF1; |
457 | |
458 | pScreen->root = pWin; |
459 | |
460 | pWin->drawable.pScreen = pScreen; |
461 | pWin->drawable.type = DRAWABLE_WINDOW0; |
462 | |
463 | pWin->drawable.depth = pScreen->rootDepth; |
464 | for (format = screenInfo.formats; |
465 | format->depth != pScreen->rootDepth; format++); |
466 | pWin->drawable.bitsPerPixel = format->bitsPerPixel; |
467 | |
468 | pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber = 1): globalSerialNumber); |
469 | |
470 | pWin->parent = NullWindow((WindowPtr) 0); |
471 | SetWindowToDefaults(pWin); |
472 | |
473 | pWin->optional = malloc(sizeof(WindowOptRec)); |
474 | if (!pWin->optional) |
475 | return FALSE0; |
476 | |
477 | pWin->optional->dontPropagateMask = 0; |
478 | pWin->optional->otherEventMasks = 0; |
479 | pWin->optional->otherClients = NULL((void*)0); |
480 | pWin->optional->passiveGrabs = NULL((void*)0); |
481 | pWin->optional->userProps = NULL((void*)0); |
482 | pWin->optional->backingBitPlanes = ~0L; |
483 | pWin->optional->backingPixel = 0; |
484 | pWin->optional->boundingShape = NULL((void*)0); |
485 | pWin->optional->clipShape = NULL((void*)0); |
486 | pWin->optional->inputShape = NULL((void*)0); |
487 | pWin->optional->inputMasks = NULL((void*)0); |
488 | pWin->optional->deviceCursors = NULL((void*)0); |
489 | pWin->optional->colormap = pScreen->defColormap; |
490 | pWin->optional->visual = pScreen->rootVisual; |
491 | |
492 | pWin->nextSib = NullWindow((WindowPtr) 0); |
493 | |
494 | pWin->drawable.id = FakeClientID(0); |
495 | |
496 | pWin->origin.x = pWin->origin.y = 0; |
497 | pWin->drawable.height = pScreen->height; |
498 | pWin->drawable.width = pScreen->width; |
499 | pWin->drawable.x = pWin->drawable.y = 0; |
500 | |
501 | box.x1 = 0; |
502 | box.y1 = 0; |
503 | box.x2 = pScreen->width; |
504 | box.y2 = pScreen->height; |
505 | RegionInit(&pWin->clipList, &box, 1); |
506 | RegionInit(&pWin->winSize, &box, 1); |
507 | RegionInit(&pWin->borderSize, &box, 1); |
508 | RegionInit(&pWin->borderClip, &box, 1); |
509 | |
510 | pWin->drawable.class = InputOutput1; |
511 | pWin->optional->visual = pScreen->rootVisual; |
512 | |
513 | pWin->backgroundState = BackgroundPixel2L; |
514 | pWin->background.pixel = pScreen->whitePixel; |
515 | |
516 | pWin->borderIsPixel = TRUE1; |
517 | pWin->border.pixel = pScreen->blackPixel; |
518 | pWin->borderWidth = 0; |
519 | |
520 | /* security creation/labeling check |
521 | */ |
522 | if (XaceHook(XACE_RESOURCE_ACCESS2, serverClient, pWin->drawable.id, |
523 | RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), pWin, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3))) |
524 | return FALSE0; |
525 | |
526 | if (!AddResourceDarwin_X_AddResource(pWin->drawable.id, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), (void *) pWin)) |
527 | return FALSE0; |
528 | |
529 | if (disableBackingStore) |
530 | pScreen->backingStoreSupport = NotUseful0; |
531 | if (enableBackingStore) |
532 | pScreen->backingStoreSupport = WhenMapped1; |
533 | #ifdef COMPOSITE |
534 | if (noCompositeExtension) |
535 | pScreen->backingStoreSupport = NotUseful0; |
536 | #endif |
537 | |
538 | pScreen->saveUnderSupport = NotUseful0; |
539 | |
540 | return TRUE1; |
541 | } |
542 | |
543 | void |
544 | InitRootWindow(WindowPtr pWin) |
545 | { |
546 | ScreenPtr pScreen = pWin->drawable.pScreen; |
547 | int backFlag = CWBorderPixel(1L<<3) | CWCursor(1L<<14) | CWBackingStore(1L<<6); |
548 | |
549 | if (!(*pScreen->CreateWindow) (pWin)) |
550 | return; /* XXX */ |
551 | (*pScreen->PositionWindow) (pWin, 0, 0); |
552 | |
553 | pWin->cursorIsNone = FALSE0; |
554 | pWin->optional->cursor = RefCursor(rootCursor); |
555 | |
556 | if (party_like_its_1989) { |
557 | MakeRootTile(pWin); |
558 | backFlag |= CWBackPixmap(1L<<0); |
559 | } |
560 | else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { |
561 | pWin->backgroundState = XaceBackgroundNoneState(pWin)((pWin)->forcedBG ? 2L : 0L); |
562 | pWin->background.pixel = pScreen->whitePixel; |
563 | backFlag |= CWBackPixmap(1L<<0); |
564 | } |
565 | else { |
566 | pWin->backgroundState = BackgroundPixel2L; |
567 | if (whiteRoot) |
568 | pWin->background.pixel = pScreen->whitePixel; |
569 | else |
570 | pWin->background.pixel = pScreen->blackPixel; |
571 | backFlag |= CWBackPixel(1L<<1); |
572 | } |
573 | |
574 | pWin->backingStore = defaultBackingStore; |
575 | pWin->forcedBS = (defaultBackingStore != NotUseful0); |
576 | /* We SHOULD check for an error value here XXX */ |
577 | (*pScreen->ChangeWindowAttributesDarwin_X_ChangeWindowAttributes) (pWin, backFlag); |
578 | |
579 | MapWindow(pWin, serverClient); |
580 | } |
581 | |
582 | /* Set the region to the intersection of the rectangle and the |
583 | * window's winSize. The window is typically the parent of the |
584 | * window from which the region came. |
585 | */ |
586 | |
587 | static void |
588 | ClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, int x, int y, int w, int h) |
589 | { |
590 | BoxRec box = *RegionExtents(&pWin->winSize); |
591 | |
592 | /* we do these calculations to avoid overflows */ |
593 | if (x > box.x1) |
594 | box.x1 = x; |
595 | if (y > box.y1) |
596 | box.y1 = y; |
597 | x += w; |
598 | if (x < box.x2) |
599 | box.x2 = x; |
600 | y += h; |
601 | if (y < box.y2) |
602 | box.y2 = y; |
603 | if (box.x1 > box.x2) |
604 | box.x2 = box.x1; |
605 | if (box.y1 > box.y2) |
606 | box.y2 = box.y1; |
607 | RegionReset(Rgn, &box); |
608 | RegionIntersect(Rgn, Rgn, &pWin->winSize); |
609 | } |
610 | |
611 | static RealChildHeadProc realChildHeadProc = NULL((void*)0); |
612 | |
613 | void |
614 | RegisterRealChildHeadProc(RealChildHeadProc proc) |
615 | { |
616 | realChildHeadProc = proc; |
617 | } |
618 | |
619 | WindowPtr |
620 | RealChildHead(WindowPtr pWin) |
621 | { |
622 | if (realChildHeadProc) { |
623 | return realChildHeadProc(pWin); |
624 | } |
625 | |
626 | if (!pWin->parent && |
627 | (screenIsSaved == SCREEN_SAVER_ON0) && |
628 | (HasSaverWindow(pWin->drawable.pScreen)(pWin->drawable.pScreen->screensaver.pWindow != ((WindowPtr ) 0)))) |
629 | return pWin->firstChild; |
630 | else |
631 | return NullWindow((WindowPtr) 0); |
632 | } |
633 | |
634 | /***** |
635 | * CreateWindow |
636 | * Makes a window in response to client request |
637 | *****/ |
638 | |
639 | WindowPtr |
640 | CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, |
641 | unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, |
642 | int depth, ClientPtr client, VisualID visual, int *error) |
643 | { |
644 | WindowPtr pWin; |
645 | WindowPtr pHead; |
646 | ScreenPtr pScreen; |
647 | int idepth, ivisual; |
648 | Bool fOK; |
649 | DepthPtr pDepth; |
650 | PixmapFormatRec *format; |
651 | WindowOptPtr ancwopt; |
652 | |
653 | if (class == CopyFromParent0L) |
654 | class = pParent->drawable.class; |
655 | |
656 | if ((class != InputOutput1) && (class != InputOnly2)) { |
657 | *error = BadValue2; |
658 | client->errorValue = class; |
659 | return NullWindow((WindowPtr) 0); |
660 | } |
661 | |
662 | if ((class != InputOnly2) && (pParent->drawable.class == InputOnly2)) { |
663 | *error = BadMatch8; |
664 | return NullWindow((WindowPtr) 0); |
665 | } |
666 | |
667 | if ((class == InputOnly2) && ((bw != 0) || (depth != 0))) { |
668 | *error = BadMatch8; |
669 | return NullWindow((WindowPtr) 0); |
670 | } |
671 | |
672 | pScreen = pParent->drawable.pScreen; |
673 | if ((class == InputOutput1) && (depth == 0)) |
674 | depth = pParent->drawable.depth; |
675 | ancwopt = pParent->optional; |
676 | if (!ancwopt) |
677 | ancwopt = FindWindowWithOptional(pParent)->optional; |
678 | if (visual == CopyFromParent0L) { |
679 | visual = ancwopt->visual; |
680 | } |
681 | |
682 | /* Find out if the depth and visual are acceptable for this Screen */ |
683 | if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { |
684 | fOK = FALSE0; |
685 | for (idepth = 0; idepth < pScreen->numDepths; idepth++) { |
686 | pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; |
687 | if ((depth == pDepth->depth) || (depth == 0)) { |
688 | for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { |
689 | if (visual == pDepth->vids[ivisual]) { |
690 | fOK = TRUE1; |
691 | break; |
692 | } |
693 | } |
694 | } |
695 | } |
696 | if (fOK == FALSE0) { |
697 | *error = BadMatch8; |
698 | return NullWindow((WindowPtr) 0); |
699 | } |
700 | } |
701 | |
702 | if (((vmask & (CWBorderPixmap(1L<<2) | CWBorderPixel(1L<<3))) == 0) && |
703 | (class != InputOnly2) && (depth != pParent->drawable.depth)) { |
704 | *error = BadMatch8; |
705 | return NullWindow((WindowPtr) 0); |
706 | } |
707 | |
708 | if (((vmask & CWColormap(1L<<13)) == 0) && |
709 | (class != InputOnly2) && |
710 | ((visual != ancwopt->visual) || (ancwopt->colormap == None0L))) { |
711 | *error = BadMatch8; |
712 | return NullWindow((WindowPtr) 0); |
713 | } |
714 | |
715 | pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW)_dixAllocateScreenObjectWithPrivates(pScreen, sizeof(WindowRec ), sizeof(WindowRec), __builtin_offsetof(WindowRec, devPrivates ), PRIVATE_WINDOW); |
716 | if (!pWin) { |
717 | *error = BadAlloc11; |
718 | return NullWindow((WindowPtr) 0); |
719 | } |
720 | pWin->drawable = pParent->drawable; |
721 | pWin->drawable.depth = depth; |
722 | if (depth == pParent->drawable.depth) |
723 | pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; |
724 | else { |
725 | for (format = screenInfo.formats; format->depth != depth; format++); |
726 | pWin->drawable.bitsPerPixel = format->bitsPerPixel; |
727 | } |
728 | if (class == InputOnly2) |
729 | pWin->drawable.type = (short) UNDRAWABLE_WINDOW2; |
730 | pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber = 1): globalSerialNumber); |
731 | |
732 | pWin->drawable.id = wid; |
733 | pWin->drawable.class = class; |
734 | |
735 | pWin->parent = pParent; |
736 | SetWindowToDefaults(pWin); |
737 | |
738 | if (visual != ancwopt->visual) { |
739 | if (!MakeWindowOptional(pWin)) { |
740 | dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW)_dixFreeObjectWithPrivates(pWin, (pWin)->devPrivates, PRIVATE_WINDOW ); |
741 | *error = BadAlloc11; |
742 | return NullWindow((WindowPtr) 0); |
743 | } |
744 | pWin->optional->visual = visual; |
745 | pWin->optional->colormap = None0L; |
746 | } |
747 | |
748 | pWin->borderWidth = bw; |
749 | |
750 | /* security creation/labeling check |
751 | */ |
752 | *error = XaceHook(XACE_RESOURCE_ACCESS2, client, wid, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), pWin, |
753 | RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), pWin->parent, |
754 | DixCreateAccess(1<<3) | DixSetAttrAccess(1<<5)); |
755 | if (*error != Success0) { |
756 | dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW)_dixFreeObjectWithPrivates(pWin, (pWin)->devPrivates, PRIVATE_WINDOW ); |
757 | return NullWindow((WindowPtr) 0); |
758 | } |
759 | |
760 | pWin->backgroundState = XaceBackgroundNoneState(pWin)((pWin)->forcedBG ? 2L : 0L); |
761 | pWin->background.pixel = pScreen->whitePixel; |
762 | |
763 | pWin->borderIsPixel = pParent->borderIsPixel; |
764 | pWin->border = pParent->border; |
765 | if (pWin->borderIsPixel == FALSE0) |
766 | pWin->border.pixmap->refcnt++; |
767 | |
768 | pWin->origin.x = x + (int) bw; |
769 | pWin->origin.y = y + (int) bw; |
770 | pWin->drawable.width = w; |
771 | pWin->drawable.height = h; |
772 | pWin->drawable.x = pParent->drawable.x + x + (int) bw; |
773 | pWin->drawable.y = pParent->drawable.y + y + (int) bw; |
774 | |
775 | /* set up clip list correctly for unobscured WindowPtr */ |
776 | RegionNull(&pWin->clipList); |
777 | RegionNull(&pWin->borderClip); |
778 | RegionNull(&pWin->winSize); |
779 | RegionNull(&pWin->borderSize); |
780 | |
781 | pHead = RealChildHead(pParent); |
782 | if (pHead) { |
783 | pWin->nextSib = pHead->nextSib; |
784 | if (pHead->nextSib) |
785 | pHead->nextSib->prevSib = pWin; |
786 | else |
787 | pParent->lastChild = pWin; |
788 | pHead->nextSib = pWin; |
789 | pWin->prevSib = pHead; |
790 | } |
791 | else { |
792 | pWin->nextSib = pParent->firstChild; |
793 | if (pParent->firstChild) |
794 | pParent->firstChild->prevSib = pWin; |
795 | else |
796 | pParent->lastChild = pWin; |
797 | pParent->firstChild = pWin; |
798 | } |
799 | |
800 | SetWinSize(pWin); |
801 | SetBorderSize(pWin); |
802 | |
803 | /* We SHOULD check for an error value here XXX */ |
804 | if (!(*pScreen->CreateWindow) (pWin)) { |
805 | *error = BadAlloc11; |
806 | DeleteWindow(pWin, None0L); |
807 | return NullWindow((WindowPtr) 0); |
808 | } |
809 | /* We SHOULD check for an error value here XXX */ |
810 | (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); |
811 | |
812 | if (!(vmask & CWEventMask(1L<<11))) |
813 | RecalculateDeliverableEvents(pWin); |
814 | |
815 | if (vmask) |
816 | *error = ChangeWindowAttributesDarwin_X_ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin)(clients[((int)((((pWin)->drawable.id) & (((1 << 8) - 1) << (29 - 8))) >> (29 - 8)))])); |
817 | else |
818 | *error = Success0; |
819 | |
820 | if (*error != Success0) { |
821 | DeleteWindow(pWin, None0L); |
822 | return NullWindow((WindowPtr) 0); |
823 | } |
824 | if (!(vmask & CWBackingStore(1L<<6)) && (defaultBackingStore != NotUseful0)) { |
825 | XID value = defaultBackingStore; |
826 | |
827 | (void) ChangeWindowAttributesDarwin_X_ChangeWindowAttributes(pWin, CWBackingStore(1L<<6), &value, |
828 | wClient(pWin)(clients[((int)((((pWin)->drawable.id) & (((1 << 8) - 1) << (29 - 8))) >> (29 - 8)))])); |
829 | pWin->forcedBS = TRUE1; |
830 | } |
831 | |
832 | if (SubSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<19))) { |
833 | xEvent event = { |
834 | .u.createNotify.window = wid, |
835 | .u.createNotify.parent = pParent->drawable.id, |
836 | .u.createNotify.x = x, |
837 | .u.createNotify.y = y, |
838 | .u.createNotify.width = w, |
839 | .u.createNotify.height = h, |
840 | .u.createNotify.borderWidth = bw, |
841 | .u.createNotify.override = pWin->overrideRedirect |
842 | }; |
843 | event.u.u.type = CreateNotify16; |
844 | DeliverEvents(pParent, &event, 1, NullWindow((WindowPtr) 0)); |
845 | } |
846 | return pWin; |
847 | } |
848 | |
849 | static void |
850 | DisposeWindowOptional(WindowPtr pWin) |
851 | { |
852 | if (!pWin->optional) |
853 | return; |
854 | /* |
855 | * everything is peachy. Delete the optional record |
856 | * and clean up |
857 | */ |
858 | if (pWin->optional->cursor) { |
859 | FreeCursor(pWin->optional->cursor, (Cursor) 0); |
860 | pWin->cursorIsNone = FALSE0; |
861 | } |
862 | else |
863 | pWin->cursorIsNone = TRUE1; |
864 | |
865 | if (pWin->optional->deviceCursors) { |
866 | DevCursorList pList; |
867 | DevCursorList pPrev; |
868 | |
869 | pList = pWin->optional->deviceCursors; |
870 | while (pList) { |
871 | if (pList->cursor) |
872 | FreeCursor(pList->cursor, (XID) 0); |
873 | pPrev = pList; |
874 | pList = pList->next; |
875 | free(pPrev); |
876 | } |
877 | pWin->optional->deviceCursors = NULL((void*)0); |
878 | } |
879 | |
880 | free(pWin->optional); |
881 | pWin->optional = NULL((void*)0); |
882 | } |
883 | |
884 | static void |
885 | FreeWindowResources(WindowPtr pWin) |
886 | { |
887 | ScreenPtr pScreen = pWin->drawable.pScreen; |
888 | |
889 | DeleteWindowFromAnySaveSet(pWin); |
890 | DeleteWindowFromAnySelections(pWin); |
891 | DeleteWindowFromAnyEvents(pWin, TRUE1); |
892 | RegionUninit(&pWin->clipList); |
893 | RegionUninit(&pWin->winSize); |
894 | RegionUninit(&pWin->borderClip); |
895 | RegionUninit(&pWin->borderSize); |
896 | if (wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))) |
897 | RegionDestroy(wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))); |
898 | if (wClipShape(pWin)((pWin)->optional ? (pWin)->optional->clipShape : (( void*)0))) |
899 | RegionDestroy(wClipShape(pWin)((pWin)->optional ? (pWin)->optional->clipShape : (( void*)0))); |
900 | if (wInputShape(pWin)((pWin)->optional ? (pWin)->optional->inputShape : ( (void*)0))) |
901 | RegionDestroy(wInputShape(pWin)((pWin)->optional ? (pWin)->optional->inputShape : ( (void*)0))); |
902 | if (pWin->borderIsPixel == FALSE0) |
903 | (*pScreen->DestroyPixmap) (pWin->border.pixmap); |
904 | if (pWin->backgroundState == BackgroundPixmap3L) |
905 | (*pScreen->DestroyPixmap) (pWin->background.pixmap); |
906 | |
907 | DeleteAllWindowProperties(pWin); |
908 | /* We SHOULD check for an error value here XXX */ |
909 | (*pScreen->DestroyWindow) (pWin); |
910 | DisposeWindowOptional(pWin); |
911 | } |
912 | |
913 | static void |
914 | CrushTree(WindowPtr pWin) |
915 | { |
916 | WindowPtr pChild, pSib, pParent; |
917 | UnrealizeWindowProcPtr UnrealizeWindow; |
918 | |
919 | if (!(pChild = pWin->firstChild)) |
920 | return; |
921 | UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; |
922 | while (1) { |
923 | if (pChild->firstChild) { |
924 | pChild = pChild->firstChild; |
925 | continue; |
926 | } |
927 | while (1) { |
928 | pParent = pChild->parent; |
929 | if (SubStrSend(pChild, pParent)(((pChild->eventMask|((pChild)->optional ? (pChild)-> optional->otherEventMasks : 0)) & (1L<<17)) || ( (pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<19)))) { |
930 | xEvent event = { .u.u.type = DestroyNotify17 }; |
931 | event.u.destroyNotify.window = pChild->drawable.id; |
932 | DeliverEvents(pChild, &event, 1, NullWindow((WindowPtr) 0)); |
933 | } |
934 | FreeResource(pChild->drawable.id, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30))); |
935 | pSib = pChild->nextSib; |
936 | pChild->viewable = FALSE0; |
937 | if (pChild->realized) { |
938 | pChild->realized = FALSE0; |
939 | (*UnrealizeWindow) (pChild); |
940 | } |
941 | FreeWindowResources(pChild); |
942 | dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW)_dixFreeObjectWithPrivates(pChild, (pChild)->devPrivates, PRIVATE_WINDOW ); |
943 | if ((pChild = pSib)) |
944 | break; |
945 | pChild = pParent; |
946 | pChild->firstChild = NullWindow((WindowPtr) 0); |
947 | pChild->lastChild = NullWindow((WindowPtr) 0); |
948 | if (pChild == pWin) |
949 | return; |
950 | } |
951 | } |
952 | } |
953 | |
954 | /***** |
955 | * DeleteWindow |
956 | * Deletes child of window then window itself |
957 | * If wid is None, don't send any events |
958 | *****/ |
959 | |
960 | int |
961 | DeleteWindow(void *value, XID wid) |
962 | { |
963 | WindowPtr pParent; |
964 | WindowPtr pWin = (WindowPtr) value; |
965 | |
966 | UnmapWindow(pWin, FALSE0); |
967 | |
968 | CrushTree(pWin); |
969 | |
970 | pParent = pWin->parent; |
971 | if (wid && pParent && SubStrSend(pWin, pParent)(((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || ((pParent ->eventMask|((pParent)->optional ? (pParent)->optional ->otherEventMasks : 0)) & (1L<<19)))) { |
972 | xEvent event = { .u.u.type = DestroyNotify17 }; |
973 | event.u.destroyNotify.window = pWin->drawable.id; |
974 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
975 | } |
976 | |
977 | FreeWindowResources(pWin); |
978 | if (pParent) { |
979 | if (pParent->firstChild == pWin) |
980 | pParent->firstChild = pWin->nextSib; |
981 | if (pParent->lastChild == pWin) |
982 | pParent->lastChild = pWin->prevSib; |
983 | if (pWin->nextSib) |
984 | pWin->nextSib->prevSib = pWin->prevSib; |
985 | if (pWin->prevSib) |
986 | pWin->prevSib->nextSib = pWin->nextSib; |
987 | } |
988 | else |
989 | pWin->drawable.pScreen->root = NULL((void*)0); |
990 | dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW)_dixFreeObjectWithPrivates(pWin, (pWin)->devPrivates, PRIVATE_WINDOW ); |
991 | return Success0; |
992 | } |
993 | |
994 | int |
995 | DestroySubwindows(WindowPtr pWin, ClientPtr client) |
996 | { |
997 | /* XXX |
998 | * The protocol is quite clear that each window should be |
999 | * destroyed in turn, however, unmapping all of the first |
1000 | * eliminates most of the calls to ValidateTree. So, |
1001 | * this implementation is incorrect in that all of the |
1002 | * UnmapNotifies occur before all of the DestroyNotifies. |
1003 | * If you care, simply delete the call to UnmapSubwindows. |
1004 | */ |
1005 | UnmapSubwindows(pWin); |
1006 | while (pWin->lastChild) { |
1007 | int rc = XaceHook(XACE_RESOURCE_ACCESS2, client, |
1008 | pWin->lastChild->drawable.id, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), |
1009 | pWin->lastChild, RT_NONE((RESTYPE)0), NULL((void*)0), DixDestroyAccess(1<<2)); |
1010 | |
1011 | if (rc != Success0) |
1012 | return rc; |
1013 | FreeResource(pWin->lastChild->drawable.id, RT_NONE((RESTYPE)0)); |
1014 | } |
1015 | return Success0; |
1016 | } |
1017 | |
1018 | static void |
1019 | SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) |
1020 | { |
1021 | /* following the protocol: "Changing the background of a root window to |
1022 | * None or ParentRelative restores the default background pixmap" */ |
1023 | if (bgNoneRoot) { |
1024 | pWin->backgroundState = XaceBackgroundNoneState(pWin)((pWin)->forcedBG ? 2L : 0L); |
1025 | pWin->background.pixel = pScreen->whitePixel; |
1026 | } |
1027 | else if (party_like_its_1989) |
1028 | MakeRootTile(pWin); |
1029 | else { |
1030 | pWin->backgroundState = BackgroundPixel2L; |
1031 | if (whiteRoot) |
1032 | pWin->background.pixel = pScreen->whitePixel; |
1033 | else |
1034 | pWin->background.pixel = pScreen->blackPixel; |
1035 | *index2 = CWBackPixel(1L<<1); |
1036 | } |
1037 | } |
1038 | |
1039 | /***** |
1040 | * ChangeWindowAttributes |
1041 | * |
1042 | * The value-mask specifies which attributes are to be changed; the |
1043 | * value-list contains one value for each one bit in the mask, from least |
1044 | * to most significant bit in the mask. |
1045 | *****/ |
1046 | |
1047 | int |
1048 | ChangeWindowAttributesDarwin_X_ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) |
1049 | { |
1050 | XID *pVlist; |
1051 | PixmapPtr pPixmap; |
1052 | Pixmap pixID; |
1053 | CursorPtr pCursor, pOldCursor; |
1054 | Cursor cursorID; |
1055 | WindowPtr pChild; |
1056 | Colormap cmap; |
1057 | ColormapPtr pCmap; |
1058 | xEvent xE; |
1059 | int error, rc; |
1060 | ScreenPtr pScreen; |
1061 | Mask index2, tmask, vmaskCopy = 0; |
1062 | unsigned int val; |
1063 | Bool checkOptional = FALSE0, borderRelative = FALSE0; |
1064 | |
1065 | if ((pWin->drawable.class == InputOnly2) && |
1066 | (vmask & (~INPUTONLY_LEGAL_MASK((1L<<5) | (1L<<11) | (1L<<12) | (1L<< 9) | (1L<<14) )))) |
1067 | return BadMatch8; |
1068 | |
1069 | error = Success0; |
1070 | pScreen = pWin->drawable.pScreen; |
1071 | pVlist = vlist; |
1072 | tmask = vmask; |
1073 | while (tmask) { |
1074 | index2 = (Mask) lowbit(tmask)((tmask) & (~(tmask) + 1)); |
1075 | tmask &= ~index2; |
1076 | switch (index2) { |
1077 | case CWBackPixmap(1L<<0): |
1078 | pixID = (Pixmap) * pVlist; |
1079 | pVlist++; |
1080 | if (pWin->backgroundState == ParentRelative1L) |
1081 | borderRelative = TRUE1; |
1082 | if (pixID == None0L) { |
1083 | if (pWin->backgroundState == BackgroundPixmap3L) |
1084 | (*pScreen->DestroyPixmap) (pWin->background.pixmap); |
1085 | if (!pWin->parent) |
1086 | SetRootWindowBackground(pWin, pScreen, &index2); |
1087 | else { |
1088 | pWin->backgroundState = XaceBackgroundNoneState(pWin)((pWin)->forcedBG ? 2L : 0L); |
1089 | pWin->background.pixel = pScreen->whitePixel; |
1090 | } |
1091 | } |
1092 | else if (pixID == ParentRelative1L) { |
1093 | if (pWin->parent && |
1094 | pWin->drawable.depth != pWin->parent->drawable.depth) { |
1095 | error = BadMatch8; |
1096 | goto PatchUp; |
1097 | } |
1098 | if (pWin->backgroundState == BackgroundPixmap3L) |
1099 | (*pScreen->DestroyPixmap) (pWin->background.pixmap); |
1100 | if (!pWin->parent) |
1101 | SetRootWindowBackground(pWin, pScreen, &index2); |
1102 | else |
1103 | pWin->backgroundState = ParentRelative1L; |
1104 | borderRelative = TRUE1; |
1105 | /* Note that the parent's backgroundTile's refcnt is NOT |
1106 | * incremented. */ |
1107 | } |
1108 | else { |
1109 | rc = dixLookupResourceByType((void **) &pPixmap, pixID, |
1110 | RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), client, DixReadAccess(1<<0)); |
1111 | if (rc == Success0) { |
1112 | if ((pPixmap->drawable.depth != pWin->drawable.depth) || |
1113 | (pPixmap->drawable.pScreen != pScreen)) { |
1114 | error = BadMatch8; |
1115 | goto PatchUp; |
1116 | } |
1117 | if (pWin->backgroundState == BackgroundPixmap3L) |
1118 | (*pScreen->DestroyPixmap) (pWin->background.pixmap); |
1119 | pWin->backgroundState = BackgroundPixmap3L; |
1120 | pWin->background.pixmap = pPixmap; |
1121 | pPixmap->refcnt++; |
1122 | } |
1123 | else { |
1124 | error = rc; |
1125 | client->errorValue = pixID; |
1126 | goto PatchUp; |
1127 | } |
1128 | } |
1129 | break; |
1130 | case CWBackPixel(1L<<1): |
1131 | if (pWin->backgroundState == ParentRelative1L) |
1132 | borderRelative = TRUE1; |
1133 | if (pWin->backgroundState == BackgroundPixmap3L) |
1134 | (*pScreen->DestroyPixmap) (pWin->background.pixmap); |
1135 | pWin->backgroundState = BackgroundPixel2L; |
1136 | pWin->background.pixel = (CARD32) *pVlist; |
1137 | /* background pixel overrides background pixmap, |
1138 | so don't let the ddx layer see both bits */ |
1139 | vmaskCopy &= ~CWBackPixmap(1L<<0); |
1140 | pVlist++; |
1141 | break; |
1142 | case CWBorderPixmap(1L<<2): |
1143 | pixID = (Pixmap) * pVlist; |
1144 | pVlist++; |
1145 | if (pixID == CopyFromParent0L) { |
1146 | if (!pWin->parent || |
1147 | (pWin->drawable.depth != pWin->parent->drawable.depth)) { |
1148 | error = BadMatch8; |
1149 | goto PatchUp; |
1150 | } |
1151 | if (pWin->parent->borderIsPixel == TRUE1) { |
1152 | if (pWin->borderIsPixel == FALSE0) |
1153 | (*pScreen->DestroyPixmap) (pWin->border.pixmap); |
1154 | pWin->border = pWin->parent->border; |
1155 | pWin->borderIsPixel = TRUE1; |
1156 | index2 = CWBorderPixel(1L<<3); |
1157 | break; |
1158 | } |
1159 | else { |
1160 | pixID = pWin->parent->border.pixmap->drawable.id; |
1161 | } |
1162 | } |
1163 | rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), |
1164 | client, DixReadAccess(1<<0)); |
1165 | if (rc == Success0) { |
1166 | if ((pPixmap->drawable.depth != pWin->drawable.depth) || |
1167 | (pPixmap->drawable.pScreen != pScreen)) { |
1168 | error = BadMatch8; |
1169 | goto PatchUp; |
1170 | } |
1171 | if (pWin->borderIsPixel == FALSE0) |
1172 | (*pScreen->DestroyPixmap) (pWin->border.pixmap); |
1173 | pWin->borderIsPixel = FALSE0; |
1174 | pWin->border.pixmap = pPixmap; |
1175 | pPixmap->refcnt++; |
1176 | } |
1177 | else { |
1178 | error = rc; |
1179 | client->errorValue = pixID; |
1180 | goto PatchUp; |
1181 | } |
1182 | break; |
1183 | case CWBorderPixel(1L<<3): |
1184 | if (pWin->borderIsPixel == FALSE0) |
1185 | (*pScreen->DestroyPixmap) (pWin->border.pixmap); |
1186 | pWin->borderIsPixel = TRUE1; |
1187 | pWin->border.pixel = (CARD32) *pVlist; |
1188 | /* border pixel overrides border pixmap, |
1189 | so don't let the ddx layer see both bits */ |
1190 | vmaskCopy &= ~CWBorderPixmap(1L<<2); |
1191 | pVlist++; |
1192 | break; |
1193 | case CWBitGravity(1L<<4): |
1194 | val = (CARD8) *pVlist; |
1195 | pVlist++; |
1196 | if (val > StaticGravity10) { |
1197 | error = BadValue2; |
1198 | client->errorValue = val; |
1199 | goto PatchUp; |
1200 | } |
1201 | pWin->bitGravity = val; |
1202 | break; |
1203 | case CWWinGravity(1L<<5): |
1204 | val = (CARD8) *pVlist; |
1205 | pVlist++; |
1206 | if (val > StaticGravity10) { |
1207 | error = BadValue2; |
1208 | client->errorValue = val; |
1209 | goto PatchUp; |
1210 | } |
1211 | pWin->winGravity = val; |
1212 | break; |
1213 | case CWBackingStore(1L<<6): |
1214 | val = (CARD8) *pVlist; |
1215 | pVlist++; |
1216 | if ((val != NotUseful0) && (val != WhenMapped1) && (val != Always2)) { |
1217 | error = BadValue2; |
1218 | client->errorValue = val; |
1219 | goto PatchUp; |
1220 | } |
1221 | pWin->backingStore = val; |
1222 | pWin->forcedBS = FALSE0; |
1223 | break; |
1224 | case CWBackingPlanes(1L<<7): |
1225 | if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) { |
1226 | if (!pWin->optional && !MakeWindowOptional(pWin)) { |
1227 | error = BadAlloc11; |
1228 | goto PatchUp; |
1229 | } |
1230 | pWin->optional->backingBitPlanes = (CARD32) *pVlist; |
1231 | if ((CARD32) *pVlist == (CARD32) ~0L) |
1232 | checkOptional = TRUE1; |
1233 | } |
1234 | pVlist++; |
1235 | break; |
1236 | case CWBackingPixel(1L<<8): |
1237 | if (pWin->optional || (CARD32) *pVlist) { |
1238 | if (!pWin->optional && !MakeWindowOptional(pWin)) { |
1239 | error = BadAlloc11; |
1240 | goto PatchUp; |
1241 | } |
1242 | pWin->optional->backingPixel = (CARD32) *pVlist; |
1243 | if (!*pVlist) |
1244 | checkOptional = TRUE1; |
1245 | } |
1246 | pVlist++; |
1247 | break; |
1248 | case CWSaveUnder(1L<<10): |
1249 | val = (BOOL) * pVlist; |
1250 | pVlist++; |
1251 | if ((val != xTrue1) && (val != xFalse0)) { |
1252 | error = BadValue2; |
1253 | client->errorValue = val; |
1254 | goto PatchUp; |
1255 | } |
1256 | pWin->saveUnder = val; |
1257 | break; |
1258 | case CWEventMask(1L<<11): |
1259 | rc = EventSelectForWindow(pWin, client, (Mask) *pVlist); |
1260 | if (rc) { |
1261 | error = rc; |
1262 | goto PatchUp; |
1263 | } |
1264 | pVlist++; |
1265 | break; |
1266 | case CWDontPropagate(1L<<12): |
1267 | rc = EventSuppressForWindow(pWin, client, (Mask) *pVlist, |
1268 | &checkOptional); |
1269 | if (rc) { |
1270 | error = rc; |
1271 | goto PatchUp; |
1272 | } |
1273 | pVlist++; |
1274 | break; |
1275 | case CWOverrideRedirect(1L<<9): |
1276 | val = (BOOL) * pVlist; |
1277 | pVlist++; |
1278 | if ((val != xTrue1) && (val != xFalse0)) { |
1279 | error = BadValue2; |
1280 | client->errorValue = val; |
1281 | goto PatchUp; |
1282 | } |
1283 | if (val == xTrue1) { |
1284 | rc = XaceHook(XACE_RESOURCE_ACCESS2, client, pWin->drawable.id, |
1285 | RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), pWin, RT_NONE((RESTYPE)0), NULL((void*)0), DixGrabAccess(1<<17)); |
1286 | if (rc != Success0) { |
1287 | error = rc; |
1288 | client->errorValue = pWin->drawable.id; |
1289 | goto PatchUp; |
1290 | } |
1291 | } |
1292 | pWin->overrideRedirect = val; |
1293 | break; |
1294 | case CWColormap(1L<<13): |
1295 | cmap = (Colormap) * pVlist; |
1296 | pVlist++; |
1297 | if (cmap == CopyFromParent0L) { |
1298 | if (pWin->parent && |
1299 | (!pWin->optional || |
1300 | pWin->optional->visual == wVisual(pWin->parent)((pWin->parent)->optional ? (pWin->parent)->optional ->visual : FindWindowWithOptional(pWin->parent)->optional ->visual))) { |
1301 | cmap = wColormap(pWin->parent)((pWin->parent)->drawable.class == 2 ? 0L : ((pWin-> parent)->optional ? (pWin->parent)->optional->colormap : FindWindowWithOptional(pWin->parent)->optional->colormap )); |
1302 | } |
1303 | else |
1304 | cmap = None0L; |
1305 | } |
1306 | if (cmap == None0L) { |
1307 | error = BadMatch8; |
1308 | goto PatchUp; |
1309 | } |
1310 | rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP((RESTYPE)6), |
1311 | client, DixUseAccess(1<<24)); |
1312 | if (rc != Success0) { |
1313 | error = rc; |
1314 | client->errorValue = cmap; |
1315 | goto PatchUp; |
1316 | } |
1317 | if (pCmap->pVisual->vid != wVisual(pWin)((pWin)->optional ? (pWin)->optional->visual : FindWindowWithOptional (pWin)->optional->visual) || |
1318 | pCmap->pScreen != pScreen) { |
1319 | error = BadMatch8; |
1320 | goto PatchUp; |
1321 | } |
1322 | if (cmap != wColormap(pWin)((pWin)->drawable.class == 2 ? 0L : ((pWin)->optional ? (pWin)->optional->colormap : FindWindowWithOptional(pWin )->optional->colormap))) { |
1323 | if (!pWin->optional) { |
1324 | if (!MakeWindowOptional(pWin)) { |
1325 | error = BadAlloc11; |
1326 | goto PatchUp; |
1327 | } |
1328 | } |
1329 | else if (pWin->parent && cmap == wColormap(pWin->parent)((pWin->parent)->drawable.class == 2 ? 0L : ((pWin-> parent)->optional ? (pWin->parent)->optional->colormap : FindWindowWithOptional(pWin->parent)->optional->colormap ))) |
1330 | checkOptional = TRUE1; |
1331 | |
1332 | /* |
1333 | * propagate the original colormap to any children |
1334 | * inheriting it |
1335 | */ |
1336 | |
1337 | for (pChild = pWin->firstChild; pChild; |
1338 | pChild = pChild->nextSib) { |
1339 | if (!pChild->optional && !MakeWindowOptional(pChild)) { |
1340 | error = BadAlloc11; |
1341 | goto PatchUp; |
1342 | } |
1343 | } |
1344 | |
1345 | pWin->optional->colormap = cmap; |
1346 | |
1347 | /* |
1348 | * check on any children now matching the new colormap |
1349 | */ |
1350 | |
1351 | for (pChild = pWin->firstChild; pChild; |
1352 | pChild = pChild->nextSib) { |
1353 | if (pChild->optional->colormap == cmap) |
1354 | CheckWindowOptionalNeed(pChild); |
1355 | } |
1356 | |
1357 | xE = (xEvent) { |
1358 | .u.colormap.window = pWin->drawable.id, |
1359 | .u.colormap.colormap = cmap, |
1360 | .u.colormap.new = xTrue1, |
1361 | .u.colormap.state = IsMapInstalled(cmap, pWin) |
1362 | }; |
1363 | xE.u.u.type = ColormapNotify32; |
1364 | DeliverEvents(pWin, &xE, 1, NullWindow((WindowPtr) 0)); |
1365 | } |
1366 | break; |
1367 | case CWCursor(1L<<14): |
1368 | cursorID = (Cursor) * pVlist; |
1369 | pVlist++; |
1370 | /* |
1371 | * install the new |
1372 | */ |
1373 | if (cursorID == None0L) { |
1374 | if (pWin == pWin->drawable.pScreen->root) |
1375 | pCursor = rootCursor; |
1376 | else |
1377 | pCursor = (CursorPtr) None0L; |
1378 | } |
1379 | else { |
1380 | rc = dixLookupResourceByType((void **) &pCursor, cursorID, |
1381 | RT_CURSOR((RESTYPE)5), client, DixUseAccess(1<<24)); |
1382 | if (rc != Success0) { |
1383 | error = rc; |
1384 | client->errorValue = cursorID; |
1385 | goto PatchUp; |
1386 | } |
1387 | } |
1388 | |
1389 | if (pCursor != wCursor(pWin)((pWin)->cursorIsNone ? 0L : ((pWin)->optional ? (pWin) ->optional->cursor : FindWindowWithOptional(pWin)->optional ->cursor))) { |
1390 | /* |
1391 | * patch up child windows so they don't lose cursors. |
1392 | */ |
1393 | |
1394 | for (pChild = pWin->firstChild; pChild; |
1395 | pChild = pChild->nextSib) { |
1396 | if (!pChild->optional && !pChild->cursorIsNone && |
1397 | !MakeWindowOptional(pChild)) { |
1398 | error = BadAlloc11; |
1399 | goto PatchUp; |
1400 | } |
1401 | } |
1402 | |
1403 | pOldCursor = 0; |
1404 | if (pCursor == (CursorPtr) None0L) { |
1405 | pWin->cursorIsNone = TRUE1; |
1406 | if (pWin->optional) { |
1407 | pOldCursor = pWin->optional->cursor; |
1408 | pWin->optional->cursor = (CursorPtr) None0L; |
1409 | checkOptional = TRUE1; |
1410 | } |
1411 | } |
1412 | else { |
1413 | if (!pWin->optional) { |
1414 | if (!MakeWindowOptional(pWin)) { |
1415 | error = BadAlloc11; |
1416 | goto PatchUp; |
1417 | } |
1418 | } |
1419 | else if (pWin->parent && pCursor == wCursor(pWin->parent)((pWin->parent)->cursorIsNone ? 0L : ((pWin->parent) ->optional ? (pWin->parent)->optional->cursor : FindWindowWithOptional (pWin->parent)->optional->cursor))) |
1420 | checkOptional = TRUE1; |
1421 | pOldCursor = pWin->optional->cursor; |
1422 | pWin->optional->cursor = RefCursor(pCursor); |
1423 | pWin->cursorIsNone = FALSE0; |
1424 | /* |
1425 | * check on any children now matching the new cursor |
1426 | */ |
1427 | |
1428 | for (pChild = pWin->firstChild; pChild; |
1429 | pChild = pChild->nextSib) { |
1430 | if (pChild->optional && |
1431 | (pChild->optional->cursor == pCursor)) |
1432 | CheckWindowOptionalNeed(pChild); |
1433 | } |
1434 | } |
1435 | |
1436 | CursorVisible = TRUE1; |
1437 | |
1438 | if (pWin->realized) |
1439 | WindowHasNewCursor(pWin); |
1440 | |
1441 | /* Can't free cursor until here - old cursor |
1442 | * is needed in WindowHasNewCursor |
1443 | */ |
1444 | if (pOldCursor) |
1445 | FreeCursor(pOldCursor, (Cursor) 0); |
1446 | } |
1447 | break; |
1448 | default: |
1449 | error = BadValue2; |
1450 | client->errorValue = vmask; |
1451 | goto PatchUp; |
1452 | } |
1453 | vmaskCopy |= index2; |
1454 | } |
1455 | PatchUp: |
1456 | if (checkOptional) |
1457 | CheckWindowOptionalNeed(pWin); |
1458 | |
1459 | /* We SHOULD check for an error value here XXX */ |
1460 | (*pScreen->ChangeWindowAttributesDarwin_X_ChangeWindowAttributes) (pWin, vmaskCopy); |
1461 | |
1462 | /* |
1463 | If the border contents have changed, redraw the border. |
1464 | Note that this has to be done AFTER pScreen->ChangeWindowAttributes |
1465 | for the tile to be rotated, and the correct function selected. |
1466 | */ |
1467 | if (((vmaskCopy & (CWBorderPixel(1L<<3) | CWBorderPixmap(1L<<2))) || borderRelative) |
1468 | && pWin->viewable && HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { |
1469 | RegionRec exposed; |
1470 | |
1471 | RegionNull(&exposed); |
1472 | RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); |
1473 | miPaintWindow(pWin, &exposed, PW_BORDER1); |
1474 | RegionUninit(&exposed); |
1475 | } |
1476 | return error; |
1477 | } |
1478 | |
1479 | /***** |
1480 | * GetWindowAttributes |
1481 | * Notice that this is different than ChangeWindowAttributes |
1482 | *****/ |
1483 | |
1484 | void |
1485 | GetWindowAttributes(WindowPtr pWin, ClientPtr client,Darwin_X_GetWindowAttributes(WindowPtr pWin,ClientPtr client, xGetWindowAttributesReply * wa) |
1486 | xGetWindowAttributesReply * wa)Darwin_X_GetWindowAttributes(WindowPtr pWin,ClientPtr client, xGetWindowAttributesReply * wa) |
1487 | { |
1488 | wa->type = X_Reply1; |
1489 | wa->bitGravity = pWin->bitGravity; |
1490 | wa->winGravity = pWin->winGravity; |
1491 | if (pWin->forcedBS && pWin->backingStore != Always2) |
1492 | wa->backingStore = NotUseful0; |
1493 | else |
1494 | wa->backingStore = pWin->backingStore; |
1495 | wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - |
1496 | sizeof(xGenericReply)); |
1497 | wa->sequenceNumber = client->sequence; |
1498 | wa->backingBitPlanes = wBackingBitPlanes(pWin)((pWin)->optional ? (pWin)->optional->backingBitPlanes : ~0L); |
1499 | wa->backingPixel = wBackingPixel(pWin)((pWin)->optional ? (pWin)->optional->backingPixel : 0); |
1500 | wa->saveUnder = (BOOL) pWin->saveUnder; |
1501 | wa->override = pWin->overrideRedirect; |
1502 | if (!pWin->mapped) |
1503 | wa->mapState = IsUnmapped0; |
1504 | else if (pWin->realized) |
1505 | wa->mapState = IsViewable2; |
1506 | else |
1507 | wa->mapState = IsUnviewable1; |
1508 | |
1509 | wa->colormap = wColormap(pWin)((pWin)->drawable.class == 2 ? 0L : ((pWin)->optional ? (pWin)->optional->colormap : FindWindowWithOptional(pWin )->optional->colormap)); |
1510 | wa->mapInstalled = (wa->colormap == None0L) ? xFalse0 |
1511 | : IsMapInstalled(wa->colormap, pWin); |
1512 | |
1513 | wa->yourEventMask = EventMaskForClient(pWin, client); |
1514 | wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0); |
1515 | wa->doNotPropagateMask = wDontPropagateMask(pWin)((pWin)->optional ? (pWin)->optional->dontPropagateMask : DontPropagateMasks[(pWin)->dontPropagate]); |
1516 | wa->class = pWin->drawable.class; |
1517 | wa->visualID = wVisual(pWin)((pWin)->optional ? (pWin)->optional->visual : FindWindowWithOptional (pWin)->optional->visual); |
1518 | } |
1519 | |
1520 | WindowPtr |
1521 | MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) |
1522 | { |
1523 | WindowPtr pParent = pWin->parent; |
1524 | WindowPtr pFirstChange = pWin; /* highest window where list changes */ |
1525 | |
1526 | if (pWin->nextSib != pNextSib) { |
1527 | WindowPtr pOldNextSib = pWin->nextSib; |
1528 | |
1529 | if (!pNextSib) { /* move to bottom */ |
1530 | if (pParent->firstChild == pWin) |
1531 | pParent->firstChild = pWin->nextSib; |
1532 | /* if (pWin->nextSib) *//* is always True: pNextSib == NULL |
1533 | * and pWin->nextSib != pNextSib |
1534 | * therefore pWin->nextSib != NULL */ |
1535 | pFirstChange = pWin->nextSib; |
1536 | pWin->nextSib->prevSib = pWin->prevSib; |
1537 | if (pWin->prevSib) |
1538 | pWin->prevSib->nextSib = pWin->nextSib; |
1539 | pParent->lastChild->nextSib = pWin; |
1540 | pWin->prevSib = pParent->lastChild; |
1541 | pWin->nextSib = NullWindow((WindowPtr) 0); |
1542 | pParent->lastChild = pWin; |
1543 | } |
1544 | else if (pParent->firstChild == pNextSib) { /* move to top */ |
1545 | pFirstChange = pWin; |
1546 | if (pParent->lastChild == pWin) |
1547 | pParent->lastChild = pWin->prevSib; |
1548 | if (pWin->nextSib) |
1549 | pWin->nextSib->prevSib = pWin->prevSib; |
1550 | if (pWin->prevSib) |
1551 | pWin->prevSib->nextSib = pWin->nextSib; |
1552 | pWin->nextSib = pParent->firstChild; |
1553 | pWin->prevSib = NULL((void*)0); |
1554 | pNextSib->prevSib = pWin; |
1555 | pParent->firstChild = pWin; |
1556 | } |
1557 | else { /* move in middle of list */ |
1558 | |
1559 | WindowPtr pOldNext = pWin->nextSib; |
1560 | |
1561 | pFirstChange = NullWindow((WindowPtr) 0); |
1562 | if (pParent->firstChild == pWin) |
1563 | pFirstChange = pParent->firstChild = pWin->nextSib; |
1564 | if (pParent->lastChild == pWin) { |
1565 | pFirstChange = pWin; |
1566 | pParent->lastChild = pWin->prevSib; |
1567 | } |
1568 | if (pWin->nextSib) |
1569 | pWin->nextSib->prevSib = pWin->prevSib; |
1570 | if (pWin->prevSib) |
1571 | pWin->prevSib->nextSib = pWin->nextSib; |
1572 | pWin->nextSib = pNextSib; |
1573 | pWin->prevSib = pNextSib->prevSib; |
1574 | if (pNextSib->prevSib) |
1575 | pNextSib->prevSib->nextSib = pWin; |
1576 | pNextSib->prevSib = pWin; |
1577 | if (!pFirstChange) { /* do we know it yet? */ |
1578 | pFirstChange = pParent->firstChild; /* no, search from top */ |
1579 | while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) |
1580 | pFirstChange = pFirstChange->nextSib; |
1581 | } |
1582 | } |
1583 | if (pWin->drawable.pScreen->RestackWindow) |
1584 | (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib); |
1585 | } |
1586 | |
1587 | #ifdef ROOTLESS1 |
1588 | /* |
1589 | * In rootless mode we can't optimize away window restacks. |
1590 | * There may be non-X windows around, so even if the window |
1591 | * is in the correct position from X's point of view, |
1592 | * the underlying window system may want to reorder it. |
1593 | */ |
1594 | else if (pWin->drawable.pScreen->RestackWindow) |
1595 | (*pWin->drawable.pScreen->RestackWindow) (pWin, pWin->nextSib); |
1596 | #endif |
1597 | |
1598 | return pFirstChange; |
1599 | } |
1600 | |
1601 | void |
1602 | SetWinSize(WindowPtr pWin) |
1603 | { |
1604 | #ifdef COMPOSITE |
1605 | if (pWin->redirectDraw != RedirectDrawNone0) { |
1606 | BoxRec box; |
1607 | |
1608 | /* |
1609 | * Redirected clients get clip list equal to their |
1610 | * own geometry, not clipped to their parent |
1611 | */ |
1612 | box.x1 = pWin->drawable.x; |
1613 | box.y1 = pWin->drawable.y; |
1614 | box.x2 = pWin->drawable.x + pWin->drawable.width; |
1615 | box.y2 = pWin->drawable.y + pWin->drawable.height; |
1616 | RegionReset(&pWin->winSize, &box); |
1617 | } |
1618 | else |
1619 | #endif |
1620 | ClippedRegionFromBox(pWin->parent, &pWin->winSize, |
1621 | pWin->drawable.x, pWin->drawable.y, |
1622 | (int) pWin->drawable.width, |
1623 | (int) pWin->drawable.height); |
1624 | if (wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0)) || wClipShape(pWin)((pWin)->optional ? (pWin)->optional->clipShape : (( void*)0))) { |
1625 | RegionTranslate(&pWin->winSize, -pWin->drawable.x, -pWin->drawable.y); |
1626 | if (wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))) |
1627 | RegionIntersect(&pWin->winSize, &pWin->winSize, |
1628 | wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))); |
1629 | if (wClipShape(pWin)((pWin)->optional ? (pWin)->optional->clipShape : (( void*)0))) |
1630 | RegionIntersect(&pWin->winSize, &pWin->winSize, wClipShape(pWin)((pWin)->optional ? (pWin)->optional->clipShape : (( void*)0))); |
1631 | RegionTranslate(&pWin->winSize, pWin->drawable.x, pWin->drawable.y); |
1632 | } |
1633 | } |
1634 | |
1635 | void |
1636 | SetBorderSize(WindowPtr pWin) |
1637 | { |
1638 | int bw; |
1639 | |
1640 | if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { |
1641 | bw = wBorderWidth(pWin)((int) (pWin)->borderWidth); |
1642 | #ifdef COMPOSITE |
1643 | if (pWin->redirectDraw != RedirectDrawNone0) { |
1644 | BoxRec box; |
1645 | |
1646 | /* |
1647 | * Redirected clients get clip list equal to their |
1648 | * own geometry, not clipped to their parent |
1649 | */ |
1650 | box.x1 = pWin->drawable.x - bw; |
1651 | box.y1 = pWin->drawable.y - bw; |
1652 | box.x2 = pWin->drawable.x + pWin->drawable.width + bw; |
1653 | box.y2 = pWin->drawable.y + pWin->drawable.height + bw; |
1654 | RegionReset(&pWin->borderSize, &box); |
1655 | } |
1656 | else |
1657 | #endif |
1658 | ClippedRegionFromBox(pWin->parent, &pWin->borderSize, |
1659 | pWin->drawable.x - bw, pWin->drawable.y - bw, |
1660 | (int) (pWin->drawable.width + (bw << 1)), |
1661 | (int) (pWin->drawable.height + (bw << 1))); |
1662 | if (wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))) { |
1663 | RegionTranslate(&pWin->borderSize, -pWin->drawable.x, |
1664 | -pWin->drawable.y); |
1665 | RegionIntersect(&pWin->borderSize, &pWin->borderSize, |
1666 | wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))); |
1667 | RegionTranslate(&pWin->borderSize, pWin->drawable.x, |
1668 | pWin->drawable.y); |
1669 | RegionUnion(&pWin->borderSize, &pWin->borderSize, &pWin->winSize); |
1670 | } |
1671 | } |
1672 | else { |
1673 | RegionCopy(&pWin->borderSize, &pWin->winSize); |
1674 | } |
1675 | } |
1676 | |
1677 | /** |
1678 | * |
1679 | * \param x,y new window position |
1680 | * \param oldx,oldy old window position |
1681 | * \param destx,desty position relative to gravity |
1682 | */ |
1683 | |
1684 | void |
1685 | GravityTranslate(int x, int y, int oldx, int oldy, |
1686 | int dw, int dh, unsigned gravity, int *destx, int *desty) |
1687 | { |
1688 | switch (gravity) { |
1689 | case NorthGravity2: |
1690 | *destx = x + dw / 2; |
1691 | *desty = y; |
1692 | break; |
1693 | case NorthEastGravity3: |
1694 | *destx = x + dw; |
1695 | *desty = y; |
1696 | break; |
1697 | case WestGravity4: |
1698 | *destx = x; |
1699 | *desty = y + dh / 2; |
1700 | break; |
1701 | case CenterGravity5: |
1702 | *destx = x + dw / 2; |
1703 | *desty = y + dh / 2; |
1704 | break; |
1705 | case EastGravity6: |
1706 | *destx = x + dw; |
1707 | *desty = y + dh / 2; |
1708 | break; |
1709 | case SouthWestGravity7: |
1710 | *destx = x; |
1711 | *desty = y + dh; |
1712 | break; |
1713 | case SouthGravity8: |
1714 | *destx = x + dw / 2; |
1715 | *desty = y + dh; |
1716 | break; |
1717 | case SouthEastGravity9: |
1718 | *destx = x + dw; |
1719 | *desty = y + dh; |
1720 | break; |
1721 | case StaticGravity10: |
1722 | *destx = oldx; |
1723 | *desty = oldy; |
1724 | break; |
1725 | default: |
1726 | *destx = x; |
1727 | *desty = y; |
1728 | break; |
1729 | } |
1730 | } |
1731 | |
1732 | /* XXX need to retile border on each window with ParentRelative origin */ |
1733 | void |
1734 | ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) |
1735 | { |
1736 | ScreenPtr pScreen; |
1737 | WindowPtr pSib, pChild; |
1738 | Bool resized = (dw || dh); |
1739 | |
1740 | pScreen = pWin->drawable.pScreen; |
1741 | |
1742 | for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) { |
1743 | if (resized && (pSib->winGravity > NorthWestGravity1)) { |
1744 | int cwsx, cwsy; |
1745 | |
1746 | cwsx = pSib->origin.x; |
1747 | cwsy = pSib->origin.y; |
1748 | GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, |
1749 | pSib->winGravity, &cwsx, &cwsy); |
1750 | if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) { |
1751 | xEvent event = { |
1752 | .u.gravity.window = pSib->drawable.id, |
1753 | .u.gravity.x = cwsx - wBorderWidth(pSib)((int) (pSib)->borderWidth), |
1754 | .u.gravity.y = cwsy - wBorderWidth(pSib)((int) (pSib)->borderWidth) |
1755 | }; |
1756 | event.u.u.type = GravityNotify24; |
1757 | DeliverEvents(pSib, &event, 1, NullWindow((WindowPtr) 0)); |
1758 | pSib->origin.x = cwsx; |
1759 | pSib->origin.y = cwsy; |
1760 | } |
1761 | } |
1762 | pSib->drawable.x = pWin->drawable.x + pSib->origin.x; |
1763 | pSib->drawable.y = pWin->drawable.y + pSib->origin.y; |
1764 | SetWinSize(pSib); |
1765 | SetBorderSize(pSib); |
1766 | (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y); |
1767 | |
1768 | if ((pChild = pSib->firstChild)) { |
1769 | while (1) { |
1770 | pChild->drawable.x = pChild->parent->drawable.x + |
1771 | pChild->origin.x; |
1772 | pChild->drawable.y = pChild->parent->drawable.y + |
1773 | pChild->origin.y; |
1774 | SetWinSize(pChild); |
1775 | SetBorderSize(pChild); |
1776 | (*pScreen->PositionWindow) (pChild, |
1777 | pChild->drawable.x, |
1778 | pChild->drawable.y); |
1779 | if (pChild->firstChild) { |
1780 | pChild = pChild->firstChild; |
1781 | continue; |
1782 | } |
1783 | while (!pChild->nextSib && (pChild != pSib)) |
1784 | pChild = pChild->parent; |
1785 | if (pChild == pSib) |
1786 | break; |
1787 | pChild = pChild->nextSib; |
1788 | } |
1789 | } |
1790 | } |
1791 | } |
1792 | |
1793 | #define GET_INT16(m, f)if (m & mask) { f = (INT16) *pVlist; pVlist++; } \ |
1794 | if (m & mask) \ |
1795 | { \ |
1796 | f = (INT16) *pVlist;\ |
1797 | pVlist++; \ |
1798 | } |
1799 | #define GET_CARD16(m, f)if (m & mask) { f = (CARD16) *pVlist; pVlist++; } \ |
1800 | if (m & mask) \ |
1801 | { \ |
1802 | f = (CARD16) *pVlist;\ |
1803 | pVlist++;\ |
1804 | } |
1805 | |
1806 | #define GET_CARD8(m, f)if (m & mask) { f = (CARD8) *pVlist; pVlist++; } \ |
1807 | if (m & mask) \ |
1808 | { \ |
1809 | f = (CARD8) *pVlist;\ |
1810 | pVlist++;\ |
1811 | } |
1812 | |
1813 | #define ChangeMask((Mask)((1<<0) | (1<<1) | (1<<2) | (1<< 3))) ((Mask)(CWX(1<<0) | CWY(1<<1) | CWWidth(1<<2) | CWHeight(1<<3))) |
1814 | |
1815 | /* |
1816 | * IsSiblingAboveMe |
1817 | * returns Above if pSib above pMe in stack or Below otherwise |
1818 | */ |
1819 | |
1820 | static int |
1821 | IsSiblingAboveMe(WindowPtr pMe, WindowPtr pSib) |
1822 | { |
1823 | WindowPtr pWin; |
1824 | |
1825 | pWin = pMe->parent->firstChild; |
1826 | while (pWin) { |
1827 | if (pWin == pSib) |
1828 | return Above0; |
1829 | else if (pWin == pMe) |
1830 | return Below1; |
1831 | pWin = pWin->nextSib; |
1832 | } |
1833 | return Below1; |
1834 | } |
1835 | |
1836 | static BoxPtr |
1837 | WindowExtents(WindowPtr pWin, BoxPtr pBox) |
1838 | { |
1839 | pBox->x1 = pWin->drawable.x - wBorderWidth(pWin)((int) (pWin)->borderWidth); |
1840 | pBox->y1 = pWin->drawable.y - wBorderWidth(pWin)((int) (pWin)->borderWidth); |
1841 | pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width |
1842 | + wBorderWidth(pWin)((int) (pWin)->borderWidth); |
1843 | pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height |
1844 | + wBorderWidth(pWin)((int) (pWin)->borderWidth); |
1845 | return pBox; |
1846 | } |
1847 | |
1848 | #define IS_SHAPED(pWin)(((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0)) != ((void*)0)) (wBoundingShape (pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0)) != NULL((void*)0)) |
1849 | |
1850 | static RegionPtr |
1851 | MakeBoundingRegion(WindowPtr pWin, BoxPtr pBox) |
1852 | { |
1853 | RegionPtr pRgn = RegionCreate(pBox, 1); |
1854 | |
1855 | if (wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))) { |
1856 | RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); |
1857 | RegionIntersect(pRgn, pRgn, wBoundingShape(pWin)((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0))); |
1858 | RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); |
1859 | } |
1860 | return pRgn; |
1861 | } |
1862 | |
1863 | static Bool |
1864 | ShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox) |
1865 | { |
1866 | RegionPtr pWinRgn, pSibRgn; |
1867 | Bool ret; |
1868 | |
1869 | if (!IS_SHAPED(pWin)(((pWin)->optional ? (pWin)->optional->boundingShape : ((void*)0)) != ((void*)0)) && !IS_SHAPED(pSib)(((pSib)->optional ? (pSib)->optional->boundingShape : ((void*)0)) != ((void*)0))) |
1870 | return TRUE1; |
1871 | pWinRgn = MakeBoundingRegion(pWin, pWinBox); |
1872 | pSibRgn = MakeBoundingRegion(pSib, pSibBox); |
1873 | RegionIntersect(pWinRgn, pWinRgn, pSibRgn); |
1874 | ret = RegionNotEmpty(pWinRgn); |
1875 | RegionDestroy(pWinRgn); |
1876 | RegionDestroy(pSibRgn); |
1877 | return ret; |
1878 | } |
1879 | |
1880 | static Bool |
1881 | AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box) |
1882 | { |
1883 | WindowPtr pSib; |
1884 | BoxRec sboxrec; |
1885 | BoxPtr sbox; |
1886 | |
1887 | for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) { |
1888 | if (pSib->mapped) { |
1889 | sbox = WindowExtents(pSib, &sboxrec); |
1890 | if (BOXES_OVERLAP(sbox, box)(!( ((sbox)->x2 <= (box)->x1) || ( ((sbox)->x1 >= (box)->x2)) || ( ((sbox)->y2 <= (box)->y1)) || ( ((sbox)->y1 >= (box)->y2)) ) ) |
1891 | && ShapeOverlap(pWin, box, pSib, sbox)) |
1892 | return TRUE1; |
1893 | } |
1894 | } |
1895 | return FALSE0; |
1896 | } |
1897 | |
1898 | static Bool |
1899 | IOverlapAnyWindow(WindowPtr pWin, BoxPtr box) |
1900 | { |
1901 | WindowPtr pSib; |
1902 | BoxRec sboxrec; |
1903 | BoxPtr sbox; |
1904 | |
1905 | for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) { |
1906 | if (pSib->mapped) { |
1907 | sbox = WindowExtents(pSib, &sboxrec); |
1908 | if (BOXES_OVERLAP(sbox, box)(!( ((sbox)->x2 <= (box)->x1) || ( ((sbox)->x1 >= (box)->x2)) || ( ((sbox)->y2 <= (box)->y1)) || ( ((sbox)->y1 >= (box)->y2)) ) ) |
1909 | && ShapeOverlap(pWin, box, pSib, sbox)) |
1910 | return TRUE1; |
1911 | } |
1912 | } |
1913 | return FALSE0; |
1914 | } |
1915 | |
1916 | /* |
1917 | * WhereDoIGoInTheStack() |
1918 | * Given pWin and pSib and the relationshipe smode, return |
1919 | * the window that pWin should go ABOVE. |
1920 | * If a pSib is specified: |
1921 | * Above: pWin is placed just above pSib |
1922 | * Below: pWin is placed just below pSib |
1923 | * TopIf: if pSib occludes pWin, then pWin is placed |
1924 | * at the top of the stack |
1925 | * BottomIf: if pWin occludes pSib, then pWin is |
1926 | * placed at the bottom of the stack |
1927 | * Opposite: if pSib occludes pWin, then pWin is placed at the |
1928 | * top of the stack, else if pWin occludes pSib, then |
1929 | * pWin is placed at the bottom of the stack |
1930 | * |
1931 | * If pSib is NULL: |
1932 | * Above: pWin is placed at the top of the stack |
1933 | * Below: pWin is placed at the bottom of the stack |
1934 | * TopIf: if any sibling occludes pWin, then pWin is placed at |
1935 | * the top of the stack |
1936 | * BottomIf: if pWin occludes any sibline, then pWin is placed at |
1937 | * the bottom of the stack |
1938 | * Opposite: if any sibling occludes pWin, then pWin is placed at |
1939 | * the top of the stack, else if pWin occludes any |
1940 | * sibling, then pWin is placed at the bottom of the stack |
1941 | * |
1942 | */ |
1943 | |
1944 | static WindowPtr |
1945 | WhereDoIGoInTheStack(WindowPtr pWin, |
1946 | WindowPtr pSib, |
1947 | short x, |
1948 | short y, unsigned short w, unsigned short h, int smode) |
1949 | { |
1950 | BoxRec box; |
1951 | WindowPtr pHead, pFirst; |
1952 | |
1953 | if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild)) |
1954 | return NULL((void*)0); |
1955 | pHead = RealChildHead(pWin->parent); |
1956 | pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; |
1957 | box.x1 = x; |
1958 | box.y1 = y; |
1959 | box.x2 = x + (int) w; |
1960 | box.y2 = y + (int) h; |
1961 | switch (smode) { |
1962 | case Above0: |
1963 | if (pSib) |
1964 | return pSib; |
1965 | else if (pWin == pFirst) |
1966 | return pWin->nextSib; |
1967 | else |
1968 | return pFirst; |
1969 | case Below1: |
1970 | if (pSib) |
1971 | if (pSib->nextSib != pWin) |
1972 | return pSib->nextSib; |
1973 | else |
1974 | return pWin->nextSib; |
1975 | else |
1976 | return NullWindow((WindowPtr) 0); |
1977 | case TopIf2: |
1978 | if ((!pWin->mapped || (pSib && !pSib->mapped))) |
1979 | return pWin->nextSib; |
1980 | else if (pSib) { |
1981 | if ((IsSiblingAboveMe(pWin, pSib) == Above0) && |
1982 | (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT0)) |
1983 | return pFirst; |
1984 | else |
1985 | return pWin->nextSib; |
1986 | } |
1987 | else if (AnyWindowOverlapsMe(pWin, pHead, &box)) |
1988 | return pFirst; |
1989 | else |
1990 | return pWin->nextSib; |
1991 | case BottomIf3: |
1992 | if ((!pWin->mapped || (pSib && !pSib->mapped))) |
1993 | return pWin->nextSib; |
1994 | else if (pSib) { |
1995 | if ((IsSiblingAboveMe(pWin, pSib) == Below1) && |
1996 | (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT0)) |
1997 | return NullWindow((WindowPtr) 0); |
1998 | else |
1999 | return pWin->nextSib; |
2000 | } |
2001 | else if (IOverlapAnyWindow(pWin, &box)) |
2002 | return NullWindow((WindowPtr) 0); |
2003 | else |
2004 | return pWin->nextSib; |
2005 | case Opposite4: |
2006 | if ((!pWin->mapped || (pSib && !pSib->mapped))) |
2007 | return pWin->nextSib; |
2008 | else if (pSib) { |
2009 | if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT0) { |
2010 | if (IsSiblingAboveMe(pWin, pSib) == Above0) |
2011 | return pFirst; |
2012 | else |
2013 | return NullWindow((WindowPtr) 0); |
2014 | } |
2015 | else |
2016 | return pWin->nextSib; |
2017 | } |
2018 | else if (AnyWindowOverlapsMe(pWin, pHead, &box)) { |
2019 | /* If I'm occluded, I can't possibly be the first child |
2020 | * if (pWin == pWin->parent->firstChild) |
2021 | * return pWin->nextSib; |
2022 | */ |
2023 | return pFirst; |
2024 | } |
2025 | else if (IOverlapAnyWindow(pWin, &box)) |
2026 | return NullWindow((WindowPtr) 0); |
2027 | else |
2028 | return pWin->nextSib; |
2029 | default: |
2030 | { |
2031 | /* should never happen; make something up. */ |
2032 | return pWin->nextSib; |
2033 | } |
2034 | } |
2035 | } |
2036 | |
2037 | static void |
2038 | ReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) |
2039 | { |
2040 | /* Note that pSib might be NULL */ |
2041 | |
2042 | Bool WasViewable = (Bool) pWin->viewable; |
2043 | Bool anyMarked; |
2044 | WindowPtr pFirstChange; |
2045 | WindowPtr pLayerWin; |
2046 | ScreenPtr pScreen = pWin->drawable.pScreen; |
2047 | |
2048 | /* if this is a root window, can't be restacked */ |
2049 | if (!pWin->parent) |
2050 | return; |
2051 | |
2052 | pFirstChange = MoveWindowInStack(pWin, pSib); |
2053 | |
2054 | if (WasViewable) { |
2055 | anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, |
2056 | &pLayerWin); |
2057 | if (pLayerWin != pWin) |
2058 | pFirstChange = pLayerWin; |
2059 | if (anyMarked) { |
2060 | (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind); |
2061 | (*pScreen->HandleExposures) (pLayerWin->parent); |
2062 | if (pWin->drawable.pScreen->PostValidateTree) |
2063 | (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, |
2064 | kind); |
2065 | } |
2066 | } |
2067 | if (pWin->realized) |
2068 | WindowsRestructured(); |
2069 | } |
2070 | |
2071 | /***** |
2072 | * ConfigureWindow |
2073 | *****/ |
2074 | |
2075 | int |
2076 | ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) |
2077 | { |
2078 | #define RESTACK_WIN 0 |
2079 | #define MOVE_WIN 1 |
2080 | #define RESIZE_WIN 2 |
2081 | #define REBORDER_WIN 3 |
2082 | WindowPtr pSib = NullWindow((WindowPtr) 0); |
2083 | WindowPtr pParent = pWin->parent; |
2084 | Window sibwid = 0; |
2085 | Mask index2, tmask; |
2086 | XID *pVlist; |
2087 | short x, y, beforeX, beforeY; |
2088 | unsigned short w = pWin->drawable.width, |
2089 | h = pWin->drawable.height, bw = pWin->borderWidth; |
2090 | int rc, action, smode = Above0; |
2091 | |
2092 | if ((pWin->drawable.class == InputOnly2) && (mask & CWBorderWidth(1<<4))) |
2093 | return BadMatch8; |
2094 | |
2095 | if ((mask & CWSibling(1<<5)) && !(mask & CWStackMode(1<<6))) |
2096 | return BadMatch8; |
2097 | |
2098 | pVlist = vlist; |
2099 | |
2100 | if (pParent) { |
2101 | x = pWin->drawable.x - pParent->drawable.x - (int) bw; |
2102 | y = pWin->drawable.y - pParent->drawable.y - (int) bw; |
2103 | } |
2104 | else { |
2105 | x = pWin->drawable.x; |
2106 | y = pWin->drawable.y; |
2107 | } |
2108 | beforeX = x; |
2109 | beforeY = y; |
2110 | action = RESTACK_WIN; |
2111 | if ((mask & (CWX(1<<0) | CWY(1<<1))) && (!(mask & (CWHeight(1<<3) | CWWidth(1<<2))))) { |
2112 | GET_INT16(CWX, x)if ((1<<0) & mask) { x = (INT16) *pVlist; pVlist++; }; |
2113 | GET_INT16(CWY, y)if ((1<<1) & mask) { y = (INT16) *pVlist; pVlist++; }; |
2114 | action = MOVE_WIN; |
2115 | } |
2116 | /* or should be resized */ |
2117 | else if (mask & (CWX(1<<0) | CWY(1<<1) | CWWidth(1<<2) | CWHeight(1<<3))) { |
2118 | GET_INT16(CWX, x)if ((1<<0) & mask) { x = (INT16) *pVlist; pVlist++; }; |
2119 | GET_INT16(CWY, y)if ((1<<1) & mask) { y = (INT16) *pVlist; pVlist++; }; |
2120 | GET_CARD16(CWWidth, w)if ((1<<2) & mask) { w = (CARD16) *pVlist; pVlist++ ; }; |
2121 | GET_CARD16(CWHeight, h)if ((1<<3) & mask) { h = (CARD16) *pVlist; pVlist++ ; }; |
2122 | if (!w || !h) { |
2123 | client->errorValue = 0; |
2124 | return BadValue2; |
2125 | } |
2126 | action = RESIZE_WIN; |
2127 | } |
2128 | tmask = mask & ~ChangeMask((Mask)((1<<0) | (1<<1) | (1<<2) | (1<< 3))); |
2129 | while (tmask) { |
2130 | index2 = (Mask) lowbit(tmask)((tmask) & (~(tmask) + 1)); |
2131 | tmask &= ~index2; |
2132 | switch (index2) { |
2133 | case CWBorderWidth(1<<4): |
2134 | GET_CARD16(CWBorderWidth, bw)if ((1<<4) & mask) { bw = (CARD16) *pVlist; pVlist++ ; }; |
2135 | break; |
2136 | case CWSibling(1<<5): |
2137 | sibwid = (Window) *pVlist; |
2138 | pVlist++; |
2139 | rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess(1<<4)); |
2140 | if (rc != Success0) { |
2141 | client->errorValue = sibwid; |
2142 | return rc; |
2143 | } |
2144 | if (pSib->parent != pParent) |
2145 | return BadMatch8; |
2146 | if (pSib == pWin) |
2147 | return BadMatch8; |
2148 | break; |
2149 | case CWStackMode(1<<6): |
2150 | GET_CARD8(CWStackMode, smode)if ((1<<6) & mask) { smode = (CARD8) *pVlist; pVlist ++; }; |
2151 | if ((smode != TopIf2) && (smode != BottomIf3) && |
2152 | (smode != Opposite4) && (smode != Above0) && (smode != Below1)) { |
2153 | client->errorValue = smode; |
2154 | return BadValue2; |
2155 | } |
2156 | break; |
2157 | default: |
2158 | client->errorValue = mask; |
2159 | return BadValue2; |
2160 | } |
2161 | } |
2162 | /* root really can't be reconfigured, so just return */ |
2163 | if (!pParent) |
2164 | return Success0; |
2165 | |
2166 | /* Figure out if the window should be moved. Doesnt |
2167 | make the changes to the window if event sent */ |
2168 | |
2169 | if (mask & CWStackMode(1<<6)) |
2170 | pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, |
2171 | pParent->drawable.y + y, |
2172 | w + (bw << 1), h + (bw << 1), smode); |
2173 | else |
2174 | pSib = pWin->nextSib; |
2175 | |
2176 | if ((!pWin->overrideRedirect) && (RedirectSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<20)))) { |
2177 | xEvent event = { |
2178 | .u.configureRequest.window = pWin->drawable.id, |
2179 | .u.configureRequest.sibling = (mask & CWSibling(1<<5)) ? sibwid : None0L, |
2180 | .u.configureRequest.x = x, |
2181 | .u.configureRequest.y = y, |
2182 | .u.configureRequest.width = w, |
2183 | .u.configureRequest.height = h, |
2184 | .u.configureRequest.borderWidth = bw, |
2185 | .u.configureRequest.valueMask = mask, |
2186 | .u.configureRequest.parent = pParent->drawable.id |
2187 | }; |
2188 | event.u.u.type = ConfigureRequest23; |
2189 | event.u.u.detail = (mask & CWStackMode(1<<6)) ? smode : Above0; |
2190 | #ifdef PANORAMIX1 |
2191 | if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { |
2192 | event.u.configureRequest.x += screenInfo.screens[0]->x; |
2193 | event.u.configureRequest.y += screenInfo.screens[0]->y; |
2194 | } |
2195 | #endif |
2196 | if (MaybeDeliverEventsToClient(pParent, &event, 1, |
2197 | SubstructureRedirectMask(1L<<20), client) == 1) |
2198 | return Success0; |
2199 | } |
2200 | if (action == RESIZE_WIN) { |
2201 | Bool size_change = (w != pWin->drawable.width) |
2202 | || (h != pWin->drawable.height); |
2203 | |
2204 | if (size_change && |
2205 | ((pWin->eventMask | wOtherEventMasks(pWin)((pWin)->optional ? (pWin)->optional->otherEventMasks : 0)) & ResizeRedirectMask(1L<<18))) { |
2206 | xEvent eventT = { |
2207 | .u.resizeRequest.window = pWin->drawable.id, |
2208 | .u.resizeRequest.width = w, |
2209 | .u.resizeRequest.height = h |
2210 | }; |
2211 | eventT.u.u.type = ResizeRequest25; |
2212 | if (MaybeDeliverEventsToClient(pWin, &eventT, 1, |
2213 | ResizeRedirectMask(1L<<18), client) == 1) { |
2214 | /* if event is delivered, leave the actual size alone. */ |
2215 | w = pWin->drawable.width; |
2216 | h = pWin->drawable.height; |
2217 | size_change = FALSE0; |
2218 | } |
2219 | } |
2220 | if (!size_change) { |
2221 | if (mask & (CWX(1<<0) | CWY(1<<1))) |
2222 | action = MOVE_WIN; |
2223 | else if (mask & (CWStackMode(1<<6) | CWBorderWidth(1<<4))) |
2224 | action = RESTACK_WIN; |
2225 | else /* really nothing to do */ |
2226 | return (Success0); |
2227 | } |
2228 | } |
2229 | |
2230 | if (action == RESIZE_WIN) |
2231 | /* we've already checked whether there's really a size change */ |
2232 | goto ActuallyDoSomething; |
2233 | if ((mask & CWX(1<<0)) && (x != beforeX)) |
2234 | goto ActuallyDoSomething; |
2235 | if ((mask & CWY(1<<1)) && (y != beforeY)) |
2236 | goto ActuallyDoSomething; |
2237 | if ((mask & CWBorderWidth(1<<4)) && (bw != wBorderWidth(pWin)((int) (pWin)->borderWidth))) |
2238 | goto ActuallyDoSomething; |
2239 | if (mask & CWStackMode(1<<6)) { |
2240 | #ifndef ROOTLESS1 |
2241 | /* See above for why we always reorder in rootless mode. */ |
2242 | if (pWin->nextSib != pSib) |
2243 | #endif |
2244 | goto ActuallyDoSomething; |
2245 | } |
2246 | return Success0; |
2247 | |
2248 | ActuallyDoSomething: |
2249 | if (pWin->drawable.pScreen->ConfigNotify) { |
2250 | int ret; |
2251 | |
2252 | ret = |
2253 | (*pWin->drawable.pScreen->ConfigNotify) (pWin, x, y, w, h, bw, |
2254 | pSib); |
2255 | if (ret) { |
2256 | client->errorValue = 0; |
2257 | return ret; |
2258 | } |
2259 | } |
2260 | |
2261 | if (SubStrSend(pWin, pParent)(((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || ((pParent ->eventMask|((pParent)->optional ? (pParent)->optional ->otherEventMasks : 0)) & (1L<<19)))) { |
2262 | xEvent event = { |
2263 | .u.configureNotify.window = pWin->drawable.id, |
2264 | .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None0L, |
2265 | .u.configureNotify.x = x, |
2266 | .u.configureNotify.y = y, |
2267 | .u.configureNotify.width = w, |
2268 | .u.configureNotify.height = h, |
2269 | .u.configureNotify.borderWidth = bw, |
2270 | .u.configureNotify.override = pWin->overrideRedirect |
2271 | }; |
2272 | event.u.u.type = ConfigureNotify22; |
2273 | #ifdef PANORAMIX1 |
2274 | if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { |
2275 | event.u.configureNotify.x += screenInfo.screens[0]->x; |
2276 | event.u.configureNotify.y += screenInfo.screens[0]->y; |
2277 | } |
2278 | #endif |
2279 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
2280 | } |
2281 | if (mask & CWBorderWidth(1<<4)) { |
2282 | if (action == RESTACK_WIN) { |
2283 | action = MOVE_WIN; |
2284 | pWin->borderWidth = bw; |
2285 | } |
2286 | else if ((action == MOVE_WIN) && |
2287 | (beforeX + wBorderWidth(pWin)((int) (pWin)->borderWidth) == x + (int) bw) && |
2288 | (beforeY + wBorderWidth(pWin)((int) (pWin)->borderWidth) == y + (int) bw)) { |
2289 | action = REBORDER_WIN; |
2290 | (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw); |
2291 | } |
2292 | else |
2293 | pWin->borderWidth = bw; |
2294 | } |
2295 | if (action == MOVE_WIN) |
2296 | (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib, |
2297 | (mask & CWBorderWidth(1<<4)) ? VTOther |
2298 | : VTMove); |
2299 | else if (action == RESIZE_WIN) |
2300 | (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); |
2301 | else if (mask & CWStackMode(1<<6)) |
2302 | ReflectStackChange(pWin, pSib, VTOther); |
2303 | |
2304 | if (action != RESTACK_WIN) |
2305 | CheckCursorConfinement(pWin); |
2306 | return Success0; |
2307 | #undef RESTACK_WIN |
2308 | #undef MOVE_WIN |
2309 | #undef RESIZE_WIN |
2310 | #undef REBORDER_WIN |
2311 | } |
2312 | |
2313 | /****** |
2314 | * |
2315 | * CirculateWindow |
2316 | * For RaiseLowest, raises the lowest mapped child (if any) that is |
2317 | * obscured by another child to the top of the stack. For LowerHighest, |
2318 | * lowers the highest mapped child (if any) that is obscuring another |
2319 | * child to the bottom of the stack. Exposure processing is performed |
2320 | * |
2321 | ******/ |
2322 | |
2323 | int |
2324 | CirculateWindow(WindowPtr pParent, int direction, ClientPtr client) |
2325 | { |
2326 | WindowPtr pWin, pHead, pFirst; |
2327 | xEvent event; |
2328 | BoxRec box; |
2329 | |
2330 | pHead = RealChildHead(pParent); |
2331 | pFirst = pHead ? pHead->nextSib : pParent->firstChild; |
2332 | if (direction == RaiseLowest0) { |
2333 | for (pWin = pParent->lastChild; |
2334 | (pWin != pHead) && |
2335 | !(pWin->mapped && |
2336 | AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); |
2337 | pWin = pWin->prevSib); |
2338 | if (pWin == pHead) |
2339 | return Success0; |
2340 | } |
2341 | else { |
2342 | for (pWin = pFirst; |
2343 | pWin && |
2344 | !(pWin->mapped && |
2345 | IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); |
2346 | pWin = pWin->nextSib); |
2347 | if (!pWin) |
2348 | return Success0; |
2349 | } |
2350 | |
2351 | event = (xEvent) { |
2352 | .u.circulate.window = pWin->drawable.id, |
2353 | .u.circulate.parent = pParent->drawable.id, |
2354 | .u.circulate.event = pParent->drawable.id, |
2355 | .u.circulate.place = (direction == RaiseLowest0) ? |
2356 | PlaceOnTop0 : PlaceOnBottom1, |
2357 | }; |
2358 | |
2359 | if (RedirectSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<20))) { |
2360 | event.u.u.type = CirculateRequest27; |
2361 | if (MaybeDeliverEventsToClient(pParent, &event, 1, |
2362 | SubstructureRedirectMask(1L<<20), client) == 1) |
2363 | return Success0; |
2364 | } |
2365 | |
2366 | event.u.u.type = CirculateNotify26; |
2367 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
2368 | ReflectStackChange(pWin, |
2369 | (direction == RaiseLowest0) ? pFirst : NullWindow((WindowPtr) 0), |
2370 | VTStack); |
2371 | |
2372 | return Success0; |
2373 | } |
2374 | |
2375 | static int |
2376 | CompareWIDs(WindowPtr pWin, void *value) |
2377 | { /* must conform to VisitWindowProcPtr */ |
2378 | Window *wid = (Window *) value; |
2379 | |
2380 | if (pWin->drawable.id == *wid) |
2381 | return WT_STOPWALKING0; |
2382 | else |
2383 | return WT_WALKCHILDREN1; |
2384 | } |
2385 | |
2386 | /***** |
2387 | * ReparentWindow |
2388 | *****/ |
2389 | |
2390 | int |
2391 | ReparentWindow(WindowPtr pWin, WindowPtr pParent, |
2392 | int x, int y, ClientPtr client) |
2393 | { |
2394 | WindowPtr pPrev, pPriorParent; |
2395 | Bool WasMapped = (Bool) (pWin->mapped); |
2396 | xEvent event; |
2397 | int bw = wBorderWidth(pWin)((int) (pWin)->borderWidth); |
2398 | ScreenPtr pScreen; |
2399 | |
2400 | pScreen = pWin->drawable.pScreen; |
2401 | if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) == |
2402 | WT_STOPWALKING0) |
2403 | return BadMatch8; |
2404 | if (!MakeWindowOptional(pWin)) |
2405 | return BadAlloc11; |
2406 | |
2407 | if (WasMapped) |
2408 | UnmapWindow(pWin, FALSE0); |
2409 | |
2410 | event = (xEvent) { |
2411 | .u.reparent.window = pWin->drawable.id, |
2412 | .u.reparent.parent = pParent->drawable.id, |
2413 | .u.reparent.x = x, |
2414 | .u.reparent.y = y, |
2415 | .u.reparent.override = pWin->overrideRedirect |
2416 | }; |
2417 | event.u.u.type = ReparentNotify21; |
2418 | #ifdef PANORAMIX1 |
2419 | if (!noPanoramiXExtension && !pParent->parent) { |
2420 | event.u.reparent.x += screenInfo.screens[0]->x; |
2421 | event.u.reparent.y += screenInfo.screens[0]->y; |
2422 | } |
2423 | #endif |
2424 | DeliverEvents(pWin, &event, 1, pParent); |
2425 | |
2426 | /* take out of sibling chain */ |
2427 | |
2428 | pPriorParent = pPrev = pWin->parent; |
2429 | if (pPrev->firstChild == pWin) |
2430 | pPrev->firstChild = pWin->nextSib; |
2431 | if (pPrev->lastChild == pWin) |
2432 | pPrev->lastChild = pWin->prevSib; |
2433 | |
2434 | if (pWin->nextSib) |
2435 | pWin->nextSib->prevSib = pWin->prevSib; |
2436 | if (pWin->prevSib) |
2437 | pWin->prevSib->nextSib = pWin->nextSib; |
2438 | |
2439 | /* insert at begining of pParent */ |
2440 | pWin->parent = pParent; |
2441 | pPrev = RealChildHead(pParent); |
2442 | if (pPrev) { |
2443 | pWin->nextSib = pPrev->nextSib; |
2444 | if (pPrev->nextSib) |
2445 | pPrev->nextSib->prevSib = pWin; |
2446 | else |
2447 | pParent->lastChild = pWin; |
2448 | pPrev->nextSib = pWin; |
2449 | pWin->prevSib = pPrev; |
2450 | } |
2451 | else { |
2452 | pWin->nextSib = pParent->firstChild; |
2453 | pWin->prevSib = NullWindow((WindowPtr) 0); |
2454 | if (pParent->firstChild) |
2455 | pParent->firstChild->prevSib = pWin; |
2456 | else |
2457 | pParent->lastChild = pWin; |
2458 | pParent->firstChild = pWin; |
2459 | } |
2460 | |
2461 | pWin->origin.x = x + bw; |
2462 | pWin->origin.y = y + bw; |
2463 | pWin->drawable.x = x + bw + pParent->drawable.x; |
2464 | pWin->drawable.y = y + bw + pParent->drawable.y; |
2465 | |
2466 | /* clip to parent */ |
2467 | SetWinSize(pWin); |
2468 | SetBorderSize(pWin); |
2469 | |
2470 | if (pScreen->ReparentWindow) |
2471 | (*pScreen->ReparentWindow) (pWin, pPriorParent); |
2472 | (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); |
2473 | ResizeChildrenWinSize(pWin, 0, 0, 0, 0); |
2474 | |
2475 | CheckWindowOptionalNeed(pWin); |
2476 | |
2477 | if (WasMapped) |
2478 | MapWindow(pWin, client); |
2479 | RecalculateDeliverableEvents(pWin); |
2480 | return Success0; |
2481 | } |
2482 | |
2483 | static void |
2484 | RealizeTree(WindowPtr pWin) |
2485 | { |
2486 | WindowPtr pChild; |
2487 | RealizeWindowProcPtr Realize; |
2488 | |
2489 | Realize = pWin->drawable.pScreen->RealizeWindow; |
2490 | pChild = pWin; |
2491 | while (1) { |
2492 | if (pChild->mapped) { |
2493 | pChild->realized = TRUE1; |
2494 | pChild->viewable = (pChild->drawable.class == InputOutput1); |
2495 | (*Realize) (pChild); |
2496 | if (pChild->firstChild) { |
2497 | pChild = pChild->firstChild; |
2498 | continue; |
2499 | } |
2500 | } |
2501 | while (!pChild->nextSib && (pChild != pWin)) |
2502 | pChild = pChild->parent; |
2503 | if (pChild == pWin) |
2504 | return; |
2505 | pChild = pChild->nextSib; |
2506 | } |
2507 | } |
2508 | |
2509 | static Bool |
2510 | MaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client) |
2511 | { |
2512 | xEvent event = { |
2513 | .u.mapRequest.window = pWin->drawable.id, |
2514 | .u.mapRequest.parent = pParent->drawable.id |
2515 | }; |
2516 | event.u.u.type = MapRequest20; |
2517 | |
2518 | return MaybeDeliverEventsToClient(pParent, &event, 1, |
2519 | SubstructureRedirectMask(1L<<20), |
2520 | client) == 1; |
2521 | } |
2522 | |
2523 | static void |
2524 | DeliverMapNotify(WindowPtr pWin) |
2525 | { |
2526 | xEvent event = { |
2527 | .u.mapNotify.window = pWin->drawable.id, |
2528 | .u.mapNotify.override = pWin->overrideRedirect, |
2529 | }; |
2530 | event.u.u.type = MapNotify19; |
2531 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
2532 | } |
2533 | |
2534 | /***** |
2535 | * MapWindow |
2536 | * If some other client has selected SubStructureReDirect on the parent |
2537 | * and override-redirect is xFalse, then a MapRequest event is generated, |
2538 | * but the window remains unmapped. Otherwise, the window is mapped and a |
2539 | * MapNotify event is generated. |
2540 | *****/ |
2541 | |
2542 | int |
2543 | MapWindow(WindowPtr pWin, ClientPtr client) |
2544 | { |
2545 | ScreenPtr pScreen; |
2546 | |
2547 | WindowPtr pParent; |
2548 | WindowPtr pLayerWin; |
2549 | |
2550 | if (pWin->mapped) |
2551 | return Success0; |
2552 | |
2553 | /* general check for permission to map window */ |
2554 | if (XaceHook(XACE_RESOURCE_ACCESS2, client, pWin->drawable.id, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), |
2555 | pWin, RT_NONE((RESTYPE)0), NULL((void*)0), DixShowAccess(1<<15)) != Success0) |
2556 | return Success0; |
2557 | |
2558 | pScreen = pWin->drawable.pScreen; |
2559 | if ((pParent = pWin->parent)) { |
2560 | Bool anyMarked; |
2561 | |
2562 | if ((!pWin->overrideRedirect) && (RedirectSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<20)))) |
2563 | if (MaybeDeliverMapRequest(pWin, pParent, client)) |
2564 | return Success0; |
2565 | |
2566 | pWin->mapped = TRUE1; |
2567 | if (SubStrSend(pWin, pParent)(((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || ((pParent ->eventMask|((pParent)->optional ? (pParent)->optional ->otherEventMasks : 0)) & (1L<<19)))) |
2568 | DeliverMapNotify(pWin); |
2569 | |
2570 | if (!pParent->realized) |
2571 | return Success0; |
2572 | RealizeTree(pWin); |
2573 | if (pWin->viewable) { |
2574 | anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, |
2575 | &pLayerWin); |
2576 | if (anyMarked) { |
2577 | (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap); |
2578 | (*pScreen->HandleExposures) (pLayerWin->parent); |
2579 | if (pScreen->PostValidateTree) |
2580 | (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, |
2581 | VTMap); |
2582 | } |
2583 | } |
2584 | WindowsRestructured(); |
2585 | } |
2586 | else { |
2587 | RegionRec temp; |
2588 | |
2589 | pWin->mapped = TRUE1; |
2590 | pWin->realized = TRUE1; /* for roots */ |
2591 | pWin->viewable = pWin->drawable.class == InputOutput1; |
2592 | /* We SHOULD check for an error value here XXX */ |
2593 | (*pScreen->RealizeWindow) (pWin); |
2594 | if (pScreen->ClipNotify) |
2595 | (*pScreen->ClipNotify) (pWin, 0, 0); |
2596 | if (pScreen->PostValidateTree) |
2597 | (*pScreen->PostValidateTree) (NullWindow((WindowPtr) 0), pWin, VTMap); |
2598 | RegionNull(&temp); |
2599 | RegionCopy(&temp, &pWin->clipList); |
2600 | (*pScreen->WindowExposures) (pWin, &temp); |
2601 | RegionUninit(&temp); |
2602 | } |
2603 | |
2604 | return Success0; |
2605 | } |
2606 | |
2607 | /***** |
2608 | * MapSubwindows |
2609 | * Performs a MapWindow all unmapped children of the window, in top |
2610 | * to bottom stacking order. |
2611 | *****/ |
2612 | |
2613 | void |
2614 | MapSubwindows(WindowPtr pParent, ClientPtr client) |
2615 | { |
2616 | WindowPtr pWin; |
2617 | WindowPtr pFirstMapped = NullWindow((WindowPtr) 0); |
2618 | ScreenPtr pScreen; |
2619 | Mask parentRedirect; |
2620 | Mask parentNotify; |
2621 | Bool anyMarked; |
2622 | WindowPtr pLayerWin; |
2623 | |
2624 | pScreen = pParent->drawable.pScreen; |
2625 | parentRedirect = RedirectSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<20)); |
2626 | parentNotify = SubSend(pParent)((pParent->eventMask|((pParent)->optional ? (pParent)-> optional->otherEventMasks : 0)) & (1L<<19)); |
2627 | anyMarked = FALSE0; |
2628 | for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) { |
2629 | if (!pWin->mapped) { |
2630 | if (parentRedirect && !pWin->overrideRedirect) |
2631 | if (MaybeDeliverMapRequest(pWin, pParent, client)) |
2632 | continue; |
2633 | |
2634 | pWin->mapped = TRUE1; |
2635 | if (parentNotify || StrSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17))) |
2636 | DeliverMapNotify(pWin); |
2637 | |
2638 | if (!pFirstMapped) |
2639 | pFirstMapped = pWin; |
2640 | if (pParent->realized) { |
2641 | RealizeTree(pWin); |
2642 | if (pWin->viewable) { |
2643 | anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, |
2644 | NULL((void*)0)); |
2645 | } |
2646 | } |
2647 | } |
2648 | } |
2649 | |
2650 | if (pFirstMapped) { |
2651 | pLayerWin = (*pScreen->GetLayerWindow) (pParent); |
2652 | if (pLayerWin->parent != pParent) { |
2653 | anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin, |
2654 | pLayerWin, NULL((void*)0)); |
2655 | pFirstMapped = pLayerWin; |
2656 | } |
2657 | if (anyMarked) { |
2658 | (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap); |
2659 | (*pScreen->HandleExposures) (pLayerWin->parent); |
2660 | if (pScreen->PostValidateTree) |
2661 | (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped, |
2662 | VTMap); |
2663 | } |
2664 | WindowsRestructured(); |
2665 | } |
2666 | } |
2667 | |
2668 | static void |
2669 | UnrealizeTree(WindowPtr pWin, Bool fromConfigure) |
2670 | { |
2671 | WindowPtr pChild; |
2672 | UnrealizeWindowProcPtr Unrealize; |
2673 | MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; |
2674 | |
2675 | Unrealize = pWin->drawable.pScreen->UnrealizeWindow; |
2676 | MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; |
2677 | pChild = pWin; |
2678 | while (1) { |
2679 | if (pChild->realized) { |
2680 | pChild->realized = FALSE0; |
2681 | pChild->visibility = VisibilityNotViewable3; |
2682 | #ifdef PANORAMIX1 |
2683 | if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { |
2684 | PanoramiXRes *win; |
2685 | int rc = dixLookupResourceByType((void **) &win, |
2686 | pChild->drawable.id, |
2687 | XRT_WINDOW, |
2688 | serverClient, DixWriteAccess(1<<1)); |
2689 | |
2690 | if (rc == Success0) |
2691 | win->u.win.visibility = VisibilityNotViewable3; |
2692 | } |
2693 | #endif |
2694 | (*Unrealize) (pChild); |
2695 | DeleteWindowFromAnyEvents(pChild, FALSE0); |
2696 | if (pChild->viewable) { |
2697 | pChild->viewable = FALSE0; |
2698 | (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); |
2699 | pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber = 1): globalSerialNumber); |
2700 | } |
2701 | if (pChild->firstChild) { |
2702 | pChild = pChild->firstChild; |
2703 | continue; |
2704 | } |
2705 | } |
2706 | while (!pChild->nextSib && (pChild != pWin)) |
2707 | pChild = pChild->parent; |
2708 | if (pChild == pWin) |
2709 | return; |
2710 | pChild = pChild->nextSib; |
2711 | } |
2712 | } |
2713 | |
2714 | static void |
2715 | DeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure) |
2716 | { |
2717 | xEvent event = { |
2718 | .u.unmapNotify.window = pWin->drawable.id, |
2719 | .u.unmapNotify.fromConfigure = fromConfigure |
2720 | }; |
2721 | event.u.u.type = UnmapNotify18; |
2722 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
2723 | } |
2724 | |
2725 | /***** |
2726 | * UnmapWindow |
2727 | * If the window is already unmapped, this request has no effect. |
2728 | * Otherwise, the window is unmapped and an UnMapNotify event is |
2729 | * generated. Cannot unmap a root window. |
2730 | *****/ |
2731 | |
2732 | int |
2733 | UnmapWindow(WindowPtr pWin, Bool fromConfigure) |
2734 | { |
2735 | WindowPtr pParent; |
2736 | Bool wasRealized = (Bool) pWin->realized; |
2737 | Bool wasViewable = (Bool) pWin->viewable; |
2738 | ScreenPtr pScreen = pWin->drawable.pScreen; |
2739 | WindowPtr pLayerWin = pWin; |
2740 | |
2741 | if ((!pWin->mapped) || (!(pParent = pWin->parent))) |
2742 | return Success0; |
2743 | if (SubStrSend(pWin, pParent)(((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<17)) || ((pParent ->eventMask|((pParent)->optional ? (pParent)->optional ->otherEventMasks : 0)) & (1L<<19)))) |
2744 | DeliverUnmapNotify(pWin, fromConfigure); |
2745 | if (wasViewable && !fromConfigure) { |
2746 | pWin->valdata = UnmapValData((ValidatePtr)1); |
2747 | (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); |
2748 | (*pScreen->MarkWindow) (pLayerWin->parent); |
2749 | } |
2750 | pWin->mapped = FALSE0; |
2751 | if (wasRealized) |
2752 | UnrealizeTree(pWin, fromConfigure); |
2753 | if (wasViewable) { |
2754 | if (!fromConfigure) { |
2755 | (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); |
2756 | (*pScreen->HandleExposures) (pLayerWin->parent); |
2757 | if (pScreen->PostValidateTree) |
2758 | (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); |
2759 | } |
2760 | } |
2761 | if (wasRealized && !fromConfigure) { |
2762 | WindowsRestructured(); |
2763 | WindowGone(pWin); |
2764 | } |
2765 | return Success0; |
2766 | } |
2767 | |
2768 | /***** |
2769 | * UnmapSubwindows |
2770 | * Performs an UnmapWindow request with the specified mode on all mapped |
2771 | * children of the window, in bottom to top stacking order. |
2772 | *****/ |
2773 | |
2774 | void |
2775 | UnmapSubwindows(WindowPtr pWin) |
2776 | { |
2777 | WindowPtr pChild, pHead; |
2778 | Bool wasRealized = (Bool) pWin->realized; |
2779 | Bool wasViewable = (Bool) pWin->viewable; |
2780 | Bool anyMarked = FALSE0; |
2781 | Mask parentNotify; |
2782 | WindowPtr pLayerWin = NULL((void*)0); |
2783 | ScreenPtr pScreen = pWin->drawable.pScreen; |
2784 | |
2785 | if (!pWin->firstChild) |
2786 | return; |
2787 | parentNotify = SubSend(pWin)((pWin->eventMask|((pWin)->optional ? (pWin)->optional ->otherEventMasks : 0)) & (1L<<19)); |
2788 | pHead = RealChildHead(pWin); |
2789 | |
2790 | if (wasViewable) |
2791 | pLayerWin = (*pScreen->GetLayerWindow) (pWin); |
2792 | |
2793 | for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { |
2794 | if (pChild->mapped) { |
2795 | if (parentNotify || StrSend(pChild)((pChild->eventMask|((pChild)->optional ? (pChild)-> optional->otherEventMasks : 0)) & (1L<<17))) |
2796 | DeliverUnmapNotify(pChild, xFalse0); |
2797 | if (pChild->viewable) { |
2798 | pChild->valdata = UnmapValData((ValidatePtr)1); |
2799 | anyMarked = TRUE1; |
2800 | } |
2801 | pChild->mapped = FALSE0; |
2802 | if (pChild->realized) |
2803 | UnrealizeTree(pChild, FALSE0); |
2804 | } |
2805 | } |
2806 | if (wasViewable) { |
2807 | if (anyMarked) { |
2808 | if (pLayerWin->parent == pWin) |
2809 | (*pScreen->MarkWindow) (pWin); |
2810 | else { |
2811 | WindowPtr ptmp; |
2812 | |
2813 | (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL((void*)0)); |
2814 | (*pScreen->MarkWindow) (pLayerWin->parent); |
2815 | |
2816 | /* Windows between pWin and pLayerWin may not have been marked */ |
2817 | ptmp = pWin; |
2818 | |
2819 | while (ptmp != pLayerWin->parent) { |
2820 | (*pScreen->MarkWindow) (ptmp); |
2821 | ptmp = ptmp->parent; |
2822 | } |
2823 | pHead = pWin->firstChild; |
2824 | } |
2825 | (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); |
2826 | (*pScreen->HandleExposures) (pLayerWin->parent); |
2827 | if (pScreen->PostValidateTree) |
2828 | (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, |
2829 | VTUnmap); |
2830 | } |
2831 | } |
2832 | if (wasRealized) { |
2833 | WindowsRestructured(); |
2834 | WindowGone(pWin); |
2835 | } |
2836 | } |
2837 | |
2838 | void |
2839 | HandleSaveSet(ClientPtr client) |
2840 | { |
2841 | WindowPtr pParent, pWin; |
2842 | int j; |
2843 | |
2844 | for (j = 0; j < client->numSaved; j++) { |
2845 | pWin = SaveSetWindow(client->saveSet[j])((client->saveSet[j]).windowPtr); |
2846 | if (SaveSetToRoot(client->saveSet[j])((client->saveSet[j]).toRoot)) |
2847 | pParent = pWin->drawable.pScreen->root; |
2848 | else |
2849 | { |
2850 | pParent = pWin->parent; |
2851 | while (pParent && (wClient(pParent)(clients[((int)((((pParent)->drawable.id) & (((1 << 8) - 1) << (29 - 8))) >> (29 - 8)))]) == client)) |
2852 | pParent = pParent->parent; |
2853 | } |
2854 | if (pParent) { |
2855 | if (pParent != pWin->parent) { |
2856 | /* unmap first so that ReparentWindow doesn't remap */ |
2857 | if (!SaveSetShouldMap(client->saveSet[j])((client->saveSet[j]).map)) |
2858 | UnmapWindow(pWin, FALSE0); |
2859 | ReparentWindow(pWin, pParent, |
2860 | pWin->drawable.x - wBorderWidth(pWin)((int) (pWin)->borderWidth) - |
2861 | pParent->drawable.x, |
2862 | pWin->drawable.y - wBorderWidth(pWin)((int) (pWin)->borderWidth) - |
2863 | pParent->drawable.y, client); |
2864 | if (!pWin->realized && pWin->mapped) |
2865 | pWin->mapped = FALSE0; |
2866 | } |
2867 | if (SaveSetShouldMap(client->saveSet[j])((client->saveSet[j]).map)) |
2868 | MapWindow(pWin, client); |
2869 | } |
2870 | } |
2871 | free(client->saveSet); |
2872 | client->numSaved = 0; |
2873 | client->saveSet = NULL((void*)0); |
2874 | } |
2875 | |
2876 | /** |
2877 | * |
2878 | * \param x,y in root |
2879 | */ |
2880 | Bool |
2881 | PointInWindowIsVisible(WindowPtr pWin, int x, int y) |
2882 | { |
2883 | BoxRec box; |
2884 | |
2885 | if (!pWin->realized) |
2886 | return FALSE0; |
2887 | if (RegionContainsPoint(&pWin->borderClip, x, y, &box) |
2888 | && (!wInputShape(pWin)((pWin)->optional ? (pWin)->optional->inputShape : ( (void*)0)) || |
2889 | RegionContainsPoint(wInputShape(pWin)((pWin)->optional ? (pWin)->optional->inputShape : ( (void*)0)), |
2890 | x - pWin->drawable.x, |
2891 | y - pWin->drawable.y, &box))) |
2892 | return TRUE1; |
2893 | return FALSE0; |
2894 | } |
2895 | |
2896 | RegionPtr |
2897 | NotClippedByChildren(WindowPtr pWin) |
2898 | { |
2899 | RegionPtr pReg = RegionCreate(NullBox((BoxPtr)0), 1); |
2900 | |
2901 | if (pWin->parent || |
2902 | screenIsSaved != SCREEN_SAVER_ON0 || |
2903 | !HasSaverWindow(pWin->drawable.pScreen)(pWin->drawable.pScreen->screensaver.pWindow != ((WindowPtr ) 0))) { |
2904 | RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); |
2905 | } |
2906 | return pReg; |
2907 | } |
2908 | |
2909 | void |
2910 | SendVisibilityNotify(WindowPtr pWin) |
2911 | { |
2912 | xEvent event; |
2913 | unsigned int visibility = pWin->visibility; |
2914 | |
2915 | #ifdef PANORAMIX1 |
2916 | /* This is not quite correct yet, but it's close */ |
2917 | if (!noPanoramiXExtension) { |
2918 | PanoramiXRes *win; |
2919 | WindowPtr pWin2; |
2920 | int rc, i, Scrnum; |
2921 | |
2922 | Scrnum = pWin->drawable.pScreen->myNum; |
2923 | |
2924 | win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); |
2925 | |
2926 | if (!win || (win->u.win.visibility == visibility)) |
2927 | return; |
2928 | |
2929 | switch (visibility) { |
2930 | case VisibilityUnobscured0: |
2931 | FOR_NSCREENS(i)for(i = 0; i < PanoramiXNumScreens; i++) { |
2932 | if (i == Scrnum) |
2933 | continue; |
2934 | |
2935 | rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, |
2936 | DixWriteAccess(1<<1)); |
2937 | |
2938 | if (rc == Success0) { |
2939 | if (pWin2->visibility == VisibilityPartiallyObscured1) |
2940 | return; |
2941 | |
2942 | if (!i) |
2943 | pWin = pWin2; |
2944 | } |
2945 | } |
2946 | break; |
2947 | case VisibilityPartiallyObscured1: |
2948 | if (Scrnum) { |
2949 | rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, |
2950 | DixWriteAccess(1<<1)); |
2951 | if (rc == Success0) |
2952 | pWin = pWin2; |
2953 | } |
2954 | break; |
2955 | case VisibilityFullyObscured2: |
2956 | FOR_NSCREENS(i)for(i = 0; i < PanoramiXNumScreens; i++) { |
2957 | if (i == Scrnum) |
2958 | continue; |
2959 | |
2960 | rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, |
2961 | DixWriteAccess(1<<1)); |
2962 | |
2963 | if (rc == Success0) { |
2964 | if (pWin2->visibility != VisibilityFullyObscured2) |
2965 | return; |
2966 | |
2967 | if (!i) |
2968 | pWin = pWin2; |
2969 | } |
2970 | } |
2971 | break; |
2972 | } |
2973 | |
2974 | win->u.win.visibility = visibility; |
2975 | } |
2976 | #endif |
2977 | |
2978 | event = (xEvent) { |
2979 | .u.visibility.window = pWin->drawable.id, |
2980 | .u.visibility.state = visibility |
2981 | }; |
2982 | event.u.u.type = VisibilityNotify15; |
2983 | DeliverEvents(pWin, &event, 1, NullWindow((WindowPtr) 0)); |
2984 | } |
2985 | |
2986 | #define RANDOM_WIDTH32 32 |
2987 | int |
2988 | dixSaveScreens(ClientPtr client, int on, int mode) |
2989 | { |
2990 | int rc, i, what, type; |
2991 | |
2992 | if (on == SCREEN_SAVER_FORCER2) { |
2993 | if (mode == ScreenSaverReset0) |
2994 | what = SCREEN_SAVER_OFF1; |
2995 | else |
2996 | what = SCREEN_SAVER_ON0; |
2997 | type = what; |
2998 | } |
2999 | else { |
3000 | what = on; |
3001 | type = what; |
3002 | if (what == screenIsSaved) |
3003 | type = SCREEN_SAVER_CYCLE3; |
3004 | } |
3005 | |
3006 | for (i = 0; i < screenInfo.numScreens; i++) { |
3007 | rc = XaceHook(XACE_SCREENSAVER_ACCESS12, client, screenInfo.screens[i], |
3008 | DixShowAccess(1<<15) | DixHideAccess(1<<14)); |
3009 | if (rc != Success0) |
3010 | return rc; |
3011 | } |
3012 | for (i = 0; i < screenInfo.numScreens; i++) { |
3013 | ScreenPtr pScreen = screenInfo.screens[i]; |
3014 | |
3015 | if (on == SCREEN_SAVER_FORCER2) |
3016 | (*pScreen->SaveScreen) (pScreen, on); |
3017 | if (pScreen->screensaver.ExternalScreenSaver) { |
3018 | if ((*pScreen->screensaver.ExternalScreenSaver) |
3019 | (pScreen, type, on == SCREEN_SAVER_FORCER2)) |
3020 | continue; |
3021 | } |
3022 | if (type == screenIsSaved) |
3023 | continue; |
3024 | switch (type) { |
3025 | case SCREEN_SAVER_OFF1: |
3026 | if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED0) { |
3027 | (*pScreen->SaveScreen) (pScreen, what); |
3028 | } |
3029 | else if (HasSaverWindow(pScreen)(pScreen->screensaver.pWindow != ((WindowPtr) 0))) { |
3030 | pScreen->screensaver.pWindow = NullWindow((WindowPtr) 0); |
3031 | FreeResource(pScreen->screensaver.wid, RT_NONE((RESTYPE)0)); |
3032 | } |
3033 | break; |
3034 | case SCREEN_SAVER_CYCLE3: |
3035 | if (pScreen->screensaver.blanked == SCREEN_IS_TILED2) { |
3036 | WindowPtr pWin = pScreen->screensaver.pWindow; |
3037 | |
3038 | /* make it look like screen saver is off, so that |
3039 | * NotClippedByChildren will compute a clip list |
3040 | * for the root window, so miPaintWindow works |
3041 | */ |
3042 | screenIsSaved = SCREEN_SAVER_OFF1; |
3043 | (*pWin->drawable.pScreen->MoveWindow) (pWin, |
3044 | (short) (- |
3045 | (rand() % |
3046 | RANDOM_WIDTH32)), |
3047 | (short) (- |
3048 | (rand() % |
3049 | RANDOM_WIDTH32)), |
3050 | pWin->nextSib, VTMove); |
3051 | screenIsSaved = SCREEN_SAVER_ON0; |
3052 | } |
3053 | /* |
3054 | * Call the DDX saver in case it wants to do something |
3055 | * at cycle time |
3056 | */ |
3057 | else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED0) { |
3058 | (*pScreen->SaveScreen) (pScreen, type); |
3059 | } |
3060 | break; |
3061 | case SCREEN_SAVER_ON0: |
3062 | if (ScreenSaverBlanking != DontPreferBlanking0) { |
3063 | if ((*pScreen->SaveScreen) (pScreen, what)) { |
3064 | pScreen->screensaver.blanked = SCREEN_IS_BLANKED0; |
3065 | continue; |
3066 | } |
3067 | if ((ScreenSaverAllowExposures != DontAllowExposures0) && |
3068 | TileScreenSaver(pScreen, SCREEN_IS_BLACK3)) { |
3069 | pScreen->screensaver.blanked = SCREEN_IS_BLACK3; |
3070 | continue; |
3071 | } |
3072 | } |
3073 | if ((ScreenSaverAllowExposures != DontAllowExposures0) && |
3074 | TileScreenSaver(pScreen, SCREEN_IS_TILED2)) { |
3075 | pScreen->screensaver.blanked = SCREEN_IS_TILED2; |
3076 | } |
3077 | else |
3078 | pScreen->screensaver.blanked = SCREEN_ISNT_SAVED1; |
3079 | break; |
3080 | } |
3081 | } |
3082 | screenIsSaved = what; |
3083 | if (mode == ScreenSaverReset0) { |
3084 | if (on == SCREEN_SAVER_FORCER2) { |
3085 | DeviceIntPtr dev; |
3086 | UpdateCurrentTimeIf(); |
3087 | nt_list_for_each_entry(dev, inputInfo.devices, next)for (dev = inputInfo.devices; dev; dev = (dev)->next) |
3088 | NoticeTime(dev, currentTime); |
3089 | } |
3090 | SetScreenSaverTimer(); |
3091 | } |
3092 | return Success0; |
3093 | } |
3094 | |
3095 | int |
3096 | SaveScreens(int on, int mode) |
3097 | { |
3098 | return dixSaveScreens(serverClient, on, mode); |
3099 | } |
3100 | |
3101 | static Bool |
3102 | TileScreenSaver(ScreenPtr pScreen, int kind) |
3103 | { |
3104 | int j; |
3105 | int result; |
3106 | XID attributes[3]; |
3107 | Mask mask; |
3108 | WindowPtr pWin; |
3109 | CursorMetricRec cm; |
3110 | unsigned char *srcbits, *mskbits; |
3111 | CursorPtr cursor; |
3112 | XID cursorID = 0; |
3113 | int attri; |
3114 | |
3115 | mask = 0; |
3116 | attri = 0; |
3117 | switch (kind) { |
3118 | case SCREEN_IS_TILED2: |
3119 | switch (pScreen->root->backgroundState) { |
3120 | case BackgroundPixel2L: |
3121 | attributes[attri++] = pScreen->root->background.pixel; |
3122 | mask |= CWBackPixel(1L<<1); |
3123 | break; |
3124 | case BackgroundPixmap3L: |
3125 | attributes[attri++] = None0L; |
3126 | mask |= CWBackPixmap(1L<<0); |
3127 | break; |
3128 | default: |
3129 | break; |
3130 | } |
3131 | break; |
3132 | case SCREEN_IS_BLACK3: |
3133 | attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; |
3134 | mask |= CWBackPixel(1L<<1); |
3135 | break; |
3136 | } |
3137 | mask |= CWOverrideRedirect(1L<<9); |
3138 | attributes[attri++] = xTrue1; |
3139 | |
3140 | /* |
3141 | * create a blank cursor |
3142 | */ |
3143 | |
3144 | cm.width = 16; |
3145 | cm.height = 16; |
3146 | cm.xhot = 8; |
3147 | cm.yhot = 8; |
3148 | srcbits = malloc(BitmapBytePad(32)(((int)((32) + 32 - 1) >> 5) << 2) * 16); |
3149 | mskbits = malloc(BitmapBytePad(32)(((int)((32) + 32 - 1) >> 5) << 2) * 16); |
3150 | if (!srcbits || !mskbits) { |
3151 | free(srcbits); |
3152 | free(mskbits); |
3153 | cursor = 0; |
3154 | } |
3155 | else { |
3156 | for (j = 0; j < BitmapBytePad(32)(((int)((32) + 32 - 1) >> 5) << 2) * 16; j++) |
3157 | srcbits[j] = mskbits[j] = 0x0; |
3158 | result = AllocARGBCursor(srcbits, mskbits, NULL((void*)0), &cm, 0, 0, 0, 0, 0, 0, |
3159 | &cursor, serverClient, (XID) 0); |
3160 | if (cursor) { |
3161 | cursorID = FakeClientID(0); |
3162 | if (AddResourceDarwin_X_AddResource(cursorID, RT_CURSOR((RESTYPE)5), (void *) cursor)) { |
3163 | attributes[attri] = cursorID; |
3164 | mask |= CWCursor(1L<<14); |
3165 | } |
3166 | else |
3167 | cursor = 0; |
3168 | } |
3169 | else { |
3170 | free(srcbits); |
3171 | free(mskbits); |
3172 | } |
3173 | } |
3174 | |
3175 | pWin = pScreen->screensaver.pWindow = |
3176 | CreateWindow(pScreen->screensaver.wid, |
3177 | pScreen->root, |
3178 | -RANDOM_WIDTH32, -RANDOM_WIDTH32, |
3179 | (unsigned short) pScreen->width + RANDOM_WIDTH32, |
3180 | (unsigned short) pScreen->height + RANDOM_WIDTH32, |
3181 | 0, InputOutput1, mask, attributes, 0, serverClient, |
3182 | wVisual(pScreen->root)((pScreen->root)->optional ? (pScreen->root)->optional ->visual : FindWindowWithOptional(pScreen->root)->optional ->visual), &result); |
3183 | |
3184 | if (cursor) |
3185 | FreeResource(cursorID, RT_NONE((RESTYPE)0)); |
3186 | |
3187 | if (!pWin) |
3188 | return FALSE0; |
3189 | |
3190 | if (!AddResourceDarwin_X_AddResource(pWin->drawable.id, RT_WINDOW((RESTYPE)1|((RESTYPE)1<<30)), |
3191 | (void *) pScreen->screensaver.pWindow)) |
3192 | return FALSE0; |
3193 | |
3194 | if (mask & CWBackPixmap(1L<<0)) { |
3195 | MakeRootTile(pWin); |
3196 | (*pWin->drawable.pScreen->ChangeWindowAttributesDarwin_X_ChangeWindowAttributes) (pWin, CWBackPixmap(1L<<0)); |
3197 | } |
3198 | MapWindow(pWin, serverClient); |
3199 | return TRUE1; |
3200 | } |
3201 | |
3202 | /* |
3203 | * FindWindowWithOptional |
3204 | * |
3205 | * search ancestors of the given window for an entry containing |
3206 | * a WindowOpt structure. Assumptions: some parent will |
3207 | * contain the structure. |
3208 | */ |
3209 | |
3210 | WindowPtr |
3211 | FindWindowWithOptional(WindowPtr w) |
3212 | { |
3213 | do |
3214 | w = w->parent; |
3215 | while (!w->optional); |
3216 | return w; |
3217 | } |
3218 | |
3219 | /* |
3220 | * CheckWindowOptionalNeed |
3221 | * |
3222 | * check each optional entry in the given window to see if |
3223 | * the value is satisfied by the default rules. If so, |
3224 | * release the optional record |
3225 | */ |
3226 | |
3227 | void |
3228 | CheckWindowOptionalNeed(WindowPtr w) |
3229 | { |
3230 | WindowOptPtr optional; |
3231 | WindowOptPtr parentOptional; |
3232 | |
3233 | if (!w->parent || !w->optional) |
3234 | return; |
3235 | optional = w->optional; |
3236 | if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) |
3237 | return; |
3238 | if (optional->otherEventMasks != 0) |
3239 | return; |
3240 | if (optional->otherClients != NULL((void*)0)) |
3241 | return; |
3242 | if (optional->passiveGrabs != NULL((void*)0)) |
3243 | return; |
3244 | if (optional->userProps != NULL((void*)0)) |
3245 | return; |
3246 | if (optional->backingBitPlanes != (CARD32)~0L) |
3247 | return; |
3248 | if (optional->backingPixel != 0) |
3249 | return; |
3250 | if (optional->boundingShape != NULL((void*)0)) |
3251 | return; |
3252 | if (optional->clipShape != NULL((void*)0)) |
3253 | return; |
3254 | if (optional->inputShape != NULL((void*)0)) |
3255 | return; |
3256 | if (optional->inputMasks != NULL((void*)0)) |
3257 | return; |
3258 | if (optional->deviceCursors != NULL((void*)0)) { |
3259 | DevCursNodePtr pNode = optional->deviceCursors; |
3260 | |
3261 | while (pNode) { |
3262 | if (pNode->cursor != None0L) |
3263 | return; |
3264 | pNode = pNode->next; |
3265 | } |
3266 | } |
3267 | |
3268 | parentOptional = FindWindowWithOptional(w)->optional; |
3269 | if (optional->visual != parentOptional->visual) |
3270 | return; |
3271 | if (optional->cursor != None0L && |
3272 | (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone)) |
3273 | return; |
3274 | if (optional->colormap != parentOptional->colormap) |
3275 | return; |
3276 | DisposeWindowOptional(w); |
3277 | } |
3278 | |
3279 | /* |
3280 | * MakeWindowOptional |
3281 | * |
3282 | * create an optional record and initialize it with the default |
3283 | * values. |
3284 | */ |
3285 | |
3286 | Bool |
3287 | MakeWindowOptional(WindowPtr pWin) |
3288 | { |
3289 | WindowOptPtr optional; |
3290 | WindowOptPtr parentOptional; |
3291 | |
3292 | if (pWin->optional) |
3293 | return TRUE1; |
3294 | optional = malloc(sizeof(WindowOptRec)); |
3295 | if (!optional) |
3296 | return FALSE0; |
3297 | optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; |
3298 | optional->otherEventMasks = 0; |
3299 | optional->otherClients = NULL((void*)0); |
3300 | optional->passiveGrabs = NULL((void*)0); |
3301 | optional->userProps = NULL((void*)0); |
3302 | optional->backingBitPlanes = ~0L; |
3303 | optional->backingPixel = 0; |
3304 | optional->boundingShape = NULL((void*)0); |
3305 | optional->clipShape = NULL((void*)0); |
3306 | optional->inputShape = NULL((void*)0); |
3307 | optional->inputMasks = NULL((void*)0); |
3308 | optional->deviceCursors = NULL((void*)0); |
3309 | |
3310 | parentOptional = FindWindowWithOptional(pWin)->optional; |
3311 | optional->visual = parentOptional->visual; |
3312 | if (!pWin->cursorIsNone) { |
3313 | optional->cursor = RefCursor(parentOptional->cursor); |
3314 | } |
3315 | else { |
3316 | optional->cursor = None0L; |
3317 | } |
3318 | optional->colormap = parentOptional->colormap; |
3319 | pWin->optional = optional; |
3320 | return TRUE1; |
3321 | } |
3322 | |
3323 | /* |
3324 | * Changes the cursor struct for the given device and the given window. |
3325 | * A cursor that does not have a device cursor set will use whatever the |
3326 | * standard cursor is for the window. If all devices have a cursor set, |
3327 | * changing the window cursor (e.g. using XDefineCursor()) will not have any |
3328 | * visible effect. Only when one of the device cursors is set to None again, |
3329 | * this device's cursor will display the changed standard cursor. |
3330 | * |
3331 | * CursorIsNone of the window struct is NOT modified if you set a device |
3332 | * cursor. |
3333 | * |
3334 | * Assumption: If there is a node for a device in the list, the device has a |
3335 | * cursor. If the cursor is set to None, it is inherited by the parent. |
3336 | */ |
3337 | int |
3338 | ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) |
3339 | { |
3340 | DevCursNodePtr pNode, pPrev; |
3341 | CursorPtr pOldCursor = NULL((void*)0); |
3342 | ScreenPtr pScreen; |
3343 | WindowPtr pChild; |
3344 | |
3345 | if (!pWin->optional && !MakeWindowOptional(pWin)) |
3346 | return BadAlloc11; |
3347 | |
3348 | /* 1) Check if window has device cursor set |
3349 | * Yes: 1.1) swap cursor with given cursor if parent does not have same |
3350 | * cursor, free old cursor |
3351 | * 1.2) free old cursor, use parent cursor |
3352 | * No: 1.1) add node to beginning of list. |
3353 | * 1.2) add cursor to node if parent does not have same cursor |
3354 | * 1.3) use parent cursor if parent does not have same cursor |
3355 | * 2) Patch up children if child has a devcursor |
3356 | * 2.1) if child has cursor None, it inherited from parent, set to old |
3357 | * cursor |
3358 | * 2.2) if child has same cursor as new cursor, remove and set to None |
3359 | */ |
3360 | |
3361 | pScreen = pWin->drawable.pScreen; |
3362 | |
3363 | if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) { |
3364 | /* has device cursor */ |
3365 | |
3366 | if (pNode->cursor == pCursor) |
3367 | return Success0; |
3368 | |
3369 | pOldCursor = pNode->cursor; |
3370 | |
3371 | if (!pCursor) { /* remove from list */ |
3372 | if (pPrev) |
3373 | pPrev->next = pNode->next; |
3374 | else |
3375 | /* first item in list */ |
3376 | pWin->optional->deviceCursors = pNode->next; |
3377 | |
3378 | free(pNode); |
3379 | goto out; |
3380 | } |
3381 | |
3382 | } |
3383 | else { |
3384 | /* no device cursor yet */ |
3385 | DevCursNodePtr pNewNode; |
3386 | |
3387 | if (!pCursor) |
3388 | return Success0; |
3389 | |
3390 | pNewNode = malloc(sizeof(DevCursNodeRec)); |
3391 | pNewNode->dev = pDev; |
3392 | pNewNode->next = pWin->optional->deviceCursors; |
3393 | pWin->optional->deviceCursors = pNewNode; |
3394 | pNode = pNewNode; |
3395 | |
3396 | } |
3397 | |
3398 | if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) |
3399 | pNode->cursor = None0L; |
3400 | else { |
3401 | pNode->cursor = RefCursor(pCursor); |
3402 | } |
3403 | |
3404 | pNode = pPrev = NULL((void*)0); |
3405 | /* fix up children */ |
3406 | for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { |
3407 | if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) { |
3408 | if (pNode->cursor == None0L) { /* inherited from parent */ |
3409 | pNode->cursor = RefCursor(pOldCursor); |
3410 | } |
3411 | else if (pNode->cursor == pCursor) { |
3412 | pNode->cursor = None0L; |
3413 | FreeCursor(pCursor, (Cursor) 0); /* fix up refcnt */ |
3414 | } |
3415 | } |
3416 | } |
3417 | |
3418 | out: |
3419 | CursorVisible = TRUE1; |
3420 | |
3421 | if (pWin->realized) |
3422 | WindowHasNewCursor(pWin); |
3423 | |
3424 | if (pOldCursor) |
3425 | FreeCursor(pOldCursor, (Cursor) 0); |
3426 | |
3427 | /* FIXME: We SHOULD check for an error value here XXX |
3428 | (comment taken from ChangeWindowAttributes) */ |
3429 | (*pScreen->ChangeWindowAttributesDarwin_X_ChangeWindowAttributes) (pWin, CWCursor(1L<<14)); |
3430 | |
3431 | return Success0; |
3432 | } |
3433 | |
3434 | /* Get device cursor for given device or None if none is set */ |
3435 | CursorPtr |
3436 | WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) |
3437 | { |
3438 | DevCursorList pList; |
3439 | |
3440 | if (!pWin->optional || !pWin->optional->deviceCursors) |
3441 | return NULL((void*)0); |
3442 | |
3443 | pList = pWin->optional->deviceCursors; |
3444 | |
3445 | while (pList) { |
3446 | if (pList->dev == pDev) { |
3447 | if (pList->cursor == None0L) /* inherited from parent */ |
3448 | return WindowGetDeviceCursor(pWin->parent, pDev); |
3449 | else |
3450 | return pList->cursor; |
3451 | } |
3452 | pList = pList->next; |
3453 | } |
3454 | return NULL((void*)0); |
3455 | } |
3456 | |
3457 | /* Searches for a DevCursorNode for the given window and device. If one is |
3458 | * found, return True and set pNode and pPrev to the node and to the node |
3459 | * before the node respectively. Otherwise return False. |
3460 | * If the device is the first in list, pPrev is set to NULL. |
3461 | */ |
3462 | static Bool |
3463 | WindowSeekDeviceCursor(WindowPtr pWin, |
3464 | DeviceIntPtr pDev, |
3465 | DevCursNodePtr * pNode, DevCursNodePtr * pPrev) |
3466 | { |
3467 | DevCursorList pList; |
3468 | |
3469 | if (!pWin->optional) |
3470 | return FALSE0; |
3471 | |
3472 | pList = pWin->optional->deviceCursors; |
3473 | |
3474 | if (pList && pList->dev == pDev) { |
3475 | *pNode = pList; |
3476 | *pPrev = NULL((void*)0); |
3477 | return TRUE1; |
3478 | } |
3479 | |
3480 | while (pList) { |
3481 | if (pList->next) { |
3482 | if (pList->next->dev == pDev) { |
3483 | *pNode = pList->next; |
3484 | *pPrev = pList; |
3485 | return TRUE1; |
3486 | } |
3487 | } |
3488 | pList = pList->next; |
3489 | } |
3490 | return FALSE0; |
3491 | } |
3492 | |
3493 | /* Return True if a parent has the same device cursor set or False if |
3494 | * otherwise |
3495 | */ |
3496 | static Bool |
3497 | WindowParentHasDeviceCursor(WindowPtr pWin, |
3498 | DeviceIntPtr pDev, CursorPtr pCursor) |
3499 | { |
3500 | WindowPtr pParent; |
3501 | DevCursNodePtr pParentNode, pParentPrev; |
3502 | |
3503 | pParent = pWin->parent; |
3504 | while (pParent) { |
3505 | if (WindowSeekDeviceCursor(pParent, pDev, &pParentNode, &pParentPrev)) { |
3506 | /* if there is a node in the list, the win has a dev cursor */ |
3507 | if (!pParentNode->cursor) /* inherited. */ |
3508 | pParent = pParent->parent; |
3509 | else if (pParentNode->cursor == pCursor) /* inherit */ |
3510 | return TRUE1; |
3511 | else /* different cursor */ |
3512 | return FALSE0; |
3513 | } |
3514 | else |
3515 | /* parent does not have a device cursor for our device */ |
3516 | return FALSE0; |
3517 | } |
3518 | return FALSE0; |
3519 | } |
3520 | |
3521 | /* |
3522 | * SetRootClip -- |
3523 | * Enable or disable rendering to the screen by |
3524 | * setting the root clip list and revalidating |
3525 | * all of the windows |
3526 | */ |
3527 | void |
3528 | SetRootClip(ScreenPtr pScreen, Bool enable) |
3529 | { |
3530 | WindowPtr pWin = pScreen->root; |
3531 | WindowPtr pChild; |
3532 | Bool WasViewable; |
3533 | Bool anyMarked = FALSE0; |
3534 | WindowPtr pLayerWin; |
3535 | BoxRec box; |
3536 | |
3537 | if (!pWin) |
3538 | return; |
3539 | WasViewable = (Bool) (pWin->viewable); |
3540 | if (WasViewable) { |
3541 | for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { |
3542 | (void) (*pScreen->MarkOverlappedWindows) (pChild, |
3543 | pChild, &pLayerWin); |
3544 | } |
3545 | (*pScreen->MarkWindow) (pWin); |
3546 | anyMarked = TRUE1; |
3547 | if (pWin->valdata) { |
3548 | if (HasBorder(pWin)((pWin)->borderWidth || ((pWin)->optional ? (pWin)-> optional->clipShape : ((void*)0)))) { |
3549 | RegionPtr borderVisible; |
3550 | |
3551 | borderVisible = RegionCreate(NullBox((BoxPtr)0), 1); |
3552 | RegionSubtract(borderVisible, |
3553 | &pWin->borderClip, &pWin->winSize); |
3554 | pWin->valdata->before.borderVisible = borderVisible; |
3555 | } |
3556 | pWin->valdata->before.resized = TRUE1; |
3557 | } |
3558 | } |
3559 | |
3560 | /* |
3561 | * Use REGION_BREAK to avoid optimizations in ValidateTree |
3562 | * that assume the root borderClip can't change well, normally |
3563 | * it doesn't...) |
3564 | */ |
3565 | if (enable) { |
3566 | box.x1 = 0; |
3567 | box.y1 = 0; |
3568 | box.x2 = pScreen->width; |
3569 | box.y2 = pScreen->height; |
3570 | RegionInit(&pWin->winSize, &box, 1); |
3571 | RegionInit(&pWin->borderSize, &box, 1); |
3572 | if (WasViewable) |
3573 | RegionReset(&pWin->borderClip, &box); |
3574 | pWin->drawable.width = pScreen->width; |
3575 | pWin->drawable.height = pScreen->height; |
3576 | RegionBreak(&pWin->clipList); |
3577 | } |
3578 | else { |
3579 | RegionEmpty(&pWin->borderClip); |
3580 | RegionBreak(&pWin->clipList); |
3581 | } |
3582 | |
3583 | ResizeChildrenWinSize(pWin, 0, 0, 0, 0); |
3584 | |
3585 | if (WasViewable) { |
3586 | if (pWin->firstChild) { |
3587 | anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin->firstChild, |
3588 | pWin->firstChild, |
3589 | NULL((void*)0)); |
3590 | } |
3591 | else { |
3592 | (*pScreen->MarkWindow) (pWin); |
3593 | anyMarked = TRUE1; |
3594 | } |
3595 | |
3596 | if (anyMarked) { |
3597 | (*pScreen->ValidateTree) (pWin, NullWindow((WindowPtr) 0), VTOther); |
3598 | (*pScreen->HandleExposures) (pWin); |
3599 | if (pScreen->PostValidateTree) |
3600 | (*pScreen->PostValidateTree) (pWin, NullWindow((WindowPtr) 0), VTOther); |
3601 | } |
3602 | } |
3603 | if (pWin->realized) |
3604 | WindowsRestructured(); |
3605 | FlushAllOutput(); |
3606 | } |
3607 | |
3608 | VisualPtr |
3609 | WindowGetVisual(WindowPtr pWin) |
3610 | { |
3611 | ScreenPtr pScreen = pWin->drawable.pScreen; |
3612 | VisualID vid = wVisual(pWin)((pWin)->optional ? (pWin)->optional->visual : FindWindowWithOptional (pWin)->optional->visual); |
3613 | int i; |
3614 | |
3615 | for (i = 0; i < pScreen->numVisuals; i++) |
3616 | if (pScreen->visuals[i].vid == vid) |
3617 | return &pScreen->visuals[i]; |
3618 | return 0; |
3619 | } |