3 Copyright (c) 2006, Red Hat, Inc.
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice (including the next
13 paragraph) shall be included in all copies or substantial portions of the
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
24 Copyright 1987, 1998 The Open Group
26 Permission to use, copy, modify, distribute, and sell this software and its
27 documentation for any purpose is hereby granted without fee, provided that
28 the above copyright notice appear in all copies and that both that
29 copyright notice and this permission notice appear in supporting
32 The above copyright notice and this permission notice shall be included
33 in all copies or substantial portions of the Software.
35 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
39 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41 OTHER DEALINGS IN THE SOFTWARE.
43 Except as contained in this notice, the name of The Open Group shall
44 not be used in advertising or otherwise to promote the sale, use or
45 other dealings in this Software without prior written authorization
48 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
52 Permission to use, copy, modify, and distribute this software and its
53 documentation for any purpose and without fee is hereby granted,
54 provided that the above copyright notice appear in all copies and that
55 both that copyright notice and this permission notice appear in
56 supporting documentation, and that the name of Digital not be
57 used in advertising or publicity pertaining to distribution of the
58 software without specific, written prior permission.
60 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
61 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
62 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
63 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
64 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
65 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70 /* The panoramix components contained the following notice */
71 /*****************************************************************
73 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
75 Permission is hereby granted, free of charge, to any person obtaining a copy
76 of this software and associated documentation files (the "Software"), to deal
77 in the Software without restriction, including without limitation the rights
78 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79 copies of the Software.
81 The above copyright notice and this permission notice shall be included in
82 all copies or substantial portions of the Software.
84 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
87 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
88 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
89 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
90 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
92 Except as contained in this notice, the name of Digital Equipment Corporation
93 shall not be used in advertising or otherwise to promote the sale, use or other
94 dealings in this Software without prior written authorization from Digital
95 Equipment Corporation.
97 ******************************************************************/
99 #ifdef HAVE_DIX_CONFIG_H
100 #include <dix-config.h>
104 #include "scrnintstr.h"
106 #include "regionstr.h"
107 #include "validate.h"
108 #include "windowstr.h"
109 #include "propertyst.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"
120 #include "panoramiX.h"
121 #include "panoramiXsrv.h"
123 #include "dixevents.h"
125 #include "mi.h" /* miPaintWindow */
129 #include "selection.h"
131 #include "privates.h"
133 #include "exevents.h"
135 #include <X11/Xatom.h> /* must come after server includes */
138 * Window stuff for server
140 * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
141 * GetWindowAttributes, DeleteWindow, DestroySubWindows,
142 * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
143 * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
144 * ChangeWindowDeviceCursor
147 Bool bgNoneRoot
= FALSE
;
149 static unsigned char _back_lsb
[4] = { 0x88, 0x22, 0x44, 0x11 };
150 static unsigned char _back_msb
[4] = { 0x11, 0x44, 0x22, 0x88 };
152 static Bool
WindowParentHasDeviceCursor(WindowPtr pWin
,
153 DeviceIntPtr pDev
, CursorPtr pCurs
);
156 WindowSeekDeviceCursor(WindowPtr pWin
,
158 DevCursNodePtr
* pNode
, DevCursNodePtr
* pPrev
);
160 int screenIsSaved
= SCREEN_SAVER_OFF
;
162 static Bool
TileScreenSaver(ScreenPtr pScreen
, int kind
);
164 #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
165 CWDontPropagate | CWOverrideRedirect | CWCursor )
167 #define BOXES_OVERLAP(b1, b2) \
168 (!( ((b1)->x2 <= (b2)->x1) || \
169 ( ((b1)->x1 >= (b2)->x2)) || \
170 ( ((b1)->y2 <= (b2)->y1)) || \
171 ( ((b1)->y1 >= (b2)->y2)) ) )
173 #define RedirectSend(pWin) \
174 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
176 #define SubSend(pWin) \
177 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
179 #define StrSend(pWin) \
180 ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
182 #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
185 static const char *overlay_win_name
= "<composite overlay>";
189 get_window_name(WindowPtr pWin
)
191 #define WINDOW_NAME_BUF_LEN 512
193 static char buf
[WINDOW_NAME_BUF_LEN
];
197 CompScreenPtr comp_screen
= GetCompScreen(pWin
->drawable
.pScreen
);
199 if (comp_screen
&& pWin
== comp_screen
->pOverlayWin
)
200 return overlay_win_name
;
203 for (prop
= wUserProps(pWin
); prop
; prop
= prop
->next
) {
204 if (prop
->propertyName
== XA_WM_NAME
&& prop
->type
== XA_STRING
&&
206 len
= min(prop
->size
, WINDOW_NAME_BUF_LEN
- 1);
207 memcpy(buf
, prop
->data
, len
);
214 #undef WINDOW_NAME_BUF_LEN
218 log_window_info(WindowPtr pWin
, int depth
)
221 const char *win_name
, *visibility
;
223 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
225 for (i
= 0; i
< (depth
<< 2); i
++)
228 win_name
= get_window_name(pWin
);
229 ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]",
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
);
236 if (pWin
->overrideRedirect
)
237 ErrorF(" (override redirect)");
239 if (pWin
->redirectDraw
)
240 ErrorF(" (%s compositing: pixmap %x)",
241 (pWin
->redirectDraw
== RedirectDrawAutomatic
) ?
242 "automatic" : "manual",
243 pScreen
->GetWindowPixmap(pWin
)->drawable
.id
);
246 switch (pWin
->visibility
) {
247 case VisibilityUnobscured
:
248 visibility
= "unobscured";
250 case VisibilityPartiallyObscured
:
251 visibility
= "partially obscured";
253 case VisibilityFullyObscured
:
254 visibility
= "fully obscured";
256 case VisibilityNotViewable
:
257 visibility
= "unviewable";
260 ErrorF(", %s", visibility
);
262 if (REGION_NOTEMPTY(pScreen
, &pWin
->clipList
)) {
263 ErrorF(", clip list:");
264 rects
= REGION_RECTS(&pWin
->clipList
);
265 for (i
= 0; i
< REGION_NUM_RECTS(&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
);
277 PrintWindowTree(void)
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 pScreen
->GetScreenPixmap(pScreen
)->drawable
.id
);
287 pWin
= pScreen
->root
;
290 log_window_info(pWin
, depth
);
291 if (pWin
->firstChild
) {
292 pWin
= pWin
->firstChild
;
296 while (pWin
&& !pWin
->nextSib
) {
302 pWin
= pWin
->nextSib
;
308 TraverseTree(WindowPtr pWin
, VisitWindowProcPtr func
, pointer data
)
313 if (!(pChild
= pWin
))
316 result
= (*func
) (pChild
, data
);
317 if (result
== WT_STOPWALKING
)
318 return WT_STOPWALKING
;
319 if ((result
== WT_WALKCHILDREN
) && pChild
->firstChild
) {
320 pChild
= pChild
->firstChild
;
323 while (!pChild
->nextSib
&& (pChild
!= pWin
))
324 pChild
= pChild
->parent
;
327 pChild
= pChild
->nextSib
;
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.
341 WalkTree(ScreenPtr pScreen
, VisitWindowProcPtr func
, pointer data
)
343 return (TraverseTree(pScreen
->root
, func
, data
));
346 /* hack for forcing backing store on all windows */
347 int defaultBackingStore
= NotUseful
;
349 /* hack to force no backing store */
350 Bool disableBackingStore
= FALSE
;
351 Bool enableBackingStore
= FALSE
;
354 SetWindowToDefaults(WindowPtr pWin
)
356 pWin
->prevSib
= NullWindow
;
357 pWin
->firstChild
= NullWindow
;
358 pWin
->lastChild
= NullWindow
;
360 pWin
->valdata
= (ValidatePtr
) NULL
;
361 pWin
->optional
= (WindowOptPtr
) NULL
;
362 pWin
->cursorIsNone
= TRUE
;
364 pWin
->backingStore
= NotUseful
;
365 pWin
->DIXsaveUnder
= FALSE
;
366 pWin
->backStorage
= (pointer
) NULL
;
368 pWin
->mapped
= FALSE
; /* off */
369 pWin
->realized
= FALSE
; /* off */
370 pWin
->viewable
= FALSE
;
371 pWin
->visibility
= VisibilityNotViewable
;
372 pWin
->overrideRedirect
= FALSE
;
373 pWin
->saveUnder
= FALSE
;
375 pWin
->bitGravity
= ForgetGravity
;
376 pWin
->winGravity
= NorthWestGravity
;
379 pWin
->deliverableEvents
= 0;
380 pWin
->dontPropagate
= 0;
381 pWin
->forcedBS
= FALSE
;
382 pWin
->redirectDraw
= RedirectDrawNone
;
383 pWin
->forcedBG
= FALSE
;
386 pWin
->rootlessUnhittable
= FALSE
;
390 pWin
->damagedDescendants
= FALSE
;
395 MakeRootTile(WindowPtr pWin
)
397 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
399 unsigned char back
[128];
400 int len
= BitmapBytePad(sizeof(long));
401 unsigned char *from
, *to
;
404 pWin
->background
.pixmap
= (*pScreen
->CreatePixmap
) (pScreen
, 4, 4,
405 pScreen
->rootDepth
, 0);
407 pWin
->backgroundState
= BackgroundPixmap
;
408 pGC
= GetScratchGC(pScreen
->rootDepth
, pScreen
);
409 if (!pWin
->background
.pixmap
|| !pGC
)
410 FatalError("could not create root tile");
413 ChangeGCVal attributes
[2];
415 attributes
[0].val
= pScreen
->whitePixel
;
416 attributes
[1].val
= pScreen
->blackPixel
;
418 (void) ChangeGC(NullClient
, pGC
, GCForeground
| GCBackground
,
422 ValidateGC((DrawablePtr
) pWin
->background
.pixmap
, pGC
);
424 from
= (screenInfo
.bitmapBitOrder
== LSBFirst
) ? _back_lsb
: _back_msb
;
427 for (i
= 4; i
> 0; i
--, from
++)
428 for (j
= len
; j
> 0; j
--)
431 (*pGC
->ops
->PutImage
) ((DrawablePtr
) pWin
->background
.pixmap
, pGC
, 1,
432 0, 0, len
, 4, 0, XYBitmap
, (char *) back
);
440 * Makes a window at initialization time for specified screen
444 CreateRootWindow(ScreenPtr pScreen
)
448 PixmapFormatRec
*format
;
450 pWin
= dixAllocateScreenObjectWithPrivates(pScreen
, WindowRec
, PRIVATE_WINDOW
);
454 pScreen
->screensaver
.pWindow
= NULL
;
455 pScreen
->screensaver
.wid
= FakeClientID(0);
456 pScreen
->screensaver
.ExternalScreenSaver
= NULL
;
457 screenIsSaved
= SCREEN_SAVER_OFF
;
459 pScreen
->root
= pWin
;
461 pWin
->drawable
.pScreen
= pScreen
;
462 pWin
->drawable
.type
= DRAWABLE_WINDOW
;
464 pWin
->drawable
.depth
= pScreen
->rootDepth
;
465 for (format
= screenInfo
.formats
;
466 format
->depth
!= pScreen
->rootDepth
; format
++);
467 pWin
->drawable
.bitsPerPixel
= format
->bitsPerPixel
;
469 pWin
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
471 pWin
->parent
= NullWindow
;
472 SetWindowToDefaults(pWin
);
474 pWin
->optional
= malloc(sizeof(WindowOptRec
));
478 pWin
->optional
->dontPropagateMask
= 0;
479 pWin
->optional
->otherEventMasks
= 0;
480 pWin
->optional
->otherClients
= NULL
;
481 pWin
->optional
->passiveGrabs
= NULL
;
482 pWin
->optional
->userProps
= NULL
;
483 pWin
->optional
->backingBitPlanes
= ~0L;
484 pWin
->optional
->backingPixel
= 0;
485 pWin
->optional
->boundingShape
= NULL
;
486 pWin
->optional
->clipShape
= NULL
;
487 pWin
->optional
->inputShape
= NULL
;
488 pWin
->optional
->inputMasks
= NULL
;
489 pWin
->optional
->deviceCursors
= NULL
;
490 pWin
->optional
->colormap
= pScreen
->defColormap
;
491 pWin
->optional
->visual
= pScreen
->rootVisual
;
493 pWin
->nextSib
= NullWindow
;
495 pWin
->drawable
.id
= FakeClientID(0);
497 pWin
->origin
.x
= pWin
->origin
.y
= 0;
498 pWin
->drawable
.height
= pScreen
->height
;
499 pWin
->drawable
.width
= pScreen
->width
;
500 pWin
->drawable
.x
= pWin
->drawable
.y
= 0;
504 box
.x2
= pScreen
->width
;
505 box
.y2
= pScreen
->height
;
506 RegionInit(&pWin
->clipList
, &box
, 1);
507 RegionInit(&pWin
->winSize
, &box
, 1);
508 RegionInit(&pWin
->borderSize
, &box
, 1);
509 RegionInit(&pWin
->borderClip
, &box
, 1);
511 pWin
->drawable
.class = InputOutput
;
512 pWin
->optional
->visual
= pScreen
->rootVisual
;
514 pWin
->backgroundState
= BackgroundPixel
;
515 pWin
->background
.pixel
= pScreen
->whitePixel
;
517 pWin
->borderIsPixel
= TRUE
;
518 pWin
->border
.pixel
= pScreen
->blackPixel
;
519 pWin
->borderWidth
= 0;
521 /* security creation/labeling check
523 if (XaceHook(XACE_RESOURCE_ACCESS
, serverClient
, pWin
->drawable
.id
,
524 RT_WINDOW
, pWin
, RT_NONE
, NULL
, DixCreateAccess
))
527 if (!AddResource(pWin
->drawable
.id
, RT_WINDOW
, (pointer
) pWin
))
530 if (disableBackingStore
)
531 pScreen
->backingStoreSupport
= NotUseful
;
532 if (enableBackingStore
)
533 pScreen
->backingStoreSupport
= WhenMapped
;
535 if (noCompositeExtension
)
536 pScreen
->backingStoreSupport
= NotUseful
;
539 pScreen
->saveUnderSupport
= NotUseful
;
545 InitRootWindow(WindowPtr pWin
)
547 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
548 int backFlag
= CWBorderPixel
| CWCursor
| CWBackingStore
;
550 if (!(*pScreen
->CreateWindow
) (pWin
))
552 (*pScreen
->PositionWindow
) (pWin
, 0, 0);
554 pWin
->cursorIsNone
= FALSE
;
555 pWin
->optional
->cursor
= RefCursor(rootCursor
);
557 if (party_like_its_1989
) {
559 backFlag
|= CWBackPixmap
;
561 else if (pScreen
->canDoBGNoneRoot
&& bgNoneRoot
) {
562 pWin
->backgroundState
= XaceBackgroundNoneState(pWin
);
563 pWin
->background
.pixel
= pScreen
->whitePixel
;
564 backFlag
|= CWBackPixmap
;
567 pWin
->backgroundState
= BackgroundPixel
;
569 pWin
->background
.pixel
= pScreen
->whitePixel
;
571 pWin
->background
.pixel
= pScreen
->blackPixel
;
572 backFlag
|= CWBackPixel
;
575 pWin
->backingStore
= defaultBackingStore
;
576 pWin
->forcedBS
= (defaultBackingStore
!= NotUseful
);
577 /* We SHOULD check for an error value here XXX */
578 (*pScreen
->ChangeWindowAttributes
) (pWin
, backFlag
);
580 MapWindow(pWin
, serverClient
);
583 /* Set the region to the intersection of the rectangle and the
584 * window's winSize. The window is typically the parent of the
585 * window from which the region came.
589 ClippedRegionFromBox(WindowPtr pWin
, RegionPtr Rgn
, int x
, int y
, int w
, int h
)
591 BoxRec box
= *RegionExtents(&pWin
->winSize
);
593 /* we do these calculations to avoid overflows */
608 RegionReset(Rgn
, &box
);
609 RegionIntersect(Rgn
, Rgn
, &pWin
->winSize
);
612 static RealChildHeadProc realChildHeadProc
= NULL
;
615 RegisterRealChildHeadProc(RealChildHeadProc proc
)
617 realChildHeadProc
= proc
;
621 RealChildHead(WindowPtr pWin
)
623 if (realChildHeadProc
) {
624 return realChildHeadProc(pWin
);
628 (screenIsSaved
== SCREEN_SAVER_ON
) &&
629 (HasSaverWindow(pWin
->drawable
.pScreen
)))
630 return pWin
->firstChild
;
637 * Makes a window in response to client request
641 CreateWindow(Window wid
, WindowPtr pParent
, int x
, int y
, unsigned w
,
642 unsigned h
, unsigned bw
, unsigned class, Mask vmask
, XID
*vlist
,
643 int depth
, ClientPtr client
, VisualID visual
, int *error
)
651 PixmapFormatRec
*format
;
652 WindowOptPtr ancwopt
;
654 if (class == CopyFromParent
)
655 class = pParent
->drawable
.class;
657 if ((class != InputOutput
) && (class != InputOnly
)) {
659 client
->errorValue
= class;
663 if ((class != InputOnly
) && (pParent
->drawable
.class == InputOnly
)) {
668 if ((class == InputOnly
) && ((bw
!= 0) || (depth
!= 0))) {
673 pScreen
= pParent
->drawable
.pScreen
;
674 if ((class == InputOutput
) && (depth
== 0))
675 depth
= pParent
->drawable
.depth
;
676 ancwopt
= pParent
->optional
;
678 ancwopt
= FindWindowWithOptional(pParent
)->optional
;
679 if (visual
== CopyFromParent
) {
680 visual
= ancwopt
->visual
;
683 /* Find out if the depth and visual are acceptable for this Screen */
684 if ((visual
!= ancwopt
->visual
) || (depth
!= pParent
->drawable
.depth
)) {
686 for (idepth
= 0; idepth
< pScreen
->numDepths
; idepth
++) {
687 pDepth
= (DepthPtr
) &pScreen
->allowedDepths
[idepth
];
688 if ((depth
== pDepth
->depth
) || (depth
== 0)) {
689 for (ivisual
= 0; ivisual
< pDepth
->numVids
; ivisual
++) {
690 if (visual
== pDepth
->vids
[ivisual
]) {
703 if (((vmask
& (CWBorderPixmap
| CWBorderPixel
)) == 0) &&
704 (class != InputOnly
) && (depth
!= pParent
->drawable
.depth
)) {
709 if (((vmask
& CWColormap
) == 0) &&
710 (class != InputOnly
) &&
711 ((visual
!= ancwopt
->visual
) || (ancwopt
->colormap
== None
))) {
716 pWin
= dixAllocateScreenObjectWithPrivates(pScreen
, WindowRec
, PRIVATE_WINDOW
);
721 pWin
->drawable
= pParent
->drawable
;
722 pWin
->drawable
.depth
= depth
;
723 if (depth
== pParent
->drawable
.depth
)
724 pWin
->drawable
.bitsPerPixel
= pParent
->drawable
.bitsPerPixel
;
726 for (format
= screenInfo
.formats
; format
->depth
!= depth
; format
++);
727 pWin
->drawable
.bitsPerPixel
= format
->bitsPerPixel
;
729 if (class == InputOnly
)
730 pWin
->drawable
.type
= (short) UNDRAWABLE_WINDOW
;
731 pWin
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
733 pWin
->drawable
.id
= wid
;
734 pWin
->drawable
.class = class;
736 pWin
->parent
= pParent
;
737 SetWindowToDefaults(pWin
);
739 if (visual
!= ancwopt
->visual
) {
740 if (!MakeWindowOptional(pWin
)) {
741 dixFreeObjectWithPrivates(pWin
, PRIVATE_WINDOW
);
745 pWin
->optional
->visual
= visual
;
746 pWin
->optional
->colormap
= None
;
749 pWin
->borderWidth
= bw
;
751 /* security creation/labeling check
753 *error
= XaceHook(XACE_RESOURCE_ACCESS
, client
, wid
, RT_WINDOW
, pWin
,
754 RT_WINDOW
, pWin
->parent
,
755 DixCreateAccess
| DixSetAttrAccess
);
756 if (*error
!= Success
) {
757 dixFreeObjectWithPrivates(pWin
, PRIVATE_WINDOW
);
761 pWin
->backgroundState
= XaceBackgroundNoneState(pWin
);
762 pWin
->background
.pixel
= pScreen
->whitePixel
;
764 pWin
->borderIsPixel
= pParent
->borderIsPixel
;
765 pWin
->border
= pParent
->border
;
766 if (pWin
->borderIsPixel
== FALSE
)
767 pWin
->border
.pixmap
->refcnt
++;
769 pWin
->origin
.x
= x
+ (int) bw
;
770 pWin
->origin
.y
= y
+ (int) bw
;
771 pWin
->drawable
.width
= w
;
772 pWin
->drawable
.height
= h
;
773 pWin
->drawable
.x
= pParent
->drawable
.x
+ x
+ (int) bw
;
774 pWin
->drawable
.y
= pParent
->drawable
.y
+ y
+ (int) bw
;
776 /* set up clip list correctly for unobscured WindowPtr */
777 RegionNull(&pWin
->clipList
);
778 RegionNull(&pWin
->borderClip
);
779 RegionNull(&pWin
->winSize
);
780 RegionNull(&pWin
->borderSize
);
782 pHead
= RealChildHead(pParent
);
784 pWin
->nextSib
= pHead
->nextSib
;
786 pHead
->nextSib
->prevSib
= pWin
;
788 pParent
->lastChild
= pWin
;
789 pHead
->nextSib
= pWin
;
790 pWin
->prevSib
= pHead
;
793 pWin
->nextSib
= pParent
->firstChild
;
794 if (pParent
->firstChild
)
795 pParent
->firstChild
->prevSib
= pWin
;
797 pParent
->lastChild
= pWin
;
798 pParent
->firstChild
= pWin
;
804 /* We SHOULD check for an error value here XXX */
805 if (!(*pScreen
->CreateWindow
) (pWin
)) {
807 DeleteWindow(pWin
, None
);
810 /* We SHOULD check for an error value here XXX */
811 (*pScreen
->PositionWindow
) (pWin
, pWin
->drawable
.x
, pWin
->drawable
.y
);
813 if (!(vmask
& CWEventMask
))
814 RecalculateDeliverableEvents(pWin
);
817 *error
= ChangeWindowAttributes(pWin
, vmask
, vlist
, wClient(pWin
));
821 if (*error
!= Success
) {
822 DeleteWindow(pWin
, None
);
825 if (!(vmask
& CWBackingStore
) && (defaultBackingStore
!= NotUseful
)) {
826 XID value
= defaultBackingStore
;
828 (void) ChangeWindowAttributes(pWin
, CWBackingStore
, &value
,
830 pWin
->forcedBS
= TRUE
;
833 if (SubSend(pParent
)) {
835 .u
.createNotify
.window
= wid
,
836 .u
.createNotify
.parent
= pParent
->drawable
.id
,
837 .u
.createNotify
.x
= x
,
838 .u
.createNotify
.y
= y
,
839 .u
.createNotify
.width
= w
,
840 .u
.createNotify
.height
= h
,
841 .u
.createNotify
.borderWidth
= bw
,
842 .u
.createNotify
.override
= pWin
->overrideRedirect
844 event
.u
.u
.type
= CreateNotify
;
845 DeliverEvents(pParent
, &event
, 1, NullWindow
);
851 DisposeWindowOptional(WindowPtr pWin
)
856 * everything is peachy. Delete the optional record
859 if (pWin
->optional
->cursor
) {
860 FreeCursor(pWin
->optional
->cursor
, (Cursor
) 0);
861 pWin
->cursorIsNone
= FALSE
;
864 pWin
->cursorIsNone
= TRUE
;
866 if (pWin
->optional
->deviceCursors
) {
870 pList
= pWin
->optional
->deviceCursors
;
873 FreeCursor(pList
->cursor
, (XID
) 0);
878 pWin
->optional
->deviceCursors
= NULL
;
881 free(pWin
->optional
);
882 pWin
->optional
= NULL
;
886 FreeWindowResources(WindowPtr pWin
)
888 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
890 DeleteWindowFromAnySaveSet(pWin
);
891 DeleteWindowFromAnySelections(pWin
);
892 DeleteWindowFromAnyEvents(pWin
, TRUE
);
893 RegionUninit(&pWin
->clipList
);
894 RegionUninit(&pWin
->winSize
);
895 RegionUninit(&pWin
->borderClip
);
896 RegionUninit(&pWin
->borderSize
);
897 if (wBoundingShape(pWin
))
898 RegionDestroy(wBoundingShape(pWin
));
899 if (wClipShape(pWin
))
900 RegionDestroy(wClipShape(pWin
));
901 if (wInputShape(pWin
))
902 RegionDestroy(wInputShape(pWin
));
903 if (pWin
->borderIsPixel
== FALSE
)
904 (*pScreen
->DestroyPixmap
) (pWin
->border
.pixmap
);
905 if (pWin
->backgroundState
== BackgroundPixmap
)
906 (*pScreen
->DestroyPixmap
) (pWin
->background
.pixmap
);
908 DeleteAllWindowProperties(pWin
);
909 /* We SHOULD check for an error value here XXX */
910 (*pScreen
->DestroyWindow
) (pWin
);
911 DisposeWindowOptional(pWin
);
915 CrushTree(WindowPtr pWin
)
917 WindowPtr pChild
, pSib
, pParent
;
918 UnrealizeWindowProcPtr UnrealizeWindow
;
920 if (!(pChild
= pWin
->firstChild
))
922 UnrealizeWindow
= pWin
->drawable
.pScreen
->UnrealizeWindow
;
924 if (pChild
->firstChild
) {
925 pChild
= pChild
->firstChild
;
929 pParent
= pChild
->parent
;
930 if (SubStrSend(pChild
, pParent
)) {
931 xEvent event
= { .u
.u
.type
= DestroyNotify
};
932 event
.u
.destroyNotify
.window
= pChild
->drawable
.id
;
933 DeliverEvents(pChild
, &event
, 1, NullWindow
);
935 FreeResource(pChild
->drawable
.id
, RT_WINDOW
);
936 pSib
= pChild
->nextSib
;
937 pChild
->viewable
= FALSE
;
938 if (pChild
->realized
) {
939 pChild
->realized
= FALSE
;
940 (*UnrealizeWindow
) (pChild
);
942 FreeWindowResources(pChild
);
943 dixFreeObjectWithPrivates(pChild
, PRIVATE_WINDOW
);
947 pChild
->firstChild
= NullWindow
;
948 pChild
->lastChild
= NullWindow
;
957 * Deletes child of window then window itself
958 * If wid is None, don't send any events
962 DeleteWindow(pointer value
, XID wid
)
965 WindowPtr pWin
= (WindowPtr
) value
;
967 UnmapWindow(pWin
, FALSE
);
971 pParent
= pWin
->parent
;
972 if (wid
&& pParent
&& SubStrSend(pWin
, pParent
)) {
973 xEvent event
= { .u
.u
.type
= DestroyNotify
};
974 event
.u
.destroyNotify
.window
= pWin
->drawable
.id
;
975 DeliverEvents(pWin
, &event
, 1, NullWindow
);
978 FreeWindowResources(pWin
);
980 if (pParent
->firstChild
== pWin
)
981 pParent
->firstChild
= pWin
->nextSib
;
982 if (pParent
->lastChild
== pWin
)
983 pParent
->lastChild
= pWin
->prevSib
;
985 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
987 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
990 pWin
->drawable
.pScreen
->root
= NULL
;
991 dixFreeObjectWithPrivates(pWin
, PRIVATE_WINDOW
);
996 DestroySubwindows(WindowPtr pWin
, ClientPtr client
)
999 * The protocol is quite clear that each window should be
1000 * destroyed in turn, however, unmapping all of the first
1001 * eliminates most of the calls to ValidateTree. So,
1002 * this implementation is incorrect in that all of the
1003 * UnmapNotifies occur before all of the DestroyNotifies.
1004 * If you care, simply delete the call to UnmapSubwindows.
1006 UnmapSubwindows(pWin
);
1007 while (pWin
->lastChild
) {
1008 int rc
= XaceHook(XACE_RESOURCE_ACCESS
, client
,
1009 pWin
->lastChild
->drawable
.id
, RT_WINDOW
,
1010 pWin
->lastChild
, RT_NONE
, NULL
, DixDestroyAccess
);
1014 FreeResource(pWin
->lastChild
->drawable
.id
, RT_NONE
);
1020 SetRootWindowBackground(WindowPtr pWin
, ScreenPtr pScreen
, Mask
*index2
)
1022 /* following the protocol: "Changing the background of a root window to
1023 * None or ParentRelative restores the default background pixmap" */
1025 pWin
->backgroundState
= XaceBackgroundNoneState(pWin
);
1026 pWin
->background
.pixel
= pScreen
->whitePixel
;
1028 else if (party_like_its_1989
)
1031 pWin
->backgroundState
= BackgroundPixel
;
1033 pWin
->background
.pixel
= pScreen
->whitePixel
;
1035 pWin
->background
.pixel
= pScreen
->blackPixel
;
1036 *index2
= CWBackPixel
;
1041 * ChangeWindowAttributes
1043 * The value-mask specifies which attributes are to be changed; the
1044 * value-list contains one value for each one bit in the mask, from least
1045 * to most significant bit in the mask.
1049 ChangeWindowAttributes(WindowPtr pWin
, Mask vmask
, XID
*vlist
, ClientPtr client
)
1054 CursorPtr pCursor
, pOldCursor
;
1062 Mask index2
, tmask
, vmaskCopy
= 0;
1064 Bool checkOptional
= FALSE
, borderRelative
= FALSE
;
1066 if ((pWin
->drawable
.class == InputOnly
) &&
1067 (vmask
& (~INPUTONLY_LEGAL_MASK
)))
1071 pScreen
= pWin
->drawable
.pScreen
;
1075 index2
= (Mask
) lowbit(tmask
);
1079 pixID
= (Pixmap
) * pVlist
;
1081 if (pWin
->backgroundState
== ParentRelative
)
1082 borderRelative
= TRUE
;
1083 if (pixID
== None
) {
1084 if (pWin
->backgroundState
== BackgroundPixmap
)
1085 (*pScreen
->DestroyPixmap
) (pWin
->background
.pixmap
);
1087 SetRootWindowBackground(pWin
, pScreen
, &index2
);
1089 pWin
->backgroundState
= XaceBackgroundNoneState(pWin
);
1090 pWin
->background
.pixel
= pScreen
->whitePixel
;
1093 else if (pixID
== ParentRelative
) {
1095 pWin
->drawable
.depth
!= pWin
->parent
->drawable
.depth
) {
1099 if (pWin
->backgroundState
== BackgroundPixmap
)
1100 (*pScreen
->DestroyPixmap
) (pWin
->background
.pixmap
);
1102 SetRootWindowBackground(pWin
, pScreen
, &index2
);
1104 pWin
->backgroundState
= ParentRelative
;
1105 borderRelative
= TRUE
;
1106 /* Note that the parent's backgroundTile's refcnt is NOT
1110 rc
= dixLookupResourceByType((pointer
*) &pPixmap
, pixID
,
1111 RT_PIXMAP
, client
, DixReadAccess
);
1112 if (rc
== Success
) {
1113 if ((pPixmap
->drawable
.depth
!= pWin
->drawable
.depth
) ||
1114 (pPixmap
->drawable
.pScreen
!= pScreen
)) {
1118 if (pWin
->backgroundState
== BackgroundPixmap
)
1119 (*pScreen
->DestroyPixmap
) (pWin
->background
.pixmap
);
1120 pWin
->backgroundState
= BackgroundPixmap
;
1121 pWin
->background
.pixmap
= pPixmap
;
1126 client
->errorValue
= pixID
;
1132 if (pWin
->backgroundState
== ParentRelative
)
1133 borderRelative
= TRUE
;
1134 if (pWin
->backgroundState
== BackgroundPixmap
)
1135 (*pScreen
->DestroyPixmap
) (pWin
->background
.pixmap
);
1136 pWin
->backgroundState
= BackgroundPixel
;
1137 pWin
->background
.pixel
= (CARD32
) *pVlist
;
1138 /* background pixel overrides background pixmap,
1139 so don't let the ddx layer see both bits */
1140 vmaskCopy
&= ~CWBackPixmap
;
1143 case CWBorderPixmap
:
1144 pixID
= (Pixmap
) * pVlist
;
1146 if (pixID
== CopyFromParent
) {
1147 if (!pWin
->parent
||
1148 (pWin
->drawable
.depth
!= pWin
->parent
->drawable
.depth
)) {
1152 if (pWin
->parent
->borderIsPixel
== TRUE
) {
1153 if (pWin
->borderIsPixel
== FALSE
)
1154 (*pScreen
->DestroyPixmap
) (pWin
->border
.pixmap
);
1155 pWin
->border
= pWin
->parent
->border
;
1156 pWin
->borderIsPixel
= TRUE
;
1157 index2
= CWBorderPixel
;
1161 pixID
= pWin
->parent
->border
.pixmap
->drawable
.id
;
1164 rc
= dixLookupResourceByType((pointer
*) &pPixmap
, pixID
, RT_PIXMAP
,
1165 client
, DixReadAccess
);
1166 if (rc
== Success
) {
1167 if ((pPixmap
->drawable
.depth
!= pWin
->drawable
.depth
) ||
1168 (pPixmap
->drawable
.pScreen
!= pScreen
)) {
1172 if (pWin
->borderIsPixel
== FALSE
)
1173 (*pScreen
->DestroyPixmap
) (pWin
->border
.pixmap
);
1174 pWin
->borderIsPixel
= FALSE
;
1175 pWin
->border
.pixmap
= pPixmap
;
1180 client
->errorValue
= pixID
;
1185 if (pWin
->borderIsPixel
== FALSE
)
1186 (*pScreen
->DestroyPixmap
) (pWin
->border
.pixmap
);
1187 pWin
->borderIsPixel
= TRUE
;
1188 pWin
->border
.pixel
= (CARD32
) *pVlist
;
1189 /* border pixel overrides border pixmap,
1190 so don't let the ddx layer see both bits */
1191 vmaskCopy
&= ~CWBorderPixmap
;
1195 val
= (CARD8
) *pVlist
;
1197 if (val
> StaticGravity
) {
1199 client
->errorValue
= val
;
1202 pWin
->bitGravity
= val
;
1205 val
= (CARD8
) *pVlist
;
1207 if (val
> StaticGravity
) {
1209 client
->errorValue
= val
;
1212 pWin
->winGravity
= val
;
1214 case CWBackingStore
:
1215 val
= (CARD8
) *pVlist
;
1217 if ((val
!= NotUseful
) && (val
!= WhenMapped
) && (val
!= Always
)) {
1219 client
->errorValue
= val
;
1222 pWin
->backingStore
= val
;
1223 pWin
->forcedBS
= FALSE
;
1225 case CWBackingPlanes
:
1226 if (pWin
->optional
|| ((CARD32
) *pVlist
!= (CARD32
) ~0L)) {
1227 if (!pWin
->optional
&& !MakeWindowOptional(pWin
)) {
1231 pWin
->optional
->backingBitPlanes
= (CARD32
) *pVlist
;
1232 if ((CARD32
) *pVlist
== (CARD32
) ~0L)
1233 checkOptional
= TRUE
;
1237 case CWBackingPixel
:
1238 if (pWin
->optional
|| (CARD32
) *pVlist
) {
1239 if (!pWin
->optional
&& !MakeWindowOptional(pWin
)) {
1243 pWin
->optional
->backingPixel
= (CARD32
) *pVlist
;
1245 checkOptional
= TRUE
;
1250 val
= (BOOL
) * pVlist
;
1252 if ((val
!= xTrue
) && (val
!= xFalse
)) {
1254 client
->errorValue
= val
;
1257 pWin
->saveUnder
= val
;
1260 rc
= EventSelectForWindow(pWin
, client
, (Mask
) *pVlist
);
1267 case CWDontPropagate
:
1268 rc
= EventSuppressForWindow(pWin
, client
, (Mask
) *pVlist
,
1276 case CWOverrideRedirect
:
1277 val
= (BOOL
) * pVlist
;
1279 if ((val
!= xTrue
) && (val
!= xFalse
)) {
1281 client
->errorValue
= val
;
1285 rc
= XaceHook(XACE_RESOURCE_ACCESS
, client
, pWin
->drawable
.id
,
1286 RT_WINDOW
, pWin
, RT_NONE
, NULL
, DixGrabAccess
);
1287 if (rc
!= Success
) {
1289 client
->errorValue
= pWin
->drawable
.id
;
1293 pWin
->overrideRedirect
= val
;
1296 cmap
= (Colormap
) * pVlist
;
1298 if (cmap
== CopyFromParent
) {
1301 pWin
->optional
->visual
== wVisual(pWin
->parent
))) {
1302 cmap
= wColormap(pWin
->parent
);
1311 rc
= dixLookupResourceByType((pointer
*) &pCmap
, cmap
, RT_COLORMAP
,
1312 client
, DixUseAccess
);
1313 if (rc
!= Success
) {
1315 client
->errorValue
= cmap
;
1318 if (pCmap
->pVisual
->vid
!= wVisual(pWin
) ||
1319 pCmap
->pScreen
!= pScreen
) {
1323 if (cmap
!= wColormap(pWin
)) {
1324 if (!pWin
->optional
) {
1325 if (!MakeWindowOptional(pWin
)) {
1330 else if (pWin
->parent
&& cmap
== wColormap(pWin
->parent
))
1331 checkOptional
= TRUE
;
1334 * propagate the original colormap to any children
1338 for (pChild
= pWin
->firstChild
; pChild
;
1339 pChild
= pChild
->nextSib
) {
1340 if (!pChild
->optional
&& !MakeWindowOptional(pChild
)) {
1346 pWin
->optional
->colormap
= cmap
;
1349 * check on any children now matching the new colormap
1352 for (pChild
= pWin
->firstChild
; pChild
;
1353 pChild
= pChild
->nextSib
) {
1354 if (pChild
->optional
->colormap
== cmap
)
1355 CheckWindowOptionalNeed(pChild
);
1359 .u
.colormap
.window
= pWin
->drawable
.id
,
1360 .u
.colormap
.colormap
= cmap
,
1361 .u
.colormap
.new = xTrue
,
1362 .u
.colormap
.state
= IsMapInstalled(cmap
, pWin
)
1364 xE
.u
.u
.type
= ColormapNotify
;
1365 DeliverEvents(pWin
, &xE
, 1, NullWindow
);
1369 cursorID
= (Cursor
) * pVlist
;
1374 if (cursorID
== None
) {
1375 if (pWin
== pWin
->drawable
.pScreen
->root
)
1376 pCursor
= rootCursor
;
1378 pCursor
= (CursorPtr
) None
;
1381 rc
= dixLookupResourceByType((pointer
*) &pCursor
, cursorID
,
1382 RT_CURSOR
, client
, DixUseAccess
);
1383 if (rc
!= Success
) {
1385 client
->errorValue
= cursorID
;
1390 if (pCursor
!= wCursor(pWin
)) {
1392 * patch up child windows so they don't lose cursors.
1395 for (pChild
= pWin
->firstChild
; pChild
;
1396 pChild
= pChild
->nextSib
) {
1397 if (!pChild
->optional
&& !pChild
->cursorIsNone
&&
1398 !MakeWindowOptional(pChild
)) {
1405 if (pCursor
== (CursorPtr
) None
) {
1406 pWin
->cursorIsNone
= TRUE
;
1407 if (pWin
->optional
) {
1408 pOldCursor
= pWin
->optional
->cursor
;
1409 pWin
->optional
->cursor
= (CursorPtr
) None
;
1410 checkOptional
= TRUE
;
1414 if (!pWin
->optional
) {
1415 if (!MakeWindowOptional(pWin
)) {
1420 else if (pWin
->parent
&& pCursor
== wCursor(pWin
->parent
))
1421 checkOptional
= TRUE
;
1422 pOldCursor
= pWin
->optional
->cursor
;
1423 pWin
->optional
->cursor
= RefCursor(pCursor
);
1424 pWin
->cursorIsNone
= FALSE
;
1426 * check on any children now matching the new cursor
1429 for (pChild
= pWin
->firstChild
; pChild
;
1430 pChild
= pChild
->nextSib
) {
1431 if (pChild
->optional
&&
1432 (pChild
->optional
->cursor
== pCursor
))
1433 CheckWindowOptionalNeed(pChild
);
1437 CursorVisible
= TRUE
;
1440 WindowHasNewCursor(pWin
);
1442 /* Can't free cursor until here - old cursor
1443 * is needed in WindowHasNewCursor
1446 FreeCursor(pOldCursor
, (Cursor
) 0);
1451 client
->errorValue
= vmask
;
1454 vmaskCopy
|= index2
;
1458 CheckWindowOptionalNeed(pWin
);
1460 /* We SHOULD check for an error value here XXX */
1461 (*pScreen
->ChangeWindowAttributes
) (pWin
, vmaskCopy
);
1464 If the border contents have changed, redraw the border.
1465 Note that this has to be done AFTER pScreen->ChangeWindowAttributes
1466 for the tile to be rotated, and the correct function selected.
1468 if (((vmaskCopy
& (CWBorderPixel
| CWBorderPixmap
)) || borderRelative
)
1469 && pWin
->viewable
&& HasBorder(pWin
)) {
1472 RegionNull(&exposed
);
1473 RegionSubtract(&exposed
, &pWin
->borderClip
, &pWin
->winSize
);
1474 miPaintWindow(pWin
, &exposed
, PW_BORDER
);
1475 RegionUninit(&exposed
);
1481 * GetWindowAttributes
1482 * Notice that this is different than ChangeWindowAttributes
1486 GetWindowAttributes(WindowPtr pWin
, ClientPtr client
,
1487 xGetWindowAttributesReply
* wa
)
1490 wa
->bitGravity
= pWin
->bitGravity
;
1491 wa
->winGravity
= pWin
->winGravity
;
1492 if (pWin
->forcedBS
&& pWin
->backingStore
!= Always
)
1493 wa
->backingStore
= NotUseful
;
1495 wa
->backingStore
= pWin
->backingStore
;
1496 wa
->length
= bytes_to_int32(sizeof(xGetWindowAttributesReply
) -
1497 sizeof(xGenericReply
));
1498 wa
->sequenceNumber
= client
->sequence
;
1499 wa
->backingBitPlanes
= wBackingBitPlanes(pWin
);
1500 wa
->backingPixel
= wBackingPixel(pWin
);
1501 wa
->saveUnder
= (BOOL
) pWin
->saveUnder
;
1502 wa
->override
= pWin
->overrideRedirect
;
1504 wa
->mapState
= IsUnmapped
;
1505 else if (pWin
->realized
)
1506 wa
->mapState
= IsViewable
;
1508 wa
->mapState
= IsUnviewable
;
1510 wa
->colormap
= wColormap(pWin
);
1511 wa
->mapInstalled
= (wa
->colormap
== None
) ? xFalse
1512 : IsMapInstalled(wa
->colormap
, pWin
);
1514 wa
->yourEventMask
= EventMaskForClient(pWin
, client
);
1515 wa
->allEventMasks
= pWin
->eventMask
| wOtherEventMasks(pWin
);
1516 wa
->doNotPropagateMask
= wDontPropagateMask(pWin
);
1517 wa
->class = pWin
->drawable
.class;
1518 wa
->visualID
= wVisual(pWin
);
1522 MoveWindowInStack(WindowPtr pWin
, WindowPtr pNextSib
)
1524 WindowPtr pParent
= pWin
->parent
;
1525 WindowPtr pFirstChange
= pWin
; /* highest window where list changes */
1527 if (pWin
->nextSib
!= pNextSib
) {
1528 WindowPtr pOldNextSib
= pWin
->nextSib
;
1530 if (!pNextSib
) { /* move to bottom */
1531 if (pParent
->firstChild
== pWin
)
1532 pParent
->firstChild
= pWin
->nextSib
;
1533 /* if (pWin->nextSib) *//* is always True: pNextSib == NULL
1534 * and pWin->nextSib != pNextSib
1535 * therefore pWin->nextSib != NULL */
1536 pFirstChange
= pWin
->nextSib
;
1537 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1539 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1540 pParent
->lastChild
->nextSib
= pWin
;
1541 pWin
->prevSib
= pParent
->lastChild
;
1542 pWin
->nextSib
= NullWindow
;
1543 pParent
->lastChild
= pWin
;
1545 else if (pParent
->firstChild
== pNextSib
) { /* move to top */
1546 pFirstChange
= pWin
;
1547 if (pParent
->lastChild
== pWin
)
1548 pParent
->lastChild
= pWin
->prevSib
;
1550 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1552 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1553 pWin
->nextSib
= pParent
->firstChild
;
1554 pWin
->prevSib
= (WindowPtr
) NULL
;
1555 pNextSib
->prevSib
= pWin
;
1556 pParent
->firstChild
= pWin
;
1558 else { /* move in middle of list */
1560 WindowPtr pOldNext
= pWin
->nextSib
;
1562 pFirstChange
= NullWindow
;
1563 if (pParent
->firstChild
== pWin
)
1564 pFirstChange
= pParent
->firstChild
= pWin
->nextSib
;
1565 if (pParent
->lastChild
== pWin
) {
1566 pFirstChange
= pWin
;
1567 pParent
->lastChild
= pWin
->prevSib
;
1570 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1572 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1573 pWin
->nextSib
= pNextSib
;
1574 pWin
->prevSib
= pNextSib
->prevSib
;
1575 if (pNextSib
->prevSib
)
1576 pNextSib
->prevSib
->nextSib
= pWin
;
1577 pNextSib
->prevSib
= pWin
;
1578 if (!pFirstChange
) { /* do we know it yet? */
1579 pFirstChange
= pParent
->firstChild
; /* no, search from top */
1580 while ((pFirstChange
!= pWin
) && (pFirstChange
!= pOldNext
))
1581 pFirstChange
= pFirstChange
->nextSib
;
1584 if (pWin
->drawable
.pScreen
->RestackWindow
)
1585 (*pWin
->drawable
.pScreen
->RestackWindow
) (pWin
, pOldNextSib
);
1590 * In rootless mode we can't optimize away window restacks.
1591 * There may be non-X windows around, so even if the window
1592 * is in the correct position from X's point of view,
1593 * the underlying window system may want to reorder it.
1595 else if (pWin
->drawable
.pScreen
->RestackWindow
)
1596 (*pWin
->drawable
.pScreen
->RestackWindow
) (pWin
, pWin
->nextSib
);
1599 return pFirstChange
;
1603 SetWinSize(WindowPtr pWin
)
1606 if (pWin
->redirectDraw
!= RedirectDrawNone
) {
1610 * Redirected clients get clip list equal to their
1611 * own geometry, not clipped to their parent
1613 box
.x1
= pWin
->drawable
.x
;
1614 box
.y1
= pWin
->drawable
.y
;
1615 box
.x2
= pWin
->drawable
.x
+ pWin
->drawable
.width
;
1616 box
.y2
= pWin
->drawable
.y
+ pWin
->drawable
.height
;
1617 RegionReset(&pWin
->winSize
, &box
);
1621 ClippedRegionFromBox(pWin
->parent
, &pWin
->winSize
,
1622 pWin
->drawable
.x
, pWin
->drawable
.y
,
1623 (int) pWin
->drawable
.width
,
1624 (int) pWin
->drawable
.height
);
1625 if (wBoundingShape(pWin
) || wClipShape(pWin
)) {
1626 RegionTranslate(&pWin
->winSize
, -pWin
->drawable
.x
, -pWin
->drawable
.y
);
1627 if (wBoundingShape(pWin
))
1628 RegionIntersect(&pWin
->winSize
, &pWin
->winSize
,
1629 wBoundingShape(pWin
));
1630 if (wClipShape(pWin
))
1631 RegionIntersect(&pWin
->winSize
, &pWin
->winSize
, wClipShape(pWin
));
1632 RegionTranslate(&pWin
->winSize
, pWin
->drawable
.x
, pWin
->drawable
.y
);
1637 SetBorderSize(WindowPtr pWin
)
1641 if (HasBorder(pWin
)) {
1642 bw
= wBorderWidth(pWin
);
1644 if (pWin
->redirectDraw
!= RedirectDrawNone
) {
1648 * Redirected clients get clip list equal to their
1649 * own geometry, not clipped to their parent
1651 box
.x1
= pWin
->drawable
.x
- bw
;
1652 box
.y1
= pWin
->drawable
.y
- bw
;
1653 box
.x2
= pWin
->drawable
.x
+ pWin
->drawable
.width
+ bw
;
1654 box
.y2
= pWin
->drawable
.y
+ pWin
->drawable
.height
+ bw
;
1655 RegionReset(&pWin
->borderSize
, &box
);
1659 ClippedRegionFromBox(pWin
->parent
, &pWin
->borderSize
,
1660 pWin
->drawable
.x
- bw
, pWin
->drawable
.y
- bw
,
1661 (int) (pWin
->drawable
.width
+ (bw
<< 1)),
1662 (int) (pWin
->drawable
.height
+ (bw
<< 1)));
1663 if (wBoundingShape(pWin
)) {
1664 RegionTranslate(&pWin
->borderSize
, -pWin
->drawable
.x
,
1666 RegionIntersect(&pWin
->borderSize
, &pWin
->borderSize
,
1667 wBoundingShape(pWin
));
1668 RegionTranslate(&pWin
->borderSize
, pWin
->drawable
.x
,
1670 RegionUnion(&pWin
->borderSize
, &pWin
->borderSize
, &pWin
->winSize
);
1674 RegionCopy(&pWin
->borderSize
, &pWin
->winSize
);
1680 * \param x,y new window position
1681 * \param oldx,oldy old window position
1682 * \param destx,desty position relative to gravity
1686 GravityTranslate(int x
, int y
, int oldx
, int oldy
,
1687 int dw
, int dh
, unsigned gravity
, int *destx
, int *desty
)
1691 *destx
= x
+ dw
/ 2;
1694 case NorthEastGravity
:
1700 *desty
= y
+ dh
/ 2;
1703 *destx
= x
+ dw
/ 2;
1704 *desty
= y
+ dh
/ 2;
1708 *desty
= y
+ dh
/ 2;
1710 case SouthWestGravity
:
1715 *destx
= x
+ dw
/ 2;
1718 case SouthEastGravity
:
1733 /* XXX need to retile border on each window with ParentRelative origin */
1735 ResizeChildrenWinSize(WindowPtr pWin
, int dx
, int dy
, int dw
, int dh
)
1738 WindowPtr pSib
, pChild
;
1739 Bool resized
= (dw
|| dh
);
1741 pScreen
= pWin
->drawable
.pScreen
;
1743 for (pSib
= pWin
->firstChild
; pSib
; pSib
= pSib
->nextSib
) {
1744 if (resized
&& (pSib
->winGravity
> NorthWestGravity
)) {
1747 cwsx
= pSib
->origin
.x
;
1748 cwsy
= pSib
->origin
.y
;
1749 GravityTranslate(cwsx
, cwsy
, cwsx
- dx
, cwsy
- dy
, dw
, dh
,
1750 pSib
->winGravity
, &cwsx
, &cwsy
);
1751 if (cwsx
!= pSib
->origin
.x
|| cwsy
!= pSib
->origin
.y
) {
1753 .u
.gravity
.window
= pSib
->drawable
.id
,
1754 .u
.gravity
.x
= cwsx
- wBorderWidth(pSib
),
1755 .u
.gravity
.y
= cwsy
- wBorderWidth(pSib
)
1757 event
.u
.u
.type
= GravityNotify
;
1758 DeliverEvents(pSib
, &event
, 1, NullWindow
);
1759 pSib
->origin
.x
= cwsx
;
1760 pSib
->origin
.y
= cwsy
;
1763 pSib
->drawable
.x
= pWin
->drawable
.x
+ pSib
->origin
.x
;
1764 pSib
->drawable
.y
= pWin
->drawable
.y
+ pSib
->origin
.y
;
1766 SetBorderSize(pSib
);
1767 (*pScreen
->PositionWindow
) (pSib
, pSib
->drawable
.x
, pSib
->drawable
.y
);
1769 if ((pChild
= pSib
->firstChild
)) {
1771 pChild
->drawable
.x
= pChild
->parent
->drawable
.x
+
1773 pChild
->drawable
.y
= pChild
->parent
->drawable
.y
+
1776 SetBorderSize(pChild
);
1777 (*pScreen
->PositionWindow
) (pChild
,
1779 pChild
->drawable
.y
);
1780 if (pChild
->firstChild
) {
1781 pChild
= pChild
->firstChild
;
1784 while (!pChild
->nextSib
&& (pChild
!= pSib
))
1785 pChild
= pChild
->parent
;
1788 pChild
= pChild
->nextSib
;
1794 #define GET_INT16(m, f) \
1797 f = (INT16) *pVlist;\
1800 #define GET_CARD16(m, f) \
1803 f = (CARD16) *pVlist;\
1807 #define GET_CARD8(m, f) \
1810 f = (CARD8) *pVlist;\
1814 #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
1816 #define IllegalInputOnlyConfigureMask (CWBorderWidth)
1820 * returns Above if pSib above pMe in stack or Below otherwise
1824 IsSiblingAboveMe(WindowPtr pMe
, WindowPtr pSib
)
1828 pWin
= pMe
->parent
->firstChild
;
1832 else if (pWin
== pMe
)
1834 pWin
= pWin
->nextSib
;
1840 WindowExtents(WindowPtr pWin
, BoxPtr pBox
)
1842 pBox
->x1
= pWin
->drawable
.x
- wBorderWidth(pWin
);
1843 pBox
->y1
= pWin
->drawable
.y
- wBorderWidth(pWin
);
1844 pBox
->x2
= pWin
->drawable
.x
+ (int) pWin
->drawable
.width
1845 + wBorderWidth(pWin
);
1846 pBox
->y2
= pWin
->drawable
.y
+ (int) pWin
->drawable
.height
1847 + wBorderWidth(pWin
);
1851 #define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
1854 MakeBoundingRegion(WindowPtr pWin
, BoxPtr pBox
)
1856 RegionPtr pRgn
= RegionCreate(pBox
, 1);
1858 if (wBoundingShape(pWin
)) {
1859 RegionTranslate(pRgn
, -pWin
->origin
.x
, -pWin
->origin
.y
);
1860 RegionIntersect(pRgn
, pRgn
, wBoundingShape(pWin
));
1861 RegionTranslate(pRgn
, pWin
->origin
.x
, pWin
->origin
.y
);
1867 ShapeOverlap(WindowPtr pWin
, BoxPtr pWinBox
, WindowPtr pSib
, BoxPtr pSibBox
)
1869 RegionPtr pWinRgn
, pSibRgn
;
1872 if (!IS_SHAPED(pWin
) && !IS_SHAPED(pSib
))
1874 pWinRgn
= MakeBoundingRegion(pWin
, pWinBox
);
1875 pSibRgn
= MakeBoundingRegion(pSib
, pSibBox
);
1876 RegionIntersect(pWinRgn
, pWinRgn
, pSibRgn
);
1877 ret
= RegionNotEmpty(pWinRgn
);
1878 RegionDestroy(pWinRgn
);
1879 RegionDestroy(pSibRgn
);
1884 AnyWindowOverlapsMe(WindowPtr pWin
, WindowPtr pHead
, BoxPtr box
)
1890 for (pSib
= pWin
->prevSib
; pSib
!= pHead
; pSib
= pSib
->prevSib
) {
1892 sbox
= WindowExtents(pSib
, &sboxrec
);
1893 if (BOXES_OVERLAP(sbox
, box
)
1894 && ShapeOverlap(pWin
, box
, pSib
, sbox
))
1902 IOverlapAnyWindow(WindowPtr pWin
, BoxPtr box
)
1908 for (pSib
= pWin
->nextSib
; pSib
; pSib
= pSib
->nextSib
) {
1910 sbox
= WindowExtents(pSib
, &sboxrec
);
1911 if (BOXES_OVERLAP(sbox
, box
)
1912 && ShapeOverlap(pWin
, box
, pSib
, sbox
))
1920 * WhereDoIGoInTheStack()
1921 * Given pWin and pSib and the relationshipe smode, return
1922 * the window that pWin should go ABOVE.
1923 * If a pSib is specified:
1924 * Above: pWin is placed just above pSib
1925 * Below: pWin is placed just below pSib
1926 * TopIf: if pSib occludes pWin, then pWin is placed
1927 * at the top of the stack
1928 * BottomIf: if pWin occludes pSib, then pWin is
1929 * placed at the bottom of the stack
1930 * Opposite: if pSib occludes pWin, then pWin is placed at the
1931 * top of the stack, else if pWin occludes pSib, then
1932 * pWin is placed at the bottom of the stack
1935 * Above: pWin is placed at the top of the stack
1936 * Below: pWin is placed at the bottom of the stack
1937 * TopIf: if any sibling occludes pWin, then pWin is placed at
1938 * the top of the stack
1939 * BottomIf: if pWin occludes any sibline, then pWin is placed at
1940 * the bottom of the stack
1941 * Opposite: if any sibling occludes pWin, then pWin is placed at
1942 * the top of the stack, else if pWin occludes any
1943 * sibling, then pWin is placed at the bottom of the stack
1948 WhereDoIGoInTheStack(WindowPtr pWin
,
1951 short y
, unsigned short w
, unsigned short h
, int smode
)
1954 WindowPtr pHead
, pFirst
;
1956 if ((pWin
== pWin
->parent
->firstChild
) && (pWin
== pWin
->parent
->lastChild
))
1957 return ((WindowPtr
) NULL
);
1958 pHead
= RealChildHead(pWin
->parent
);
1959 pFirst
= pHead
? pHead
->nextSib
: pWin
->parent
->firstChild
;
1962 box
.x2
= x
+ (int) w
;
1963 box
.y2
= y
+ (int) h
;
1968 else if (pWin
== pFirst
)
1969 return pWin
->nextSib
;
1974 if (pSib
->nextSib
!= pWin
)
1975 return pSib
->nextSib
;
1977 return pWin
->nextSib
;
1981 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
1982 return pWin
->nextSib
;
1984 if ((IsSiblingAboveMe(pWin
, pSib
) == Above
) &&
1985 (RegionContainsRect(&pSib
->borderSize
, &box
) != rgnOUT
))
1988 return pWin
->nextSib
;
1990 else if (AnyWindowOverlapsMe(pWin
, pHead
, &box
))
1993 return pWin
->nextSib
;
1995 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
1996 return pWin
->nextSib
;
1998 if ((IsSiblingAboveMe(pWin
, pSib
) == Below
) &&
1999 (RegionContainsRect(&pSib
->borderSize
, &box
) != rgnOUT
))
2002 return pWin
->nextSib
;
2004 else if (IOverlapAnyWindow(pWin
, &box
))
2007 return pWin
->nextSib
;
2009 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
2010 return pWin
->nextSib
;
2012 if (RegionContainsRect(&pSib
->borderSize
, &box
) != rgnOUT
) {
2013 if (IsSiblingAboveMe(pWin
, pSib
) == Above
)
2019 return pWin
->nextSib
;
2021 else if (AnyWindowOverlapsMe(pWin
, pHead
, &box
)) {
2022 /* If I'm occluded, I can't possibly be the first child
2023 * if (pWin == pWin->parent->firstChild)
2024 * return pWin->nextSib;
2028 else if (IOverlapAnyWindow(pWin
, &box
))
2031 return pWin
->nextSib
;
2034 /* should never happen; make something up. */
2035 return pWin
->nextSib
;
2041 ReflectStackChange(WindowPtr pWin
, WindowPtr pSib
, VTKind kind
)
2043 /* Note that pSib might be NULL */
2045 Bool WasViewable
= (Bool
) pWin
->viewable
;
2047 WindowPtr pFirstChange
;
2048 WindowPtr pLayerWin
;
2049 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
2051 /* if this is a root window, can't be restacked */
2055 pFirstChange
= MoveWindowInStack(pWin
, pSib
);
2058 anyMarked
= (*pScreen
->MarkOverlappedWindows
) (pWin
, pFirstChange
,
2060 if (pLayerWin
!= pWin
)
2061 pFirstChange
= pLayerWin
;
2063 (*pScreen
->ValidateTree
) (pLayerWin
->parent
, pFirstChange
, kind
);
2064 (*pScreen
->HandleExposures
) (pLayerWin
->parent
);
2066 if (anyMarked
&& pWin
->drawable
.pScreen
->PostValidateTree
)
2067 (*pScreen
->PostValidateTree
) (pLayerWin
->parent
, pFirstChange
,
2071 WindowsRestructured();
2079 ConfigureWindow(WindowPtr pWin
, Mask mask
, XID
*vlist
, ClientPtr client
)
2081 #define RESTACK_WIN 0
2083 #define RESIZE_WIN 2
2084 #define REBORDER_WIN 3
2085 WindowPtr pSib
= NullWindow
;
2086 WindowPtr pParent
= pWin
->parent
;
2090 short x
, y
, beforeX
, beforeY
;
2091 unsigned short w
= pWin
->drawable
.width
,
2092 h
= pWin
->drawable
.height
, bw
= pWin
->borderWidth
;
2093 int rc
, action
, smode
= Above
;
2095 if ((pWin
->drawable
.class == InputOnly
) &&
2096 (mask
& IllegalInputOnlyConfigureMask
))
2099 if ((mask
& CWSibling
) && !(mask
& CWStackMode
))
2105 x
= pWin
->drawable
.x
- pParent
->drawable
.x
- (int) bw
;
2106 y
= pWin
->drawable
.y
- pParent
->drawable
.y
- (int) bw
;
2109 x
= pWin
->drawable
.x
;
2110 y
= pWin
->drawable
.y
;
2114 action
= RESTACK_WIN
;
2115 if ((mask
& (CWX
| CWY
)) && (!(mask
& (CWHeight
| CWWidth
)))) {
2120 /* or should be resized */
2121 else if (mask
& (CWX
| CWY
| CWWidth
| CWHeight
)) {
2124 GET_CARD16(CWWidth
, w
);
2125 GET_CARD16(CWHeight
, h
);
2127 client
->errorValue
= 0;
2130 action
= RESIZE_WIN
;
2132 tmask
= mask
& ~ChangeMask
;
2134 index2
= (Mask
) lowbit(tmask
);
2138 GET_CARD16(CWBorderWidth
, bw
);
2141 sibwid
= (Window
) *pVlist
;
2143 rc
= dixLookupWindow(&pSib
, sibwid
, client
, DixGetAttrAccess
);
2144 if (rc
!= Success
) {
2145 client
->errorValue
= sibwid
;
2148 if (pSib
->parent
!= pParent
)
2154 GET_CARD8(CWStackMode
, smode
);
2155 if ((smode
!= TopIf
) && (smode
!= BottomIf
) &&
2156 (smode
!= Opposite
) && (smode
!= Above
) && (smode
!= Below
)) {
2157 client
->errorValue
= smode
;
2162 client
->errorValue
= mask
;
2166 /* root really can't be reconfigured, so just return */
2170 /* Figure out if the window should be moved. Doesnt
2171 make the changes to the window if event sent */
2173 if (mask
& CWStackMode
)
2174 pSib
= WhereDoIGoInTheStack(pWin
, pSib
, pParent
->drawable
.x
+ x
,
2175 pParent
->drawable
.y
+ y
,
2176 w
+ (bw
<< 1), h
+ (bw
<< 1), smode
);
2178 pSib
= pWin
->nextSib
;
2180 if ((!pWin
->overrideRedirect
) && (RedirectSend(pParent
))) {
2182 .u
.configureRequest
.window
= pWin
->drawable
.id
,
2183 .u
.configureRequest
.sibling
= (mask
& CWSibling
) ? sibwid
: None
,
2184 .u
.configureRequest
.x
= x
,
2185 .u
.configureRequest
.y
= y
,
2186 .u
.configureRequest
.width
= w
,
2187 .u
.configureRequest
.height
= h
,
2188 .u
.configureRequest
.borderWidth
= bw
,
2189 .u
.configureRequest
.valueMask
= mask
,
2190 .u
.configureRequest
.parent
= pParent
->drawable
.id
2192 event
.u
.u
.type
= ConfigureRequest
;
2193 event
.u
.u
.detail
= (mask
& CWStackMode
) ? smode
: Above
;
2195 if (!noPanoramiXExtension
&& (!pParent
|| !pParent
->parent
)) {
2196 event
.u
.configureRequest
.x
+= screenInfo
.screens
[0]->x
;
2197 event
.u
.configureRequest
.y
+= screenInfo
.screens
[0]->y
;
2200 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2201 SubstructureRedirectMask
, client
) == 1)
2204 if (action
== RESIZE_WIN
) {
2205 Bool size_change
= (w
!= pWin
->drawable
.width
)
2206 || (h
!= pWin
->drawable
.height
);
2209 ((pWin
->eventMask
| wOtherEventMasks(pWin
)) & ResizeRedirectMask
)) {
2211 .u
.resizeRequest
.window
= pWin
->drawable
.id
,
2212 .u
.resizeRequest
.width
= w
,
2213 .u
.resizeRequest
.height
= h
2215 eventT
.u
.u
.type
= ResizeRequest
;
2216 if (MaybeDeliverEventsToClient(pWin
, &eventT
, 1,
2217 ResizeRedirectMask
, client
) == 1) {
2218 /* if event is delivered, leave the actual size alone. */
2219 w
= pWin
->drawable
.width
;
2220 h
= pWin
->drawable
.height
;
2221 size_change
= FALSE
;
2225 if (mask
& (CWX
| CWY
))
2227 else if (mask
& (CWStackMode
| CWBorderWidth
))
2228 action
= RESTACK_WIN
;
2229 else /* really nothing to do */
2234 if (action
== RESIZE_WIN
)
2235 /* we've already checked whether there's really a size change */
2236 goto ActuallyDoSomething
;
2237 if ((mask
& CWX
) && (x
!= beforeX
))
2238 goto ActuallyDoSomething
;
2239 if ((mask
& CWY
) && (y
!= beforeY
))
2240 goto ActuallyDoSomething
;
2241 if ((mask
& CWBorderWidth
) && (bw
!= wBorderWidth(pWin
)))
2242 goto ActuallyDoSomething
;
2243 if (mask
& CWStackMode
) {
2245 /* See above for why we always reorder in rootless mode. */
2246 if (pWin
->nextSib
!= pSib
)
2248 goto ActuallyDoSomething
;
2252 ActuallyDoSomething
:
2253 if (pWin
->drawable
.pScreen
->ConfigNotify
) {
2257 (*pWin
->drawable
.pScreen
->ConfigNotify
) (pWin
, x
, y
, w
, h
, bw
,
2260 client
->errorValue
= 0;
2265 if (SubStrSend(pWin
, pParent
)) {
2267 .u
.configureNotify
.window
= pWin
->drawable
.id
,
2268 .u
.configureNotify
.aboveSibling
= pSib
? pSib
->drawable
.id
: None
,
2269 .u
.configureNotify
.x
= x
,
2270 .u
.configureNotify
.y
= y
,
2271 .u
.configureNotify
.width
= w
,
2272 .u
.configureNotify
.height
= h
,
2273 .u
.configureNotify
.borderWidth
= bw
,
2274 .u
.configureNotify
.override
= pWin
->overrideRedirect
2276 event
.u
.u
.type
= ConfigureNotify
;
2278 if (!noPanoramiXExtension
&& (!pParent
|| !pParent
->parent
)) {
2279 event
.u
.configureNotify
.x
+= screenInfo
.screens
[0]->x
;
2280 event
.u
.configureNotify
.y
+= screenInfo
.screens
[0]->y
;
2283 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2285 if (mask
& CWBorderWidth
) {
2286 if (action
== RESTACK_WIN
) {
2288 pWin
->borderWidth
= bw
;
2290 else if ((action
== MOVE_WIN
) &&
2291 (beforeX
+ wBorderWidth(pWin
) == x
+ (int) bw
) &&
2292 (beforeY
+ wBorderWidth(pWin
) == y
+ (int) bw
)) {
2293 action
= REBORDER_WIN
;
2294 (*pWin
->drawable
.pScreen
->ChangeBorderWidth
) (pWin
, bw
);
2297 pWin
->borderWidth
= bw
;
2299 if (action
== MOVE_WIN
)
2300 (*pWin
->drawable
.pScreen
->MoveWindow
) (pWin
, x
, y
, pSib
,
2301 (mask
& CWBorderWidth
) ? VTOther
2303 else if (action
== RESIZE_WIN
)
2304 (*pWin
->drawable
.pScreen
->ResizeWindow
) (pWin
, x
, y
, w
, h
, pSib
);
2305 else if (mask
& CWStackMode
)
2306 ReflectStackChange(pWin
, pSib
, VTOther
);
2308 if (action
!= RESTACK_WIN
)
2309 CheckCursorConfinement(pWin
);
2320 * For RaiseLowest, raises the lowest mapped child (if any) that is
2321 * obscured by another child to the top of the stack. For LowerHighest,
2322 * lowers the highest mapped child (if any) that is obscuring another
2323 * child to the bottom of the stack. Exposure processing is performed
2328 CirculateWindow(WindowPtr pParent
, int direction
, ClientPtr client
)
2330 WindowPtr pWin
, pHead
, pFirst
;
2334 pHead
= RealChildHead(pParent
);
2335 pFirst
= pHead
? pHead
->nextSib
: pParent
->firstChild
;
2336 if (direction
== RaiseLowest
) {
2337 for (pWin
= pParent
->lastChild
;
2340 AnyWindowOverlapsMe(pWin
, pHead
, WindowExtents(pWin
, &box
)));
2341 pWin
= pWin
->prevSib
);
2349 IOverlapAnyWindow(pWin
, WindowExtents(pWin
, &box
)));
2350 pWin
= pWin
->nextSib
);
2356 .u
.circulate
.window
= pWin
->drawable
.id
,
2357 .u
.circulate
.parent
= pParent
->drawable
.id
,
2358 .u
.circulate
.event
= pParent
->drawable
.id
,
2359 .u
.circulate
.place
= (direction
== RaiseLowest
) ?
2360 PlaceOnTop
: PlaceOnBottom
,
2363 if (RedirectSend(pParent
)) {
2364 event
.u
.u
.type
= CirculateRequest
;
2365 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2366 SubstructureRedirectMask
, client
) == 1)
2370 event
.u
.u
.type
= CirculateNotify
;
2371 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2372 ReflectStackChange(pWin
,
2373 (direction
== RaiseLowest
) ? pFirst
: NullWindow
,
2380 CompareWIDs(WindowPtr pWin
, pointer value
)
2381 { /* must conform to VisitWindowProcPtr */
2382 Window
*wid
= (Window
*) value
;
2384 if (pWin
->drawable
.id
== *wid
)
2385 return WT_STOPWALKING
;
2387 return WT_WALKCHILDREN
;
2395 ReparentWindow(WindowPtr pWin
, WindowPtr pParent
,
2396 int x
, int y
, ClientPtr client
)
2398 WindowPtr pPrev
, pPriorParent
;
2399 Bool WasMapped
= (Bool
) (pWin
->mapped
);
2401 int bw
= wBorderWidth(pWin
);
2404 pScreen
= pWin
->drawable
.pScreen
;
2405 if (TraverseTree(pWin
, CompareWIDs
, (pointer
) &pParent
->drawable
.id
) ==
2408 if (!MakeWindowOptional(pWin
))
2412 UnmapWindow(pWin
, FALSE
);
2415 .u
.reparent
.window
= pWin
->drawable
.id
,
2416 .u
.reparent
.parent
= pParent
->drawable
.id
,
2419 .u
.reparent
.override
= pWin
->overrideRedirect
2421 event
.u
.u
.type
= ReparentNotify
;
2423 if (!noPanoramiXExtension
&& !pParent
->parent
) {
2424 event
.u
.reparent
.x
+= screenInfo
.screens
[0]->x
;
2425 event
.u
.reparent
.y
+= screenInfo
.screens
[0]->y
;
2428 DeliverEvents(pWin
, &event
, 1, pParent
);
2430 /* take out of sibling chain */
2432 pPriorParent
= pPrev
= pWin
->parent
;
2433 if (pPrev
->firstChild
== pWin
)
2434 pPrev
->firstChild
= pWin
->nextSib
;
2435 if (pPrev
->lastChild
== pWin
)
2436 pPrev
->lastChild
= pWin
->prevSib
;
2439 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
2441 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
2443 /* insert at begining of pParent */
2444 pWin
->parent
= pParent
;
2445 pPrev
= RealChildHead(pParent
);
2447 pWin
->nextSib
= pPrev
->nextSib
;
2449 pPrev
->nextSib
->prevSib
= pWin
;
2451 pParent
->lastChild
= pWin
;
2452 pPrev
->nextSib
= pWin
;
2453 pWin
->prevSib
= pPrev
;
2456 pWin
->nextSib
= pParent
->firstChild
;
2457 pWin
->prevSib
= NullWindow
;
2458 if (pParent
->firstChild
)
2459 pParent
->firstChild
->prevSib
= pWin
;
2461 pParent
->lastChild
= pWin
;
2462 pParent
->firstChild
= pWin
;
2465 pWin
->origin
.x
= x
+ bw
;
2466 pWin
->origin
.y
= y
+ bw
;
2467 pWin
->drawable
.x
= x
+ bw
+ pParent
->drawable
.x
;
2468 pWin
->drawable
.y
= y
+ bw
+ pParent
->drawable
.y
;
2470 /* clip to parent */
2472 SetBorderSize(pWin
);
2474 if (pScreen
->ReparentWindow
)
2475 (*pScreen
->ReparentWindow
) (pWin
, pPriorParent
);
2476 (*pScreen
->PositionWindow
) (pWin
, pWin
->drawable
.x
, pWin
->drawable
.y
);
2477 ResizeChildrenWinSize(pWin
, 0, 0, 0, 0);
2479 CheckWindowOptionalNeed(pWin
);
2482 MapWindow(pWin
, client
);
2483 RecalculateDeliverableEvents(pWin
);
2488 RealizeTree(WindowPtr pWin
)
2491 RealizeWindowProcPtr Realize
;
2493 Realize
= pWin
->drawable
.pScreen
->RealizeWindow
;
2496 if (pChild
->mapped
) {
2497 pChild
->realized
= TRUE
;
2498 pChild
->viewable
= (pChild
->drawable
.class == InputOutput
);
2499 (*Realize
) (pChild
);
2500 if (pChild
->firstChild
) {
2501 pChild
= pChild
->firstChild
;
2505 while (!pChild
->nextSib
&& (pChild
!= pWin
))
2506 pChild
= pChild
->parent
;
2509 pChild
= pChild
->nextSib
;
2514 MaybeDeliverMapRequest(WindowPtr pWin
, WindowPtr pParent
, ClientPtr client
)
2517 .u
.mapRequest
.window
= pWin
->drawable
.id
,
2518 .u
.mapRequest
.parent
= pParent
->drawable
.id
2520 event
.u
.u
.type
= MapRequest
;
2522 return MaybeDeliverEventsToClient(pParent
, &event
, 1,
2523 SubstructureRedirectMask
,
2528 DeliverMapNotify(WindowPtr pWin
)
2531 .u
.mapNotify
.window
= pWin
->drawable
.id
,
2532 .u
.mapNotify
.override
= pWin
->overrideRedirect
,
2534 event
.u
.u
.type
= MapNotify
;
2535 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2540 * If some other client has selected SubStructureReDirect on the parent
2541 * and override-redirect is xFalse, then a MapRequest event is generated,
2542 * but the window remains unmapped. Otherwise, the window is mapped and a
2543 * MapNotify event is generated.
2547 MapWindow(WindowPtr pWin
, ClientPtr client
)
2552 WindowPtr pLayerWin
;
2557 /* general check for permission to map window */
2558 if (XaceHook(XACE_RESOURCE_ACCESS
, client
, pWin
->drawable
.id
, RT_WINDOW
,
2559 pWin
, RT_NONE
, NULL
, DixShowAccess
) != Success
)
2562 pScreen
= pWin
->drawable
.pScreen
;
2563 if ((pParent
= pWin
->parent
)) {
2566 if ((!pWin
->overrideRedirect
) && (RedirectSend(pParent
)))
2567 if (MaybeDeliverMapRequest(pWin
, pParent
, client
))
2570 pWin
->mapped
= TRUE
;
2571 if (SubStrSend(pWin
, pParent
))
2572 DeliverMapNotify(pWin
);
2574 if (!pParent
->realized
)
2577 if (pWin
->viewable
) {
2578 anyMarked
= (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
,
2581 (*pScreen
->ValidateTree
) (pLayerWin
->parent
, pLayerWin
, VTMap
);
2582 (*pScreen
->HandleExposures
) (pLayerWin
->parent
);
2584 if (anyMarked
&& pScreen
->PostValidateTree
)
2585 (*pScreen
->PostValidateTree
) (pLayerWin
->parent
, pLayerWin
,
2588 WindowsRestructured();
2593 pWin
->mapped
= TRUE
;
2594 pWin
->realized
= TRUE
; /* for roots */
2595 pWin
->viewable
= pWin
->drawable
.class == InputOutput
;
2596 /* We SHOULD check for an error value here XXX */
2597 (*pScreen
->RealizeWindow
) (pWin
);
2598 if (pScreen
->ClipNotify
)
2599 (*pScreen
->ClipNotify
) (pWin
, 0, 0);
2600 if (pScreen
->PostValidateTree
)
2601 (*pScreen
->PostValidateTree
) (NullWindow
, pWin
, VTMap
);
2603 RegionCopy(&temp
, &pWin
->clipList
);
2604 (*pScreen
->WindowExposures
) (pWin
, &temp
, NullRegion
);
2605 RegionUninit(&temp
);
2613 * Performs a MapWindow all unmapped children of the window, in top
2614 * to bottom stacking order.
2618 MapSubwindows(WindowPtr pParent
, ClientPtr client
)
2621 WindowPtr pFirstMapped
= NullWindow
;
2623 Mask parentRedirect
;
2626 WindowPtr pLayerWin
;
2628 pScreen
= pParent
->drawable
.pScreen
;
2629 parentRedirect
= RedirectSend(pParent
);
2630 parentNotify
= SubSend(pParent
);
2632 for (pWin
= pParent
->firstChild
; pWin
; pWin
= pWin
->nextSib
) {
2633 if (!pWin
->mapped
) {
2634 if (parentRedirect
&& !pWin
->overrideRedirect
)
2635 if (MaybeDeliverMapRequest(pWin
, pParent
, client
))
2638 pWin
->mapped
= TRUE
;
2639 if (parentNotify
|| StrSend(pWin
))
2640 DeliverMapNotify(pWin
);
2643 pFirstMapped
= pWin
;
2644 if (pParent
->realized
) {
2646 if (pWin
->viewable
) {
2647 anyMarked
|= (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
,
2656 pLayerWin
= (*pScreen
->GetLayerWindow
) (pParent
);
2657 if (pLayerWin
->parent
!= pParent
) {
2658 anyMarked
|= (*pScreen
->MarkOverlappedWindows
) (pLayerWin
,
2660 (WindowPtr
*) NULL
);
2661 pFirstMapped
= pLayerWin
;
2664 (*pScreen
->ValidateTree
) (pLayerWin
->parent
, pFirstMapped
, VTMap
);
2665 (*pScreen
->HandleExposures
) (pLayerWin
->parent
);
2667 if (anyMarked
&& pScreen
->PostValidateTree
)
2668 (*pScreen
->PostValidateTree
) (pLayerWin
->parent
, pFirstMapped
,
2670 WindowsRestructured();
2675 UnrealizeTree(WindowPtr pWin
, Bool fromConfigure
)
2678 UnrealizeWindowProcPtr Unrealize
;
2679 MarkUnrealizedWindowProcPtr MarkUnrealizedWindow
;
2681 Unrealize
= pWin
->drawable
.pScreen
->UnrealizeWindow
;
2682 MarkUnrealizedWindow
= pWin
->drawable
.pScreen
->MarkUnrealizedWindow
;
2685 if (pChild
->realized
) {
2686 pChild
->realized
= FALSE
;
2687 pChild
->visibility
= VisibilityNotViewable
;
2689 if (!noPanoramiXExtension
&& !pChild
->drawable
.pScreen
->myNum
) {
2691 int rc
= dixLookupResourceByType((pointer
*) &win
,
2692 pChild
->drawable
.id
,
2694 serverClient
, DixWriteAccess
);
2697 win
->u
.win
.visibility
= VisibilityNotViewable
;
2700 (*Unrealize
) (pChild
);
2701 DeleteWindowFromAnyEvents(pChild
, FALSE
);
2702 if (pChild
->viewable
) {
2703 pChild
->viewable
= FALSE
;
2704 (*MarkUnrealizedWindow
) (pChild
, pWin
, fromConfigure
);
2705 pChild
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
2707 if (pChild
->firstChild
) {
2708 pChild
= pChild
->firstChild
;
2712 while (!pChild
->nextSib
&& (pChild
!= pWin
))
2713 pChild
= pChild
->parent
;
2716 pChild
= pChild
->nextSib
;
2721 DeliverUnmapNotify(WindowPtr pWin
, Bool fromConfigure
)
2724 .u
.unmapNotify
.window
= pWin
->drawable
.id
,
2725 .u
.unmapNotify
.fromConfigure
= fromConfigure
2727 event
.u
.u
.type
= UnmapNotify
;
2728 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2733 * If the window is already unmapped, this request has no effect.
2734 * Otherwise, the window is unmapped and an UnMapNotify event is
2735 * generated. Cannot unmap a root window.
2739 UnmapWindow(WindowPtr pWin
, Bool fromConfigure
)
2742 Bool wasRealized
= (Bool
) pWin
->realized
;
2743 Bool wasViewable
= (Bool
) pWin
->viewable
;
2744 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
2745 WindowPtr pLayerWin
= pWin
;
2747 if ((!pWin
->mapped
) || (!(pParent
= pWin
->parent
)))
2749 if (SubStrSend(pWin
, pParent
))
2750 DeliverUnmapNotify(pWin
, fromConfigure
);
2751 if (wasViewable
&& !fromConfigure
) {
2752 pWin
->valdata
= UnmapValData
;
2753 (*pScreen
->MarkOverlappedWindows
) (pWin
, pWin
->nextSib
, &pLayerWin
);
2754 (*pScreen
->MarkWindow
) (pLayerWin
->parent
);
2756 pWin
->mapped
= FALSE
;
2758 UnrealizeTree(pWin
, fromConfigure
);
2760 if (!fromConfigure
) {
2761 (*pScreen
->ValidateTree
) (pLayerWin
->parent
, pWin
, VTUnmap
);
2762 (*pScreen
->HandleExposures
) (pLayerWin
->parent
);
2764 if (!fromConfigure
&& pScreen
->PostValidateTree
)
2765 (*pScreen
->PostValidateTree
) (pLayerWin
->parent
, pWin
, VTUnmap
);
2767 if (wasRealized
&& !fromConfigure
) {
2768 WindowsRestructured();
2776 * Performs an UnmapWindow request with the specified mode on all mapped
2777 * children of the window, in bottom to top stacking order.
2781 UnmapSubwindows(WindowPtr pWin
)
2783 WindowPtr pChild
, pHead
;
2784 Bool wasRealized
= (Bool
) pWin
->realized
;
2785 Bool wasViewable
= (Bool
) pWin
->viewable
;
2786 Bool anyMarked
= FALSE
;
2788 WindowPtr pLayerWin
= NULL
;
2789 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
2791 if (!pWin
->firstChild
)
2793 parentNotify
= SubSend(pWin
);
2794 pHead
= RealChildHead(pWin
);
2797 pLayerWin
= (*pScreen
->GetLayerWindow
) (pWin
);
2799 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
) {
2800 if (pChild
->mapped
) {
2801 if (parentNotify
|| StrSend(pChild
))
2802 DeliverUnmapNotify(pChild
, xFalse
);
2803 if (pChild
->viewable
) {
2804 pChild
->valdata
= UnmapValData
;
2807 pChild
->mapped
= FALSE
;
2808 if (pChild
->realized
)
2809 UnrealizeTree(pChild
, FALSE
);
2816 if (pLayerWin
->parent
== pWin
)
2817 (*pScreen
->MarkWindow
) (pWin
);
2821 (*pScreen
->MarkOverlappedWindows
) (pWin
, pLayerWin
,
2822 (WindowPtr
*) NULL
);
2823 (*pScreen
->MarkWindow
) (pLayerWin
->parent
);
2825 /* Windows between pWin and pLayerWin may not have been marked */
2828 while (ptmp
!= pLayerWin
->parent
) {
2829 (*pScreen
->MarkWindow
) (ptmp
);
2830 ptmp
= ptmp
->parent
;
2832 pHead
= pWin
->firstChild
;
2834 (*pScreen
->ValidateTree
) (pLayerWin
->parent
, pHead
, VTUnmap
);
2835 (*pScreen
->HandleExposures
) (pLayerWin
->parent
);
2837 if (anyMarked
&& pScreen
->PostValidateTree
)
2838 (*pScreen
->PostValidateTree
) (pLayerWin
->parent
, pHead
, VTUnmap
);
2841 WindowsRestructured();
2847 HandleSaveSet(ClientPtr client
)
2849 WindowPtr pParent
, pWin
;
2852 for (j
= 0; j
< client
->numSaved
; j
++) {
2853 pWin
= SaveSetWindow(client
->saveSet
[j
]);
2854 if (SaveSetToRoot(client
->saveSet
[j
]))
2855 pParent
= pWin
->drawable
.pScreen
->root
;
2858 pParent
= pWin
->parent
;
2859 while (pParent
&& (wClient(pParent
) == client
))
2860 pParent
= pParent
->parent
;
2863 if (pParent
!= pWin
->parent
) {
2864 /* unmap first so that ReparentWindow doesn't remap */
2865 if (!SaveSetShouldMap(client
->saveSet
[j
]))
2866 UnmapWindow(pWin
, FALSE
);
2867 ReparentWindow(pWin
, pParent
,
2868 pWin
->drawable
.x
- wBorderWidth(pWin
) -
2869 pParent
->drawable
.x
,
2870 pWin
->drawable
.y
- wBorderWidth(pWin
) -
2871 pParent
->drawable
.y
, client
);
2872 if (!pWin
->realized
&& pWin
->mapped
)
2873 pWin
->mapped
= FALSE
;
2875 if (SaveSetShouldMap(client
->saveSet
[j
]))
2876 MapWindow(pWin
, client
);
2879 free(client
->saveSet
);
2880 client
->numSaved
= 0;
2881 client
->saveSet
= (SaveSetElt
*) NULL
;
2886 * \param x,y in root
2889 PointInWindowIsVisible(WindowPtr pWin
, int x
, int y
)
2893 if (!pWin
->realized
)
2895 if (RegionContainsPoint(&pWin
->borderClip
, x
, y
, &box
)
2896 && (!wInputShape(pWin
) ||
2897 RegionContainsPoint(wInputShape(pWin
),
2898 x
- pWin
->drawable
.x
,
2899 y
- pWin
->drawable
.y
, &box
)))
2905 NotClippedByChildren(WindowPtr pWin
)
2907 RegionPtr pReg
= RegionCreate(NullBox
, 1);
2910 screenIsSaved
!= SCREEN_SAVER_ON
||
2911 !HasSaverWindow(pWin
->drawable
.pScreen
)) {
2912 RegionIntersect(pReg
, &pWin
->borderClip
, &pWin
->winSize
);
2918 SendVisibilityNotify(WindowPtr pWin
)
2921 unsigned int visibility
= pWin
->visibility
;
2924 /* This is not quite correct yet, but it's close */
2925 if (!noPanoramiXExtension
) {
2930 Scrnum
= pWin
->drawable
.pScreen
->myNum
;
2932 win
= PanoramiXFindIDByScrnum(XRT_WINDOW
, pWin
->drawable
.id
, Scrnum
);
2934 if (!win
|| (win
->u
.win
.visibility
== visibility
))
2937 switch (visibility
) {
2938 case VisibilityUnobscured
:
2943 rc
= dixLookupWindow(&pWin2
, win
->info
[i
].id
, serverClient
,
2946 if (rc
== Success
) {
2947 if (pWin2
->visibility
== VisibilityPartiallyObscured
)
2955 case VisibilityPartiallyObscured
:
2957 rc
= dixLookupWindow(&pWin2
, win
->info
[0].id
, serverClient
,
2963 case VisibilityFullyObscured
:
2968 rc
= dixLookupWindow(&pWin2
, win
->info
[i
].id
, serverClient
,
2971 if (rc
== Success
) {
2972 if (pWin2
->visibility
!= VisibilityFullyObscured
)
2982 win
->u
.win
.visibility
= visibility
;
2987 .u
.visibility
.window
= pWin
->drawable
.id
,
2988 .u
.visibility
.state
= visibility
2990 event
.u
.u
.type
= VisibilityNotify
;
2991 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2994 #define RANDOM_WIDTH 32
2996 dixSaveScreens(ClientPtr client
, int on
, int mode
)
2998 int rc
, i
, what
, type
;
3000 if (on
== SCREEN_SAVER_FORCER
) {
3001 if (mode
== ScreenSaverReset
)
3002 what
= SCREEN_SAVER_OFF
;
3004 what
= SCREEN_SAVER_ON
;
3010 if (what
== screenIsSaved
)
3011 type
= SCREEN_SAVER_CYCLE
;
3014 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
3015 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, screenInfo
.screens
[i
],
3016 DixShowAccess
| DixHideAccess
);
3020 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
3021 ScreenPtr pScreen
= screenInfo
.screens
[i
];
3023 if (on
== SCREEN_SAVER_FORCER
)
3024 (*pScreen
->SaveScreen
) (pScreen
, on
);
3025 if (pScreen
->screensaver
.ExternalScreenSaver
) {
3026 if ((*pScreen
->screensaver
.ExternalScreenSaver
)
3027 (pScreen
, type
, on
== SCREEN_SAVER_FORCER
))
3030 if (type
== screenIsSaved
)
3033 case SCREEN_SAVER_OFF
:
3034 if (pScreen
->screensaver
.blanked
== SCREEN_IS_BLANKED
) {
3035 (*pScreen
->SaveScreen
) (pScreen
, what
);
3037 else if (HasSaverWindow(pScreen
)) {
3038 pScreen
->screensaver
.pWindow
= NullWindow
;
3039 FreeResource(pScreen
->screensaver
.wid
, RT_NONE
);
3042 case SCREEN_SAVER_CYCLE
:
3043 if (pScreen
->screensaver
.blanked
== SCREEN_IS_TILED
) {
3044 WindowPtr pWin
= pScreen
->screensaver
.pWindow
;
3046 /* make it look like screen saver is off, so that
3047 * NotClippedByChildren will compute a clip list
3048 * for the root window, so miPaintWindow works
3050 screenIsSaved
= SCREEN_SAVER_OFF
;
3051 (*pWin
->drawable
.pScreen
->MoveWindow
) (pWin
,
3058 pWin
->nextSib
, VTMove
);
3059 screenIsSaved
= SCREEN_SAVER_ON
;
3062 * Call the DDX saver in case it wants to do something
3065 else if (pScreen
->screensaver
.blanked
== SCREEN_IS_BLANKED
) {
3066 (*pScreen
->SaveScreen
) (pScreen
, type
);
3069 case SCREEN_SAVER_ON
:
3070 if (ScreenSaverBlanking
!= DontPreferBlanking
) {
3071 if ((*pScreen
->SaveScreen
) (pScreen
, what
)) {
3072 pScreen
->screensaver
.blanked
= SCREEN_IS_BLANKED
;
3075 if ((ScreenSaverAllowExposures
!= DontAllowExposures
) &&
3076 TileScreenSaver(pScreen
, SCREEN_IS_BLACK
)) {
3077 pScreen
->screensaver
.blanked
= SCREEN_IS_BLACK
;
3081 if ((ScreenSaverAllowExposures
!= DontAllowExposures
) &&
3082 TileScreenSaver(pScreen
, SCREEN_IS_TILED
)) {
3083 pScreen
->screensaver
.blanked
= SCREEN_IS_TILED
;
3086 pScreen
->screensaver
.blanked
= SCREEN_ISNT_SAVED
;
3090 screenIsSaved
= what
;
3091 if (mode
== ScreenSaverReset
) {
3092 if (on
== SCREEN_SAVER_FORCER
) {
3094 UpdateCurrentTimeIf();
3095 nt_list_for_each_entry(dev
, inputInfo
.devices
, next
)
3096 NoticeTime(dev
, currentTime
);
3098 SetScreenSaverTimer();
3104 SaveScreens(int on
, int mode
)
3106 return dixSaveScreens(serverClient
, on
, mode
);
3110 TileScreenSaver(ScreenPtr pScreen
, int kind
)
3118 unsigned char *srcbits
, *mskbits
;
3126 case SCREEN_IS_TILED
:
3127 switch (pScreen
->root
->backgroundState
) {
3128 case BackgroundPixel
:
3129 attributes
[attri
++] = pScreen
->root
->background
.pixel
;
3130 mask
|= CWBackPixel
;
3132 case BackgroundPixmap
:
3133 attributes
[attri
++] = None
;
3134 mask
|= CWBackPixmap
;
3140 case SCREEN_IS_BLACK
:
3141 attributes
[attri
++] = pScreen
->root
->drawable
.pScreen
->blackPixel
;
3142 mask
|= CWBackPixel
;
3145 mask
|= CWOverrideRedirect
;
3146 attributes
[attri
++] = xTrue
;
3149 * create a blank cursor
3156 srcbits
= malloc(BitmapBytePad(32) * 16);
3157 mskbits
= malloc(BitmapBytePad(32) * 16);
3158 if (!srcbits
|| !mskbits
) {
3164 for (j
= 0; j
< BitmapBytePad(32) * 16; j
++)
3165 srcbits
[j
] = mskbits
[j
] = 0x0;
3166 result
= AllocARGBCursor(srcbits
, mskbits
, NULL
, &cm
, 0, 0, 0, 0, 0, 0,
3167 &cursor
, serverClient
, (XID
) 0);
3169 cursorID
= FakeClientID(0);
3170 if (AddResource(cursorID
, RT_CURSOR
, (pointer
) cursor
)) {
3171 attributes
[attri
] = cursorID
;
3183 pWin
= pScreen
->screensaver
.pWindow
=
3184 CreateWindow(pScreen
->screensaver
.wid
,
3186 -RANDOM_WIDTH
, -RANDOM_WIDTH
,
3187 (unsigned short) pScreen
->width
+ RANDOM_WIDTH
,
3188 (unsigned short) pScreen
->height
+ RANDOM_WIDTH
,
3189 0, InputOutput
, mask
, attributes
, 0, serverClient
,
3190 wVisual(pScreen
->root
), &result
);
3193 FreeResource(cursorID
, RT_NONE
);
3198 if (!AddResource(pWin
->drawable
.id
, RT_WINDOW
,
3199 (pointer
) pScreen
->screensaver
.pWindow
))
3202 if (mask
& CWBackPixmap
) {
3204 (*pWin
->drawable
.pScreen
->ChangeWindowAttributes
) (pWin
, CWBackPixmap
);
3206 MapWindow(pWin
, serverClient
);
3211 * FindWindowWithOptional
3213 * search ancestors of the given window for an entry containing
3214 * a WindowOpt structure. Assumptions: some parent will
3215 * contain the structure.
3219 FindWindowWithOptional(WindowPtr w
)
3223 while (!w
->optional
);
3228 * CheckWindowOptionalNeed
3230 * check each optional entry in the given window to see if
3231 * the value is satisfied by the default rules. If so,
3232 * release the optional record
3236 CheckWindowOptionalNeed(WindowPtr w
)
3238 WindowOptPtr optional
;
3239 WindowOptPtr parentOptional
;
3241 if (!w
->parent
|| !w
->optional
)
3243 optional
= w
->optional
;
3244 if (optional
->dontPropagateMask
!= DontPropagateMasks
[w
->dontPropagate
])
3246 if (optional
->otherEventMasks
!= 0)
3248 if (optional
->otherClients
!= NULL
)
3250 if (optional
->passiveGrabs
!= NULL
)
3252 if (optional
->userProps
!= NULL
)
3254 if (optional
->backingBitPlanes
!= ~0L)
3256 if (optional
->backingPixel
!= 0)
3258 if (optional
->boundingShape
!= NULL
)
3260 if (optional
->clipShape
!= NULL
)
3262 if (optional
->inputShape
!= NULL
)
3264 if (optional
->inputMasks
!= NULL
)
3266 if (optional
->deviceCursors
!= NULL
) {
3267 DevCursNodePtr pNode
= optional
->deviceCursors
;
3270 if (pNode
->cursor
!= None
)
3272 pNode
= pNode
->next
;
3276 parentOptional
= FindWindowWithOptional(w
)->optional
;
3277 if (optional
->visual
!= parentOptional
->visual
)
3279 if (optional
->cursor
!= None
&&
3280 (optional
->cursor
!= parentOptional
->cursor
|| w
->parent
->cursorIsNone
))
3282 if (optional
->colormap
!= parentOptional
->colormap
)
3284 DisposeWindowOptional(w
);
3288 * MakeWindowOptional
3290 * create an optional record and initialize it with the default
3295 MakeWindowOptional(WindowPtr pWin
)
3297 WindowOptPtr optional
;
3298 WindowOptPtr parentOptional
;
3302 optional
= malloc(sizeof(WindowOptRec
));
3305 optional
->dontPropagateMask
= DontPropagateMasks
[pWin
->dontPropagate
];
3306 optional
->otherEventMasks
= 0;
3307 optional
->otherClients
= NULL
;
3308 optional
->passiveGrabs
= NULL
;
3309 optional
->userProps
= NULL
;
3310 optional
->backingBitPlanes
= ~0L;
3311 optional
->backingPixel
= 0;
3312 optional
->boundingShape
= NULL
;
3313 optional
->clipShape
= NULL
;
3314 optional
->inputShape
= NULL
;
3315 optional
->inputMasks
= NULL
;
3316 optional
->deviceCursors
= NULL
;
3318 parentOptional
= FindWindowWithOptional(pWin
)->optional
;
3319 optional
->visual
= parentOptional
->visual
;
3320 if (!pWin
->cursorIsNone
) {
3321 optional
->cursor
= RefCursor(parentOptional
->cursor
);
3324 optional
->cursor
= None
;
3326 optional
->colormap
= parentOptional
->colormap
;
3327 pWin
->optional
= optional
;
3332 * Changes the cursor struct for the given device and the given window.
3333 * A cursor that does not have a device cursor set will use whatever the
3334 * standard cursor is for the window. If all devices have a cursor set,
3335 * changing the window cursor (e.g. using XDefineCursor()) will not have any
3336 * visible effect. Only when one of the device cursors is set to None again,
3337 * this device's cursor will display the changed standard cursor.
3339 * CursorIsNone of the window struct is NOT modified if you set a device
3342 * Assumption: If there is a node for a device in the list, the device has a
3343 * cursor. If the cursor is set to None, it is inherited by the parent.
3346 ChangeWindowDeviceCursor(WindowPtr pWin
, DeviceIntPtr pDev
, CursorPtr pCursor
)
3348 DevCursNodePtr pNode
, pPrev
;
3349 CursorPtr pOldCursor
= NULL
;
3353 if (!pWin
->optional
&& !MakeWindowOptional(pWin
))
3356 /* 1) Check if window has device cursor set
3357 * Yes: 1.1) swap cursor with given cursor if parent does not have same
3358 * cursor, free old cursor
3359 * 1.2) free old cursor, use parent cursor
3360 * No: 1.1) add node to beginning of list.
3361 * 1.2) add cursor to node if parent does not have same cursor
3362 * 1.3) use parent cursor if parent does not have same cursor
3363 * 2) Patch up children if child has a devcursor
3364 * 2.1) if child has cursor None, it inherited from parent, set to old
3366 * 2.2) if child has same cursor as new cursor, remove and set to None
3369 pScreen
= pWin
->drawable
.pScreen
;
3371 if (WindowSeekDeviceCursor(pWin
, pDev
, &pNode
, &pPrev
)) {
3372 /* has device cursor */
3374 if (pNode
->cursor
== pCursor
)
3377 pOldCursor
= pNode
->cursor
;
3379 if (!pCursor
) { /* remove from list */
3381 pPrev
->next
= pNode
->next
;
3383 /* first item in list */
3384 pWin
->optional
->deviceCursors
= pNode
->next
;
3392 /* no device cursor yet */
3393 DevCursNodePtr pNewNode
;
3398 pNewNode
= malloc(sizeof(DevCursNodeRec
));
3399 pNewNode
->dev
= pDev
;
3400 pNewNode
->next
= pWin
->optional
->deviceCursors
;
3401 pWin
->optional
->deviceCursors
= pNewNode
;
3406 if (pCursor
&& WindowParentHasDeviceCursor(pWin
, pDev
, pCursor
))
3407 pNode
->cursor
= None
;
3409 pNode
->cursor
= RefCursor(pCursor
);
3412 pNode
= pPrev
= NULL
;
3413 /* fix up children */
3414 for (pChild
= pWin
->firstChild
; pChild
; pChild
= pChild
->nextSib
) {
3415 if (WindowSeekDeviceCursor(pChild
, pDev
, &pNode
, &pPrev
)) {
3416 if (pNode
->cursor
== None
) { /* inherited from parent */
3417 pNode
->cursor
= RefCursor(pOldCursor
);
3419 else if (pNode
->cursor
== pCursor
) {
3420 pNode
->cursor
= None
;
3421 FreeCursor(pCursor
, (Cursor
) 0); /* fix up refcnt */
3427 CursorVisible
= TRUE
;
3430 WindowHasNewCursor(pWin
);
3433 FreeCursor(pOldCursor
, (Cursor
) 0);
3435 /* FIXME: We SHOULD check for an error value here XXX
3436 (comment taken from ChangeWindowAttributes) */
3437 (*pScreen
->ChangeWindowAttributes
) (pWin
, CWCursor
);
3442 /* Get device cursor for given device or None if none is set */
3444 WindowGetDeviceCursor(WindowPtr pWin
, DeviceIntPtr pDev
)
3446 DevCursorList pList
;
3448 if (!pWin
->optional
|| !pWin
->optional
->deviceCursors
)
3451 pList
= pWin
->optional
->deviceCursors
;
3454 if (pList
->dev
== pDev
) {
3455 if (pList
->cursor
== None
) /* inherited from parent */
3456 return WindowGetDeviceCursor(pWin
->parent
, pDev
);
3458 return pList
->cursor
;
3460 pList
= pList
->next
;
3465 /* Searches for a DevCursorNode for the given window and device. If one is
3466 * found, return True and set pNode and pPrev to the node and to the node
3467 * before the node respectively. Otherwise return False.
3468 * If the device is the first in list, pPrev is set to NULL.
3471 WindowSeekDeviceCursor(WindowPtr pWin
,
3473 DevCursNodePtr
* pNode
, DevCursNodePtr
* pPrev
)
3475 DevCursorList pList
;
3477 if (!pWin
->optional
)
3480 pList
= pWin
->optional
->deviceCursors
;
3482 if (pList
&& pList
->dev
== pDev
) {
3490 if (pList
->next
->dev
== pDev
) {
3491 *pNode
= pList
->next
;
3496 pList
= pList
->next
;
3501 /* Return True if a parent has the same device cursor set or False if
3505 WindowParentHasDeviceCursor(WindowPtr pWin
,
3506 DeviceIntPtr pDev
, CursorPtr pCursor
)
3509 DevCursNodePtr pParentNode
, pParentPrev
;
3511 pParent
= pWin
->parent
;
3513 if (WindowSeekDeviceCursor(pParent
, pDev
, &pParentNode
, &pParentPrev
)) {
3514 /* if there is a node in the list, the win has a dev cursor */
3515 if (!pParentNode
->cursor
) /* inherited. */
3516 pParent
= pParent
->parent
;
3517 else if (pParentNode
->cursor
== pCursor
) /* inherit */
3519 else /* different cursor */
3523 /* parent does not have a device cursor for our device */
3531 * Enable or disable rendering to the screen by
3532 * setting the root clip list and revalidating
3533 * all of the windows
3536 SetRootClip(ScreenPtr pScreen
, Bool enable
)
3538 WindowPtr pWin
= pScreen
->root
;
3541 Bool anyMarked
= FALSE
;
3542 WindowPtr pLayerWin
;
3547 WasViewable
= (Bool
) (pWin
->viewable
);
3549 for (pChild
= pWin
->firstChild
; pChild
; pChild
= pChild
->nextSib
) {
3550 (void) (*pScreen
->MarkOverlappedWindows
) (pChild
,
3551 pChild
, &pLayerWin
);
3553 (*pScreen
->MarkWindow
) (pWin
);
3555 if (pWin
->valdata
) {
3556 if (HasBorder(pWin
)) {
3557 RegionPtr borderVisible
;
3559 borderVisible
= RegionCreate(NullBox
, 1);
3560 RegionSubtract(borderVisible
,
3561 &pWin
->borderClip
, &pWin
->winSize
);
3562 pWin
->valdata
->before
.borderVisible
= borderVisible
;
3564 pWin
->valdata
->before
.resized
= TRUE
;
3569 * Use REGION_BREAK to avoid optimizations in ValidateTree
3570 * that assume the root borderClip can't change well, normally
3576 box
.x2
= pScreen
->width
;
3577 box
.y2
= pScreen
->height
;
3578 RegionInit(&pWin
->winSize
, &box
, 1);
3579 RegionInit(&pWin
->borderSize
, &box
, 1);
3581 RegionReset(&pWin
->borderClip
, &box
);
3582 pWin
->drawable
.width
= pScreen
->width
;
3583 pWin
->drawable
.height
= pScreen
->height
;
3584 RegionBreak(&pWin
->clipList
);
3587 RegionEmpty(&pWin
->borderClip
);
3588 RegionBreak(&pWin
->clipList
);
3591 ResizeChildrenWinSize(pWin
, 0, 0, 0, 0);
3594 if (pWin
->firstChild
) {
3595 anyMarked
|= (*pScreen
->MarkOverlappedWindows
) (pWin
->firstChild
,
3597 (WindowPtr
*) NULL
);
3600 (*pScreen
->MarkWindow
) (pWin
);
3605 (*pScreen
->ValidateTree
) (pWin
, NullWindow
, VTOther
);
3610 (*pScreen
->HandleExposures
) (pWin
);
3611 if (anyMarked
&& pScreen
->PostValidateTree
)
3612 (*pScreen
->PostValidateTree
) (pWin
, NullWindow
, VTOther
);
3615 WindowsRestructured();
3620 WindowGetVisual(WindowPtr pWin
)
3622 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
3623 VisualID vid
= wVisual(pWin
);
3626 for (i
= 0; i
< pScreen
->numVisuals
; i
++)
3627 if (pScreen
->visuals
[i
].vid
== vid
)
3628 return &pScreen
->visuals
[i
];