3 Copyright 1993 by Davor Matic
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation. Davor Matic makes no representations about
10 the suitability of this software for any purpose. It is provided "as
11 is" without express or implied warranty.
15 #ifdef HAVE_XNEST_CONFIG_H
16 #include <xnest-config.h>
20 #include <X11/Xproto.h>
23 #include "windowstr.h"
24 #include "pixmapstr.h"
25 #include "colormapst.h"
26 #include "scrnintstr.h"
42 DevPrivateKeyRec xnestWindowPrivateKeyRec
;
45 xnestFindWindowMatch(WindowPtr pWin
, pointer ptr
)
47 xnestWindowMatch
*wm
= (xnestWindowMatch
*) ptr
;
49 if (wm
->window
== xnestWindow(pWin
)) {
51 return WT_STOPWALKING
;
54 return WT_WALKCHILDREN
;
58 xnestWindowPtr(Window window
)
66 for (i
= 0; i
< xnestNumScreens
; i
++) {
67 WalkTree(screenInfo
.screens
[i
], xnestFindWindowMatch
, (pointer
) &wm
);
76 xnestCreateWindow(WindowPtr pWin
)
79 XSetWindowAttributes attributes
;
83 if (pWin
->drawable
.class == InputOnly
) {
85 visual
= CopyFromParent
;
88 mask
= CWEventMask
| CWBackingStore
;
89 attributes
.event_mask
= ExposureMask
;
90 attributes
.backing_store
= NotUseful
;
94 pWin
->optional
->visual
!= wVisual(pWin
->parent
)) {
96 xnestVisualFromID(pWin
->drawable
.pScreen
, wVisual(pWin
));
98 if (pWin
->optional
->colormap
) {
99 dixLookupResourceByType((pointer
*) &pCmap
, wColormap(pWin
),
100 RT_COLORMAP
, serverClient
,
102 attributes
.colormap
= xnestColormap(pCmap
);
105 attributes
.colormap
= xnestDefaultVisualColormap(visual
);
108 visual
= CopyFromParent
;
110 else { /* root windows have their own colormaps at creation time */
111 visual
= xnestVisualFromID(pWin
->drawable
.pScreen
, wVisual(pWin
));
112 dixLookupResourceByType((pointer
*) &pCmap
, wColormap(pWin
),
113 RT_COLORMAP
, serverClient
, DixUseAccess
);
115 attributes
.colormap
= xnestColormap(pCmap
);
119 xnestWindowPriv(pWin
)->window
= XCreateWindow(xnestDisplay
,
120 xnestWindowParent(pWin
),
125 pWin
->drawable
.width
,
126 pWin
->drawable
.height
,
128 pWin
->drawable
.depth
,
129 pWin
->drawable
.class,
130 visual
, mask
, &attributes
);
131 xnestWindowPriv(pWin
)->parent
= xnestWindowParent(pWin
);
132 xnestWindowPriv(pWin
)->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
133 xnestWindowPriv(pWin
)->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
134 xnestWindowPriv(pWin
)->width
= pWin
->drawable
.width
;
135 xnestWindowPriv(pWin
)->height
= pWin
->drawable
.height
;
136 xnestWindowPriv(pWin
)->border_width
= pWin
->borderWidth
;
137 xnestWindowPriv(pWin
)->sibling_above
= None
;
139 xnestWindowPriv(pWin
->nextSib
)->sibling_above
= xnestWindow(pWin
);
140 xnestWindowPriv(pWin
)->bounding_shape
= RegionCreate(NULL
, 1);
141 xnestWindowPriv(pWin
)->clip_shape
= RegionCreate(NULL
, 1);
143 if (!pWin
->parent
) /* only the root window will have the right colormap */
144 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
150 xnestDestroyWindow(WindowPtr pWin
)
153 xnestWindowPriv(pWin
->nextSib
)->sibling_above
=
154 xnestWindowPriv(pWin
)->sibling_above
;
155 RegionDestroy(xnestWindowPriv(pWin
)->bounding_shape
);
156 RegionDestroy(xnestWindowPriv(pWin
)->clip_shape
);
157 XDestroyWindow(xnestDisplay
, xnestWindow(pWin
));
158 xnestWindowPriv(pWin
)->window
= None
;
160 if (pWin
->optional
&& pWin
->optional
->colormap
&& pWin
->parent
)
161 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
167 xnestPositionWindow(WindowPtr pWin
, int x
, int y
)
169 xnestConfigureWindow(pWin
,
171 CWX
| CWY
| CWWidth
| CWHeight
| CWBorderWidth
);
177 xnestConfigureWindow(WindowPtr pWin
, unsigned int mask
)
179 unsigned int valuemask
;
180 XWindowChanges values
;
182 if (mask
& CWParent
&&
183 xnestWindowPriv(pWin
)->parent
!= xnestWindowParent(pWin
)) {
184 XReparentWindow(xnestDisplay
, xnestWindow(pWin
),
185 xnestWindowParent(pWin
),
186 pWin
->origin
.x
- wBorderWidth(pWin
),
187 pWin
->origin
.y
- wBorderWidth(pWin
));
188 xnestWindowPriv(pWin
)->parent
= xnestWindowParent(pWin
);
189 xnestWindowPriv(pWin
)->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
190 xnestWindowPriv(pWin
)->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
191 xnestWindowPriv(pWin
)->sibling_above
= None
;
193 xnestWindowPriv(pWin
->nextSib
)->sibling_above
= xnestWindow(pWin
);
199 xnestWindowPriv(pWin
)->x
!= pWin
->origin
.x
- wBorderWidth(pWin
)) {
202 xnestWindowPriv(pWin
)->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
206 xnestWindowPriv(pWin
)->y
!= pWin
->origin
.y
- wBorderWidth(pWin
)) {
209 xnestWindowPriv(pWin
)->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
212 if (mask
& CWWidth
&& xnestWindowPriv(pWin
)->width
!= pWin
->drawable
.width
) {
213 valuemask
|= CWWidth
;
214 values
.width
= xnestWindowPriv(pWin
)->width
= pWin
->drawable
.width
;
217 if (mask
& CWHeight
&&
218 xnestWindowPriv(pWin
)->height
!= pWin
->drawable
.height
) {
219 valuemask
|= CWHeight
;
220 values
.height
= xnestWindowPriv(pWin
)->height
= pWin
->drawable
.height
;
223 if (mask
& CWBorderWidth
&&
224 xnestWindowPriv(pWin
)->border_width
!= pWin
->borderWidth
) {
225 valuemask
|= CWBorderWidth
;
226 values
.border_width
=
227 xnestWindowPriv(pWin
)->border_width
= pWin
->borderWidth
;
231 XConfigureWindow(xnestDisplay
, xnestWindow(pWin
), valuemask
, &values
);
233 if (mask
& CWStackingOrder
&&
234 xnestWindowPriv(pWin
)->sibling_above
!= xnestWindowSiblingAbove(pWin
)) {
237 /* find the top sibling */
238 for (pSib
= pWin
; pSib
->prevSib
!= NullWindow
; pSib
= pSib
->prevSib
);
240 /* the top sibling */
241 valuemask
= CWStackMode
;
242 values
.stack_mode
= Above
;
243 XConfigureWindow(xnestDisplay
, xnestWindow(pSib
), valuemask
, &values
);
244 xnestWindowPriv(pSib
)->sibling_above
= None
;
246 /* the rest of siblings */
247 for (pSib
= pSib
->nextSib
; pSib
!= NullWindow
; pSib
= pSib
->nextSib
) {
248 valuemask
= CWSibling
| CWStackMode
;
249 values
.sibling
= xnestWindowSiblingAbove(pSib
);
250 values
.stack_mode
= Below
;
251 XConfigureWindow(xnestDisplay
, xnestWindow(pSib
), valuemask
,
253 xnestWindowPriv(pSib
)->sibling_above
=
254 xnestWindowSiblingAbove(pSib
);
260 xnestChangeWindowAttributes(WindowPtr pWin
, unsigned long mask
)
262 XSetWindowAttributes attributes
;
264 if (mask
& CWBackPixmap
)
265 switch (pWin
->backgroundState
) {
267 attributes
.background_pixmap
= None
;
271 attributes
.background_pixmap
= ParentRelative
;
274 case BackgroundPixmap
:
275 attributes
.background_pixmap
= xnestPixmap(pWin
->background
.pixmap
);
278 case BackgroundPixel
:
279 mask
&= ~CWBackPixmap
;
283 if (mask
& CWBackPixel
) {
284 if (pWin
->backgroundState
== BackgroundPixel
)
285 attributes
.background_pixel
= xnestPixel(pWin
->background
.pixel
);
287 mask
&= ~CWBackPixel
;
290 if (mask
& CWBorderPixmap
) {
291 if (pWin
->borderIsPixel
)
292 mask
&= ~CWBorderPixmap
;
294 attributes
.border_pixmap
= xnestPixmap(pWin
->border
.pixmap
);
297 if (mask
& CWBorderPixel
) {
298 if (pWin
->borderIsPixel
)
299 attributes
.border_pixel
= xnestPixel(pWin
->border
.pixel
);
301 mask
&= ~CWBorderPixel
;
304 if (mask
& CWBitGravity
)
305 attributes
.bit_gravity
= pWin
->bitGravity
;
307 if (mask
& CWWinGravity
) /* dix does this for us */
308 mask
&= ~CWWinGravity
;
310 if (mask
& CWBackingStore
) /* this is really not useful */
311 mask
&= ~CWBackingStore
;
313 if (mask
& CWBackingPlanes
) /* this is really not useful */
314 mask
&= ~CWBackingPlanes
;
316 if (mask
& CWBackingPixel
) /* this is really not useful */
317 mask
&= ~CWBackingPixel
;
319 if (mask
& CWOverrideRedirect
)
320 attributes
.override_redirect
= pWin
->overrideRedirect
;
322 if (mask
& CWSaveUnder
) /* this is really not useful */
323 mask
&= ~CWSaveUnder
;
325 if (mask
& CWEventMask
) /* events are handled elsewhere */
326 mask
&= ~CWEventMask
;
328 if (mask
& CWDontPropagate
) /* events are handled elsewhere */
329 mask
&= ~CWDontPropagate
;
331 if (mask
& CWColormap
) {
334 dixLookupResourceByType((pointer
*) &pCmap
, wColormap(pWin
),
335 RT_COLORMAP
, serverClient
, DixUseAccess
);
337 attributes
.colormap
= xnestColormap(pCmap
);
339 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
342 if (mask
& CWCursor
) /* this is handeled in cursor code */
346 XChangeWindowAttributes(xnestDisplay
, xnestWindow(pWin
),
353 xnestRealizeWindow(WindowPtr pWin
)
355 xnestConfigureWindow(pWin
, CWStackingOrder
);
356 xnestShapeWindow(pWin
);
357 XMapWindow(xnestDisplay
, xnestWindow(pWin
));
363 xnestUnrealizeWindow(WindowPtr pWin
)
365 XUnmapWindow(xnestDisplay
, xnestWindow(pWin
));
371 xnestCopyWindow(WindowPtr pWin
, xPoint oldOrigin
, RegionPtr oldRegion
)
376 xnestClipNotify(WindowPtr pWin
, int dx
, int dy
)
378 xnestConfigureWindow(pWin
, CWStackingOrder
);
379 xnestShapeWindow(pWin
);
383 xnestWindowExposurePredicate(Display
* display
, XEvent
* event
, XPointer ptr
)
385 return (event
->type
== Expose
&& event
->xexpose
.window
== *(Window
*) ptr
);
389 xnestWindowExposures(WindowPtr pWin
, RegionPtr pRgn
, RegionPtr other_exposed
)
395 XSync(xnestDisplay
, False
);
397 window
= xnestWindow(pWin
);
399 while (XCheckIfEvent(xnestDisplay
, &event
,
400 xnestWindowExposurePredicate
, (char *) &window
)) {
402 Box
.x1
= pWin
->drawable
.x
+ wBorderWidth(pWin
) + event
.xexpose
.x
;
403 Box
.y1
= pWin
->drawable
.y
+ wBorderWidth(pWin
) + event
.xexpose
.y
;
404 Box
.x2
= Box
.x1
+ event
.xexpose
.width
;
405 Box
.y2
= Box
.y1
+ event
.xexpose
.height
;
407 event
.xexpose
.type
= ProcessedExpose
;
409 if (RegionContainsRect(pRgn
, &Box
) != rgnIN
)
410 XPutBackEvent(xnestDisplay
, &event
);
413 miWindowExposures(pWin
, pRgn
, other_exposed
);
417 xnestSetShape(WindowPtr pWin
, int kind
)
419 xnestShapeWindow(pWin
);
420 miSetShape(pWin
, kind
);
424 xnestRegionEqual(RegionPtr pReg1
, RegionPtr pReg2
)
432 if (pReg1
== NullRegion
|| pReg2
== NullRegion
)
435 pBox1
= RegionRects(pReg1
);
436 n1
= RegionNumRects(pReg1
);
438 pBox2
= RegionRects(pReg2
);
439 n2
= RegionNumRects(pReg2
);
447 if (memcmp(pBox1
, pBox2
, n1
* sizeof(BoxRec
)))
454 xnestShapeWindow(WindowPtr pWin
)
461 if (!xnestRegionEqual(xnestWindowPriv(pWin
)->bounding_shape
,
462 wBoundingShape(pWin
))) {
464 if (wBoundingShape(pWin
)) {
465 RegionCopy(xnestWindowPriv(pWin
)->bounding_shape
,
466 wBoundingShape(pWin
));
468 reg
= XCreateRegion();
469 pBox
= RegionRects(xnestWindowPriv(pWin
)->bounding_shape
);
471 i
< RegionNumRects(xnestWindowPriv(pWin
)->bounding_shape
);
475 rect
.width
= pBox
[i
].x2
- pBox
[i
].x1
;
476 rect
.height
= pBox
[i
].y2
- pBox
[i
].y1
;
477 XUnionRectWithRegion(&rect
, reg
, reg
);
479 XShapeCombineRegion(xnestDisplay
, xnestWindow(pWin
),
480 ShapeBounding
, 0, 0, reg
, ShapeSet
);
484 RegionEmpty(xnestWindowPriv(pWin
)->bounding_shape
);
486 XShapeCombineMask(xnestDisplay
, xnestWindow(pWin
),
487 ShapeBounding
, 0, 0, None
, ShapeSet
);
491 if (!xnestRegionEqual(xnestWindowPriv(pWin
)->clip_shape
, wClipShape(pWin
))) {
493 if (wClipShape(pWin
)) {
494 RegionCopy(xnestWindowPriv(pWin
)->clip_shape
, wClipShape(pWin
));
496 reg
= XCreateRegion();
497 pBox
= RegionRects(xnestWindowPriv(pWin
)->clip_shape
);
499 i
< RegionNumRects(xnestWindowPriv(pWin
)->clip_shape
); i
++) {
502 rect
.width
= pBox
[i
].x2
- pBox
[i
].x1
;
503 rect
.height
= pBox
[i
].y2
- pBox
[i
].y1
;
504 XUnionRectWithRegion(&rect
, reg
, reg
);
506 XShapeCombineRegion(xnestDisplay
, xnestWindow(pWin
),
507 ShapeClip
, 0, 0, reg
, ShapeSet
);
511 RegionEmpty(xnestWindowPriv(pWin
)->clip_shape
);
513 XShapeCombineMask(xnestDisplay
, xnestWindow(pWin
),
514 ShapeClip
, 0, 0, None
, ShapeSet
);