xref: /OK3568_Linux_fs/external/xserver/hw/xnest/Window.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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