1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1993 by Davor Matic
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software
6*4882a593Smuzhiyun and its documentation for any purpose is hereby granted without fee,
7*4882a593Smuzhiyun provided that the above copyright notice appear in all copies and that
8*4882a593Smuzhiyun both that copyright notice and this permission notice appear in
9*4882a593Smuzhiyun supporting documentation. Davor Matic makes no representations about
10*4882a593Smuzhiyun the suitability of this software for any purpose. It is provided "as
11*4882a593Smuzhiyun is" without express or implied warranty.
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #ifdef HAVE_XNEST_CONFIG_H
16*4882a593Smuzhiyun #include <xnest-config.h>
17*4882a593Smuzhiyun #endif
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <X11/X.h>
20*4882a593Smuzhiyun #include <X11/Xproto.h>
21*4882a593Smuzhiyun #include "gcstruct.h"
22*4882a593Smuzhiyun #include "window.h"
23*4882a593Smuzhiyun #include "windowstr.h"
24*4882a593Smuzhiyun #include "pixmapstr.h"
25*4882a593Smuzhiyun #include "colormapst.h"
26*4882a593Smuzhiyun #include "scrnintstr.h"
27*4882a593Smuzhiyun #include "region.h"
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include "mi.h"
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "Xnest.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include "Display.h"
34*4882a593Smuzhiyun #include "Screen.h"
35*4882a593Smuzhiyun #include "XNGC.h"
36*4882a593Smuzhiyun #include "Drawable.h"
37*4882a593Smuzhiyun #include "Color.h"
38*4882a593Smuzhiyun #include "Visual.h"
39*4882a593Smuzhiyun #include "Events.h"
40*4882a593Smuzhiyun #include "Args.h"
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun DevPrivateKeyRec xnestWindowPrivateKeyRec;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun static int
xnestFindWindowMatch(WindowPtr pWin,void * ptr)45*4882a593Smuzhiyun xnestFindWindowMatch(WindowPtr pWin, void *ptr)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun xnestWindowMatch *wm = (xnestWindowMatch *) ptr;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun if (wm->window == xnestWindow(pWin)) {
50*4882a593Smuzhiyun wm->pWin = pWin;
51*4882a593Smuzhiyun return WT_STOPWALKING;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun else
54*4882a593Smuzhiyun return WT_WALKCHILDREN;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun WindowPtr
xnestWindowPtr(Window window)58*4882a593Smuzhiyun xnestWindowPtr(Window window)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun xnestWindowMatch wm;
61*4882a593Smuzhiyun int i;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun wm.pWin = NullWindow;
64*4882a593Smuzhiyun wm.window = window;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun for (i = 0; i < xnestNumScreens; i++) {
67*4882a593Smuzhiyun WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (void *) &wm);
68*4882a593Smuzhiyun if (wm.pWin)
69*4882a593Smuzhiyun break;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun return wm.pWin;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun Bool
xnestCreateWindow(WindowPtr pWin)76*4882a593Smuzhiyun xnestCreateWindow(WindowPtr pWin)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun unsigned long mask;
79*4882a593Smuzhiyun XSetWindowAttributes attributes;
80*4882a593Smuzhiyun Visual *visual;
81*4882a593Smuzhiyun ColormapPtr pCmap;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun if (pWin->drawable.class == InputOnly) {
84*4882a593Smuzhiyun mask = 0L;
85*4882a593Smuzhiyun visual = CopyFromParent;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun else {
88*4882a593Smuzhiyun mask = CWEventMask | CWBackingStore;
89*4882a593Smuzhiyun attributes.event_mask = ExposureMask;
90*4882a593Smuzhiyun attributes.backing_store = NotUseful;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun if (pWin->parent) {
93*4882a593Smuzhiyun if (pWin->optional &&
94*4882a593Smuzhiyun pWin->optional->visual != wVisual(pWin->parent)) {
95*4882a593Smuzhiyun visual =
96*4882a593Smuzhiyun xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
97*4882a593Smuzhiyun mask |= CWColormap;
98*4882a593Smuzhiyun if (pWin->optional->colormap) {
99*4882a593Smuzhiyun dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
100*4882a593Smuzhiyun RT_COLORMAP, serverClient,
101*4882a593Smuzhiyun DixUseAccess);
102*4882a593Smuzhiyun attributes.colormap = xnestColormap(pCmap);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun else
105*4882a593Smuzhiyun attributes.colormap = xnestDefaultVisualColormap(visual);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun else
108*4882a593Smuzhiyun visual = CopyFromParent;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun else { /* root windows have their own colormaps at creation time */
111*4882a593Smuzhiyun visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
112*4882a593Smuzhiyun dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
113*4882a593Smuzhiyun RT_COLORMAP, serverClient, DixUseAccess);
114*4882a593Smuzhiyun mask |= CWColormap;
115*4882a593Smuzhiyun attributes.colormap = xnestColormap(pCmap);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
120*4882a593Smuzhiyun xnestWindowParent(pWin),
121*4882a593Smuzhiyun pWin->origin.x -
122*4882a593Smuzhiyun wBorderWidth(pWin),
123*4882a593Smuzhiyun pWin->origin.y -
124*4882a593Smuzhiyun wBorderWidth(pWin),
125*4882a593Smuzhiyun pWin->drawable.width,
126*4882a593Smuzhiyun pWin->drawable.height,
127*4882a593Smuzhiyun pWin->borderWidth,
128*4882a593Smuzhiyun pWin->drawable.depth,
129*4882a593Smuzhiyun pWin->drawable.class,
130*4882a593Smuzhiyun visual, mask, &attributes);
131*4882a593Smuzhiyun xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
132*4882a593Smuzhiyun xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
133*4882a593Smuzhiyun xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
134*4882a593Smuzhiyun xnestWindowPriv(pWin)->width = pWin->drawable.width;
135*4882a593Smuzhiyun xnestWindowPriv(pWin)->height = pWin->drawable.height;
136*4882a593Smuzhiyun xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
137*4882a593Smuzhiyun xnestWindowPriv(pWin)->sibling_above = None;
138*4882a593Smuzhiyun if (pWin->nextSib)
139*4882a593Smuzhiyun xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
140*4882a593Smuzhiyun xnestWindowPriv(pWin)->bounding_shape = RegionCreate(NULL, 1);
141*4882a593Smuzhiyun xnestWindowPriv(pWin)->clip_shape = RegionCreate(NULL, 1);
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun if (!pWin->parent) /* only the root window will have the right colormap */
144*4882a593Smuzhiyun xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun return True;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun Bool
xnestDestroyWindow(WindowPtr pWin)150*4882a593Smuzhiyun xnestDestroyWindow(WindowPtr pWin)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun if (pWin->nextSib)
153*4882a593Smuzhiyun xnestWindowPriv(pWin->nextSib)->sibling_above =
154*4882a593Smuzhiyun xnestWindowPriv(pWin)->sibling_above;
155*4882a593Smuzhiyun RegionDestroy(xnestWindowPriv(pWin)->bounding_shape);
156*4882a593Smuzhiyun RegionDestroy(xnestWindowPriv(pWin)->clip_shape);
157*4882a593Smuzhiyun XDestroyWindow(xnestDisplay, xnestWindow(pWin));
158*4882a593Smuzhiyun xnestWindowPriv(pWin)->window = None;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if (pWin->optional && pWin->optional->colormap && pWin->parent)
161*4882a593Smuzhiyun xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun return True;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun Bool
xnestPositionWindow(WindowPtr pWin,int x,int y)167*4882a593Smuzhiyun xnestPositionWindow(WindowPtr pWin, int x, int y)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun xnestConfigureWindow(pWin,
170*4882a593Smuzhiyun CWParent |
171*4882a593Smuzhiyun CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun return True;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun void
xnestConfigureWindow(WindowPtr pWin,unsigned int mask)177*4882a593Smuzhiyun xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun unsigned int valuemask;
180*4882a593Smuzhiyun XWindowChanges values;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (mask & CWParent &&
183*4882a593Smuzhiyun xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
184*4882a593Smuzhiyun XReparentWindow(xnestDisplay, xnestWindow(pWin),
185*4882a593Smuzhiyun xnestWindowParent(pWin),
186*4882a593Smuzhiyun pWin->origin.x - wBorderWidth(pWin),
187*4882a593Smuzhiyun pWin->origin.y - wBorderWidth(pWin));
188*4882a593Smuzhiyun xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
189*4882a593Smuzhiyun xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
190*4882a593Smuzhiyun xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
191*4882a593Smuzhiyun xnestWindowPriv(pWin)->sibling_above = None;
192*4882a593Smuzhiyun if (pWin->nextSib)
193*4882a593Smuzhiyun xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun valuemask = 0;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun if (mask & CWX &&
199*4882a593Smuzhiyun xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
200*4882a593Smuzhiyun valuemask |= CWX;
201*4882a593Smuzhiyun values.x =
202*4882a593Smuzhiyun xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun if (mask & CWY &&
206*4882a593Smuzhiyun xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
207*4882a593Smuzhiyun valuemask |= CWY;
208*4882a593Smuzhiyun values.y =
209*4882a593Smuzhiyun xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun if (mask & CWWidth && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
213*4882a593Smuzhiyun valuemask |= CWWidth;
214*4882a593Smuzhiyun values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if (mask & CWHeight &&
218*4882a593Smuzhiyun xnestWindowPriv(pWin)->height != pWin->drawable.height) {
219*4882a593Smuzhiyun valuemask |= CWHeight;
220*4882a593Smuzhiyun values.height = xnestWindowPriv(pWin)->height = pWin->drawable.height;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun if (mask & CWBorderWidth &&
224*4882a593Smuzhiyun xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
225*4882a593Smuzhiyun valuemask |= CWBorderWidth;
226*4882a593Smuzhiyun values.border_width =
227*4882a593Smuzhiyun xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (valuemask)
231*4882a593Smuzhiyun XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (mask & CWStackingOrder &&
234*4882a593Smuzhiyun xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
235*4882a593Smuzhiyun WindowPtr pSib;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* find the top sibling */
238*4882a593Smuzhiyun for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun /* the top sibling */
241*4882a593Smuzhiyun valuemask = CWStackMode;
242*4882a593Smuzhiyun values.stack_mode = Above;
243*4882a593Smuzhiyun XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
244*4882a593Smuzhiyun xnestWindowPriv(pSib)->sibling_above = None;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /* the rest of siblings */
247*4882a593Smuzhiyun for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
248*4882a593Smuzhiyun valuemask = CWSibling | CWStackMode;
249*4882a593Smuzhiyun values.sibling = xnestWindowSiblingAbove(pSib);
250*4882a593Smuzhiyun values.stack_mode = Below;
251*4882a593Smuzhiyun XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask,
252*4882a593Smuzhiyun &values);
253*4882a593Smuzhiyun xnestWindowPriv(pSib)->sibling_above =
254*4882a593Smuzhiyun xnestWindowSiblingAbove(pSib);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun Bool
xnestChangeWindowAttributes(WindowPtr pWin,unsigned long mask)260*4882a593Smuzhiyun xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun XSetWindowAttributes attributes;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun if (mask & CWBackPixmap)
265*4882a593Smuzhiyun switch (pWin->backgroundState) {
266*4882a593Smuzhiyun case None:
267*4882a593Smuzhiyun attributes.background_pixmap = None;
268*4882a593Smuzhiyun break;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun case ParentRelative:
271*4882a593Smuzhiyun attributes.background_pixmap = ParentRelative;
272*4882a593Smuzhiyun break;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun case BackgroundPixmap:
275*4882a593Smuzhiyun attributes.background_pixmap = xnestPixmap(pWin->background.pixmap);
276*4882a593Smuzhiyun break;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun case BackgroundPixel:
279*4882a593Smuzhiyun mask &= ~CWBackPixmap;
280*4882a593Smuzhiyun break;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun if (mask & CWBackPixel) {
284*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixel)
285*4882a593Smuzhiyun attributes.background_pixel = xnestPixel(pWin->background.pixel);
286*4882a593Smuzhiyun else
287*4882a593Smuzhiyun mask &= ~CWBackPixel;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (mask & CWBorderPixmap) {
291*4882a593Smuzhiyun if (pWin->borderIsPixel)
292*4882a593Smuzhiyun mask &= ~CWBorderPixmap;
293*4882a593Smuzhiyun else
294*4882a593Smuzhiyun attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (mask & CWBorderPixel) {
298*4882a593Smuzhiyun if (pWin->borderIsPixel)
299*4882a593Smuzhiyun attributes.border_pixel = xnestPixel(pWin->border.pixel);
300*4882a593Smuzhiyun else
301*4882a593Smuzhiyun mask &= ~CWBorderPixel;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun if (mask & CWBitGravity)
305*4882a593Smuzhiyun attributes.bit_gravity = pWin->bitGravity;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (mask & CWWinGravity) /* dix does this for us */
308*4882a593Smuzhiyun mask &= ~CWWinGravity;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (mask & CWBackingStore) /* this is really not useful */
311*4882a593Smuzhiyun mask &= ~CWBackingStore;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (mask & CWBackingPlanes) /* this is really not useful */
314*4882a593Smuzhiyun mask &= ~CWBackingPlanes;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun if (mask & CWBackingPixel) /* this is really not useful */
317*4882a593Smuzhiyun mask &= ~CWBackingPixel;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (mask & CWOverrideRedirect)
320*4882a593Smuzhiyun attributes.override_redirect = pWin->overrideRedirect;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun if (mask & CWSaveUnder) /* this is really not useful */
323*4882a593Smuzhiyun mask &= ~CWSaveUnder;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun if (mask & CWEventMask) /* events are handled elsewhere */
326*4882a593Smuzhiyun mask &= ~CWEventMask;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun if (mask & CWDontPropagate) /* events are handled elsewhere */
329*4882a593Smuzhiyun mask &= ~CWDontPropagate;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (mask & CWColormap) {
332*4882a593Smuzhiyun ColormapPtr pCmap;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
335*4882a593Smuzhiyun RT_COLORMAP, serverClient, DixUseAccess);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun attributes.colormap = xnestColormap(pCmap);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun if (mask & CWCursor) /* this is handeled in cursor code */
343*4882a593Smuzhiyun mask &= ~CWCursor;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if (mask)
346*4882a593Smuzhiyun XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
347*4882a593Smuzhiyun mask, &attributes);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun return True;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun Bool
xnestRealizeWindow(WindowPtr pWin)353*4882a593Smuzhiyun xnestRealizeWindow(WindowPtr pWin)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun xnestConfigureWindow(pWin, CWStackingOrder);
356*4882a593Smuzhiyun xnestShapeWindow(pWin);
357*4882a593Smuzhiyun XMapWindow(xnestDisplay, xnestWindow(pWin));
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun return True;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun Bool
xnestUnrealizeWindow(WindowPtr pWin)363*4882a593Smuzhiyun xnestUnrealizeWindow(WindowPtr pWin)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun XUnmapWindow(xnestDisplay, xnestWindow(pWin));
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun return True;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun void
xnestCopyWindow(WindowPtr pWin,xPoint oldOrigin,RegionPtr oldRegion)371*4882a593Smuzhiyun xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun void
xnestClipNotify(WindowPtr pWin,int dx,int dy)376*4882a593Smuzhiyun xnestClipNotify(WindowPtr pWin, int dx, int dy)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun xnestConfigureWindow(pWin, CWStackingOrder);
379*4882a593Smuzhiyun xnestShapeWindow(pWin);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun static Bool
xnestWindowExposurePredicate(Display * dpy,XEvent * event,XPointer ptr)383*4882a593Smuzhiyun xnestWindowExposurePredicate(Display * dpy, XEvent * event, XPointer ptr)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun return (event->type == Expose && event->xexpose.window == *(Window *) ptr);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun void
xnestWindowExposures(WindowPtr pWin,RegionPtr pRgn)389*4882a593Smuzhiyun xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun XEvent event;
392*4882a593Smuzhiyun Window window;
393*4882a593Smuzhiyun BoxRec Box;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun XSync(xnestDisplay, False);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun window = xnestWindow(pWin);
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun while (XCheckIfEvent(xnestDisplay, &event,
400*4882a593Smuzhiyun xnestWindowExposurePredicate, (char *) &window)) {
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x;
403*4882a593Smuzhiyun Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y;
404*4882a593Smuzhiyun Box.x2 = Box.x1 + event.xexpose.width;
405*4882a593Smuzhiyun Box.y2 = Box.y1 + event.xexpose.height;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun event.xexpose.type = ProcessedExpose;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (RegionContainsRect(pRgn, &Box) != rgnIN)
410*4882a593Smuzhiyun XPutBackEvent(xnestDisplay, &event);
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun miWindowExposures(pWin, pRgn);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun void
xnestSetShape(WindowPtr pWin,int kind)417*4882a593Smuzhiyun xnestSetShape(WindowPtr pWin, int kind)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun xnestShapeWindow(pWin);
420*4882a593Smuzhiyun miSetShape(pWin, kind);
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun static Bool
xnestRegionEqual(RegionPtr pReg1,RegionPtr pReg2)424*4882a593Smuzhiyun xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun BoxPtr pBox1, pBox2;
427*4882a593Smuzhiyun unsigned int n1, n2;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun if (pReg1 == pReg2)
430*4882a593Smuzhiyun return True;
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun if (pReg1 == NullRegion || pReg2 == NullRegion)
433*4882a593Smuzhiyun return False;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun pBox1 = RegionRects(pReg1);
436*4882a593Smuzhiyun n1 = RegionNumRects(pReg1);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun pBox2 = RegionRects(pReg2);
439*4882a593Smuzhiyun n2 = RegionNumRects(pReg2);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun if (n1 != n2)
442*4882a593Smuzhiyun return False;
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun if (pBox1 == pBox2)
445*4882a593Smuzhiyun return True;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec)))
448*4882a593Smuzhiyun return False;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun return True;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun void
xnestShapeWindow(WindowPtr pWin)454*4882a593Smuzhiyun xnestShapeWindow(WindowPtr pWin)
455*4882a593Smuzhiyun {
456*4882a593Smuzhiyun Region reg;
457*4882a593Smuzhiyun BoxPtr pBox;
458*4882a593Smuzhiyun XRectangle rect;
459*4882a593Smuzhiyun int i;
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
462*4882a593Smuzhiyun wBoundingShape(pWin))) {
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun if (wBoundingShape(pWin)) {
465*4882a593Smuzhiyun RegionCopy(xnestWindowPriv(pWin)->bounding_shape,
466*4882a593Smuzhiyun wBoundingShape(pWin));
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun reg = XCreateRegion();
469*4882a593Smuzhiyun pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
470*4882a593Smuzhiyun for (i = 0;
471*4882a593Smuzhiyun i < RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
472*4882a593Smuzhiyun i++) {
473*4882a593Smuzhiyun rect.x = pBox[i].x1;
474*4882a593Smuzhiyun rect.y = pBox[i].y1;
475*4882a593Smuzhiyun rect.width = pBox[i].x2 - pBox[i].x1;
476*4882a593Smuzhiyun rect.height = pBox[i].y2 - pBox[i].y1;
477*4882a593Smuzhiyun XUnionRectWithRegion(&rect, reg, reg);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
480*4882a593Smuzhiyun ShapeBounding, 0, 0, reg, ShapeSet);
481*4882a593Smuzhiyun XDestroyRegion(reg);
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun else {
484*4882a593Smuzhiyun RegionEmpty(xnestWindowPriv(pWin)->bounding_shape);
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
487*4882a593Smuzhiyun ShapeBounding, 0, 0, None, ShapeSet);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun if (!xnestRegionEqual(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin))) {
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (wClipShape(pWin)) {
494*4882a593Smuzhiyun RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun reg = XCreateRegion();
497*4882a593Smuzhiyun pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
498*4882a593Smuzhiyun for (i = 0;
499*4882a593Smuzhiyun i < RegionNumRects(xnestWindowPriv(pWin)->clip_shape); i++) {
500*4882a593Smuzhiyun rect.x = pBox[i].x1;
501*4882a593Smuzhiyun rect.y = pBox[i].y1;
502*4882a593Smuzhiyun rect.width = pBox[i].x2 - pBox[i].x1;
503*4882a593Smuzhiyun rect.height = pBox[i].y2 - pBox[i].y1;
504*4882a593Smuzhiyun XUnionRectWithRegion(&rect, reg, reg);
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
507*4882a593Smuzhiyun ShapeClip, 0, 0, reg, ShapeSet);
508*4882a593Smuzhiyun XDestroyRegion(reg);
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun else {
511*4882a593Smuzhiyun RegionEmpty(xnestWindowPriv(pWin)->clip_shape);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
514*4882a593Smuzhiyun ShapeClip, 0, 0, None, ShapeSet);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun }
518