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 int xnestWindowPrivateIndex
;
45 xnestFindWindowMatch(WindowPtr pWin
, pointer ptr
)
47 xnestWindowMatch
*wm
= (xnestWindowMatch
*)ptr
;
48 if (wm
->window
== xnestWindow(pWin
)) {
50 return WT_STOPWALKING
;
53 return WT_WALKCHILDREN
;
57 xnestWindowPtr(Window window
)
65 for (i
= 0; i
< xnestNumScreens
; i
++) {
66 WalkTree(screenInfo
.screens
[i
], xnestFindWindowMatch
, (pointer
) &wm
);
74 xnestCreateWindow(WindowPtr pWin
)
77 XSetWindowAttributes attributes
;
81 if (pWin
->drawable
.class == InputOnly
) {
83 visual
= CopyFromParent
;
86 mask
= CWEventMask
| CWBackingStore
;
87 attributes
.event_mask
= ExposureMask
;
88 attributes
.backing_store
= NotUseful
;
91 if (pWin
->optional
&& pWin
->optional
->visual
!= wVisual(pWin
->parent
)) {
92 visual
= xnestVisualFromID(pWin
->drawable
.pScreen
, wVisual(pWin
));
94 if (pWin
->optional
->colormap
) {
95 pCmap
= (ColormapPtr
)LookupIDByType(wColormap(pWin
), RT_COLORMAP
);
96 attributes
.colormap
= xnestColormap(pCmap
);
99 attributes
.colormap
= xnestDefaultVisualColormap(visual
);
102 visual
= CopyFromParent
;
104 else { /* root windows have their own colormaps at creation time */
105 visual
= xnestVisualFromID(pWin
->drawable
.pScreen
, wVisual(pWin
));
106 pCmap
= (ColormapPtr
)LookupIDByType(wColormap(pWin
), RT_COLORMAP
);
108 attributes
.colormap
= xnestColormap(pCmap
);
112 xnestWindowPriv(pWin
)->window
= XCreateWindow(xnestDisplay
,
113 xnestWindowParent(pWin
),
118 pWin
->drawable
.width
,
119 pWin
->drawable
.height
,
121 pWin
->drawable
.depth
,
122 pWin
->drawable
.class,
125 xnestWindowPriv(pWin
)->parent
= xnestWindowParent(pWin
);
126 xnestWindowPriv(pWin
)->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
127 xnestWindowPriv(pWin
)->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
128 xnestWindowPriv(pWin
)->width
= pWin
->drawable
.width
;
129 xnestWindowPriv(pWin
)->height
= pWin
->drawable
.height
;
130 xnestWindowPriv(pWin
)->border_width
= pWin
->borderWidth
;
131 xnestWindowPriv(pWin
)->sibling_above
= None
;
133 xnestWindowPriv(pWin
->nextSib
)->sibling_above
= xnestWindow(pWin
);
135 xnestWindowPriv(pWin
)->bounding_shape
=
136 REGION_CREATE(pWin
->drawable
.pScreen
, NULL
, 1);
137 xnestWindowPriv(pWin
)->clip_shape
=
138 REGION_CREATE(pWin
->drawable
.pScreen
, NULL
, 1);
141 if (!pWin
->parent
) /* only the root window will have the right colormap */
142 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
148 xnestDestroyWindow(WindowPtr pWin
)
151 xnestWindowPriv(pWin
->nextSib
)->sibling_above
=
152 xnestWindowPriv(pWin
)->sibling_above
;
154 REGION_DESTROY(pWin
->drawable
.pScreen
,
155 xnestWindowPriv(pWin
)->bounding_shape
);
156 REGION_DESTROY(pWin
->drawable
.pScreen
,
157 xnestWindowPriv(pWin
)->clip_shape
);
159 XDestroyWindow(xnestDisplay
, xnestWindow(pWin
));
160 xnestWindowPriv(pWin
)->window
= None
;
162 if (pWin
->optional
&& pWin
->optional
->colormap
&& pWin
->parent
)
163 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
169 xnestPositionWindow(WindowPtr pWin
, int x
, int y
)
171 xnestConfigureWindow(pWin
,
181 xnestConfigureWindow(WindowPtr pWin
, unsigned int mask
)
183 unsigned int valuemask
;
184 XWindowChanges values
;
186 if (mask
& CWParent
&&
187 xnestWindowPriv(pWin
)->parent
!= xnestWindowParent(pWin
)) {
188 XReparentWindow(xnestDisplay
, xnestWindow(pWin
),
189 xnestWindowParent(pWin
),
190 pWin
->origin
.x
- wBorderWidth(pWin
),
191 pWin
->origin
.y
- wBorderWidth(pWin
));
192 xnestWindowPriv(pWin
)->parent
= xnestWindowParent(pWin
);
193 xnestWindowPriv(pWin
)->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
194 xnestWindowPriv(pWin
)->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
195 xnestWindowPriv(pWin
)->sibling_above
= None
;
197 xnestWindowPriv(pWin
->nextSib
)->sibling_above
= xnestWindow(pWin
);
203 xnestWindowPriv(pWin
)->x
!= pWin
->origin
.x
- wBorderWidth(pWin
)) {
206 xnestWindowPriv(pWin
)->x
=
207 pWin
->origin
.x
- wBorderWidth(pWin
);
211 xnestWindowPriv(pWin
)->y
!= pWin
->origin
.y
- wBorderWidth(pWin
)) {
214 xnestWindowPriv(pWin
)->y
=
215 pWin
->origin
.y
- wBorderWidth(pWin
);
218 if (mask
& CWWidth
&&
219 xnestWindowPriv(pWin
)->width
!= pWin
->drawable
.width
) {
220 valuemask
|= CWWidth
;
222 xnestWindowPriv(pWin
)->width
=
223 pWin
->drawable
.width
;
226 if (mask
& CWHeight
&&
227 xnestWindowPriv(pWin
)->height
!= pWin
->drawable
.height
) {
228 valuemask
|= CWHeight
;
230 xnestWindowPriv(pWin
)->height
=
231 pWin
->drawable
.height
;
234 if (mask
& CWBorderWidth
&&
235 xnestWindowPriv(pWin
)->border_width
!= pWin
->borderWidth
) {
236 valuemask
|= CWBorderWidth
;
237 values
.border_width
=
238 xnestWindowPriv(pWin
)->border_width
=
243 XConfigureWindow(xnestDisplay
, xnestWindow(pWin
), valuemask
, &values
);
245 if (mask
& CWStackingOrder
&&
246 xnestWindowPriv(pWin
)->sibling_above
!= xnestWindowSiblingAbove(pWin
)) {
249 /* find the top sibling */
250 for (pSib
= pWin
; pSib
->prevSib
!= NullWindow
; pSib
= pSib
->prevSib
);
252 /* the top sibling */
253 valuemask
= CWStackMode
;
254 values
.stack_mode
= Above
;
255 XConfigureWindow(xnestDisplay
, xnestWindow(pSib
), valuemask
, &values
);
256 xnestWindowPriv(pSib
)->sibling_above
= None
;
258 /* the rest of siblings */
259 for (pSib
= pSib
->nextSib
; pSib
!= NullWindow
; pSib
= pSib
->nextSib
) {
260 valuemask
= CWSibling
| CWStackMode
;
261 values
.sibling
= xnestWindowSiblingAbove(pSib
);
262 values
.stack_mode
= Below
;
263 XConfigureWindow(xnestDisplay
, xnestWindow(pSib
), valuemask
, &values
);
264 xnestWindowPriv(pSib
)->sibling_above
= xnestWindowSiblingAbove(pSib
);
270 xnestChangeWindowAttributes(WindowPtr pWin
, unsigned long mask
)
272 XSetWindowAttributes attributes
;
274 if (mask
& CWBackPixmap
)
275 switch (pWin
->backgroundState
) {
277 attributes
.background_pixmap
= None
;
281 attributes
.background_pixmap
= ParentRelative
;
284 case BackgroundPixmap
:
285 attributes
.background_pixmap
= xnestPixmap(pWin
->background
.pixmap
);
288 case BackgroundPixel
:
289 mask
&= ~CWBackPixmap
;
293 if (mask
& CWBackPixel
) {
294 if (pWin
->backgroundState
== BackgroundPixel
)
295 attributes
.background_pixel
= xnestPixel(pWin
->background
.pixel
);
297 mask
&= ~CWBackPixel
;
300 if (mask
& CWBorderPixmap
) {
301 if (pWin
->borderIsPixel
)
302 mask
&= ~CWBorderPixmap
;
304 attributes
.border_pixmap
= xnestPixmap(pWin
->border
.pixmap
);
307 if (mask
& CWBorderPixel
) {
308 if (pWin
->borderIsPixel
)
309 attributes
.border_pixel
= xnestPixel(pWin
->border
.pixel
);
311 mask
&= ~CWBorderPixel
;
314 if (mask
& CWBitGravity
)
315 attributes
.bit_gravity
= pWin
->bitGravity
;
317 if (mask
& CWWinGravity
) /* dix does this for us */
318 mask
&= ~CWWinGravity
;
320 if (mask
& CWBackingStore
) /* this is really not useful */
321 mask
&= ~CWBackingStore
;
323 if (mask
& CWBackingPlanes
) /* this is really not useful */
324 mask
&= ~CWBackingPlanes
;
326 if (mask
& CWBackingPixel
) /* this is really not useful */
327 mask
&= ~CWBackingPixel
;
329 if (mask
& CWOverrideRedirect
)
330 attributes
.override_redirect
= pWin
->overrideRedirect
;
332 if (mask
& CWSaveUnder
) /* this is really not useful */
333 mask
&= ~CWSaveUnder
;
335 if (mask
& CWEventMask
) /* events are handled elsewhere */
336 mask
&= ~CWEventMask
;
338 if (mask
& CWDontPropagate
) /* events are handled elsewhere */
339 mask
&= ~CWDontPropagate
;
341 if (mask
& CWColormap
) {
344 pCmap
= (ColormapPtr
)LookupIDByType(wColormap(pWin
), RT_COLORMAP
);
346 attributes
.colormap
= xnestColormap(pCmap
);
348 xnestSetInstalledColormapWindows(pWin
->drawable
.pScreen
);
351 if (mask
& CWCursor
) /* this is handeled in cursor code */
355 XChangeWindowAttributes(xnestDisplay
, xnestWindow(pWin
),
362 xnestRealizeWindow(WindowPtr pWin
)
364 xnestConfigureWindow(pWin
, CWStackingOrder
);
366 xnestShapeWindow(pWin
);
368 XMapWindow(xnestDisplay
, xnestWindow(pWin
));
374 xnestUnrealizeWindow(WindowPtr pWin
)
376 XUnmapWindow(xnestDisplay
, xnestWindow(pWin
));
382 xnestPaintWindowBackground(WindowPtr pWin
, RegionPtr pRegion
, int what
)
387 xnestConfigureWindow(pWin
, CWWidth
| CWHeight
);
389 pBox
= REGION_RECTS(pRegion
);
390 for (i
= 0; i
< REGION_NUM_RECTS(pRegion
); i
++)
391 XClearArea(xnestDisplay
, xnestWindow(pWin
),
392 pBox
[i
].x1
- pWin
->drawable
.x
,
393 pBox
[i
].y1
- pWin
->drawable
.y
,
394 pBox
[i
].x2
- pBox
[i
].x1
,
395 pBox
[i
].y2
- pBox
[i
].y1
,
400 xnestPaintWindowBorder(WindowPtr pWin
, RegionPtr pRegion
, int what
)
402 xnestConfigureWindow(pWin
, CWBorderWidth
);
406 xnestCopyWindow(WindowPtr pWin
, xPoint oldOrigin
, RegionPtr oldRegion
)
411 xnestClipNotify(WindowPtr pWin
, int dx
, int dy
)
413 xnestConfigureWindow(pWin
, CWStackingOrder
);
415 xnestShapeWindow(pWin
);
420 xnestWindowExposurePredicate(Display
*display
, XEvent
*event
, XPointer ptr
)
422 return (event
->type
== Expose
&& event
->xexpose
.window
== *(Window
*)ptr
);
426 xnestWindowExposures(WindowPtr pWin
, RegionPtr pRgn
, RegionPtr other_exposed
)
432 XSync(xnestDisplay
, False
);
434 window
= xnestWindow(pWin
);
436 while (XCheckIfEvent(xnestDisplay
, &event
,
437 xnestWindowExposurePredicate
, (char *)&window
)) {
439 Box
.x1
= pWin
->drawable
.x
+ wBorderWidth(pWin
) + event
.xexpose
.x
;
440 Box
.y1
= pWin
->drawable
.y
+ wBorderWidth(pWin
) + event
.xexpose
.y
;
441 Box
.x2
= Box
.x1
+ event
.xexpose
.width
;
442 Box
.y2
= Box
.y1
+ event
.xexpose
.height
;
444 event
.xexpose
.type
= ProcessedExpose
;
446 if (RECT_IN_REGION(pWin
->drawable
.pScreen
, pRgn
, &Box
) != rgnIN
)
447 XPutBackEvent(xnestDisplay
, &event
);
450 miWindowExposures(pWin
, pRgn
, other_exposed
);
455 xnestSetShape(WindowPtr pWin
)
457 xnestShapeWindow(pWin
);
462 xnestRegionEqual(RegionPtr pReg1
, RegionPtr pReg2
)
467 if (pReg1
== pReg2
) return True
;
469 if (pReg1
== NullRegion
|| pReg2
== NullRegion
) return False
;
471 pBox1
= REGION_RECTS(pReg1
);
472 n1
= REGION_NUM_RECTS(pReg1
);
474 pBox2
= REGION_RECTS(pReg2
);
475 n2
= REGION_NUM_RECTS(pReg2
);
477 if (n1
!= n2
) return False
;
479 if (pBox1
== pBox2
) return True
;
481 if (memcmp(pBox1
, pBox2
, n1
* sizeof(BoxRec
))) return False
;
487 xnestShapeWindow(WindowPtr pWin
)
494 if (!xnestRegionEqual(xnestWindowPriv(pWin
)->bounding_shape
,
495 wBoundingShape(pWin
))) {
497 if (wBoundingShape(pWin
)) {
498 REGION_COPY(pWin
->drawable
.pScreen
,
499 xnestWindowPriv(pWin
)->bounding_shape
, wBoundingShape(pWin
));
501 reg
= XCreateRegion();
502 pBox
= REGION_RECTS(xnestWindowPriv(pWin
)->bounding_shape
);
504 i
< REGION_NUM_RECTS(xnestWindowPriv(pWin
)->bounding_shape
);
508 rect
.width
= pBox
[i
].x2
- pBox
[i
].x1
;
509 rect
.height
= pBox
[i
].y2
- pBox
[i
].y1
;
510 XUnionRectWithRegion(&rect
, reg
, reg
);
512 XShapeCombineRegion(xnestDisplay
, xnestWindow(pWin
),
513 ShapeBounding
, 0, 0, reg
, ShapeSet
);
517 REGION_EMPTY(pWin
->drawable
.pScreen
,
518 xnestWindowPriv(pWin
)->bounding_shape
);
520 XShapeCombineMask(xnestDisplay
, xnestWindow(pWin
),
521 ShapeBounding
, 0, 0, None
, ShapeSet
);
525 if (!xnestRegionEqual(xnestWindowPriv(pWin
)->clip_shape
,
528 if (wClipShape(pWin
)) {
529 REGION_COPY(pWin
->drawable
.pScreen
,
530 xnestWindowPriv(pWin
)->clip_shape
, wClipShape(pWin
));
532 reg
= XCreateRegion();
533 pBox
= REGION_RECTS(xnestWindowPriv(pWin
)->clip_shape
);
535 i
< REGION_NUM_RECTS(xnestWindowPriv(pWin
)->clip_shape
);
539 rect
.width
= pBox
[i
].x2
- pBox
[i
].x1
;
540 rect
.height
= pBox
[i
].y2
- pBox
[i
].y1
;
541 XUnionRectWithRegion(&rect
, reg
, reg
);
543 XShapeCombineRegion(xnestDisplay
, xnestWindow(pWin
),
544 ShapeClip
, 0, 0, reg
, ShapeSet
);
548 REGION_EMPTY(pWin
->drawable
.pScreen
,
549 xnestWindowPriv(pWin
)->clip_shape
);
551 XShapeCombineMask(xnestDisplay
, xnestWindow(pWin
),
552 ShapeClip
, 0, 0, None
, ShapeSet
);