Bug Summary

File:dix/window.c
Location:line 223, column 15
Description:Value stored to 'pScreen' during its initialization is never read

Annotated Source Code

1/*
2
3Copyright (c) 2006, Red Hat, Inc.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8the rights to use, copy, modify, merge, publish, distribute, sublicense,
9and/or sell copies of the Software, and to permit persons to whom the
10Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22DEALINGS IN THE SOFTWARE.
23
24Copyright 1987, 1998 The Open Group
25
26Permission to use, copy, modify, distribute, and sell this software and its
27documentation for any purpose is hereby granted without fee, provided that
28the above copyright notice appear in all copies and that both that
29copyright notice and this permission notice appear in supporting
30documentation.
31
32The above copyright notice and this permission notice shall be included
33in all copies or substantial portions of the Software.
34
35THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
39OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41OTHER DEALINGS IN THE SOFTWARE.
42
43Except as contained in this notice, the name of The Open Group shall
44not be used in advertising or otherwise to promote the sale, use or
45other dealings in this Software without prior written authorization
46from The Open Group.
47
48Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
49
50 All Rights Reserved
51
52Permission to use, copy, modify, and distribute this software and its
53documentation for any purpose and without fee is hereby granted,
54provided that the above copyright notice appear in all copies and that
55both that copyright notice and this permission notice appear in
56supporting documentation, and that the name of Digital not be
57used in advertising or publicity pertaining to distribution of the
58software without specific, written prior permission.
59
60DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
61ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
62DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
63ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
64WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
65ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
66SOFTWARE.
67
68*/
69
70/* The panoramix components contained the following notice */
71/*****************************************************************
72
73Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
74
75Permission is hereby granted, free of charge, to any person obtaining a copy
76of this software and associated documentation files (the "Software"), to deal
77in the Software without restriction, including without limitation the rights
78to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79copies of the Software.
80
81The above copyright notice and this permission notice shall be included in
82all copies or substantial portions of the Software.
83
84THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
87DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
88BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
89WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
90IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
91
92Except as contained in this notice, the name of Digital Equipment Corporation
93shall not be used in advertising or otherwise to promote the sale, use or other
94dealings in this Software without prior written authorization from Digital
95Equipment 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
147Bool bgNoneRoot = FALSE0;
148
149static unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 };
150static unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 };
151
152static Bool WindowParentHasDeviceCursor(WindowPtr pWin,
153 DeviceIntPtr pDev, CursorPtr pCurs);
154static Bool
155
156WindowSeekDeviceCursor(WindowPtr pWin,
157 DeviceIntPtr pDev,
158 DevCursNodePtr * pNode, DevCursNodePtr * pPrev);
159
160int screenIsSaved = SCREEN_SAVER_OFF1;
161
162static 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
185static const char *overlay_win_name = "<composite overlay>";
186#endif
187
188static const char *
189get_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
217static void
218log_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
276void
277PrintWindowTree(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
307int
308TraverseTree(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
340int
341WalkTree(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 */
347int defaultBackingStore = NotUseful0;
348
349/* hack to force no backing store */
350Bool disableBackingStore = FALSE0;
351Bool enableBackingStore = FALSE0;
352
353static void
354SetWindowToDefaults(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
393static void
394MakeRootTile(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
442Bool
443CreateRootWindow(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
543void
544InitRootWindow(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
587static void
588ClippedRegionFromBox(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
611static RealChildHeadProc realChildHeadProc = NULL((void*)0);
612
613void
614RegisterRealChildHeadProc(RealChildHeadProc proc)
615{
616 realChildHeadProc = proc;
617}
618
619WindowPtr
620RealChildHead(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
639WindowPtr
640CreateWindow(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
849static void
850DisposeWindowOptional(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
884static void
885FreeWindowResources(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
913static void
914CrushTree(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
960int
961DeleteWindow(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
994int
995DestroySubwindows(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
1018static void
1019SetRootWindowBackground(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
1047int
1048ChangeWindowAttributesDarwin_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
1484void
1485GetWindowAttributes(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
1520WindowPtr
1521MoveWindowInStack(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
1601void
1602SetWinSize(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
1635void
1636SetBorderSize(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
1684void
1685GravityTranslate(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 */
1733void
1734ResizeChildrenWinSize(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
1820static int
1821IsSiblingAboveMe(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
1836static BoxPtr
1837WindowExtents(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
1850static RegionPtr
1851MakeBoundingRegion(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
1863static Bool
1864ShapeOverlap(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
1880static Bool
1881AnyWindowOverlapsMe(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
1898static Bool
1899IOverlapAnyWindow(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
1944static WindowPtr
1945WhereDoIGoInTheStack(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
2037static void
2038ReflectStackChange(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
2075int
2076ConfigureWindow(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
2323int
2324CirculateWindow(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
2375static int
2376CompareWIDs(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
2390int
2391ReparentWindow(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
2483static void
2484RealizeTree(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
2509static Bool
2510MaybeDeliverMapRequest(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
2523static void
2524DeliverMapNotify(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
2542int
2543MapWindow(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
2613void
2614MapSubwindows(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
2668static void
2669UnrealizeTree(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
2714static void
2715DeliverUnmapNotify(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
2732int
2733UnmapWindow(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
2774void
2775UnmapSubwindows(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
2838void
2839HandleSaveSet(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 */
2880Bool
2881PointInWindowIsVisible(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
2896RegionPtr
2897NotClippedByChildren(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
2909void
2910SendVisibilityNotify(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
2987int
2988dixSaveScreens(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
3095int
3096SaveScreens(int on, int mode)
3097{
3098 return dixSaveScreens(serverClient, on, mode);
3099}
3100
3101static Bool
3102TileScreenSaver(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
3210WindowPtr
3211FindWindowWithOptional(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
3227void
3228CheckWindowOptionalNeed(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
3286Bool
3287MakeWindowOptional(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 */
3337int
3338ChangeWindowDeviceCursor(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 */
3435CursorPtr
3436WindowGetDeviceCursor(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 */
3462static Bool
3463WindowSeekDeviceCursor(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 */
3496static Bool
3497WindowParentHasDeviceCursor(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 */
3527void
3528SetRootClip(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
3608VisualPtr
3609WindowGetVisual(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}