1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright (c) 2006, Red Hat, Inc.
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun copy of this software and associated documentation files (the "Software"),
7*4882a593Smuzhiyun to deal in the Software without restriction, including without limitation
8*4882a593Smuzhiyun the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*4882a593Smuzhiyun and/or sell copies of the Software, and to permit persons to whom the
10*4882a593Smuzhiyun Software is furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun The above copyright notice and this permission notice (including the next
13*4882a593Smuzhiyun paragraph) shall be included in all copies or substantial portions of the
14*4882a593Smuzhiyun Software.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*4882a593Smuzhiyun THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*4882a593Smuzhiyun LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*4882a593Smuzhiyun FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22*4882a593Smuzhiyun DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun Copyright 1987, 1998 The Open Group
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
27*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
28*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
29*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
30*4882a593Smuzhiyun documentation.
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
33*4882a593Smuzhiyun in all copies or substantial portions of the Software.
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
39*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
44*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
45*4882a593Smuzhiyun other dealings in this Software without prior written authorization
46*4882a593Smuzhiyun from The Open Group.
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun All Rights Reserved
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this software and its
53*4882a593Smuzhiyun documentation for any purpose and without fee is hereby granted,
54*4882a593Smuzhiyun provided that the above copyright notice appear in all copies and that
55*4882a593Smuzhiyun both that copyright notice and this permission notice appear in
56*4882a593Smuzhiyun supporting documentation, and that the name of Digital not be
57*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution of the
58*4882a593Smuzhiyun software without specific, written prior permission.
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
61*4882a593Smuzhiyun ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
62*4882a593Smuzhiyun DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
63*4882a593Smuzhiyun ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
64*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
65*4882a593Smuzhiyun ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
66*4882a593Smuzhiyun SOFTWARE.
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* The panoramix components contained the following notice */
71*4882a593Smuzhiyun /*****************************************************************
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy
76*4882a593Smuzhiyun of this software and associated documentation files (the "Software"), to deal
77*4882a593Smuzhiyun in the Software without restriction, including without limitation the rights
78*4882a593Smuzhiyun to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79*4882a593Smuzhiyun copies of the Software.
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
82*4882a593Smuzhiyun all copies or substantial portions of the Software.
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
87*4882a593Smuzhiyun DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
88*4882a593Smuzhiyun BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
89*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
90*4882a593Smuzhiyun IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun Except as contained in this notice, the name of Digital Equipment Corporation
93*4882a593Smuzhiyun shall not be used in advertising or otherwise to promote the sale, use or other
94*4882a593Smuzhiyun dealings in this Software without prior written authorization from Digital
95*4882a593Smuzhiyun Equipment Corporation.
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun ******************************************************************/
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
100*4882a593Smuzhiyun #include <dix-config.h>
101*4882a593Smuzhiyun #endif
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun #include "misc.h"
104*4882a593Smuzhiyun #include "scrnintstr.h"
105*4882a593Smuzhiyun #include "os.h"
106*4882a593Smuzhiyun #include "regionstr.h"
107*4882a593Smuzhiyun #include "validate.h"
108*4882a593Smuzhiyun #include "windowstr.h"
109*4882a593Smuzhiyun #include "propertyst.h"
110*4882a593Smuzhiyun #include "input.h"
111*4882a593Smuzhiyun #include "inputstr.h"
112*4882a593Smuzhiyun #include "resource.h"
113*4882a593Smuzhiyun #include "colormapst.h"
114*4882a593Smuzhiyun #include "cursorstr.h"
115*4882a593Smuzhiyun #include "dixstruct.h"
116*4882a593Smuzhiyun #include "gcstruct.h"
117*4882a593Smuzhiyun #include "servermd.h"
118*4882a593Smuzhiyun #include "mivalidate.h"
119*4882a593Smuzhiyun #ifdef PANORAMIX
120*4882a593Smuzhiyun #include "panoramiX.h"
121*4882a593Smuzhiyun #include "panoramiXsrv.h"
122*4882a593Smuzhiyun #endif
123*4882a593Smuzhiyun #include "dixevents.h"
124*4882a593Smuzhiyun #include "globals.h"
125*4882a593Smuzhiyun #include "mi.h" /* miPaintWindow */
126*4882a593Smuzhiyun #ifdef COMPOSITE
127*4882a593Smuzhiyun #include "compint.h"
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun #include "selection.h"
130*4882a593Smuzhiyun #include "inpututils.h"
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun #include "privates.h"
133*4882a593Smuzhiyun #include "xace.h"
134*4882a593Smuzhiyun #include "exevents.h"
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #include <X11/Xatom.h> /* must come after server includes */
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /******
139*4882a593Smuzhiyun * Window stuff for server
140*4882a593Smuzhiyun *
141*4882a593Smuzhiyun * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
142*4882a593Smuzhiyun * GetWindowAttributes, DeleteWindow, DestroySubWindows,
143*4882a593Smuzhiyun * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
144*4882a593Smuzhiyun * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
145*4882a593Smuzhiyun * ChangeWindowDeviceCursor
146*4882a593Smuzhiyun ******/
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun Bool bgNoneRoot = FALSE;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun static unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 };
151*4882a593Smuzhiyun static unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 };
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun static Bool WindowParentHasDeviceCursor(WindowPtr pWin,
154*4882a593Smuzhiyun DeviceIntPtr pDev, CursorPtr pCurs);
155*4882a593Smuzhiyun static Bool
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun WindowSeekDeviceCursor(WindowPtr pWin,
158*4882a593Smuzhiyun DeviceIntPtr pDev,
159*4882a593Smuzhiyun DevCursNodePtr * pNode, DevCursNodePtr * pPrev);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun int screenIsSaved = SCREEN_SAVER_OFF;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun static Bool TileScreenSaver(ScreenPtr pScreen, int kind);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
166*4882a593Smuzhiyun CWDontPropagate | CWOverrideRedirect | CWCursor )
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun #define BOXES_OVERLAP(b1, b2) \
169*4882a593Smuzhiyun (!( ((b1)->x2 <= (b2)->x1) || \
170*4882a593Smuzhiyun ( ((b1)->x1 >= (b2)->x2)) || \
171*4882a593Smuzhiyun ( ((b1)->y2 <= (b2)->y1)) || \
172*4882a593Smuzhiyun ( ((b1)->y1 >= (b2)->y2)) ) )
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun #define RedirectSend(pWin) \
175*4882a593Smuzhiyun ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun #define SubSend(pWin) \
178*4882a593Smuzhiyun ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun #define StrSend(pWin) \
181*4882a593Smuzhiyun ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun #ifdef COMPOSITE
186*4882a593Smuzhiyun static const char *overlay_win_name = "<composite overlay>";
187*4882a593Smuzhiyun #endif
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun static const char *
get_window_name(WindowPtr pWin)190*4882a593Smuzhiyun get_window_name(WindowPtr pWin)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun #define WINDOW_NAME_BUF_LEN 512
193*4882a593Smuzhiyun PropertyPtr prop;
194*4882a593Smuzhiyun static char buf[WINDOW_NAME_BUF_LEN];
195*4882a593Smuzhiyun int len;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun #ifdef COMPOSITE
198*4882a593Smuzhiyun CompScreenPtr comp_screen = GetCompScreen(pWin->drawable.pScreen);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun if (comp_screen && pWin == comp_screen->pOverlayWin)
201*4882a593Smuzhiyun return overlay_win_name;
202*4882a593Smuzhiyun #endif
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun for (prop = wUserProps(pWin); prop; prop = prop->next) {
205*4882a593Smuzhiyun if (prop->propertyName == XA_WM_NAME && prop->type == XA_STRING &&
206*4882a593Smuzhiyun prop->data) {
207*4882a593Smuzhiyun len = min(prop->size, WINDOW_NAME_BUF_LEN - 1);
208*4882a593Smuzhiyun memcpy(buf, prop->data, len);
209*4882a593Smuzhiyun buf[len] = '\0';
210*4882a593Smuzhiyun return buf;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun return NULL;
215*4882a593Smuzhiyun #undef WINDOW_NAME_BUF_LEN
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun static void
log_window_info(WindowPtr pWin,int depth)219*4882a593Smuzhiyun log_window_info(WindowPtr pWin, int depth)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun int i;
222*4882a593Smuzhiyun const char *win_name, *visibility;
223*4882a593Smuzhiyun BoxPtr rects;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun for (i = 0; i < (depth << 2); i++)
226*4882a593Smuzhiyun ErrorF(" ");
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun win_name = get_window_name(pWin);
229*4882a593Smuzhiyun ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]",
230*4882a593Smuzhiyun (unsigned) pWin->drawable.id,
231*4882a593Smuzhiyun win_name ? win_name : "no name",
232*4882a593Smuzhiyun pWin->drawable.x, pWin->drawable.y,
233*4882a593Smuzhiyun pWin->drawable.x + pWin->drawable.width,
234*4882a593Smuzhiyun pWin->drawable.y + pWin->drawable.height);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (pWin->overrideRedirect)
237*4882a593Smuzhiyun ErrorF(" (override redirect)");
238*4882a593Smuzhiyun #ifdef COMPOSITE
239*4882a593Smuzhiyun if (pWin->redirectDraw)
240*4882a593Smuzhiyun ErrorF(" (%s compositing: pixmap %x)",
241*4882a593Smuzhiyun (pWin->redirectDraw == RedirectDrawAutomatic) ?
242*4882a593Smuzhiyun "automatic" : "manual",
243*4882a593Smuzhiyun (unsigned) pWin->drawable.pScreen->GetWindowPixmap(pWin)->drawable.id);
244*4882a593Smuzhiyun #endif
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun switch (pWin->visibility) {
247*4882a593Smuzhiyun case VisibilityUnobscured:
248*4882a593Smuzhiyun visibility = "unobscured";
249*4882a593Smuzhiyun break;
250*4882a593Smuzhiyun case VisibilityPartiallyObscured:
251*4882a593Smuzhiyun visibility = "partially obscured";
252*4882a593Smuzhiyun break;
253*4882a593Smuzhiyun case VisibilityFullyObscured:
254*4882a593Smuzhiyun visibility = "fully obscured";
255*4882a593Smuzhiyun break;
256*4882a593Smuzhiyun case VisibilityNotViewable:
257*4882a593Smuzhiyun visibility = "unviewable";
258*4882a593Smuzhiyun break;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun ErrorF(", %s", visibility);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun if (RegionNotEmpty(&pWin->clipList)) {
263*4882a593Smuzhiyun ErrorF(", clip list:");
264*4882a593Smuzhiyun rects = RegionRects(&pWin->clipList);
265*4882a593Smuzhiyun for (i = 0; i < RegionNumRects(&pWin->clipList); i++)
266*4882a593Smuzhiyun ErrorF(" [(%d, %d) to (%d, %d)]",
267*4882a593Smuzhiyun rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
268*4882a593Smuzhiyun ErrorF("; extents [(%d, %d) to (%d, %d)]",
269*4882a593Smuzhiyun pWin->clipList.extents.x1, pWin->clipList.extents.y1,
270*4882a593Smuzhiyun pWin->clipList.extents.x2, pWin->clipList.extents.y2);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun ErrorF("\n");
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun static const char*
grab_grabtype_to_text(GrabPtr pGrab)277*4882a593Smuzhiyun grab_grabtype_to_text(GrabPtr pGrab)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun switch (pGrab->grabtype) {
280*4882a593Smuzhiyun case XI2:
281*4882a593Smuzhiyun return "xi2";
282*4882a593Smuzhiyun case CORE:
283*4882a593Smuzhiyun return "core";
284*4882a593Smuzhiyun default:
285*4882a593Smuzhiyun return "xi1";
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun static const char*
grab_type_to_text(GrabPtr pGrab)290*4882a593Smuzhiyun grab_type_to_text(GrabPtr pGrab)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun switch (pGrab->type) {
293*4882a593Smuzhiyun case ButtonPress:
294*4882a593Smuzhiyun return "ButtonPress";
295*4882a593Smuzhiyun case KeyPress:
296*4882a593Smuzhiyun return "KeyPress";
297*4882a593Smuzhiyun case XI_Enter:
298*4882a593Smuzhiyun return "XI_Enter";
299*4882a593Smuzhiyun case XI_FocusIn:
300*4882a593Smuzhiyun return "XI_FocusIn";
301*4882a593Smuzhiyun default:
302*4882a593Smuzhiyun return "unknown?!";
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun static void
log_grab_info(void * value,XID id,void * cdata)307*4882a593Smuzhiyun log_grab_info(void *value, XID id, void *cdata)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun int i, j;
310*4882a593Smuzhiyun GrabPtr pGrab = (GrabPtr)value;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun ErrorF(" grab 0x%lx (%s), type '%s' on window 0x%lx\n",
313*4882a593Smuzhiyun (unsigned long) pGrab->resource,
314*4882a593Smuzhiyun grab_grabtype_to_text(pGrab),
315*4882a593Smuzhiyun grab_type_to_text(pGrab),
316*4882a593Smuzhiyun (unsigned long) pGrab->window->drawable.id);
317*4882a593Smuzhiyun ErrorF(" detail %d (mask %lu), modifiersDetail %d (mask %lu)\n",
318*4882a593Smuzhiyun pGrab->detail.exact,
319*4882a593Smuzhiyun pGrab->detail.pMask ? (unsigned long) *(pGrab->detail.pMask) : 0,
320*4882a593Smuzhiyun pGrab->modifiersDetail.exact,
321*4882a593Smuzhiyun pGrab->modifiersDetail.pMask ?
322*4882a593Smuzhiyun (unsigned long) *(pGrab->modifiersDetail.pMask) :
323*4882a593Smuzhiyun (unsigned long) 0);
324*4882a593Smuzhiyun ErrorF(" device '%s' (%d), modifierDevice '%s' (%d)\n",
325*4882a593Smuzhiyun pGrab->device->name, pGrab->device->id,
326*4882a593Smuzhiyun pGrab->modifierDevice->name, pGrab->modifierDevice->id);
327*4882a593Smuzhiyun if (pGrab->grabtype == CORE) {
328*4882a593Smuzhiyun ErrorF(" core event mask 0x%lx\n",
329*4882a593Smuzhiyun (unsigned long) pGrab->eventMask);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun else if (pGrab->grabtype == XI) {
332*4882a593Smuzhiyun ErrorF(" xi1 event mask 0x%lx\n",
333*4882a593Smuzhiyun (unsigned long) pGrab->eventMask);
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun else if (pGrab->grabtype == XI2) {
336*4882a593Smuzhiyun for (i = 0; i < xi2mask_num_masks(pGrab->xi2mask); i++) {
337*4882a593Smuzhiyun const unsigned char *mask;
338*4882a593Smuzhiyun int print;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun print = 0;
341*4882a593Smuzhiyun for (j = 0; j < XI2MASKSIZE; j++) {
342*4882a593Smuzhiyun mask = xi2mask_get_one_mask(pGrab->xi2mask, i);
343*4882a593Smuzhiyun if (mask[j]) {
344*4882a593Smuzhiyun print = 1;
345*4882a593Smuzhiyun break;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun if (!print)
349*4882a593Smuzhiyun continue;
350*4882a593Smuzhiyun ErrorF(" xi2 event mask 0x");
351*4882a593Smuzhiyun for (j = 0; j < xi2mask_mask_size(pGrab->xi2mask); j++)
352*4882a593Smuzhiyun ErrorF("%x ", mask[j]);
353*4882a593Smuzhiyun ErrorF("\n");
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun ErrorF(" owner-events %s, kb %d ptr %d, confine 0x%lx, cursor 0x%lx\n",
357*4882a593Smuzhiyun pGrab->ownerEvents ? "true" : "false",
358*4882a593Smuzhiyun pGrab->keyboardMode, pGrab->pointerMode,
359*4882a593Smuzhiyun pGrab->confineTo ? (unsigned long) pGrab->confineTo->drawable.id : 0,
360*4882a593Smuzhiyun pGrab->cursor ? (unsigned long) pGrab->cursor->id : 0);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun void
PrintPassiveGrabs(void)364*4882a593Smuzhiyun PrintPassiveGrabs(void)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun int i;
367*4882a593Smuzhiyun LocalClientCredRec *lcc;
368*4882a593Smuzhiyun pid_t clientpid;
369*4882a593Smuzhiyun const char *cmdname;
370*4882a593Smuzhiyun const char *cmdargs;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun ErrorF("Printing all currently registered grabs\n");
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun for (i = 1; i < currentMaxClients; i++) {
375*4882a593Smuzhiyun if (!clients[i] || clients[i]->clientState != ClientStateRunning)
376*4882a593Smuzhiyun continue;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun clientpid = GetClientPid(clients[i]);
379*4882a593Smuzhiyun cmdname = GetClientCmdName(clients[i]);
380*4882a593Smuzhiyun cmdargs = GetClientCmdArgs(clients[i]);
381*4882a593Smuzhiyun if ((clientpid > 0) && (cmdname != NULL)) {
382*4882a593Smuzhiyun ErrorF(" Printing all registered grabs of client pid %ld %s %s\n",
383*4882a593Smuzhiyun (long) clientpid, cmdname, cmdargs ? cmdargs : "");
384*4882a593Smuzhiyun } else {
385*4882a593Smuzhiyun if (GetLocalClientCreds(clients[i], &lcc) == -1) {
386*4882a593Smuzhiyun ErrorF(" GetLocalClientCreds() failed\n");
387*4882a593Smuzhiyun continue;
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun ErrorF(" Printing all registered grabs of client pid %ld uid %ld gid %ld\n",
390*4882a593Smuzhiyun (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0,
391*4882a593Smuzhiyun (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0,
392*4882a593Smuzhiyun (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0);
393*4882a593Smuzhiyun FreeLocalClientCreds(lcc);
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, log_grab_info, NULL);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun ErrorF("End list of registered passive grabs\n");
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun void
PrintWindowTree(void)402*4882a593Smuzhiyun PrintWindowTree(void)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun int scrnum, depth;
405*4882a593Smuzhiyun ScreenPtr pScreen;
406*4882a593Smuzhiyun WindowPtr pWin;
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun for (scrnum = 0; scrnum < screenInfo.numScreens; scrnum++) {
409*4882a593Smuzhiyun pScreen = screenInfo.screens[scrnum];
410*4882a593Smuzhiyun ErrorF("[dix] Dumping windows for screen %d (pixmap %x):\n", scrnum,
411*4882a593Smuzhiyun (unsigned) pScreen->GetScreenPixmap(pScreen)->drawable.id);
412*4882a593Smuzhiyun pWin = pScreen->root;
413*4882a593Smuzhiyun depth = 1;
414*4882a593Smuzhiyun while (pWin) {
415*4882a593Smuzhiyun log_window_info(pWin, depth);
416*4882a593Smuzhiyun if (pWin->firstChild) {
417*4882a593Smuzhiyun pWin = pWin->firstChild;
418*4882a593Smuzhiyun depth++;
419*4882a593Smuzhiyun continue;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun while (pWin && !pWin->nextSib) {
422*4882a593Smuzhiyun pWin = pWin->parent;
423*4882a593Smuzhiyun depth--;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun if (!pWin)
426*4882a593Smuzhiyun break;
427*4882a593Smuzhiyun pWin = pWin->nextSib;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun int
TraverseTree(WindowPtr pWin,VisitWindowProcPtr func,void * data)433*4882a593Smuzhiyun TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, void *data)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun int result;
436*4882a593Smuzhiyun WindowPtr pChild;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun if (!(pChild = pWin))
439*4882a593Smuzhiyun return WT_NOMATCH;
440*4882a593Smuzhiyun while (1) {
441*4882a593Smuzhiyun result = (*func) (pChild, data);
442*4882a593Smuzhiyun if (result == WT_STOPWALKING)
443*4882a593Smuzhiyun return WT_STOPWALKING;
444*4882a593Smuzhiyun if ((result == WT_WALKCHILDREN) && pChild->firstChild) {
445*4882a593Smuzhiyun pChild = pChild->firstChild;
446*4882a593Smuzhiyun continue;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pWin))
449*4882a593Smuzhiyun pChild = pChild->parent;
450*4882a593Smuzhiyun if (pChild == pWin)
451*4882a593Smuzhiyun break;
452*4882a593Smuzhiyun pChild = pChild->nextSib;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun return WT_NOMATCH;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun /*****
458*4882a593Smuzhiyun * WalkTree
459*4882a593Smuzhiyun * Walk the window tree, for SCREEN, performing FUNC(pWin, data) on
460*4882a593Smuzhiyun * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
461*4882a593Smuzhiyun * if it returns WT_DONTWALKCHILDREN, don't. If it returns WT_STOPWALKING,
462*4882a593Smuzhiyun * exit WalkTree. Does depth-first traverse.
463*4882a593Smuzhiyun *****/
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun int
WalkTree(ScreenPtr pScreen,VisitWindowProcPtr func,void * data)466*4882a593Smuzhiyun WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void *data)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun return (TraverseTree(pScreen->root, func, data));
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun /* hack for forcing backing store on all windows */
472*4882a593Smuzhiyun int defaultBackingStore = NotUseful;
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun /* hack to force no backing store */
475*4882a593Smuzhiyun Bool disableBackingStore = FALSE;
476*4882a593Smuzhiyun Bool enableBackingStore = FALSE;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun static void
SetWindowToDefaults(WindowPtr pWin)479*4882a593Smuzhiyun SetWindowToDefaults(WindowPtr pWin)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun pWin->prevSib = NullWindow;
482*4882a593Smuzhiyun pWin->firstChild = NullWindow;
483*4882a593Smuzhiyun pWin->lastChild = NullWindow;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun pWin->valdata = NULL;
486*4882a593Smuzhiyun pWin->optional = NULL;
487*4882a593Smuzhiyun pWin->cursorIsNone = TRUE;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun pWin->backingStore = NotUseful;
490*4882a593Smuzhiyun pWin->backStorage = 0;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun pWin->mapped = FALSE; /* off */
493*4882a593Smuzhiyun pWin->realized = FALSE; /* off */
494*4882a593Smuzhiyun pWin->viewable = FALSE;
495*4882a593Smuzhiyun pWin->visibility = VisibilityNotViewable;
496*4882a593Smuzhiyun pWin->overrideRedirect = FALSE;
497*4882a593Smuzhiyun pWin->saveUnder = FALSE;
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun pWin->bitGravity = ForgetGravity;
500*4882a593Smuzhiyun pWin->winGravity = NorthWestGravity;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun pWin->eventMask = 0;
503*4882a593Smuzhiyun pWin->deliverableEvents = 0;
504*4882a593Smuzhiyun pWin->dontPropagate = 0;
505*4882a593Smuzhiyun pWin->forcedBS = FALSE;
506*4882a593Smuzhiyun pWin->redirectDraw = RedirectDrawNone;
507*4882a593Smuzhiyun pWin->forcedBG = FALSE;
508*4882a593Smuzhiyun pWin->unhittable = FALSE;
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun #ifdef COMPOSITE
511*4882a593Smuzhiyun pWin->damagedDescendants = FALSE;
512*4882a593Smuzhiyun #endif
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun static void
MakeRootTile(WindowPtr pWin)516*4882a593Smuzhiyun MakeRootTile(WindowPtr pWin)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
519*4882a593Smuzhiyun GCPtr pGC;
520*4882a593Smuzhiyun unsigned char back[128];
521*4882a593Smuzhiyun int len = BitmapBytePad(sizeof(long));
522*4882a593Smuzhiyun unsigned char *from, *to;
523*4882a593Smuzhiyun int i, j;
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4,
526*4882a593Smuzhiyun pScreen->rootDepth, 0);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixmap;
529*4882a593Smuzhiyun pGC = GetScratchGC(pScreen->rootDepth, pScreen);
530*4882a593Smuzhiyun if (!pWin->background.pixmap || !pGC)
531*4882a593Smuzhiyun FatalError("could not create root tile");
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun ChangeGCVal attributes[2];
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun attributes[0].val = pScreen->whitePixel;
537*4882a593Smuzhiyun attributes[1].val = pScreen->blackPixel;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun (void) ChangeGC(NullClient, pGC, GCForeground | GCBackground,
540*4882a593Smuzhiyun attributes);
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun ValidateGC((DrawablePtr) pWin->background.pixmap, pGC);
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
546*4882a593Smuzhiyun to = back;
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun for (i = 4; i > 0; i--, from++)
549*4882a593Smuzhiyun for (j = len; j > 0; j--)
550*4882a593Smuzhiyun *to++ = *from;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1,
553*4882a593Smuzhiyun 0, 0, len, 4, 0, XYBitmap, (char *) back);
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun FreeScratchGC(pGC);
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun /*****
560*4882a593Smuzhiyun * CreateRootWindow
561*4882a593Smuzhiyun * Makes a window at initialization time for specified screen
562*4882a593Smuzhiyun *****/
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun Bool
CreateRootWindow(ScreenPtr pScreen)565*4882a593Smuzhiyun CreateRootWindow(ScreenPtr pScreen)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun WindowPtr pWin;
568*4882a593Smuzhiyun BoxRec box;
569*4882a593Smuzhiyun PixmapFormatRec *format;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW);
572*4882a593Smuzhiyun if (!pWin)
573*4882a593Smuzhiyun return FALSE;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun pScreen->screensaver.pWindow = NULL;
576*4882a593Smuzhiyun pScreen->screensaver.wid = FakeClientID(0);
577*4882a593Smuzhiyun pScreen->screensaver.ExternalScreenSaver = NULL;
578*4882a593Smuzhiyun screenIsSaved = SCREEN_SAVER_OFF;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun pScreen->root = pWin;
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun pWin->drawable.pScreen = pScreen;
583*4882a593Smuzhiyun pWin->drawable.type = DRAWABLE_WINDOW;
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun pWin->drawable.depth = pScreen->rootDepth;
586*4882a593Smuzhiyun for (format = screenInfo.formats;
587*4882a593Smuzhiyun format->depth != pScreen->rootDepth; format++);
588*4882a593Smuzhiyun pWin->drawable.bitsPerPixel = format->bitsPerPixel;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun pWin->parent = NullWindow;
593*4882a593Smuzhiyun SetWindowToDefaults(pWin);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun pWin->optional = malloc(sizeof(WindowOptRec));
596*4882a593Smuzhiyun if (!pWin->optional)
597*4882a593Smuzhiyun return FALSE;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun pWin->optional->dontPropagateMask = 0;
600*4882a593Smuzhiyun pWin->optional->otherEventMasks = 0;
601*4882a593Smuzhiyun pWin->optional->otherClients = NULL;
602*4882a593Smuzhiyun pWin->optional->passiveGrabs = NULL;
603*4882a593Smuzhiyun pWin->optional->userProps = NULL;
604*4882a593Smuzhiyun pWin->optional->backingBitPlanes = ~0L;
605*4882a593Smuzhiyun pWin->optional->backingPixel = 0;
606*4882a593Smuzhiyun pWin->optional->boundingShape = NULL;
607*4882a593Smuzhiyun pWin->optional->clipShape = NULL;
608*4882a593Smuzhiyun pWin->optional->inputShape = NULL;
609*4882a593Smuzhiyun pWin->optional->inputMasks = NULL;
610*4882a593Smuzhiyun pWin->optional->deviceCursors = NULL;
611*4882a593Smuzhiyun pWin->optional->colormap = pScreen->defColormap;
612*4882a593Smuzhiyun pWin->optional->visual = pScreen->rootVisual;
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun pWin->nextSib = NullWindow;
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun pWin->drawable.id = FakeClientID(0);
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun pWin->origin.x = pWin->origin.y = 0;
619*4882a593Smuzhiyun pWin->drawable.height = pScreen->height;
620*4882a593Smuzhiyun pWin->drawable.width = pScreen->width;
621*4882a593Smuzhiyun pWin->drawable.x = pWin->drawable.y = 0;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun box.x1 = 0;
624*4882a593Smuzhiyun box.y1 = 0;
625*4882a593Smuzhiyun box.x2 = pScreen->width;
626*4882a593Smuzhiyun box.y2 = pScreen->height;
627*4882a593Smuzhiyun RegionInit(&pWin->clipList, &box, 1);
628*4882a593Smuzhiyun RegionInit(&pWin->winSize, &box, 1);
629*4882a593Smuzhiyun RegionInit(&pWin->borderSize, &box, 1);
630*4882a593Smuzhiyun RegionInit(&pWin->borderClip, &box, 1);
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun pWin->drawable.class = InputOutput;
633*4882a593Smuzhiyun pWin->optional->visual = pScreen->rootVisual;
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixel;
636*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun pWin->borderIsPixel = TRUE;
639*4882a593Smuzhiyun pWin->border.pixel = pScreen->blackPixel;
640*4882a593Smuzhiyun pWin->borderWidth = 0;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun /* security creation/labeling check
643*4882a593Smuzhiyun */
644*4882a593Smuzhiyun if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id,
645*4882a593Smuzhiyun RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess))
646*4882a593Smuzhiyun return FALSE;
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
649*4882a593Smuzhiyun return FALSE;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun if (disableBackingStore)
652*4882a593Smuzhiyun pScreen->backingStoreSupport = NotUseful;
653*4882a593Smuzhiyun if (enableBackingStore)
654*4882a593Smuzhiyun pScreen->backingStoreSupport = WhenMapped;
655*4882a593Smuzhiyun #ifdef COMPOSITE
656*4882a593Smuzhiyun if (noCompositeExtension)
657*4882a593Smuzhiyun pScreen->backingStoreSupport = NotUseful;
658*4882a593Smuzhiyun #endif
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun pScreen->saveUnderSupport = NotUseful;
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun return TRUE;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun void
InitRootWindow(WindowPtr pWin)666*4882a593Smuzhiyun InitRootWindow(WindowPtr pWin)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
669*4882a593Smuzhiyun int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun if (!(*pScreen->CreateWindow) (pWin))
672*4882a593Smuzhiyun return; /* XXX */
673*4882a593Smuzhiyun (*pScreen->PositionWindow) (pWin, 0, 0);
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun pWin->cursorIsNone = FALSE;
676*4882a593Smuzhiyun pWin->optional->cursor = RefCursor(rootCursor);
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun if (party_like_its_1989) {
679*4882a593Smuzhiyun MakeRootTile(pWin);
680*4882a593Smuzhiyun backFlag |= CWBackPixmap;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun else if (pScreen->canDoBGNoneRoot && bgNoneRoot) {
683*4882a593Smuzhiyun pWin->backgroundState = XaceBackgroundNoneState(pWin);
684*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
685*4882a593Smuzhiyun backFlag |= CWBackPixmap;
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun else {
688*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixel;
689*4882a593Smuzhiyun if (whiteRoot)
690*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
691*4882a593Smuzhiyun else
692*4882a593Smuzhiyun pWin->background.pixel = pScreen->blackPixel;
693*4882a593Smuzhiyun backFlag |= CWBackPixel;
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun pWin->backingStore = defaultBackingStore;
697*4882a593Smuzhiyun pWin->forcedBS = (defaultBackingStore != NotUseful);
698*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
699*4882a593Smuzhiyun (*pScreen->ChangeWindowAttributes) (pWin, backFlag);
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun MapWindow(pWin, serverClient);
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun /* Set the region to the intersection of the rectangle and the
705*4882a593Smuzhiyun * window's winSize. The window is typically the parent of the
706*4882a593Smuzhiyun * window from which the region came.
707*4882a593Smuzhiyun */
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun static void
ClippedRegionFromBox(WindowPtr pWin,RegionPtr Rgn,int x,int y,int w,int h)710*4882a593Smuzhiyun ClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, int x, int y, int w, int h)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun BoxRec box = *RegionExtents(&pWin->winSize);
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun /* we do these calculations to avoid overflows */
715*4882a593Smuzhiyun if (x > box.x1)
716*4882a593Smuzhiyun box.x1 = x;
717*4882a593Smuzhiyun if (y > box.y1)
718*4882a593Smuzhiyun box.y1 = y;
719*4882a593Smuzhiyun x += w;
720*4882a593Smuzhiyun if (x < box.x2)
721*4882a593Smuzhiyun box.x2 = x;
722*4882a593Smuzhiyun y += h;
723*4882a593Smuzhiyun if (y < box.y2)
724*4882a593Smuzhiyun box.y2 = y;
725*4882a593Smuzhiyun if (box.x1 > box.x2)
726*4882a593Smuzhiyun box.x2 = box.x1;
727*4882a593Smuzhiyun if (box.y1 > box.y2)
728*4882a593Smuzhiyun box.y2 = box.y1;
729*4882a593Smuzhiyun RegionReset(Rgn, &box);
730*4882a593Smuzhiyun RegionIntersect(Rgn, Rgn, &pWin->winSize);
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun static RealChildHeadProc realChildHeadProc = NULL;
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun void
RegisterRealChildHeadProc(RealChildHeadProc proc)736*4882a593Smuzhiyun RegisterRealChildHeadProc(RealChildHeadProc proc)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun realChildHeadProc = proc;
739*4882a593Smuzhiyun }
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun WindowPtr
RealChildHead(WindowPtr pWin)742*4882a593Smuzhiyun RealChildHead(WindowPtr pWin)
743*4882a593Smuzhiyun {
744*4882a593Smuzhiyun if (realChildHeadProc) {
745*4882a593Smuzhiyun return realChildHeadProc(pWin);
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun if (!pWin->parent &&
749*4882a593Smuzhiyun (screenIsSaved == SCREEN_SAVER_ON) &&
750*4882a593Smuzhiyun (HasSaverWindow(pWin->drawable.pScreen)))
751*4882a593Smuzhiyun return pWin->firstChild;
752*4882a593Smuzhiyun else
753*4882a593Smuzhiyun return NullWindow;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /*****
757*4882a593Smuzhiyun * CreateWindow
758*4882a593Smuzhiyun * Makes a window in response to client request
759*4882a593Smuzhiyun *****/
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun WindowPtr
CreateWindow(Window wid,WindowPtr pParent,int x,int y,unsigned w,unsigned h,unsigned bw,unsigned class,Mask vmask,XID * vlist,int depth,ClientPtr client,VisualID visual,int * error)762*4882a593Smuzhiyun CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
763*4882a593Smuzhiyun unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist,
764*4882a593Smuzhiyun int depth, ClientPtr client, VisualID visual, int *error)
765*4882a593Smuzhiyun {
766*4882a593Smuzhiyun WindowPtr pWin;
767*4882a593Smuzhiyun WindowPtr pHead;
768*4882a593Smuzhiyun ScreenPtr pScreen;
769*4882a593Smuzhiyun int idepth, ivisual;
770*4882a593Smuzhiyun Bool fOK;
771*4882a593Smuzhiyun DepthPtr pDepth;
772*4882a593Smuzhiyun PixmapFormatRec *format;
773*4882a593Smuzhiyun WindowOptPtr ancwopt;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun if (class == CopyFromParent)
776*4882a593Smuzhiyun class = pParent->drawable.class;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun if ((class != InputOutput) && (class != InputOnly)) {
779*4882a593Smuzhiyun *error = BadValue;
780*4882a593Smuzhiyun client->errorValue = class;
781*4882a593Smuzhiyun return NullWindow;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) {
785*4882a593Smuzhiyun *error = BadMatch;
786*4882a593Smuzhiyun return NullWindow;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun if ((class == InputOnly) && ((bw != 0) || (depth != 0))) {
790*4882a593Smuzhiyun *error = BadMatch;
791*4882a593Smuzhiyun return NullWindow;
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun pScreen = pParent->drawable.pScreen;
795*4882a593Smuzhiyun if ((class == InputOutput) && (depth == 0))
796*4882a593Smuzhiyun depth = pParent->drawable.depth;
797*4882a593Smuzhiyun ancwopt = pParent->optional;
798*4882a593Smuzhiyun if (!ancwopt)
799*4882a593Smuzhiyun ancwopt = FindWindowWithOptional(pParent)->optional;
800*4882a593Smuzhiyun if (visual == CopyFromParent) {
801*4882a593Smuzhiyun visual = ancwopt->visual;
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun /* Find out if the depth and visual are acceptable for this Screen */
805*4882a593Smuzhiyun if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
806*4882a593Smuzhiyun fOK = FALSE;
807*4882a593Smuzhiyun for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
808*4882a593Smuzhiyun pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
809*4882a593Smuzhiyun if ((depth == pDepth->depth) || (depth == 0)) {
810*4882a593Smuzhiyun for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
811*4882a593Smuzhiyun if (visual == pDepth->vids[ivisual]) {
812*4882a593Smuzhiyun fOK = TRUE;
813*4882a593Smuzhiyun break;
814*4882a593Smuzhiyun }
815*4882a593Smuzhiyun }
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun }
818*4882a593Smuzhiyun if (fOK == FALSE) {
819*4882a593Smuzhiyun *error = BadMatch;
820*4882a593Smuzhiyun return NullWindow;
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
825*4882a593Smuzhiyun (class != InputOnly) && (depth != pParent->drawable.depth)) {
826*4882a593Smuzhiyun *error = BadMatch;
827*4882a593Smuzhiyun return NullWindow;
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun if (((vmask & CWColormap) == 0) &&
831*4882a593Smuzhiyun (class != InputOnly) &&
832*4882a593Smuzhiyun ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
833*4882a593Smuzhiyun *error = BadMatch;
834*4882a593Smuzhiyun return NullWindow;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW);
838*4882a593Smuzhiyun if (!pWin) {
839*4882a593Smuzhiyun *error = BadAlloc;
840*4882a593Smuzhiyun return NullWindow;
841*4882a593Smuzhiyun }
842*4882a593Smuzhiyun pWin->drawable = pParent->drawable;
843*4882a593Smuzhiyun pWin->drawable.depth = depth;
844*4882a593Smuzhiyun if (depth == pParent->drawable.depth)
845*4882a593Smuzhiyun pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
846*4882a593Smuzhiyun else {
847*4882a593Smuzhiyun for (format = screenInfo.formats; format->depth != depth; format++);
848*4882a593Smuzhiyun pWin->drawable.bitsPerPixel = format->bitsPerPixel;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun if (class == InputOnly)
851*4882a593Smuzhiyun pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
852*4882a593Smuzhiyun pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun pWin->drawable.id = wid;
855*4882a593Smuzhiyun pWin->drawable.class = class;
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun pWin->parent = pParent;
858*4882a593Smuzhiyun SetWindowToDefaults(pWin);
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun if (visual != ancwopt->visual) {
861*4882a593Smuzhiyun if (!MakeWindowOptional(pWin)) {
862*4882a593Smuzhiyun dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
863*4882a593Smuzhiyun *error = BadAlloc;
864*4882a593Smuzhiyun return NullWindow;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun pWin->optional->visual = visual;
867*4882a593Smuzhiyun pWin->optional->colormap = None;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun pWin->borderWidth = bw;
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun /* security creation/labeling check
873*4882a593Smuzhiyun */
874*4882a593Smuzhiyun *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin,
875*4882a593Smuzhiyun RT_WINDOW, pWin->parent,
876*4882a593Smuzhiyun DixCreateAccess | DixSetAttrAccess);
877*4882a593Smuzhiyun if (*error != Success) {
878*4882a593Smuzhiyun dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
879*4882a593Smuzhiyun return NullWindow;
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun pWin->backgroundState = XaceBackgroundNoneState(pWin);
883*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun pWin->borderIsPixel = pParent->borderIsPixel;
886*4882a593Smuzhiyun pWin->border = pParent->border;
887*4882a593Smuzhiyun if (pWin->borderIsPixel == FALSE)
888*4882a593Smuzhiyun pWin->border.pixmap->refcnt++;
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun pWin->origin.x = x + (int) bw;
891*4882a593Smuzhiyun pWin->origin.y = y + (int) bw;
892*4882a593Smuzhiyun pWin->drawable.width = w;
893*4882a593Smuzhiyun pWin->drawable.height = h;
894*4882a593Smuzhiyun pWin->drawable.x = pParent->drawable.x + x + (int) bw;
895*4882a593Smuzhiyun pWin->drawable.y = pParent->drawable.y + y + (int) bw;
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun /* set up clip list correctly for unobscured WindowPtr */
898*4882a593Smuzhiyun RegionNull(&pWin->clipList);
899*4882a593Smuzhiyun RegionNull(&pWin->borderClip);
900*4882a593Smuzhiyun RegionNull(&pWin->winSize);
901*4882a593Smuzhiyun RegionNull(&pWin->borderSize);
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun pHead = RealChildHead(pParent);
904*4882a593Smuzhiyun if (pHead) {
905*4882a593Smuzhiyun pWin->nextSib = pHead->nextSib;
906*4882a593Smuzhiyun if (pHead->nextSib)
907*4882a593Smuzhiyun pHead->nextSib->prevSib = pWin;
908*4882a593Smuzhiyun else
909*4882a593Smuzhiyun pParent->lastChild = pWin;
910*4882a593Smuzhiyun pHead->nextSib = pWin;
911*4882a593Smuzhiyun pWin->prevSib = pHead;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun else {
914*4882a593Smuzhiyun pWin->nextSib = pParent->firstChild;
915*4882a593Smuzhiyun if (pParent->firstChild)
916*4882a593Smuzhiyun pParent->firstChild->prevSib = pWin;
917*4882a593Smuzhiyun else
918*4882a593Smuzhiyun pParent->lastChild = pWin;
919*4882a593Smuzhiyun pParent->firstChild = pWin;
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun SetWinSize(pWin);
923*4882a593Smuzhiyun SetBorderSize(pWin);
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
926*4882a593Smuzhiyun if (!(*pScreen->CreateWindow) (pWin)) {
927*4882a593Smuzhiyun *error = BadAlloc;
928*4882a593Smuzhiyun DeleteWindow(pWin, None);
929*4882a593Smuzhiyun return NullWindow;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
932*4882a593Smuzhiyun (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun if (!(vmask & CWEventMask))
935*4882a593Smuzhiyun RecalculateDeliverableEvents(pWin);
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun if (vmask)
938*4882a593Smuzhiyun *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin));
939*4882a593Smuzhiyun else
940*4882a593Smuzhiyun *error = Success;
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun if (*error != Success) {
943*4882a593Smuzhiyun DeleteWindow(pWin, None);
944*4882a593Smuzhiyun return NullWindow;
945*4882a593Smuzhiyun }
946*4882a593Smuzhiyun if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) {
947*4882a593Smuzhiyun XID value = defaultBackingStore;
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun (void) ChangeWindowAttributes(pWin, CWBackingStore, &value,
950*4882a593Smuzhiyun wClient(pWin));
951*4882a593Smuzhiyun pWin->forcedBS = TRUE;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun if (SubSend(pParent)) {
955*4882a593Smuzhiyun xEvent event = {
956*4882a593Smuzhiyun .u.createNotify.window = wid,
957*4882a593Smuzhiyun .u.createNotify.parent = pParent->drawable.id,
958*4882a593Smuzhiyun .u.createNotify.x = x,
959*4882a593Smuzhiyun .u.createNotify.y = y,
960*4882a593Smuzhiyun .u.createNotify.width = w,
961*4882a593Smuzhiyun .u.createNotify.height = h,
962*4882a593Smuzhiyun .u.createNotify.borderWidth = bw,
963*4882a593Smuzhiyun .u.createNotify.override = pWin->overrideRedirect
964*4882a593Smuzhiyun };
965*4882a593Smuzhiyun event.u.u.type = CreateNotify;
966*4882a593Smuzhiyun DeliverEvents(pParent, &event, 1, NullWindow);
967*4882a593Smuzhiyun }
968*4882a593Smuzhiyun return pWin;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun static void
DisposeWindowOptional(WindowPtr pWin)972*4882a593Smuzhiyun DisposeWindowOptional(WindowPtr pWin)
973*4882a593Smuzhiyun {
974*4882a593Smuzhiyun if (!pWin->optional)
975*4882a593Smuzhiyun return;
976*4882a593Smuzhiyun /*
977*4882a593Smuzhiyun * everything is peachy. Delete the optional record
978*4882a593Smuzhiyun * and clean up
979*4882a593Smuzhiyun */
980*4882a593Smuzhiyun if (pWin->optional->cursor) {
981*4882a593Smuzhiyun FreeCursor(pWin->optional->cursor, (Cursor) 0);
982*4882a593Smuzhiyun pWin->cursorIsNone = FALSE;
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun else
985*4882a593Smuzhiyun pWin->cursorIsNone = TRUE;
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun if (pWin->optional->deviceCursors) {
988*4882a593Smuzhiyun DevCursorList pList;
989*4882a593Smuzhiyun DevCursorList pPrev;
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun pList = pWin->optional->deviceCursors;
992*4882a593Smuzhiyun while (pList) {
993*4882a593Smuzhiyun if (pList->cursor)
994*4882a593Smuzhiyun FreeCursor(pList->cursor, (XID) 0);
995*4882a593Smuzhiyun pPrev = pList;
996*4882a593Smuzhiyun pList = pList->next;
997*4882a593Smuzhiyun free(pPrev);
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun pWin->optional->deviceCursors = NULL;
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun free(pWin->optional);
1003*4882a593Smuzhiyun pWin->optional = NULL;
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun static void
FreeWindowResources(WindowPtr pWin)1007*4882a593Smuzhiyun FreeWindowResources(WindowPtr pWin)
1008*4882a593Smuzhiyun {
1009*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun DeleteWindowFromAnySaveSet(pWin);
1012*4882a593Smuzhiyun DeleteWindowFromAnySelections(pWin);
1013*4882a593Smuzhiyun DeleteWindowFromAnyEvents(pWin, TRUE);
1014*4882a593Smuzhiyun RegionUninit(&pWin->clipList);
1015*4882a593Smuzhiyun RegionUninit(&pWin->winSize);
1016*4882a593Smuzhiyun RegionUninit(&pWin->borderClip);
1017*4882a593Smuzhiyun RegionUninit(&pWin->borderSize);
1018*4882a593Smuzhiyun if (wBoundingShape(pWin))
1019*4882a593Smuzhiyun RegionDestroy(wBoundingShape(pWin));
1020*4882a593Smuzhiyun if (wClipShape(pWin))
1021*4882a593Smuzhiyun RegionDestroy(wClipShape(pWin));
1022*4882a593Smuzhiyun if (wInputShape(pWin))
1023*4882a593Smuzhiyun RegionDestroy(wInputShape(pWin));
1024*4882a593Smuzhiyun if (pWin->borderIsPixel == FALSE)
1025*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->border.pixmap);
1026*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixmap)
1027*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->background.pixmap);
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun DeleteAllWindowProperties(pWin);
1030*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
1031*4882a593Smuzhiyun (*pScreen->DestroyWindow) (pWin);
1032*4882a593Smuzhiyun DisposeWindowOptional(pWin);
1033*4882a593Smuzhiyun }
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun static void
CrushTree(WindowPtr pWin)1036*4882a593Smuzhiyun CrushTree(WindowPtr pWin)
1037*4882a593Smuzhiyun {
1038*4882a593Smuzhiyun WindowPtr pChild, pSib, pParent;
1039*4882a593Smuzhiyun UnrealizeWindowProcPtr UnrealizeWindow;
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun if (!(pChild = pWin->firstChild))
1042*4882a593Smuzhiyun return;
1043*4882a593Smuzhiyun UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
1044*4882a593Smuzhiyun while (1) {
1045*4882a593Smuzhiyun if (pChild->firstChild) {
1046*4882a593Smuzhiyun pChild = pChild->firstChild;
1047*4882a593Smuzhiyun continue;
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun while (1) {
1050*4882a593Smuzhiyun pParent = pChild->parent;
1051*4882a593Smuzhiyun if (SubStrSend(pChild, pParent)) {
1052*4882a593Smuzhiyun xEvent event = { .u.u.type = DestroyNotify };
1053*4882a593Smuzhiyun event.u.destroyNotify.window = pChild->drawable.id;
1054*4882a593Smuzhiyun DeliverEvents(pChild, &event, 1, NullWindow);
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun FreeResource(pChild->drawable.id, RT_WINDOW);
1057*4882a593Smuzhiyun pSib = pChild->nextSib;
1058*4882a593Smuzhiyun pChild->viewable = FALSE;
1059*4882a593Smuzhiyun if (pChild->realized) {
1060*4882a593Smuzhiyun pChild->realized = FALSE;
1061*4882a593Smuzhiyun (*UnrealizeWindow) (pChild);
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun FreeWindowResources(pChild);
1064*4882a593Smuzhiyun dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW);
1065*4882a593Smuzhiyun if ((pChild = pSib))
1066*4882a593Smuzhiyun break;
1067*4882a593Smuzhiyun pChild = pParent;
1068*4882a593Smuzhiyun pChild->firstChild = NullWindow;
1069*4882a593Smuzhiyun pChild->lastChild = NullWindow;
1070*4882a593Smuzhiyun if (pChild == pWin)
1071*4882a593Smuzhiyun return;
1072*4882a593Smuzhiyun }
1073*4882a593Smuzhiyun }
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun /*****
1077*4882a593Smuzhiyun * DeleteWindow
1078*4882a593Smuzhiyun * Deletes child of window then window itself
1079*4882a593Smuzhiyun * If wid is None, don't send any events
1080*4882a593Smuzhiyun *****/
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun int
DeleteWindow(void * value,XID wid)1083*4882a593Smuzhiyun DeleteWindow(void *value, XID wid)
1084*4882a593Smuzhiyun {
1085*4882a593Smuzhiyun WindowPtr pParent;
1086*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) value;
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun UnmapWindow(pWin, FALSE);
1089*4882a593Smuzhiyun
1090*4882a593Smuzhiyun CrushTree(pWin);
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun pParent = pWin->parent;
1093*4882a593Smuzhiyun if (wid && pParent && SubStrSend(pWin, pParent)) {
1094*4882a593Smuzhiyun xEvent event = { .u.u.type = DestroyNotify };
1095*4882a593Smuzhiyun event.u.destroyNotify.window = pWin->drawable.id;
1096*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun
1099*4882a593Smuzhiyun FreeWindowResources(pWin);
1100*4882a593Smuzhiyun if (pParent) {
1101*4882a593Smuzhiyun if (pParent->firstChild == pWin)
1102*4882a593Smuzhiyun pParent->firstChild = pWin->nextSib;
1103*4882a593Smuzhiyun if (pParent->lastChild == pWin)
1104*4882a593Smuzhiyun pParent->lastChild = pWin->prevSib;
1105*4882a593Smuzhiyun if (pWin->nextSib)
1106*4882a593Smuzhiyun pWin->nextSib->prevSib = pWin->prevSib;
1107*4882a593Smuzhiyun if (pWin->prevSib)
1108*4882a593Smuzhiyun pWin->prevSib->nextSib = pWin->nextSib;
1109*4882a593Smuzhiyun }
1110*4882a593Smuzhiyun else
1111*4882a593Smuzhiyun pWin->drawable.pScreen->root = NULL;
1112*4882a593Smuzhiyun dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
1113*4882a593Smuzhiyun return Success;
1114*4882a593Smuzhiyun }
1115*4882a593Smuzhiyun
1116*4882a593Smuzhiyun int
DestroySubwindows(WindowPtr pWin,ClientPtr client)1117*4882a593Smuzhiyun DestroySubwindows(WindowPtr pWin, ClientPtr client)
1118*4882a593Smuzhiyun {
1119*4882a593Smuzhiyun /* XXX
1120*4882a593Smuzhiyun * The protocol is quite clear that each window should be
1121*4882a593Smuzhiyun * destroyed in turn, however, unmapping all of the first
1122*4882a593Smuzhiyun * eliminates most of the calls to ValidateTree. So,
1123*4882a593Smuzhiyun * this implementation is incorrect in that all of the
1124*4882a593Smuzhiyun * UnmapNotifies occur before all of the DestroyNotifies.
1125*4882a593Smuzhiyun * If you care, simply delete the call to UnmapSubwindows.
1126*4882a593Smuzhiyun */
1127*4882a593Smuzhiyun UnmapSubwindows(pWin);
1128*4882a593Smuzhiyun while (pWin->lastChild) {
1129*4882a593Smuzhiyun int rc = XaceHook(XACE_RESOURCE_ACCESS, client,
1130*4882a593Smuzhiyun pWin->lastChild->drawable.id, RT_WINDOW,
1131*4882a593Smuzhiyun pWin->lastChild, RT_NONE, NULL, DixDestroyAccess);
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun if (rc != Success)
1134*4882a593Smuzhiyun return rc;
1135*4882a593Smuzhiyun FreeResource(pWin->lastChild->drawable.id, RT_NONE);
1136*4882a593Smuzhiyun }
1137*4882a593Smuzhiyun return Success;
1138*4882a593Smuzhiyun }
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun static void
SetRootWindowBackground(WindowPtr pWin,ScreenPtr pScreen,Mask * index2)1141*4882a593Smuzhiyun SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2)
1142*4882a593Smuzhiyun {
1143*4882a593Smuzhiyun /* following the protocol: "Changing the background of a root window to
1144*4882a593Smuzhiyun * None or ParentRelative restores the default background pixmap" */
1145*4882a593Smuzhiyun if (bgNoneRoot) {
1146*4882a593Smuzhiyun pWin->backgroundState = XaceBackgroundNoneState(pWin);
1147*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun else if (party_like_its_1989)
1150*4882a593Smuzhiyun MakeRootTile(pWin);
1151*4882a593Smuzhiyun else {
1152*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixel;
1153*4882a593Smuzhiyun if (whiteRoot)
1154*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
1155*4882a593Smuzhiyun else
1156*4882a593Smuzhiyun pWin->background.pixel = pScreen->blackPixel;
1157*4882a593Smuzhiyun *index2 = CWBackPixel;
1158*4882a593Smuzhiyun }
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun /*****
1162*4882a593Smuzhiyun * ChangeWindowAttributes
1163*4882a593Smuzhiyun *
1164*4882a593Smuzhiyun * The value-mask specifies which attributes are to be changed; the
1165*4882a593Smuzhiyun * value-list contains one value for each one bit in the mask, from least
1166*4882a593Smuzhiyun * to most significant bit in the mask.
1167*4882a593Smuzhiyun *****/
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun int
ChangeWindowAttributes(WindowPtr pWin,Mask vmask,XID * vlist,ClientPtr client)1170*4882a593Smuzhiyun ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
1171*4882a593Smuzhiyun {
1172*4882a593Smuzhiyun XID *pVlist;
1173*4882a593Smuzhiyun PixmapPtr pPixmap;
1174*4882a593Smuzhiyun Pixmap pixID;
1175*4882a593Smuzhiyun CursorPtr pCursor, pOldCursor;
1176*4882a593Smuzhiyun Cursor cursorID;
1177*4882a593Smuzhiyun WindowPtr pChild;
1178*4882a593Smuzhiyun Colormap cmap;
1179*4882a593Smuzhiyun ColormapPtr pCmap;
1180*4882a593Smuzhiyun xEvent xE;
1181*4882a593Smuzhiyun int error, rc;
1182*4882a593Smuzhiyun ScreenPtr pScreen;
1183*4882a593Smuzhiyun Mask index2, tmask, vmaskCopy = 0;
1184*4882a593Smuzhiyun unsigned int val;
1185*4882a593Smuzhiyun Bool checkOptional = FALSE, borderRelative = FALSE;
1186*4882a593Smuzhiyun
1187*4882a593Smuzhiyun if ((pWin->drawable.class == InputOnly) &&
1188*4882a593Smuzhiyun (vmask & (~INPUTONLY_LEGAL_MASK)))
1189*4882a593Smuzhiyun return BadMatch;
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun error = Success;
1192*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
1193*4882a593Smuzhiyun pVlist = vlist;
1194*4882a593Smuzhiyun tmask = vmask;
1195*4882a593Smuzhiyun while (tmask) {
1196*4882a593Smuzhiyun index2 = (Mask) lowbit(tmask);
1197*4882a593Smuzhiyun tmask &= ~index2;
1198*4882a593Smuzhiyun switch (index2) {
1199*4882a593Smuzhiyun case CWBackPixmap:
1200*4882a593Smuzhiyun pixID = (Pixmap) * pVlist;
1201*4882a593Smuzhiyun pVlist++;
1202*4882a593Smuzhiyun if (pWin->backgroundState == ParentRelative)
1203*4882a593Smuzhiyun borderRelative = TRUE;
1204*4882a593Smuzhiyun if (pixID == None) {
1205*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixmap)
1206*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->background.pixmap);
1207*4882a593Smuzhiyun if (!pWin->parent)
1208*4882a593Smuzhiyun SetRootWindowBackground(pWin, pScreen, &index2);
1209*4882a593Smuzhiyun else {
1210*4882a593Smuzhiyun pWin->backgroundState = XaceBackgroundNoneState(pWin);
1211*4882a593Smuzhiyun pWin->background.pixel = pScreen->whitePixel;
1212*4882a593Smuzhiyun }
1213*4882a593Smuzhiyun }
1214*4882a593Smuzhiyun else if (pixID == ParentRelative) {
1215*4882a593Smuzhiyun if (pWin->parent &&
1216*4882a593Smuzhiyun pWin->drawable.depth != pWin->parent->drawable.depth) {
1217*4882a593Smuzhiyun error = BadMatch;
1218*4882a593Smuzhiyun goto PatchUp;
1219*4882a593Smuzhiyun }
1220*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixmap)
1221*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->background.pixmap);
1222*4882a593Smuzhiyun if (!pWin->parent)
1223*4882a593Smuzhiyun SetRootWindowBackground(pWin, pScreen, &index2);
1224*4882a593Smuzhiyun else
1225*4882a593Smuzhiyun pWin->backgroundState = ParentRelative;
1226*4882a593Smuzhiyun borderRelative = TRUE;
1227*4882a593Smuzhiyun /* Note that the parent's backgroundTile's refcnt is NOT
1228*4882a593Smuzhiyun * incremented. */
1229*4882a593Smuzhiyun }
1230*4882a593Smuzhiyun else {
1231*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pPixmap, pixID,
1232*4882a593Smuzhiyun RT_PIXMAP, client, DixReadAccess);
1233*4882a593Smuzhiyun if (rc == Success) {
1234*4882a593Smuzhiyun if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
1235*4882a593Smuzhiyun (pPixmap->drawable.pScreen != pScreen)) {
1236*4882a593Smuzhiyun error = BadMatch;
1237*4882a593Smuzhiyun goto PatchUp;
1238*4882a593Smuzhiyun }
1239*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixmap)
1240*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->background.pixmap);
1241*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixmap;
1242*4882a593Smuzhiyun pWin->background.pixmap = pPixmap;
1243*4882a593Smuzhiyun pPixmap->refcnt++;
1244*4882a593Smuzhiyun }
1245*4882a593Smuzhiyun else {
1246*4882a593Smuzhiyun error = rc;
1247*4882a593Smuzhiyun client->errorValue = pixID;
1248*4882a593Smuzhiyun goto PatchUp;
1249*4882a593Smuzhiyun }
1250*4882a593Smuzhiyun }
1251*4882a593Smuzhiyun break;
1252*4882a593Smuzhiyun case CWBackPixel:
1253*4882a593Smuzhiyun if (pWin->backgroundState == ParentRelative)
1254*4882a593Smuzhiyun borderRelative = TRUE;
1255*4882a593Smuzhiyun if (pWin->backgroundState == BackgroundPixmap)
1256*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->background.pixmap);
1257*4882a593Smuzhiyun pWin->backgroundState = BackgroundPixel;
1258*4882a593Smuzhiyun pWin->background.pixel = (CARD32) *pVlist;
1259*4882a593Smuzhiyun /* background pixel overrides background pixmap,
1260*4882a593Smuzhiyun so don't let the ddx layer see both bits */
1261*4882a593Smuzhiyun vmaskCopy &= ~CWBackPixmap;
1262*4882a593Smuzhiyun pVlist++;
1263*4882a593Smuzhiyun break;
1264*4882a593Smuzhiyun case CWBorderPixmap:
1265*4882a593Smuzhiyun pixID = (Pixmap) * pVlist;
1266*4882a593Smuzhiyun pVlist++;
1267*4882a593Smuzhiyun if (pixID == CopyFromParent) {
1268*4882a593Smuzhiyun if (!pWin->parent ||
1269*4882a593Smuzhiyun (pWin->drawable.depth != pWin->parent->drawable.depth)) {
1270*4882a593Smuzhiyun error = BadMatch;
1271*4882a593Smuzhiyun goto PatchUp;
1272*4882a593Smuzhiyun }
1273*4882a593Smuzhiyun if (pWin->parent->borderIsPixel == TRUE) {
1274*4882a593Smuzhiyun if (pWin->borderIsPixel == FALSE)
1275*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->border.pixmap);
1276*4882a593Smuzhiyun pWin->border = pWin->parent->border;
1277*4882a593Smuzhiyun pWin->borderIsPixel = TRUE;
1278*4882a593Smuzhiyun index2 = CWBorderPixel;
1279*4882a593Smuzhiyun break;
1280*4882a593Smuzhiyun }
1281*4882a593Smuzhiyun else {
1282*4882a593Smuzhiyun pixID = pWin->parent->border.pixmap->drawable.id;
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun }
1285*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP,
1286*4882a593Smuzhiyun client, DixReadAccess);
1287*4882a593Smuzhiyun if (rc == Success) {
1288*4882a593Smuzhiyun if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
1289*4882a593Smuzhiyun (pPixmap->drawable.pScreen != pScreen)) {
1290*4882a593Smuzhiyun error = BadMatch;
1291*4882a593Smuzhiyun goto PatchUp;
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun if (pWin->borderIsPixel == FALSE)
1294*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->border.pixmap);
1295*4882a593Smuzhiyun pWin->borderIsPixel = FALSE;
1296*4882a593Smuzhiyun pWin->border.pixmap = pPixmap;
1297*4882a593Smuzhiyun pPixmap->refcnt++;
1298*4882a593Smuzhiyun }
1299*4882a593Smuzhiyun else {
1300*4882a593Smuzhiyun error = rc;
1301*4882a593Smuzhiyun client->errorValue = pixID;
1302*4882a593Smuzhiyun goto PatchUp;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun break;
1305*4882a593Smuzhiyun case CWBorderPixel:
1306*4882a593Smuzhiyun if (pWin->borderIsPixel == FALSE)
1307*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pWin->border.pixmap);
1308*4882a593Smuzhiyun pWin->borderIsPixel = TRUE;
1309*4882a593Smuzhiyun pWin->border.pixel = (CARD32) *pVlist;
1310*4882a593Smuzhiyun /* border pixel overrides border pixmap,
1311*4882a593Smuzhiyun so don't let the ddx layer see both bits */
1312*4882a593Smuzhiyun vmaskCopy &= ~CWBorderPixmap;
1313*4882a593Smuzhiyun pVlist++;
1314*4882a593Smuzhiyun break;
1315*4882a593Smuzhiyun case CWBitGravity:
1316*4882a593Smuzhiyun val = (CARD8) *pVlist;
1317*4882a593Smuzhiyun pVlist++;
1318*4882a593Smuzhiyun if (val > StaticGravity) {
1319*4882a593Smuzhiyun error = BadValue;
1320*4882a593Smuzhiyun client->errorValue = val;
1321*4882a593Smuzhiyun goto PatchUp;
1322*4882a593Smuzhiyun }
1323*4882a593Smuzhiyun pWin->bitGravity = val;
1324*4882a593Smuzhiyun break;
1325*4882a593Smuzhiyun case CWWinGravity:
1326*4882a593Smuzhiyun val = (CARD8) *pVlist;
1327*4882a593Smuzhiyun pVlist++;
1328*4882a593Smuzhiyun if (val > StaticGravity) {
1329*4882a593Smuzhiyun error = BadValue;
1330*4882a593Smuzhiyun client->errorValue = val;
1331*4882a593Smuzhiyun goto PatchUp;
1332*4882a593Smuzhiyun }
1333*4882a593Smuzhiyun pWin->winGravity = val;
1334*4882a593Smuzhiyun break;
1335*4882a593Smuzhiyun case CWBackingStore:
1336*4882a593Smuzhiyun val = (CARD8) *pVlist;
1337*4882a593Smuzhiyun pVlist++;
1338*4882a593Smuzhiyun if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
1339*4882a593Smuzhiyun error = BadValue;
1340*4882a593Smuzhiyun client->errorValue = val;
1341*4882a593Smuzhiyun goto PatchUp;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun pWin->backingStore = val;
1344*4882a593Smuzhiyun pWin->forcedBS = FALSE;
1345*4882a593Smuzhiyun break;
1346*4882a593Smuzhiyun case CWBackingPlanes:
1347*4882a593Smuzhiyun if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) {
1348*4882a593Smuzhiyun if (!pWin->optional && !MakeWindowOptional(pWin)) {
1349*4882a593Smuzhiyun error = BadAlloc;
1350*4882a593Smuzhiyun goto PatchUp;
1351*4882a593Smuzhiyun }
1352*4882a593Smuzhiyun pWin->optional->backingBitPlanes = (CARD32) *pVlist;
1353*4882a593Smuzhiyun if ((CARD32) *pVlist == (CARD32) ~0L)
1354*4882a593Smuzhiyun checkOptional = TRUE;
1355*4882a593Smuzhiyun }
1356*4882a593Smuzhiyun pVlist++;
1357*4882a593Smuzhiyun break;
1358*4882a593Smuzhiyun case CWBackingPixel:
1359*4882a593Smuzhiyun if (pWin->optional || (CARD32) *pVlist) {
1360*4882a593Smuzhiyun if (!pWin->optional && !MakeWindowOptional(pWin)) {
1361*4882a593Smuzhiyun error = BadAlloc;
1362*4882a593Smuzhiyun goto PatchUp;
1363*4882a593Smuzhiyun }
1364*4882a593Smuzhiyun pWin->optional->backingPixel = (CARD32) *pVlist;
1365*4882a593Smuzhiyun if (!*pVlist)
1366*4882a593Smuzhiyun checkOptional = TRUE;
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun pVlist++;
1369*4882a593Smuzhiyun break;
1370*4882a593Smuzhiyun case CWSaveUnder:
1371*4882a593Smuzhiyun val = (BOOL) * pVlist;
1372*4882a593Smuzhiyun pVlist++;
1373*4882a593Smuzhiyun if ((val != xTrue) && (val != xFalse)) {
1374*4882a593Smuzhiyun error = BadValue;
1375*4882a593Smuzhiyun client->errorValue = val;
1376*4882a593Smuzhiyun goto PatchUp;
1377*4882a593Smuzhiyun }
1378*4882a593Smuzhiyun pWin->saveUnder = val;
1379*4882a593Smuzhiyun break;
1380*4882a593Smuzhiyun case CWEventMask:
1381*4882a593Smuzhiyun rc = EventSelectForWindow(pWin, client, (Mask) *pVlist);
1382*4882a593Smuzhiyun if (rc) {
1383*4882a593Smuzhiyun error = rc;
1384*4882a593Smuzhiyun goto PatchUp;
1385*4882a593Smuzhiyun }
1386*4882a593Smuzhiyun pVlist++;
1387*4882a593Smuzhiyun break;
1388*4882a593Smuzhiyun case CWDontPropagate:
1389*4882a593Smuzhiyun rc = EventSuppressForWindow(pWin, client, (Mask) *pVlist,
1390*4882a593Smuzhiyun &checkOptional);
1391*4882a593Smuzhiyun if (rc) {
1392*4882a593Smuzhiyun error = rc;
1393*4882a593Smuzhiyun goto PatchUp;
1394*4882a593Smuzhiyun }
1395*4882a593Smuzhiyun pVlist++;
1396*4882a593Smuzhiyun break;
1397*4882a593Smuzhiyun case CWOverrideRedirect:
1398*4882a593Smuzhiyun val = (BOOL) * pVlist;
1399*4882a593Smuzhiyun pVlist++;
1400*4882a593Smuzhiyun if ((val != xTrue) && (val != xFalse)) {
1401*4882a593Smuzhiyun error = BadValue;
1402*4882a593Smuzhiyun client->errorValue = val;
1403*4882a593Smuzhiyun goto PatchUp;
1404*4882a593Smuzhiyun }
1405*4882a593Smuzhiyun if (val == xTrue) {
1406*4882a593Smuzhiyun rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id,
1407*4882a593Smuzhiyun RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess);
1408*4882a593Smuzhiyun if (rc != Success) {
1409*4882a593Smuzhiyun error = rc;
1410*4882a593Smuzhiyun client->errorValue = pWin->drawable.id;
1411*4882a593Smuzhiyun goto PatchUp;
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun }
1414*4882a593Smuzhiyun pWin->overrideRedirect = val;
1415*4882a593Smuzhiyun break;
1416*4882a593Smuzhiyun case CWColormap:
1417*4882a593Smuzhiyun cmap = (Colormap) * pVlist;
1418*4882a593Smuzhiyun pVlist++;
1419*4882a593Smuzhiyun if (cmap == CopyFromParent) {
1420*4882a593Smuzhiyun if (pWin->parent &&
1421*4882a593Smuzhiyun (!pWin->optional ||
1422*4882a593Smuzhiyun pWin->optional->visual == wVisual(pWin->parent))) {
1423*4882a593Smuzhiyun cmap = wColormap(pWin->parent);
1424*4882a593Smuzhiyun }
1425*4882a593Smuzhiyun else
1426*4882a593Smuzhiyun cmap = None;
1427*4882a593Smuzhiyun }
1428*4882a593Smuzhiyun if (cmap == None) {
1429*4882a593Smuzhiyun error = BadMatch;
1430*4882a593Smuzhiyun goto PatchUp;
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP,
1433*4882a593Smuzhiyun client, DixUseAccess);
1434*4882a593Smuzhiyun if (rc != Success) {
1435*4882a593Smuzhiyun error = rc;
1436*4882a593Smuzhiyun client->errorValue = cmap;
1437*4882a593Smuzhiyun goto PatchUp;
1438*4882a593Smuzhiyun }
1439*4882a593Smuzhiyun if (pCmap->pVisual->vid != wVisual(pWin) ||
1440*4882a593Smuzhiyun pCmap->pScreen != pScreen) {
1441*4882a593Smuzhiyun error = BadMatch;
1442*4882a593Smuzhiyun goto PatchUp;
1443*4882a593Smuzhiyun }
1444*4882a593Smuzhiyun if (cmap != wColormap(pWin)) {
1445*4882a593Smuzhiyun if (!pWin->optional) {
1446*4882a593Smuzhiyun if (!MakeWindowOptional(pWin)) {
1447*4882a593Smuzhiyun error = BadAlloc;
1448*4882a593Smuzhiyun goto PatchUp;
1449*4882a593Smuzhiyun }
1450*4882a593Smuzhiyun }
1451*4882a593Smuzhiyun else if (pWin->parent && cmap == wColormap(pWin->parent))
1452*4882a593Smuzhiyun checkOptional = TRUE;
1453*4882a593Smuzhiyun
1454*4882a593Smuzhiyun /*
1455*4882a593Smuzhiyun * propagate the original colormap to any children
1456*4882a593Smuzhiyun * inheriting it
1457*4882a593Smuzhiyun */
1458*4882a593Smuzhiyun
1459*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild;
1460*4882a593Smuzhiyun pChild = pChild->nextSib) {
1461*4882a593Smuzhiyun if (!pChild->optional && !MakeWindowOptional(pChild)) {
1462*4882a593Smuzhiyun error = BadAlloc;
1463*4882a593Smuzhiyun goto PatchUp;
1464*4882a593Smuzhiyun }
1465*4882a593Smuzhiyun }
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun pWin->optional->colormap = cmap;
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun /*
1470*4882a593Smuzhiyun * check on any children now matching the new colormap
1471*4882a593Smuzhiyun */
1472*4882a593Smuzhiyun
1473*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild;
1474*4882a593Smuzhiyun pChild = pChild->nextSib) {
1475*4882a593Smuzhiyun if (pChild->optional->colormap == cmap)
1476*4882a593Smuzhiyun CheckWindowOptionalNeed(pChild);
1477*4882a593Smuzhiyun }
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun xE = (xEvent) {
1480*4882a593Smuzhiyun .u.colormap.window = pWin->drawable.id,
1481*4882a593Smuzhiyun .u.colormap.colormap = cmap,
1482*4882a593Smuzhiyun .u.colormap.new = xTrue,
1483*4882a593Smuzhiyun .u.colormap.state = IsMapInstalled(cmap, pWin)
1484*4882a593Smuzhiyun };
1485*4882a593Smuzhiyun xE.u.u.type = ColormapNotify;
1486*4882a593Smuzhiyun DeliverEvents(pWin, &xE, 1, NullWindow);
1487*4882a593Smuzhiyun }
1488*4882a593Smuzhiyun break;
1489*4882a593Smuzhiyun case CWCursor:
1490*4882a593Smuzhiyun cursorID = (Cursor) * pVlist;
1491*4882a593Smuzhiyun pVlist++;
1492*4882a593Smuzhiyun /*
1493*4882a593Smuzhiyun * install the new
1494*4882a593Smuzhiyun */
1495*4882a593Smuzhiyun if (cursorID == None) {
1496*4882a593Smuzhiyun if (pWin == pWin->drawable.pScreen->root)
1497*4882a593Smuzhiyun pCursor = rootCursor;
1498*4882a593Smuzhiyun else
1499*4882a593Smuzhiyun pCursor = (CursorPtr) None;
1500*4882a593Smuzhiyun }
1501*4882a593Smuzhiyun else {
1502*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pCursor, cursorID,
1503*4882a593Smuzhiyun RT_CURSOR, client, DixUseAccess);
1504*4882a593Smuzhiyun if (rc != Success) {
1505*4882a593Smuzhiyun error = rc;
1506*4882a593Smuzhiyun client->errorValue = cursorID;
1507*4882a593Smuzhiyun goto PatchUp;
1508*4882a593Smuzhiyun }
1509*4882a593Smuzhiyun }
1510*4882a593Smuzhiyun
1511*4882a593Smuzhiyun if (pCursor != wCursor(pWin)) {
1512*4882a593Smuzhiyun /*
1513*4882a593Smuzhiyun * patch up child windows so they don't lose cursors.
1514*4882a593Smuzhiyun */
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild;
1517*4882a593Smuzhiyun pChild = pChild->nextSib) {
1518*4882a593Smuzhiyun if (!pChild->optional && !pChild->cursorIsNone &&
1519*4882a593Smuzhiyun !MakeWindowOptional(pChild)) {
1520*4882a593Smuzhiyun error = BadAlloc;
1521*4882a593Smuzhiyun goto PatchUp;
1522*4882a593Smuzhiyun }
1523*4882a593Smuzhiyun }
1524*4882a593Smuzhiyun
1525*4882a593Smuzhiyun pOldCursor = 0;
1526*4882a593Smuzhiyun if (pCursor == (CursorPtr) None) {
1527*4882a593Smuzhiyun pWin->cursorIsNone = TRUE;
1528*4882a593Smuzhiyun if (pWin->optional) {
1529*4882a593Smuzhiyun pOldCursor = pWin->optional->cursor;
1530*4882a593Smuzhiyun pWin->optional->cursor = (CursorPtr) None;
1531*4882a593Smuzhiyun checkOptional = TRUE;
1532*4882a593Smuzhiyun }
1533*4882a593Smuzhiyun }
1534*4882a593Smuzhiyun else {
1535*4882a593Smuzhiyun if (!pWin->optional) {
1536*4882a593Smuzhiyun if (!MakeWindowOptional(pWin)) {
1537*4882a593Smuzhiyun error = BadAlloc;
1538*4882a593Smuzhiyun goto PatchUp;
1539*4882a593Smuzhiyun }
1540*4882a593Smuzhiyun }
1541*4882a593Smuzhiyun else if (pWin->parent && pCursor == wCursor(pWin->parent))
1542*4882a593Smuzhiyun checkOptional = TRUE;
1543*4882a593Smuzhiyun pOldCursor = pWin->optional->cursor;
1544*4882a593Smuzhiyun pWin->optional->cursor = RefCursor(pCursor);
1545*4882a593Smuzhiyun pWin->cursorIsNone = FALSE;
1546*4882a593Smuzhiyun /*
1547*4882a593Smuzhiyun * check on any children now matching the new cursor
1548*4882a593Smuzhiyun */
1549*4882a593Smuzhiyun
1550*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild;
1551*4882a593Smuzhiyun pChild = pChild->nextSib) {
1552*4882a593Smuzhiyun if (pChild->optional &&
1553*4882a593Smuzhiyun (pChild->optional->cursor == pCursor))
1554*4882a593Smuzhiyun CheckWindowOptionalNeed(pChild);
1555*4882a593Smuzhiyun }
1556*4882a593Smuzhiyun }
1557*4882a593Smuzhiyun
1558*4882a593Smuzhiyun CursorVisible = TRUE;
1559*4882a593Smuzhiyun
1560*4882a593Smuzhiyun if (pWin->realized)
1561*4882a593Smuzhiyun WindowHasNewCursor(pWin);
1562*4882a593Smuzhiyun
1563*4882a593Smuzhiyun /* Can't free cursor until here - old cursor
1564*4882a593Smuzhiyun * is needed in WindowHasNewCursor
1565*4882a593Smuzhiyun */
1566*4882a593Smuzhiyun if (pOldCursor)
1567*4882a593Smuzhiyun FreeCursor(pOldCursor, (Cursor) 0);
1568*4882a593Smuzhiyun }
1569*4882a593Smuzhiyun break;
1570*4882a593Smuzhiyun default:
1571*4882a593Smuzhiyun error = BadValue;
1572*4882a593Smuzhiyun client->errorValue = vmask;
1573*4882a593Smuzhiyun goto PatchUp;
1574*4882a593Smuzhiyun }
1575*4882a593Smuzhiyun vmaskCopy |= index2;
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun PatchUp:
1578*4882a593Smuzhiyun if (checkOptional)
1579*4882a593Smuzhiyun CheckWindowOptionalNeed(pWin);
1580*4882a593Smuzhiyun
1581*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
1582*4882a593Smuzhiyun (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy);
1583*4882a593Smuzhiyun
1584*4882a593Smuzhiyun /*
1585*4882a593Smuzhiyun If the border contents have changed, redraw the border.
1586*4882a593Smuzhiyun Note that this has to be done AFTER pScreen->ChangeWindowAttributes
1587*4882a593Smuzhiyun for the tile to be rotated, and the correct function selected.
1588*4882a593Smuzhiyun */
1589*4882a593Smuzhiyun if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
1590*4882a593Smuzhiyun && pWin->viewable && HasBorder(pWin)) {
1591*4882a593Smuzhiyun RegionRec exposed;
1592*4882a593Smuzhiyun
1593*4882a593Smuzhiyun RegionNull(&exposed);
1594*4882a593Smuzhiyun RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize);
1595*4882a593Smuzhiyun pWin->drawable.pScreen->PaintWindow(pWin, &exposed, PW_BORDER);
1596*4882a593Smuzhiyun RegionUninit(&exposed);
1597*4882a593Smuzhiyun }
1598*4882a593Smuzhiyun return error;
1599*4882a593Smuzhiyun }
1600*4882a593Smuzhiyun
1601*4882a593Smuzhiyun /*****
1602*4882a593Smuzhiyun * GetWindowAttributes
1603*4882a593Smuzhiyun * Notice that this is different than ChangeWindowAttributes
1604*4882a593Smuzhiyun *****/
1605*4882a593Smuzhiyun
1606*4882a593Smuzhiyun void
GetWindowAttributes(WindowPtr pWin,ClientPtr client,xGetWindowAttributesReply * wa)1607*4882a593Smuzhiyun GetWindowAttributes(WindowPtr pWin, ClientPtr client,
1608*4882a593Smuzhiyun xGetWindowAttributesReply * wa)
1609*4882a593Smuzhiyun {
1610*4882a593Smuzhiyun wa->type = X_Reply;
1611*4882a593Smuzhiyun wa->bitGravity = pWin->bitGravity;
1612*4882a593Smuzhiyun wa->winGravity = pWin->winGravity;
1613*4882a593Smuzhiyun if (pWin->forcedBS && pWin->backingStore != Always)
1614*4882a593Smuzhiyun wa->backingStore = NotUseful;
1615*4882a593Smuzhiyun else
1616*4882a593Smuzhiyun wa->backingStore = pWin->backingStore;
1617*4882a593Smuzhiyun wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) -
1618*4882a593Smuzhiyun sizeof(xGenericReply));
1619*4882a593Smuzhiyun wa->sequenceNumber = client->sequence;
1620*4882a593Smuzhiyun wa->backingBitPlanes = wBackingBitPlanes(pWin);
1621*4882a593Smuzhiyun wa->backingPixel = wBackingPixel(pWin);
1622*4882a593Smuzhiyun wa->saveUnder = (BOOL) pWin->saveUnder;
1623*4882a593Smuzhiyun wa->override = pWin->overrideRedirect;
1624*4882a593Smuzhiyun if (!pWin->mapped)
1625*4882a593Smuzhiyun wa->mapState = IsUnmapped;
1626*4882a593Smuzhiyun else if (pWin->realized)
1627*4882a593Smuzhiyun wa->mapState = IsViewable;
1628*4882a593Smuzhiyun else
1629*4882a593Smuzhiyun wa->mapState = IsUnviewable;
1630*4882a593Smuzhiyun
1631*4882a593Smuzhiyun wa->colormap = wColormap(pWin);
1632*4882a593Smuzhiyun wa->mapInstalled = (wa->colormap == None) ? xFalse
1633*4882a593Smuzhiyun : IsMapInstalled(wa->colormap, pWin);
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun wa->yourEventMask = EventMaskForClient(pWin, client);
1636*4882a593Smuzhiyun wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin);
1637*4882a593Smuzhiyun wa->doNotPropagateMask = wDontPropagateMask(pWin);
1638*4882a593Smuzhiyun wa->class = pWin->drawable.class;
1639*4882a593Smuzhiyun wa->visualID = wVisual(pWin);
1640*4882a593Smuzhiyun }
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun WindowPtr
MoveWindowInStack(WindowPtr pWin,WindowPtr pNextSib)1643*4882a593Smuzhiyun MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib)
1644*4882a593Smuzhiyun {
1645*4882a593Smuzhiyun WindowPtr pParent = pWin->parent;
1646*4882a593Smuzhiyun WindowPtr pFirstChange = pWin; /* highest window where list changes */
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun if (pWin->nextSib != pNextSib) {
1649*4882a593Smuzhiyun WindowPtr pOldNextSib = pWin->nextSib;
1650*4882a593Smuzhiyun
1651*4882a593Smuzhiyun if (!pNextSib) { /* move to bottom */
1652*4882a593Smuzhiyun if (pParent->firstChild == pWin)
1653*4882a593Smuzhiyun pParent->firstChild = pWin->nextSib;
1654*4882a593Smuzhiyun /* if (pWin->nextSib) *//* is always True: pNextSib == NULL
1655*4882a593Smuzhiyun * and pWin->nextSib != pNextSib
1656*4882a593Smuzhiyun * therefore pWin->nextSib != NULL */
1657*4882a593Smuzhiyun pFirstChange = pWin->nextSib;
1658*4882a593Smuzhiyun pWin->nextSib->prevSib = pWin->prevSib;
1659*4882a593Smuzhiyun if (pWin->prevSib)
1660*4882a593Smuzhiyun pWin->prevSib->nextSib = pWin->nextSib;
1661*4882a593Smuzhiyun pParent->lastChild->nextSib = pWin;
1662*4882a593Smuzhiyun pWin->prevSib = pParent->lastChild;
1663*4882a593Smuzhiyun pWin->nextSib = NullWindow;
1664*4882a593Smuzhiyun pParent->lastChild = pWin;
1665*4882a593Smuzhiyun }
1666*4882a593Smuzhiyun else if (pParent->firstChild == pNextSib) { /* move to top */
1667*4882a593Smuzhiyun pFirstChange = pWin;
1668*4882a593Smuzhiyun if (pParent->lastChild == pWin)
1669*4882a593Smuzhiyun pParent->lastChild = pWin->prevSib;
1670*4882a593Smuzhiyun if (pWin->nextSib)
1671*4882a593Smuzhiyun pWin->nextSib->prevSib = pWin->prevSib;
1672*4882a593Smuzhiyun if (pWin->prevSib)
1673*4882a593Smuzhiyun pWin->prevSib->nextSib = pWin->nextSib;
1674*4882a593Smuzhiyun pWin->nextSib = pParent->firstChild;
1675*4882a593Smuzhiyun pWin->prevSib = NULL;
1676*4882a593Smuzhiyun pNextSib->prevSib = pWin;
1677*4882a593Smuzhiyun pParent->firstChild = pWin;
1678*4882a593Smuzhiyun }
1679*4882a593Smuzhiyun else { /* move in middle of list */
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun WindowPtr pOldNext = pWin->nextSib;
1682*4882a593Smuzhiyun
1683*4882a593Smuzhiyun pFirstChange = NullWindow;
1684*4882a593Smuzhiyun if (pParent->firstChild == pWin)
1685*4882a593Smuzhiyun pFirstChange = pParent->firstChild = pWin->nextSib;
1686*4882a593Smuzhiyun if (pParent->lastChild == pWin) {
1687*4882a593Smuzhiyun pFirstChange = pWin;
1688*4882a593Smuzhiyun pParent->lastChild = pWin->prevSib;
1689*4882a593Smuzhiyun }
1690*4882a593Smuzhiyun if (pWin->nextSib)
1691*4882a593Smuzhiyun pWin->nextSib->prevSib = pWin->prevSib;
1692*4882a593Smuzhiyun if (pWin->prevSib)
1693*4882a593Smuzhiyun pWin->prevSib->nextSib = pWin->nextSib;
1694*4882a593Smuzhiyun pWin->nextSib = pNextSib;
1695*4882a593Smuzhiyun pWin->prevSib = pNextSib->prevSib;
1696*4882a593Smuzhiyun if (pNextSib->prevSib)
1697*4882a593Smuzhiyun pNextSib->prevSib->nextSib = pWin;
1698*4882a593Smuzhiyun pNextSib->prevSib = pWin;
1699*4882a593Smuzhiyun if (!pFirstChange) { /* do we know it yet? */
1700*4882a593Smuzhiyun pFirstChange = pParent->firstChild; /* no, search from top */
1701*4882a593Smuzhiyun while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
1702*4882a593Smuzhiyun pFirstChange = pFirstChange->nextSib;
1703*4882a593Smuzhiyun }
1704*4882a593Smuzhiyun }
1705*4882a593Smuzhiyun if (pWin->drawable.pScreen->RestackWindow)
1706*4882a593Smuzhiyun (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib);
1707*4882a593Smuzhiyun }
1708*4882a593Smuzhiyun
1709*4882a593Smuzhiyun #ifdef ROOTLESS
1710*4882a593Smuzhiyun /*
1711*4882a593Smuzhiyun * In rootless mode we can't optimize away window restacks.
1712*4882a593Smuzhiyun * There may be non-X windows around, so even if the window
1713*4882a593Smuzhiyun * is in the correct position from X's point of view,
1714*4882a593Smuzhiyun * the underlying window system may want to reorder it.
1715*4882a593Smuzhiyun */
1716*4882a593Smuzhiyun else if (pWin->drawable.pScreen->RestackWindow)
1717*4882a593Smuzhiyun (*pWin->drawable.pScreen->RestackWindow) (pWin, pWin->nextSib);
1718*4882a593Smuzhiyun #endif
1719*4882a593Smuzhiyun
1720*4882a593Smuzhiyun return pFirstChange;
1721*4882a593Smuzhiyun }
1722*4882a593Smuzhiyun
1723*4882a593Smuzhiyun void
SetWinSize(WindowPtr pWin)1724*4882a593Smuzhiyun SetWinSize(WindowPtr pWin)
1725*4882a593Smuzhiyun {
1726*4882a593Smuzhiyun #ifdef COMPOSITE
1727*4882a593Smuzhiyun if (pWin->redirectDraw != RedirectDrawNone) {
1728*4882a593Smuzhiyun BoxRec box;
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun /*
1731*4882a593Smuzhiyun * Redirected clients get clip list equal to their
1732*4882a593Smuzhiyun * own geometry, not clipped to their parent
1733*4882a593Smuzhiyun */
1734*4882a593Smuzhiyun box.x1 = pWin->drawable.x;
1735*4882a593Smuzhiyun box.y1 = pWin->drawable.y;
1736*4882a593Smuzhiyun box.x2 = pWin->drawable.x + pWin->drawable.width;
1737*4882a593Smuzhiyun box.y2 = pWin->drawable.y + pWin->drawable.height;
1738*4882a593Smuzhiyun RegionReset(&pWin->winSize, &box);
1739*4882a593Smuzhiyun }
1740*4882a593Smuzhiyun else
1741*4882a593Smuzhiyun #endif
1742*4882a593Smuzhiyun ClippedRegionFromBox(pWin->parent, &pWin->winSize,
1743*4882a593Smuzhiyun pWin->drawable.x, pWin->drawable.y,
1744*4882a593Smuzhiyun (int) pWin->drawable.width,
1745*4882a593Smuzhiyun (int) pWin->drawable.height);
1746*4882a593Smuzhiyun if (wBoundingShape(pWin) || wClipShape(pWin)) {
1747*4882a593Smuzhiyun RegionTranslate(&pWin->winSize, -pWin->drawable.x, -pWin->drawable.y);
1748*4882a593Smuzhiyun if (wBoundingShape(pWin))
1749*4882a593Smuzhiyun RegionIntersect(&pWin->winSize, &pWin->winSize,
1750*4882a593Smuzhiyun wBoundingShape(pWin));
1751*4882a593Smuzhiyun if (wClipShape(pWin))
1752*4882a593Smuzhiyun RegionIntersect(&pWin->winSize, &pWin->winSize, wClipShape(pWin));
1753*4882a593Smuzhiyun RegionTranslate(&pWin->winSize, pWin->drawable.x, pWin->drawable.y);
1754*4882a593Smuzhiyun }
1755*4882a593Smuzhiyun }
1756*4882a593Smuzhiyun
1757*4882a593Smuzhiyun void
SetBorderSize(WindowPtr pWin)1758*4882a593Smuzhiyun SetBorderSize(WindowPtr pWin)
1759*4882a593Smuzhiyun {
1760*4882a593Smuzhiyun int bw;
1761*4882a593Smuzhiyun
1762*4882a593Smuzhiyun if (HasBorder(pWin)) {
1763*4882a593Smuzhiyun bw = wBorderWidth(pWin);
1764*4882a593Smuzhiyun #ifdef COMPOSITE
1765*4882a593Smuzhiyun if (pWin->redirectDraw != RedirectDrawNone) {
1766*4882a593Smuzhiyun BoxRec box;
1767*4882a593Smuzhiyun
1768*4882a593Smuzhiyun /*
1769*4882a593Smuzhiyun * Redirected clients get clip list equal to their
1770*4882a593Smuzhiyun * own geometry, not clipped to their parent
1771*4882a593Smuzhiyun */
1772*4882a593Smuzhiyun box.x1 = pWin->drawable.x - bw;
1773*4882a593Smuzhiyun box.y1 = pWin->drawable.y - bw;
1774*4882a593Smuzhiyun box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
1775*4882a593Smuzhiyun box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
1776*4882a593Smuzhiyun RegionReset(&pWin->borderSize, &box);
1777*4882a593Smuzhiyun }
1778*4882a593Smuzhiyun else
1779*4882a593Smuzhiyun #endif
1780*4882a593Smuzhiyun ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
1781*4882a593Smuzhiyun pWin->drawable.x - bw, pWin->drawable.y - bw,
1782*4882a593Smuzhiyun (int) (pWin->drawable.width + (bw << 1)),
1783*4882a593Smuzhiyun (int) (pWin->drawable.height + (bw << 1)));
1784*4882a593Smuzhiyun if (wBoundingShape(pWin)) {
1785*4882a593Smuzhiyun RegionTranslate(&pWin->borderSize, -pWin->drawable.x,
1786*4882a593Smuzhiyun -pWin->drawable.y);
1787*4882a593Smuzhiyun RegionIntersect(&pWin->borderSize, &pWin->borderSize,
1788*4882a593Smuzhiyun wBoundingShape(pWin));
1789*4882a593Smuzhiyun RegionTranslate(&pWin->borderSize, pWin->drawable.x,
1790*4882a593Smuzhiyun pWin->drawable.y);
1791*4882a593Smuzhiyun RegionUnion(&pWin->borderSize, &pWin->borderSize, &pWin->winSize);
1792*4882a593Smuzhiyun }
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun else {
1795*4882a593Smuzhiyun RegionCopy(&pWin->borderSize, &pWin->winSize);
1796*4882a593Smuzhiyun }
1797*4882a593Smuzhiyun }
1798*4882a593Smuzhiyun
1799*4882a593Smuzhiyun /**
1800*4882a593Smuzhiyun *
1801*4882a593Smuzhiyun * \param x,y new window position
1802*4882a593Smuzhiyun * \param oldx,oldy old window position
1803*4882a593Smuzhiyun * \param destx,desty position relative to gravity
1804*4882a593Smuzhiyun */
1805*4882a593Smuzhiyun
1806*4882a593Smuzhiyun void
GravityTranslate(int x,int y,int oldx,int oldy,int dw,int dh,unsigned gravity,int * destx,int * desty)1807*4882a593Smuzhiyun GravityTranslate(int x, int y, int oldx, int oldy,
1808*4882a593Smuzhiyun int dw, int dh, unsigned gravity, int *destx, int *desty)
1809*4882a593Smuzhiyun {
1810*4882a593Smuzhiyun switch (gravity) {
1811*4882a593Smuzhiyun case NorthGravity:
1812*4882a593Smuzhiyun *destx = x + dw / 2;
1813*4882a593Smuzhiyun *desty = y;
1814*4882a593Smuzhiyun break;
1815*4882a593Smuzhiyun case NorthEastGravity:
1816*4882a593Smuzhiyun *destx = x + dw;
1817*4882a593Smuzhiyun *desty = y;
1818*4882a593Smuzhiyun break;
1819*4882a593Smuzhiyun case WestGravity:
1820*4882a593Smuzhiyun *destx = x;
1821*4882a593Smuzhiyun *desty = y + dh / 2;
1822*4882a593Smuzhiyun break;
1823*4882a593Smuzhiyun case CenterGravity:
1824*4882a593Smuzhiyun *destx = x + dw / 2;
1825*4882a593Smuzhiyun *desty = y + dh / 2;
1826*4882a593Smuzhiyun break;
1827*4882a593Smuzhiyun case EastGravity:
1828*4882a593Smuzhiyun *destx = x + dw;
1829*4882a593Smuzhiyun *desty = y + dh / 2;
1830*4882a593Smuzhiyun break;
1831*4882a593Smuzhiyun case SouthWestGravity:
1832*4882a593Smuzhiyun *destx = x;
1833*4882a593Smuzhiyun *desty = y + dh;
1834*4882a593Smuzhiyun break;
1835*4882a593Smuzhiyun case SouthGravity:
1836*4882a593Smuzhiyun *destx = x + dw / 2;
1837*4882a593Smuzhiyun *desty = y + dh;
1838*4882a593Smuzhiyun break;
1839*4882a593Smuzhiyun case SouthEastGravity:
1840*4882a593Smuzhiyun *destx = x + dw;
1841*4882a593Smuzhiyun *desty = y + dh;
1842*4882a593Smuzhiyun break;
1843*4882a593Smuzhiyun case StaticGravity:
1844*4882a593Smuzhiyun *destx = oldx;
1845*4882a593Smuzhiyun *desty = oldy;
1846*4882a593Smuzhiyun break;
1847*4882a593Smuzhiyun default:
1848*4882a593Smuzhiyun *destx = x;
1849*4882a593Smuzhiyun *desty = y;
1850*4882a593Smuzhiyun break;
1851*4882a593Smuzhiyun }
1852*4882a593Smuzhiyun }
1853*4882a593Smuzhiyun
1854*4882a593Smuzhiyun /* XXX need to retile border on each window with ParentRelative origin */
1855*4882a593Smuzhiyun void
ResizeChildrenWinSize(WindowPtr pWin,int dx,int dy,int dw,int dh)1856*4882a593Smuzhiyun ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
1857*4882a593Smuzhiyun {
1858*4882a593Smuzhiyun ScreenPtr pScreen;
1859*4882a593Smuzhiyun WindowPtr pSib, pChild;
1860*4882a593Smuzhiyun Bool resized = (dw || dh);
1861*4882a593Smuzhiyun
1862*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
1863*4882a593Smuzhiyun
1864*4882a593Smuzhiyun for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) {
1865*4882a593Smuzhiyun if (resized && (pSib->winGravity > NorthWestGravity)) {
1866*4882a593Smuzhiyun int cwsx, cwsy;
1867*4882a593Smuzhiyun
1868*4882a593Smuzhiyun cwsx = pSib->origin.x;
1869*4882a593Smuzhiyun cwsy = pSib->origin.y;
1870*4882a593Smuzhiyun GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
1871*4882a593Smuzhiyun pSib->winGravity, &cwsx, &cwsy);
1872*4882a593Smuzhiyun if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) {
1873*4882a593Smuzhiyun xEvent event = {
1874*4882a593Smuzhiyun .u.gravity.window = pSib->drawable.id,
1875*4882a593Smuzhiyun .u.gravity.x = cwsx - wBorderWidth(pSib),
1876*4882a593Smuzhiyun .u.gravity.y = cwsy - wBorderWidth(pSib)
1877*4882a593Smuzhiyun };
1878*4882a593Smuzhiyun event.u.u.type = GravityNotify;
1879*4882a593Smuzhiyun DeliverEvents(pSib, &event, 1, NullWindow);
1880*4882a593Smuzhiyun pSib->origin.x = cwsx;
1881*4882a593Smuzhiyun pSib->origin.y = cwsy;
1882*4882a593Smuzhiyun }
1883*4882a593Smuzhiyun }
1884*4882a593Smuzhiyun pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
1885*4882a593Smuzhiyun pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
1886*4882a593Smuzhiyun SetWinSize(pSib);
1887*4882a593Smuzhiyun SetBorderSize(pSib);
1888*4882a593Smuzhiyun (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y);
1889*4882a593Smuzhiyun
1890*4882a593Smuzhiyun if ((pChild = pSib->firstChild)) {
1891*4882a593Smuzhiyun while (1) {
1892*4882a593Smuzhiyun pChild->drawable.x = pChild->parent->drawable.x +
1893*4882a593Smuzhiyun pChild->origin.x;
1894*4882a593Smuzhiyun pChild->drawable.y = pChild->parent->drawable.y +
1895*4882a593Smuzhiyun pChild->origin.y;
1896*4882a593Smuzhiyun SetWinSize(pChild);
1897*4882a593Smuzhiyun SetBorderSize(pChild);
1898*4882a593Smuzhiyun (*pScreen->PositionWindow) (pChild,
1899*4882a593Smuzhiyun pChild->drawable.x,
1900*4882a593Smuzhiyun pChild->drawable.y);
1901*4882a593Smuzhiyun if (pChild->firstChild) {
1902*4882a593Smuzhiyun pChild = pChild->firstChild;
1903*4882a593Smuzhiyun continue;
1904*4882a593Smuzhiyun }
1905*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pSib))
1906*4882a593Smuzhiyun pChild = pChild->parent;
1907*4882a593Smuzhiyun if (pChild == pSib)
1908*4882a593Smuzhiyun break;
1909*4882a593Smuzhiyun pChild = pChild->nextSib;
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun }
1912*4882a593Smuzhiyun }
1913*4882a593Smuzhiyun }
1914*4882a593Smuzhiyun
1915*4882a593Smuzhiyun #define GET_INT16(m, f) \
1916*4882a593Smuzhiyun if (m & mask) \
1917*4882a593Smuzhiyun { \
1918*4882a593Smuzhiyun f = (INT16) *pVlist;\
1919*4882a593Smuzhiyun pVlist++; \
1920*4882a593Smuzhiyun }
1921*4882a593Smuzhiyun #define GET_CARD16(m, f) \
1922*4882a593Smuzhiyun if (m & mask) \
1923*4882a593Smuzhiyun { \
1924*4882a593Smuzhiyun f = (CARD16) *pVlist;\
1925*4882a593Smuzhiyun pVlist++;\
1926*4882a593Smuzhiyun }
1927*4882a593Smuzhiyun
1928*4882a593Smuzhiyun #define GET_CARD8(m, f) \
1929*4882a593Smuzhiyun if (m & mask) \
1930*4882a593Smuzhiyun { \
1931*4882a593Smuzhiyun f = (CARD8) *pVlist;\
1932*4882a593Smuzhiyun pVlist++;\
1933*4882a593Smuzhiyun }
1934*4882a593Smuzhiyun
1935*4882a593Smuzhiyun #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
1936*4882a593Smuzhiyun
1937*4882a593Smuzhiyun /*
1938*4882a593Smuzhiyun * IsSiblingAboveMe
1939*4882a593Smuzhiyun * returns Above if pSib above pMe in stack or Below otherwise
1940*4882a593Smuzhiyun */
1941*4882a593Smuzhiyun
1942*4882a593Smuzhiyun static int
IsSiblingAboveMe(WindowPtr pMe,WindowPtr pSib)1943*4882a593Smuzhiyun IsSiblingAboveMe(WindowPtr pMe, WindowPtr pSib)
1944*4882a593Smuzhiyun {
1945*4882a593Smuzhiyun WindowPtr pWin;
1946*4882a593Smuzhiyun
1947*4882a593Smuzhiyun pWin = pMe->parent->firstChild;
1948*4882a593Smuzhiyun while (pWin) {
1949*4882a593Smuzhiyun if (pWin == pSib)
1950*4882a593Smuzhiyun return Above;
1951*4882a593Smuzhiyun else if (pWin == pMe)
1952*4882a593Smuzhiyun return Below;
1953*4882a593Smuzhiyun pWin = pWin->nextSib;
1954*4882a593Smuzhiyun }
1955*4882a593Smuzhiyun return Below;
1956*4882a593Smuzhiyun }
1957*4882a593Smuzhiyun
1958*4882a593Smuzhiyun static BoxPtr
WindowExtents(WindowPtr pWin,BoxPtr pBox)1959*4882a593Smuzhiyun WindowExtents(WindowPtr pWin, BoxPtr pBox)
1960*4882a593Smuzhiyun {
1961*4882a593Smuzhiyun pBox->x1 = pWin->drawable.x - wBorderWidth(pWin);
1962*4882a593Smuzhiyun pBox->y1 = pWin->drawable.y - wBorderWidth(pWin);
1963*4882a593Smuzhiyun pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width
1964*4882a593Smuzhiyun + wBorderWidth(pWin);
1965*4882a593Smuzhiyun pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height
1966*4882a593Smuzhiyun + wBorderWidth(pWin);
1967*4882a593Smuzhiyun return pBox;
1968*4882a593Smuzhiyun }
1969*4882a593Smuzhiyun
1970*4882a593Smuzhiyun #define IS_SHAPED(pWin) (wBoundingShape (pWin) != NULL)
1971*4882a593Smuzhiyun
1972*4882a593Smuzhiyun static RegionPtr
MakeBoundingRegion(WindowPtr pWin,BoxPtr pBox)1973*4882a593Smuzhiyun MakeBoundingRegion(WindowPtr pWin, BoxPtr pBox)
1974*4882a593Smuzhiyun {
1975*4882a593Smuzhiyun RegionPtr pRgn = RegionCreate(pBox, 1);
1976*4882a593Smuzhiyun
1977*4882a593Smuzhiyun if (wBoundingShape(pWin)) {
1978*4882a593Smuzhiyun RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y);
1979*4882a593Smuzhiyun RegionIntersect(pRgn, pRgn, wBoundingShape(pWin));
1980*4882a593Smuzhiyun RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y);
1981*4882a593Smuzhiyun }
1982*4882a593Smuzhiyun return pRgn;
1983*4882a593Smuzhiyun }
1984*4882a593Smuzhiyun
1985*4882a593Smuzhiyun static Bool
ShapeOverlap(WindowPtr pWin,BoxPtr pWinBox,WindowPtr pSib,BoxPtr pSibBox)1986*4882a593Smuzhiyun ShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox)
1987*4882a593Smuzhiyun {
1988*4882a593Smuzhiyun RegionPtr pWinRgn, pSibRgn;
1989*4882a593Smuzhiyun Bool ret;
1990*4882a593Smuzhiyun
1991*4882a593Smuzhiyun if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
1992*4882a593Smuzhiyun return TRUE;
1993*4882a593Smuzhiyun pWinRgn = MakeBoundingRegion(pWin, pWinBox);
1994*4882a593Smuzhiyun pSibRgn = MakeBoundingRegion(pSib, pSibBox);
1995*4882a593Smuzhiyun RegionIntersect(pWinRgn, pWinRgn, pSibRgn);
1996*4882a593Smuzhiyun ret = RegionNotEmpty(pWinRgn);
1997*4882a593Smuzhiyun RegionDestroy(pWinRgn);
1998*4882a593Smuzhiyun RegionDestroy(pSibRgn);
1999*4882a593Smuzhiyun return ret;
2000*4882a593Smuzhiyun }
2001*4882a593Smuzhiyun
2002*4882a593Smuzhiyun static Bool
AnyWindowOverlapsMe(WindowPtr pWin,WindowPtr pHead,BoxPtr box)2003*4882a593Smuzhiyun AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box)
2004*4882a593Smuzhiyun {
2005*4882a593Smuzhiyun WindowPtr pSib;
2006*4882a593Smuzhiyun BoxRec sboxrec;
2007*4882a593Smuzhiyun BoxPtr sbox;
2008*4882a593Smuzhiyun
2009*4882a593Smuzhiyun for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) {
2010*4882a593Smuzhiyun if (pSib->mapped) {
2011*4882a593Smuzhiyun sbox = WindowExtents(pSib, &sboxrec);
2012*4882a593Smuzhiyun if (BOXES_OVERLAP(sbox, box)
2013*4882a593Smuzhiyun && ShapeOverlap(pWin, box, pSib, sbox))
2014*4882a593Smuzhiyun return TRUE;
2015*4882a593Smuzhiyun }
2016*4882a593Smuzhiyun }
2017*4882a593Smuzhiyun return FALSE;
2018*4882a593Smuzhiyun }
2019*4882a593Smuzhiyun
2020*4882a593Smuzhiyun static Bool
IOverlapAnyWindow(WindowPtr pWin,BoxPtr box)2021*4882a593Smuzhiyun IOverlapAnyWindow(WindowPtr pWin, BoxPtr box)
2022*4882a593Smuzhiyun {
2023*4882a593Smuzhiyun WindowPtr pSib;
2024*4882a593Smuzhiyun BoxRec sboxrec;
2025*4882a593Smuzhiyun BoxPtr sbox;
2026*4882a593Smuzhiyun
2027*4882a593Smuzhiyun for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) {
2028*4882a593Smuzhiyun if (pSib->mapped) {
2029*4882a593Smuzhiyun sbox = WindowExtents(pSib, &sboxrec);
2030*4882a593Smuzhiyun if (BOXES_OVERLAP(sbox, box)
2031*4882a593Smuzhiyun && ShapeOverlap(pWin, box, pSib, sbox))
2032*4882a593Smuzhiyun return TRUE;
2033*4882a593Smuzhiyun }
2034*4882a593Smuzhiyun }
2035*4882a593Smuzhiyun return FALSE;
2036*4882a593Smuzhiyun }
2037*4882a593Smuzhiyun
2038*4882a593Smuzhiyun /*
2039*4882a593Smuzhiyun * WhereDoIGoInTheStack()
2040*4882a593Smuzhiyun * Given pWin and pSib and the relationshipe smode, return
2041*4882a593Smuzhiyun * the window that pWin should go ABOVE.
2042*4882a593Smuzhiyun * If a pSib is specified:
2043*4882a593Smuzhiyun * Above: pWin is placed just above pSib
2044*4882a593Smuzhiyun * Below: pWin is placed just below pSib
2045*4882a593Smuzhiyun * TopIf: if pSib occludes pWin, then pWin is placed
2046*4882a593Smuzhiyun * at the top of the stack
2047*4882a593Smuzhiyun * BottomIf: if pWin occludes pSib, then pWin is
2048*4882a593Smuzhiyun * placed at the bottom of the stack
2049*4882a593Smuzhiyun * Opposite: if pSib occludes pWin, then pWin is placed at the
2050*4882a593Smuzhiyun * top of the stack, else if pWin occludes pSib, then
2051*4882a593Smuzhiyun * pWin is placed at the bottom of the stack
2052*4882a593Smuzhiyun *
2053*4882a593Smuzhiyun * If pSib is NULL:
2054*4882a593Smuzhiyun * Above: pWin is placed at the top of the stack
2055*4882a593Smuzhiyun * Below: pWin is placed at the bottom of the stack
2056*4882a593Smuzhiyun * TopIf: if any sibling occludes pWin, then pWin is placed at
2057*4882a593Smuzhiyun * the top of the stack
2058*4882a593Smuzhiyun * BottomIf: if pWin occludes any sibline, then pWin is placed at
2059*4882a593Smuzhiyun * the bottom of the stack
2060*4882a593Smuzhiyun * Opposite: if any sibling occludes pWin, then pWin is placed at
2061*4882a593Smuzhiyun * the top of the stack, else if pWin occludes any
2062*4882a593Smuzhiyun * sibling, then pWin is placed at the bottom of the stack
2063*4882a593Smuzhiyun *
2064*4882a593Smuzhiyun */
2065*4882a593Smuzhiyun
2066*4882a593Smuzhiyun static WindowPtr
WhereDoIGoInTheStack(WindowPtr pWin,WindowPtr pSib,short x,short y,unsigned short w,unsigned short h,int smode)2067*4882a593Smuzhiyun WhereDoIGoInTheStack(WindowPtr pWin,
2068*4882a593Smuzhiyun WindowPtr pSib,
2069*4882a593Smuzhiyun short x,
2070*4882a593Smuzhiyun short y, unsigned short w, unsigned short h, int smode)
2071*4882a593Smuzhiyun {
2072*4882a593Smuzhiyun BoxRec box;
2073*4882a593Smuzhiyun WindowPtr pHead, pFirst;
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild))
2076*4882a593Smuzhiyun return NULL;
2077*4882a593Smuzhiyun pHead = RealChildHead(pWin->parent);
2078*4882a593Smuzhiyun pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
2079*4882a593Smuzhiyun box.x1 = x;
2080*4882a593Smuzhiyun box.y1 = y;
2081*4882a593Smuzhiyun box.x2 = x + (int) w;
2082*4882a593Smuzhiyun box.y2 = y + (int) h;
2083*4882a593Smuzhiyun switch (smode) {
2084*4882a593Smuzhiyun case Above:
2085*4882a593Smuzhiyun if (pSib)
2086*4882a593Smuzhiyun return pSib;
2087*4882a593Smuzhiyun else if (pWin == pFirst)
2088*4882a593Smuzhiyun return pWin->nextSib;
2089*4882a593Smuzhiyun else
2090*4882a593Smuzhiyun return pFirst;
2091*4882a593Smuzhiyun case Below:
2092*4882a593Smuzhiyun if (pSib)
2093*4882a593Smuzhiyun if (pSib->nextSib != pWin)
2094*4882a593Smuzhiyun return pSib->nextSib;
2095*4882a593Smuzhiyun else
2096*4882a593Smuzhiyun return pWin->nextSib;
2097*4882a593Smuzhiyun else
2098*4882a593Smuzhiyun return NullWindow;
2099*4882a593Smuzhiyun case TopIf:
2100*4882a593Smuzhiyun if ((!pWin->mapped || (pSib && !pSib->mapped)))
2101*4882a593Smuzhiyun return pWin->nextSib;
2102*4882a593Smuzhiyun else if (pSib) {
2103*4882a593Smuzhiyun if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
2104*4882a593Smuzhiyun (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
2105*4882a593Smuzhiyun return pFirst;
2106*4882a593Smuzhiyun else
2107*4882a593Smuzhiyun return pWin->nextSib;
2108*4882a593Smuzhiyun }
2109*4882a593Smuzhiyun else if (AnyWindowOverlapsMe(pWin, pHead, &box))
2110*4882a593Smuzhiyun return pFirst;
2111*4882a593Smuzhiyun else
2112*4882a593Smuzhiyun return pWin->nextSib;
2113*4882a593Smuzhiyun case BottomIf:
2114*4882a593Smuzhiyun if ((!pWin->mapped || (pSib && !pSib->mapped)))
2115*4882a593Smuzhiyun return pWin->nextSib;
2116*4882a593Smuzhiyun else if (pSib) {
2117*4882a593Smuzhiyun if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
2118*4882a593Smuzhiyun (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
2119*4882a593Smuzhiyun return NullWindow;
2120*4882a593Smuzhiyun else
2121*4882a593Smuzhiyun return pWin->nextSib;
2122*4882a593Smuzhiyun }
2123*4882a593Smuzhiyun else if (IOverlapAnyWindow(pWin, &box))
2124*4882a593Smuzhiyun return NullWindow;
2125*4882a593Smuzhiyun else
2126*4882a593Smuzhiyun return pWin->nextSib;
2127*4882a593Smuzhiyun case Opposite:
2128*4882a593Smuzhiyun if ((!pWin->mapped || (pSib && !pSib->mapped)))
2129*4882a593Smuzhiyun return pWin->nextSib;
2130*4882a593Smuzhiyun else if (pSib) {
2131*4882a593Smuzhiyun if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) {
2132*4882a593Smuzhiyun if (IsSiblingAboveMe(pWin, pSib) == Above)
2133*4882a593Smuzhiyun return pFirst;
2134*4882a593Smuzhiyun else
2135*4882a593Smuzhiyun return NullWindow;
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun else
2138*4882a593Smuzhiyun return pWin->nextSib;
2139*4882a593Smuzhiyun }
2140*4882a593Smuzhiyun else if (AnyWindowOverlapsMe(pWin, pHead, &box)) {
2141*4882a593Smuzhiyun /* If I'm occluded, I can't possibly be the first child
2142*4882a593Smuzhiyun * if (pWin == pWin->parent->firstChild)
2143*4882a593Smuzhiyun * return pWin->nextSib;
2144*4882a593Smuzhiyun */
2145*4882a593Smuzhiyun return pFirst;
2146*4882a593Smuzhiyun }
2147*4882a593Smuzhiyun else if (IOverlapAnyWindow(pWin, &box))
2148*4882a593Smuzhiyun return NullWindow;
2149*4882a593Smuzhiyun else
2150*4882a593Smuzhiyun return pWin->nextSib;
2151*4882a593Smuzhiyun default:
2152*4882a593Smuzhiyun {
2153*4882a593Smuzhiyun /* should never happen; make something up. */
2154*4882a593Smuzhiyun return pWin->nextSib;
2155*4882a593Smuzhiyun }
2156*4882a593Smuzhiyun }
2157*4882a593Smuzhiyun }
2158*4882a593Smuzhiyun
2159*4882a593Smuzhiyun static void
ReflectStackChange(WindowPtr pWin,WindowPtr pSib,VTKind kind)2160*4882a593Smuzhiyun ReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind)
2161*4882a593Smuzhiyun {
2162*4882a593Smuzhiyun /* Note that pSib might be NULL */
2163*4882a593Smuzhiyun
2164*4882a593Smuzhiyun Bool WasViewable = (Bool) pWin->viewable;
2165*4882a593Smuzhiyun Bool anyMarked;
2166*4882a593Smuzhiyun WindowPtr pFirstChange;
2167*4882a593Smuzhiyun WindowPtr pLayerWin;
2168*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
2169*4882a593Smuzhiyun
2170*4882a593Smuzhiyun /* if this is a root window, can't be restacked */
2171*4882a593Smuzhiyun if (!pWin->parent)
2172*4882a593Smuzhiyun return;
2173*4882a593Smuzhiyun
2174*4882a593Smuzhiyun pFirstChange = MoveWindowInStack(pWin, pSib);
2175*4882a593Smuzhiyun
2176*4882a593Smuzhiyun if (WasViewable) {
2177*4882a593Smuzhiyun anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange,
2178*4882a593Smuzhiyun &pLayerWin);
2179*4882a593Smuzhiyun if (pLayerWin != pWin)
2180*4882a593Smuzhiyun pFirstChange = pLayerWin;
2181*4882a593Smuzhiyun if (anyMarked) {
2182*4882a593Smuzhiyun (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind);
2183*4882a593Smuzhiyun (*pScreen->HandleExposures) (pLayerWin->parent);
2184*4882a593Smuzhiyun if (pWin->drawable.pScreen->PostValidateTree)
2185*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange,
2186*4882a593Smuzhiyun kind);
2187*4882a593Smuzhiyun }
2188*4882a593Smuzhiyun }
2189*4882a593Smuzhiyun if (pWin->realized)
2190*4882a593Smuzhiyun WindowsRestructured();
2191*4882a593Smuzhiyun }
2192*4882a593Smuzhiyun
2193*4882a593Smuzhiyun /*****
2194*4882a593Smuzhiyun * ConfigureWindow
2195*4882a593Smuzhiyun *****/
2196*4882a593Smuzhiyun
2197*4882a593Smuzhiyun int
ConfigureWindow(WindowPtr pWin,Mask mask,XID * vlist,ClientPtr client)2198*4882a593Smuzhiyun ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
2199*4882a593Smuzhiyun {
2200*4882a593Smuzhiyun #define RESTACK_WIN 0
2201*4882a593Smuzhiyun #define MOVE_WIN 1
2202*4882a593Smuzhiyun #define RESIZE_WIN 2
2203*4882a593Smuzhiyun #define REBORDER_WIN 3
2204*4882a593Smuzhiyun WindowPtr pSib = NullWindow;
2205*4882a593Smuzhiyun WindowPtr pParent = pWin->parent;
2206*4882a593Smuzhiyun Window sibwid = 0;
2207*4882a593Smuzhiyun Mask index2, tmask;
2208*4882a593Smuzhiyun XID *pVlist;
2209*4882a593Smuzhiyun short x, y, beforeX, beforeY;
2210*4882a593Smuzhiyun unsigned short w = pWin->drawable.width,
2211*4882a593Smuzhiyun h = pWin->drawable.height, bw = pWin->borderWidth;
2212*4882a593Smuzhiyun int rc, action, smode = Above;
2213*4882a593Smuzhiyun
2214*4882a593Smuzhiyun if ((pWin->drawable.class == InputOnly) && (mask & CWBorderWidth))
2215*4882a593Smuzhiyun return BadMatch;
2216*4882a593Smuzhiyun
2217*4882a593Smuzhiyun if ((mask & CWSibling) && !(mask & CWStackMode))
2218*4882a593Smuzhiyun return BadMatch;
2219*4882a593Smuzhiyun
2220*4882a593Smuzhiyun pVlist = vlist;
2221*4882a593Smuzhiyun
2222*4882a593Smuzhiyun if (pParent) {
2223*4882a593Smuzhiyun x = pWin->drawable.x - pParent->drawable.x - (int) bw;
2224*4882a593Smuzhiyun y = pWin->drawable.y - pParent->drawable.y - (int) bw;
2225*4882a593Smuzhiyun }
2226*4882a593Smuzhiyun else {
2227*4882a593Smuzhiyun x = pWin->drawable.x;
2228*4882a593Smuzhiyun y = pWin->drawable.y;
2229*4882a593Smuzhiyun }
2230*4882a593Smuzhiyun beforeX = x;
2231*4882a593Smuzhiyun beforeY = y;
2232*4882a593Smuzhiyun action = RESTACK_WIN;
2233*4882a593Smuzhiyun if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) {
2234*4882a593Smuzhiyun GET_INT16(CWX, x);
2235*4882a593Smuzhiyun GET_INT16(CWY, y);
2236*4882a593Smuzhiyun action = MOVE_WIN;
2237*4882a593Smuzhiyun }
2238*4882a593Smuzhiyun /* or should be resized */
2239*4882a593Smuzhiyun else if (mask & (CWX | CWY | CWWidth | CWHeight)) {
2240*4882a593Smuzhiyun GET_INT16(CWX, x);
2241*4882a593Smuzhiyun GET_INT16(CWY, y);
2242*4882a593Smuzhiyun GET_CARD16(CWWidth, w);
2243*4882a593Smuzhiyun GET_CARD16(CWHeight, h);
2244*4882a593Smuzhiyun if (!w || !h) {
2245*4882a593Smuzhiyun client->errorValue = 0;
2246*4882a593Smuzhiyun return BadValue;
2247*4882a593Smuzhiyun }
2248*4882a593Smuzhiyun action = RESIZE_WIN;
2249*4882a593Smuzhiyun }
2250*4882a593Smuzhiyun tmask = mask & ~ChangeMask;
2251*4882a593Smuzhiyun while (tmask) {
2252*4882a593Smuzhiyun index2 = (Mask) lowbit(tmask);
2253*4882a593Smuzhiyun tmask &= ~index2;
2254*4882a593Smuzhiyun switch (index2) {
2255*4882a593Smuzhiyun case CWBorderWidth:
2256*4882a593Smuzhiyun GET_CARD16(CWBorderWidth, bw);
2257*4882a593Smuzhiyun break;
2258*4882a593Smuzhiyun case CWSibling:
2259*4882a593Smuzhiyun sibwid = (Window) *pVlist;
2260*4882a593Smuzhiyun pVlist++;
2261*4882a593Smuzhiyun rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess);
2262*4882a593Smuzhiyun if (rc != Success) {
2263*4882a593Smuzhiyun client->errorValue = sibwid;
2264*4882a593Smuzhiyun return rc;
2265*4882a593Smuzhiyun }
2266*4882a593Smuzhiyun if (pSib->parent != pParent)
2267*4882a593Smuzhiyun return BadMatch;
2268*4882a593Smuzhiyun if (pSib == pWin)
2269*4882a593Smuzhiyun return BadMatch;
2270*4882a593Smuzhiyun break;
2271*4882a593Smuzhiyun case CWStackMode:
2272*4882a593Smuzhiyun GET_CARD8(CWStackMode, smode);
2273*4882a593Smuzhiyun if ((smode != TopIf) && (smode != BottomIf) &&
2274*4882a593Smuzhiyun (smode != Opposite) && (smode != Above) && (smode != Below)) {
2275*4882a593Smuzhiyun client->errorValue = smode;
2276*4882a593Smuzhiyun return BadValue;
2277*4882a593Smuzhiyun }
2278*4882a593Smuzhiyun break;
2279*4882a593Smuzhiyun default:
2280*4882a593Smuzhiyun client->errorValue = mask;
2281*4882a593Smuzhiyun return BadValue;
2282*4882a593Smuzhiyun }
2283*4882a593Smuzhiyun }
2284*4882a593Smuzhiyun /* root really can't be reconfigured, so just return */
2285*4882a593Smuzhiyun if (!pParent)
2286*4882a593Smuzhiyun return Success;
2287*4882a593Smuzhiyun
2288*4882a593Smuzhiyun /* Figure out if the window should be moved. Doesnt
2289*4882a593Smuzhiyun make the changes to the window if event sent */
2290*4882a593Smuzhiyun
2291*4882a593Smuzhiyun if (mask & CWStackMode)
2292*4882a593Smuzhiyun pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
2293*4882a593Smuzhiyun pParent->drawable.y + y,
2294*4882a593Smuzhiyun w + (bw << 1), h + (bw << 1), smode);
2295*4882a593Smuzhiyun else
2296*4882a593Smuzhiyun pSib = pWin->nextSib;
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) {
2299*4882a593Smuzhiyun xEvent event = {
2300*4882a593Smuzhiyun .u.configureRequest.window = pWin->drawable.id,
2301*4882a593Smuzhiyun .u.configureRequest.sibling = (mask & CWSibling) ? sibwid : None,
2302*4882a593Smuzhiyun .u.configureRequest.x = x,
2303*4882a593Smuzhiyun .u.configureRequest.y = y,
2304*4882a593Smuzhiyun .u.configureRequest.width = w,
2305*4882a593Smuzhiyun .u.configureRequest.height = h,
2306*4882a593Smuzhiyun .u.configureRequest.borderWidth = bw,
2307*4882a593Smuzhiyun .u.configureRequest.valueMask = mask,
2308*4882a593Smuzhiyun .u.configureRequest.parent = pParent->drawable.id
2309*4882a593Smuzhiyun };
2310*4882a593Smuzhiyun event.u.u.type = ConfigureRequest;
2311*4882a593Smuzhiyun event.u.u.detail = (mask & CWStackMode) ? smode : Above;
2312*4882a593Smuzhiyun #ifdef PANORAMIX
2313*4882a593Smuzhiyun if (!noPanoramiXExtension && (!pParent || !pParent->parent)) {
2314*4882a593Smuzhiyun event.u.configureRequest.x += screenInfo.screens[0]->x;
2315*4882a593Smuzhiyun event.u.configureRequest.y += screenInfo.screens[0]->y;
2316*4882a593Smuzhiyun }
2317*4882a593Smuzhiyun #endif
2318*4882a593Smuzhiyun if (MaybeDeliverEventsToClient(pParent, &event, 1,
2319*4882a593Smuzhiyun SubstructureRedirectMask, client) == 1)
2320*4882a593Smuzhiyun return Success;
2321*4882a593Smuzhiyun }
2322*4882a593Smuzhiyun if (action == RESIZE_WIN) {
2323*4882a593Smuzhiyun Bool size_change = (w != pWin->drawable.width)
2324*4882a593Smuzhiyun || (h != pWin->drawable.height);
2325*4882a593Smuzhiyun
2326*4882a593Smuzhiyun if (size_change &&
2327*4882a593Smuzhiyun ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) {
2328*4882a593Smuzhiyun xEvent eventT = {
2329*4882a593Smuzhiyun .u.resizeRequest.window = pWin->drawable.id,
2330*4882a593Smuzhiyun .u.resizeRequest.width = w,
2331*4882a593Smuzhiyun .u.resizeRequest.height = h
2332*4882a593Smuzhiyun };
2333*4882a593Smuzhiyun eventT.u.u.type = ResizeRequest;
2334*4882a593Smuzhiyun if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
2335*4882a593Smuzhiyun ResizeRedirectMask, client) == 1) {
2336*4882a593Smuzhiyun /* if event is delivered, leave the actual size alone. */
2337*4882a593Smuzhiyun w = pWin->drawable.width;
2338*4882a593Smuzhiyun h = pWin->drawable.height;
2339*4882a593Smuzhiyun size_change = FALSE;
2340*4882a593Smuzhiyun }
2341*4882a593Smuzhiyun }
2342*4882a593Smuzhiyun if (!size_change) {
2343*4882a593Smuzhiyun if (mask & (CWX | CWY))
2344*4882a593Smuzhiyun action = MOVE_WIN;
2345*4882a593Smuzhiyun else if (mask & (CWStackMode | CWBorderWidth))
2346*4882a593Smuzhiyun action = RESTACK_WIN;
2347*4882a593Smuzhiyun else /* really nothing to do */
2348*4882a593Smuzhiyun return (Success);
2349*4882a593Smuzhiyun }
2350*4882a593Smuzhiyun }
2351*4882a593Smuzhiyun
2352*4882a593Smuzhiyun if (action == RESIZE_WIN)
2353*4882a593Smuzhiyun /* we've already checked whether there's really a size change */
2354*4882a593Smuzhiyun goto ActuallyDoSomething;
2355*4882a593Smuzhiyun if ((mask & CWX) && (x != beforeX))
2356*4882a593Smuzhiyun goto ActuallyDoSomething;
2357*4882a593Smuzhiyun if ((mask & CWY) && (y != beforeY))
2358*4882a593Smuzhiyun goto ActuallyDoSomething;
2359*4882a593Smuzhiyun if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin)))
2360*4882a593Smuzhiyun goto ActuallyDoSomething;
2361*4882a593Smuzhiyun if (mask & CWStackMode) {
2362*4882a593Smuzhiyun #ifndef ROOTLESS
2363*4882a593Smuzhiyun /* See above for why we always reorder in rootless mode. */
2364*4882a593Smuzhiyun if (pWin->nextSib != pSib)
2365*4882a593Smuzhiyun #endif
2366*4882a593Smuzhiyun goto ActuallyDoSomething;
2367*4882a593Smuzhiyun }
2368*4882a593Smuzhiyun return Success;
2369*4882a593Smuzhiyun
2370*4882a593Smuzhiyun ActuallyDoSomething:
2371*4882a593Smuzhiyun if (pWin->drawable.pScreen->ConfigNotify) {
2372*4882a593Smuzhiyun int ret;
2373*4882a593Smuzhiyun
2374*4882a593Smuzhiyun ret =
2375*4882a593Smuzhiyun (*pWin->drawable.pScreen->ConfigNotify) (pWin, x, y, w, h, bw,
2376*4882a593Smuzhiyun pSib);
2377*4882a593Smuzhiyun if (ret) {
2378*4882a593Smuzhiyun client->errorValue = 0;
2379*4882a593Smuzhiyun return ret;
2380*4882a593Smuzhiyun }
2381*4882a593Smuzhiyun }
2382*4882a593Smuzhiyun
2383*4882a593Smuzhiyun if (SubStrSend(pWin, pParent)) {
2384*4882a593Smuzhiyun xEvent event = {
2385*4882a593Smuzhiyun .u.configureNotify.window = pWin->drawable.id,
2386*4882a593Smuzhiyun .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None,
2387*4882a593Smuzhiyun .u.configureNotify.x = x,
2388*4882a593Smuzhiyun .u.configureNotify.y = y,
2389*4882a593Smuzhiyun .u.configureNotify.width = w,
2390*4882a593Smuzhiyun .u.configureNotify.height = h,
2391*4882a593Smuzhiyun .u.configureNotify.borderWidth = bw,
2392*4882a593Smuzhiyun .u.configureNotify.override = pWin->overrideRedirect
2393*4882a593Smuzhiyun };
2394*4882a593Smuzhiyun event.u.u.type = ConfigureNotify;
2395*4882a593Smuzhiyun #ifdef PANORAMIX
2396*4882a593Smuzhiyun if (!noPanoramiXExtension && (!pParent || !pParent->parent)) {
2397*4882a593Smuzhiyun event.u.configureNotify.x += screenInfo.screens[0]->x;
2398*4882a593Smuzhiyun event.u.configureNotify.y += screenInfo.screens[0]->y;
2399*4882a593Smuzhiyun }
2400*4882a593Smuzhiyun #endif
2401*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
2402*4882a593Smuzhiyun }
2403*4882a593Smuzhiyun if (mask & CWBorderWidth) {
2404*4882a593Smuzhiyun if (action == RESTACK_WIN) {
2405*4882a593Smuzhiyun action = MOVE_WIN;
2406*4882a593Smuzhiyun pWin->borderWidth = bw;
2407*4882a593Smuzhiyun }
2408*4882a593Smuzhiyun else if ((action == MOVE_WIN) &&
2409*4882a593Smuzhiyun (beforeX + wBorderWidth(pWin) == x + (int) bw) &&
2410*4882a593Smuzhiyun (beforeY + wBorderWidth(pWin) == y + (int) bw)) {
2411*4882a593Smuzhiyun action = REBORDER_WIN;
2412*4882a593Smuzhiyun (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw);
2413*4882a593Smuzhiyun }
2414*4882a593Smuzhiyun else
2415*4882a593Smuzhiyun pWin->borderWidth = bw;
2416*4882a593Smuzhiyun }
2417*4882a593Smuzhiyun if (action == MOVE_WIN)
2418*4882a593Smuzhiyun (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib,
2419*4882a593Smuzhiyun (mask & CWBorderWidth) ? VTOther
2420*4882a593Smuzhiyun : VTMove);
2421*4882a593Smuzhiyun else if (action == RESIZE_WIN)
2422*4882a593Smuzhiyun (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
2423*4882a593Smuzhiyun else if (mask & CWStackMode)
2424*4882a593Smuzhiyun ReflectStackChange(pWin, pSib, VTOther);
2425*4882a593Smuzhiyun
2426*4882a593Smuzhiyun if (action != RESTACK_WIN)
2427*4882a593Smuzhiyun CheckCursorConfinement(pWin);
2428*4882a593Smuzhiyun return Success;
2429*4882a593Smuzhiyun #undef RESTACK_WIN
2430*4882a593Smuzhiyun #undef MOVE_WIN
2431*4882a593Smuzhiyun #undef RESIZE_WIN
2432*4882a593Smuzhiyun #undef REBORDER_WIN
2433*4882a593Smuzhiyun }
2434*4882a593Smuzhiyun
2435*4882a593Smuzhiyun /******
2436*4882a593Smuzhiyun *
2437*4882a593Smuzhiyun * CirculateWindow
2438*4882a593Smuzhiyun * For RaiseLowest, raises the lowest mapped child (if any) that is
2439*4882a593Smuzhiyun * obscured by another child to the top of the stack. For LowerHighest,
2440*4882a593Smuzhiyun * lowers the highest mapped child (if any) that is obscuring another
2441*4882a593Smuzhiyun * child to the bottom of the stack. Exposure processing is performed
2442*4882a593Smuzhiyun *
2443*4882a593Smuzhiyun ******/
2444*4882a593Smuzhiyun
2445*4882a593Smuzhiyun int
CirculateWindow(WindowPtr pParent,int direction,ClientPtr client)2446*4882a593Smuzhiyun CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
2447*4882a593Smuzhiyun {
2448*4882a593Smuzhiyun WindowPtr pWin, pHead, pFirst;
2449*4882a593Smuzhiyun xEvent event;
2450*4882a593Smuzhiyun BoxRec box;
2451*4882a593Smuzhiyun
2452*4882a593Smuzhiyun pHead = RealChildHead(pParent);
2453*4882a593Smuzhiyun pFirst = pHead ? pHead->nextSib : pParent->firstChild;
2454*4882a593Smuzhiyun if (direction == RaiseLowest) {
2455*4882a593Smuzhiyun for (pWin = pParent->lastChild;
2456*4882a593Smuzhiyun (pWin != pHead) &&
2457*4882a593Smuzhiyun !(pWin->mapped &&
2458*4882a593Smuzhiyun AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
2459*4882a593Smuzhiyun pWin = pWin->prevSib);
2460*4882a593Smuzhiyun if (pWin == pHead)
2461*4882a593Smuzhiyun return Success;
2462*4882a593Smuzhiyun }
2463*4882a593Smuzhiyun else {
2464*4882a593Smuzhiyun for (pWin = pFirst;
2465*4882a593Smuzhiyun pWin &&
2466*4882a593Smuzhiyun !(pWin->mapped &&
2467*4882a593Smuzhiyun IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
2468*4882a593Smuzhiyun pWin = pWin->nextSib);
2469*4882a593Smuzhiyun if (!pWin)
2470*4882a593Smuzhiyun return Success;
2471*4882a593Smuzhiyun }
2472*4882a593Smuzhiyun
2473*4882a593Smuzhiyun event = (xEvent) {
2474*4882a593Smuzhiyun .u.circulate.window = pWin->drawable.id,
2475*4882a593Smuzhiyun .u.circulate.parent = pParent->drawable.id,
2476*4882a593Smuzhiyun .u.circulate.event = pParent->drawable.id,
2477*4882a593Smuzhiyun .u.circulate.place = (direction == RaiseLowest) ?
2478*4882a593Smuzhiyun PlaceOnTop : PlaceOnBottom,
2479*4882a593Smuzhiyun };
2480*4882a593Smuzhiyun
2481*4882a593Smuzhiyun if (RedirectSend(pParent)) {
2482*4882a593Smuzhiyun event.u.u.type = CirculateRequest;
2483*4882a593Smuzhiyun if (MaybeDeliverEventsToClient(pParent, &event, 1,
2484*4882a593Smuzhiyun SubstructureRedirectMask, client) == 1)
2485*4882a593Smuzhiyun return Success;
2486*4882a593Smuzhiyun }
2487*4882a593Smuzhiyun
2488*4882a593Smuzhiyun event.u.u.type = CirculateNotify;
2489*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
2490*4882a593Smuzhiyun ReflectStackChange(pWin,
2491*4882a593Smuzhiyun (direction == RaiseLowest) ? pFirst : NullWindow,
2492*4882a593Smuzhiyun VTStack);
2493*4882a593Smuzhiyun
2494*4882a593Smuzhiyun return Success;
2495*4882a593Smuzhiyun }
2496*4882a593Smuzhiyun
2497*4882a593Smuzhiyun static int
CompareWIDs(WindowPtr pWin,void * value)2498*4882a593Smuzhiyun CompareWIDs(WindowPtr pWin, void *value)
2499*4882a593Smuzhiyun { /* must conform to VisitWindowProcPtr */
2500*4882a593Smuzhiyun Window *wid = (Window *) value;
2501*4882a593Smuzhiyun
2502*4882a593Smuzhiyun if (pWin->drawable.id == *wid)
2503*4882a593Smuzhiyun return WT_STOPWALKING;
2504*4882a593Smuzhiyun else
2505*4882a593Smuzhiyun return WT_WALKCHILDREN;
2506*4882a593Smuzhiyun }
2507*4882a593Smuzhiyun
2508*4882a593Smuzhiyun /*****
2509*4882a593Smuzhiyun * ReparentWindow
2510*4882a593Smuzhiyun *****/
2511*4882a593Smuzhiyun
2512*4882a593Smuzhiyun int
ReparentWindow(WindowPtr pWin,WindowPtr pParent,int x,int y,ClientPtr client)2513*4882a593Smuzhiyun ReparentWindow(WindowPtr pWin, WindowPtr pParent,
2514*4882a593Smuzhiyun int x, int y, ClientPtr client)
2515*4882a593Smuzhiyun {
2516*4882a593Smuzhiyun WindowPtr pPrev, pPriorParent;
2517*4882a593Smuzhiyun Bool WasMapped = (Bool) (pWin->mapped);
2518*4882a593Smuzhiyun xEvent event;
2519*4882a593Smuzhiyun int bw = wBorderWidth(pWin);
2520*4882a593Smuzhiyun ScreenPtr pScreen;
2521*4882a593Smuzhiyun
2522*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
2523*4882a593Smuzhiyun if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) ==
2524*4882a593Smuzhiyun WT_STOPWALKING)
2525*4882a593Smuzhiyun return BadMatch;
2526*4882a593Smuzhiyun if (!MakeWindowOptional(pWin))
2527*4882a593Smuzhiyun return BadAlloc;
2528*4882a593Smuzhiyun
2529*4882a593Smuzhiyun if (WasMapped)
2530*4882a593Smuzhiyun UnmapWindow(pWin, FALSE);
2531*4882a593Smuzhiyun
2532*4882a593Smuzhiyun event = (xEvent) {
2533*4882a593Smuzhiyun .u.reparent.window = pWin->drawable.id,
2534*4882a593Smuzhiyun .u.reparent.parent = pParent->drawable.id,
2535*4882a593Smuzhiyun .u.reparent.x = x,
2536*4882a593Smuzhiyun .u.reparent.y = y,
2537*4882a593Smuzhiyun .u.reparent.override = pWin->overrideRedirect
2538*4882a593Smuzhiyun };
2539*4882a593Smuzhiyun event.u.u.type = ReparentNotify;
2540*4882a593Smuzhiyun #ifdef PANORAMIX
2541*4882a593Smuzhiyun if (!noPanoramiXExtension && !pParent->parent) {
2542*4882a593Smuzhiyun event.u.reparent.x += screenInfo.screens[0]->x;
2543*4882a593Smuzhiyun event.u.reparent.y += screenInfo.screens[0]->y;
2544*4882a593Smuzhiyun }
2545*4882a593Smuzhiyun #endif
2546*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, pParent);
2547*4882a593Smuzhiyun
2548*4882a593Smuzhiyun /* take out of sibling chain */
2549*4882a593Smuzhiyun
2550*4882a593Smuzhiyun pPriorParent = pPrev = pWin->parent;
2551*4882a593Smuzhiyun if (pPrev->firstChild == pWin)
2552*4882a593Smuzhiyun pPrev->firstChild = pWin->nextSib;
2553*4882a593Smuzhiyun if (pPrev->lastChild == pWin)
2554*4882a593Smuzhiyun pPrev->lastChild = pWin->prevSib;
2555*4882a593Smuzhiyun
2556*4882a593Smuzhiyun if (pWin->nextSib)
2557*4882a593Smuzhiyun pWin->nextSib->prevSib = pWin->prevSib;
2558*4882a593Smuzhiyun if (pWin->prevSib)
2559*4882a593Smuzhiyun pWin->prevSib->nextSib = pWin->nextSib;
2560*4882a593Smuzhiyun
2561*4882a593Smuzhiyun /* insert at begining of pParent */
2562*4882a593Smuzhiyun pWin->parent = pParent;
2563*4882a593Smuzhiyun pPrev = RealChildHead(pParent);
2564*4882a593Smuzhiyun if (pPrev) {
2565*4882a593Smuzhiyun pWin->nextSib = pPrev->nextSib;
2566*4882a593Smuzhiyun if (pPrev->nextSib)
2567*4882a593Smuzhiyun pPrev->nextSib->prevSib = pWin;
2568*4882a593Smuzhiyun else
2569*4882a593Smuzhiyun pParent->lastChild = pWin;
2570*4882a593Smuzhiyun pPrev->nextSib = pWin;
2571*4882a593Smuzhiyun pWin->prevSib = pPrev;
2572*4882a593Smuzhiyun }
2573*4882a593Smuzhiyun else {
2574*4882a593Smuzhiyun pWin->nextSib = pParent->firstChild;
2575*4882a593Smuzhiyun pWin->prevSib = NullWindow;
2576*4882a593Smuzhiyun if (pParent->firstChild)
2577*4882a593Smuzhiyun pParent->firstChild->prevSib = pWin;
2578*4882a593Smuzhiyun else
2579*4882a593Smuzhiyun pParent->lastChild = pWin;
2580*4882a593Smuzhiyun pParent->firstChild = pWin;
2581*4882a593Smuzhiyun }
2582*4882a593Smuzhiyun
2583*4882a593Smuzhiyun pWin->origin.x = x + bw;
2584*4882a593Smuzhiyun pWin->origin.y = y + bw;
2585*4882a593Smuzhiyun pWin->drawable.x = x + bw + pParent->drawable.x;
2586*4882a593Smuzhiyun pWin->drawable.y = y + bw + pParent->drawable.y;
2587*4882a593Smuzhiyun
2588*4882a593Smuzhiyun /* clip to parent */
2589*4882a593Smuzhiyun SetWinSize(pWin);
2590*4882a593Smuzhiyun SetBorderSize(pWin);
2591*4882a593Smuzhiyun
2592*4882a593Smuzhiyun if (pScreen->ReparentWindow)
2593*4882a593Smuzhiyun (*pScreen->ReparentWindow) (pWin, pPriorParent);
2594*4882a593Smuzhiyun (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
2595*4882a593Smuzhiyun ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
2596*4882a593Smuzhiyun
2597*4882a593Smuzhiyun CheckWindowOptionalNeed(pWin);
2598*4882a593Smuzhiyun
2599*4882a593Smuzhiyun if (WasMapped)
2600*4882a593Smuzhiyun MapWindow(pWin, client);
2601*4882a593Smuzhiyun RecalculateDeliverableEvents(pWin);
2602*4882a593Smuzhiyun return Success;
2603*4882a593Smuzhiyun }
2604*4882a593Smuzhiyun
2605*4882a593Smuzhiyun static void
RealizeTree(WindowPtr pWin)2606*4882a593Smuzhiyun RealizeTree(WindowPtr pWin)
2607*4882a593Smuzhiyun {
2608*4882a593Smuzhiyun WindowPtr pChild;
2609*4882a593Smuzhiyun RealizeWindowProcPtr Realize;
2610*4882a593Smuzhiyun
2611*4882a593Smuzhiyun Realize = pWin->drawable.pScreen->RealizeWindow;
2612*4882a593Smuzhiyun pChild = pWin;
2613*4882a593Smuzhiyun while (1) {
2614*4882a593Smuzhiyun if (pChild->mapped) {
2615*4882a593Smuzhiyun pChild->realized = TRUE;
2616*4882a593Smuzhiyun pChild->viewable = (pChild->drawable.class == InputOutput);
2617*4882a593Smuzhiyun (*Realize) (pChild);
2618*4882a593Smuzhiyun if (pChild->firstChild) {
2619*4882a593Smuzhiyun pChild = pChild->firstChild;
2620*4882a593Smuzhiyun continue;
2621*4882a593Smuzhiyun }
2622*4882a593Smuzhiyun }
2623*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pWin))
2624*4882a593Smuzhiyun pChild = pChild->parent;
2625*4882a593Smuzhiyun if (pChild == pWin)
2626*4882a593Smuzhiyun return;
2627*4882a593Smuzhiyun pChild = pChild->nextSib;
2628*4882a593Smuzhiyun }
2629*4882a593Smuzhiyun }
2630*4882a593Smuzhiyun
2631*4882a593Smuzhiyun static Bool
MaybeDeliverMapRequest(WindowPtr pWin,WindowPtr pParent,ClientPtr client)2632*4882a593Smuzhiyun MaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client)
2633*4882a593Smuzhiyun {
2634*4882a593Smuzhiyun xEvent event = {
2635*4882a593Smuzhiyun .u.mapRequest.window = pWin->drawable.id,
2636*4882a593Smuzhiyun .u.mapRequest.parent = pParent->drawable.id
2637*4882a593Smuzhiyun };
2638*4882a593Smuzhiyun event.u.u.type = MapRequest;
2639*4882a593Smuzhiyun
2640*4882a593Smuzhiyun return MaybeDeliverEventsToClient(pParent, &event, 1,
2641*4882a593Smuzhiyun SubstructureRedirectMask,
2642*4882a593Smuzhiyun client) == 1;
2643*4882a593Smuzhiyun }
2644*4882a593Smuzhiyun
2645*4882a593Smuzhiyun static void
DeliverMapNotify(WindowPtr pWin)2646*4882a593Smuzhiyun DeliverMapNotify(WindowPtr pWin)
2647*4882a593Smuzhiyun {
2648*4882a593Smuzhiyun xEvent event = {
2649*4882a593Smuzhiyun .u.mapNotify.window = pWin->drawable.id,
2650*4882a593Smuzhiyun .u.mapNotify.override = pWin->overrideRedirect,
2651*4882a593Smuzhiyun };
2652*4882a593Smuzhiyun event.u.u.type = MapNotify;
2653*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
2654*4882a593Smuzhiyun }
2655*4882a593Smuzhiyun
2656*4882a593Smuzhiyun /*****
2657*4882a593Smuzhiyun * MapWindow
2658*4882a593Smuzhiyun * If some other client has selected SubStructureReDirect on the parent
2659*4882a593Smuzhiyun * and override-redirect is xFalse, then a MapRequest event is generated,
2660*4882a593Smuzhiyun * but the window remains unmapped. Otherwise, the window is mapped and a
2661*4882a593Smuzhiyun * MapNotify event is generated.
2662*4882a593Smuzhiyun *****/
2663*4882a593Smuzhiyun
2664*4882a593Smuzhiyun int
MapWindow(WindowPtr pWin,ClientPtr client)2665*4882a593Smuzhiyun MapWindow(WindowPtr pWin, ClientPtr client)
2666*4882a593Smuzhiyun {
2667*4882a593Smuzhiyun ScreenPtr pScreen;
2668*4882a593Smuzhiyun
2669*4882a593Smuzhiyun WindowPtr pParent;
2670*4882a593Smuzhiyun WindowPtr pLayerWin;
2671*4882a593Smuzhiyun
2672*4882a593Smuzhiyun if (pWin->mapped)
2673*4882a593Smuzhiyun return Success;
2674*4882a593Smuzhiyun
2675*4882a593Smuzhiyun /* general check for permission to map window */
2676*4882a593Smuzhiyun if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW,
2677*4882a593Smuzhiyun pWin, RT_NONE, NULL, DixShowAccess) != Success)
2678*4882a593Smuzhiyun return Success;
2679*4882a593Smuzhiyun
2680*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
2681*4882a593Smuzhiyun if ((pParent = pWin->parent)) {
2682*4882a593Smuzhiyun Bool anyMarked;
2683*4882a593Smuzhiyun
2684*4882a593Smuzhiyun if ((!pWin->overrideRedirect) && (RedirectSend(pParent)))
2685*4882a593Smuzhiyun if (MaybeDeliverMapRequest(pWin, pParent, client))
2686*4882a593Smuzhiyun return Success;
2687*4882a593Smuzhiyun
2688*4882a593Smuzhiyun pWin->mapped = TRUE;
2689*4882a593Smuzhiyun if (SubStrSend(pWin, pParent))
2690*4882a593Smuzhiyun DeliverMapNotify(pWin);
2691*4882a593Smuzhiyun
2692*4882a593Smuzhiyun if (!pParent->realized)
2693*4882a593Smuzhiyun return Success;
2694*4882a593Smuzhiyun RealizeTree(pWin);
2695*4882a593Smuzhiyun if (pWin->viewable) {
2696*4882a593Smuzhiyun anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
2697*4882a593Smuzhiyun &pLayerWin);
2698*4882a593Smuzhiyun if (anyMarked) {
2699*4882a593Smuzhiyun (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap);
2700*4882a593Smuzhiyun (*pScreen->HandleExposures) (pLayerWin->parent);
2701*4882a593Smuzhiyun if (pScreen->PostValidateTree)
2702*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin,
2703*4882a593Smuzhiyun VTMap);
2704*4882a593Smuzhiyun }
2705*4882a593Smuzhiyun }
2706*4882a593Smuzhiyun WindowsRestructured();
2707*4882a593Smuzhiyun }
2708*4882a593Smuzhiyun else {
2709*4882a593Smuzhiyun RegionRec temp;
2710*4882a593Smuzhiyun
2711*4882a593Smuzhiyun pWin->mapped = TRUE;
2712*4882a593Smuzhiyun pWin->realized = TRUE; /* for roots */
2713*4882a593Smuzhiyun pWin->viewable = pWin->drawable.class == InputOutput;
2714*4882a593Smuzhiyun /* We SHOULD check for an error value here XXX */
2715*4882a593Smuzhiyun (*pScreen->RealizeWindow) (pWin);
2716*4882a593Smuzhiyun if (pScreen->ClipNotify)
2717*4882a593Smuzhiyun (*pScreen->ClipNotify) (pWin, 0, 0);
2718*4882a593Smuzhiyun if (pScreen->PostValidateTree)
2719*4882a593Smuzhiyun (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap);
2720*4882a593Smuzhiyun RegionNull(&temp);
2721*4882a593Smuzhiyun RegionCopy(&temp, &pWin->clipList);
2722*4882a593Smuzhiyun (*pScreen->WindowExposures) (pWin, &temp);
2723*4882a593Smuzhiyun RegionUninit(&temp);
2724*4882a593Smuzhiyun }
2725*4882a593Smuzhiyun
2726*4882a593Smuzhiyun return Success;
2727*4882a593Smuzhiyun }
2728*4882a593Smuzhiyun
2729*4882a593Smuzhiyun /*****
2730*4882a593Smuzhiyun * MapSubwindows
2731*4882a593Smuzhiyun * Performs a MapWindow all unmapped children of the window, in top
2732*4882a593Smuzhiyun * to bottom stacking order.
2733*4882a593Smuzhiyun *****/
2734*4882a593Smuzhiyun
2735*4882a593Smuzhiyun void
MapSubwindows(WindowPtr pParent,ClientPtr client)2736*4882a593Smuzhiyun MapSubwindows(WindowPtr pParent, ClientPtr client)
2737*4882a593Smuzhiyun {
2738*4882a593Smuzhiyun WindowPtr pWin;
2739*4882a593Smuzhiyun WindowPtr pFirstMapped = NullWindow;
2740*4882a593Smuzhiyun ScreenPtr pScreen;
2741*4882a593Smuzhiyun Mask parentRedirect;
2742*4882a593Smuzhiyun Mask parentNotify;
2743*4882a593Smuzhiyun Bool anyMarked;
2744*4882a593Smuzhiyun WindowPtr pLayerWin;
2745*4882a593Smuzhiyun
2746*4882a593Smuzhiyun pScreen = pParent->drawable.pScreen;
2747*4882a593Smuzhiyun parentRedirect = RedirectSend(pParent);
2748*4882a593Smuzhiyun parentNotify = SubSend(pParent);
2749*4882a593Smuzhiyun anyMarked = FALSE;
2750*4882a593Smuzhiyun for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) {
2751*4882a593Smuzhiyun if (!pWin->mapped) {
2752*4882a593Smuzhiyun if (parentRedirect && !pWin->overrideRedirect)
2753*4882a593Smuzhiyun if (MaybeDeliverMapRequest(pWin, pParent, client))
2754*4882a593Smuzhiyun continue;
2755*4882a593Smuzhiyun
2756*4882a593Smuzhiyun pWin->mapped = TRUE;
2757*4882a593Smuzhiyun if (parentNotify || StrSend(pWin))
2758*4882a593Smuzhiyun DeliverMapNotify(pWin);
2759*4882a593Smuzhiyun
2760*4882a593Smuzhiyun if (!pFirstMapped)
2761*4882a593Smuzhiyun pFirstMapped = pWin;
2762*4882a593Smuzhiyun if (pParent->realized) {
2763*4882a593Smuzhiyun RealizeTree(pWin);
2764*4882a593Smuzhiyun if (pWin->viewable) {
2765*4882a593Smuzhiyun anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin,
2766*4882a593Smuzhiyun NULL);
2767*4882a593Smuzhiyun }
2768*4882a593Smuzhiyun }
2769*4882a593Smuzhiyun }
2770*4882a593Smuzhiyun }
2771*4882a593Smuzhiyun
2772*4882a593Smuzhiyun if (pFirstMapped) {
2773*4882a593Smuzhiyun pLayerWin = (*pScreen->GetLayerWindow) (pParent);
2774*4882a593Smuzhiyun if (pLayerWin->parent != pParent) {
2775*4882a593Smuzhiyun anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin,
2776*4882a593Smuzhiyun pLayerWin, NULL);
2777*4882a593Smuzhiyun pFirstMapped = pLayerWin;
2778*4882a593Smuzhiyun }
2779*4882a593Smuzhiyun if (anyMarked) {
2780*4882a593Smuzhiyun (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap);
2781*4882a593Smuzhiyun (*pScreen->HandleExposures) (pLayerWin->parent);
2782*4882a593Smuzhiyun if (pScreen->PostValidateTree)
2783*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped,
2784*4882a593Smuzhiyun VTMap);
2785*4882a593Smuzhiyun }
2786*4882a593Smuzhiyun WindowsRestructured();
2787*4882a593Smuzhiyun }
2788*4882a593Smuzhiyun }
2789*4882a593Smuzhiyun
2790*4882a593Smuzhiyun static void
UnrealizeTree(WindowPtr pWin,Bool fromConfigure)2791*4882a593Smuzhiyun UnrealizeTree(WindowPtr pWin, Bool fromConfigure)
2792*4882a593Smuzhiyun {
2793*4882a593Smuzhiyun WindowPtr pChild;
2794*4882a593Smuzhiyun UnrealizeWindowProcPtr Unrealize;
2795*4882a593Smuzhiyun MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
2796*4882a593Smuzhiyun
2797*4882a593Smuzhiyun Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
2798*4882a593Smuzhiyun MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
2799*4882a593Smuzhiyun pChild = pWin;
2800*4882a593Smuzhiyun while (1) {
2801*4882a593Smuzhiyun if (pChild->realized) {
2802*4882a593Smuzhiyun pChild->realized = FALSE;
2803*4882a593Smuzhiyun pChild->visibility = VisibilityNotViewable;
2804*4882a593Smuzhiyun #ifdef PANORAMIX
2805*4882a593Smuzhiyun if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
2806*4882a593Smuzhiyun PanoramiXRes *win;
2807*4882a593Smuzhiyun int rc = dixLookupResourceByType((void **) &win,
2808*4882a593Smuzhiyun pChild->drawable.id,
2809*4882a593Smuzhiyun XRT_WINDOW,
2810*4882a593Smuzhiyun serverClient, DixWriteAccess);
2811*4882a593Smuzhiyun
2812*4882a593Smuzhiyun if (rc == Success)
2813*4882a593Smuzhiyun win->u.win.visibility = VisibilityNotViewable;
2814*4882a593Smuzhiyun }
2815*4882a593Smuzhiyun #endif
2816*4882a593Smuzhiyun (*Unrealize) (pChild);
2817*4882a593Smuzhiyun DeleteWindowFromAnyEvents(pChild, FALSE);
2818*4882a593Smuzhiyun if (pChild->viewable) {
2819*4882a593Smuzhiyun pChild->viewable = FALSE;
2820*4882a593Smuzhiyun (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure);
2821*4882a593Smuzhiyun pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
2822*4882a593Smuzhiyun }
2823*4882a593Smuzhiyun if (pChild->firstChild) {
2824*4882a593Smuzhiyun pChild = pChild->firstChild;
2825*4882a593Smuzhiyun continue;
2826*4882a593Smuzhiyun }
2827*4882a593Smuzhiyun }
2828*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pWin))
2829*4882a593Smuzhiyun pChild = pChild->parent;
2830*4882a593Smuzhiyun if (pChild == pWin)
2831*4882a593Smuzhiyun return;
2832*4882a593Smuzhiyun pChild = pChild->nextSib;
2833*4882a593Smuzhiyun }
2834*4882a593Smuzhiyun }
2835*4882a593Smuzhiyun
2836*4882a593Smuzhiyun static void
DeliverUnmapNotify(WindowPtr pWin,Bool fromConfigure)2837*4882a593Smuzhiyun DeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure)
2838*4882a593Smuzhiyun {
2839*4882a593Smuzhiyun xEvent event = {
2840*4882a593Smuzhiyun .u.unmapNotify.window = pWin->drawable.id,
2841*4882a593Smuzhiyun .u.unmapNotify.fromConfigure = fromConfigure
2842*4882a593Smuzhiyun };
2843*4882a593Smuzhiyun event.u.u.type = UnmapNotify;
2844*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
2845*4882a593Smuzhiyun }
2846*4882a593Smuzhiyun
2847*4882a593Smuzhiyun /*****
2848*4882a593Smuzhiyun * UnmapWindow
2849*4882a593Smuzhiyun * If the window is already unmapped, this request has no effect.
2850*4882a593Smuzhiyun * Otherwise, the window is unmapped and an UnMapNotify event is
2851*4882a593Smuzhiyun * generated. Cannot unmap a root window.
2852*4882a593Smuzhiyun *****/
2853*4882a593Smuzhiyun
2854*4882a593Smuzhiyun int
UnmapWindow(WindowPtr pWin,Bool fromConfigure)2855*4882a593Smuzhiyun UnmapWindow(WindowPtr pWin, Bool fromConfigure)
2856*4882a593Smuzhiyun {
2857*4882a593Smuzhiyun WindowPtr pParent;
2858*4882a593Smuzhiyun Bool wasRealized = (Bool) pWin->realized;
2859*4882a593Smuzhiyun Bool wasViewable = (Bool) pWin->viewable;
2860*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
2861*4882a593Smuzhiyun WindowPtr pLayerWin = pWin;
2862*4882a593Smuzhiyun
2863*4882a593Smuzhiyun if ((!pWin->mapped) || (!(pParent = pWin->parent)))
2864*4882a593Smuzhiyun return Success;
2865*4882a593Smuzhiyun if (SubStrSend(pWin, pParent))
2866*4882a593Smuzhiyun DeliverUnmapNotify(pWin, fromConfigure);
2867*4882a593Smuzhiyun if (wasViewable && !fromConfigure) {
2868*4882a593Smuzhiyun pWin->valdata = UnmapValData;
2869*4882a593Smuzhiyun (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin);
2870*4882a593Smuzhiyun (*pScreen->MarkWindow) (pLayerWin->parent);
2871*4882a593Smuzhiyun }
2872*4882a593Smuzhiyun pWin->mapped = FALSE;
2873*4882a593Smuzhiyun if (wasRealized)
2874*4882a593Smuzhiyun UnrealizeTree(pWin, fromConfigure);
2875*4882a593Smuzhiyun if (wasViewable) {
2876*4882a593Smuzhiyun if (!fromConfigure) {
2877*4882a593Smuzhiyun (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap);
2878*4882a593Smuzhiyun (*pScreen->HandleExposures) (pLayerWin->parent);
2879*4882a593Smuzhiyun if (pScreen->PostValidateTree)
2880*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap);
2881*4882a593Smuzhiyun }
2882*4882a593Smuzhiyun }
2883*4882a593Smuzhiyun if (wasRealized && !fromConfigure) {
2884*4882a593Smuzhiyun WindowsRestructured();
2885*4882a593Smuzhiyun WindowGone(pWin);
2886*4882a593Smuzhiyun }
2887*4882a593Smuzhiyun return Success;
2888*4882a593Smuzhiyun }
2889*4882a593Smuzhiyun
2890*4882a593Smuzhiyun /*****
2891*4882a593Smuzhiyun * UnmapSubwindows
2892*4882a593Smuzhiyun * Performs an UnmapWindow request with the specified mode on all mapped
2893*4882a593Smuzhiyun * children of the window, in bottom to top stacking order.
2894*4882a593Smuzhiyun *****/
2895*4882a593Smuzhiyun
2896*4882a593Smuzhiyun void
UnmapSubwindows(WindowPtr pWin)2897*4882a593Smuzhiyun UnmapSubwindows(WindowPtr pWin)
2898*4882a593Smuzhiyun {
2899*4882a593Smuzhiyun WindowPtr pChild, pHead;
2900*4882a593Smuzhiyun Bool wasRealized = (Bool) pWin->realized;
2901*4882a593Smuzhiyun Bool wasViewable = (Bool) pWin->viewable;
2902*4882a593Smuzhiyun Bool anyMarked = FALSE;
2903*4882a593Smuzhiyun Mask parentNotify;
2904*4882a593Smuzhiyun WindowPtr pLayerWin = NULL;
2905*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
2906*4882a593Smuzhiyun
2907*4882a593Smuzhiyun if (!pWin->firstChild)
2908*4882a593Smuzhiyun return;
2909*4882a593Smuzhiyun parentNotify = SubSend(pWin);
2910*4882a593Smuzhiyun pHead = RealChildHead(pWin);
2911*4882a593Smuzhiyun
2912*4882a593Smuzhiyun if (wasViewable)
2913*4882a593Smuzhiyun pLayerWin = (*pScreen->GetLayerWindow) (pWin);
2914*4882a593Smuzhiyun
2915*4882a593Smuzhiyun for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) {
2916*4882a593Smuzhiyun if (pChild->mapped) {
2917*4882a593Smuzhiyun if (parentNotify || StrSend(pChild))
2918*4882a593Smuzhiyun DeliverUnmapNotify(pChild, xFalse);
2919*4882a593Smuzhiyun if (pChild->viewable) {
2920*4882a593Smuzhiyun pChild->valdata = UnmapValData;
2921*4882a593Smuzhiyun anyMarked = TRUE;
2922*4882a593Smuzhiyun }
2923*4882a593Smuzhiyun pChild->mapped = FALSE;
2924*4882a593Smuzhiyun if (pChild->realized)
2925*4882a593Smuzhiyun UnrealizeTree(pChild, FALSE);
2926*4882a593Smuzhiyun }
2927*4882a593Smuzhiyun }
2928*4882a593Smuzhiyun if (wasViewable) {
2929*4882a593Smuzhiyun if (anyMarked) {
2930*4882a593Smuzhiyun if (pLayerWin->parent == pWin)
2931*4882a593Smuzhiyun (*pScreen->MarkWindow) (pWin);
2932*4882a593Smuzhiyun else {
2933*4882a593Smuzhiyun WindowPtr ptmp;
2934*4882a593Smuzhiyun
2935*4882a593Smuzhiyun (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL);
2936*4882a593Smuzhiyun (*pScreen->MarkWindow) (pLayerWin->parent);
2937*4882a593Smuzhiyun
2938*4882a593Smuzhiyun /* Windows between pWin and pLayerWin may not have been marked */
2939*4882a593Smuzhiyun ptmp = pWin;
2940*4882a593Smuzhiyun
2941*4882a593Smuzhiyun while (ptmp != pLayerWin->parent) {
2942*4882a593Smuzhiyun (*pScreen->MarkWindow) (ptmp);
2943*4882a593Smuzhiyun ptmp = ptmp->parent;
2944*4882a593Smuzhiyun }
2945*4882a593Smuzhiyun pHead = pWin->firstChild;
2946*4882a593Smuzhiyun }
2947*4882a593Smuzhiyun (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap);
2948*4882a593Smuzhiyun (*pScreen->HandleExposures) (pLayerWin->parent);
2949*4882a593Smuzhiyun if (pScreen->PostValidateTree)
2950*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pLayerWin->parent, pHead,
2951*4882a593Smuzhiyun VTUnmap);
2952*4882a593Smuzhiyun }
2953*4882a593Smuzhiyun }
2954*4882a593Smuzhiyun if (wasRealized) {
2955*4882a593Smuzhiyun WindowsRestructured();
2956*4882a593Smuzhiyun WindowGone(pWin);
2957*4882a593Smuzhiyun }
2958*4882a593Smuzhiyun }
2959*4882a593Smuzhiyun
2960*4882a593Smuzhiyun void
HandleSaveSet(ClientPtr client)2961*4882a593Smuzhiyun HandleSaveSet(ClientPtr client)
2962*4882a593Smuzhiyun {
2963*4882a593Smuzhiyun WindowPtr pParent, pWin;
2964*4882a593Smuzhiyun int j;
2965*4882a593Smuzhiyun
2966*4882a593Smuzhiyun for (j = 0; j < client->numSaved; j++) {
2967*4882a593Smuzhiyun pWin = SaveSetWindow(client->saveSet[j]);
2968*4882a593Smuzhiyun if (SaveSetToRoot(client->saveSet[j]))
2969*4882a593Smuzhiyun pParent = pWin->drawable.pScreen->root;
2970*4882a593Smuzhiyun else
2971*4882a593Smuzhiyun {
2972*4882a593Smuzhiyun pParent = pWin->parent;
2973*4882a593Smuzhiyun while (pParent && (wClient(pParent) == client))
2974*4882a593Smuzhiyun pParent = pParent->parent;
2975*4882a593Smuzhiyun }
2976*4882a593Smuzhiyun if (pParent) {
2977*4882a593Smuzhiyun if (pParent != pWin->parent) {
2978*4882a593Smuzhiyun /* unmap first so that ReparentWindow doesn't remap */
2979*4882a593Smuzhiyun if (!SaveSetShouldMap(client->saveSet[j]))
2980*4882a593Smuzhiyun UnmapWindow(pWin, FALSE);
2981*4882a593Smuzhiyun ReparentWindow(pWin, pParent,
2982*4882a593Smuzhiyun pWin->drawable.x - wBorderWidth(pWin) -
2983*4882a593Smuzhiyun pParent->drawable.x,
2984*4882a593Smuzhiyun pWin->drawable.y - wBorderWidth(pWin) -
2985*4882a593Smuzhiyun pParent->drawable.y, client);
2986*4882a593Smuzhiyun if (!pWin->realized && pWin->mapped)
2987*4882a593Smuzhiyun pWin->mapped = FALSE;
2988*4882a593Smuzhiyun }
2989*4882a593Smuzhiyun if (SaveSetShouldMap(client->saveSet[j]))
2990*4882a593Smuzhiyun MapWindow(pWin, client);
2991*4882a593Smuzhiyun }
2992*4882a593Smuzhiyun }
2993*4882a593Smuzhiyun free(client->saveSet);
2994*4882a593Smuzhiyun client->numSaved = 0;
2995*4882a593Smuzhiyun client->saveSet = NULL;
2996*4882a593Smuzhiyun }
2997*4882a593Smuzhiyun
2998*4882a593Smuzhiyun /**
2999*4882a593Smuzhiyun *
3000*4882a593Smuzhiyun * \param x,y in root
3001*4882a593Smuzhiyun */
3002*4882a593Smuzhiyun Bool
PointInWindowIsVisible(WindowPtr pWin,int x,int y)3003*4882a593Smuzhiyun PointInWindowIsVisible(WindowPtr pWin, int x, int y)
3004*4882a593Smuzhiyun {
3005*4882a593Smuzhiyun BoxRec box;
3006*4882a593Smuzhiyun
3007*4882a593Smuzhiyun if (!pWin->realized)
3008*4882a593Smuzhiyun return FALSE;
3009*4882a593Smuzhiyun if (RegionContainsPoint(&pWin->borderClip, x, y, &box)
3010*4882a593Smuzhiyun && (!wInputShape(pWin) ||
3011*4882a593Smuzhiyun RegionContainsPoint(wInputShape(pWin),
3012*4882a593Smuzhiyun x - pWin->drawable.x,
3013*4882a593Smuzhiyun y - pWin->drawable.y, &box)))
3014*4882a593Smuzhiyun return TRUE;
3015*4882a593Smuzhiyun return FALSE;
3016*4882a593Smuzhiyun }
3017*4882a593Smuzhiyun
3018*4882a593Smuzhiyun RegionPtr
NotClippedByChildren(WindowPtr pWin)3019*4882a593Smuzhiyun NotClippedByChildren(WindowPtr pWin)
3020*4882a593Smuzhiyun {
3021*4882a593Smuzhiyun RegionPtr pReg = RegionCreate(NullBox, 1);
3022*4882a593Smuzhiyun
3023*4882a593Smuzhiyun if (pWin->parent ||
3024*4882a593Smuzhiyun screenIsSaved != SCREEN_SAVER_ON ||
3025*4882a593Smuzhiyun !HasSaverWindow(pWin->drawable.pScreen)) {
3026*4882a593Smuzhiyun RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize);
3027*4882a593Smuzhiyun }
3028*4882a593Smuzhiyun return pReg;
3029*4882a593Smuzhiyun }
3030*4882a593Smuzhiyun
3031*4882a593Smuzhiyun void
SendVisibilityNotify(WindowPtr pWin)3032*4882a593Smuzhiyun SendVisibilityNotify(WindowPtr pWin)
3033*4882a593Smuzhiyun {
3034*4882a593Smuzhiyun xEvent event;
3035*4882a593Smuzhiyun unsigned int visibility = pWin->visibility;
3036*4882a593Smuzhiyun
3037*4882a593Smuzhiyun #ifdef PANORAMIX
3038*4882a593Smuzhiyun /* This is not quite correct yet, but it's close */
3039*4882a593Smuzhiyun if (!noPanoramiXExtension) {
3040*4882a593Smuzhiyun PanoramiXRes *win;
3041*4882a593Smuzhiyun WindowPtr pWin2;
3042*4882a593Smuzhiyun int rc, i, Scrnum;
3043*4882a593Smuzhiyun
3044*4882a593Smuzhiyun Scrnum = pWin->drawable.pScreen->myNum;
3045*4882a593Smuzhiyun
3046*4882a593Smuzhiyun win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
3047*4882a593Smuzhiyun
3048*4882a593Smuzhiyun if (!win || (win->u.win.visibility == visibility))
3049*4882a593Smuzhiyun return;
3050*4882a593Smuzhiyun
3051*4882a593Smuzhiyun switch (visibility) {
3052*4882a593Smuzhiyun case VisibilityUnobscured:
3053*4882a593Smuzhiyun FOR_NSCREENS(i) {
3054*4882a593Smuzhiyun if (i == Scrnum)
3055*4882a593Smuzhiyun continue;
3056*4882a593Smuzhiyun
3057*4882a593Smuzhiyun rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient,
3058*4882a593Smuzhiyun DixWriteAccess);
3059*4882a593Smuzhiyun
3060*4882a593Smuzhiyun if (rc == Success) {
3061*4882a593Smuzhiyun if (pWin2->visibility == VisibilityPartiallyObscured)
3062*4882a593Smuzhiyun return;
3063*4882a593Smuzhiyun
3064*4882a593Smuzhiyun if (!i)
3065*4882a593Smuzhiyun pWin = pWin2;
3066*4882a593Smuzhiyun }
3067*4882a593Smuzhiyun }
3068*4882a593Smuzhiyun break;
3069*4882a593Smuzhiyun case VisibilityPartiallyObscured:
3070*4882a593Smuzhiyun if (Scrnum) {
3071*4882a593Smuzhiyun rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient,
3072*4882a593Smuzhiyun DixWriteAccess);
3073*4882a593Smuzhiyun if (rc == Success)
3074*4882a593Smuzhiyun pWin = pWin2;
3075*4882a593Smuzhiyun }
3076*4882a593Smuzhiyun break;
3077*4882a593Smuzhiyun case VisibilityFullyObscured:
3078*4882a593Smuzhiyun FOR_NSCREENS(i) {
3079*4882a593Smuzhiyun if (i == Scrnum)
3080*4882a593Smuzhiyun continue;
3081*4882a593Smuzhiyun
3082*4882a593Smuzhiyun rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient,
3083*4882a593Smuzhiyun DixWriteAccess);
3084*4882a593Smuzhiyun
3085*4882a593Smuzhiyun if (rc == Success) {
3086*4882a593Smuzhiyun if (pWin2->visibility != VisibilityFullyObscured)
3087*4882a593Smuzhiyun return;
3088*4882a593Smuzhiyun
3089*4882a593Smuzhiyun if (!i)
3090*4882a593Smuzhiyun pWin = pWin2;
3091*4882a593Smuzhiyun }
3092*4882a593Smuzhiyun }
3093*4882a593Smuzhiyun break;
3094*4882a593Smuzhiyun }
3095*4882a593Smuzhiyun
3096*4882a593Smuzhiyun win->u.win.visibility = visibility;
3097*4882a593Smuzhiyun }
3098*4882a593Smuzhiyun #endif
3099*4882a593Smuzhiyun
3100*4882a593Smuzhiyun event = (xEvent) {
3101*4882a593Smuzhiyun .u.visibility.window = pWin->drawable.id,
3102*4882a593Smuzhiyun .u.visibility.state = visibility
3103*4882a593Smuzhiyun };
3104*4882a593Smuzhiyun event.u.u.type = VisibilityNotify;
3105*4882a593Smuzhiyun DeliverEvents(pWin, &event, 1, NullWindow);
3106*4882a593Smuzhiyun }
3107*4882a593Smuzhiyun
3108*4882a593Smuzhiyun #define RANDOM_WIDTH 32
3109*4882a593Smuzhiyun int
dixSaveScreens(ClientPtr client,int on,int mode)3110*4882a593Smuzhiyun dixSaveScreens(ClientPtr client, int on, int mode)
3111*4882a593Smuzhiyun {
3112*4882a593Smuzhiyun int rc, i, what, type;
3113*4882a593Smuzhiyun
3114*4882a593Smuzhiyun if (on == SCREEN_SAVER_FORCER) {
3115*4882a593Smuzhiyun if (mode == ScreenSaverReset)
3116*4882a593Smuzhiyun what = SCREEN_SAVER_OFF;
3117*4882a593Smuzhiyun else
3118*4882a593Smuzhiyun what = SCREEN_SAVER_ON;
3119*4882a593Smuzhiyun type = what;
3120*4882a593Smuzhiyun }
3121*4882a593Smuzhiyun else {
3122*4882a593Smuzhiyun what = on;
3123*4882a593Smuzhiyun type = what;
3124*4882a593Smuzhiyun if (what == screenIsSaved)
3125*4882a593Smuzhiyun type = SCREEN_SAVER_CYCLE;
3126*4882a593Smuzhiyun }
3127*4882a593Smuzhiyun
3128*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
3129*4882a593Smuzhiyun rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3130*4882a593Smuzhiyun DixShowAccess | DixHideAccess);
3131*4882a593Smuzhiyun if (rc != Success)
3132*4882a593Smuzhiyun return rc;
3133*4882a593Smuzhiyun }
3134*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
3135*4882a593Smuzhiyun ScreenPtr pScreen = screenInfo.screens[i];
3136*4882a593Smuzhiyun
3137*4882a593Smuzhiyun if (on == SCREEN_SAVER_FORCER)
3138*4882a593Smuzhiyun (*pScreen->SaveScreen) (pScreen, on);
3139*4882a593Smuzhiyun if (pScreen->screensaver.ExternalScreenSaver) {
3140*4882a593Smuzhiyun if ((*pScreen->screensaver.ExternalScreenSaver)
3141*4882a593Smuzhiyun (pScreen, type, on == SCREEN_SAVER_FORCER))
3142*4882a593Smuzhiyun continue;
3143*4882a593Smuzhiyun }
3144*4882a593Smuzhiyun if (type == screenIsSaved)
3145*4882a593Smuzhiyun continue;
3146*4882a593Smuzhiyun switch (type) {
3147*4882a593Smuzhiyun case SCREEN_SAVER_OFF:
3148*4882a593Smuzhiyun if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) {
3149*4882a593Smuzhiyun (*pScreen->SaveScreen) (pScreen, what);
3150*4882a593Smuzhiyun }
3151*4882a593Smuzhiyun else if (HasSaverWindow(pScreen)) {
3152*4882a593Smuzhiyun pScreen->screensaver.pWindow = NullWindow;
3153*4882a593Smuzhiyun FreeResource(pScreen->screensaver.wid, RT_NONE);
3154*4882a593Smuzhiyun }
3155*4882a593Smuzhiyun break;
3156*4882a593Smuzhiyun case SCREEN_SAVER_CYCLE:
3157*4882a593Smuzhiyun if (pScreen->screensaver.blanked == SCREEN_IS_TILED) {
3158*4882a593Smuzhiyun WindowPtr pWin = pScreen->screensaver.pWindow;
3159*4882a593Smuzhiyun
3160*4882a593Smuzhiyun /* make it look like screen saver is off, so that
3161*4882a593Smuzhiyun * NotClippedByChildren will compute a clip list
3162*4882a593Smuzhiyun * for the root window, so PaintWindow works
3163*4882a593Smuzhiyun */
3164*4882a593Smuzhiyun screenIsSaved = SCREEN_SAVER_OFF;
3165*4882a593Smuzhiyun (*pWin->drawable.pScreen->MoveWindow) (pWin,
3166*4882a593Smuzhiyun (short) (-
3167*4882a593Smuzhiyun (rand() %
3168*4882a593Smuzhiyun RANDOM_WIDTH)),
3169*4882a593Smuzhiyun (short) (-
3170*4882a593Smuzhiyun (rand() %
3171*4882a593Smuzhiyun RANDOM_WIDTH)),
3172*4882a593Smuzhiyun pWin->nextSib, VTMove);
3173*4882a593Smuzhiyun screenIsSaved = SCREEN_SAVER_ON;
3174*4882a593Smuzhiyun }
3175*4882a593Smuzhiyun /*
3176*4882a593Smuzhiyun * Call the DDX saver in case it wants to do something
3177*4882a593Smuzhiyun * at cycle time
3178*4882a593Smuzhiyun */
3179*4882a593Smuzhiyun else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) {
3180*4882a593Smuzhiyun (*pScreen->SaveScreen) (pScreen, type);
3181*4882a593Smuzhiyun }
3182*4882a593Smuzhiyun break;
3183*4882a593Smuzhiyun case SCREEN_SAVER_ON:
3184*4882a593Smuzhiyun if (ScreenSaverBlanking != DontPreferBlanking) {
3185*4882a593Smuzhiyun if ((*pScreen->SaveScreen) (pScreen, what)) {
3186*4882a593Smuzhiyun pScreen->screensaver.blanked = SCREEN_IS_BLANKED;
3187*4882a593Smuzhiyun continue;
3188*4882a593Smuzhiyun }
3189*4882a593Smuzhiyun if ((ScreenSaverAllowExposures != DontAllowExposures) &&
3190*4882a593Smuzhiyun TileScreenSaver(pScreen, SCREEN_IS_BLACK)) {
3191*4882a593Smuzhiyun pScreen->screensaver.blanked = SCREEN_IS_BLACK;
3192*4882a593Smuzhiyun continue;
3193*4882a593Smuzhiyun }
3194*4882a593Smuzhiyun }
3195*4882a593Smuzhiyun if ((ScreenSaverAllowExposures != DontAllowExposures) &&
3196*4882a593Smuzhiyun TileScreenSaver(pScreen, SCREEN_IS_TILED)) {
3197*4882a593Smuzhiyun pScreen->screensaver.blanked = SCREEN_IS_TILED;
3198*4882a593Smuzhiyun }
3199*4882a593Smuzhiyun else
3200*4882a593Smuzhiyun pScreen->screensaver.blanked = SCREEN_ISNT_SAVED;
3201*4882a593Smuzhiyun break;
3202*4882a593Smuzhiyun }
3203*4882a593Smuzhiyun }
3204*4882a593Smuzhiyun screenIsSaved = what;
3205*4882a593Smuzhiyun if (mode == ScreenSaverReset) {
3206*4882a593Smuzhiyun if (on == SCREEN_SAVER_FORCER) {
3207*4882a593Smuzhiyun DeviceIntPtr dev;
3208*4882a593Smuzhiyun UpdateCurrentTimeIf();
3209*4882a593Smuzhiyun nt_list_for_each_entry(dev, inputInfo.devices, next)
3210*4882a593Smuzhiyun NoticeTime(dev, currentTime);
3211*4882a593Smuzhiyun }
3212*4882a593Smuzhiyun SetScreenSaverTimer();
3213*4882a593Smuzhiyun }
3214*4882a593Smuzhiyun return Success;
3215*4882a593Smuzhiyun }
3216*4882a593Smuzhiyun
3217*4882a593Smuzhiyun int
SaveScreens(int on,int mode)3218*4882a593Smuzhiyun SaveScreens(int on, int mode)
3219*4882a593Smuzhiyun {
3220*4882a593Smuzhiyun return dixSaveScreens(serverClient, on, mode);
3221*4882a593Smuzhiyun }
3222*4882a593Smuzhiyun
3223*4882a593Smuzhiyun static Bool
TileScreenSaver(ScreenPtr pScreen,int kind)3224*4882a593Smuzhiyun TileScreenSaver(ScreenPtr pScreen, int kind)
3225*4882a593Smuzhiyun {
3226*4882a593Smuzhiyun int j;
3227*4882a593Smuzhiyun int result;
3228*4882a593Smuzhiyun XID attributes[3];
3229*4882a593Smuzhiyun Mask mask;
3230*4882a593Smuzhiyun WindowPtr pWin;
3231*4882a593Smuzhiyun CursorMetricRec cm;
3232*4882a593Smuzhiyun unsigned char *srcbits, *mskbits;
3233*4882a593Smuzhiyun CursorPtr cursor;
3234*4882a593Smuzhiyun XID cursorID = 0;
3235*4882a593Smuzhiyun int attri;
3236*4882a593Smuzhiyun
3237*4882a593Smuzhiyun mask = 0;
3238*4882a593Smuzhiyun attri = 0;
3239*4882a593Smuzhiyun switch (kind) {
3240*4882a593Smuzhiyun case SCREEN_IS_TILED:
3241*4882a593Smuzhiyun switch (pScreen->root->backgroundState) {
3242*4882a593Smuzhiyun case BackgroundPixel:
3243*4882a593Smuzhiyun attributes[attri++] = pScreen->root->background.pixel;
3244*4882a593Smuzhiyun mask |= CWBackPixel;
3245*4882a593Smuzhiyun break;
3246*4882a593Smuzhiyun case BackgroundPixmap:
3247*4882a593Smuzhiyun attributes[attri++] = None;
3248*4882a593Smuzhiyun mask |= CWBackPixmap;
3249*4882a593Smuzhiyun break;
3250*4882a593Smuzhiyun default:
3251*4882a593Smuzhiyun break;
3252*4882a593Smuzhiyun }
3253*4882a593Smuzhiyun break;
3254*4882a593Smuzhiyun case SCREEN_IS_BLACK:
3255*4882a593Smuzhiyun attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel;
3256*4882a593Smuzhiyun mask |= CWBackPixel;
3257*4882a593Smuzhiyun break;
3258*4882a593Smuzhiyun }
3259*4882a593Smuzhiyun mask |= CWOverrideRedirect;
3260*4882a593Smuzhiyun attributes[attri++] = xTrue;
3261*4882a593Smuzhiyun
3262*4882a593Smuzhiyun /*
3263*4882a593Smuzhiyun * create a blank cursor
3264*4882a593Smuzhiyun */
3265*4882a593Smuzhiyun
3266*4882a593Smuzhiyun cm.width = 16;
3267*4882a593Smuzhiyun cm.height = 16;
3268*4882a593Smuzhiyun cm.xhot = 8;
3269*4882a593Smuzhiyun cm.yhot = 8;
3270*4882a593Smuzhiyun srcbits = malloc(BitmapBytePad(32) * 16);
3271*4882a593Smuzhiyun mskbits = malloc(BitmapBytePad(32) * 16);
3272*4882a593Smuzhiyun if (!srcbits || !mskbits) {
3273*4882a593Smuzhiyun free(srcbits);
3274*4882a593Smuzhiyun free(mskbits);
3275*4882a593Smuzhiyun cursor = 0;
3276*4882a593Smuzhiyun }
3277*4882a593Smuzhiyun else {
3278*4882a593Smuzhiyun for (j = 0; j < BitmapBytePad(32) * 16; j++)
3279*4882a593Smuzhiyun srcbits[j] = mskbits[j] = 0x0;
3280*4882a593Smuzhiyun result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0,
3281*4882a593Smuzhiyun &cursor, serverClient, (XID) 0);
3282*4882a593Smuzhiyun if (cursor) {
3283*4882a593Smuzhiyun cursorID = FakeClientID(0);
3284*4882a593Smuzhiyun if (AddResource(cursorID, RT_CURSOR, (void *) cursor)) {
3285*4882a593Smuzhiyun attributes[attri] = cursorID;
3286*4882a593Smuzhiyun mask |= CWCursor;
3287*4882a593Smuzhiyun }
3288*4882a593Smuzhiyun else
3289*4882a593Smuzhiyun cursor = 0;
3290*4882a593Smuzhiyun }
3291*4882a593Smuzhiyun else {
3292*4882a593Smuzhiyun free(srcbits);
3293*4882a593Smuzhiyun free(mskbits);
3294*4882a593Smuzhiyun }
3295*4882a593Smuzhiyun }
3296*4882a593Smuzhiyun
3297*4882a593Smuzhiyun pWin = pScreen->screensaver.pWindow =
3298*4882a593Smuzhiyun CreateWindow(pScreen->screensaver.wid,
3299*4882a593Smuzhiyun pScreen->root,
3300*4882a593Smuzhiyun -RANDOM_WIDTH, -RANDOM_WIDTH,
3301*4882a593Smuzhiyun (unsigned short) pScreen->width + RANDOM_WIDTH,
3302*4882a593Smuzhiyun (unsigned short) pScreen->height + RANDOM_WIDTH,
3303*4882a593Smuzhiyun 0, InputOutput, mask, attributes, 0, serverClient,
3304*4882a593Smuzhiyun wVisual(pScreen->root), &result);
3305*4882a593Smuzhiyun
3306*4882a593Smuzhiyun if (cursor)
3307*4882a593Smuzhiyun FreeResource(cursorID, RT_NONE);
3308*4882a593Smuzhiyun
3309*4882a593Smuzhiyun if (!pWin)
3310*4882a593Smuzhiyun return FALSE;
3311*4882a593Smuzhiyun
3312*4882a593Smuzhiyun if (!AddResource(pWin->drawable.id, RT_WINDOW,
3313*4882a593Smuzhiyun (void *) pScreen->screensaver.pWindow))
3314*4882a593Smuzhiyun return FALSE;
3315*4882a593Smuzhiyun
3316*4882a593Smuzhiyun if (mask & CWBackPixmap) {
3317*4882a593Smuzhiyun MakeRootTile(pWin);
3318*4882a593Smuzhiyun (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap);
3319*4882a593Smuzhiyun }
3320*4882a593Smuzhiyun MapWindow(pWin, serverClient);
3321*4882a593Smuzhiyun return TRUE;
3322*4882a593Smuzhiyun }
3323*4882a593Smuzhiyun
3324*4882a593Smuzhiyun /*
3325*4882a593Smuzhiyun * FindWindowWithOptional
3326*4882a593Smuzhiyun *
3327*4882a593Smuzhiyun * search ancestors of the given window for an entry containing
3328*4882a593Smuzhiyun * a WindowOpt structure. Assumptions: some parent will
3329*4882a593Smuzhiyun * contain the structure.
3330*4882a593Smuzhiyun */
3331*4882a593Smuzhiyun
3332*4882a593Smuzhiyun WindowPtr
FindWindowWithOptional(WindowPtr w)3333*4882a593Smuzhiyun FindWindowWithOptional(WindowPtr w)
3334*4882a593Smuzhiyun {
3335*4882a593Smuzhiyun do
3336*4882a593Smuzhiyun w = w->parent;
3337*4882a593Smuzhiyun while (!w->optional);
3338*4882a593Smuzhiyun return w;
3339*4882a593Smuzhiyun }
3340*4882a593Smuzhiyun
3341*4882a593Smuzhiyun /*
3342*4882a593Smuzhiyun * CheckWindowOptionalNeed
3343*4882a593Smuzhiyun *
3344*4882a593Smuzhiyun * check each optional entry in the given window to see if
3345*4882a593Smuzhiyun * the value is satisfied by the default rules. If so,
3346*4882a593Smuzhiyun * release the optional record
3347*4882a593Smuzhiyun */
3348*4882a593Smuzhiyun
3349*4882a593Smuzhiyun void
CheckWindowOptionalNeed(WindowPtr w)3350*4882a593Smuzhiyun CheckWindowOptionalNeed(WindowPtr w)
3351*4882a593Smuzhiyun {
3352*4882a593Smuzhiyun WindowOptPtr optional;
3353*4882a593Smuzhiyun WindowOptPtr parentOptional;
3354*4882a593Smuzhiyun
3355*4882a593Smuzhiyun if (!w->parent || !w->optional)
3356*4882a593Smuzhiyun return;
3357*4882a593Smuzhiyun optional = w->optional;
3358*4882a593Smuzhiyun if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
3359*4882a593Smuzhiyun return;
3360*4882a593Smuzhiyun if (optional->otherEventMasks != 0)
3361*4882a593Smuzhiyun return;
3362*4882a593Smuzhiyun if (optional->otherClients != NULL)
3363*4882a593Smuzhiyun return;
3364*4882a593Smuzhiyun if (optional->passiveGrabs != NULL)
3365*4882a593Smuzhiyun return;
3366*4882a593Smuzhiyun if (optional->userProps != NULL)
3367*4882a593Smuzhiyun return;
3368*4882a593Smuzhiyun if (optional->backingBitPlanes != (CARD32)~0L)
3369*4882a593Smuzhiyun return;
3370*4882a593Smuzhiyun if (optional->backingPixel != 0)
3371*4882a593Smuzhiyun return;
3372*4882a593Smuzhiyun if (optional->boundingShape != NULL)
3373*4882a593Smuzhiyun return;
3374*4882a593Smuzhiyun if (optional->clipShape != NULL)
3375*4882a593Smuzhiyun return;
3376*4882a593Smuzhiyun if (optional->inputShape != NULL)
3377*4882a593Smuzhiyun return;
3378*4882a593Smuzhiyun if (optional->inputMasks != NULL)
3379*4882a593Smuzhiyun return;
3380*4882a593Smuzhiyun if (optional->deviceCursors != NULL) {
3381*4882a593Smuzhiyun DevCursNodePtr pNode = optional->deviceCursors;
3382*4882a593Smuzhiyun
3383*4882a593Smuzhiyun while (pNode) {
3384*4882a593Smuzhiyun if (pNode->cursor != None)
3385*4882a593Smuzhiyun return;
3386*4882a593Smuzhiyun pNode = pNode->next;
3387*4882a593Smuzhiyun }
3388*4882a593Smuzhiyun }
3389*4882a593Smuzhiyun
3390*4882a593Smuzhiyun parentOptional = FindWindowWithOptional(w)->optional;
3391*4882a593Smuzhiyun if (optional->visual != parentOptional->visual)
3392*4882a593Smuzhiyun return;
3393*4882a593Smuzhiyun if (optional->cursor != None &&
3394*4882a593Smuzhiyun (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone))
3395*4882a593Smuzhiyun return;
3396*4882a593Smuzhiyun if (optional->colormap != parentOptional->colormap)
3397*4882a593Smuzhiyun return;
3398*4882a593Smuzhiyun DisposeWindowOptional(w);
3399*4882a593Smuzhiyun }
3400*4882a593Smuzhiyun
3401*4882a593Smuzhiyun /*
3402*4882a593Smuzhiyun * MakeWindowOptional
3403*4882a593Smuzhiyun *
3404*4882a593Smuzhiyun * create an optional record and initialize it with the default
3405*4882a593Smuzhiyun * values.
3406*4882a593Smuzhiyun */
3407*4882a593Smuzhiyun
3408*4882a593Smuzhiyun Bool
MakeWindowOptional(WindowPtr pWin)3409*4882a593Smuzhiyun MakeWindowOptional(WindowPtr pWin)
3410*4882a593Smuzhiyun {
3411*4882a593Smuzhiyun WindowOptPtr optional;
3412*4882a593Smuzhiyun WindowOptPtr parentOptional;
3413*4882a593Smuzhiyun
3414*4882a593Smuzhiyun if (pWin->optional)
3415*4882a593Smuzhiyun return TRUE;
3416*4882a593Smuzhiyun optional = malloc(sizeof(WindowOptRec));
3417*4882a593Smuzhiyun if (!optional)
3418*4882a593Smuzhiyun return FALSE;
3419*4882a593Smuzhiyun optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
3420*4882a593Smuzhiyun optional->otherEventMasks = 0;
3421*4882a593Smuzhiyun optional->otherClients = NULL;
3422*4882a593Smuzhiyun optional->passiveGrabs = NULL;
3423*4882a593Smuzhiyun optional->userProps = NULL;
3424*4882a593Smuzhiyun optional->backingBitPlanes = ~0L;
3425*4882a593Smuzhiyun optional->backingPixel = 0;
3426*4882a593Smuzhiyun optional->boundingShape = NULL;
3427*4882a593Smuzhiyun optional->clipShape = NULL;
3428*4882a593Smuzhiyun optional->inputShape = NULL;
3429*4882a593Smuzhiyun optional->inputMasks = NULL;
3430*4882a593Smuzhiyun optional->deviceCursors = NULL;
3431*4882a593Smuzhiyun
3432*4882a593Smuzhiyun parentOptional = FindWindowWithOptional(pWin)->optional;
3433*4882a593Smuzhiyun optional->visual = parentOptional->visual;
3434*4882a593Smuzhiyun if (!pWin->cursorIsNone) {
3435*4882a593Smuzhiyun optional->cursor = RefCursor(parentOptional->cursor);
3436*4882a593Smuzhiyun }
3437*4882a593Smuzhiyun else {
3438*4882a593Smuzhiyun optional->cursor = None;
3439*4882a593Smuzhiyun }
3440*4882a593Smuzhiyun optional->colormap = parentOptional->colormap;
3441*4882a593Smuzhiyun pWin->optional = optional;
3442*4882a593Smuzhiyun return TRUE;
3443*4882a593Smuzhiyun }
3444*4882a593Smuzhiyun
3445*4882a593Smuzhiyun /*
3446*4882a593Smuzhiyun * Changes the cursor struct for the given device and the given window.
3447*4882a593Smuzhiyun * A cursor that does not have a device cursor set will use whatever the
3448*4882a593Smuzhiyun * standard cursor is for the window. If all devices have a cursor set,
3449*4882a593Smuzhiyun * changing the window cursor (e.g. using XDefineCursor()) will not have any
3450*4882a593Smuzhiyun * visible effect. Only when one of the device cursors is set to None again,
3451*4882a593Smuzhiyun * this device's cursor will display the changed standard cursor.
3452*4882a593Smuzhiyun *
3453*4882a593Smuzhiyun * CursorIsNone of the window struct is NOT modified if you set a device
3454*4882a593Smuzhiyun * cursor.
3455*4882a593Smuzhiyun *
3456*4882a593Smuzhiyun * Assumption: If there is a node for a device in the list, the device has a
3457*4882a593Smuzhiyun * cursor. If the cursor is set to None, it is inherited by the parent.
3458*4882a593Smuzhiyun */
3459*4882a593Smuzhiyun int
ChangeWindowDeviceCursor(WindowPtr pWin,DeviceIntPtr pDev,CursorPtr pCursor)3460*4882a593Smuzhiyun ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
3461*4882a593Smuzhiyun {
3462*4882a593Smuzhiyun DevCursNodePtr pNode, pPrev;
3463*4882a593Smuzhiyun CursorPtr pOldCursor = NULL;
3464*4882a593Smuzhiyun ScreenPtr pScreen;
3465*4882a593Smuzhiyun WindowPtr pChild;
3466*4882a593Smuzhiyun
3467*4882a593Smuzhiyun if (!pWin->optional && !MakeWindowOptional(pWin))
3468*4882a593Smuzhiyun return BadAlloc;
3469*4882a593Smuzhiyun
3470*4882a593Smuzhiyun /* 1) Check if window has device cursor set
3471*4882a593Smuzhiyun * Yes: 1.1) swap cursor with given cursor if parent does not have same
3472*4882a593Smuzhiyun * cursor, free old cursor
3473*4882a593Smuzhiyun * 1.2) free old cursor, use parent cursor
3474*4882a593Smuzhiyun * No: 1.1) add node to beginning of list.
3475*4882a593Smuzhiyun * 1.2) add cursor to node if parent does not have same cursor
3476*4882a593Smuzhiyun * 1.3) use parent cursor if parent does not have same cursor
3477*4882a593Smuzhiyun * 2) Patch up children if child has a devcursor
3478*4882a593Smuzhiyun * 2.1) if child has cursor None, it inherited from parent, set to old
3479*4882a593Smuzhiyun * cursor
3480*4882a593Smuzhiyun * 2.2) if child has same cursor as new cursor, remove and set to None
3481*4882a593Smuzhiyun */
3482*4882a593Smuzhiyun
3483*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
3484*4882a593Smuzhiyun
3485*4882a593Smuzhiyun if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) {
3486*4882a593Smuzhiyun /* has device cursor */
3487*4882a593Smuzhiyun
3488*4882a593Smuzhiyun if (pNode->cursor == pCursor)
3489*4882a593Smuzhiyun return Success;
3490*4882a593Smuzhiyun
3491*4882a593Smuzhiyun pOldCursor = pNode->cursor;
3492*4882a593Smuzhiyun
3493*4882a593Smuzhiyun if (!pCursor) { /* remove from list */
3494*4882a593Smuzhiyun if (pPrev)
3495*4882a593Smuzhiyun pPrev->next = pNode->next;
3496*4882a593Smuzhiyun else
3497*4882a593Smuzhiyun /* first item in list */
3498*4882a593Smuzhiyun pWin->optional->deviceCursors = pNode->next;
3499*4882a593Smuzhiyun
3500*4882a593Smuzhiyun free(pNode);
3501*4882a593Smuzhiyun goto out;
3502*4882a593Smuzhiyun }
3503*4882a593Smuzhiyun
3504*4882a593Smuzhiyun }
3505*4882a593Smuzhiyun else {
3506*4882a593Smuzhiyun /* no device cursor yet */
3507*4882a593Smuzhiyun DevCursNodePtr pNewNode;
3508*4882a593Smuzhiyun
3509*4882a593Smuzhiyun if (!pCursor)
3510*4882a593Smuzhiyun return Success;
3511*4882a593Smuzhiyun
3512*4882a593Smuzhiyun pNewNode = malloc(sizeof(DevCursNodeRec));
3513*4882a593Smuzhiyun pNewNode->dev = pDev;
3514*4882a593Smuzhiyun pNewNode->next = pWin->optional->deviceCursors;
3515*4882a593Smuzhiyun pWin->optional->deviceCursors = pNewNode;
3516*4882a593Smuzhiyun pNode = pNewNode;
3517*4882a593Smuzhiyun
3518*4882a593Smuzhiyun }
3519*4882a593Smuzhiyun
3520*4882a593Smuzhiyun if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
3521*4882a593Smuzhiyun pNode->cursor = None;
3522*4882a593Smuzhiyun else {
3523*4882a593Smuzhiyun pNode->cursor = RefCursor(pCursor);
3524*4882a593Smuzhiyun }
3525*4882a593Smuzhiyun
3526*4882a593Smuzhiyun pNode = pPrev = NULL;
3527*4882a593Smuzhiyun /* fix up children */
3528*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
3529*4882a593Smuzhiyun if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
3530*4882a593Smuzhiyun if (pNode->cursor == None) { /* inherited from parent */
3531*4882a593Smuzhiyun pNode->cursor = RefCursor(pOldCursor);
3532*4882a593Smuzhiyun }
3533*4882a593Smuzhiyun else if (pNode->cursor == pCursor) {
3534*4882a593Smuzhiyun pNode->cursor = None;
3535*4882a593Smuzhiyun FreeCursor(pCursor, (Cursor) 0); /* fix up refcnt */
3536*4882a593Smuzhiyun }
3537*4882a593Smuzhiyun }
3538*4882a593Smuzhiyun }
3539*4882a593Smuzhiyun
3540*4882a593Smuzhiyun out:
3541*4882a593Smuzhiyun CursorVisible = TRUE;
3542*4882a593Smuzhiyun
3543*4882a593Smuzhiyun if (pWin->realized)
3544*4882a593Smuzhiyun WindowHasNewCursor(pWin);
3545*4882a593Smuzhiyun
3546*4882a593Smuzhiyun if (pOldCursor)
3547*4882a593Smuzhiyun FreeCursor(pOldCursor, (Cursor) 0);
3548*4882a593Smuzhiyun
3549*4882a593Smuzhiyun /* FIXME: We SHOULD check for an error value here XXX
3550*4882a593Smuzhiyun (comment taken from ChangeWindowAttributes) */
3551*4882a593Smuzhiyun (*pScreen->ChangeWindowAttributes) (pWin, CWCursor);
3552*4882a593Smuzhiyun
3553*4882a593Smuzhiyun return Success;
3554*4882a593Smuzhiyun }
3555*4882a593Smuzhiyun
3556*4882a593Smuzhiyun /* Get device cursor for given device or None if none is set */
3557*4882a593Smuzhiyun CursorPtr
WindowGetDeviceCursor(WindowPtr pWin,DeviceIntPtr pDev)3558*4882a593Smuzhiyun WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev)
3559*4882a593Smuzhiyun {
3560*4882a593Smuzhiyun DevCursorList pList;
3561*4882a593Smuzhiyun
3562*4882a593Smuzhiyun if (!pWin->optional || !pWin->optional->deviceCursors)
3563*4882a593Smuzhiyun return NULL;
3564*4882a593Smuzhiyun
3565*4882a593Smuzhiyun pList = pWin->optional->deviceCursors;
3566*4882a593Smuzhiyun
3567*4882a593Smuzhiyun while (pList) {
3568*4882a593Smuzhiyun if (pList->dev == pDev) {
3569*4882a593Smuzhiyun if (pList->cursor == None) /* inherited from parent */
3570*4882a593Smuzhiyun return WindowGetDeviceCursor(pWin->parent, pDev);
3571*4882a593Smuzhiyun else
3572*4882a593Smuzhiyun return pList->cursor;
3573*4882a593Smuzhiyun }
3574*4882a593Smuzhiyun pList = pList->next;
3575*4882a593Smuzhiyun }
3576*4882a593Smuzhiyun return NULL;
3577*4882a593Smuzhiyun }
3578*4882a593Smuzhiyun
3579*4882a593Smuzhiyun /* Searches for a DevCursorNode for the given window and device. If one is
3580*4882a593Smuzhiyun * found, return True and set pNode and pPrev to the node and to the node
3581*4882a593Smuzhiyun * before the node respectively. Otherwise return False.
3582*4882a593Smuzhiyun * If the device is the first in list, pPrev is set to NULL.
3583*4882a593Smuzhiyun */
3584*4882a593Smuzhiyun static Bool
WindowSeekDeviceCursor(WindowPtr pWin,DeviceIntPtr pDev,DevCursNodePtr * pNode,DevCursNodePtr * pPrev)3585*4882a593Smuzhiyun WindowSeekDeviceCursor(WindowPtr pWin,
3586*4882a593Smuzhiyun DeviceIntPtr pDev,
3587*4882a593Smuzhiyun DevCursNodePtr * pNode, DevCursNodePtr * pPrev)
3588*4882a593Smuzhiyun {
3589*4882a593Smuzhiyun DevCursorList pList;
3590*4882a593Smuzhiyun
3591*4882a593Smuzhiyun if (!pWin->optional)
3592*4882a593Smuzhiyun return FALSE;
3593*4882a593Smuzhiyun
3594*4882a593Smuzhiyun pList = pWin->optional->deviceCursors;
3595*4882a593Smuzhiyun
3596*4882a593Smuzhiyun if (pList && pList->dev == pDev) {
3597*4882a593Smuzhiyun *pNode = pList;
3598*4882a593Smuzhiyun *pPrev = NULL;
3599*4882a593Smuzhiyun return TRUE;
3600*4882a593Smuzhiyun }
3601*4882a593Smuzhiyun
3602*4882a593Smuzhiyun while (pList) {
3603*4882a593Smuzhiyun if (pList->next) {
3604*4882a593Smuzhiyun if (pList->next->dev == pDev) {
3605*4882a593Smuzhiyun *pNode = pList->next;
3606*4882a593Smuzhiyun *pPrev = pList;
3607*4882a593Smuzhiyun return TRUE;
3608*4882a593Smuzhiyun }
3609*4882a593Smuzhiyun }
3610*4882a593Smuzhiyun pList = pList->next;
3611*4882a593Smuzhiyun }
3612*4882a593Smuzhiyun return FALSE;
3613*4882a593Smuzhiyun }
3614*4882a593Smuzhiyun
3615*4882a593Smuzhiyun /* Return True if a parent has the same device cursor set or False if
3616*4882a593Smuzhiyun * otherwise
3617*4882a593Smuzhiyun */
3618*4882a593Smuzhiyun static Bool
WindowParentHasDeviceCursor(WindowPtr pWin,DeviceIntPtr pDev,CursorPtr pCursor)3619*4882a593Smuzhiyun WindowParentHasDeviceCursor(WindowPtr pWin,
3620*4882a593Smuzhiyun DeviceIntPtr pDev, CursorPtr pCursor)
3621*4882a593Smuzhiyun {
3622*4882a593Smuzhiyun WindowPtr pParent;
3623*4882a593Smuzhiyun DevCursNodePtr pParentNode, pParentPrev;
3624*4882a593Smuzhiyun
3625*4882a593Smuzhiyun pParent = pWin->parent;
3626*4882a593Smuzhiyun while (pParent) {
3627*4882a593Smuzhiyun if (WindowSeekDeviceCursor(pParent, pDev, &pParentNode, &pParentPrev)) {
3628*4882a593Smuzhiyun /* if there is a node in the list, the win has a dev cursor */
3629*4882a593Smuzhiyun if (!pParentNode->cursor) /* inherited. */
3630*4882a593Smuzhiyun pParent = pParent->parent;
3631*4882a593Smuzhiyun else if (pParentNode->cursor == pCursor) /* inherit */
3632*4882a593Smuzhiyun return TRUE;
3633*4882a593Smuzhiyun else /* different cursor */
3634*4882a593Smuzhiyun return FALSE;
3635*4882a593Smuzhiyun }
3636*4882a593Smuzhiyun else
3637*4882a593Smuzhiyun /* parent does not have a device cursor for our device */
3638*4882a593Smuzhiyun return FALSE;
3639*4882a593Smuzhiyun }
3640*4882a593Smuzhiyun return FALSE;
3641*4882a593Smuzhiyun }
3642*4882a593Smuzhiyun
3643*4882a593Smuzhiyun /*
3644*4882a593Smuzhiyun * SetRootClip --
3645*4882a593Smuzhiyun * Enable or disable rendering to the screen by
3646*4882a593Smuzhiyun * setting the root clip list and revalidating
3647*4882a593Smuzhiyun * all of the windows
3648*4882a593Smuzhiyun */
3649*4882a593Smuzhiyun void
SetRootClip(ScreenPtr pScreen,int enable)3650*4882a593Smuzhiyun SetRootClip(ScreenPtr pScreen, int enable)
3651*4882a593Smuzhiyun {
3652*4882a593Smuzhiyun WindowPtr pWin = pScreen->root;
3653*4882a593Smuzhiyun WindowPtr pChild;
3654*4882a593Smuzhiyun Bool WasViewable;
3655*4882a593Smuzhiyun Bool anyMarked = FALSE;
3656*4882a593Smuzhiyun WindowPtr pLayerWin;
3657*4882a593Smuzhiyun BoxRec box;
3658*4882a593Smuzhiyun enum RootClipMode mode = enable;
3659*4882a593Smuzhiyun
3660*4882a593Smuzhiyun if (!pWin)
3661*4882a593Smuzhiyun return;
3662*4882a593Smuzhiyun WasViewable = (Bool) (pWin->viewable);
3663*4882a593Smuzhiyun if (WasViewable) {
3664*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
3665*4882a593Smuzhiyun (void) (*pScreen->MarkOverlappedWindows) (pChild,
3666*4882a593Smuzhiyun pChild, &pLayerWin);
3667*4882a593Smuzhiyun }
3668*4882a593Smuzhiyun (*pScreen->MarkWindow) (pWin);
3669*4882a593Smuzhiyun anyMarked = TRUE;
3670*4882a593Smuzhiyun if (pWin->valdata) {
3671*4882a593Smuzhiyun if (HasBorder(pWin)) {
3672*4882a593Smuzhiyun RegionPtr borderVisible;
3673*4882a593Smuzhiyun
3674*4882a593Smuzhiyun borderVisible = RegionCreate(NullBox, 1);
3675*4882a593Smuzhiyun RegionSubtract(borderVisible,
3676*4882a593Smuzhiyun &pWin->borderClip, &pWin->winSize);
3677*4882a593Smuzhiyun pWin->valdata->before.borderVisible = borderVisible;
3678*4882a593Smuzhiyun }
3679*4882a593Smuzhiyun pWin->valdata->before.resized = TRUE;
3680*4882a593Smuzhiyun }
3681*4882a593Smuzhiyun }
3682*4882a593Smuzhiyun
3683*4882a593Smuzhiyun if (mode != ROOT_CLIP_NONE) {
3684*4882a593Smuzhiyun pWin->drawable.width = pScreen->width;
3685*4882a593Smuzhiyun pWin->drawable.height = pScreen->height;
3686*4882a593Smuzhiyun
3687*4882a593Smuzhiyun box.x1 = 0;
3688*4882a593Smuzhiyun box.y1 = 0;
3689*4882a593Smuzhiyun box.x2 = pScreen->width;
3690*4882a593Smuzhiyun box.y2 = pScreen->height;
3691*4882a593Smuzhiyun
3692*4882a593Smuzhiyun RegionInit(&pWin->winSize, &box, 1);
3693*4882a593Smuzhiyun RegionInit(&pWin->borderSize, &box, 1);
3694*4882a593Smuzhiyun
3695*4882a593Smuzhiyun /*
3696*4882a593Smuzhiyun * Use REGION_BREAK to avoid optimizations in ValidateTree
3697*4882a593Smuzhiyun * that assume the root borderClip can't change well, normally
3698*4882a593Smuzhiyun * it doesn't...)
3699*4882a593Smuzhiyun */
3700*4882a593Smuzhiyun RegionBreak(&pWin->clipList);
3701*4882a593Smuzhiyun
3702*4882a593Smuzhiyun /* For INPUT_ONLY, empty the borderClip so no rendering will ever
3703*4882a593Smuzhiyun * be attempted to the screen pixmap (only redirected windows),
3704*4882a593Smuzhiyun * but we keep borderSize as full regardless. */
3705*4882a593Smuzhiyun if (WasViewable && mode == ROOT_CLIP_FULL)
3706*4882a593Smuzhiyun RegionReset(&pWin->borderClip, &box);
3707*4882a593Smuzhiyun else
3708*4882a593Smuzhiyun RegionEmpty(&pWin->borderClip);
3709*4882a593Smuzhiyun }
3710*4882a593Smuzhiyun else {
3711*4882a593Smuzhiyun RegionEmpty(&pWin->borderClip);
3712*4882a593Smuzhiyun RegionBreak(&pWin->clipList);
3713*4882a593Smuzhiyun }
3714*4882a593Smuzhiyun
3715*4882a593Smuzhiyun ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
3716*4882a593Smuzhiyun
3717*4882a593Smuzhiyun if (WasViewable) {
3718*4882a593Smuzhiyun if (pWin->firstChild) {
3719*4882a593Smuzhiyun anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin->firstChild,
3720*4882a593Smuzhiyun pWin->firstChild,
3721*4882a593Smuzhiyun NULL);
3722*4882a593Smuzhiyun }
3723*4882a593Smuzhiyun else {
3724*4882a593Smuzhiyun (*pScreen->MarkWindow) (pWin);
3725*4882a593Smuzhiyun anyMarked = TRUE;
3726*4882a593Smuzhiyun }
3727*4882a593Smuzhiyun
3728*4882a593Smuzhiyun if (anyMarked) {
3729*4882a593Smuzhiyun (*pScreen->ValidateTree) (pWin, NullWindow, VTOther);
3730*4882a593Smuzhiyun (*pScreen->HandleExposures) (pWin);
3731*4882a593Smuzhiyun if (pScreen->PostValidateTree)
3732*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pWin, NullWindow, VTOther);
3733*4882a593Smuzhiyun }
3734*4882a593Smuzhiyun }
3735*4882a593Smuzhiyun if (pWin->realized)
3736*4882a593Smuzhiyun WindowsRestructured();
3737*4882a593Smuzhiyun FlushAllOutput();
3738*4882a593Smuzhiyun }
3739*4882a593Smuzhiyun
3740*4882a593Smuzhiyun VisualPtr
WindowGetVisual(WindowPtr pWin)3741*4882a593Smuzhiyun WindowGetVisual(WindowPtr pWin)
3742*4882a593Smuzhiyun {
3743*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
3744*4882a593Smuzhiyun VisualID vid = wVisual(pWin);
3745*4882a593Smuzhiyun int i;
3746*4882a593Smuzhiyun
3747*4882a593Smuzhiyun for (i = 0; i < pScreen->numVisuals; i++)
3748*4882a593Smuzhiyun if (pScreen->visuals[i].vid == vid)
3749*4882a593Smuzhiyun return &pScreen->visuals[i];
3750*4882a593Smuzhiyun return 0;
3751*4882a593Smuzhiyun }
3752