3 Copyright (c) 2006, Red Hat, Inc.
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of Red Hat shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from Red Hat.
25 Copyright 1987, 1998 The Open Group
27 Permission to use, copy, modify, distribute, and sell this software and its
28 documentation for any purpose is hereby granted without fee, provided that
29 the above copyright notice appear in all copies and that both that
30 copyright notice and this permission notice appear in supporting
33 The above copyright notice and this permission notice shall be included
34 in all copies or substantial portions of the Software.
36 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
37 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
39 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
40 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
42 OTHER DEALINGS IN THE SOFTWARE.
44 Except as contained in this notice, the name of The Open Group shall
45 not be used in advertising or otherwise to promote the sale, use or
46 other dealings in this Software without prior written authorization
50 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
54 Permission to use, copy, modify, and distribute this software and its
55 documentation for any purpose and without fee is hereby granted,
56 provided that the above copyright notice appear in all copies and that
57 both that copyright notice and this permission notice appear in
58 supporting documentation, and that the name of Digital not be
59 used in advertising or publicity pertaining to distribution of the
60 software without specific, written prior permission.
62 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
63 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
64 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
65 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
66 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
67 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
72 /* The panoramix components contained the following notice */
73 /*****************************************************************
75 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
77 Permission is hereby granted, free of charge, to any person obtaining a copy
78 of this software and associated documentation files (the "Software"), to deal
79 in the Software without restriction, including without limitation the rights
80 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
81 copies of the Software.
83 The above copyright notice and this permission notice shall be included in
84 all copies or substantial portions of the Software.
86 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
89 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
90 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
91 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
92 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
94 Except as contained in this notice, the name of Digital Equipment Corporation
95 shall not be used in advertising or otherwise to promote the sale, use or other
96 dealings in this Software without prior written authorization from Digital
97 Equipment Corporation.
99 ******************************************************************/
102 #ifdef HAVE_DIX_CONFIG_H
103 #include <dix-config.h>
107 #include "scrnintstr.h"
109 #include "regionstr.h"
110 #include "validate.h"
111 #include "windowstr.h"
113 #include "resource.h"
114 #include "colormapst.h"
115 #include "cursorstr.h"
116 #include "dixstruct.h"
117 #include "gcstruct.h"
118 #include "servermd.h"
120 #include "panoramiX.h"
121 #include "panoramiXsrv.h"
123 #include "dixevents.h"
127 #include "appgroup.h"
132 * Window stuff for server
134 * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
135 * GetWindowAttributes, DeleteWindow, DestroySubWindows,
136 * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
137 * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
141 static unsigned char _back_lsb
[4] = {0x88, 0x22, 0x44, 0x11};
142 static unsigned char _back_msb
[4] = {0x11, 0x44, 0x22, 0x88};
144 _X_EXPORT
int screenIsSaved
= SCREEN_SAVER_OFF
;
146 _X_EXPORT ScreenSaverStuffRec savedScreenInfo
[MAXSCREENS
];
149 extern void DeleteWindowFromAnyEvents();
150 extern Mask
EventMaskForClient();
151 extern void WindowHasNewCursor();
152 extern void RecalculateDeliverableEvents();
155 static Bool
TileScreenSaver(int i
, int kind
);
158 #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
159 CWDontPropagate | CWOverrideRedirect | CWCursor )
161 #define BOXES_OVERLAP(b1, b2) \
162 (!( ((b1)->x2 <= (b2)->x1) || \
163 ( ((b1)->x1 >= (b2)->x2)) || \
164 ( ((b1)->y2 <= (b2)->y1)) || \
165 ( ((b1)->y1 >= (b2)->y2)) ) )
167 #define RedirectSend(pWin) \
168 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
170 #define SubSend(pWin) \
171 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
173 #define StrSend(pWin) \
174 ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
176 #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
179 _X_EXPORT
int numSaveUndersViewable
= 0;
180 _X_EXPORT
int deltaSaveUndersViewable
= 0;
189 PrintChildren(WindowPtr p1
, int indent
)
197 for (i
=0; i
<indent
; i
++) ErrorF( " ");
198 ErrorF( "%lx\n", p1
->drawable
.id
);
199 miPrintRegion(&p1
->clipList
);
200 PrintChildren(p2
, indent
+4);
206 PrintWindowTree(void)
211 for (i
=0; i
<screenInfo
.numScreens
; i
++)
213 ErrorF( "WINDOW %d\n", i
);
214 pWin
= WindowTable
[i
];
215 miPrintRegion(&pWin
->clipList
);
216 p1
= pWin
->firstChild
;
217 PrintChildren(p1
, 4);
223 TraverseTree(WindowPtr pWin
, VisitWindowProcPtr func
, pointer data
)
228 if (!(pChild
= pWin
))
232 result
= (* func
)(pChild
, data
);
233 if (result
== WT_STOPWALKING
)
234 return(WT_STOPWALKING
);
235 if ((result
== WT_WALKCHILDREN
) && pChild
->firstChild
)
237 pChild
= pChild
->firstChild
;
240 while (!pChild
->nextSib
&& (pChild
!= pWin
))
241 pChild
= pChild
->parent
;
244 pChild
= pChild
->nextSib
;
251 * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
252 * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
253 * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
254 * exit WalkTree. Does depth-first traverse.
258 WalkTree(ScreenPtr pScreen
, VisitWindowProcPtr func
, pointer data
)
260 return(TraverseTree(WindowTable
[pScreen
->myNum
], func
, data
));
263 /* hack for forcing backing store on all windows */
264 int defaultBackingStore
= NotUseful
;
265 /* hack to force no backing store */
266 Bool disableBackingStore
= FALSE
;
267 Bool enableBackingStore
= FALSE
;
268 /* hack to force no save unders */
269 Bool disableSaveUnders
= FALSE
;
272 SetWindowToDefaults(WindowPtr pWin
)
274 pWin
->prevSib
= NullWindow
;
275 pWin
->firstChild
= NullWindow
;
276 pWin
->lastChild
= NullWindow
;
278 pWin
->valdata
= (ValidatePtr
)NULL
;
279 pWin
->optional
= (WindowOptPtr
)NULL
;
280 pWin
->cursorIsNone
= TRUE
;
282 pWin
->backingStore
= NotUseful
;
283 pWin
->DIXsaveUnder
= FALSE
;
284 pWin
->backStorage
= (pointer
) NULL
;
286 pWin
->mapped
= FALSE
; /* off */
287 pWin
->realized
= FALSE
; /* off */
288 pWin
->viewable
= FALSE
;
289 pWin
->visibility
= VisibilityNotViewable
;
290 pWin
->overrideRedirect
= FALSE
;
291 pWin
->saveUnder
= FALSE
;
293 pWin
->bitGravity
= ForgetGravity
;
294 pWin
->winGravity
= NorthWestGravity
;
297 pWin
->deliverableEvents
= 0;
298 pWin
->dontPropagate
= 0;
299 pWin
->forcedBS
= FALSE
;
301 pWin
->redirectDraw
= RedirectDrawNone
;
306 MakeRootTile(WindowPtr pWin
)
308 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
310 unsigned char back
[128];
311 int len
= BitmapBytePad(sizeof(long));
312 unsigned char *from
, *to
;
315 pWin
->background
.pixmap
= (*pScreen
->CreatePixmap
)(pScreen
, 4, 4,
318 pWin
->backgroundState
= BackgroundPixmap
;
319 pGC
= GetScratchGC(pScreen
->rootDepth
, pScreen
);
320 if (!pWin
->background
.pixmap
|| !pGC
)
321 FatalError("could not create root tile");
324 CARD32 attributes
[2];
326 attributes
[0] = pScreen
->whitePixel
;
327 attributes
[1] = pScreen
->blackPixel
;
329 (void)ChangeGC(pGC
, GCForeground
| GCBackground
, attributes
);
332 ValidateGC((DrawablePtr
)pWin
->background
.pixmap
, pGC
);
334 from
= (screenInfo
.bitmapBitOrder
== LSBFirst
) ? _back_lsb
: _back_msb
;
337 for (i
= 4; i
> 0; i
--, from
++)
338 for (j
= len
; j
> 0; j
--)
341 (*pGC
->ops
->PutImage
)((DrawablePtr
)pWin
->background
.pixmap
, pGC
, 1,
342 0, 0, len
, 4, 0, XYBitmap
, (char *)back
);
349 AllocateWindow(ScreenPtr pScreen
)
358 pWin
= (WindowPtr
)xalloc(pScreen
->totalWindowSize
);
361 ppriv
= (DevUnion
*)(pWin
+ 1);
362 pWin
->devPrivates
= ppriv
;
363 sizes
= pScreen
->WindowPrivateSizes
;
364 ptr
= (char *)(ppriv
+ pScreen
->WindowPrivateLen
);
365 for (i
= pScreen
->WindowPrivateLen
; --i
>= 0; ppriv
++, sizes
++)
367 if ( (size
= *sizes
) )
369 ppriv
->ptr
= (pointer
)ptr
;
373 ppriv
->ptr
= (pointer
)NULL
;
376 pWin
->drawable
.pad0
= 0;
377 pWin
->drawable
.pad1
= 0;
385 * Makes a window at initialization time for specified screen
389 CreateRootWindow(ScreenPtr pScreen
)
393 PixmapFormatRec
*format
;
395 pWin
= AllocateWindow(pScreen
);
399 savedScreenInfo
[pScreen
->myNum
].pWindow
= NULL
;
400 savedScreenInfo
[pScreen
->myNum
].wid
= FakeClientID(0);
401 savedScreenInfo
[pScreen
->myNum
].ExternalScreenSaver
= NULL
;
402 screenIsSaved
= SCREEN_SAVER_OFF
;
404 WindowTable
[pScreen
->myNum
] = pWin
;
406 pWin
->drawable
.pScreen
= pScreen
;
407 pWin
->drawable
.type
= DRAWABLE_WINDOW
;
409 pWin
->drawable
.depth
= pScreen
->rootDepth
;
410 for (format
= screenInfo
.formats
;
411 format
->depth
!= pScreen
->rootDepth
;
414 pWin
->drawable
.bitsPerPixel
= format
->bitsPerPixel
;
416 pWin
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
418 pWin
->parent
= NullWindow
;
419 SetWindowToDefaults(pWin
);
421 pWin
->optional
= (WindowOptRec
*) xalloc (sizeof (WindowOptRec
));
425 pWin
->optional
->dontPropagateMask
= 0;
426 pWin
->optional
->otherEventMasks
= 0;
427 pWin
->optional
->otherClients
= NULL
;
428 pWin
->optional
->passiveGrabs
= NULL
;
429 pWin
->optional
->userProps
= NULL
;
430 pWin
->optional
->backingBitPlanes
= ~0L;
431 pWin
->optional
->backingPixel
= 0;
433 pWin
->optional
->boundingShape
= NULL
;
434 pWin
->optional
->clipShape
= NULL
;
435 pWin
->optional
->inputShape
= NULL
;
438 pWin
->optional
->inputMasks
= NULL
;
440 pWin
->optional
->colormap
= pScreen
->defColormap
;
441 pWin
->optional
->visual
= pScreen
->rootVisual
;
443 pWin
->nextSib
= NullWindow
;
445 pWin
->drawable
.id
= FakeClientID(0);
447 pWin
->origin
.x
= pWin
->origin
.y
= 0;
448 pWin
->drawable
.height
= pScreen
->height
;
449 pWin
->drawable
.width
= pScreen
->width
;
450 pWin
->drawable
.x
= pWin
->drawable
.y
= 0;
454 box
.x2
= pScreen
->width
;
455 box
.y2
= pScreen
->height
;
456 REGION_INIT(pScreen
, &pWin
->clipList
, &box
, 1);
457 REGION_INIT(pScreen
, &pWin
->winSize
, &box
, 1);
458 REGION_INIT(pScreen
, &pWin
->borderSize
, &box
, 1);
459 REGION_INIT(pScreen
, &pWin
->borderClip
, &box
, 1);
461 pWin
->drawable
.class = InputOutput
;
462 pWin
->optional
->visual
= pScreen
->rootVisual
;
464 pWin
->backgroundState
= BackgroundPixel
;
465 pWin
->background
.pixel
= pScreen
->whitePixel
;
467 pWin
->borderIsPixel
= TRUE
;
468 pWin
->border
.pixel
= pScreen
->blackPixel
;
469 pWin
->borderWidth
= 0;
471 if (!AddResource(pWin
->drawable
.id
, RT_WINDOW
, (pointer
)pWin
))
474 if (disableBackingStore
)
475 pScreen
->backingStoreSupport
= NotUseful
;
476 if (enableBackingStore
)
477 pScreen
->backingStoreSupport
= Always
;
479 #ifdef DO_SAVE_UNDERS
480 if ((pScreen
->backingStoreSupport
!= NotUseful
) &&
481 (pScreen
->saveUnderSupport
== NotUseful
))
484 * If the screen has backing-store but no save-unders, let the
485 * clients know we can support save-unders using backing-store.
487 pScreen
->saveUnderSupport
= USE_DIX_SAVE_UNDERS
;
489 #endif /* DO_SAVE_UNDERS */
491 if (disableSaveUnders
)
492 pScreen
->saveUnderSupport
= NotUseful
;
498 InitRootWindow(WindowPtr pWin
)
500 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
501 int backFlag
= CWBorderPixel
| CWCursor
| CWBackingStore
;
503 if (!(*pScreen
->CreateWindow
)(pWin
))
505 (*pScreen
->PositionWindow
)(pWin
, 0, 0);
507 pWin
->cursorIsNone
= FALSE
;
508 pWin
->optional
->cursor
= rootCursor
;
509 rootCursor
->refcnt
++;
511 if (!blackRoot
&& !whiteRoot
) {
513 backFlag
|= CWBackPixmap
;
517 pWin
->background
.pixel
= pScreen
->blackPixel
;
519 pWin
->background
.pixel
= pScreen
->whitePixel
;
520 backFlag
|= CWBackPixel
;
523 pWin
->backingStore
= defaultBackingStore
;
524 pWin
->forcedBS
= (defaultBackingStore
!= NotUseful
);
525 /* We SHOULD check for an error value here XXX */
526 (*pScreen
->ChangeWindowAttributes
)(pWin
, backFlag
);
528 XaceHook(XACE_WINDOW_INIT
, serverClient
, pWin
);
530 MapWindow(pWin
, serverClient
);
533 /* Set the region to the intersection of the rectangle and the
534 * window's winSize. The window is typically the parent of the
535 * window from which the region came.
539 ClippedRegionFromBox(WindowPtr pWin
, RegionPtr Rgn
,
546 pScreen
= pWin
->drawable
.pScreen
;
548 box
= *(REGION_EXTENTS(pScreen
, &pWin
->winSize
));
549 /* we do these calculations to avoid overflows */
564 REGION_RESET(pScreen
, Rgn
, &box
);
565 REGION_INTERSECT(pScreen
, Rgn
, Rgn
, &pWin
->winSize
);
568 static RealChildHeadProc realChildHeadProc
= NULL
;
571 RegisterRealChildHeadProc (RealChildHeadProc proc
)
573 realChildHeadProc
= proc
;
578 RealChildHead(WindowPtr pWin
)
580 if (realChildHeadProc
) {
581 return realChildHeadProc (pWin
);
585 (screenIsSaved
== SCREEN_SAVER_ON
) &&
586 (HasSaverWindow (pWin
->drawable
.pScreen
->myNum
)))
587 return (pWin
->firstChild
);
594 * Makes a window in response to client request
598 CreateWindow(Window wid
, WindowPtr pParent
, int x
, int y
, unsigned w
,
599 unsigned h
, unsigned bw
, unsigned class, Mask vmask
, XID
*vlist
,
600 int depth
, ClientPtr client
, VisualID visual
, int *error
)
609 PixmapFormatRec
*format
;
610 WindowOptPtr ancwopt
;
612 if (class == CopyFromParent
)
613 class = pParent
->drawable
.class;
615 if ((class != InputOutput
) && (class != InputOnly
))
618 client
->errorValue
= class;
622 if ((class != InputOnly
) && (pParent
->drawable
.class == InputOnly
))
628 if ((class == InputOnly
) && ((bw
!= 0) || (depth
!= 0)))
634 pScreen
= pParent
->drawable
.pScreen
;
635 if ((class == InputOutput
) && (depth
== 0))
636 depth
= pParent
->drawable
.depth
;
637 ancwopt
= pParent
->optional
;
639 ancwopt
= FindWindowWithOptional(pParent
)->optional
;
640 if (visual
== CopyFromParent
) {
644 if (client
->appgroup
&& !pParent
->parent
&&
645 (ag_visual
= XagRootVisual (client
)))
649 visual
= ancwopt
->visual
;
652 /* Find out if the depth and visual are acceptable for this Screen */
653 if ((visual
!= ancwopt
->visual
) || (depth
!= pParent
->drawable
.depth
))
656 for(idepth
= 0; idepth
< pScreen
->numDepths
; idepth
++)
658 pDepth
= (DepthPtr
) &pScreen
->allowedDepths
[idepth
];
659 if ((depth
== pDepth
->depth
) || (depth
== 0))
661 for (ivisual
= 0; ivisual
< pDepth
->numVids
; ivisual
++)
663 if (visual
== pDepth
->vids
[ivisual
])
678 if (((vmask
& (CWBorderPixmap
| CWBorderPixel
)) == 0) &&
679 (class != InputOnly
) &&
680 (depth
!= pParent
->drawable
.depth
))
686 if (((vmask
& CWColormap
) == 0) &&
687 (class != InputOnly
) &&
688 ((visual
!= ancwopt
->visual
) || (ancwopt
->colormap
== None
)))
694 pWin
= AllocateWindow(pScreen
);
700 pWin
->drawable
= pParent
->drawable
;
701 pWin
->drawable
.depth
= depth
;
702 if (depth
== pParent
->drawable
.depth
)
703 pWin
->drawable
.bitsPerPixel
= pParent
->drawable
.bitsPerPixel
;
706 for (format
= screenInfo
.formats
; format
->depth
!= depth
; format
++)
708 pWin
->drawable
.bitsPerPixel
= format
->bitsPerPixel
;
710 if (class == InputOnly
)
711 pWin
->drawable
.type
= (short) UNDRAWABLE_WINDOW
;
712 pWin
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
714 pWin
->drawable
.id
= wid
;
715 pWin
->drawable
.class = class;
717 pWin
->parent
= pParent
;
718 SetWindowToDefaults(pWin
);
720 if (visual
!= ancwopt
->visual
)
722 if (!MakeWindowOptional (pWin
))
728 pWin
->optional
->visual
= visual
;
729 pWin
->optional
->colormap
= None
;
732 pWin
->borderWidth
= bw
;
734 /* can't let untrusted clients have background None windows;
735 * they make it too easy to steal window contents
737 if (XaceHook(XACE_BACKGRND_ACCESS
, client
, pWin
))
738 pWin
->backgroundState
= None
;
740 pWin
->backgroundState
= BackgroundPixel
;
741 pWin
->background
.pixel
= 0;
744 pWin
->borderIsPixel
= pParent
->borderIsPixel
;
745 pWin
->border
= pParent
->border
;
746 if (pWin
->borderIsPixel
== FALSE
)
747 pWin
->border
.pixmap
->refcnt
++;
749 pWin
->origin
.x
= x
+ (int)bw
;
750 pWin
->origin
.y
= y
+ (int)bw
;
751 pWin
->drawable
.width
= w
;
752 pWin
->drawable
.height
= h
;
753 pWin
->drawable
.x
= pParent
->drawable
.x
+ x
+ (int)bw
;
754 pWin
->drawable
.y
= pParent
->drawable
.y
+ y
+ (int)bw
;
756 /* set up clip list correctly for unobscured WindowPtr */
757 REGION_NULL(pScreen
, &pWin
->clipList
);
758 REGION_NULL(pScreen
, &pWin
->borderClip
);
759 REGION_NULL(pScreen
, &pWin
->winSize
);
760 REGION_NULL(pScreen
, &pWin
->borderSize
);
762 XaceHook(XACE_WINDOW_INIT
, client
, pWin
);
764 pHead
= RealChildHead(pParent
);
767 pWin
->nextSib
= pHead
->nextSib
;
769 pHead
->nextSib
->prevSib
= pWin
;
771 pParent
->lastChild
= pWin
;
772 pHead
->nextSib
= pWin
;
773 pWin
->prevSib
= pHead
;
777 pWin
->nextSib
= pParent
->firstChild
;
778 if (pParent
->firstChild
)
779 pParent
->firstChild
->prevSib
= pWin
;
781 pParent
->lastChild
= pWin
;
782 pParent
->firstChild
= pWin
;
786 SetBorderSize (pWin
);
788 /* We SHOULD check for an error value here XXX */
789 if (!(*pScreen
->CreateWindow
)(pWin
))
792 DeleteWindow(pWin
, None
);
795 /* We SHOULD check for an error value here XXX */
796 (*pScreen
->PositionWindow
)(pWin
, pWin
->drawable
.x
, pWin
->drawable
.y
);
798 if (!(vmask
& CWEventMask
))
799 RecalculateDeliverableEvents(pWin
);
802 *error
= ChangeWindowAttributes(pWin
, vmask
, vlist
, wClient (pWin
));
806 if (*error
!= Success
)
808 DeleteWindow(pWin
, None
);
811 if (!(vmask
& CWBackingStore
) && (defaultBackingStore
!= NotUseful
))
813 XID value
= defaultBackingStore
;
814 (void)ChangeWindowAttributes(pWin
, CWBackingStore
, &value
, wClient (pWin
));
815 pWin
->forcedBS
= TRUE
;
818 if (SubSend(pParent
))
820 event
.u
.u
.type
= CreateNotify
;
821 event
.u
.createNotify
.window
= wid
;
822 event
.u
.createNotify
.parent
= pParent
->drawable
.id
;
823 event
.u
.createNotify
.x
= x
;
824 event
.u
.createNotify
.y
= y
;
825 event
.u
.createNotify
.width
= w
;
826 event
.u
.createNotify
.height
= h
;
827 event
.u
.createNotify
.borderWidth
= bw
;
828 event
.u
.createNotify
.override
= pWin
->overrideRedirect
;
829 DeliverEvents(pParent
, &event
, 1, NullWindow
);
835 DisposeWindowOptional (WindowPtr pWin
)
840 * everything is peachy. Delete the optional record
843 if (pWin
->optional
->cursor
)
845 FreeCursor (pWin
->optional
->cursor
, (Cursor
)0);
846 pWin
->cursorIsNone
= FALSE
;
849 pWin
->cursorIsNone
= TRUE
;
850 xfree (pWin
->optional
);
851 pWin
->optional
= NULL
;
855 FreeWindowResources(WindowPtr pWin
)
857 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
859 DeleteWindowFromAnySaveSet(pWin
);
860 DeleteWindowFromAnySelections(pWin
);
861 DeleteWindowFromAnyEvents(pWin
, TRUE
);
862 REGION_UNINIT(pScreen
, &pWin
->clipList
);
863 REGION_UNINIT(pScreen
, &pWin
->winSize
);
864 REGION_UNINIT(pScreen
, &pWin
->borderClip
);
865 REGION_UNINIT(pScreen
, &pWin
->borderSize
);
867 if (wBoundingShape (pWin
))
868 REGION_DESTROY(pScreen
, wBoundingShape (pWin
));
869 if (wClipShape (pWin
))
870 REGION_DESTROY(pScreen
, wClipShape (pWin
));
871 if (wInputShape (pWin
))
872 REGION_DESTROY(pScreen
, wInputShape (pWin
));
874 if (pWin
->borderIsPixel
== FALSE
)
875 (*pScreen
->DestroyPixmap
)(pWin
->border
.pixmap
);
876 if (pWin
->backgroundState
== BackgroundPixmap
)
877 (*pScreen
->DestroyPixmap
)(pWin
->background
.pixmap
);
879 DeleteAllWindowProperties(pWin
);
880 /* We SHOULD check for an error value here XXX */
881 (*pScreen
->DestroyWindow
)(pWin
);
882 DisposeWindowOptional (pWin
);
886 CrushTree(WindowPtr pWin
)
888 WindowPtr pChild
, pSib
, pParent
;
889 UnrealizeWindowProcPtr UnrealizeWindow
;
892 if (!(pChild
= pWin
->firstChild
))
894 UnrealizeWindow
= pWin
->drawable
.pScreen
->UnrealizeWindow
;
897 if (pChild
->firstChild
)
899 pChild
= pChild
->firstChild
;
904 pParent
= pChild
->parent
;
905 if (SubStrSend(pChild
, pParent
))
907 event
.u
.u
.type
= DestroyNotify
;
908 event
.u
.destroyNotify
.window
= pChild
->drawable
.id
;
909 DeliverEvents(pChild
, &event
, 1, NullWindow
);
911 FreeResource(pChild
->drawable
.id
, RT_WINDOW
);
912 pSib
= pChild
->nextSib
;
913 #ifdef DO_SAVE_UNDERS
914 if (pChild
->saveUnder
&& pChild
->viewable
)
915 deltaSaveUndersViewable
--;
917 pChild
->viewable
= FALSE
;
918 if (pChild
->realized
)
920 pChild
->realized
= FALSE
;
921 (*UnrealizeWindow
)(pChild
);
923 FreeWindowResources(pChild
);
925 if ( (pChild
= pSib
) )
928 pChild
->firstChild
= NullWindow
;
929 pChild
->lastChild
= NullWindow
;
938 * Deletes child of window then window itself
939 * If wid is None, don't send any events
943 DeleteWindow(pointer value
, XID wid
)
946 WindowPtr pWin
= (WindowPtr
)value
;
949 UnmapWindow(pWin
, FALSE
);
953 pParent
= pWin
->parent
;
954 if (wid
&& pParent
&& SubStrSend(pWin
, pParent
))
956 event
.u
.u
.type
= DestroyNotify
;
957 event
.u
.destroyNotify
.window
= pWin
->drawable
.id
;
958 DeliverEvents(pWin
, &event
, 1, NullWindow
);
961 FreeWindowResources(pWin
);
964 if (pParent
->firstChild
== pWin
)
965 pParent
->firstChild
= pWin
->nextSib
;
966 if (pParent
->lastChild
== pWin
)
967 pParent
->lastChild
= pWin
->prevSib
;
969 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
971 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
978 DestroySubwindows(WindowPtr pWin
, ClientPtr client
)
981 * The protocol is quite clear that each window should be
982 * destroyed in turn, however, unmapping all of the first
983 * eliminates most of the calls to ValidateTree. So,
984 * this implementation is incorrect in that all of the
985 * UnmapNotifies occur before all of the DestroyNotifies.
986 * If you care, simply delete the call to UnmapSubwindows.
988 UnmapSubwindows(pWin
);
989 while (pWin
->lastChild
)
990 FreeResource(pWin
->lastChild
->drawable
.id
, RT_NONE
);
993 #define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
994 ButtonReleaseMask | PointerMotionMask)
997 * ChangeWindowAttributes
999 * The value-mask specifies which attributes are to be changed; the
1000 * value-list contains one value for each one bit in the mask, from least
1001 * to most significant bit in the mask.
1005 ChangeWindowAttributes(WindowPtr pWin
, Mask vmask
, XID
*vlist
, ClientPtr client
)
1011 CursorPtr pCursor
, pOldCursor
;
1023 Bool checkOptional
= FALSE
;
1024 Bool borderRelative
= FALSE
;
1025 WindowPtr pLayerWin
;
1027 if ((pWin
->drawable
.class == InputOnly
) && (vmask
& (~INPUTONLY_LEGAL_MASK
)))
1031 pScreen
= pWin
->drawable
.pScreen
;
1036 index2
= (Mask
) lowbit (tmask
);
1041 pixID
= (Pixmap
)*pVlist
;
1043 if (pWin
->backgroundState
== ParentRelative
)
1044 borderRelative
= TRUE
;
1047 /* can't let untrusted clients have background None windows */
1048 if (XaceHook(XACE_BACKGRND_ACCESS
, client
, pWin
)) {
1049 if (pWin
->backgroundState
== BackgroundPixmap
)
1050 (*pScreen
->DestroyPixmap
)(pWin
->background
.pixmap
);
1054 pWin
->backgroundState
= None
;
1056 /* didn't change the backgrnd to None, so don't tell ddx */
1060 else if (pixID
== ParentRelative
)
1063 pWin
->drawable
.depth
!= pWin
->parent
->drawable
.depth
)
1068 if (pWin
->backgroundState
== BackgroundPixmap
)
1069 (*pScreen
->DestroyPixmap
)(pWin
->background
.pixmap
);
1073 pWin
->backgroundState
= ParentRelative
;
1074 borderRelative
= TRUE
;
1075 /* Note that the parent's backgroundTile's refcnt is NOT
1080 pPixmap
= (PixmapPtr
)SecurityLookupIDByType(client
, pixID
,
1081 RT_PIXMAP
, DixReadAccess
);
1082 if (pPixmap
!= (PixmapPtr
) NULL
)
1084 if ((pPixmap
->drawable
.depth
!= pWin
->drawable
.depth
) ||
1085 (pPixmap
->drawable
.pScreen
!= pScreen
))
1090 if (pWin
->backgroundState
== BackgroundPixmap
)
1091 (*pScreen
->DestroyPixmap
)(pWin
->background
.pixmap
);
1092 pWin
->backgroundState
= BackgroundPixmap
;
1093 pWin
->background
.pixmap
= pPixmap
;
1099 client
->errorValue
= pixID
;
1105 if (pWin
->backgroundState
== ParentRelative
)
1106 borderRelative
= TRUE
;
1107 if (pWin
->backgroundState
== BackgroundPixmap
)
1108 (*pScreen
->DestroyPixmap
)(pWin
->background
.pixmap
);
1109 pWin
->backgroundState
= BackgroundPixel
;
1110 pWin
->background
.pixel
= (CARD32
) *pVlist
;
1111 /* background pixel overrides background pixmap,
1112 so don't let the ddx layer see both bits */
1113 vmaskCopy
&= ~CWBackPixmap
;
1116 case CWBorderPixmap
:
1117 pixID
= (Pixmap
) *pVlist
;
1119 if (pixID
== CopyFromParent
)
1121 if (!pWin
->parent
||
1122 (pWin
->drawable
.depth
!= pWin
->parent
->drawable
.depth
))
1127 if (pWin
->borderIsPixel
== FALSE
)
1128 (*pScreen
->DestroyPixmap
)(pWin
->border
.pixmap
);
1129 pWin
->border
= pWin
->parent
->border
;
1130 if ((pWin
->borderIsPixel
= pWin
->parent
->borderIsPixel
) == TRUE
)
1132 index2
= CWBorderPixel
;
1136 pWin
->parent
->border
.pixmap
->refcnt
++;
1141 pPixmap
= (PixmapPtr
)SecurityLookupIDByType(client
, pixID
,
1142 RT_PIXMAP
, DixReadAccess
);
1145 if ((pPixmap
->drawable
.depth
!= pWin
->drawable
.depth
) ||
1146 (pPixmap
->drawable
.pScreen
!= pScreen
))
1151 if (pWin
->borderIsPixel
== FALSE
)
1152 (*pScreen
->DestroyPixmap
)(pWin
->border
.pixmap
);
1153 pWin
->borderIsPixel
= FALSE
;
1154 pWin
->border
.pixmap
= pPixmap
;
1160 client
->errorValue
= pixID
;
1166 if (pWin
->borderIsPixel
== FALSE
)
1167 (*pScreen
->DestroyPixmap
)(pWin
->border
.pixmap
);
1168 pWin
->borderIsPixel
= TRUE
;
1169 pWin
->border
.pixel
= (CARD32
) *pVlist
;
1170 /* border pixel overrides border pixmap,
1171 so don't let the ddx layer see both bits */
1172 vmaskCopy
&= ~CWBorderPixmap
;
1176 val
= (CARD8
)*pVlist
;
1178 if (val
> StaticGravity
)
1181 client
->errorValue
= val
;
1184 pWin
->bitGravity
= val
;
1187 val
= (CARD8
)*pVlist
;
1189 if (val
> StaticGravity
)
1192 client
->errorValue
= val
;
1195 pWin
->winGravity
= val
;
1197 case CWBackingStore
:
1198 val
= (CARD8
)*pVlist
;
1200 if ((val
!= NotUseful
) && (val
!= WhenMapped
) && (val
!= Always
))
1203 client
->errorValue
= val
;
1206 pWin
->backingStore
= val
;
1207 pWin
->forcedBS
= FALSE
;
1209 case CWBackingPlanes
:
1210 if (pWin
->optional
|| ((CARD32
)*pVlist
!= (CARD32
)~0L)) {
1211 if (!pWin
->optional
&& !MakeWindowOptional (pWin
))
1216 pWin
->optional
->backingBitPlanes
= (CARD32
) *pVlist
;
1217 if ((CARD32
)*pVlist
== (CARD32
)~0L)
1218 checkOptional
= TRUE
;
1222 case CWBackingPixel
:
1223 if (pWin
->optional
|| (CARD32
) *pVlist
) {
1224 if (!pWin
->optional
&& !MakeWindowOptional (pWin
))
1229 pWin
->optional
->backingPixel
= (CARD32
) *pVlist
;
1231 checkOptional
= TRUE
;
1236 val
= (BOOL
) *pVlist
;
1238 if ((val
!= xTrue
) && (val
!= xFalse
))
1241 client
->errorValue
= val
;
1244 #ifdef DO_SAVE_UNDERS
1245 if (pWin
->parent
&& (pWin
->saveUnder
!= val
) && (pWin
->viewable
) &&
1246 DO_SAVE_UNDERS(pWin
))
1249 * Re-check all siblings and inferiors for obscurity or
1250 * exposition (hee hee).
1252 if (pWin
->saveUnder
)
1253 deltaSaveUndersViewable
--;
1255 deltaSaveUndersViewable
++;
1256 pWin
->saveUnder
= val
;
1258 if (pWin
->firstChild
)
1260 pLayerWin
= (*pScreen
->GetLayerWindow
)(pWin
);
1261 if ((*pScreen
->ChangeSaveUnder
)(pLayerWin
->parent
, pWin
->nextSib
))
1262 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
->parent
,
1267 if ((*pScreen
->ChangeSaveUnder
)(pWin
, pWin
->nextSib
))
1268 (*pScreen
->PostChangeSaveUnder
)(pWin
,
1274 /* If we're changing the saveUnder attribute of the root
1275 * window, all we do is set pWin->saveUnder so that
1276 * GetWindowAttributes returns the right value. We don't
1277 * do the "normal" save-under processing (as above).
1278 * Hope that doesn't cause any problems.
1280 pWin
->saveUnder
= val
;
1283 pWin
->saveUnder
= val
;
1284 #endif /* DO_SAVE_UNDERS */
1287 result
= EventSelectForWindow(pWin
, client
, (Mask
)*pVlist
);
1295 case CWDontPropagate
:
1296 result
= EventSuppressForWindow(pWin
, client
, (Mask
)*pVlist
,
1305 case CWOverrideRedirect
:
1306 val
= (BOOL
) *pVlist
;
1308 if ((val
!= xTrue
) && (val
!= xFalse
))
1311 client
->errorValue
= val
;
1314 pWin
->overrideRedirect
= val
;
1317 cmap
= (Colormap
) *pVlist
;
1319 if (cmap
== CopyFromParent
)
1322 Colormap ag_colormap
;
1323 ClientPtr win_owner
;
1326 * win_owner == client for CreateWindow, other clients
1327 * can ChangeWindowAttributes
1329 win_owner
= clients
[CLIENT_ID(pWin
->drawable
.id
)];
1331 if ( win_owner
&& win_owner
->appgroup
&&
1332 !pWin
->parent
->parent
&&
1333 (ag_colormap
= XagDefaultColormap (win_owner
)))
1339 pWin
->optional
->visual
== wVisual (pWin
->parent
)))
1341 cmap
= wColormap (pWin
->parent
);
1351 pCmap
= (ColormapPtr
)SecurityLookupIDByType(client
, cmap
,
1352 RT_COLORMAP
, DixReadAccess
);
1356 client
->errorValue
= cmap
;
1359 if (pCmap
->pVisual
->vid
!= wVisual (pWin
) ||
1360 pCmap
->pScreen
!= pScreen
)
1365 if (cmap
!= wColormap (pWin
))
1367 if (!pWin
->optional
)
1369 if (!MakeWindowOptional (pWin
))
1375 else if (pWin
->parent
&& cmap
== wColormap (pWin
->parent
))
1376 checkOptional
= TRUE
;
1379 * propagate the original colormap to any children
1383 for (pChild
= pWin
->firstChild
; pChild
; pChild
=pChild
->nextSib
)
1385 if (!pChild
->optional
&& !MakeWindowOptional (pChild
))
1392 pWin
->optional
->colormap
= cmap
;
1395 * check on any children now matching the new colormap
1398 for (pChild
= pWin
->firstChild
; pChild
; pChild
=pChild
->nextSib
)
1400 if (pChild
->optional
->colormap
== cmap
)
1401 CheckWindowOptionalNeed (pChild
);
1404 xE
.u
.u
.type
= ColormapNotify
;
1405 xE
.u
.colormap
.window
= pWin
->drawable
.id
;
1406 xE
.u
.colormap
.colormap
= cmap
;
1407 xE
.u
.colormap
.new = xTrue
;
1408 xE
.u
.colormap
.state
= IsMapInstalled(cmap
, pWin
);
1409 DeliverEvents(pWin
, &xE
, 1, NullWindow
);
1413 cursorID
= (Cursor
) *pVlist
;
1418 if ( cursorID
== None
)
1420 if (pWin
== WindowTable
[pWin
->drawable
.pScreen
->myNum
])
1421 pCursor
= rootCursor
;
1423 pCursor
= (CursorPtr
) None
;
1427 pCursor
= (CursorPtr
)SecurityLookupIDByType(client
, cursorID
,
1428 RT_CURSOR
, DixReadAccess
);
1432 client
->errorValue
= cursorID
;
1437 if (pCursor
!= wCursor (pWin
))
1440 * patch up child windows so they don't lose cursors.
1443 for (pChild
= pWin
->firstChild
; pChild
; pChild
=pChild
->nextSib
)
1445 if (!pChild
->optional
&& !pChild
->cursorIsNone
&&
1446 !MakeWindowOptional (pChild
))
1454 if (pCursor
== (CursorPtr
) None
)
1456 pWin
->cursorIsNone
= TRUE
;
1459 pOldCursor
= pWin
->optional
->cursor
;
1460 pWin
->optional
->cursor
= (CursorPtr
) None
;
1461 checkOptional
= TRUE
;
1464 if (!pWin
->optional
)
1466 if (!MakeWindowOptional (pWin
))
1472 else if (pWin
->parent
&& pCursor
== wCursor (pWin
->parent
))
1473 checkOptional
= TRUE
;
1474 pOldCursor
= pWin
->optional
->cursor
;
1475 pWin
->optional
->cursor
= pCursor
;
1477 pWin
->cursorIsNone
= FALSE
;
1479 * check on any children now matching the new cursor
1482 for (pChild
=pWin
->firstChild
; pChild
; pChild
=pChild
->nextSib
)
1484 if (pChild
->optional
&&
1485 (pChild
->optional
->cursor
== pCursor
))
1486 CheckWindowOptionalNeed (pChild
);
1491 WindowHasNewCursor( pWin
);
1493 /* Can't free cursor until here - old cursor
1494 * is needed in WindowHasNewCursor
1497 FreeCursor (pOldCursor
, (Cursor
)0);
1502 client
->errorValue
= vmask
;
1505 vmaskCopy
|= index2
;
1509 CheckWindowOptionalNeed (pWin
);
1511 /* We SHOULD check for an error value here XXX */
1512 (*pScreen
->ChangeWindowAttributes
)(pWin
, vmaskCopy
);
1515 If the border contents have changed, redraw the border.
1516 Note that this has to be done AFTER pScreen->ChangeWindowAttributes
1517 for the tile to be rotated, and the correct function selected.
1519 if (((vmaskCopy
& (CWBorderPixel
| CWBorderPixmap
)) || borderRelative
)
1520 && pWin
->viewable
&& HasBorder (pWin
))
1524 REGION_NULL(pScreen
, &exposed
);
1525 REGION_SUBTRACT(pScreen
, &exposed
, &pWin
->borderClip
, &pWin
->winSize
);
1526 (*pWin
->drawable
.pScreen
->PaintWindowBorder
)(pWin
, &exposed
, PW_BORDER
);
1527 REGION_UNINIT(pScreen
, &exposed
);
1534 * GetWindowAttributes
1535 * Notice that this is different than ChangeWindowAttributes
1539 GetWindowAttributes(WindowPtr pWin
, ClientPtr client
, xGetWindowAttributesReply
*wa
)
1542 wa
->bitGravity
= pWin
->bitGravity
;
1543 wa
->winGravity
= pWin
->winGravity
;
1544 if (pWin
->forcedBS
&& pWin
->backingStore
!= Always
)
1545 wa
->backingStore
= NotUseful
;
1547 wa
->backingStore
= pWin
->backingStore
;
1548 wa
->length
= (sizeof(xGetWindowAttributesReply
) -
1549 sizeof(xGenericReply
)) >> 2;
1550 wa
->sequenceNumber
= client
->sequence
;
1551 wa
->backingBitPlanes
= wBackingBitPlanes (pWin
);
1552 wa
->backingPixel
= wBackingPixel (pWin
);
1553 wa
->saveUnder
= (BOOL
)pWin
->saveUnder
;
1554 wa
->override
= pWin
->overrideRedirect
;
1556 wa
->mapState
= IsUnmapped
;
1557 else if (pWin
->realized
)
1558 wa
->mapState
= IsViewable
;
1560 wa
->mapState
= IsUnviewable
;
1562 wa
->colormap
= wColormap (pWin
);
1563 wa
->mapInstalled
= (wa
->colormap
== None
) ? xFalse
1564 : IsMapInstalled(wa
->colormap
, pWin
);
1566 wa
->yourEventMask
= EventMaskForClient(pWin
, client
);
1567 wa
->allEventMasks
= pWin
->eventMask
| wOtherEventMasks (pWin
);
1568 wa
->doNotPropagateMask
= wDontPropagateMask (pWin
);
1569 wa
->class = pWin
->drawable
.class;
1570 wa
->visualID
= wVisual (pWin
);
1575 MoveWindowInStack(WindowPtr pWin
, WindowPtr pNextSib
)
1577 WindowPtr pParent
= pWin
->parent
;
1578 WindowPtr pFirstChange
= pWin
; /* highest window where list changes */
1580 if (pWin
->nextSib
!= pNextSib
)
1582 WindowPtr pOldNextSib
= pWin
->nextSib
;
1584 if (!pNextSib
) /* move to bottom */
1586 if (pParent
->firstChild
== pWin
)
1587 pParent
->firstChild
= pWin
->nextSib
;
1588 /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
1589 * and pWin->nextSib != pNextSib
1590 * therefore pWin->nextSib != NULL */
1591 pFirstChange
= pWin
->nextSib
;
1592 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1594 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1595 pParent
->lastChild
->nextSib
= pWin
;
1596 pWin
->prevSib
= pParent
->lastChild
;
1597 pWin
->nextSib
= NullWindow
;
1598 pParent
->lastChild
= pWin
;
1600 else if (pParent
->firstChild
== pNextSib
) /* move to top */
1602 pFirstChange
= pWin
;
1603 if (pParent
->lastChild
== pWin
)
1604 pParent
->lastChild
= pWin
->prevSib
;
1606 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1608 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1609 pWin
->nextSib
= pParent
->firstChild
;
1610 pWin
->prevSib
= (WindowPtr
) NULL
;
1611 pNextSib
->prevSib
= pWin
;
1612 pParent
->firstChild
= pWin
;
1614 else /* move in middle of list */
1616 WindowPtr pOldNext
= pWin
->nextSib
;
1618 pFirstChange
= NullWindow
;
1619 if (pParent
->firstChild
== pWin
)
1620 pFirstChange
= pParent
->firstChild
= pWin
->nextSib
;
1621 if (pParent
->lastChild
== pWin
) {
1622 pFirstChange
= pWin
;
1623 pParent
->lastChild
= pWin
->prevSib
;
1626 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
1628 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
1629 pWin
->nextSib
= pNextSib
;
1630 pWin
->prevSib
= pNextSib
->prevSib
;
1631 if (pNextSib
->prevSib
)
1632 pNextSib
->prevSib
->nextSib
= pWin
;
1633 pNextSib
->prevSib
= pWin
;
1634 if (!pFirstChange
) { /* do we know it yet? */
1635 pFirstChange
= pParent
->firstChild
; /* no, search from top */
1636 while ((pFirstChange
!= pWin
) && (pFirstChange
!= pOldNext
))
1637 pFirstChange
= pFirstChange
->nextSib
;
1640 if(pWin
->drawable
.pScreen
->RestackWindow
)
1641 (*pWin
->drawable
.pScreen
->RestackWindow
)(pWin
, pOldNextSib
);
1646 * In rootless mode we can't optimize away window restacks.
1647 * There may be non-X windows around, so even if the window
1648 * is in the correct position from X's point of view,
1649 * the underlying window system may want to reorder it.
1651 else if (pWin
->drawable
.pScreen
->RestackWindow
)
1652 (*pWin
->drawable
.pScreen
->RestackWindow
)(pWin
, pWin
->nextSib
);
1655 return( pFirstChange
);
1659 CreateUnclippedWinSize (WindowPtr pWin
)
1664 box
.x1
= pWin
->drawable
.x
;
1665 box
.y1
= pWin
->drawable
.y
;
1666 box
.x2
= pWin
->drawable
.x
+ (int) pWin
->drawable
.width
;
1667 box
.y2
= pWin
->drawable
.y
+ (int) pWin
->drawable
.height
;
1668 pRgn
= REGION_CREATE(pWin
->drawable
.pScreen
, &box
, 1);
1670 if (wBoundingShape (pWin
) || wClipShape (pWin
)) {
1672 pScreen
= pWin
->drawable
.pScreen
;
1674 REGION_TRANSLATE(pScreen
, pRgn
, - pWin
->drawable
.x
,
1675 - pWin
->drawable
.y
);
1676 if (wBoundingShape (pWin
))
1677 REGION_INTERSECT(pScreen
, pRgn
, pRgn
, wBoundingShape (pWin
));
1678 if (wClipShape (pWin
))
1679 REGION_INTERSECT(pScreen
, pRgn
, pRgn
, wClipShape (pWin
));
1680 REGION_TRANSLATE(pScreen
, pRgn
, pWin
->drawable
.x
, pWin
->drawable
.y
);
1687 SetWinSize (WindowPtr pWin
)
1690 if (pWin
->redirectDraw
!= RedirectDrawNone
)
1695 * Redirected clients get clip list equal to their
1696 * own geometry, not clipped to their parent
1698 box
.x1
= pWin
->drawable
.x
;
1699 box
.y1
= pWin
->drawable
.y
;
1700 box
.x2
= pWin
->drawable
.x
+ pWin
->drawable
.width
;
1701 box
.y2
= pWin
->drawable
.y
+ pWin
->drawable
.height
;
1702 REGION_RESET (pScreen
, &pWin
->winSize
, &box
);
1706 ClippedRegionFromBox(pWin
->parent
, &pWin
->winSize
,
1707 pWin
->drawable
.x
, pWin
->drawable
.y
,
1708 (int)pWin
->drawable
.width
,
1709 (int)pWin
->drawable
.height
);
1711 if (wBoundingShape (pWin
) || wClipShape (pWin
)) {
1713 pScreen
= pWin
->drawable
.pScreen
;
1715 REGION_TRANSLATE(pScreen
, &pWin
->winSize
, - pWin
->drawable
.x
,
1716 - pWin
->drawable
.y
);
1717 if (wBoundingShape (pWin
))
1718 REGION_INTERSECT(pScreen
, &pWin
->winSize
, &pWin
->winSize
,
1719 wBoundingShape (pWin
));
1720 if (wClipShape (pWin
))
1721 REGION_INTERSECT(pScreen
, &pWin
->winSize
, &pWin
->winSize
,
1723 REGION_TRANSLATE(pScreen
, &pWin
->winSize
, pWin
->drawable
.x
,
1730 SetBorderSize (WindowPtr pWin
)
1734 if (HasBorder (pWin
)) {
1735 bw
= wBorderWidth (pWin
);
1737 if (pWin
->redirectDraw
!= RedirectDrawNone
)
1742 * Redirected clients get clip list equal to their
1743 * own geometry, not clipped to their parent
1745 box
.x1
= pWin
->drawable
.x
- bw
;
1746 box
.y1
= pWin
->drawable
.y
- bw
;
1747 box
.x2
= pWin
->drawable
.x
+ pWin
->drawable
.width
+ bw
;
1748 box
.y2
= pWin
->drawable
.y
+ pWin
->drawable
.height
+ bw
;
1749 REGION_RESET (pScreen
, &pWin
->borderSize
, &box
);
1753 ClippedRegionFromBox(pWin
->parent
, &pWin
->borderSize
,
1754 pWin
->drawable
.x
- bw
, pWin
->drawable
.y
- bw
,
1755 (int)(pWin
->drawable
.width
+ (bw
<<1)),
1756 (int)(pWin
->drawable
.height
+ (bw
<<1)));
1758 if (wBoundingShape (pWin
)) {
1760 pScreen
= pWin
->drawable
.pScreen
;
1762 REGION_TRANSLATE(pScreen
, &pWin
->borderSize
, - pWin
->drawable
.x
,
1763 - pWin
->drawable
.y
);
1764 REGION_INTERSECT(pScreen
, &pWin
->borderSize
, &pWin
->borderSize
,
1765 wBoundingShape (pWin
));
1766 REGION_TRANSLATE(pScreen
, &pWin
->borderSize
, pWin
->drawable
.x
,
1768 REGION_UNION(pScreen
, &pWin
->borderSize
, &pWin
->borderSize
,
1773 REGION_COPY(pWin
->drawable
.pScreen
, &pWin
->borderSize
,
1780 * \param x,y new window position
1781 * \param oldx,oldy old window position
1782 * \param destx,desty position relative to gravity
1786 GravityTranslate (int x
, int y
, int oldx
, int oldy
,
1787 int dw
, int dh
, unsigned gravity
,
1788 int *destx
, int *desty
)
1792 *destx
= x
+ dw
/ 2;
1795 case NorthEastGravity
:
1801 *desty
= y
+ dh
/ 2;
1804 *destx
= x
+ dw
/ 2;
1805 *desty
= y
+ dh
/ 2;
1809 *desty
= y
+ dh
/ 2;
1811 case SouthWestGravity
:
1816 *destx
= x
+ dw
/ 2;
1819 case SouthEastGravity
:
1834 /* XXX need to retile border on each window with ParentRelative origin */
1836 ResizeChildrenWinSize(WindowPtr pWin
, int dx
, int dy
, int dw
, int dh
)
1839 WindowPtr pSib
, pChild
;
1840 Bool resized
= (dw
|| dh
);
1842 pScreen
= pWin
->drawable
.pScreen
;
1844 for (pSib
= pWin
->firstChild
; pSib
; pSib
= pSib
->nextSib
)
1846 if (resized
&& (pSib
->winGravity
> NorthWestGravity
))
1850 cwsx
= pSib
->origin
.x
;
1851 cwsy
= pSib
->origin
.y
;
1852 GravityTranslate (cwsx
, cwsy
, cwsx
- dx
, cwsy
- dy
, dw
, dh
,
1853 pSib
->winGravity
, &cwsx
, &cwsy
);
1854 if (cwsx
!= pSib
->origin
.x
|| cwsy
!= pSib
->origin
.y
)
1858 event
.u
.u
.type
= GravityNotify
;
1859 event
.u
.gravity
.window
= pSib
->drawable
.id
;
1860 event
.u
.gravity
.x
= cwsx
- wBorderWidth (pSib
);
1861 event
.u
.gravity
.y
= cwsy
- wBorderWidth (pSib
);
1862 DeliverEvents (pSib
, &event
, 1, NullWindow
);
1863 pSib
->origin
.x
= cwsx
;
1864 pSib
->origin
.y
= cwsy
;
1867 pSib
->drawable
.x
= pWin
->drawable
.x
+ pSib
->origin
.x
;
1868 pSib
->drawable
.y
= pWin
->drawable
.y
+ pSib
->origin
.y
;
1870 SetBorderSize (pSib
);
1871 (*pScreen
->PositionWindow
)(pSib
, pSib
->drawable
.x
, pSib
->drawable
.y
);
1873 if ( (pChild
= pSib
->firstChild
) )
1877 pChild
->drawable
.x
= pChild
->parent
->drawable
.x
+
1879 pChild
->drawable
.y
= pChild
->parent
->drawable
.y
+
1881 SetWinSize (pChild
);
1882 SetBorderSize (pChild
);
1883 (*pScreen
->PositionWindow
)(pChild
,
1884 pChild
->drawable
.x
, pChild
->drawable
.y
);
1885 if (pChild
->firstChild
)
1887 pChild
= pChild
->firstChild
;
1890 while (!pChild
->nextSib
&& (pChild
!= pSib
))
1891 pChild
= pChild
->parent
;
1894 pChild
= pChild
->nextSib
;
1900 #define GET_INT16(m, f) \
1903 f = (INT16) *pVlist;\
1906 #define GET_CARD16(m, f) \
1909 f = (CARD16) *pVlist;\
1913 #define GET_CARD8(m, f) \
1916 f = (CARD8) *pVlist;\
1920 #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
1922 #define IllegalInputOnlyConfigureMask (CWBorderWidth)
1926 * returns Above if pSib above pMe in stack or Below otherwise
1936 pWin
= pMe
->parent
->firstChild
;
1941 else if (pWin
== pMe
)
1943 pWin
= pWin
->nextSib
;
1953 pBox
->x1
= pWin
->drawable
.x
- wBorderWidth (pWin
);
1954 pBox
->y1
= pWin
->drawable
.y
- wBorderWidth (pWin
);
1955 pBox
->x2
= pWin
->drawable
.x
+ (int)pWin
->drawable
.width
1956 + wBorderWidth (pWin
);
1957 pBox
->y2
= pWin
->drawable
.y
+ (int)pWin
->drawable
.height
1958 + wBorderWidth (pWin
);
1963 #define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
1966 MakeBoundingRegion (
1972 pScreen
= pWin
->drawable
.pScreen
;
1974 pRgn
= REGION_CREATE(pScreen
, pBox
, 1);
1975 if (wBoundingShape (pWin
)) {
1976 REGION_TRANSLATE(pScreen
, pRgn
, -pWin
->origin
.x
,
1978 REGION_INTERSECT(pScreen
, pRgn
, pRgn
, wBoundingShape (pWin
));
1979 REGION_TRANSLATE(pScreen
, pRgn
, pWin
->origin
.x
,
1992 RegionPtr pWinRgn
, pSibRgn
;
1996 if (!IS_SHAPED(pWin
) && !IS_SHAPED(pSib
))
1998 pScreen
= pWin
->drawable
.pScreen
;
1999 pWinRgn
= MakeBoundingRegion (pWin
, pWinBox
);
2000 pSibRgn
= MakeBoundingRegion (pSib
, pSibBox
);
2001 REGION_INTERSECT(pScreen
, pWinRgn
, pWinRgn
, pSibRgn
);
2002 ret
= REGION_NOTEMPTY(pScreen
, pWinRgn
);
2003 REGION_DESTROY(pScreen
, pWinRgn
);
2004 REGION_DESTROY(pScreen
, pSibRgn
);
2010 AnyWindowOverlapsMe(
2019 for (pSib
= pWin
->prevSib
; pSib
!= pHead
; pSib
= pSib
->prevSib
)
2023 sbox
= WindowExtents(pSib
, &sboxrec
);
2024 if (BOXES_OVERLAP(sbox
, box
)
2026 && ShapeOverlap (pWin
, box
, pSib
, sbox
)
2044 for (pSib
= pWin
->nextSib
; pSib
; pSib
= pSib
->nextSib
)
2048 sbox
= WindowExtents(pSib
, &sboxrec
);
2049 if (BOXES_OVERLAP(sbox
, box
)
2051 && ShapeOverlap (pWin
, box
, pSib
, sbox
)
2061 * WhereDoIGoInTheStack()
2062 * Given pWin and pSib and the relationshipe smode, return
2063 * the window that pWin should go ABOVE.
2064 * If a pSib is specified:
2065 * Above: pWin is placed just above pSib
2066 * Below: pWin is placed just below pSib
2067 * TopIf: if pSib occludes pWin, then pWin is placed
2068 * at the top of the stack
2069 * BottomIf: if pWin occludes pSib, then pWin is
2070 * placed at the bottom of the stack
2071 * Opposite: if pSib occludes pWin, then pWin is placed at the
2072 * top of the stack, else if pWin occludes pSib, then
2073 * pWin is placed at the bottom of the stack
2076 * Above: pWin is placed at the top of the stack
2077 * Below: pWin is placed at the bottom of the stack
2078 * TopIf: if any sibling occludes pWin, then pWin is placed at
2079 * the top of the stack
2080 * BottomIf: if pWin occludes any sibline, then pWin is placed at
2081 * the bottom of the stack
2082 * Opposite: if any sibling occludes pWin, then pWin is placed at
2083 * the top of the stack, else if pWin occludes any
2084 * sibling, then pWin is placed at the bottom of the stack
2089 WhereDoIGoInTheStack(
2100 WindowPtr pHead
, pFirst
;
2102 if ((pWin
== pWin
->parent
->firstChild
) &&
2103 (pWin
== pWin
->parent
->lastChild
))
2104 return((WindowPtr
) NULL
);
2105 pHead
= RealChildHead(pWin
->parent
);
2106 pFirst
= pHead
? pHead
->nextSib
: pWin
->parent
->firstChild
;
2107 pScreen
= pWin
->drawable
.pScreen
;
2110 box
.x2
= x
+ (int)w
;
2111 box
.y2
= y
+ (int)h
;
2117 else if (pWin
== pFirst
)
2118 return(pWin
->nextSib
);
2123 if (pSib
->nextSib
!= pWin
)
2124 return(pSib
->nextSib
);
2126 return(pWin
->nextSib
);
2130 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
2131 return(pWin
->nextSib
);
2134 if ((IsSiblingAboveMe(pWin
, pSib
) == Above
) &&
2135 (RECT_IN_REGION(pScreen
, &pSib
->borderSize
, &box
) != rgnOUT
))
2138 return(pWin
->nextSib
);
2140 else if (AnyWindowOverlapsMe(pWin
, pHead
, &box
))
2143 return(pWin
->nextSib
);
2145 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
2146 return(pWin
->nextSib
);
2149 if ((IsSiblingAboveMe(pWin
, pSib
) == Below
) &&
2150 (RECT_IN_REGION(pScreen
, &pSib
->borderSize
, &box
) != rgnOUT
))
2153 return(pWin
->nextSib
);
2155 else if (IOverlapAnyWindow(pWin
, &box
))
2158 return(pWin
->nextSib
);
2160 if ((!pWin
->mapped
|| (pSib
&& !pSib
->mapped
)))
2161 return(pWin
->nextSib
);
2164 if (RECT_IN_REGION(pScreen
, &pSib
->borderSize
, &box
) != rgnOUT
)
2166 if (IsSiblingAboveMe(pWin
, pSib
) == Above
)
2172 return(pWin
->nextSib
);
2174 else if (AnyWindowOverlapsMe(pWin
, pHead
, &box
))
2176 /* If I'm occluded, I can't possibly be the first child
2177 * if (pWin == pWin->parent->firstChild)
2178 * return pWin->nextSib;
2182 else if (IOverlapAnyWindow(pWin
, &box
))
2185 return pWin
->nextSib
;
2188 ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode
);
2189 return pWin
->nextSib
;
2200 /* Note that pSib might be NULL */
2202 Bool WasViewable
= (Bool
)pWin
->viewable
;
2204 WindowPtr pFirstChange
;
2205 #ifdef DO_SAVE_UNDERS
2206 Bool dosave
= FALSE
;
2208 WindowPtr pLayerWin
;
2209 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
2211 /* if this is a root window, can't be restacked */
2215 pFirstChange
= MoveWindowInStack(pWin
, pSib
);
2219 anyMarked
= (*pScreen
->MarkOverlappedWindows
)(pWin
, pFirstChange
,
2221 if (pLayerWin
!= pWin
) pFirstChange
= pLayerWin
;
2222 #ifdef DO_SAVE_UNDERS
2223 if (DO_SAVE_UNDERS(pWin
))
2225 dosave
= (*pScreen
->ChangeSaveUnder
)(pLayerWin
, pFirstChange
);
2227 #endif /* DO_SAVE_UNDERS */
2230 (*pScreen
->ValidateTree
)(pLayerWin
->parent
, pFirstChange
, kind
);
2231 (*pScreen
->HandleExposures
)(pLayerWin
->parent
);
2233 #ifdef DO_SAVE_UNDERS
2235 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
, pFirstChange
);
2236 #endif /* DO_SAVE_UNDERS */
2237 if (anyMarked
&& pWin
->drawable
.pScreen
->PostValidateTree
)
2238 (*pScreen
->PostValidateTree
)(pLayerWin
->parent
, pFirstChange
, kind
);
2241 WindowsRestructured ();
2249 ConfigureWindow(WindowPtr pWin
, Mask mask
, XID
*vlist
, ClientPtr client
)
2251 #define RESTACK_WIN 0
2253 #define RESIZE_WIN 2
2254 #define REBORDER_WIN 3
2255 WindowPtr pSib
= NullWindow
;
2256 WindowPtr pParent
= pWin
->parent
;
2260 short x
, y
, beforeX
, beforeY
;
2261 unsigned short w
= pWin
->drawable
.width
,
2262 h
= pWin
->drawable
.height
,
2263 bw
= pWin
->borderWidth
;
2264 int action
, smode
= Above
;
2266 ClientPtr win_owner
;
2267 ClientPtr ag_leader
= NULL
;
2271 if ((pWin
->drawable
.class == InputOnly
) && (mask
& IllegalInputOnlyConfigureMask
))
2274 if ((mask
& CWSibling
) && !(mask
& CWStackMode
))
2281 x
= pWin
->drawable
.x
- pParent
->drawable
.x
- (int)bw
;
2282 y
= pWin
->drawable
.y
- pParent
->drawable
.y
- (int)bw
;
2286 x
= pWin
->drawable
.x
;
2287 y
= pWin
->drawable
.y
;
2291 action
= RESTACK_WIN
;
2292 if ((mask
& (CWX
| CWY
)) && (!(mask
& (CWHeight
| CWWidth
))))
2298 /* or should be resized */
2299 else if (mask
& (CWX
| CWY
| CWWidth
| CWHeight
))
2303 GET_CARD16(CWWidth
, w
);
2304 GET_CARD16 (CWHeight
, h
);
2307 client
->errorValue
= 0;
2310 action
= RESIZE_WIN
;
2312 tmask
= mask
& ~ChangeMask
;
2315 index2
= (Mask
)lowbit (tmask
);
2320 GET_CARD16(CWBorderWidth
, bw
);
2323 sibwid
= (Window
) *pVlist
;
2325 pSib
= (WindowPtr
)SecurityLookupIDByType(client
, sibwid
,
2326 RT_WINDOW
, DixReadAccess
);
2329 client
->errorValue
= sibwid
;
2332 if (pSib
->parent
!= pParent
)
2338 GET_CARD8(CWStackMode
, smode
);
2339 if ((smode
!= TopIf
) && (smode
!= BottomIf
) &&
2340 (smode
!= Opposite
) && (smode
!= Above
) && (smode
!= Below
))
2342 client
->errorValue
= smode
;
2347 client
->errorValue
= mask
;
2351 /* root really can't be reconfigured, so just return */
2355 /* Figure out if the window should be moved. Doesnt
2356 make the changes to the window if event sent */
2358 if (mask
& CWStackMode
)
2359 pSib
= WhereDoIGoInTheStack(pWin
, pSib
, pParent
->drawable
.x
+ x
,
2360 pParent
->drawable
.y
+ y
,
2361 w
+ (bw
<< 1), h
+ (bw
<< 1), smode
);
2363 pSib
= pWin
->nextSib
;
2366 win_owner
= clients
[CLIENT_ID(pWin
->drawable
.id
)];
2367 ag_leader
= XagLeader (win_owner
);
2370 if ((!pWin
->overrideRedirect
) &&
2371 (RedirectSend(pParent
)
2373 || (win_owner
->appgroup
&& ag_leader
&&
2374 XagIsControlledRoot (client
, pParent
))
2378 event
.u
.u
.type
= ConfigureRequest
;
2379 event
.u
.configureRequest
.window
= pWin
->drawable
.id
;
2380 if (mask
& CWSibling
)
2381 event
.u
.configureRequest
.sibling
= sibwid
;
2383 event
.u
.configureRequest
.sibling
= None
;
2384 if (mask
& CWStackMode
)
2385 event
.u
.u
.detail
= smode
;
2387 event
.u
.u
.detail
= Above
;
2388 event
.u
.configureRequest
.x
= x
;
2389 event
.u
.configureRequest
.y
= y
;
2391 if(!noPanoramiXExtension
&& (!pParent
|| !pParent
->parent
)) {
2392 event
.u
.configureRequest
.x
+= panoramiXdataPtr
[0].x
;
2393 event
.u
.configureRequest
.y
+= panoramiXdataPtr
[0].y
;
2396 event
.u
.configureRequest
.width
= w
;
2397 event
.u
.configureRequest
.height
= h
;
2398 event
.u
.configureRequest
.borderWidth
= bw
;
2399 event
.u
.configureRequest
.valueMask
= mask
;
2401 /* make sure if the ag_leader maps the window it goes to the wm */
2402 if (ag_leader
&& ag_leader
!= client
&&
2403 XagIsControlledRoot (client
, pParent
)) {
2404 event
.u
.configureRequest
.parent
= XagId (win_owner
);
2405 (void) TryClientEvents (ag_leader
, &event
, 1,
2406 NoEventMask
, NoEventMask
, NullGrab
);
2410 event
.u
.configureRequest
.parent
= pParent
->drawable
.id
;
2411 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2412 SubstructureRedirectMask
, client
) == 1)
2415 if (action
== RESIZE_WIN
)
2417 Bool size_change
= (w
!= pWin
->drawable
.width
)
2418 || (h
!= pWin
->drawable
.height
);
2419 if (size_change
&& ((pWin
->eventMask
|wOtherEventMasks(pWin
)) & ResizeRedirectMask
))
2422 eventT
.u
.u
.type
= ResizeRequest
;
2423 eventT
.u
.resizeRequest
.window
= pWin
->drawable
.id
;
2424 eventT
.u
.resizeRequest
.width
= w
;
2425 eventT
.u
.resizeRequest
.height
= h
;
2426 if (MaybeDeliverEventsToClient(pWin
, &eventT
, 1,
2427 ResizeRedirectMask
, client
) == 1)
2429 /* if event is delivered, leave the actual size alone. */
2430 w
= pWin
->drawable
.width
;
2431 h
= pWin
->drawable
.height
;
2432 size_change
= FALSE
;
2437 if (mask
& (CWX
| CWY
))
2439 else if (mask
& (CWStackMode
| CWBorderWidth
))
2440 action
= RESTACK_WIN
;
2441 else /* really nothing to do */
2446 if (action
== RESIZE_WIN
)
2447 /* we've already checked whether there's really a size change */
2448 goto ActuallyDoSomething
;
2449 if ((mask
& CWX
) && (x
!= beforeX
))
2450 goto ActuallyDoSomething
;
2451 if ((mask
& CWY
) && (y
!= beforeY
))
2452 goto ActuallyDoSomething
;
2453 if ((mask
& CWBorderWidth
) && (bw
!= wBorderWidth (pWin
)))
2454 goto ActuallyDoSomething
;
2455 if (mask
& CWStackMode
)
2458 /* See above for why we always reorder in rootless mode. */
2459 if (pWin
->nextSib
!= pSib
)
2461 goto ActuallyDoSomething
;
2465 ActuallyDoSomething
:
2466 if (SubStrSend(pWin
, pParent
))
2468 event
.u
.u
.type
= ConfigureNotify
;
2469 event
.u
.configureNotify
.window
= pWin
->drawable
.id
;
2471 event
.u
.configureNotify
.aboveSibling
= pSib
->drawable
.id
;
2473 event
.u
.configureNotify
.aboveSibling
= None
;
2474 event
.u
.configureNotify
.x
= x
;
2475 event
.u
.configureNotify
.y
= y
;
2477 if(!noPanoramiXExtension
&& (!pParent
|| !pParent
->parent
)) {
2478 event
.u
.configureNotify
.x
+= panoramiXdataPtr
[0].x
;
2479 event
.u
.configureNotify
.y
+= panoramiXdataPtr
[0].y
;
2482 event
.u
.configureNotify
.width
= w
;
2483 event
.u
.configureNotify
.height
= h
;
2484 event
.u
.configureNotify
.borderWidth
= bw
;
2485 event
.u
.configureNotify
.override
= pWin
->overrideRedirect
;
2486 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2488 if (mask
& CWBorderWidth
)
2490 if (action
== RESTACK_WIN
)
2493 pWin
->borderWidth
= bw
;
2495 else if ((action
== MOVE_WIN
) &&
2496 (beforeX
+ wBorderWidth (pWin
) == x
+ (int)bw
) &&
2497 (beforeY
+ wBorderWidth (pWin
) == y
+ (int)bw
))
2499 action
= REBORDER_WIN
;
2500 (*pWin
->drawable
.pScreen
->ChangeBorderWidth
)(pWin
, bw
);
2503 pWin
->borderWidth
= bw
;
2505 if (action
== MOVE_WIN
)
2506 (*pWin
->drawable
.pScreen
->MoveWindow
)(pWin
, x
, y
, pSib
,
2507 (mask
& CWBorderWidth
) ? VTOther
: VTMove
);
2508 else if (action
== RESIZE_WIN
)
2509 (*pWin
->drawable
.pScreen
->ResizeWindow
)(pWin
, x
, y
, w
, h
, pSib
);
2510 else if (mask
& CWStackMode
)
2511 ReflectStackChange(pWin
, pSib
, VTOther
);
2513 if (action
!= RESTACK_WIN
)
2514 CheckCursorConfinement(pWin
);
2526 * For RaiseLowest, raises the lowest mapped child (if any) that is
2527 * obscured by another child to the top of the stack. For LowerHighest,
2528 * lowers the highest mapped child (if any) that is obscuring another
2529 * child to the bottom of the stack. Exposure processing is performed
2534 CirculateWindow(WindowPtr pParent
, int direction
, ClientPtr client
)
2536 WindowPtr pWin
, pHead
, pFirst
;
2540 pHead
= RealChildHead(pParent
);
2541 pFirst
= pHead
? pHead
->nextSib
: pParent
->firstChild
;
2542 if (direction
== RaiseLowest
)
2544 for (pWin
= pParent
->lastChild
;
2547 AnyWindowOverlapsMe(pWin
, pHead
, WindowExtents(pWin
, &box
)));
2548 pWin
= pWin
->prevSib
) ;
2557 IOverlapAnyWindow(pWin
, WindowExtents(pWin
, &box
)));
2558 pWin
= pWin
->nextSib
) ;
2563 event
.u
.circulate
.window
= pWin
->drawable
.id
;
2564 event
.u
.circulate
.parent
= pParent
->drawable
.id
;
2565 event
.u
.circulate
.event
= pParent
->drawable
.id
;
2566 if (direction
== RaiseLowest
)
2567 event
.u
.circulate
.place
= PlaceOnTop
;
2569 event
.u
.circulate
.place
= PlaceOnBottom
;
2571 if (RedirectSend(pParent
))
2573 event
.u
.u
.type
= CirculateRequest
;
2574 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2575 SubstructureRedirectMask
, client
) == 1)
2579 event
.u
.u
.type
= CirculateNotify
;
2580 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2581 ReflectStackChange(pWin
,
2582 (direction
== RaiseLowest
) ? pFirst
: NullWindow
,
2591 pointer value
) /* must conform to VisitWindowProcPtr */
2593 Window
*wid
= (Window
*)value
;
2595 if (pWin
->drawable
.id
== *wid
)
2596 return(WT_STOPWALKING
);
2598 return(WT_WALKCHILDREN
);
2606 ReparentWindow(WindowPtr pWin
, WindowPtr pParent
,
2607 int x
, int y
, ClientPtr client
)
2609 WindowPtr pPrev
, pPriorParent
;
2610 Bool WasMapped
= (Bool
)(pWin
->mapped
);
2612 int bw
= wBorderWidth (pWin
);
2615 pScreen
= pWin
->drawable
.pScreen
;
2616 if (TraverseTree(pWin
, CompareWIDs
, (pointer
)&pParent
->drawable
.id
) == WT_STOPWALKING
)
2618 if (!MakeWindowOptional(pWin
))
2622 UnmapWindow(pWin
, FALSE
);
2624 event
.u
.u
.type
= ReparentNotify
;
2625 event
.u
.reparent
.window
= pWin
->drawable
.id
;
2626 event
.u
.reparent
.parent
= pParent
->drawable
.id
;
2627 event
.u
.reparent
.x
= x
;
2628 event
.u
.reparent
.y
= y
;
2630 if(!noPanoramiXExtension
&& !pParent
->parent
) {
2631 event
.u
.reparent
.x
+= panoramiXdataPtr
[0].x
;
2632 event
.u
.reparent
.y
+= panoramiXdataPtr
[0].y
;
2635 event
.u
.reparent
.override
= pWin
->overrideRedirect
;
2636 DeliverEvents(pWin
, &event
, 1, pParent
);
2638 /* take out of sibling chain */
2640 pPriorParent
= pPrev
= pWin
->parent
;
2641 if (pPrev
->firstChild
== pWin
)
2642 pPrev
->firstChild
= pWin
->nextSib
;
2643 if (pPrev
->lastChild
== pWin
)
2644 pPrev
->lastChild
= pWin
->prevSib
;
2647 pWin
->nextSib
->prevSib
= pWin
->prevSib
;
2649 pWin
->prevSib
->nextSib
= pWin
->nextSib
;
2651 /* insert at begining of pParent */
2652 pWin
->parent
= pParent
;
2653 pPrev
= RealChildHead(pParent
);
2656 pWin
->nextSib
= pPrev
->nextSib
;
2658 pPrev
->nextSib
->prevSib
= pWin
;
2660 pParent
->lastChild
= pWin
;
2661 pPrev
->nextSib
= pWin
;
2662 pWin
->prevSib
= pPrev
;
2666 pWin
->nextSib
= pParent
->firstChild
;
2667 pWin
->prevSib
= NullWindow
;
2668 if (pParent
->firstChild
)
2669 pParent
->firstChild
->prevSib
= pWin
;
2671 pParent
->lastChild
= pWin
;
2672 pParent
->firstChild
= pWin
;
2675 pWin
->origin
.x
= x
+ bw
;
2676 pWin
->origin
.y
= y
+ bw
;
2677 pWin
->drawable
.x
= x
+ bw
+ pParent
->drawable
.x
;
2678 pWin
->drawable
.y
= y
+ bw
+ pParent
->drawable
.y
;
2680 /* clip to parent */
2682 SetBorderSize (pWin
);
2684 if (pScreen
->ReparentWindow
)
2685 (*pScreen
->ReparentWindow
)(pWin
, pPriorParent
);
2686 (*pScreen
->PositionWindow
)(pWin
, pWin
->drawable
.x
, pWin
->drawable
.y
);
2687 ResizeChildrenWinSize(pWin
, 0, 0, 0, 0);
2689 CheckWindowOptionalNeed(pWin
);
2692 MapWindow(pWin
, client
);
2693 RecalculateDeliverableEvents(pWin
);
2698 RealizeTree(WindowPtr pWin
)
2701 RealizeWindowProcPtr Realize
;
2703 Realize
= pWin
->drawable
.pScreen
->RealizeWindow
;
2709 pChild
->realized
= TRUE
;
2710 #ifdef DO_SAVE_UNDERS
2711 if (pChild
->saveUnder
)
2712 deltaSaveUndersViewable
++;
2714 pChild
->viewable
= (pChild
->drawable
.class == InputOutput
);
2715 (* Realize
)(pChild
);
2716 if (pChild
->firstChild
)
2718 pChild
= pChild
->firstChild
;
2722 while (!pChild
->nextSib
&& (pChild
!= pWin
))
2723 pChild
= pChild
->parent
;
2726 pChild
= pChild
->nextSib
;
2730 static WindowPtr windowDisableMapUnmapEvents
;
2733 DisableMapUnmapEvents(WindowPtr pWin
)
2735 assert (windowDisableMapUnmapEvents
== NULL
);
2737 windowDisableMapUnmapEvents
= pWin
;
2741 EnableMapUnmapEvents(WindowPtr pWin
)
2743 assert (windowDisableMapUnmapEvents
!= NULL
);
2745 windowDisableMapUnmapEvents
= NULL
;
2749 MapUnmapEventsEnabled(WindowPtr pWin
)
2751 return pWin
!= windowDisableMapUnmapEvents
;
2756 * If some other client has selected SubStructureReDirect on the parent
2757 * and override-redirect is xFalse, then a MapRequest event is generated,
2758 * but the window remains unmapped. Otherwise, the window is mapped and a
2759 * MapNotify event is generated.
2763 MapWindow(WindowPtr pWin
, ClientPtr client
)
2768 #ifdef DO_SAVE_UNDERS
2769 Bool dosave
= FALSE
;
2771 WindowPtr pLayerWin
;
2776 /* general check for permission to map window */
2777 if (!XaceHook(XACE_MAP_ACCESS
, client
, pWin
))
2780 pScreen
= pWin
->drawable
.pScreen
;
2781 if ( (pParent
= pWin
->parent
) )
2786 ClientPtr win_owner
= clients
[CLIENT_ID(pWin
->drawable
.id
)];
2787 ClientPtr ag_leader
= XagLeader (win_owner
);
2790 if ((!pWin
->overrideRedirect
) &&
2791 (RedirectSend(pParent
)
2793 || (win_owner
->appgroup
&& ag_leader
&&
2794 XagIsControlledRoot (client
, pParent
))
2798 event
.u
.u
.type
= MapRequest
;
2799 event
.u
.mapRequest
.window
= pWin
->drawable
.id
;
2801 /* make sure if the ag_leader maps the window it goes to the wm */
2802 if (ag_leader
&& ag_leader
!= client
&&
2803 XagIsControlledRoot (client
, pParent
)) {
2804 event
.u
.mapRequest
.parent
= XagId (win_owner
);
2805 (void) TryClientEvents (ag_leader
, &event
, 1,
2806 NoEventMask
, NoEventMask
, NullGrab
);
2810 event
.u
.mapRequest
.parent
= pParent
->drawable
.id
;
2812 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2813 SubstructureRedirectMask
, client
) == 1)
2817 pWin
->mapped
= TRUE
;
2818 if (SubStrSend(pWin
, pParent
) && MapUnmapEventsEnabled(pWin
))
2820 event
.u
.u
.type
= MapNotify
;
2821 event
.u
.mapNotify
.window
= pWin
->drawable
.id
;
2822 event
.u
.mapNotify
.override
= pWin
->overrideRedirect
;
2823 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2826 if (!pParent
->realized
)
2831 anyMarked
= (*pScreen
->MarkOverlappedWindows
)(pWin
, pWin
,
2833 #ifdef DO_SAVE_UNDERS
2834 if (DO_SAVE_UNDERS(pWin
))
2836 dosave
= (*pScreen
->ChangeSaveUnder
)(pLayerWin
, pWin
->nextSib
);
2838 #endif /* DO_SAVE_UNDERS */
2841 (*pScreen
->ValidateTree
)(pLayerWin
->parent
, pLayerWin
, VTMap
);
2842 (*pScreen
->HandleExposures
)(pLayerWin
->parent
);
2844 #ifdef DO_SAVE_UNDERS
2846 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
, pWin
->nextSib
);
2847 #endif /* DO_SAVE_UNDERS */
2848 if (anyMarked
&& pScreen
->PostValidateTree
)
2849 (*pScreen
->PostValidateTree
)(pLayerWin
->parent
, pLayerWin
, VTMap
);
2851 WindowsRestructured ();
2857 pWin
->mapped
= TRUE
;
2858 pWin
->realized
= TRUE
; /* for roots */
2859 pWin
->viewable
= pWin
->drawable
.class == InputOutput
;
2860 /* We SHOULD check for an error value here XXX */
2861 (*pScreen
->RealizeWindow
)(pWin
);
2862 if (pScreen
->ClipNotify
)
2863 (*pScreen
->ClipNotify
) (pWin
, 0, 0);
2864 if (pScreen
->PostValidateTree
)
2865 (*pScreen
->PostValidateTree
)(NullWindow
, pWin
, VTMap
);
2866 REGION_NULL(pScreen
, &temp
);
2867 REGION_COPY(pScreen
, &temp
, &pWin
->clipList
);
2868 (*pScreen
->WindowExposures
) (pWin
, &temp
, NullRegion
);
2869 REGION_UNINIT(pScreen
, &temp
);
2878 * Performs a MapWindow all unmapped children of the window, in top
2879 * to bottom stacking order.
2883 MapSubwindows(WindowPtr pParent
, ClientPtr client
)
2886 WindowPtr pFirstMapped
= NullWindow
;
2887 #ifdef DO_SAVE_UNDERS
2888 WindowPtr pFirstSaveUndered
= NullWindow
;
2891 Mask parentRedirect
;
2895 #ifdef DO_SAVE_UNDERS
2896 Bool dosave
= FALSE
;
2898 WindowPtr pLayerWin
;
2900 pScreen
= pParent
->drawable
.pScreen
;
2901 parentRedirect
= RedirectSend(pParent
);
2902 parentNotify
= SubSend(pParent
);
2904 for (pWin
= pParent
->firstChild
; pWin
; pWin
= pWin
->nextSib
)
2908 if (parentRedirect
&& !pWin
->overrideRedirect
)
2910 event
.u
.u
.type
= MapRequest
;
2911 event
.u
.mapRequest
.window
= pWin
->drawable
.id
;
2912 event
.u
.mapRequest
.parent
= pParent
->drawable
.id
;
2914 if (MaybeDeliverEventsToClient(pParent
, &event
, 1,
2915 SubstructureRedirectMask
, client
) == 1)
2919 pWin
->mapped
= TRUE
;
2920 if (parentNotify
|| StrSend(pWin
))
2922 event
.u
.u
.type
= MapNotify
;
2923 event
.u
.mapNotify
.window
= pWin
->drawable
.id
;
2924 event
.u
.mapNotify
.override
= pWin
->overrideRedirect
;
2925 DeliverEvents(pWin
, &event
, 1, NullWindow
);
2929 pFirstMapped
= pWin
;
2930 if (pParent
->realized
)
2935 anyMarked
|= (*pScreen
->MarkOverlappedWindows
)(pWin
, pWin
,
2937 #ifdef DO_SAVE_UNDERS
2938 if (DO_SAVE_UNDERS(pWin
))
2942 #endif /* DO_SAVE_UNDERS */
2950 pLayerWin
= (*pScreen
->GetLayerWindow
)(pParent
);
2951 if (pLayerWin
->parent
!= pParent
) {
2952 anyMarked
|= (*pScreen
->MarkOverlappedWindows
)(pLayerWin
,
2955 pFirstMapped
= pLayerWin
;
2959 #ifdef DO_SAVE_UNDERS
2960 if (pLayerWin
->parent
!= pParent
)
2962 if (dosave
|| (DO_SAVE_UNDERS(pLayerWin
)))
2964 dosave
= (*pScreen
->ChangeSaveUnder
)(pLayerWin
,
2971 for (pWin
= pParent
->firstChild
; pWin
; pWin
= pWin
->nextSib
)
2973 if (DO_SAVE_UNDERS(pWin
))
2975 dosave
|= (*pScreen
->ChangeSaveUnder
)(pWin
,
2977 if (dosave
&& !pFirstSaveUndered
)
2978 pFirstSaveUndered
= pWin
;
2982 #endif /* DO_SAVE_UNDERS */
2983 (*pScreen
->ValidateTree
)(pLayerWin
->parent
, pFirstMapped
, VTMap
);
2984 (*pScreen
->HandleExposures
)(pLayerWin
->parent
);
2986 #ifdef DO_SAVE_UNDERS
2988 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
,
2989 pFirstSaveUndered
->nextSib
);
2990 #endif /* DO_SAVE_UNDERS */
2991 if (anyMarked
&& pScreen
->PostValidateTree
)
2992 (*pScreen
->PostValidateTree
)(pLayerWin
->parent
, pFirstMapped
,
2994 WindowsRestructured ();
3004 UnrealizeWindowProcPtr Unrealize
;
3005 MarkUnrealizedWindowProcPtr MarkUnrealizedWindow
;
3007 Unrealize
= pWin
->drawable
.pScreen
->UnrealizeWindow
;
3008 MarkUnrealizedWindow
= pWin
->drawable
.pScreen
->MarkUnrealizedWindow
;
3012 if (pChild
->realized
)
3014 pChild
->realized
= FALSE
;
3015 pChild
->visibility
= VisibilityNotViewable
;
3017 if(!noPanoramiXExtension
&& !pChild
->drawable
.pScreen
->myNum
) {
3019 win
= (PanoramiXRes
*)LookupIDByType(pChild
->drawable
.id
,
3022 win
->u
.win
.visibility
= VisibilityNotViewable
;
3025 (* Unrealize
)(pChild
);
3026 DeleteWindowFromAnyEvents(pChild
, FALSE
);
3027 if (pChild
->viewable
)
3029 #ifdef DO_SAVE_UNDERS
3030 if (pChild
->saveUnder
)
3031 deltaSaveUndersViewable
--;
3033 pChild
->viewable
= FALSE
;
3034 if (pChild
->backStorage
)
3035 (*pChild
->drawable
.pScreen
->SaveDoomedAreas
)(
3036 pChild
, &pChild
->clipList
, 0, 0);
3037 (* MarkUnrealizedWindow
)(pChild
, pWin
, fromConfigure
);
3038 pChild
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
3040 if (pChild
->firstChild
)
3042 pChild
= pChild
->firstChild
;
3046 while (!pChild
->nextSib
&& (pChild
!= pWin
))
3047 pChild
= pChild
->parent
;
3050 pChild
= pChild
->nextSib
;
3056 * If the window is already unmapped, this request has no effect.
3057 * Otherwise, the window is unmapped and an UnMapNotify event is
3058 * generated. Cannot unmap a root window.
3062 UnmapWindow(WindowPtr pWin
, Bool fromConfigure
)
3066 Bool wasRealized
= (Bool
)pWin
->realized
;
3067 Bool wasViewable
= (Bool
)pWin
->viewable
;
3068 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
3069 WindowPtr pLayerWin
= pWin
;
3071 if ((!pWin
->mapped
) || (!(pParent
= pWin
->parent
)))
3073 if (SubStrSend(pWin
, pParent
) && MapUnmapEventsEnabled(pWin
))
3075 event
.u
.u
.type
= UnmapNotify
;
3076 event
.u
.unmapNotify
.window
= pWin
->drawable
.id
;
3077 event
.u
.unmapNotify
.fromConfigure
= fromConfigure
;
3078 DeliverEvents(pWin
, &event
, 1, NullWindow
);
3080 if (wasViewable
&& !fromConfigure
)
3082 pWin
->valdata
= UnmapValData
;
3083 (*pScreen
->MarkOverlappedWindows
)(pWin
, pWin
->nextSib
, &pLayerWin
);
3084 (*pScreen
->MarkWindow
)(pLayerWin
->parent
);
3086 pWin
->mapped
= FALSE
;
3088 UnrealizeTree(pWin
, fromConfigure
);
3093 (*pScreen
->ValidateTree
)(pLayerWin
->parent
, pWin
, VTUnmap
);
3094 (*pScreen
->HandleExposures
)(pLayerWin
->parent
);
3096 #ifdef DO_SAVE_UNDERS
3097 if (DO_SAVE_UNDERS(pWin
))
3099 if ( (*pScreen
->ChangeSaveUnder
)(pLayerWin
, pWin
->nextSib
) )
3101 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
, pWin
->nextSib
);
3104 pWin
->DIXsaveUnder
= FALSE
;
3105 #endif /* DO_SAVE_UNDERS */
3106 if (!fromConfigure
&& pScreen
->PostValidateTree
)
3107 (*pScreen
->PostValidateTree
)(pLayerWin
->parent
, pWin
, VTUnmap
);
3109 if (wasRealized
&& !fromConfigure
)
3110 WindowsRestructured ();
3116 * Performs an UnmapWindow request with the specified mode on all mapped
3117 * children of the window, in bottom to top stacking order.
3121 UnmapSubwindows(WindowPtr pWin
)
3123 WindowPtr pChild
, pHead
;
3125 Bool wasRealized
= (Bool
)pWin
->realized
;
3126 Bool wasViewable
= (Bool
)pWin
->viewable
;
3127 Bool anyMarked
= FALSE
;
3129 WindowPtr pLayerWin
= NULL
;
3130 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
3132 if (!pWin
->firstChild
)
3134 parentNotify
= SubSend(pWin
);
3135 pHead
= RealChildHead(pWin
);
3138 pLayerWin
= (*pScreen
->GetLayerWindow
)(pWin
);
3140 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
)
3144 if (parentNotify
|| StrSend(pChild
))
3146 event
.u
.u
.type
= UnmapNotify
;
3147 event
.u
.unmapNotify
.window
= pChild
->drawable
.id
;
3148 event
.u
.unmapNotify
.fromConfigure
= xFalse
;
3149 DeliverEvents(pChild
, &event
, 1, NullWindow
);
3151 if (pChild
->viewable
)
3153 pChild
->valdata
= UnmapValData
;
3156 pChild
->mapped
= FALSE
;
3157 if (pChild
->realized
)
3158 UnrealizeTree(pChild
, FALSE
);
3161 #ifdef DO_SAVE_UNDERS
3162 pChild
->DIXsaveUnder
= FALSE
;
3163 #endif /* DO_SAVE_UNDERS */
3164 if (pChild
->backStorage
)
3165 (*pScreen
->SaveDoomedAreas
)(
3166 pChild
, &pChild
->clipList
, 0, 0);
3174 if (pLayerWin
->parent
== pWin
)
3175 (*pScreen
->MarkWindow
)(pWin
);
3179 (*pScreen
->MarkOverlappedWindows
)(pWin
, pLayerWin
,
3181 (*pScreen
->MarkWindow
)(pLayerWin
->parent
);
3183 /* Windows between pWin and pLayerWin may not have been marked */
3186 while (ptmp
!= pLayerWin
->parent
)
3188 (*pScreen
->MarkWindow
)(ptmp
);
3189 ptmp
= ptmp
->parent
;
3191 pHead
= pWin
->firstChild
;
3193 (*pScreen
->ValidateTree
)(pLayerWin
->parent
, pHead
, VTUnmap
);
3194 (*pScreen
->HandleExposures
)(pLayerWin
->parent
);
3196 #ifdef DO_SAVE_UNDERS
3197 if (DO_SAVE_UNDERS(pWin
))
3199 if ( (*pScreen
->ChangeSaveUnder
)(pLayerWin
, pLayerWin
))
3200 (*pScreen
->PostChangeSaveUnder
)(pLayerWin
, pLayerWin
);
3202 #endif /* DO_SAVE_UNDERS */
3203 if (anyMarked
&& pScreen
->PostValidateTree
)
3204 (*pScreen
->PostValidateTree
)(pLayerWin
->parent
, pHead
, VTUnmap
);
3207 WindowsRestructured ();
3212 HandleSaveSet(ClientPtr client
)
3214 WindowPtr pParent
, pWin
;
3217 for (j
=0; j
<client
->numSaved
; j
++)
3219 pWin
= SaveSetWindow(client
->saveSet
[j
]);
3221 if (SaveSetToRoot(client
->saveSet
[j
]))
3222 pParent
= WindowTable
[pWin
->drawable
.pScreen
->myNum
];
3226 pParent
= pWin
->parent
;
3227 while (pParent
&& (wClient (pParent
) == client
))
3228 pParent
= pParent
->parent
;
3232 if (pParent
!= pWin
->parent
)
3234 ReparentWindow(pWin
, pParent
,
3235 pWin
->drawable
.x
- wBorderWidth (pWin
) - pParent
->drawable
.x
,
3236 pWin
->drawable
.y
- wBorderWidth (pWin
) - pParent
->drawable
.y
,
3238 if(!pWin
->realized
&& pWin
->mapped
)
3239 pWin
->mapped
= FALSE
;
3242 if (SaveSetRemap (client
->saveSet
[j
]))
3244 MapWindow(pWin
, client
);
3247 xfree(client
->saveSet
);
3248 client
->numSaved
= 0;
3249 client
->saveSet
= (SaveSetElt
*)NULL
;
3254 * \param x,y in root
3257 PointInWindowIsVisible(WindowPtr pWin
, int x
, int y
)
3261 if (!pWin
->realized
)
3263 if (POINT_IN_REGION(pWin
->drawable
.pScreen
, &pWin
->borderClip
,
3265 && (!wInputShape(pWin
) ||
3266 POINT_IN_REGION(pWin
->drawable
.pScreen
,
3268 x
- pWin
->drawable
.x
,
3269 y
- pWin
->drawable
.y
, &box
)))
3276 NotClippedByChildren(WindowPtr pWin
)
3281 pScreen
= pWin
->drawable
.pScreen
;
3282 pReg
= REGION_CREATE(pScreen
, NullBox
, 1);
3284 screenIsSaved
!= SCREEN_SAVER_ON
||
3285 !HasSaverWindow (pWin
->drawable
.pScreen
->myNum
))
3287 REGION_INTERSECT(pScreen
, pReg
, &pWin
->borderClip
, &pWin
->winSize
);
3293 SendVisibilityNotify(WindowPtr pWin
)
3296 #ifndef NO_XINERAMA_PORT
3297 unsigned int visibility
= pWin
->visibility
;
3300 /* This is not quite correct yet, but it's close */
3301 if(!noPanoramiXExtension
) {
3306 Scrnum
= pWin
->drawable
.pScreen
->myNum
;
3308 win
= PanoramiXFindIDByScrnum(XRT_WINDOW
, pWin
->drawable
.id
, Scrnum
);
3310 if(!win
|| (win
->u
.win
.visibility
== visibility
))
3313 switch(visibility
) {
3314 case VisibilityUnobscured
:
3315 for(i
= 0; i
< PanoramiXNumScreens
; i
++) {
3316 if(i
== Scrnum
) continue;
3318 pWin2
= (WindowPtr
)LookupIDByType(win
->info
[i
].id
, RT_WINDOW
);
3321 if(pWin2
->visibility
== VisibilityPartiallyObscured
)
3324 if(!i
) pWin
= pWin2
;
3328 case VisibilityPartiallyObscured
:
3330 pWin2
= (WindowPtr
)LookupIDByType(win
->info
[0].id
, RT_WINDOW
);
3331 if (pWin2
) pWin
= pWin2
;
3334 case VisibilityFullyObscured
:
3335 for(i
= 0; i
< PanoramiXNumScreens
; i
++) {
3336 if(i
== Scrnum
) continue;
3338 pWin2
= (WindowPtr
)LookupIDByType(win
->info
[i
].id
, RT_WINDOW
);
3341 if(pWin2
->visibility
!= VisibilityFullyObscured
)
3344 if(!i
) pWin
= pWin2
;
3350 win
->u
.win
.visibility
= visibility
;
3354 event
.u
.u
.type
= VisibilityNotify
;
3355 event
.u
.visibility
.window
= pWin
->drawable
.id
;
3356 event
.u
.visibility
.state
= visibility
;
3357 DeliverEvents(pWin
, &event
, 1, NullWindow
);
3360 #define RANDOM_WIDTH 32
3363 static void DrawLogo(
3369 SaveScreens(int on
, int mode
)
3375 if (on
== SCREEN_SAVER_FORCER
)
3377 UpdateCurrentTimeIf();
3378 lastDeviceEventTime
= currentTime
;
3379 if (mode
== ScreenSaverReset
)
3380 what
= SCREEN_SAVER_OFF
;
3382 what
= SCREEN_SAVER_ON
;
3389 if (what
== screenIsSaved
)
3390 type
= SCREEN_SAVER_CYCLE
;
3392 for (i
= 0; i
< screenInfo
.numScreens
; i
++)
3394 if (on
== SCREEN_SAVER_FORCER
)
3395 (* screenInfo
.screens
[i
]->SaveScreen
) (screenInfo
.screens
[i
], on
);
3396 if (savedScreenInfo
[i
].ExternalScreenSaver
)
3398 if ((*savedScreenInfo
[i
].ExternalScreenSaver
)
3399 (screenInfo
.screens
[i
], type
, on
== SCREEN_SAVER_FORCER
))
3402 if (type
== screenIsSaved
)
3405 case SCREEN_SAVER_OFF
:
3406 if (savedScreenInfo
[i
].blanked
== SCREEN_IS_BLANKED
)
3408 (* screenInfo
.screens
[i
]->SaveScreen
) (screenInfo
.screens
[i
],
3411 else if (HasSaverWindow (i
))
3413 savedScreenInfo
[i
].pWindow
= NullWindow
;
3414 FreeResource(savedScreenInfo
[i
].wid
, RT_NONE
);
3417 case SCREEN_SAVER_CYCLE
:
3418 if (savedScreenInfo
[i
].blanked
== SCREEN_IS_TILED
)
3420 WindowPtr pWin
= savedScreenInfo
[i
].pWindow
;
3421 /* make it look like screen saver is off, so that
3422 * NotClippedByChildren will compute a clip list
3423 * for the root window, so miPaintWindow works
3425 screenIsSaved
= SCREEN_SAVER_OFF
;
3427 if (logoScreenSaver
)
3428 (*pWin
->drawable
.pScreen
->ClearToBackground
)(pWin
, 0, 0, 0, 0, FALSE
);
3430 (*pWin
->drawable
.pScreen
->MoveWindow
)(pWin
,
3431 (short)(-(rand() % RANDOM_WIDTH
)),
3432 (short)(-(rand() % RANDOM_WIDTH
)),
3433 pWin
->nextSib
, VTMove
);
3435 if (logoScreenSaver
)
3438 screenIsSaved
= SCREEN_SAVER_ON
;
3441 * Call the DDX saver in case it wants to do something
3444 else if (savedScreenInfo
[i
].blanked
== SCREEN_IS_BLANKED
)
3446 (* screenInfo
.screens
[i
]->SaveScreen
) (screenInfo
.screens
[i
],
3450 case SCREEN_SAVER_ON
:
3451 if (ScreenSaverBlanking
!= DontPreferBlanking
)
3453 if ((* screenInfo
.screens
[i
]->SaveScreen
)
3454 (screenInfo
.screens
[i
], what
))
3456 savedScreenInfo
[i
].blanked
= SCREEN_IS_BLANKED
;
3459 if ((ScreenSaverAllowExposures
!= DontAllowExposures
) &&
3460 TileScreenSaver(i
, SCREEN_IS_BLACK
))
3462 savedScreenInfo
[i
].blanked
= SCREEN_IS_BLACK
;
3466 if ((ScreenSaverAllowExposures
!= DontAllowExposures
) &&
3467 TileScreenSaver(i
, SCREEN_IS_TILED
))
3469 savedScreenInfo
[i
].blanked
= SCREEN_IS_TILED
;
3472 savedScreenInfo
[i
].blanked
= SCREEN_ISNT_SAVED
;
3476 screenIsSaved
= what
;
3477 if (mode
== ScreenSaverReset
)
3478 SetScreenSaverTimer();
3482 TileScreenSaver(int i
, int kind
)
3490 unsigned char *srcbits
, *mskbits
;
3498 case SCREEN_IS_TILED
:
3499 switch (WindowTable
[i
]->backgroundState
) {
3500 case BackgroundPixel
:
3501 attributes
[attri
++] = WindowTable
[i
]->background
.pixel
;
3502 mask
|= CWBackPixel
;
3504 case BackgroundPixmap
:
3505 attributes
[attri
++] = None
;
3506 mask
|= CWBackPixmap
;
3512 case SCREEN_IS_BLACK
:
3513 attributes
[attri
++] = WindowTable
[i
]->drawable
.pScreen
->blackPixel
;
3514 mask
|= CWBackPixel
;
3517 mask
|= CWOverrideRedirect
;
3518 attributes
[attri
++] = xTrue
;
3521 * create a blank cursor
3528 srcbits
= (unsigned char *)xalloc( BitmapBytePad(32)*16);
3529 mskbits
= (unsigned char *)xalloc( BitmapBytePad(32)*16);
3530 if (!srcbits
|| !mskbits
)
3538 for (j
=0; j
<BitmapBytePad(32)*16; j
++)
3539 srcbits
[j
] = mskbits
[j
] = 0x0;
3540 cursor
= AllocCursor(srcbits
, mskbits
, &cm
, 0, 0, 0, 0, 0, 0);
3543 cursorID
= FakeClientID(0);
3544 if (AddResource (cursorID
, RT_CURSOR
, (pointer
) cursor
))
3546 attributes
[attri
] = cursorID
;
3559 pWin
= savedScreenInfo
[i
].pWindow
=
3560 CreateWindow(savedScreenInfo
[i
].wid
,
3562 -RANDOM_WIDTH
, -RANDOM_WIDTH
,
3563 (unsigned short)screenInfo
.screens
[i
]->width
+ RANDOM_WIDTH
,
3564 (unsigned short)screenInfo
.screens
[i
]->height
+ RANDOM_WIDTH
,
3565 0, InputOutput
, mask
, attributes
, 0, serverClient
,
3566 wVisual (WindowTable
[i
]), &result
);
3569 FreeResource (cursorID
, RT_NONE
);
3574 if (!AddResource(pWin
->drawable
.id
, RT_WINDOW
,
3575 (pointer
)savedScreenInfo
[i
].pWindow
))
3578 if (mask
& CWBackPixmap
)
3580 MakeRootTile (pWin
);
3581 (*pWin
->drawable
.pScreen
->ChangeWindowAttributes
)(pWin
, CWBackPixmap
);
3583 MapWindow(pWin
, serverClient
);
3585 if (kind
== SCREEN_IS_TILED
&& logoScreenSaver
)
3592 * FindWindowWithOptional
3594 * search ancestors of the given window for an entry containing
3595 * a WindowOpt structure. Assumptions: some parent will
3596 * contain the structure.
3600 FindWindowWithOptional (WindowPtr w
)
3604 while (!w
->optional
);
3609 * CheckWindowOptionalNeed
3611 * check each optional entry in the given window to see if
3612 * the value is satisfied by the default rules. If so,
3613 * release the optional record
3617 CheckWindowOptionalNeed (WindowPtr w
)
3619 WindowOptPtr optional
;
3620 WindowOptPtr parentOptional
;
3624 optional
= w
->optional
;
3625 if (optional
->dontPropagateMask
!= DontPropagateMasks
[w
->dontPropagate
])
3627 if (optional
->otherEventMasks
!= 0)
3629 if (optional
->otherClients
!= NULL
)
3631 if (optional
->passiveGrabs
!= NULL
)
3633 if (optional
->userProps
!= NULL
)
3635 if (optional
->backingBitPlanes
!= ~0L)
3637 if (optional
->backingPixel
!= 0)
3640 if (optional
->boundingShape
!= NULL
)
3642 if (optional
->clipShape
!= NULL
)
3644 if (optional
->inputShape
!= NULL
)
3648 if (optional
->inputMasks
!= NULL
)
3651 parentOptional
= FindWindowWithOptional(w
)->optional
;
3652 if (optional
->visual
!= parentOptional
->visual
)
3654 if (optional
->cursor
!= None
&&
3655 (optional
->cursor
!= parentOptional
->cursor
||
3656 w
->parent
->cursorIsNone
))
3658 if (optional
->colormap
!= parentOptional
->colormap
)
3660 DisposeWindowOptional (w
);
3664 * MakeWindowOptional
3666 * create an optional record and initialize it with the default
3671 MakeWindowOptional (WindowPtr pWin
)
3673 WindowOptPtr optional
;
3674 WindowOptPtr parentOptional
;
3678 optional
= (WindowOptPtr
) xalloc (sizeof (WindowOptRec
));
3681 optional
->dontPropagateMask
= DontPropagateMasks
[pWin
->dontPropagate
];
3682 optional
->otherEventMasks
= 0;
3683 optional
->otherClients
= NULL
;
3684 optional
->passiveGrabs
= NULL
;
3685 optional
->userProps
= NULL
;
3686 optional
->backingBitPlanes
= ~0L;
3687 optional
->backingPixel
= 0;
3689 optional
->boundingShape
= NULL
;
3690 optional
->clipShape
= NULL
;
3691 optional
->inputShape
= NULL
;
3694 optional
->inputMasks
= NULL
;
3696 parentOptional
= FindWindowWithOptional(pWin
)->optional
;
3697 optional
->visual
= parentOptional
->visual
;
3698 if (!pWin
->cursorIsNone
)
3700 optional
->cursor
= parentOptional
->cursor
;
3701 optional
->cursor
->refcnt
++;
3705 optional
->cursor
= None
;
3707 optional
->colormap
= parentOptional
->colormap
;
3708 pWin
->optional
= optional
;
3714 DrawLogo(WindowPtr pWin
)
3719 unsigned int width
, height
, size
;
3722 DDXPointRec poly
[4];
3723 ChangeGCVal fore
[2], back
[2];
3725 BITS32 fmask
, bmask
;
3728 pDraw
= (DrawablePtr
)pWin
;
3729 pScreen
= pDraw
->pScreen
;
3730 x
= -pWin
->origin
.x
;
3731 y
= -pWin
->origin
.y
;
3732 width
= pScreen
->width
;
3733 height
= pScreen
->height
;
3734 pGC
= GetScratchGC(pScreen
->rootDepth
, pScreen
);
3738 if ((rand() % 100) <= 17) /* make the probability for white fairly low */
3739 fore
[0].val
= pScreen
->whitePixel
;
3741 fore
[0].val
= pScreen
->blackPixel
;
3742 if ((pWin
->backgroundState
== BackgroundPixel
) &&
3743 (cmap
= (ColormapPtr
)LookupIDByType(wColormap (pWin
), RT_COLORMAP
))) {
3744 Pixel querypixels
[2];
3746 querypixels
[0] = fore
[0].val
;
3747 querypixels
[1] = pWin
->background
.pixel
;
3748 QueryColors(cmap
, 2, querypixels
, rgb
);
3749 if ((rgb
[0].red
== rgb
[1].red
) &&
3750 (rgb
[0].green
== rgb
[1].green
) &&
3751 (rgb
[0].blue
== rgb
[1].blue
)) {
3752 if (fore
[0].val
== pScreen
->blackPixel
)
3753 fore
[0].val
= pScreen
->whitePixel
;
3755 fore
[0].val
= pScreen
->blackPixel
;
3758 fore
[1].val
= FillSolid
;
3759 fmask
= GCForeground
|GCFillStyle
;
3760 if (pWin
->backgroundState
== BackgroundPixel
) {
3761 back
[0].val
= pWin
->background
.pixel
;
3762 back
[1].val
= FillSolid
;
3763 bmask
= GCForeground
|GCFillStyle
;
3767 dixChangeGC(NullClient
, pGC
, GCTileStipXOrigin
|GCTileStipYOrigin
,
3769 back
[0].val
= FillTiled
;
3770 back
[1].ptr
= pWin
->background
.pixmap
;
3771 bmask
= GCFillStyle
|GCTile
;
3774 /* should be the same as the reference function XmuDrawLogo() */
3779 size
= RANDOM_WIDTH
+ rand() % (size
- RANDOM_WIDTH
);
3781 x
+= rand() % (width
- size
);
3782 y
+= rand() % (height
- size
);
3785 * Draw what will be the thin strokes.
3795 * Point d is 9/44 (~1/5) of the way across.
3799 if (thin
< 1) thin
= 1;
3801 d31
= thin
+ thin
+ gap
;
3802 poly
[0].x
= x
+ size
; poly
[0].y
= y
;
3803 poly
[1].x
= x
+ size
-d31
; poly
[1].y
= y
;
3804 poly
[2].x
= x
+ 0; poly
[2].y
= y
+ size
;
3805 poly
[3].x
= x
+ d31
; poly
[3].y
= y
+ size
;
3806 dixChangeGC(NullClient
, pGC
, fmask
, NULL
, fore
);
3807 ValidateGC(pDraw
, pGC
);
3808 (*pGC
->ops
->FillPolygon
)(pDraw
, pGC
, Convex
, CoordModeOrigin
, 4, poly
);
3811 * Erase area not needed for lower thin stroke.
3821 poly
[0].x
= x
+ d31
/2; poly
[0].y
= y
+ size
;
3822 poly
[1].x
= x
+ size
/ 2; poly
[1].y
= y
+ size
/2;
3823 poly
[2].x
= x
+ (size
/2)+(d31
-(d31
/2)); poly
[2].y
= y
+ size
/2;
3824 poly
[3].x
= x
+ d31
; poly
[3].y
= y
+ size
;
3825 dixChangeGC(NullClient
, pGC
, bmask
, NULL
, back
);
3826 ValidateGC(pDraw
, pGC
);
3827 (*pGC
->ops
->FillPolygon
)(pDraw
, pGC
, Convex
, CoordModeOrigin
, 4, poly
);
3830 * Erase area not needed for upper thin stroke.
3840 poly
[0].x
= x
+ size
- d31
/2; poly
[0].y
= y
;
3841 poly
[1].x
= x
+ size
/ 2; poly
[1].y
= y
+ size
/2;
3842 poly
[2].x
= x
+ (size
/2)-(d31
-(d31
/2)); poly
[2].y
= y
+ size
/2;
3843 poly
[3].x
= x
+ size
- d31
; poly
[3].y
= y
;
3844 ValidateGC(pDraw
, pGC
);
3845 (*pGC
->ops
->FillPolygon
)(pDraw
, pGC
, Convex
, CoordModeOrigin
, 4, poly
);
3848 * Draw thick stroke.
3849 * Point b is 1/4 of the way across.
3860 poly
[0].x
= x
; poly
[0].y
= y
;
3861 poly
[1].x
= x
+ size
/4; poly
[1].y
= y
;
3862 poly
[2].x
= x
+ size
; poly
[2].y
= y
+ size
;
3863 poly
[3].x
= x
+ size
- size
/4; poly
[3].y
= y
+ size
;
3864 dixChangeGC(NullClient
, pGC
, fmask
, NULL
, fore
);
3865 ValidateGC(pDraw
, pGC
);
3866 (*pGC
->ops
->FillPolygon
)(pDraw
, pGC
, Convex
, CoordModeOrigin
, 4, poly
);
3869 * Erase to create gap.
3878 poly
[0].x
= x
+ size
- thin
; poly
[0].y
= y
;
3879 poly
[1].x
= x
+ size
-( thin
+gap
); poly
[1].y
= y
;
3880 poly
[2].x
= x
+ thin
; poly
[2].y
= y
+ size
;
3881 poly
[3].x
= x
+ thin
+ gap
; poly
[3].y
= y
+ size
;
3882 dixChangeGC(NullClient
, pGC
, bmask
, NULL
, back
);
3883 ValidateGC(pDraw
, pGC
);
3884 (*pGC
->ops
->FillPolygon
)(pDraw
, pGC
, Convex
, CoordModeOrigin
, 4, poly
);