window.c revision 7e31ba66
105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright (c) 2006, Red Hat, Inc. 405b261ecSmrg 54202a189SmrgPermission is hereby granted, free of charge, to any person obtaining a 64202a189Smrgcopy of this software and associated documentation files (the "Software"), 74202a189Smrgto deal in the Software without restriction, including without limitation 84202a189Smrgthe rights to use, copy, modify, merge, publish, distribute, sublicense, 94202a189Smrgand/or sell copies of the Software, and to permit persons to whom the 104202a189SmrgSoftware is furnished to do so, subject to the following conditions: 1105b261ecSmrg 124202a189SmrgThe above copyright notice and this permission notice (including the next 134202a189Smrgparagraph) shall be included in all copies or substantial portions of the 144202a189SmrgSoftware. 1505b261ecSmrg 1605b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1705b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 184202a189SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 194202a189SmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 204202a189SmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 214202a189SmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 224202a189SmrgDEALINGS IN THE SOFTWARE. 2305b261ecSmrg 2405b261ecSmrgCopyright 1987, 1998 The Open Group 2505b261ecSmrg 2605b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 2705b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 2805b261ecSmrgthe above copyright notice appear in all copies and that both that 2905b261ecSmrgcopyright notice and this permission notice appear in supporting 3005b261ecSmrgdocumentation. 3105b261ecSmrg 3205b261ecSmrgThe above copyright notice and this permission notice shall be included 3305b261ecSmrgin all copies or substantial portions of the Software. 3405b261ecSmrg 3505b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 3605b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3705b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 3805b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 3905b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 4005b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 4105b261ecSmrgOTHER DEALINGS IN THE SOFTWARE. 4205b261ecSmrg 4305b261ecSmrgExcept as contained in this notice, the name of The Open Group shall 4405b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or 4505b261ecSmrgother dealings in this Software without prior written authorization 4605b261ecSmrgfrom The Open Group. 4705b261ecSmrg 4805b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, 4905b261ecSmrg 5005b261ecSmrg All Rights Reserved 5105b261ecSmrg 52f7df2e56SmrgPermission to use, copy, modify, and distribute this software and its 53f7df2e56Smrgdocumentation for any purpose and without fee is hereby granted, 5405b261ecSmrgprovided that the above copyright notice appear in all copies and that 55f7df2e56Smrgboth that copyright notice and this permission notice appear in 5605b261ecSmrgsupporting documentation, and that the name of Digital not be 5705b261ecSmrgused in advertising or publicity pertaining to distribution of the 58f7df2e56Smrgsoftware without specific, written prior permission. 5905b261ecSmrg 6005b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 6105b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 6205b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 6305b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 6405b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 6505b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 6605b261ecSmrgSOFTWARE. 6705b261ecSmrg 6805b261ecSmrg*/ 6905b261ecSmrg 7005b261ecSmrg/* The panoramix components contained the following notice */ 7105b261ecSmrg/***************************************************************** 7205b261ecSmrg 7305b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 7405b261ecSmrg 7505b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 7605b261ecSmrgof this software and associated documentation files (the "Software"), to deal 7705b261ecSmrgin the Software without restriction, including without limitation the rights 7805b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7905b261ecSmrgcopies of the Software. 8005b261ecSmrg 8105b261ecSmrgThe above copyright notice and this permission notice shall be included in 8205b261ecSmrgall copies or substantial portions of the Software. 8305b261ecSmrg 8405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8705b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 8805b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 8905b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 9005b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9105b261ecSmrg 9205b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 9305b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 9405b261ecSmrgdealings in this Software without prior written authorization from Digital 9505b261ecSmrgEquipment Corporation. 9605b261ecSmrg 9705b261ecSmrg******************************************************************/ 9805b261ecSmrg 9905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 10005b261ecSmrg#include <dix-config.h> 10105b261ecSmrg#endif 10205b261ecSmrg 10305b261ecSmrg#include "misc.h" 10405b261ecSmrg#include "scrnintstr.h" 10505b261ecSmrg#include "os.h" 10605b261ecSmrg#include "regionstr.h" 10705b261ecSmrg#include "validate.h" 10805b261ecSmrg#include "windowstr.h" 109f7df2e56Smrg#include "propertyst.h" 11005b261ecSmrg#include "input.h" 111637ac9abSmrg#include "inputstr.h" 11205b261ecSmrg#include "resource.h" 11305b261ecSmrg#include "colormapst.h" 11405b261ecSmrg#include "cursorstr.h" 11505b261ecSmrg#include "dixstruct.h" 11605b261ecSmrg#include "gcstruct.h" 11705b261ecSmrg#include "servermd.h" 118f7df2e56Smrg#include "mivalidate.h" 11905b261ecSmrg#ifdef PANORAMIX 12005b261ecSmrg#include "panoramiX.h" 12105b261ecSmrg#include "panoramiXsrv.h" 12205b261ecSmrg#endif 12305b261ecSmrg#include "dixevents.h" 12405b261ecSmrg#include "globals.h" 125f7df2e56Smrg#include "mi.h" /* miPaintWindow */ 126f7df2e56Smrg#ifdef COMPOSITE 127f7df2e56Smrg#include "compint.h" 128f7df2e56Smrg#endif 129f7df2e56Smrg#include "selection.h" 130f7df2e56Smrg#include "inpututils.h" 13105b261ecSmrg 132637ac9abSmrg#include "privates.h" 13305b261ecSmrg#include "xace.h" 134f7df2e56Smrg#include "exevents.h" 135f7df2e56Smrg 136f7df2e56Smrg#include <X11/Xatom.h> /* must come after server includes */ 13705b261ecSmrg 13805b261ecSmrg/****** 139f7df2e56Smrg * Window stuff for server 14005b261ecSmrg * 14105b261ecSmrg * CreateRootWindow, CreateWindow, ChangeWindowAttributes, 14205b261ecSmrg * GetWindowAttributes, DeleteWindow, DestroySubWindows, 14305b261ecSmrg * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, 14405b261ecSmrg * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, 145637ac9abSmrg * ChangeWindowDeviceCursor 14605b261ecSmrg ******/ 14705b261ecSmrg 14865b04b38SmrgBool bgNoneRoot = FALSE; 14965b04b38Smrg 150f7df2e56Smrgstatic unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 }; 151f7df2e56Smrgstatic unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 }; 152f7df2e56Smrg 153f7df2e56Smrgstatic Bool WindowParentHasDeviceCursor(WindowPtr pWin, 154f7df2e56Smrg DeviceIntPtr pDev, CursorPtr pCurs); 155f7df2e56Smrgstatic Bool 15605b261ecSmrg 157f7df2e56SmrgWindowSeekDeviceCursor(WindowPtr pWin, 158f7df2e56Smrg DeviceIntPtr pDev, 159f7df2e56Smrg DevCursNodePtr * pNode, DevCursNodePtr * pPrev); 160637ac9abSmrg 1614202a189Smrgint screenIsSaved = SCREEN_SAVER_OFF; 16205b261ecSmrg 1634202a189Smrgstatic Bool TileScreenSaver(ScreenPtr pScreen, int kind); 16405b261ecSmrg 16505b261ecSmrg#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ 16605b261ecSmrg CWDontPropagate | CWOverrideRedirect | CWCursor ) 16705b261ecSmrg 16805b261ecSmrg#define BOXES_OVERLAP(b1, b2) \ 16905b261ecSmrg (!( ((b1)->x2 <= (b2)->x1) || \ 17005b261ecSmrg ( ((b1)->x1 >= (b2)->x2)) || \ 17105b261ecSmrg ( ((b1)->y2 <= (b2)->y1)) || \ 17205b261ecSmrg ( ((b1)->y1 >= (b2)->y2)) ) ) 17305b261ecSmrg 17405b261ecSmrg#define RedirectSend(pWin) \ 17505b261ecSmrg ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask) 17605b261ecSmrg 17705b261ecSmrg#define SubSend(pWin) \ 17805b261ecSmrg ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) 17905b261ecSmrg 18005b261ecSmrg#define StrSend(pWin) \ 18105b261ecSmrg ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) 18205b261ecSmrg 18305b261ecSmrg#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) 18405b261ecSmrg 185f7df2e56Smrg#ifdef COMPOSITE 186f7df2e56Smrgstatic const char *overlay_win_name = "<composite overlay>"; 187f7df2e56Smrg#endif 188f7df2e56Smrg 189f7df2e56Smrgstatic const char * 190f7df2e56Smrgget_window_name(WindowPtr pWin) 191f7df2e56Smrg{ 192f7df2e56Smrg#define WINDOW_NAME_BUF_LEN 512 193f7df2e56Smrg PropertyPtr prop; 194f7df2e56Smrg static char buf[WINDOW_NAME_BUF_LEN]; 195f7df2e56Smrg int len; 196f7df2e56Smrg 197f7df2e56Smrg#ifdef COMPOSITE 198f7df2e56Smrg CompScreenPtr comp_screen = GetCompScreen(pWin->drawable.pScreen); 199f7df2e56Smrg 200f7df2e56Smrg if (comp_screen && pWin == comp_screen->pOverlayWin) 201f7df2e56Smrg return overlay_win_name; 202f7df2e56Smrg#endif 203f7df2e56Smrg 204f7df2e56Smrg for (prop = wUserProps(pWin); prop; prop = prop->next) { 205f7df2e56Smrg if (prop->propertyName == XA_WM_NAME && prop->type == XA_STRING && 206f7df2e56Smrg prop->data) { 207f7df2e56Smrg len = min(prop->size, WINDOW_NAME_BUF_LEN - 1); 208f7df2e56Smrg memcpy(buf, prop->data, len); 209f7df2e56Smrg buf[len] = '\0'; 210f7df2e56Smrg return buf; 211f7df2e56Smrg } 212f7df2e56Smrg } 213f7df2e56Smrg 214f7df2e56Smrg return NULL; 215f7df2e56Smrg#undef WINDOW_NAME_BUF_LEN 216f7df2e56Smrg} 21705b261ecSmrg 21805b261ecSmrgstatic void 219f7df2e56Smrglog_window_info(WindowPtr pWin, int depth) 22005b261ecSmrg{ 22105b261ecSmrg int i; 222f7df2e56Smrg const char *win_name, *visibility; 223f7df2e56Smrg BoxPtr rects; 224f7df2e56Smrg 225f7df2e56Smrg for (i = 0; i < (depth << 2); i++) 226f7df2e56Smrg ErrorF(" "); 227f7df2e56Smrg 228f7df2e56Smrg win_name = get_window_name(pWin); 229f7df2e56Smrg ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]", 230f7df2e56Smrg (unsigned) pWin->drawable.id, 231f7df2e56Smrg win_name ? win_name : "no name", 232f7df2e56Smrg pWin->drawable.x, pWin->drawable.y, 233f7df2e56Smrg pWin->drawable.x + pWin->drawable.width, 234f7df2e56Smrg pWin->drawable.y + pWin->drawable.height); 235f7df2e56Smrg 236f7df2e56Smrg if (pWin->overrideRedirect) 237f7df2e56Smrg ErrorF(" (override redirect)"); 238f7df2e56Smrg#ifdef COMPOSITE 239f7df2e56Smrg if (pWin->redirectDraw) 240f7df2e56Smrg ErrorF(" (%s compositing: pixmap %x)", 241f7df2e56Smrg (pWin->redirectDraw == RedirectDrawAutomatic) ? 242f7df2e56Smrg "automatic" : "manual", 243f7df2e56Smrg (unsigned) pWin->drawable.pScreen->GetWindowPixmap(pWin)->drawable.id); 244f7df2e56Smrg#endif 24505b261ecSmrg 246f7df2e56Smrg switch (pWin->visibility) { 247f7df2e56Smrg case VisibilityUnobscured: 248f7df2e56Smrg visibility = "unobscured"; 249f7df2e56Smrg break; 250f7df2e56Smrg case VisibilityPartiallyObscured: 251f7df2e56Smrg visibility = "partially obscured"; 252f7df2e56Smrg break; 253f7df2e56Smrg case VisibilityFullyObscured: 254f7df2e56Smrg visibility = "fully obscured"; 255f7df2e56Smrg break; 256f7df2e56Smrg case VisibilityNotViewable: 257f7df2e56Smrg visibility = "unviewable"; 258f7df2e56Smrg break; 259f7df2e56Smrg } 260f7df2e56Smrg ErrorF(", %s", visibility); 261f7df2e56Smrg 262f7df2e56Smrg if (RegionNotEmpty(&pWin->clipList)) { 263f7df2e56Smrg ErrorF(", clip list:"); 264f7df2e56Smrg rects = RegionRects(&pWin->clipList); 265f7df2e56Smrg for (i = 0; i < RegionNumRects(&pWin->clipList); i++) 266f7df2e56Smrg ErrorF(" [(%d, %d) to (%d, %d)]", 267f7df2e56Smrg rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); 268f7df2e56Smrg ErrorF("; extents [(%d, %d) to (%d, %d)]", 269f7df2e56Smrg pWin->clipList.extents.x1, pWin->clipList.extents.y1, 270f7df2e56Smrg pWin->clipList.extents.x2, pWin->clipList.extents.y2); 271f7df2e56Smrg } 272f7df2e56Smrg 273f7df2e56Smrg ErrorF("\n"); 274f7df2e56Smrg} 275f7df2e56Smrg 276f7df2e56Smrgstatic const char* 277f7df2e56Smrggrab_grabtype_to_text(GrabPtr pGrab) 278f7df2e56Smrg{ 279f7df2e56Smrg switch (pGrab->grabtype) { 280f7df2e56Smrg case XI2: 281f7df2e56Smrg return "xi2"; 282f7df2e56Smrg case CORE: 283f7df2e56Smrg return "core"; 284f7df2e56Smrg default: 285f7df2e56Smrg return "xi1"; 286f7df2e56Smrg } 287f7df2e56Smrg} 288f7df2e56Smrg 289f7df2e56Smrgstatic const char* 290f7df2e56Smrggrab_type_to_text(GrabPtr pGrab) 291f7df2e56Smrg{ 292f7df2e56Smrg switch (pGrab->type) { 293f7df2e56Smrg case ButtonPress: 294f7df2e56Smrg return "ButtonPress"; 295f7df2e56Smrg case KeyPress: 296f7df2e56Smrg return "KeyPress"; 297f7df2e56Smrg case XI_Enter: 298f7df2e56Smrg return "XI_Enter"; 299f7df2e56Smrg case XI_FocusIn: 300f7df2e56Smrg return "XI_FocusIn"; 301f7df2e56Smrg default: 302f7df2e56Smrg return "unknown?!"; 30305b261ecSmrg } 30405b261ecSmrg} 30505b261ecSmrg 30605b261ecSmrgstatic void 307f7df2e56Smrglog_grab_info(void *value, XID id, void *cdata) 308f7df2e56Smrg{ 309f7df2e56Smrg int i, j; 310f7df2e56Smrg GrabPtr pGrab = (GrabPtr)value; 311f7df2e56Smrg 312f7df2e56Smrg ErrorF(" grab 0x%lx (%s), type '%s' on window 0x%lx\n", 313f7df2e56Smrg (unsigned long) pGrab->resource, 314f7df2e56Smrg grab_grabtype_to_text(pGrab), 315f7df2e56Smrg grab_type_to_text(pGrab), 316f7df2e56Smrg (unsigned long) pGrab->window->drawable.id); 317f7df2e56Smrg ErrorF(" detail %d (mask %lu), modifiersDetail %d (mask %lu)\n", 318f7df2e56Smrg pGrab->detail.exact, 319f7df2e56Smrg pGrab->detail.pMask ? (unsigned long) *(pGrab->detail.pMask) : 0, 320f7df2e56Smrg pGrab->modifiersDetail.exact, 321f7df2e56Smrg pGrab->modifiersDetail.pMask ? 322f7df2e56Smrg (unsigned long) *(pGrab->modifiersDetail.pMask) : 323f7df2e56Smrg (unsigned long) 0); 324f7df2e56Smrg ErrorF(" device '%s' (%d), modifierDevice '%s' (%d)\n", 325f7df2e56Smrg pGrab->device->name, pGrab->device->id, 326f7df2e56Smrg pGrab->modifierDevice->name, pGrab->modifierDevice->id); 327f7df2e56Smrg if (pGrab->grabtype == CORE) { 328f7df2e56Smrg ErrorF(" core event mask 0x%lx\n", 329f7df2e56Smrg (unsigned long) pGrab->eventMask); 330f7df2e56Smrg } 331f7df2e56Smrg else if (pGrab->grabtype == XI) { 332f7df2e56Smrg ErrorF(" xi1 event mask 0x%lx\n", 333f7df2e56Smrg (unsigned long) pGrab->eventMask); 334f7df2e56Smrg } 335f7df2e56Smrg else if (pGrab->grabtype == XI2) { 336f7df2e56Smrg for (i = 0; i < xi2mask_num_masks(pGrab->xi2mask); i++) { 337f7df2e56Smrg const unsigned char *mask; 338f7df2e56Smrg int print; 339f7df2e56Smrg 340f7df2e56Smrg print = 0; 341f7df2e56Smrg for (j = 0; j < XI2MASKSIZE; j++) { 342f7df2e56Smrg mask = xi2mask_get_one_mask(pGrab->xi2mask, i); 343f7df2e56Smrg if (mask[j]) { 344f7df2e56Smrg print = 1; 345f7df2e56Smrg break; 346f7df2e56Smrg } 347f7df2e56Smrg } 348f7df2e56Smrg if (!print) 349f7df2e56Smrg continue; 350f7df2e56Smrg ErrorF(" xi2 event mask 0x"); 351f7df2e56Smrg for (j = 0; j < xi2mask_mask_size(pGrab->xi2mask); j++) 352f7df2e56Smrg ErrorF("%x ", mask[j]); 353f7df2e56Smrg ErrorF("\n"); 354f7df2e56Smrg } 355f7df2e56Smrg } 356f7df2e56Smrg ErrorF(" owner-events %s, kb %d ptr %d, confine 0x%lx, cursor 0x%lx\n", 357f7df2e56Smrg pGrab->ownerEvents ? "true" : "false", 358f7df2e56Smrg pGrab->keyboardMode, pGrab->pointerMode, 359f7df2e56Smrg pGrab->confineTo ? (unsigned long) pGrab->confineTo->drawable.id : 0, 360f7df2e56Smrg pGrab->cursor ? (unsigned long) pGrab->cursor->id : 0); 361f7df2e56Smrg} 362f7df2e56Smrg 363f7df2e56Smrgvoid 364f7df2e56SmrgPrintPassiveGrabs(void) 36505b261ecSmrg{ 36605b261ecSmrg int i; 367f7df2e56Smrg LocalClientCredRec *lcc; 368f7df2e56Smrg pid_t clientpid; 369f7df2e56Smrg const char *cmdname; 370f7df2e56Smrg const char *cmdargs; 371f7df2e56Smrg 372f7df2e56Smrg ErrorF("Printing all currently registered grabs\n"); 373f7df2e56Smrg 374f7df2e56Smrg for (i = 1; i < currentMaxClients; i++) { 375f7df2e56Smrg if (!clients[i] || clients[i]->clientState != ClientStateRunning) 376f7df2e56Smrg continue; 377f7df2e56Smrg 378f7df2e56Smrg clientpid = GetClientPid(clients[i]); 379f7df2e56Smrg cmdname = GetClientCmdName(clients[i]); 380f7df2e56Smrg cmdargs = GetClientCmdArgs(clients[i]); 381f7df2e56Smrg if ((clientpid > 0) && (cmdname != NULL)) { 382f7df2e56Smrg ErrorF(" Printing all registered grabs of client pid %ld %s %s\n", 383f7df2e56Smrg (long) clientpid, cmdname, cmdargs ? cmdargs : ""); 384f7df2e56Smrg } else { 385f7df2e56Smrg if (GetLocalClientCreds(clients[i], &lcc) == -1) { 386f7df2e56Smrg ErrorF(" GetLocalClientCreds() failed\n"); 387f7df2e56Smrg continue; 388f7df2e56Smrg } 389f7df2e56Smrg ErrorF(" Printing all registered grabs of client pid %ld uid %ld gid %ld\n", 390f7df2e56Smrg (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, 391f7df2e56Smrg (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, 392f7df2e56Smrg (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); 393f7df2e56Smrg FreeLocalClientCreds(lcc); 394f7df2e56Smrg } 39505b261ecSmrg 396f7df2e56Smrg FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, log_grab_info, NULL); 397f7df2e56Smrg } 398f7df2e56Smrg ErrorF("End list of registered passive grabs\n"); 399f7df2e56Smrg} 400f7df2e56Smrg 401f7df2e56Smrgvoid 402f7df2e56SmrgPrintWindowTree(void) 403f7df2e56Smrg{ 404f7df2e56Smrg int scrnum, depth; 405f7df2e56Smrg ScreenPtr pScreen; 406f7df2e56Smrg WindowPtr pWin; 407f7df2e56Smrg 408f7df2e56Smrg for (scrnum = 0; scrnum < screenInfo.numScreens; scrnum++) { 409f7df2e56Smrg pScreen = screenInfo.screens[scrnum]; 410f7df2e56Smrg ErrorF("[dix] Dumping windows for screen %d (pixmap %x):\n", scrnum, 411f7df2e56Smrg (unsigned) pScreen->GetScreenPixmap(pScreen)->drawable.id); 412f7df2e56Smrg pWin = pScreen->root; 413f7df2e56Smrg depth = 1; 414f7df2e56Smrg while (pWin) { 415f7df2e56Smrg log_window_info(pWin, depth); 416f7df2e56Smrg if (pWin->firstChild) { 417f7df2e56Smrg pWin = pWin->firstChild; 418f7df2e56Smrg depth++; 419f7df2e56Smrg continue; 420f7df2e56Smrg } 421f7df2e56Smrg while (pWin && !pWin->nextSib) { 422f7df2e56Smrg pWin = pWin->parent; 423f7df2e56Smrg depth--; 424f7df2e56Smrg } 425f7df2e56Smrg if (!pWin) 426f7df2e56Smrg break; 427f7df2e56Smrg pWin = pWin->nextSib; 428f7df2e56Smrg } 42905b261ecSmrg } 43005b261ecSmrg} 43105b261ecSmrg 4324202a189Smrgint 433f7df2e56SmrgTraverseTree(WindowPtr pWin, VisitWindowProcPtr func, void *data) 43405b261ecSmrg{ 43505b261ecSmrg int result; 43605b261ecSmrg WindowPtr pChild; 43705b261ecSmrg 43805b261ecSmrg if (!(pChild = pWin)) 439f7df2e56Smrg return WT_NOMATCH; 440f7df2e56Smrg while (1) { 441f7df2e56Smrg result = (*func) (pChild, data); 442f7df2e56Smrg if (result == WT_STOPWALKING) 443f7df2e56Smrg return WT_STOPWALKING; 444f7df2e56Smrg if ((result == WT_WALKCHILDREN) && pChild->firstChild) { 445f7df2e56Smrg pChild = pChild->firstChild; 446f7df2e56Smrg continue; 447f7df2e56Smrg } 448f7df2e56Smrg while (!pChild->nextSib && (pChild != pWin)) 449f7df2e56Smrg pChild = pChild->parent; 450f7df2e56Smrg if (pChild == pWin) 451f7df2e56Smrg break; 452f7df2e56Smrg pChild = pChild->nextSib; 45305b261ecSmrg } 4544202a189Smrg return WT_NOMATCH; 45505b261ecSmrg} 45605b261ecSmrg 45705b261ecSmrg/***** 45805b261ecSmrg * WalkTree 4597e31ba66Smrg * Walk the window tree, for SCREEN, performing FUNC(pWin, data) on 46005b261ecSmrg * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, 4617e31ba66Smrg * if it returns WT_DONTWALKCHILDREN, don't. If it returns WT_STOPWALKING, 46205b261ecSmrg * exit WalkTree. Does depth-first traverse. 46305b261ecSmrg *****/ 46405b261ecSmrg 4654202a189Smrgint 466f7df2e56SmrgWalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void *data) 46705b261ecSmrg{ 468f7df2e56Smrg return (TraverseTree(pScreen->root, func, data)); 46905b261ecSmrg} 47005b261ecSmrg 47105b261ecSmrg/* hack for forcing backing store on all windows */ 472f7df2e56Smrgint defaultBackingStore = NotUseful; 473f7df2e56Smrg 47405b261ecSmrg/* hack to force no backing store */ 475f7df2e56SmrgBool disableBackingStore = FALSE; 476f7df2e56SmrgBool enableBackingStore = FALSE; 47705b261ecSmrg 47805b261ecSmrgstatic void 47905b261ecSmrgSetWindowToDefaults(WindowPtr pWin) 48005b261ecSmrg{ 48105b261ecSmrg pWin->prevSib = NullWindow; 48205b261ecSmrg pWin->firstChild = NullWindow; 48305b261ecSmrg pWin->lastChild = NullWindow; 48405b261ecSmrg 485f7df2e56Smrg pWin->valdata = NULL; 486f7df2e56Smrg pWin->optional = NULL; 48705b261ecSmrg pWin->cursorIsNone = TRUE; 48805b261ecSmrg 48905b261ecSmrg pWin->backingStore = NotUseful; 490f7df2e56Smrg pWin->backStorage = 0; 49105b261ecSmrg 492f7df2e56Smrg pWin->mapped = FALSE; /* off */ 493f7df2e56Smrg pWin->realized = FALSE; /* off */ 49405b261ecSmrg pWin->viewable = FALSE; 49505b261ecSmrg pWin->visibility = VisibilityNotViewable; 49605b261ecSmrg pWin->overrideRedirect = FALSE; 49705b261ecSmrg pWin->saveUnder = FALSE; 49805b261ecSmrg 49905b261ecSmrg pWin->bitGravity = ForgetGravity; 50005b261ecSmrg pWin->winGravity = NorthWestGravity; 50105b261ecSmrg 50205b261ecSmrg pWin->eventMask = 0; 50305b261ecSmrg pWin->deliverableEvents = 0; 50405b261ecSmrg pWin->dontPropagate = 0; 50505b261ecSmrg pWin->forcedBS = FALSE; 50605b261ecSmrg pWin->redirectDraw = RedirectDrawNone; 507637ac9abSmrg pWin->forcedBG = FALSE; 508f7df2e56Smrg pWin->unhittable = FALSE; 50965b04b38Smrg 51065b04b38Smrg#ifdef COMPOSITE 51165b04b38Smrg pWin->damagedDescendants = FALSE; 51265b04b38Smrg#endif 51305b261ecSmrg} 51405b261ecSmrg 51505b261ecSmrgstatic void 51605b261ecSmrgMakeRootTile(WindowPtr pWin) 51705b261ecSmrg{ 51805b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 51905b261ecSmrg GCPtr pGC; 52005b261ecSmrg unsigned char back[128]; 52105b261ecSmrg int len = BitmapBytePad(sizeof(long)); 52205b261ecSmrg unsigned char *from, *to; 52305b261ecSmrg int i, j; 52405b261ecSmrg 525f7df2e56Smrg pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4, 526f7df2e56Smrg pScreen->rootDepth, 0); 52705b261ecSmrg 52805b261ecSmrg pWin->backgroundState = BackgroundPixmap; 52905b261ecSmrg pGC = GetScratchGC(pScreen->rootDepth, pScreen); 53005b261ecSmrg if (!pWin->background.pixmap || !pGC) 531f7df2e56Smrg FatalError("could not create root tile"); 53205b261ecSmrg 53305b261ecSmrg { 534f7df2e56Smrg ChangeGCVal attributes[2]; 53505b261ecSmrg 536f7df2e56Smrg attributes[0].val = pScreen->whitePixel; 537f7df2e56Smrg attributes[1].val = pScreen->blackPixel; 53805b261ecSmrg 539f7df2e56Smrg (void) ChangeGC(NullClient, pGC, GCForeground | GCBackground, 540f7df2e56Smrg attributes); 54105b261ecSmrg } 54205b261ecSmrg 543f7df2e56Smrg ValidateGC((DrawablePtr) pWin->background.pixmap, pGC); 54405b261ecSmrg 545f7df2e56Smrg from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; 546f7df2e56Smrg to = back; 54705b261ecSmrg 548f7df2e56Smrg for (i = 4; i > 0; i--, from++) 549f7df2e56Smrg for (j = len; j > 0; j--) 550f7df2e56Smrg *to++ = *from; 55105b261ecSmrg 552f7df2e56Smrg (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1, 553f7df2e56Smrg 0, 0, len, 4, 0, XYBitmap, (char *) back); 55405b261ecSmrg 555f7df2e56Smrg FreeScratchGC(pGC); 55605b261ecSmrg 55705b261ecSmrg} 55805b261ecSmrg 55905b261ecSmrg/***** 56005b261ecSmrg * CreateRootWindow 56105b261ecSmrg * Makes a window at initialization time for specified screen 56205b261ecSmrg *****/ 56305b261ecSmrg 56405b261ecSmrgBool 56505b261ecSmrgCreateRootWindow(ScreenPtr pScreen) 56605b261ecSmrg{ 567f7df2e56Smrg WindowPtr pWin; 568f7df2e56Smrg BoxRec box; 56905b261ecSmrg PixmapFormatRec *format; 57005b261ecSmrg 571f7df2e56Smrg pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); 57205b261ecSmrg if (!pWin) 573f7df2e56Smrg return FALSE; 57405b261ecSmrg 5754202a189Smrg pScreen->screensaver.pWindow = NULL; 5764202a189Smrg pScreen->screensaver.wid = FakeClientID(0); 5774202a189Smrg pScreen->screensaver.ExternalScreenSaver = NULL; 57805b261ecSmrg screenIsSaved = SCREEN_SAVER_OFF; 57905b261ecSmrg 5804202a189Smrg pScreen->root = pWin; 58105b261ecSmrg 58205b261ecSmrg pWin->drawable.pScreen = pScreen; 58305b261ecSmrg pWin->drawable.type = DRAWABLE_WINDOW; 58405b261ecSmrg 58505b261ecSmrg pWin->drawable.depth = pScreen->rootDepth; 58605b261ecSmrg for (format = screenInfo.formats; 587f7df2e56Smrg format->depth != pScreen->rootDepth; format++); 58805b261ecSmrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 58905b261ecSmrg 59005b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 59105b261ecSmrg 59205b261ecSmrg pWin->parent = NullWindow; 59305b261ecSmrg SetWindowToDefaults(pWin); 59405b261ecSmrg 595f7df2e56Smrg pWin->optional = malloc(sizeof(WindowOptRec)); 59605b261ecSmrg if (!pWin->optional) 59705b261ecSmrg return FALSE; 59805b261ecSmrg 59905b261ecSmrg pWin->optional->dontPropagateMask = 0; 60005b261ecSmrg pWin->optional->otherEventMasks = 0; 60105b261ecSmrg pWin->optional->otherClients = NULL; 60205b261ecSmrg pWin->optional->passiveGrabs = NULL; 60305b261ecSmrg pWin->optional->userProps = NULL; 60405b261ecSmrg pWin->optional->backingBitPlanes = ~0L; 60505b261ecSmrg pWin->optional->backingPixel = 0; 60605b261ecSmrg pWin->optional->boundingShape = NULL; 60705b261ecSmrg pWin->optional->clipShape = NULL; 60805b261ecSmrg pWin->optional->inputShape = NULL; 60905b261ecSmrg pWin->optional->inputMasks = NULL; 610637ac9abSmrg pWin->optional->deviceCursors = NULL; 61105b261ecSmrg pWin->optional->colormap = pScreen->defColormap; 61205b261ecSmrg pWin->optional->visual = pScreen->rootVisual; 61305b261ecSmrg 61405b261ecSmrg pWin->nextSib = NullWindow; 61505b261ecSmrg 61605b261ecSmrg pWin->drawable.id = FakeClientID(0); 61705b261ecSmrg 61805b261ecSmrg pWin->origin.x = pWin->origin.y = 0; 61905b261ecSmrg pWin->drawable.height = pScreen->height; 62005b261ecSmrg pWin->drawable.width = pScreen->width; 62105b261ecSmrg pWin->drawable.x = pWin->drawable.y = 0; 62205b261ecSmrg 62305b261ecSmrg box.x1 = 0; 62405b261ecSmrg box.y1 = 0; 62505b261ecSmrg box.x2 = pScreen->width; 62605b261ecSmrg box.y2 = pScreen->height; 6274202a189Smrg RegionInit(&pWin->clipList, &box, 1); 6284202a189Smrg RegionInit(&pWin->winSize, &box, 1); 6294202a189Smrg RegionInit(&pWin->borderSize, &box, 1); 6304202a189Smrg RegionInit(&pWin->borderClip, &box, 1); 63105b261ecSmrg 63205b261ecSmrg pWin->drawable.class = InputOutput; 63305b261ecSmrg pWin->optional->visual = pScreen->rootVisual; 63405b261ecSmrg 63505b261ecSmrg pWin->backgroundState = BackgroundPixel; 63605b261ecSmrg pWin->background.pixel = pScreen->whitePixel; 63705b261ecSmrg 63805b261ecSmrg pWin->borderIsPixel = TRUE; 63905b261ecSmrg pWin->border.pixel = pScreen->blackPixel; 64005b261ecSmrg pWin->borderWidth = 0; 64105b261ecSmrg 642637ac9abSmrg /* security creation/labeling check 643637ac9abSmrg */ 644637ac9abSmrg if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id, 645f7df2e56Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess)) 646f7df2e56Smrg return FALSE; 647637ac9abSmrg 648f7df2e56Smrg if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin)) 649f7df2e56Smrg return FALSE; 65005b261ecSmrg 65105b261ecSmrg if (disableBackingStore) 652f7df2e56Smrg pScreen->backingStoreSupport = NotUseful; 65305b261ecSmrg if (enableBackingStore) 654f7df2e56Smrg pScreen->backingStoreSupport = WhenMapped; 655f7df2e56Smrg#ifdef COMPOSITE 656f7df2e56Smrg if (noCompositeExtension) 657f7df2e56Smrg pScreen->backingStoreSupport = NotUseful; 658f7df2e56Smrg#endif 65905b261ecSmrg 660637ac9abSmrg pScreen->saveUnderSupport = NotUseful; 66105b261ecSmrg 66205b261ecSmrg return TRUE; 66305b261ecSmrg} 66405b261ecSmrg 66505b261ecSmrgvoid 66605b261ecSmrgInitRootWindow(WindowPtr pWin) 66705b261ecSmrg{ 66805b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 66905b261ecSmrg int backFlag = CWBorderPixel | CWCursor | CWBackingStore; 67005b261ecSmrg 671f7df2e56Smrg if (!(*pScreen->CreateWindow) (pWin)) 672f7df2e56Smrg return; /* XXX */ 673f7df2e56Smrg (*pScreen->PositionWindow) (pWin, 0, 0); 67405b261ecSmrg 67505b261ecSmrg pWin->cursorIsNone = FALSE; 676f7df2e56Smrg pWin->optional->cursor = RefCursor(rootCursor); 677637ac9abSmrg 678637ac9abSmrg if (party_like_its_1989) { 67905b261ecSmrg MakeRootTile(pWin); 68005b261ecSmrg backFlag |= CWBackPixmap; 681f7df2e56Smrg } 682f7df2e56Smrg else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { 68365b04b38Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 68465b04b38Smrg pWin->background.pixel = pScreen->whitePixel; 68565b04b38Smrg backFlag |= CWBackPixmap; 686f7df2e56Smrg } 687f7df2e56Smrg else { 68865b04b38Smrg pWin->backgroundState = BackgroundPixel; 689f7df2e56Smrg if (whiteRoot) 69005b261ecSmrg pWin->background.pixel = pScreen->whitePixel; 691637ac9abSmrg else 692637ac9abSmrg pWin->background.pixel = pScreen->blackPixel; 69305b261ecSmrg backFlag |= CWBackPixel; 694f7df2e56Smrg } 69505b261ecSmrg 69605b261ecSmrg pWin->backingStore = defaultBackingStore; 69705b261ecSmrg pWin->forcedBS = (defaultBackingStore != NotUseful); 69805b261ecSmrg /* We SHOULD check for an error value here XXX */ 699f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, backFlag); 70005b261ecSmrg 70105b261ecSmrg MapWindow(pWin, serverClient); 70205b261ecSmrg} 70305b261ecSmrg 70405b261ecSmrg/* Set the region to the intersection of the rectangle and the 70505b261ecSmrg * window's winSize. The window is typically the parent of the 70605b261ecSmrg * window from which the region came. 70705b261ecSmrg */ 70805b261ecSmrg 70905b261ecSmrgstatic void 710f7df2e56SmrgClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, int x, int y, int w, int h) 71105b261ecSmrg{ 7124202a189Smrg BoxRec box = *RegionExtents(&pWin->winSize); 71305b261ecSmrg 71405b261ecSmrg /* we do these calculations to avoid overflows */ 71505b261ecSmrg if (x > box.x1) 716f7df2e56Smrg box.x1 = x; 71705b261ecSmrg if (y > box.y1) 718f7df2e56Smrg box.y1 = y; 71905b261ecSmrg x += w; 72005b261ecSmrg if (x < box.x2) 721f7df2e56Smrg box.x2 = x; 72205b261ecSmrg y += h; 72305b261ecSmrg if (y < box.y2) 724f7df2e56Smrg box.y2 = y; 72505b261ecSmrg if (box.x1 > box.x2) 726f7df2e56Smrg box.x2 = box.x1; 72705b261ecSmrg if (box.y1 > box.y2) 728f7df2e56Smrg box.y2 = box.y1; 7294202a189Smrg RegionReset(Rgn, &box); 7304202a189Smrg RegionIntersect(Rgn, Rgn, &pWin->winSize); 73105b261ecSmrg} 73205b261ecSmrg 73305b261ecSmrgstatic RealChildHeadProc realChildHeadProc = NULL; 73405b261ecSmrg 73505b261ecSmrgvoid 736f7df2e56SmrgRegisterRealChildHeadProc(RealChildHeadProc proc) 73705b261ecSmrg{ 73805b261ecSmrg realChildHeadProc = proc; 73905b261ecSmrg} 74005b261ecSmrg 74105b261ecSmrgWindowPtr 74205b261ecSmrgRealChildHead(WindowPtr pWin) 74305b261ecSmrg{ 74405b261ecSmrg if (realChildHeadProc) { 745f7df2e56Smrg return realChildHeadProc(pWin); 74605b261ecSmrg } 74705b261ecSmrg 74805b261ecSmrg if (!pWin->parent && 749f7df2e56Smrg (screenIsSaved == SCREEN_SAVER_ON) && 750f7df2e56Smrg (HasSaverWindow(pWin->drawable.pScreen))) 751f7df2e56Smrg return pWin->firstChild; 75205b261ecSmrg else 753f7df2e56Smrg return NullWindow; 75405b261ecSmrg} 75505b261ecSmrg 75605b261ecSmrg/***** 75705b261ecSmrg * CreateWindow 758f7df2e56Smrg * Makes a window in response to client request 75905b261ecSmrg *****/ 76005b261ecSmrg 7614202a189SmrgWindowPtr 76205b261ecSmrgCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, 76305b261ecSmrg unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, 76405b261ecSmrg int depth, ClientPtr client, VisualID visual, int *error) 76505b261ecSmrg{ 76605b261ecSmrg WindowPtr pWin; 76705b261ecSmrg WindowPtr pHead; 76805b261ecSmrg ScreenPtr pScreen; 76905b261ecSmrg int idepth, ivisual; 77005b261ecSmrg Bool fOK; 77105b261ecSmrg DepthPtr pDepth; 77205b261ecSmrg PixmapFormatRec *format; 77305b261ecSmrg WindowOptPtr ancwopt; 77405b261ecSmrg 77505b261ecSmrg if (class == CopyFromParent) 776f7df2e56Smrg class = pParent->drawable.class; 77705b261ecSmrg 778f7df2e56Smrg if ((class != InputOutput) && (class != InputOnly)) { 779f7df2e56Smrg *error = BadValue; 780f7df2e56Smrg client->errorValue = class; 781f7df2e56Smrg return NullWindow; 78205b261ecSmrg } 78305b261ecSmrg 784f7df2e56Smrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) { 785f7df2e56Smrg *error = BadMatch; 786f7df2e56Smrg return NullWindow; 78705b261ecSmrg } 78805b261ecSmrg 789f7df2e56Smrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) { 790f7df2e56Smrg *error = BadMatch; 791f7df2e56Smrg return NullWindow; 79205b261ecSmrg } 79305b261ecSmrg 79405b261ecSmrg pScreen = pParent->drawable.pScreen; 79505b261ecSmrg if ((class == InputOutput) && (depth == 0)) 796f7df2e56Smrg depth = pParent->drawable.depth; 79705b261ecSmrg ancwopt = pParent->optional; 79805b261ecSmrg if (!ancwopt) 799f7df2e56Smrg ancwopt = FindWindowWithOptional(pParent)->optional; 80005b261ecSmrg if (visual == CopyFromParent) { 801f7df2e56Smrg visual = ancwopt->visual; 80205b261ecSmrg } 80305b261ecSmrg 80405b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 805f7df2e56Smrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { 806f7df2e56Smrg fOK = FALSE; 807f7df2e56Smrg for (idepth = 0; idepth < pScreen->numDepths; idepth++) { 808f7df2e56Smrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 809f7df2e56Smrg if ((depth == pDepth->depth) || (depth == 0)) { 810f7df2e56Smrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { 811f7df2e56Smrg if (visual == pDepth->vids[ivisual]) { 812f7df2e56Smrg fOK = TRUE; 813f7df2e56Smrg break; 814f7df2e56Smrg } 815f7df2e56Smrg } 816f7df2e56Smrg } 817f7df2e56Smrg } 818f7df2e56Smrg if (fOK == FALSE) { 819f7df2e56Smrg *error = BadMatch; 820f7df2e56Smrg return NullWindow; 821f7df2e56Smrg } 82205b261ecSmrg } 82305b261ecSmrg 82405b261ecSmrg if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) && 825f7df2e56Smrg (class != InputOnly) && (depth != pParent->drawable.depth)) { 826f7df2e56Smrg *error = BadMatch; 827f7df2e56Smrg return NullWindow; 82805b261ecSmrg } 82905b261ecSmrg 83005b261ecSmrg if (((vmask & CWColormap) == 0) && 831f7df2e56Smrg (class != InputOnly) && 832f7df2e56Smrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) { 833f7df2e56Smrg *error = BadMatch; 834f7df2e56Smrg return NullWindow; 83505b261ecSmrg } 83605b261ecSmrg 837f7df2e56Smrg pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); 838f7df2e56Smrg if (!pWin) { 839f7df2e56Smrg *error = BadAlloc; 840f7df2e56Smrg return NullWindow; 84105b261ecSmrg } 84205b261ecSmrg pWin->drawable = pParent->drawable; 84305b261ecSmrg pWin->drawable.depth = depth; 84405b261ecSmrg if (depth == pParent->drawable.depth) 845f7df2e56Smrg pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; 846f7df2e56Smrg else { 847f7df2e56Smrg for (format = screenInfo.formats; format->depth != depth; format++); 848f7df2e56Smrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 84905b261ecSmrg } 85005b261ecSmrg if (class == InputOnly) 851f7df2e56Smrg pWin->drawable.type = (short) UNDRAWABLE_WINDOW; 85205b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 85305b261ecSmrg 85405b261ecSmrg pWin->drawable.id = wid; 85505b261ecSmrg pWin->drawable.class = class; 85605b261ecSmrg 85705b261ecSmrg pWin->parent = pParent; 85805b261ecSmrg SetWindowToDefaults(pWin); 85905b261ecSmrg 860f7df2e56Smrg if (visual != ancwopt->visual) { 861f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 862f7df2e56Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 863f7df2e56Smrg *error = BadAlloc; 864f7df2e56Smrg return NullWindow; 865f7df2e56Smrg } 866f7df2e56Smrg pWin->optional->visual = visual; 867f7df2e56Smrg pWin->optional->colormap = None; 86805b261ecSmrg } 86905b261ecSmrg 87005b261ecSmrg pWin->borderWidth = bw; 87105b261ecSmrg 872637ac9abSmrg /* security creation/labeling check 87305b261ecSmrg */ 874637ac9abSmrg *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin, 875f7df2e56Smrg RT_WINDOW, pWin->parent, 876f7df2e56Smrg DixCreateAccess | DixSetAttrAccess); 877637ac9abSmrg if (*error != Success) { 878f7df2e56Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 879f7df2e56Smrg return NullWindow; 88005b261ecSmrg } 88105b261ecSmrg 882637ac9abSmrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 883637ac9abSmrg pWin->background.pixel = pScreen->whitePixel; 884637ac9abSmrg 88505b261ecSmrg pWin->borderIsPixel = pParent->borderIsPixel; 88605b261ecSmrg pWin->border = pParent->border; 88705b261ecSmrg if (pWin->borderIsPixel == FALSE) 888f7df2e56Smrg pWin->border.pixmap->refcnt++; 889f7df2e56Smrg 890f7df2e56Smrg pWin->origin.x = x + (int) bw; 891f7df2e56Smrg pWin->origin.y = y + (int) bw; 89205b261ecSmrg pWin->drawable.width = w; 89305b261ecSmrg pWin->drawable.height = h; 894f7df2e56Smrg pWin->drawable.x = pParent->drawable.x + x + (int) bw; 895f7df2e56Smrg pWin->drawable.y = pParent->drawable.y + y + (int) bw; 89605b261ecSmrg 897f7df2e56Smrg /* set up clip list correctly for unobscured WindowPtr */ 8984202a189Smrg RegionNull(&pWin->clipList); 8994202a189Smrg RegionNull(&pWin->borderClip); 9004202a189Smrg RegionNull(&pWin->winSize); 9014202a189Smrg RegionNull(&pWin->borderSize); 90205b261ecSmrg 90305b261ecSmrg pHead = RealChildHead(pParent); 904f7df2e56Smrg if (pHead) { 905f7df2e56Smrg pWin->nextSib = pHead->nextSib; 906f7df2e56Smrg if (pHead->nextSib) 907f7df2e56Smrg pHead->nextSib->prevSib = pWin; 908f7df2e56Smrg else 909f7df2e56Smrg pParent->lastChild = pWin; 910f7df2e56Smrg pHead->nextSib = pWin; 911f7df2e56Smrg pWin->prevSib = pHead; 91205b261ecSmrg } 913f7df2e56Smrg else { 914f7df2e56Smrg pWin->nextSib = pParent->firstChild; 915f7df2e56Smrg if (pParent->firstChild) 916f7df2e56Smrg pParent->firstChild->prevSib = pWin; 917f7df2e56Smrg else 918f7df2e56Smrg pParent->lastChild = pWin; 919f7df2e56Smrg pParent->firstChild = pWin; 92005b261ecSmrg } 92105b261ecSmrg 922f7df2e56Smrg SetWinSize(pWin); 923f7df2e56Smrg SetBorderSize(pWin); 92405b261ecSmrg 92505b261ecSmrg /* We SHOULD check for an error value here XXX */ 926f7df2e56Smrg if (!(*pScreen->CreateWindow) (pWin)) { 927f7df2e56Smrg *error = BadAlloc; 928f7df2e56Smrg DeleteWindow(pWin, None); 929f7df2e56Smrg return NullWindow; 93005b261ecSmrg } 93105b261ecSmrg /* We SHOULD check for an error value here XXX */ 932f7df2e56Smrg (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); 93305b261ecSmrg 93405b261ecSmrg if (!(vmask & CWEventMask)) 935f7df2e56Smrg RecalculateDeliverableEvents(pWin); 93605b261ecSmrg 93705b261ecSmrg if (vmask) 938f7df2e56Smrg *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin)); 93905b261ecSmrg else 940f7df2e56Smrg *error = Success; 94105b261ecSmrg 942f7df2e56Smrg if (*error != Success) { 943f7df2e56Smrg DeleteWindow(pWin, None); 944f7df2e56Smrg return NullWindow; 945f7df2e56Smrg } 946f7df2e56Smrg if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) { 947f7df2e56Smrg XID value = defaultBackingStore; 948f7df2e56Smrg 949f7df2e56Smrg (void) ChangeWindowAttributes(pWin, CWBackingStore, &value, 950f7df2e56Smrg wClient(pWin)); 951f7df2e56Smrg pWin->forcedBS = TRUE; 952f7df2e56Smrg } 953f7df2e56Smrg 954f7df2e56Smrg if (SubSend(pParent)) { 955f7df2e56Smrg xEvent event = { 956f7df2e56Smrg .u.createNotify.window = wid, 957f7df2e56Smrg .u.createNotify.parent = pParent->drawable.id, 958f7df2e56Smrg .u.createNotify.x = x, 959f7df2e56Smrg .u.createNotify.y = y, 960f7df2e56Smrg .u.createNotify.width = w, 961f7df2e56Smrg .u.createNotify.height = h, 962f7df2e56Smrg .u.createNotify.borderWidth = bw, 963f7df2e56Smrg .u.createNotify.override = pWin->overrideRedirect 964f7df2e56Smrg }; 965f7df2e56Smrg event.u.u.type = CreateNotify; 966f7df2e56Smrg DeliverEvents(pParent, &event, 1, NullWindow); 96705b261ecSmrg } 96805b261ecSmrg return pWin; 96905b261ecSmrg} 97005b261ecSmrg 97105b261ecSmrgstatic void 972f7df2e56SmrgDisposeWindowOptional(WindowPtr pWin) 97305b261ecSmrg{ 97405b261ecSmrg if (!pWin->optional) 975f7df2e56Smrg return; 97605b261ecSmrg /* 97705b261ecSmrg * everything is peachy. Delete the optional record 97805b261ecSmrg * and clean up 97905b261ecSmrg */ 980f7df2e56Smrg if (pWin->optional->cursor) { 981f7df2e56Smrg FreeCursor(pWin->optional->cursor, (Cursor) 0); 982f7df2e56Smrg pWin->cursorIsNone = FALSE; 98305b261ecSmrg } 98405b261ecSmrg else 985f7df2e56Smrg pWin->cursorIsNone = TRUE; 986637ac9abSmrg 987f7df2e56Smrg if (pWin->optional->deviceCursors) { 988637ac9abSmrg DevCursorList pList; 989637ac9abSmrg DevCursorList pPrev; 990f7df2e56Smrg 991637ac9abSmrg pList = pWin->optional->deviceCursors; 992f7df2e56Smrg while (pList) { 993637ac9abSmrg if (pList->cursor) 994f7df2e56Smrg FreeCursor(pList->cursor, (XID) 0); 995637ac9abSmrg pPrev = pList; 996637ac9abSmrg pList = pList->next; 9974202a189Smrg free(pPrev); 998637ac9abSmrg } 999637ac9abSmrg pWin->optional->deviceCursors = NULL; 1000637ac9abSmrg } 1001637ac9abSmrg 10024202a189Smrg free(pWin->optional); 100305b261ecSmrg pWin->optional = NULL; 100405b261ecSmrg} 100505b261ecSmrg 100605b261ecSmrgstatic void 100705b261ecSmrgFreeWindowResources(WindowPtr pWin) 100805b261ecSmrg{ 100905b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 101005b261ecSmrg 101105b261ecSmrg DeleteWindowFromAnySaveSet(pWin); 101205b261ecSmrg DeleteWindowFromAnySelections(pWin); 101305b261ecSmrg DeleteWindowFromAnyEvents(pWin, TRUE); 10144202a189Smrg RegionUninit(&pWin->clipList); 10154202a189Smrg RegionUninit(&pWin->winSize); 10164202a189Smrg RegionUninit(&pWin->borderClip); 10174202a189Smrg RegionUninit(&pWin->borderSize); 1018f7df2e56Smrg if (wBoundingShape(pWin)) 1019f7df2e56Smrg RegionDestroy(wBoundingShape(pWin)); 1020f7df2e56Smrg if (wClipShape(pWin)) 1021f7df2e56Smrg RegionDestroy(wClipShape(pWin)); 1022f7df2e56Smrg if (wInputShape(pWin)) 1023f7df2e56Smrg RegionDestroy(wInputShape(pWin)); 102405b261ecSmrg if (pWin->borderIsPixel == FALSE) 1025f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 102605b261ecSmrg if (pWin->backgroundState == BackgroundPixmap) 1027f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 102805b261ecSmrg 102905b261ecSmrg DeleteAllWindowProperties(pWin); 103005b261ecSmrg /* We SHOULD check for an error value here XXX */ 1031f7df2e56Smrg (*pScreen->DestroyWindow) (pWin); 1032f7df2e56Smrg DisposeWindowOptional(pWin); 103305b261ecSmrg} 103405b261ecSmrg 103505b261ecSmrgstatic void 103605b261ecSmrgCrushTree(WindowPtr pWin) 103705b261ecSmrg{ 103805b261ecSmrg WindowPtr pChild, pSib, pParent; 103905b261ecSmrg UnrealizeWindowProcPtr UnrealizeWindow; 104005b261ecSmrg 104105b261ecSmrg if (!(pChild = pWin->firstChild)) 1042f7df2e56Smrg return; 104305b261ecSmrg UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; 1044f7df2e56Smrg while (1) { 1045f7df2e56Smrg if (pChild->firstChild) { 1046f7df2e56Smrg pChild = pChild->firstChild; 1047f7df2e56Smrg continue; 1048f7df2e56Smrg } 1049f7df2e56Smrg while (1) { 1050f7df2e56Smrg pParent = pChild->parent; 1051f7df2e56Smrg if (SubStrSend(pChild, pParent)) { 1052f7df2e56Smrg xEvent event = { .u.u.type = DestroyNotify }; 1053f7df2e56Smrg event.u.destroyNotify.window = pChild->drawable.id; 1054f7df2e56Smrg DeliverEvents(pChild, &event, 1, NullWindow); 1055f7df2e56Smrg } 1056f7df2e56Smrg FreeResource(pChild->drawable.id, RT_WINDOW); 1057f7df2e56Smrg pSib = pChild->nextSib; 1058f7df2e56Smrg pChild->viewable = FALSE; 1059f7df2e56Smrg if (pChild->realized) { 1060f7df2e56Smrg pChild->realized = FALSE; 1061f7df2e56Smrg (*UnrealizeWindow) (pChild); 1062f7df2e56Smrg } 1063f7df2e56Smrg FreeWindowResources(pChild); 1064f7df2e56Smrg dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW); 1065f7df2e56Smrg if ((pChild = pSib)) 1066f7df2e56Smrg break; 1067f7df2e56Smrg pChild = pParent; 1068f7df2e56Smrg pChild->firstChild = NullWindow; 1069f7df2e56Smrg pChild->lastChild = NullWindow; 1070f7df2e56Smrg if (pChild == pWin) 1071f7df2e56Smrg return; 1072f7df2e56Smrg } 1073f7df2e56Smrg } 1074f7df2e56Smrg} 1075f7df2e56Smrg 107605b261ecSmrg/***** 107705b261ecSmrg * DeleteWindow 107805b261ecSmrg * Deletes child of window then window itself 107905b261ecSmrg * If wid is None, don't send any events 108005b261ecSmrg *****/ 108105b261ecSmrg 108205b261ecSmrgint 1083f7df2e56SmrgDeleteWindow(void *value, XID wid) 1084f7df2e56Smrg{ 108505b261ecSmrg WindowPtr pParent; 1086f7df2e56Smrg WindowPtr pWin = (WindowPtr) value; 108705b261ecSmrg 108805b261ecSmrg UnmapWindow(pWin, FALSE); 108905b261ecSmrg 109005b261ecSmrg CrushTree(pWin); 109105b261ecSmrg 109205b261ecSmrg pParent = pWin->parent; 1093f7df2e56Smrg if (wid && pParent && SubStrSend(pWin, pParent)) { 1094f7df2e56Smrg xEvent event = { .u.u.type = DestroyNotify }; 1095f7df2e56Smrg event.u.destroyNotify.window = pWin->drawable.id; 1096f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 109705b261ecSmrg } 109805b261ecSmrg 109905b261ecSmrg FreeWindowResources(pWin); 1100f7df2e56Smrg if (pParent) { 1101f7df2e56Smrg if (pParent->firstChild == pWin) 1102f7df2e56Smrg pParent->firstChild = pWin->nextSib; 1103f7df2e56Smrg if (pParent->lastChild == pWin) 1104f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1105f7df2e56Smrg if (pWin->nextSib) 1106f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1107f7df2e56Smrg if (pWin->prevSib) 1108f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 110905b261ecSmrg } 11104202a189Smrg else 1111f7df2e56Smrg pWin->drawable.pScreen->root = NULL; 11124202a189Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 111305b261ecSmrg return Success; 111405b261ecSmrg} 111505b261ecSmrg 1116637ac9abSmrgint 111705b261ecSmrgDestroySubwindows(WindowPtr pWin, ClientPtr client) 111805b261ecSmrg{ 111905b261ecSmrg /* XXX 112005b261ecSmrg * The protocol is quite clear that each window should be 112105b261ecSmrg * destroyed in turn, however, unmapping all of the first 112205b261ecSmrg * eliminates most of the calls to ValidateTree. So, 112305b261ecSmrg * this implementation is incorrect in that all of the 112405b261ecSmrg * UnmapNotifies occur before all of the DestroyNotifies. 112505b261ecSmrg * If you care, simply delete the call to UnmapSubwindows. 112605b261ecSmrg */ 112705b261ecSmrg UnmapSubwindows(pWin); 1128637ac9abSmrg while (pWin->lastChild) { 1129f7df2e56Smrg int rc = XaceHook(XACE_RESOURCE_ACCESS, client, 1130f7df2e56Smrg pWin->lastChild->drawable.id, RT_WINDOW, 1131f7df2e56Smrg pWin->lastChild, RT_NONE, NULL, DixDestroyAccess); 1132f7df2e56Smrg 1133f7df2e56Smrg if (rc != Success) 1134f7df2e56Smrg return rc; 1135f7df2e56Smrg FreeResource(pWin->lastChild->drawable.id, RT_NONE); 1136637ac9abSmrg } 1137637ac9abSmrg return Success; 113805b261ecSmrg} 113905b261ecSmrg 114065b04b38Smrgstatic void 114165b04b38SmrgSetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) 114265b04b38Smrg{ 114365b04b38Smrg /* following the protocol: "Changing the background of a root window to 114465b04b38Smrg * None or ParentRelative restores the default background pixmap" */ 114565b04b38Smrg if (bgNoneRoot) { 1146f7df2e56Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 1147f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 114865b04b38Smrg } 114965b04b38Smrg else if (party_like_its_1989) 1150f7df2e56Smrg MakeRootTile(pWin); 115165b04b38Smrg else { 115265b04b38Smrg pWin->backgroundState = BackgroundPixel; 1153f7df2e56Smrg if (whiteRoot) 1154f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 1155f7df2e56Smrg else 1156f7df2e56Smrg pWin->background.pixel = pScreen->blackPixel; 1157f7df2e56Smrg *index2 = CWBackPixel; 115865b04b38Smrg } 115965b04b38Smrg} 116065b04b38Smrg 116105b261ecSmrg/***** 116205b261ecSmrg * ChangeWindowAttributes 1163f7df2e56Smrg * 116405b261ecSmrg * The value-mask specifies which attributes are to be changed; the 116505b261ecSmrg * value-list contains one value for each one bit in the mask, from least 1166f7df2e56Smrg * to most significant bit in the mask. 116705b261ecSmrg *****/ 1168f7df2e56Smrg 11694202a189Smrgint 117005b261ecSmrgChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) 117105b261ecSmrg{ 117205b261ecSmrg XID *pVlist; 117305b261ecSmrg PixmapPtr pPixmap; 117405b261ecSmrg Pixmap pixID; 117505b261ecSmrg CursorPtr pCursor, pOldCursor; 117605b261ecSmrg Cursor cursorID; 117705b261ecSmrg WindowPtr pChild; 117805b261ecSmrg Colormap cmap; 1179f7df2e56Smrg ColormapPtr pCmap; 118005b261ecSmrg xEvent xE; 1181637ac9abSmrg int error, rc; 118205b261ecSmrg ScreenPtr pScreen; 1183637ac9abSmrg Mask index2, tmask, vmaskCopy = 0; 118405b261ecSmrg unsigned int val; 1185637ac9abSmrg Bool checkOptional = FALSE, borderRelative = FALSE; 118605b261ecSmrg 1187f7df2e56Smrg if ((pWin->drawable.class == InputOnly) && 1188f7df2e56Smrg (vmask & (~INPUTONLY_LEGAL_MASK))) 1189f7df2e56Smrg return BadMatch; 119005b261ecSmrg 119105b261ecSmrg error = Success; 119205b261ecSmrg pScreen = pWin->drawable.pScreen; 119305b261ecSmrg pVlist = vlist; 119405b261ecSmrg tmask = vmask; 1195f7df2e56Smrg while (tmask) { 1196f7df2e56Smrg index2 = (Mask) lowbit(tmask); 1197f7df2e56Smrg tmask &= ~index2; 1198f7df2e56Smrg switch (index2) { 1199f7df2e56Smrg case CWBackPixmap: 1200f7df2e56Smrg pixID = (Pixmap) * pVlist; 1201f7df2e56Smrg pVlist++; 1202f7df2e56Smrg if (pWin->backgroundState == ParentRelative) 1203f7df2e56Smrg borderRelative = TRUE; 1204f7df2e56Smrg if (pixID == None) { 1205f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1206f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1207f7df2e56Smrg if (!pWin->parent) 1208f7df2e56Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1209f7df2e56Smrg else { 1210f7df2e56Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 1211f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 1212f7df2e56Smrg } 1213f7df2e56Smrg } 1214f7df2e56Smrg else if (pixID == ParentRelative) { 1215f7df2e56Smrg if (pWin->parent && 1216f7df2e56Smrg pWin->drawable.depth != pWin->parent->drawable.depth) { 1217f7df2e56Smrg error = BadMatch; 1218f7df2e56Smrg goto PatchUp; 1219f7df2e56Smrg } 1220f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1221f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1222f7df2e56Smrg if (!pWin->parent) 1223f7df2e56Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1224f7df2e56Smrg else 1225f7df2e56Smrg pWin->backgroundState = ParentRelative; 1226f7df2e56Smrg borderRelative = TRUE; 1227f7df2e56Smrg /* Note that the parent's backgroundTile's refcnt is NOT 1228f7df2e56Smrg * incremented. */ 1229f7df2e56Smrg } 1230f7df2e56Smrg else { 1231f7df2e56Smrg rc = dixLookupResourceByType((void **) &pPixmap, pixID, 1232f7df2e56Smrg RT_PIXMAP, client, DixReadAccess); 1233f7df2e56Smrg if (rc == Success) { 1234f7df2e56Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1235f7df2e56Smrg (pPixmap->drawable.pScreen != pScreen)) { 1236f7df2e56Smrg error = BadMatch; 1237f7df2e56Smrg goto PatchUp; 1238f7df2e56Smrg } 1239f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1240f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1241f7df2e56Smrg pWin->backgroundState = BackgroundPixmap; 1242f7df2e56Smrg pWin->background.pixmap = pPixmap; 1243f7df2e56Smrg pPixmap->refcnt++; 1244f7df2e56Smrg } 1245f7df2e56Smrg else { 1246f7df2e56Smrg error = rc; 1247f7df2e56Smrg client->errorValue = pixID; 1248f7df2e56Smrg goto PatchUp; 1249f7df2e56Smrg } 1250f7df2e56Smrg } 1251f7df2e56Smrg break; 1252f7df2e56Smrg case CWBackPixel: 1253f7df2e56Smrg if (pWin->backgroundState == ParentRelative) 1254f7df2e56Smrg borderRelative = TRUE; 1255f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1256f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1257f7df2e56Smrg pWin->backgroundState = BackgroundPixel; 1258f7df2e56Smrg pWin->background.pixel = (CARD32) *pVlist; 1259f7df2e56Smrg /* background pixel overrides background pixmap, 1260f7df2e56Smrg so don't let the ddx layer see both bits */ 1261f7df2e56Smrg vmaskCopy &= ~CWBackPixmap; 1262f7df2e56Smrg pVlist++; 1263f7df2e56Smrg break; 1264f7df2e56Smrg case CWBorderPixmap: 1265f7df2e56Smrg pixID = (Pixmap) * pVlist; 1266f7df2e56Smrg pVlist++; 1267f7df2e56Smrg if (pixID == CopyFromParent) { 1268f7df2e56Smrg if (!pWin->parent || 1269f7df2e56Smrg (pWin->drawable.depth != pWin->parent->drawable.depth)) { 1270f7df2e56Smrg error = BadMatch; 1271f7df2e56Smrg goto PatchUp; 1272f7df2e56Smrg } 1273f7df2e56Smrg if (pWin->parent->borderIsPixel == TRUE) { 1274f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1275f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1276f7df2e56Smrg pWin->border = pWin->parent->border; 1277f7df2e56Smrg pWin->borderIsPixel = TRUE; 1278f7df2e56Smrg index2 = CWBorderPixel; 1279f7df2e56Smrg break; 1280f7df2e56Smrg } 1281f7df2e56Smrg else { 1282f7df2e56Smrg pixID = pWin->parent->border.pixmap->drawable.id; 1283f7df2e56Smrg } 1284f7df2e56Smrg } 1285f7df2e56Smrg rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP, 1286f7df2e56Smrg client, DixReadAccess); 1287f7df2e56Smrg if (rc == Success) { 1288f7df2e56Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1289f7df2e56Smrg (pPixmap->drawable.pScreen != pScreen)) { 1290f7df2e56Smrg error = BadMatch; 1291f7df2e56Smrg goto PatchUp; 1292f7df2e56Smrg } 1293f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1294f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1295f7df2e56Smrg pWin->borderIsPixel = FALSE; 1296f7df2e56Smrg pWin->border.pixmap = pPixmap; 1297f7df2e56Smrg pPixmap->refcnt++; 1298f7df2e56Smrg } 1299f7df2e56Smrg else { 1300f7df2e56Smrg error = rc; 1301f7df2e56Smrg client->errorValue = pixID; 1302f7df2e56Smrg goto PatchUp; 1303f7df2e56Smrg } 1304f7df2e56Smrg break; 1305f7df2e56Smrg case CWBorderPixel: 1306f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1307f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1308f7df2e56Smrg pWin->borderIsPixel = TRUE; 1309f7df2e56Smrg pWin->border.pixel = (CARD32) *pVlist; 1310f7df2e56Smrg /* border pixel overrides border pixmap, 1311f7df2e56Smrg so don't let the ddx layer see both bits */ 1312f7df2e56Smrg vmaskCopy &= ~CWBorderPixmap; 1313f7df2e56Smrg pVlist++; 1314f7df2e56Smrg break; 1315f7df2e56Smrg case CWBitGravity: 1316f7df2e56Smrg val = (CARD8) *pVlist; 1317f7df2e56Smrg pVlist++; 1318f7df2e56Smrg if (val > StaticGravity) { 1319f7df2e56Smrg error = BadValue; 1320f7df2e56Smrg client->errorValue = val; 1321f7df2e56Smrg goto PatchUp; 1322f7df2e56Smrg } 1323f7df2e56Smrg pWin->bitGravity = val; 1324f7df2e56Smrg break; 1325f7df2e56Smrg case CWWinGravity: 1326f7df2e56Smrg val = (CARD8) *pVlist; 1327f7df2e56Smrg pVlist++; 1328f7df2e56Smrg if (val > StaticGravity) { 1329f7df2e56Smrg error = BadValue; 1330f7df2e56Smrg client->errorValue = val; 1331f7df2e56Smrg goto PatchUp; 1332f7df2e56Smrg } 1333f7df2e56Smrg pWin->winGravity = val; 1334f7df2e56Smrg break; 1335f7df2e56Smrg case CWBackingStore: 1336f7df2e56Smrg val = (CARD8) *pVlist; 1337f7df2e56Smrg pVlist++; 1338f7df2e56Smrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) { 1339f7df2e56Smrg error = BadValue; 1340f7df2e56Smrg client->errorValue = val; 1341f7df2e56Smrg goto PatchUp; 1342f7df2e56Smrg } 1343f7df2e56Smrg pWin->backingStore = val; 1344f7df2e56Smrg pWin->forcedBS = FALSE; 1345f7df2e56Smrg break; 1346f7df2e56Smrg case CWBackingPlanes: 1347f7df2e56Smrg if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) { 1348f7df2e56Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) { 1349f7df2e56Smrg error = BadAlloc; 1350f7df2e56Smrg goto PatchUp; 1351f7df2e56Smrg } 1352f7df2e56Smrg pWin->optional->backingBitPlanes = (CARD32) *pVlist; 1353f7df2e56Smrg if ((CARD32) *pVlist == (CARD32) ~0L) 1354f7df2e56Smrg checkOptional = TRUE; 1355f7df2e56Smrg } 1356f7df2e56Smrg pVlist++; 1357f7df2e56Smrg break; 1358f7df2e56Smrg case CWBackingPixel: 1359f7df2e56Smrg if (pWin->optional || (CARD32) *pVlist) { 1360f7df2e56Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) { 1361f7df2e56Smrg error = BadAlloc; 1362f7df2e56Smrg goto PatchUp; 1363f7df2e56Smrg } 1364f7df2e56Smrg pWin->optional->backingPixel = (CARD32) *pVlist; 1365f7df2e56Smrg if (!*pVlist) 1366f7df2e56Smrg checkOptional = TRUE; 1367f7df2e56Smrg } 1368f7df2e56Smrg pVlist++; 1369f7df2e56Smrg break; 1370f7df2e56Smrg case CWSaveUnder: 1371f7df2e56Smrg val = (BOOL) * pVlist; 1372f7df2e56Smrg pVlist++; 1373f7df2e56Smrg if ((val != xTrue) && (val != xFalse)) { 1374f7df2e56Smrg error = BadValue; 1375f7df2e56Smrg client->errorValue = val; 1376f7df2e56Smrg goto PatchUp; 1377f7df2e56Smrg } 1378f7df2e56Smrg pWin->saveUnder = val; 1379f7df2e56Smrg break; 1380f7df2e56Smrg case CWEventMask: 1381f7df2e56Smrg rc = EventSelectForWindow(pWin, client, (Mask) *pVlist); 1382f7df2e56Smrg if (rc) { 1383f7df2e56Smrg error = rc; 1384f7df2e56Smrg goto PatchUp; 1385f7df2e56Smrg } 1386f7df2e56Smrg pVlist++; 1387f7df2e56Smrg break; 1388f7df2e56Smrg case CWDontPropagate: 1389f7df2e56Smrg rc = EventSuppressForWindow(pWin, client, (Mask) *pVlist, 1390f7df2e56Smrg &checkOptional); 1391f7df2e56Smrg if (rc) { 1392f7df2e56Smrg error = rc; 1393f7df2e56Smrg goto PatchUp; 1394f7df2e56Smrg } 1395f7df2e56Smrg pVlist++; 1396f7df2e56Smrg break; 1397f7df2e56Smrg case CWOverrideRedirect: 1398f7df2e56Smrg val = (BOOL) * pVlist; 1399f7df2e56Smrg pVlist++; 1400f7df2e56Smrg if ((val != xTrue) && (val != xFalse)) { 1401f7df2e56Smrg error = BadValue; 1402f7df2e56Smrg client->errorValue = val; 1403f7df2e56Smrg goto PatchUp; 1404f7df2e56Smrg } 1405f7df2e56Smrg if (val == xTrue) { 1406f7df2e56Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, 1407f7df2e56Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess); 1408f7df2e56Smrg if (rc != Success) { 1409f7df2e56Smrg error = rc; 1410f7df2e56Smrg client->errorValue = pWin->drawable.id; 1411f7df2e56Smrg goto PatchUp; 1412f7df2e56Smrg } 1413f7df2e56Smrg } 1414f7df2e56Smrg pWin->overrideRedirect = val; 1415f7df2e56Smrg break; 1416f7df2e56Smrg case CWColormap: 1417f7df2e56Smrg cmap = (Colormap) * pVlist; 1418f7df2e56Smrg pVlist++; 1419f7df2e56Smrg if (cmap == CopyFromParent) { 1420f7df2e56Smrg if (pWin->parent && 1421f7df2e56Smrg (!pWin->optional || 1422f7df2e56Smrg pWin->optional->visual == wVisual(pWin->parent))) { 1423f7df2e56Smrg cmap = wColormap(pWin->parent); 1424f7df2e56Smrg } 1425f7df2e56Smrg else 1426f7df2e56Smrg cmap = None; 1427f7df2e56Smrg } 1428f7df2e56Smrg if (cmap == None) { 1429f7df2e56Smrg error = BadMatch; 1430f7df2e56Smrg goto PatchUp; 1431f7df2e56Smrg } 1432f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP, 1433f7df2e56Smrg client, DixUseAccess); 1434f7df2e56Smrg if (rc != Success) { 1435f7df2e56Smrg error = rc; 1436f7df2e56Smrg client->errorValue = cmap; 1437f7df2e56Smrg goto PatchUp; 1438f7df2e56Smrg } 1439f7df2e56Smrg if (pCmap->pVisual->vid != wVisual(pWin) || 1440f7df2e56Smrg pCmap->pScreen != pScreen) { 1441f7df2e56Smrg error = BadMatch; 1442f7df2e56Smrg goto PatchUp; 1443f7df2e56Smrg } 1444f7df2e56Smrg if (cmap != wColormap(pWin)) { 1445f7df2e56Smrg if (!pWin->optional) { 1446f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 1447f7df2e56Smrg error = BadAlloc; 1448f7df2e56Smrg goto PatchUp; 1449f7df2e56Smrg } 1450f7df2e56Smrg } 1451f7df2e56Smrg else if (pWin->parent && cmap == wColormap(pWin->parent)) 1452f7df2e56Smrg checkOptional = TRUE; 1453f7df2e56Smrg 1454f7df2e56Smrg /* 1455f7df2e56Smrg * propagate the original colormap to any children 1456f7df2e56Smrg * inheriting it 1457f7df2e56Smrg */ 1458f7df2e56Smrg 1459f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1460f7df2e56Smrg pChild = pChild->nextSib) { 1461f7df2e56Smrg if (!pChild->optional && !MakeWindowOptional(pChild)) { 1462f7df2e56Smrg error = BadAlloc; 1463f7df2e56Smrg goto PatchUp; 1464f7df2e56Smrg } 1465f7df2e56Smrg } 1466f7df2e56Smrg 1467f7df2e56Smrg pWin->optional->colormap = cmap; 1468f7df2e56Smrg 1469f7df2e56Smrg /* 1470f7df2e56Smrg * check on any children now matching the new colormap 1471f7df2e56Smrg */ 1472f7df2e56Smrg 1473f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1474f7df2e56Smrg pChild = pChild->nextSib) { 1475f7df2e56Smrg if (pChild->optional->colormap == cmap) 1476f7df2e56Smrg CheckWindowOptionalNeed(pChild); 1477f7df2e56Smrg } 1478f7df2e56Smrg 1479f7df2e56Smrg xE = (xEvent) { 1480f7df2e56Smrg .u.colormap.window = pWin->drawable.id, 1481f7df2e56Smrg .u.colormap.colormap = cmap, 1482f7df2e56Smrg .u.colormap.new = xTrue, 1483f7df2e56Smrg .u.colormap.state = IsMapInstalled(cmap, pWin) 1484f7df2e56Smrg }; 1485f7df2e56Smrg xE.u.u.type = ColormapNotify; 1486f7df2e56Smrg DeliverEvents(pWin, &xE, 1, NullWindow); 1487f7df2e56Smrg } 1488f7df2e56Smrg break; 1489f7df2e56Smrg case CWCursor: 1490f7df2e56Smrg cursorID = (Cursor) * pVlist; 1491f7df2e56Smrg pVlist++; 1492f7df2e56Smrg /* 1493f7df2e56Smrg * install the new 1494f7df2e56Smrg */ 1495f7df2e56Smrg if (cursorID == None) { 1496f7df2e56Smrg if (pWin == pWin->drawable.pScreen->root) 1497f7df2e56Smrg pCursor = rootCursor; 1498f7df2e56Smrg else 1499f7df2e56Smrg pCursor = (CursorPtr) None; 1500f7df2e56Smrg } 1501f7df2e56Smrg else { 1502f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCursor, cursorID, 1503f7df2e56Smrg RT_CURSOR, client, DixUseAccess); 1504f7df2e56Smrg if (rc != Success) { 1505f7df2e56Smrg error = rc; 1506f7df2e56Smrg client->errorValue = cursorID; 1507f7df2e56Smrg goto PatchUp; 1508f7df2e56Smrg } 1509f7df2e56Smrg } 1510f7df2e56Smrg 1511f7df2e56Smrg if (pCursor != wCursor(pWin)) { 1512f7df2e56Smrg /* 1513f7df2e56Smrg * patch up child windows so they don't lose cursors. 1514f7df2e56Smrg */ 1515f7df2e56Smrg 1516f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1517f7df2e56Smrg pChild = pChild->nextSib) { 1518f7df2e56Smrg if (!pChild->optional && !pChild->cursorIsNone && 1519f7df2e56Smrg !MakeWindowOptional(pChild)) { 1520f7df2e56Smrg error = BadAlloc; 1521f7df2e56Smrg goto PatchUp; 1522f7df2e56Smrg } 1523f7df2e56Smrg } 1524f7df2e56Smrg 1525f7df2e56Smrg pOldCursor = 0; 1526f7df2e56Smrg if (pCursor == (CursorPtr) None) { 1527f7df2e56Smrg pWin->cursorIsNone = TRUE; 1528f7df2e56Smrg if (pWin->optional) { 1529f7df2e56Smrg pOldCursor = pWin->optional->cursor; 1530f7df2e56Smrg pWin->optional->cursor = (CursorPtr) None; 1531f7df2e56Smrg checkOptional = TRUE; 1532f7df2e56Smrg } 1533f7df2e56Smrg } 1534f7df2e56Smrg else { 1535f7df2e56Smrg if (!pWin->optional) { 1536f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 1537f7df2e56Smrg error = BadAlloc; 1538f7df2e56Smrg goto PatchUp; 1539f7df2e56Smrg } 1540f7df2e56Smrg } 1541f7df2e56Smrg else if (pWin->parent && pCursor == wCursor(pWin->parent)) 1542f7df2e56Smrg checkOptional = TRUE; 1543f7df2e56Smrg pOldCursor = pWin->optional->cursor; 1544f7df2e56Smrg pWin->optional->cursor = RefCursor(pCursor); 1545f7df2e56Smrg pWin->cursorIsNone = FALSE; 1546f7df2e56Smrg /* 1547f7df2e56Smrg * check on any children now matching the new cursor 1548f7df2e56Smrg */ 1549f7df2e56Smrg 1550f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1551f7df2e56Smrg pChild = pChild->nextSib) { 1552f7df2e56Smrg if (pChild->optional && 1553f7df2e56Smrg (pChild->optional->cursor == pCursor)) 1554f7df2e56Smrg CheckWindowOptionalNeed(pChild); 1555f7df2e56Smrg } 1556f7df2e56Smrg } 1557f7df2e56Smrg 1558f7df2e56Smrg CursorVisible = TRUE; 1559f7df2e56Smrg 1560f7df2e56Smrg if (pWin->realized) 1561f7df2e56Smrg WindowHasNewCursor(pWin); 1562f7df2e56Smrg 1563f7df2e56Smrg /* Can't free cursor until here - old cursor 1564f7df2e56Smrg * is needed in WindowHasNewCursor 1565f7df2e56Smrg */ 1566f7df2e56Smrg if (pOldCursor) 1567f7df2e56Smrg FreeCursor(pOldCursor, (Cursor) 0); 1568f7df2e56Smrg } 1569f7df2e56Smrg break; 1570f7df2e56Smrg default: 1571f7df2e56Smrg error = BadValue; 1572f7df2e56Smrg client->errorValue = vmask; 1573f7df2e56Smrg goto PatchUp; 1574f7df2e56Smrg } 1575f7df2e56Smrg vmaskCopy |= index2; 1576f7df2e56Smrg } 1577f7df2e56Smrg PatchUp: 157805b261ecSmrg if (checkOptional) 1579f7df2e56Smrg CheckWindowOptionalNeed(pWin); 158005b261ecSmrg 1581f7df2e56Smrg /* We SHOULD check for an error value here XXX */ 1582f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy); 158305b261ecSmrg 1584f7df2e56Smrg /* 1585f7df2e56Smrg If the border contents have changed, redraw the border. 1586f7df2e56Smrg Note that this has to be done AFTER pScreen->ChangeWindowAttributes 1587f7df2e56Smrg for the tile to be rotated, and the correct function selected. 1588f7df2e56Smrg */ 158905b261ecSmrg if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) 1590f7df2e56Smrg && pWin->viewable && HasBorder(pWin)) { 1591f7df2e56Smrg RegionRec exposed; 159205b261ecSmrg 1593f7df2e56Smrg RegionNull(&exposed); 1594f7df2e56Smrg RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); 1595f7df2e56Smrg pWin->drawable.pScreen->PaintWindow(pWin, &exposed, PW_BORDER); 1596f7df2e56Smrg RegionUninit(&exposed); 159705b261ecSmrg } 159805b261ecSmrg return error; 159905b261ecSmrg} 160005b261ecSmrg 160105b261ecSmrg/***** 160205b261ecSmrg * GetWindowAttributes 160305b261ecSmrg * Notice that this is different than ChangeWindowAttributes 160405b261ecSmrg *****/ 160505b261ecSmrg 160605b261ecSmrgvoid 1607f7df2e56SmrgGetWindowAttributes(WindowPtr pWin, ClientPtr client, 1608f7df2e56Smrg xGetWindowAttributesReply * wa) 160905b261ecSmrg{ 161005b261ecSmrg wa->type = X_Reply; 161105b261ecSmrg wa->bitGravity = pWin->bitGravity; 161205b261ecSmrg wa->winGravity = pWin->winGravity; 161305b261ecSmrg if (pWin->forcedBS && pWin->backingStore != Always) 1614f7df2e56Smrg wa->backingStore = NotUseful; 161505b261ecSmrg else 1616f7df2e56Smrg wa->backingStore = pWin->backingStore; 16174202a189Smrg wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - 1618f7df2e56Smrg sizeof(xGenericReply)); 161905b261ecSmrg wa->sequenceNumber = client->sequence; 1620f7df2e56Smrg wa->backingBitPlanes = wBackingBitPlanes(pWin); 1621f7df2e56Smrg wa->backingPixel = wBackingPixel(pWin); 1622f7df2e56Smrg wa->saveUnder = (BOOL) pWin->saveUnder; 162305b261ecSmrg wa->override = pWin->overrideRedirect; 162405b261ecSmrg if (!pWin->mapped) 1625f7df2e56Smrg wa->mapState = IsUnmapped; 162605b261ecSmrg else if (pWin->realized) 1627f7df2e56Smrg wa->mapState = IsViewable; 162805b261ecSmrg else 1629f7df2e56Smrg wa->mapState = IsUnviewable; 163005b261ecSmrg 1631f7df2e56Smrg wa->colormap = wColormap(pWin); 163205b261ecSmrg wa->mapInstalled = (wa->colormap == None) ? xFalse 1633f7df2e56Smrg : IsMapInstalled(wa->colormap, pWin); 163405b261ecSmrg 163505b261ecSmrg wa->yourEventMask = EventMaskForClient(pWin, client); 1636f7df2e56Smrg wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin); 1637f7df2e56Smrg wa->doNotPropagateMask = wDontPropagateMask(pWin); 163805b261ecSmrg wa->class = pWin->drawable.class; 1639f7df2e56Smrg wa->visualID = wVisual(pWin); 164005b261ecSmrg} 164105b261ecSmrg 1642637ac9abSmrgWindowPtr 164305b261ecSmrgMoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) 164405b261ecSmrg{ 164505b261ecSmrg WindowPtr pParent = pWin->parent; 1646f7df2e56Smrg WindowPtr pFirstChange = pWin; /* highest window where list changes */ 1647f7df2e56Smrg 1648f7df2e56Smrg if (pWin->nextSib != pNextSib) { 1649f7df2e56Smrg WindowPtr pOldNextSib = pWin->nextSib; 1650f7df2e56Smrg 1651f7df2e56Smrg if (!pNextSib) { /* move to bottom */ 1652f7df2e56Smrg if (pParent->firstChild == pWin) 1653f7df2e56Smrg pParent->firstChild = pWin->nextSib; 1654f7df2e56Smrg /* if (pWin->nextSib) *//* is always True: pNextSib == NULL 1655f7df2e56Smrg * and pWin->nextSib != pNextSib 1656f7df2e56Smrg * therefore pWin->nextSib != NULL */ 1657f7df2e56Smrg pFirstChange = pWin->nextSib; 1658f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1659f7df2e56Smrg if (pWin->prevSib) 1660f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1661f7df2e56Smrg pParent->lastChild->nextSib = pWin; 1662f7df2e56Smrg pWin->prevSib = pParent->lastChild; 1663f7df2e56Smrg pWin->nextSib = NullWindow; 1664f7df2e56Smrg pParent->lastChild = pWin; 1665f7df2e56Smrg } 1666f7df2e56Smrg else if (pParent->firstChild == pNextSib) { /* move to top */ 1667f7df2e56Smrg pFirstChange = pWin; 1668f7df2e56Smrg if (pParent->lastChild == pWin) 1669f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1670f7df2e56Smrg if (pWin->nextSib) 1671f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1672f7df2e56Smrg if (pWin->prevSib) 1673f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1674f7df2e56Smrg pWin->nextSib = pParent->firstChild; 1675f7df2e56Smrg pWin->prevSib = NULL; 1676f7df2e56Smrg pNextSib->prevSib = pWin; 1677f7df2e56Smrg pParent->firstChild = pWin; 1678f7df2e56Smrg } 1679f7df2e56Smrg else { /* move in middle of list */ 168005b261ecSmrg 1681f7df2e56Smrg WindowPtr pOldNext = pWin->nextSib; 1682f7df2e56Smrg 1683f7df2e56Smrg pFirstChange = NullWindow; 1684f7df2e56Smrg if (pParent->firstChild == pWin) 1685f7df2e56Smrg pFirstChange = pParent->firstChild = pWin->nextSib; 1686f7df2e56Smrg if (pParent->lastChild == pWin) { 1687f7df2e56Smrg pFirstChange = pWin; 1688f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1689f7df2e56Smrg } 1690f7df2e56Smrg if (pWin->nextSib) 1691f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1692f7df2e56Smrg if (pWin->prevSib) 1693f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1694f7df2e56Smrg pWin->nextSib = pNextSib; 1695f7df2e56Smrg pWin->prevSib = pNextSib->prevSib; 1696f7df2e56Smrg if (pNextSib->prevSib) 1697f7df2e56Smrg pNextSib->prevSib->nextSib = pWin; 1698f7df2e56Smrg pNextSib->prevSib = pWin; 1699f7df2e56Smrg if (!pFirstChange) { /* do we know it yet? */ 1700f7df2e56Smrg pFirstChange = pParent->firstChild; /* no, search from top */ 1701f7df2e56Smrg while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) 1702f7df2e56Smrg pFirstChange = pFirstChange->nextSib; 1703f7df2e56Smrg } 1704f7df2e56Smrg } 1705f7df2e56Smrg if (pWin->drawable.pScreen->RestackWindow) 1706f7df2e56Smrg (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib); 170705b261ecSmrg } 170805b261ecSmrg 170905b261ecSmrg#ifdef ROOTLESS 171005b261ecSmrg /* 171105b261ecSmrg * In rootless mode we can't optimize away window restacks. 171205b261ecSmrg * There may be non-X windows around, so even if the window 171305b261ecSmrg * is in the correct position from X's point of view, 171405b261ecSmrg * the underlying window system may want to reorder it. 171505b261ecSmrg */ 171605b261ecSmrg else if (pWin->drawable.pScreen->RestackWindow) 1717f7df2e56Smrg (*pWin->drawable.pScreen->RestackWindow) (pWin, pWin->nextSib); 171805b261ecSmrg#endif 171905b261ecSmrg 17204202a189Smrg return pFirstChange; 172105b261ecSmrg} 172205b261ecSmrg 1723637ac9abSmrgvoid 1724f7df2e56SmrgSetWinSize(WindowPtr pWin) 172505b261ecSmrg{ 172605b261ecSmrg#ifdef COMPOSITE 1727f7df2e56Smrg if (pWin->redirectDraw != RedirectDrawNone) { 1728f7df2e56Smrg BoxRec box; 1729f7df2e56Smrg 1730f7df2e56Smrg /* 1731f7df2e56Smrg * Redirected clients get clip list equal to their 1732f7df2e56Smrg * own geometry, not clipped to their parent 1733f7df2e56Smrg */ 1734f7df2e56Smrg box.x1 = pWin->drawable.x; 1735f7df2e56Smrg box.y1 = pWin->drawable.y; 1736f7df2e56Smrg box.x2 = pWin->drawable.x + pWin->drawable.width; 1737f7df2e56Smrg box.y2 = pWin->drawable.y + pWin->drawable.height; 1738f7df2e56Smrg RegionReset(&pWin->winSize, &box); 173905b261ecSmrg } 174005b261ecSmrg else 174105b261ecSmrg#endif 1742f7df2e56Smrg ClippedRegionFromBox(pWin->parent, &pWin->winSize, 1743f7df2e56Smrg pWin->drawable.x, pWin->drawable.y, 1744f7df2e56Smrg (int) pWin->drawable.width, 1745f7df2e56Smrg (int) pWin->drawable.height); 1746f7df2e56Smrg if (wBoundingShape(pWin) || wClipShape(pWin)) { 1747f7df2e56Smrg RegionTranslate(&pWin->winSize, -pWin->drawable.x, -pWin->drawable.y); 1748f7df2e56Smrg if (wBoundingShape(pWin)) 1749f7df2e56Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, 1750f7df2e56Smrg wBoundingShape(pWin)); 1751f7df2e56Smrg if (wClipShape(pWin)) 1752f7df2e56Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, wClipShape(pWin)); 1753f7df2e56Smrg RegionTranslate(&pWin->winSize, pWin->drawable.x, pWin->drawable.y); 175405b261ecSmrg } 175505b261ecSmrg} 175605b261ecSmrg 1757637ac9abSmrgvoid 1758f7df2e56SmrgSetBorderSize(WindowPtr pWin) 175905b261ecSmrg{ 1760f7df2e56Smrg int bw; 176105b261ecSmrg 1762f7df2e56Smrg if (HasBorder(pWin)) { 1763f7df2e56Smrg bw = wBorderWidth(pWin); 176405b261ecSmrg#ifdef COMPOSITE 1765f7df2e56Smrg if (pWin->redirectDraw != RedirectDrawNone) { 1766f7df2e56Smrg BoxRec box; 1767f7df2e56Smrg 1768f7df2e56Smrg /* 1769f7df2e56Smrg * Redirected clients get clip list equal to their 1770f7df2e56Smrg * own geometry, not clipped to their parent 1771f7df2e56Smrg */ 1772f7df2e56Smrg box.x1 = pWin->drawable.x - bw; 1773f7df2e56Smrg box.y1 = pWin->drawable.y - bw; 1774f7df2e56Smrg box.x2 = pWin->drawable.x + pWin->drawable.width + bw; 1775f7df2e56Smrg box.y2 = pWin->drawable.y + pWin->drawable.height + bw; 1776f7df2e56Smrg RegionReset(&pWin->borderSize, &box); 1777f7df2e56Smrg } 1778f7df2e56Smrg else 177905b261ecSmrg#endif 1780f7df2e56Smrg ClippedRegionFromBox(pWin->parent, &pWin->borderSize, 1781f7df2e56Smrg pWin->drawable.x - bw, pWin->drawable.y - bw, 1782f7df2e56Smrg (int) (pWin->drawable.width + (bw << 1)), 1783f7df2e56Smrg (int) (pWin->drawable.height + (bw << 1))); 1784f7df2e56Smrg if (wBoundingShape(pWin)) { 1785f7df2e56Smrg RegionTranslate(&pWin->borderSize, -pWin->drawable.x, 1786f7df2e56Smrg -pWin->drawable.y); 1787f7df2e56Smrg RegionIntersect(&pWin->borderSize, &pWin->borderSize, 1788f7df2e56Smrg wBoundingShape(pWin)); 1789f7df2e56Smrg RegionTranslate(&pWin->borderSize, pWin->drawable.x, 1790f7df2e56Smrg pWin->drawable.y); 1791f7df2e56Smrg RegionUnion(&pWin->borderSize, &pWin->borderSize, &pWin->winSize); 1792f7df2e56Smrg } 1793f7df2e56Smrg } 1794f7df2e56Smrg else { 1795f7df2e56Smrg RegionCopy(&pWin->borderSize, &pWin->winSize); 179605b261ecSmrg } 179705b261ecSmrg} 179805b261ecSmrg 179905b261ecSmrg/** 180005b261ecSmrg * 180105b261ecSmrg * \param x,y new window position 180205b261ecSmrg * \param oldx,oldy old window position 180305b261ecSmrg * \param destx,desty position relative to gravity 180405b261ecSmrg */ 180505b261ecSmrg 18064202a189Smrgvoid 1807f7df2e56SmrgGravityTranslate(int x, int y, int oldx, int oldy, 1808f7df2e56Smrg int dw, int dh, unsigned gravity, int *destx, int *desty) 180905b261ecSmrg{ 181005b261ecSmrg switch (gravity) { 181105b261ecSmrg case NorthGravity: 1812f7df2e56Smrg *destx = x + dw / 2; 1813f7df2e56Smrg *desty = y; 1814f7df2e56Smrg break; 181505b261ecSmrg case NorthEastGravity: 1816f7df2e56Smrg *destx = x + dw; 1817f7df2e56Smrg *desty = y; 1818f7df2e56Smrg break; 181905b261ecSmrg case WestGravity: 1820f7df2e56Smrg *destx = x; 1821f7df2e56Smrg *desty = y + dh / 2; 1822f7df2e56Smrg break; 182305b261ecSmrg case CenterGravity: 1824f7df2e56Smrg *destx = x + dw / 2; 1825f7df2e56Smrg *desty = y + dh / 2; 1826f7df2e56Smrg break; 182705b261ecSmrg case EastGravity: 1828f7df2e56Smrg *destx = x + dw; 1829f7df2e56Smrg *desty = y + dh / 2; 1830f7df2e56Smrg break; 183105b261ecSmrg case SouthWestGravity: 1832f7df2e56Smrg *destx = x; 1833f7df2e56Smrg *desty = y + dh; 1834f7df2e56Smrg break; 183505b261ecSmrg case SouthGravity: 1836f7df2e56Smrg *destx = x + dw / 2; 1837f7df2e56Smrg *desty = y + dh; 1838f7df2e56Smrg break; 183905b261ecSmrg case SouthEastGravity: 1840f7df2e56Smrg *destx = x + dw; 1841f7df2e56Smrg *desty = y + dh; 1842f7df2e56Smrg break; 184305b261ecSmrg case StaticGravity: 1844f7df2e56Smrg *destx = oldx; 1845f7df2e56Smrg *desty = oldy; 1846f7df2e56Smrg break; 184705b261ecSmrg default: 1848f7df2e56Smrg *destx = x; 1849f7df2e56Smrg *desty = y; 1850f7df2e56Smrg break; 185105b261ecSmrg } 185205b261ecSmrg} 185305b261ecSmrg 185405b261ecSmrg/* XXX need to retile border on each window with ParentRelative origin */ 1855637ac9abSmrgvoid 185605b261ecSmrgResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) 185705b261ecSmrg{ 185805b261ecSmrg ScreenPtr pScreen; 185905b261ecSmrg WindowPtr pSib, pChild; 186005b261ecSmrg Bool resized = (dw || dh); 186105b261ecSmrg 186205b261ecSmrg pScreen = pWin->drawable.pScreen; 186305b261ecSmrg 1864f7df2e56Smrg for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) { 1865f7df2e56Smrg if (resized && (pSib->winGravity > NorthWestGravity)) { 1866f7df2e56Smrg int cwsx, cwsy; 1867f7df2e56Smrg 1868f7df2e56Smrg cwsx = pSib->origin.x; 1869f7df2e56Smrg cwsy = pSib->origin.y; 1870f7df2e56Smrg GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, 1871f7df2e56Smrg pSib->winGravity, &cwsx, &cwsy); 1872f7df2e56Smrg if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) { 1873f7df2e56Smrg xEvent event = { 1874f7df2e56Smrg .u.gravity.window = pSib->drawable.id, 1875f7df2e56Smrg .u.gravity.x = cwsx - wBorderWidth(pSib), 1876f7df2e56Smrg .u.gravity.y = cwsy - wBorderWidth(pSib) 1877f7df2e56Smrg }; 1878f7df2e56Smrg event.u.u.type = GravityNotify; 1879f7df2e56Smrg DeliverEvents(pSib, &event, 1, NullWindow); 1880f7df2e56Smrg pSib->origin.x = cwsx; 1881f7df2e56Smrg pSib->origin.y = cwsy; 1882f7df2e56Smrg } 1883f7df2e56Smrg } 1884f7df2e56Smrg pSib->drawable.x = pWin->drawable.x + pSib->origin.x; 1885f7df2e56Smrg pSib->drawable.y = pWin->drawable.y + pSib->origin.y; 1886f7df2e56Smrg SetWinSize(pSib); 1887f7df2e56Smrg SetBorderSize(pSib); 1888f7df2e56Smrg (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y); 1889f7df2e56Smrg 1890f7df2e56Smrg if ((pChild = pSib->firstChild)) { 1891f7df2e56Smrg while (1) { 1892f7df2e56Smrg pChild->drawable.x = pChild->parent->drawable.x + 1893f7df2e56Smrg pChild->origin.x; 1894f7df2e56Smrg pChild->drawable.y = pChild->parent->drawable.y + 1895f7df2e56Smrg pChild->origin.y; 1896f7df2e56Smrg SetWinSize(pChild); 1897f7df2e56Smrg SetBorderSize(pChild); 1898f7df2e56Smrg (*pScreen->PositionWindow) (pChild, 1899f7df2e56Smrg pChild->drawable.x, 1900f7df2e56Smrg pChild->drawable.y); 1901f7df2e56Smrg if (pChild->firstChild) { 1902f7df2e56Smrg pChild = pChild->firstChild; 1903f7df2e56Smrg continue; 1904f7df2e56Smrg } 1905f7df2e56Smrg while (!pChild->nextSib && (pChild != pSib)) 1906f7df2e56Smrg pChild = pChild->parent; 1907f7df2e56Smrg if (pChild == pSib) 1908f7df2e56Smrg break; 1909f7df2e56Smrg pChild = pChild->nextSib; 1910f7df2e56Smrg } 1911f7df2e56Smrg } 191205b261ecSmrg } 191305b261ecSmrg} 191405b261ecSmrg 191505b261ecSmrg#define GET_INT16(m, f) \ 191605b261ecSmrg if (m & mask) \ 191705b261ecSmrg { \ 191805b261ecSmrg f = (INT16) *pVlist;\ 191905b261ecSmrg pVlist++; \ 192005b261ecSmrg } 192105b261ecSmrg#define GET_CARD16(m, f) \ 192205b261ecSmrg if (m & mask) \ 192305b261ecSmrg { \ 192405b261ecSmrg f = (CARD16) *pVlist;\ 192505b261ecSmrg pVlist++;\ 192605b261ecSmrg } 192705b261ecSmrg 192805b261ecSmrg#define GET_CARD8(m, f) \ 192905b261ecSmrg if (m & mask) \ 193005b261ecSmrg { \ 193105b261ecSmrg f = (CARD8) *pVlist;\ 193205b261ecSmrg pVlist++;\ 193305b261ecSmrg } 193405b261ecSmrg 193505b261ecSmrg#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight)) 193605b261ecSmrg 193705b261ecSmrg/* 193805b261ecSmrg * IsSiblingAboveMe 1939f7df2e56Smrg * returns Above if pSib above pMe in stack or Below otherwise 194005b261ecSmrg */ 194105b261ecSmrg 194205b261ecSmrgstatic int 1943f7df2e56SmrgIsSiblingAboveMe(WindowPtr pMe, WindowPtr pSib) 194405b261ecSmrg{ 194505b261ecSmrg WindowPtr pWin; 194605b261ecSmrg 194705b261ecSmrg pWin = pMe->parent->firstChild; 1948f7df2e56Smrg while (pWin) { 1949f7df2e56Smrg if (pWin == pSib) 1950f7df2e56Smrg return Above; 1951f7df2e56Smrg else if (pWin == pMe) 1952f7df2e56Smrg return Below; 1953f7df2e56Smrg pWin = pWin->nextSib; 195405b261ecSmrg } 19554202a189Smrg return Below; 195605b261ecSmrg} 195705b261ecSmrg 195805b261ecSmrgstatic BoxPtr 1959f7df2e56SmrgWindowExtents(WindowPtr pWin, BoxPtr pBox) 1960f7df2e56Smrg{ 1961f7df2e56Smrg pBox->x1 = pWin->drawable.x - wBorderWidth(pWin); 1962f7df2e56Smrg pBox->y1 = pWin->drawable.y - wBorderWidth(pWin); 1963f7df2e56Smrg pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width 1964f7df2e56Smrg + wBorderWidth(pWin); 1965f7df2e56Smrg pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height 1966f7df2e56Smrg + wBorderWidth(pWin); 19674202a189Smrg return pBox; 196805b261ecSmrg} 196905b261ecSmrg 1970f7df2e56Smrg#define IS_SHAPED(pWin) (wBoundingShape (pWin) != NULL) 197105b261ecSmrg 197205b261ecSmrgstatic RegionPtr 1973f7df2e56SmrgMakeBoundingRegion(WindowPtr pWin, BoxPtr pBox) 197405b261ecSmrg{ 1975f7df2e56Smrg RegionPtr pRgn = RegionCreate(pBox, 1); 1976f7df2e56Smrg 1977f7df2e56Smrg if (wBoundingShape(pWin)) { 1978f7df2e56Smrg RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); 1979f7df2e56Smrg RegionIntersect(pRgn, pRgn, wBoundingShape(pWin)); 1980f7df2e56Smrg RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); 198105b261ecSmrg } 198205b261ecSmrg return pRgn; 198305b261ecSmrg} 198405b261ecSmrg 198505b261ecSmrgstatic Bool 1986f7df2e56SmrgShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox) 198705b261ecSmrg{ 1988f7df2e56Smrg RegionPtr pWinRgn, pSibRgn; 1989f7df2e56Smrg Bool ret; 199005b261ecSmrg 199105b261ecSmrg if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib)) 1992f7df2e56Smrg return TRUE; 1993f7df2e56Smrg pWinRgn = MakeBoundingRegion(pWin, pWinBox); 1994f7df2e56Smrg pSibRgn = MakeBoundingRegion(pSib, pSibBox); 19954202a189Smrg RegionIntersect(pWinRgn, pWinRgn, pSibRgn); 19964202a189Smrg ret = RegionNotEmpty(pWinRgn); 19974202a189Smrg RegionDestroy(pWinRgn); 19984202a189Smrg RegionDestroy(pSibRgn); 199905b261ecSmrg return ret; 200005b261ecSmrg} 200105b261ecSmrg 200205b261ecSmrgstatic Bool 2003f7df2e56SmrgAnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box) 200405b261ecSmrg{ 200505b261ecSmrg WindowPtr pSib; 200605b261ecSmrg BoxRec sboxrec; 200705b261ecSmrg BoxPtr sbox; 200805b261ecSmrg 2009f7df2e56Smrg for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) { 2010f7df2e56Smrg if (pSib->mapped) { 2011f7df2e56Smrg sbox = WindowExtents(pSib, &sboxrec); 2012f7df2e56Smrg if (BOXES_OVERLAP(sbox, box) 2013f7df2e56Smrg && ShapeOverlap(pWin, box, pSib, sbox)) 2014f7df2e56Smrg return TRUE; 2015f7df2e56Smrg } 201605b261ecSmrg } 20174202a189Smrg return FALSE; 201805b261ecSmrg} 201905b261ecSmrg 202005b261ecSmrgstatic Bool 2021f7df2e56SmrgIOverlapAnyWindow(WindowPtr pWin, BoxPtr box) 202205b261ecSmrg{ 202305b261ecSmrg WindowPtr pSib; 202405b261ecSmrg BoxRec sboxrec; 202505b261ecSmrg BoxPtr sbox; 202605b261ecSmrg 2027f7df2e56Smrg for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) { 2028f7df2e56Smrg if (pSib->mapped) { 2029f7df2e56Smrg sbox = WindowExtents(pSib, &sboxrec); 2030f7df2e56Smrg if (BOXES_OVERLAP(sbox, box) 2031f7df2e56Smrg && ShapeOverlap(pWin, box, pSib, sbox)) 2032f7df2e56Smrg return TRUE; 2033f7df2e56Smrg } 203405b261ecSmrg } 20354202a189Smrg return FALSE; 203605b261ecSmrg} 203705b261ecSmrg 203805b261ecSmrg/* 2039f7df2e56Smrg * WhereDoIGoInTheStack() 204005b261ecSmrg * Given pWin and pSib and the relationshipe smode, return 204105b261ecSmrg * the window that pWin should go ABOVE. 204205b261ecSmrg * If a pSib is specified: 204305b261ecSmrg * Above: pWin is placed just above pSib 204405b261ecSmrg * Below: pWin is placed just below pSib 204505b261ecSmrg * TopIf: if pSib occludes pWin, then pWin is placed 204605b261ecSmrg * at the top of the stack 2047f7df2e56Smrg * BottomIf: if pWin occludes pSib, then pWin is 204805b261ecSmrg * placed at the bottom of the stack 204905b261ecSmrg * Opposite: if pSib occludes pWin, then pWin is placed at the 205005b261ecSmrg * top of the stack, else if pWin occludes pSib, then 205105b261ecSmrg * pWin is placed at the bottom of the stack 205205b261ecSmrg * 205305b261ecSmrg * If pSib is NULL: 205405b261ecSmrg * Above: pWin is placed at the top of the stack 205505b261ecSmrg * Below: pWin is placed at the bottom of the stack 205605b261ecSmrg * TopIf: if any sibling occludes pWin, then pWin is placed at 205705b261ecSmrg * the top of the stack 205805b261ecSmrg * BottomIf: if pWin occludes any sibline, then pWin is placed at 205905b261ecSmrg * the bottom of the stack 206005b261ecSmrg * Opposite: if any sibling occludes pWin, then pWin is placed at 206105b261ecSmrg * the top of the stack, else if pWin occludes any 206205b261ecSmrg * sibling, then pWin is placed at the bottom of the stack 206305b261ecSmrg * 206405b261ecSmrg */ 206505b261ecSmrg 206605b261ecSmrgstatic WindowPtr 2067f7df2e56SmrgWhereDoIGoInTheStack(WindowPtr pWin, 2068f7df2e56Smrg WindowPtr pSib, 2069f7df2e56Smrg short x, 2070f7df2e56Smrg short y, unsigned short w, unsigned short h, int smode) 207105b261ecSmrg{ 207205b261ecSmrg BoxRec box; 207305b261ecSmrg WindowPtr pHead, pFirst; 207405b261ecSmrg 2075f7df2e56Smrg if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild)) 2076f7df2e56Smrg return NULL; 207705b261ecSmrg pHead = RealChildHead(pWin->parent); 207805b261ecSmrg pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; 207905b261ecSmrg box.x1 = x; 208005b261ecSmrg box.y1 = y; 2081f7df2e56Smrg box.x2 = x + (int) w; 2082f7df2e56Smrg box.y2 = y + (int) h; 2083f7df2e56Smrg switch (smode) { 2084f7df2e56Smrg case Above: 2085f7df2e56Smrg if (pSib) 2086f7df2e56Smrg return pSib; 2087f7df2e56Smrg else if (pWin == pFirst) 2088f7df2e56Smrg return pWin->nextSib; 2089f7df2e56Smrg else 2090f7df2e56Smrg return pFirst; 2091f7df2e56Smrg case Below: 2092f7df2e56Smrg if (pSib) 2093f7df2e56Smrg if (pSib->nextSib != pWin) 2094f7df2e56Smrg return pSib->nextSib; 2095f7df2e56Smrg else 2096f7df2e56Smrg return pWin->nextSib; 2097f7df2e56Smrg else 2098f7df2e56Smrg return NullWindow; 2099f7df2e56Smrg case TopIf: 2100f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2101f7df2e56Smrg return pWin->nextSib; 2102f7df2e56Smrg else if (pSib) { 2103f7df2e56Smrg if ((IsSiblingAboveMe(pWin, pSib) == Above) && 2104f7df2e56Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2105f7df2e56Smrg return pFirst; 2106f7df2e56Smrg else 2107f7df2e56Smrg return pWin->nextSib; 2108f7df2e56Smrg } 2109f7df2e56Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) 2110f7df2e56Smrg return pFirst; 2111f7df2e56Smrg else 2112f7df2e56Smrg return pWin->nextSib; 2113f7df2e56Smrg case BottomIf: 2114f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2115f7df2e56Smrg return pWin->nextSib; 2116f7df2e56Smrg else if (pSib) { 2117f7df2e56Smrg if ((IsSiblingAboveMe(pWin, pSib) == Below) && 2118f7df2e56Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2119f7df2e56Smrg return NullWindow; 2120f7df2e56Smrg else 2121f7df2e56Smrg return pWin->nextSib; 2122f7df2e56Smrg } 2123f7df2e56Smrg else if (IOverlapAnyWindow(pWin, &box)) 2124f7df2e56Smrg return NullWindow; 2125f7df2e56Smrg else 2126f7df2e56Smrg return pWin->nextSib; 2127f7df2e56Smrg case Opposite: 2128f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2129f7df2e56Smrg return pWin->nextSib; 2130f7df2e56Smrg else if (pSib) { 2131f7df2e56Smrg if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) { 2132f7df2e56Smrg if (IsSiblingAboveMe(pWin, pSib) == Above) 2133f7df2e56Smrg return pFirst; 2134f7df2e56Smrg else 2135f7df2e56Smrg return NullWindow; 2136f7df2e56Smrg } 2137f7df2e56Smrg else 2138f7df2e56Smrg return pWin->nextSib; 2139f7df2e56Smrg } 2140f7df2e56Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) { 2141f7df2e56Smrg /* If I'm occluded, I can't possibly be the first child 2142f7df2e56Smrg * if (pWin == pWin->parent->firstChild) 2143f7df2e56Smrg * return pWin->nextSib; 2144f7df2e56Smrg */ 2145f7df2e56Smrg return pFirst; 2146f7df2e56Smrg } 2147f7df2e56Smrg else if (IOverlapAnyWindow(pWin, &box)) 2148f7df2e56Smrg return NullWindow; 2149f7df2e56Smrg else 2150f7df2e56Smrg return pWin->nextSib; 2151f7df2e56Smrg default: 215205b261ecSmrg { 2153f7df2e56Smrg /* should never happen; make something up. */ 2154f7df2e56Smrg return pWin->nextSib; 2155f7df2e56Smrg } 215605b261ecSmrg } 215705b261ecSmrg} 215805b261ecSmrg 215905b261ecSmrgstatic void 2160f7df2e56SmrgReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) 216105b261ecSmrg{ 216205b261ecSmrg/* Note that pSib might be NULL */ 216305b261ecSmrg 2164f7df2e56Smrg Bool WasViewable = (Bool) pWin->viewable; 216505b261ecSmrg Bool anyMarked; 216605b261ecSmrg WindowPtr pFirstChange; 2167f7df2e56Smrg WindowPtr pLayerWin; 216805b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 216905b261ecSmrg 217005b261ecSmrg /* if this is a root window, can't be restacked */ 217105b261ecSmrg if (!pWin->parent) 2172f7df2e56Smrg return; 217305b261ecSmrg 217405b261ecSmrg pFirstChange = MoveWindowInStack(pWin, pSib); 217505b261ecSmrg 2176f7df2e56Smrg if (WasViewable) { 2177f7df2e56Smrg anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, 2178f7df2e56Smrg &pLayerWin); 2179f7df2e56Smrg if (pLayerWin != pWin) 2180f7df2e56Smrg pFirstChange = pLayerWin; 2181f7df2e56Smrg if (anyMarked) { 2182f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind); 2183f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2184f7df2e56Smrg if (pWin->drawable.pScreen->PostValidateTree) 2185f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, 2186f7df2e56Smrg kind); 2187f7df2e56Smrg } 218805b261ecSmrg } 218905b261ecSmrg if (pWin->realized) 2190f7df2e56Smrg WindowsRestructured(); 219105b261ecSmrg} 219205b261ecSmrg 219305b261ecSmrg/***** 219405b261ecSmrg * ConfigureWindow 219505b261ecSmrg *****/ 219605b261ecSmrg 219705b261ecSmrgint 219805b261ecSmrgConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) 219905b261ecSmrg{ 220005b261ecSmrg#define RESTACK_WIN 0 220105b261ecSmrg#define MOVE_WIN 1 220205b261ecSmrg#define RESIZE_WIN 2 220305b261ecSmrg#define REBORDER_WIN 3 220405b261ecSmrg WindowPtr pSib = NullWindow; 220505b261ecSmrg WindowPtr pParent = pWin->parent; 220605b261ecSmrg Window sibwid = 0; 220705b261ecSmrg Mask index2, tmask; 220805b261ecSmrg XID *pVlist; 2209f7df2e56Smrg short x, y, beforeX, beforeY; 221005b261ecSmrg unsigned short w = pWin->drawable.width, 2211f7df2e56Smrg h = pWin->drawable.height, bw = pWin->borderWidth; 2212637ac9abSmrg int rc, action, smode = Above; 221305b261ecSmrg 2214f7df2e56Smrg if ((pWin->drawable.class == InputOnly) && (mask & CWBorderWidth)) 2215f7df2e56Smrg return BadMatch; 221605b261ecSmrg 221705b261ecSmrg if ((mask & CWSibling) && !(mask & CWStackMode)) 2218f7df2e56Smrg return BadMatch; 221905b261ecSmrg 222005b261ecSmrg pVlist = vlist; 222105b261ecSmrg 2222f7df2e56Smrg if (pParent) { 2223f7df2e56Smrg x = pWin->drawable.x - pParent->drawable.x - (int) bw; 2224f7df2e56Smrg y = pWin->drawable.y - pParent->drawable.y - (int) bw; 222505b261ecSmrg } 2226f7df2e56Smrg else { 2227f7df2e56Smrg x = pWin->drawable.x; 2228f7df2e56Smrg y = pWin->drawable.y; 222905b261ecSmrg } 223005b261ecSmrg beforeX = x; 223105b261ecSmrg beforeY = y; 2232f7df2e56Smrg action = RESTACK_WIN; 2233f7df2e56Smrg if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) { 2234f7df2e56Smrg GET_INT16(CWX, x); 2235f7df2e56Smrg GET_INT16(CWY, y); 2236f7df2e56Smrg action = MOVE_WIN; 2237f7df2e56Smrg } 2238f7df2e56Smrg /* or should be resized */ 2239f7df2e56Smrg else if (mask & (CWX | CWY | CWWidth | CWHeight)) { 2240f7df2e56Smrg GET_INT16(CWX, x); 2241f7df2e56Smrg GET_INT16(CWY, y); 2242f7df2e56Smrg GET_CARD16(CWWidth, w); 2243f7df2e56Smrg GET_CARD16(CWHeight, h); 2244f7df2e56Smrg if (!w || !h) { 2245f7df2e56Smrg client->errorValue = 0; 2246f7df2e56Smrg return BadValue; 2247f7df2e56Smrg } 2248f7df2e56Smrg action = RESIZE_WIN; 224905b261ecSmrg } 225005b261ecSmrg tmask = mask & ~ChangeMask; 2251f7df2e56Smrg while (tmask) { 2252f7df2e56Smrg index2 = (Mask) lowbit(tmask); 2253f7df2e56Smrg tmask &= ~index2; 2254f7df2e56Smrg switch (index2) { 2255f7df2e56Smrg case CWBorderWidth: 2256f7df2e56Smrg GET_CARD16(CWBorderWidth, bw); 2257f7df2e56Smrg break; 2258f7df2e56Smrg case CWSibling: 2259f7df2e56Smrg sibwid = (Window) *pVlist; 2260f7df2e56Smrg pVlist++; 2261f7df2e56Smrg rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess); 2262f7df2e56Smrg if (rc != Success) { 2263f7df2e56Smrg client->errorValue = sibwid; 2264f7df2e56Smrg return rc; 2265f7df2e56Smrg } 2266f7df2e56Smrg if (pSib->parent != pParent) 2267f7df2e56Smrg return BadMatch; 2268f7df2e56Smrg if (pSib == pWin) 2269f7df2e56Smrg return BadMatch; 2270f7df2e56Smrg break; 2271f7df2e56Smrg case CWStackMode: 2272f7df2e56Smrg GET_CARD8(CWStackMode, smode); 2273f7df2e56Smrg if ((smode != TopIf) && (smode != BottomIf) && 2274f7df2e56Smrg (smode != Opposite) && (smode != Above) && (smode != Below)) { 2275f7df2e56Smrg client->errorValue = smode; 2276f7df2e56Smrg return BadValue; 2277f7df2e56Smrg } 2278f7df2e56Smrg break; 2279f7df2e56Smrg default: 2280f7df2e56Smrg client->errorValue = mask; 2281f7df2e56Smrg return BadValue; 2282f7df2e56Smrg } 2283f7df2e56Smrg } 2284f7df2e56Smrg /* root really can't be reconfigured, so just return */ 228505b261ecSmrg if (!pParent) 2286f7df2e56Smrg return Success; 228705b261ecSmrg 2288f7df2e56Smrg /* Figure out if the window should be moved. Doesnt 2289f7df2e56Smrg make the changes to the window if event sent */ 229005b261ecSmrg 229105b261ecSmrg if (mask & CWStackMode) 2292f7df2e56Smrg pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, 2293f7df2e56Smrg pParent->drawable.y + y, 2294f7df2e56Smrg w + (bw << 1), h + (bw << 1), smode); 229505b261ecSmrg else 2296f7df2e56Smrg pSib = pWin->nextSib; 2297f7df2e56Smrg 2298f7df2e56Smrg if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) { 2299f7df2e56Smrg xEvent event = { 2300f7df2e56Smrg .u.configureRequest.window = pWin->drawable.id, 2301f7df2e56Smrg .u.configureRequest.sibling = (mask & CWSibling) ? sibwid : None, 2302f7df2e56Smrg .u.configureRequest.x = x, 2303f7df2e56Smrg .u.configureRequest.y = y, 2304f7df2e56Smrg .u.configureRequest.width = w, 2305f7df2e56Smrg .u.configureRequest.height = h, 2306f7df2e56Smrg .u.configureRequest.borderWidth = bw, 2307f7df2e56Smrg .u.configureRequest.valueMask = mask, 2308f7df2e56Smrg .u.configureRequest.parent = pParent->drawable.id 2309f7df2e56Smrg }; 2310f7df2e56Smrg event.u.u.type = ConfigureRequest; 2311f7df2e56Smrg event.u.u.detail = (mask & CWStackMode) ? smode : Above; 231205b261ecSmrg#ifdef PANORAMIX 2313f7df2e56Smrg if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { 23144202a189Smrg event.u.configureRequest.x += screenInfo.screens[0]->x; 23154202a189Smrg event.u.configureRequest.y += screenInfo.screens[0]->y; 2316f7df2e56Smrg } 231705b261ecSmrg#endif 2318f7df2e56Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2319f7df2e56Smrg SubstructureRedirectMask, client) == 1) 2320f7df2e56Smrg return Success; 232105b261ecSmrg } 2322f7df2e56Smrg if (action == RESIZE_WIN) { 2323f7df2e56Smrg Bool size_change = (w != pWin->drawable.width) 2324f7df2e56Smrg || (h != pWin->drawable.height); 2325f7df2e56Smrg 2326f7df2e56Smrg if (size_change && 2327f7df2e56Smrg ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) { 2328f7df2e56Smrg xEvent eventT = { 2329f7df2e56Smrg .u.resizeRequest.window = pWin->drawable.id, 2330f7df2e56Smrg .u.resizeRequest.width = w, 2331f7df2e56Smrg .u.resizeRequest.height = h 2332f7df2e56Smrg }; 2333f7df2e56Smrg eventT.u.u.type = ResizeRequest; 2334f7df2e56Smrg if (MaybeDeliverEventsToClient(pWin, &eventT, 1, 2335f7df2e56Smrg ResizeRedirectMask, client) == 1) { 2336f7df2e56Smrg /* if event is delivered, leave the actual size alone. */ 2337f7df2e56Smrg w = pWin->drawable.width; 2338f7df2e56Smrg h = pWin->drawable.height; 2339f7df2e56Smrg size_change = FALSE; 2340f7df2e56Smrg } 2341f7df2e56Smrg } 2342f7df2e56Smrg if (!size_change) { 2343f7df2e56Smrg if (mask & (CWX | CWY)) 2344f7df2e56Smrg action = MOVE_WIN; 2345f7df2e56Smrg else if (mask & (CWStackMode | CWBorderWidth)) 2346f7df2e56Smrg action = RESTACK_WIN; 2347f7df2e56Smrg else /* really nothing to do */ 2348f7df2e56Smrg return (Success); 2349f7df2e56Smrg } 235005b261ecSmrg } 235105b261ecSmrg 235205b261ecSmrg if (action == RESIZE_WIN) 2353f7df2e56Smrg /* we've already checked whether there's really a size change */ 2354f7df2e56Smrg goto ActuallyDoSomething; 235505b261ecSmrg if ((mask & CWX) && (x != beforeX)) 2356f7df2e56Smrg goto ActuallyDoSomething; 235705b261ecSmrg if ((mask & CWY) && (y != beforeY)) 2358f7df2e56Smrg goto ActuallyDoSomething; 2359f7df2e56Smrg if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin))) 2360f7df2e56Smrg goto ActuallyDoSomething; 2361f7df2e56Smrg if (mask & CWStackMode) { 236205b261ecSmrg#ifndef ROOTLESS 236305b261ecSmrg /* See above for why we always reorder in rootless mode. */ 2364f7df2e56Smrg if (pWin->nextSib != pSib) 236505b261ecSmrg#endif 2366f7df2e56Smrg goto ActuallyDoSomething; 236705b261ecSmrg } 23684202a189Smrg return Success; 236905b261ecSmrg 2370f7df2e56Smrg ActuallyDoSomething: 2371f7df2e56Smrg if (pWin->drawable.pScreen->ConfigNotify) { 2372f7df2e56Smrg int ret; 2373f7df2e56Smrg 2374f7df2e56Smrg ret = 2375f7df2e56Smrg (*pWin->drawable.pScreen->ConfigNotify) (pWin, x, y, w, h, bw, 2376f7df2e56Smrg pSib); 2377f7df2e56Smrg if (ret) { 2378f7df2e56Smrg client->errorValue = 0; 2379f7df2e56Smrg return ret; 2380f7df2e56Smrg } 23814202a189Smrg } 23824202a189Smrg 2383f7df2e56Smrg if (SubStrSend(pWin, pParent)) { 2384f7df2e56Smrg xEvent event = { 2385f7df2e56Smrg .u.configureNotify.window = pWin->drawable.id, 2386f7df2e56Smrg .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None, 2387f7df2e56Smrg .u.configureNotify.x = x, 2388f7df2e56Smrg .u.configureNotify.y = y, 2389f7df2e56Smrg .u.configureNotify.width = w, 2390f7df2e56Smrg .u.configureNotify.height = h, 2391f7df2e56Smrg .u.configureNotify.borderWidth = bw, 2392f7df2e56Smrg .u.configureNotify.override = pWin->overrideRedirect 2393f7df2e56Smrg }; 2394f7df2e56Smrg event.u.u.type = ConfigureNotify; 239505b261ecSmrg#ifdef PANORAMIX 2396f7df2e56Smrg if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { 2397f7df2e56Smrg event.u.configureNotify.x += screenInfo.screens[0]->x; 2398f7df2e56Smrg event.u.configureNotify.y += screenInfo.screens[0]->y; 2399f7df2e56Smrg } 240005b261ecSmrg#endif 2401f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 240205b261ecSmrg } 2403f7df2e56Smrg if (mask & CWBorderWidth) { 2404f7df2e56Smrg if (action == RESTACK_WIN) { 2405f7df2e56Smrg action = MOVE_WIN; 2406f7df2e56Smrg pWin->borderWidth = bw; 2407f7df2e56Smrg } 2408f7df2e56Smrg else if ((action == MOVE_WIN) && 2409f7df2e56Smrg (beforeX + wBorderWidth(pWin) == x + (int) bw) && 2410f7df2e56Smrg (beforeY + wBorderWidth(pWin) == y + (int) bw)) { 2411f7df2e56Smrg action = REBORDER_WIN; 2412f7df2e56Smrg (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw); 2413f7df2e56Smrg } 2414f7df2e56Smrg else 2415f7df2e56Smrg pWin->borderWidth = bw; 241605b261ecSmrg } 241705b261ecSmrg if (action == MOVE_WIN) 2418f7df2e56Smrg (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib, 2419f7df2e56Smrg (mask & CWBorderWidth) ? VTOther 2420f7df2e56Smrg : VTMove); 242105b261ecSmrg else if (action == RESIZE_WIN) 2422f7df2e56Smrg (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); 242305b261ecSmrg else if (mask & CWStackMode) 2424f7df2e56Smrg ReflectStackChange(pWin, pSib, VTOther); 242505b261ecSmrg 242605b261ecSmrg if (action != RESTACK_WIN) 2427f7df2e56Smrg CheckCursorConfinement(pWin); 24284202a189Smrg return Success; 242905b261ecSmrg#undef RESTACK_WIN 243005b261ecSmrg#undef MOVE_WIN 243105b261ecSmrg#undef RESIZE_WIN 243205b261ecSmrg#undef REBORDER_WIN 243305b261ecSmrg} 243405b261ecSmrg 243505b261ecSmrg/****** 243605b261ecSmrg * 243705b261ecSmrg * CirculateWindow 243805b261ecSmrg * For RaiseLowest, raises the lowest mapped child (if any) that is 243905b261ecSmrg * obscured by another child to the top of the stack. For LowerHighest, 244005b261ecSmrg * lowers the highest mapped child (if any) that is obscuring another 2441f7df2e56Smrg * child to the bottom of the stack. Exposure processing is performed 244205b261ecSmrg * 244305b261ecSmrg ******/ 244405b261ecSmrg 244505b261ecSmrgint 244605b261ecSmrgCirculateWindow(WindowPtr pParent, int direction, ClientPtr client) 244705b261ecSmrg{ 244805b261ecSmrg WindowPtr pWin, pHead, pFirst; 244905b261ecSmrg xEvent event; 245005b261ecSmrg BoxRec box; 245105b261ecSmrg 245205b261ecSmrg pHead = RealChildHead(pParent); 245305b261ecSmrg pFirst = pHead ? pHead->nextSib : pParent->firstChild; 2454f7df2e56Smrg if (direction == RaiseLowest) { 2455f7df2e56Smrg for (pWin = pParent->lastChild; 2456f7df2e56Smrg (pWin != pHead) && 2457f7df2e56Smrg !(pWin->mapped && 2458f7df2e56Smrg AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); 2459f7df2e56Smrg pWin = pWin->prevSib); 2460f7df2e56Smrg if (pWin == pHead) 2461f7df2e56Smrg return Success; 2462f7df2e56Smrg } 2463f7df2e56Smrg else { 2464f7df2e56Smrg for (pWin = pFirst; 2465f7df2e56Smrg pWin && 2466f7df2e56Smrg !(pWin->mapped && 2467f7df2e56Smrg IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); 2468f7df2e56Smrg pWin = pWin->nextSib); 2469f7df2e56Smrg if (!pWin) 2470f7df2e56Smrg return Success; 247105b261ecSmrg } 247205b261ecSmrg 2473f7df2e56Smrg event = (xEvent) { 2474f7df2e56Smrg .u.circulate.window = pWin->drawable.id, 2475f7df2e56Smrg .u.circulate.parent = pParent->drawable.id, 2476f7df2e56Smrg .u.circulate.event = pParent->drawable.id, 2477f7df2e56Smrg .u.circulate.place = (direction == RaiseLowest) ? 2478f7df2e56Smrg PlaceOnTop : PlaceOnBottom, 2479f7df2e56Smrg }; 2480f7df2e56Smrg 2481f7df2e56Smrg if (RedirectSend(pParent)) { 2482f7df2e56Smrg event.u.u.type = CirculateRequest; 2483f7df2e56Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2484f7df2e56Smrg SubstructureRedirectMask, client) == 1) 2485f7df2e56Smrg return Success; 248605b261ecSmrg } 248705b261ecSmrg 248805b261ecSmrg event.u.u.type = CirculateNotify; 248905b261ecSmrg DeliverEvents(pWin, &event, 1, NullWindow); 249005b261ecSmrg ReflectStackChange(pWin, 2491f7df2e56Smrg (direction == RaiseLowest) ? pFirst : NullWindow, 2492f7df2e56Smrg VTStack); 249305b261ecSmrg 24944202a189Smrg return Success; 249505b261ecSmrg} 249605b261ecSmrg 249705b261ecSmrgstatic int 2498f7df2e56SmrgCompareWIDs(WindowPtr pWin, void *value) 2499f7df2e56Smrg{ /* must conform to VisitWindowProcPtr */ 2500f7df2e56Smrg Window *wid = (Window *) value; 250105b261ecSmrg 250205b261ecSmrg if (pWin->drawable.id == *wid) 2503f7df2e56Smrg return WT_STOPWALKING; 250405b261ecSmrg else 2505f7df2e56Smrg return WT_WALKCHILDREN; 250605b261ecSmrg} 250705b261ecSmrg 250805b261ecSmrg/***** 250905b261ecSmrg * ReparentWindow 251005b261ecSmrg *****/ 251105b261ecSmrg 251205b261ecSmrgint 251305b261ecSmrgReparentWindow(WindowPtr pWin, WindowPtr pParent, 251405b261ecSmrg int x, int y, ClientPtr client) 251505b261ecSmrg{ 251605b261ecSmrg WindowPtr pPrev, pPriorParent; 2517f7df2e56Smrg Bool WasMapped = (Bool) (pWin->mapped); 251805b261ecSmrg xEvent event; 2519f7df2e56Smrg int bw = wBorderWidth(pWin); 252005b261ecSmrg ScreenPtr pScreen; 252105b261ecSmrg 252205b261ecSmrg pScreen = pWin->drawable.pScreen; 2523f7df2e56Smrg if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) == 2524f7df2e56Smrg WT_STOPWALKING) 2525f7df2e56Smrg return BadMatch; 252605b261ecSmrg if (!MakeWindowOptional(pWin)) 2527f7df2e56Smrg return BadAlloc; 252805b261ecSmrg 252905b261ecSmrg if (WasMapped) 2530f7df2e56Smrg UnmapWindow(pWin, FALSE); 2531f7df2e56Smrg 2532f7df2e56Smrg event = (xEvent) { 2533f7df2e56Smrg .u.reparent.window = pWin->drawable.id, 2534f7df2e56Smrg .u.reparent.parent = pParent->drawable.id, 2535f7df2e56Smrg .u.reparent.x = x, 2536f7df2e56Smrg .u.reparent.y = y, 2537f7df2e56Smrg .u.reparent.override = pWin->overrideRedirect 2538f7df2e56Smrg }; 253905b261ecSmrg event.u.u.type = ReparentNotify; 254005b261ecSmrg#ifdef PANORAMIX 2541f7df2e56Smrg if (!noPanoramiXExtension && !pParent->parent) { 2542f7df2e56Smrg event.u.reparent.x += screenInfo.screens[0]->x; 2543f7df2e56Smrg event.u.reparent.y += screenInfo.screens[0]->y; 254405b261ecSmrg } 254505b261ecSmrg#endif 254605b261ecSmrg DeliverEvents(pWin, &event, 1, pParent); 254705b261ecSmrg 254805b261ecSmrg /* take out of sibling chain */ 254905b261ecSmrg 255005b261ecSmrg pPriorParent = pPrev = pWin->parent; 255105b261ecSmrg if (pPrev->firstChild == pWin) 2552f7df2e56Smrg pPrev->firstChild = pWin->nextSib; 255305b261ecSmrg if (pPrev->lastChild == pWin) 2554f7df2e56Smrg pPrev->lastChild = pWin->prevSib; 255505b261ecSmrg 255605b261ecSmrg if (pWin->nextSib) 2557f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 255805b261ecSmrg if (pWin->prevSib) 2559f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 256005b261ecSmrg 256105b261ecSmrg /* insert at begining of pParent */ 256205b261ecSmrg pWin->parent = pParent; 256305b261ecSmrg pPrev = RealChildHead(pParent); 2564f7df2e56Smrg if (pPrev) { 2565f7df2e56Smrg pWin->nextSib = pPrev->nextSib; 2566f7df2e56Smrg if (pPrev->nextSib) 2567f7df2e56Smrg pPrev->nextSib->prevSib = pWin; 2568f7df2e56Smrg else 2569f7df2e56Smrg pParent->lastChild = pWin; 2570f7df2e56Smrg pPrev->nextSib = pWin; 2571f7df2e56Smrg pWin->prevSib = pPrev; 257205b261ecSmrg } 2573f7df2e56Smrg else { 2574f7df2e56Smrg pWin->nextSib = pParent->firstChild; 2575f7df2e56Smrg pWin->prevSib = NullWindow; 2576f7df2e56Smrg if (pParent->firstChild) 2577f7df2e56Smrg pParent->firstChild->prevSib = pWin; 2578f7df2e56Smrg else 2579f7df2e56Smrg pParent->lastChild = pWin; 2580f7df2e56Smrg pParent->firstChild = pWin; 258105b261ecSmrg } 258205b261ecSmrg 258305b261ecSmrg pWin->origin.x = x + bw; 258405b261ecSmrg pWin->origin.y = y + bw; 258505b261ecSmrg pWin->drawable.x = x + bw + pParent->drawable.x; 258605b261ecSmrg pWin->drawable.y = y + bw + pParent->drawable.y; 258705b261ecSmrg 258805b261ecSmrg /* clip to parent */ 2589f7df2e56Smrg SetWinSize(pWin); 2590f7df2e56Smrg SetBorderSize(pWin); 259105b261ecSmrg 259205b261ecSmrg if (pScreen->ReparentWindow) 2593f7df2e56Smrg (*pScreen->ReparentWindow) (pWin, pPriorParent); 2594f7df2e56Smrg (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); 259505b261ecSmrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 259605b261ecSmrg 259705b261ecSmrg CheckWindowOptionalNeed(pWin); 259805b261ecSmrg 259905b261ecSmrg if (WasMapped) 2600f7df2e56Smrg MapWindow(pWin, client); 260105b261ecSmrg RecalculateDeliverableEvents(pWin); 26024202a189Smrg return Success; 260305b261ecSmrg} 260405b261ecSmrg 260505b261ecSmrgstatic void 260605b261ecSmrgRealizeTree(WindowPtr pWin) 260705b261ecSmrg{ 260805b261ecSmrg WindowPtr pChild; 260905b261ecSmrg RealizeWindowProcPtr Realize; 261005b261ecSmrg 261105b261ecSmrg Realize = pWin->drawable.pScreen->RealizeWindow; 261205b261ecSmrg pChild = pWin; 2613f7df2e56Smrg while (1) { 2614f7df2e56Smrg if (pChild->mapped) { 2615f7df2e56Smrg pChild->realized = TRUE; 2616f7df2e56Smrg pChild->viewable = (pChild->drawable.class == InputOutput); 2617f7df2e56Smrg (*Realize) (pChild); 2618f7df2e56Smrg if (pChild->firstChild) { 2619f7df2e56Smrg pChild = pChild->firstChild; 2620f7df2e56Smrg continue; 2621f7df2e56Smrg } 2622f7df2e56Smrg } 2623f7df2e56Smrg while (!pChild->nextSib && (pChild != pWin)) 2624f7df2e56Smrg pChild = pChild->parent; 2625f7df2e56Smrg if (pChild == pWin) 2626f7df2e56Smrg return; 2627f7df2e56Smrg pChild = pChild->nextSib; 2628f7df2e56Smrg } 262905b261ecSmrg} 263005b261ecSmrg 2631f7df2e56Smrgstatic Bool 2632f7df2e56SmrgMaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client) 263305b261ecSmrg{ 2634f7df2e56Smrg xEvent event = { 2635f7df2e56Smrg .u.mapRequest.window = pWin->drawable.id, 2636f7df2e56Smrg .u.mapRequest.parent = pParent->drawable.id 2637f7df2e56Smrg }; 2638f7df2e56Smrg event.u.u.type = MapRequest; 2639f7df2e56Smrg 2640f7df2e56Smrg return MaybeDeliverEventsToClient(pParent, &event, 1, 2641f7df2e56Smrg SubstructureRedirectMask, 2642f7df2e56Smrg client) == 1; 264305b261ecSmrg} 264405b261ecSmrg 2645f7df2e56Smrgstatic void 2646f7df2e56SmrgDeliverMapNotify(WindowPtr pWin) 264705b261ecSmrg{ 2648f7df2e56Smrg xEvent event = { 2649f7df2e56Smrg .u.mapNotify.window = pWin->drawable.id, 2650f7df2e56Smrg .u.mapNotify.override = pWin->overrideRedirect, 2651f7df2e56Smrg }; 2652f7df2e56Smrg event.u.u.type = MapNotify; 2653f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 265405b261ecSmrg} 265505b261ecSmrg 265605b261ecSmrg/***** 265705b261ecSmrg * MapWindow 265805b261ecSmrg * If some other client has selected SubStructureReDirect on the parent 265905b261ecSmrg * and override-redirect is xFalse, then a MapRequest event is generated, 266005b261ecSmrg * but the window remains unmapped. Otherwise, the window is mapped and a 266105b261ecSmrg * MapNotify event is generated. 266205b261ecSmrg *****/ 266305b261ecSmrg 26644202a189Smrgint 266505b261ecSmrgMapWindow(WindowPtr pWin, ClientPtr client) 266605b261ecSmrg{ 266705b261ecSmrg ScreenPtr pScreen; 266805b261ecSmrg 266905b261ecSmrg WindowPtr pParent; 2670f7df2e56Smrg WindowPtr pLayerWin; 267105b261ecSmrg 267205b261ecSmrg if (pWin->mapped) 2673f7df2e56Smrg return Success; 267405b261ecSmrg 2675f7df2e56Smrg /* general check for permission to map window */ 2676637ac9abSmrg if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, 2677f7df2e56Smrg pWin, RT_NONE, NULL, DixShowAccess) != Success) 2678f7df2e56Smrg return Success; 267905b261ecSmrg 268005b261ecSmrg pScreen = pWin->drawable.pScreen; 2681f7df2e56Smrg if ((pParent = pWin->parent)) { 2682f7df2e56Smrg Bool anyMarked; 2683f7df2e56Smrg 2684f7df2e56Smrg if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) 2685f7df2e56Smrg if (MaybeDeliverMapRequest(pWin, pParent, client)) 2686f7df2e56Smrg return Success; 2687f7df2e56Smrg 2688f7df2e56Smrg pWin->mapped = TRUE; 2689f7df2e56Smrg if (SubStrSend(pWin, pParent)) 2690f7df2e56Smrg DeliverMapNotify(pWin); 2691f7df2e56Smrg 2692f7df2e56Smrg if (!pParent->realized) 2693f7df2e56Smrg return Success; 2694f7df2e56Smrg RealizeTree(pWin); 2695f7df2e56Smrg if (pWin->viewable) { 2696f7df2e56Smrg anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, 2697f7df2e56Smrg &pLayerWin); 2698f7df2e56Smrg if (anyMarked) { 2699f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap); 2700f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2701f7df2e56Smrg if (pScreen->PostValidateTree) 2702f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, 2703f7df2e56Smrg VTMap); 2704f7df2e56Smrg } 2705f7df2e56Smrg } 2706f7df2e56Smrg WindowsRestructured(); 270705b261ecSmrg } 2708f7df2e56Smrg else { 2709f7df2e56Smrg RegionRec temp; 2710f7df2e56Smrg 2711f7df2e56Smrg pWin->mapped = TRUE; 2712f7df2e56Smrg pWin->realized = TRUE; /* for roots */ 2713f7df2e56Smrg pWin->viewable = pWin->drawable.class == InputOutput; 2714f7df2e56Smrg /* We SHOULD check for an error value here XXX */ 2715f7df2e56Smrg (*pScreen->RealizeWindow) (pWin); 2716f7df2e56Smrg if (pScreen->ClipNotify) 2717f7df2e56Smrg (*pScreen->ClipNotify) (pWin, 0, 0); 2718f7df2e56Smrg if (pScreen->PostValidateTree) 2719f7df2e56Smrg (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap); 2720f7df2e56Smrg RegionNull(&temp); 2721f7df2e56Smrg RegionCopy(&temp, &pWin->clipList); 2722f7df2e56Smrg (*pScreen->WindowExposures) (pWin, &temp); 2723f7df2e56Smrg RegionUninit(&temp); 272405b261ecSmrg } 272505b261ecSmrg 27264202a189Smrg return Success; 272705b261ecSmrg} 272805b261ecSmrg 272905b261ecSmrg/***** 273005b261ecSmrg * MapSubwindows 273105b261ecSmrg * Performs a MapWindow all unmapped children of the window, in top 273205b261ecSmrg * to bottom stacking order. 273305b261ecSmrg *****/ 273405b261ecSmrg 273505b261ecSmrgvoid 273605b261ecSmrgMapSubwindows(WindowPtr pParent, ClientPtr client) 273705b261ecSmrg{ 2738f7df2e56Smrg WindowPtr pWin; 2739f7df2e56Smrg WindowPtr pFirstMapped = NullWindow; 2740f7df2e56Smrg ScreenPtr pScreen; 2741f7df2e56Smrg Mask parentRedirect; 2742f7df2e56Smrg Mask parentNotify; 2743f7df2e56Smrg Bool anyMarked; 2744f7df2e56Smrg WindowPtr pLayerWin; 274505b261ecSmrg 274605b261ecSmrg pScreen = pParent->drawable.pScreen; 274705b261ecSmrg parentRedirect = RedirectSend(pParent); 274805b261ecSmrg parentNotify = SubSend(pParent); 274905b261ecSmrg anyMarked = FALSE; 2750f7df2e56Smrg for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) { 2751f7df2e56Smrg if (!pWin->mapped) { 2752f7df2e56Smrg if (parentRedirect && !pWin->overrideRedirect) 2753f7df2e56Smrg if (MaybeDeliverMapRequest(pWin, pParent, client)) 2754f7df2e56Smrg continue; 2755f7df2e56Smrg 2756f7df2e56Smrg pWin->mapped = TRUE; 2757f7df2e56Smrg if (parentNotify || StrSend(pWin)) 2758f7df2e56Smrg DeliverMapNotify(pWin); 2759f7df2e56Smrg 2760f7df2e56Smrg if (!pFirstMapped) 2761f7df2e56Smrg pFirstMapped = pWin; 2762f7df2e56Smrg if (pParent->realized) { 2763f7df2e56Smrg RealizeTree(pWin); 2764f7df2e56Smrg if (pWin->viewable) { 2765f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, 2766f7df2e56Smrg NULL); 2767f7df2e56Smrg } 2768f7df2e56Smrg } 2769f7df2e56Smrg } 2770f7df2e56Smrg } 2771f7df2e56Smrg 2772f7df2e56Smrg if (pFirstMapped) { 2773f7df2e56Smrg pLayerWin = (*pScreen->GetLayerWindow) (pParent); 2774f7df2e56Smrg if (pLayerWin->parent != pParent) { 2775f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin, 2776f7df2e56Smrg pLayerWin, NULL); 2777f7df2e56Smrg pFirstMapped = pLayerWin; 2778f7df2e56Smrg } 2779f7df2e56Smrg if (anyMarked) { 2780f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap); 2781f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2782f7df2e56Smrg if (pScreen->PostValidateTree) 2783f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped, 2784f7df2e56Smrg VTMap); 2785f7df2e56Smrg } 2786f7df2e56Smrg WindowsRestructured(); 278705b261ecSmrg } 278805b261ecSmrg} 278905b261ecSmrg 279005b261ecSmrgstatic void 2791f7df2e56SmrgUnrealizeTree(WindowPtr pWin, Bool fromConfigure) 279205b261ecSmrg{ 279305b261ecSmrg WindowPtr pChild; 279405b261ecSmrg UnrealizeWindowProcPtr Unrealize; 279505b261ecSmrg MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; 279605b261ecSmrg 279705b261ecSmrg Unrealize = pWin->drawable.pScreen->UnrealizeWindow; 279805b261ecSmrg MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; 279905b261ecSmrg pChild = pWin; 2800f7df2e56Smrg while (1) { 2801f7df2e56Smrg if (pChild->realized) { 2802f7df2e56Smrg pChild->realized = FALSE; 2803f7df2e56Smrg pChild->visibility = VisibilityNotViewable; 280405b261ecSmrg#ifdef PANORAMIX 2805f7df2e56Smrg if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { 2806f7df2e56Smrg PanoramiXRes *win; 2807f7df2e56Smrg int rc = dixLookupResourceByType((void **) &win, 2808f7df2e56Smrg pChild->drawable.id, 2809f7df2e56Smrg XRT_WINDOW, 2810f7df2e56Smrg serverClient, DixWriteAccess); 2811f7df2e56Smrg 2812f7df2e56Smrg if (rc == Success) 2813f7df2e56Smrg win->u.win.visibility = VisibilityNotViewable; 2814f7df2e56Smrg } 281505b261ecSmrg#endif 2816f7df2e56Smrg (*Unrealize) (pChild); 2817f7df2e56Smrg DeleteWindowFromAnyEvents(pChild, FALSE); 2818f7df2e56Smrg if (pChild->viewable) { 2819f7df2e56Smrg pChild->viewable = FALSE; 2820f7df2e56Smrg (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); 2821f7df2e56Smrg pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; 2822f7df2e56Smrg } 2823f7df2e56Smrg if (pChild->firstChild) { 2824f7df2e56Smrg pChild = pChild->firstChild; 2825f7df2e56Smrg continue; 2826f7df2e56Smrg } 2827f7df2e56Smrg } 2828f7df2e56Smrg while (!pChild->nextSib && (pChild != pWin)) 2829f7df2e56Smrg pChild = pChild->parent; 2830f7df2e56Smrg if (pChild == pWin) 2831f7df2e56Smrg return; 2832f7df2e56Smrg pChild = pChild->nextSib; 283305b261ecSmrg } 283405b261ecSmrg} 283505b261ecSmrg 2836f7df2e56Smrgstatic void 2837f7df2e56SmrgDeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure) 2838f7df2e56Smrg{ 2839f7df2e56Smrg xEvent event = { 2840f7df2e56Smrg .u.unmapNotify.window = pWin->drawable.id, 2841f7df2e56Smrg .u.unmapNotify.fromConfigure = fromConfigure 2842f7df2e56Smrg }; 2843f7df2e56Smrg event.u.u.type = UnmapNotify; 2844f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2845f7df2e56Smrg} 2846f7df2e56Smrg 284705b261ecSmrg/***** 284805b261ecSmrg * UnmapWindow 284905b261ecSmrg * If the window is already unmapped, this request has no effect. 285005b261ecSmrg * Otherwise, the window is unmapped and an UnMapNotify event is 285105b261ecSmrg * generated. Cannot unmap a root window. 285205b261ecSmrg *****/ 285305b261ecSmrg 28544202a189Smrgint 285505b261ecSmrgUnmapWindow(WindowPtr pWin, Bool fromConfigure) 285605b261ecSmrg{ 285705b261ecSmrg WindowPtr pParent; 2858f7df2e56Smrg Bool wasRealized = (Bool) pWin->realized; 2859f7df2e56Smrg Bool wasViewable = (Bool) pWin->viewable; 286005b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 286105b261ecSmrg WindowPtr pLayerWin = pWin; 286205b261ecSmrg 286305b261ecSmrg if ((!pWin->mapped) || (!(pParent = pWin->parent))) 2864f7df2e56Smrg return Success; 2865f7df2e56Smrg if (SubStrSend(pWin, pParent)) 2866f7df2e56Smrg DeliverUnmapNotify(pWin, fromConfigure); 2867f7df2e56Smrg if (wasViewable && !fromConfigure) { 2868f7df2e56Smrg pWin->valdata = UnmapValData; 2869f7df2e56Smrg (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); 2870f7df2e56Smrg (*pScreen->MarkWindow) (pLayerWin->parent); 287105b261ecSmrg } 287205b261ecSmrg pWin->mapped = FALSE; 287305b261ecSmrg if (wasRealized) 2874f7df2e56Smrg UnrealizeTree(pWin, fromConfigure); 2875f7df2e56Smrg if (wasViewable) { 2876f7df2e56Smrg if (!fromConfigure) { 2877f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); 2878f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2879f7df2e56Smrg if (pScreen->PostValidateTree) 2880f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); 2881f7df2e56Smrg } 2882f7df2e56Smrg } 2883f7df2e56Smrg if (wasRealized && !fromConfigure) { 2884f7df2e56Smrg WindowsRestructured(); 2885f7df2e56Smrg WindowGone(pWin); 2886f7df2e56Smrg } 28874202a189Smrg return Success; 288805b261ecSmrg} 288905b261ecSmrg 289005b261ecSmrg/***** 289105b261ecSmrg * UnmapSubwindows 289205b261ecSmrg * Performs an UnmapWindow request with the specified mode on all mapped 289305b261ecSmrg * children of the window, in bottom to top stacking order. 289405b261ecSmrg *****/ 289505b261ecSmrg 289605b261ecSmrgvoid 289705b261ecSmrgUnmapSubwindows(WindowPtr pWin) 289805b261ecSmrg{ 289905b261ecSmrg WindowPtr pChild, pHead; 2900f7df2e56Smrg Bool wasRealized = (Bool) pWin->realized; 2901f7df2e56Smrg Bool wasViewable = (Bool) pWin->viewable; 290205b261ecSmrg Bool anyMarked = FALSE; 290305b261ecSmrg Mask parentNotify; 290405b261ecSmrg WindowPtr pLayerWin = NULL; 290505b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 290605b261ecSmrg 290705b261ecSmrg if (!pWin->firstChild) 2908f7df2e56Smrg return; 290905b261ecSmrg parentNotify = SubSend(pWin); 291005b261ecSmrg pHead = RealChildHead(pWin); 291105b261ecSmrg 291205b261ecSmrg if (wasViewable) 2913f7df2e56Smrg pLayerWin = (*pScreen->GetLayerWindow) (pWin); 2914f7df2e56Smrg 2915f7df2e56Smrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { 2916f7df2e56Smrg if (pChild->mapped) { 2917f7df2e56Smrg if (parentNotify || StrSend(pChild)) 2918f7df2e56Smrg DeliverUnmapNotify(pChild, xFalse); 2919f7df2e56Smrg if (pChild->viewable) { 2920f7df2e56Smrg pChild->valdata = UnmapValData; 2921f7df2e56Smrg anyMarked = TRUE; 2922f7df2e56Smrg } 2923f7df2e56Smrg pChild->mapped = FALSE; 2924f7df2e56Smrg if (pChild->realized) 2925f7df2e56Smrg UnrealizeTree(pChild, FALSE); 2926f7df2e56Smrg } 292705b261ecSmrg } 2928f7df2e56Smrg if (wasViewable) { 2929f7df2e56Smrg if (anyMarked) { 2930f7df2e56Smrg if (pLayerWin->parent == pWin) 2931f7df2e56Smrg (*pScreen->MarkWindow) (pWin); 2932f7df2e56Smrg else { 2933f7df2e56Smrg WindowPtr ptmp; 2934f7df2e56Smrg 2935f7df2e56Smrg (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); 2936f7df2e56Smrg (*pScreen->MarkWindow) (pLayerWin->parent); 2937f7df2e56Smrg 2938f7df2e56Smrg /* Windows between pWin and pLayerWin may not have been marked */ 2939f7df2e56Smrg ptmp = pWin; 2940f7df2e56Smrg 2941f7df2e56Smrg while (ptmp != pLayerWin->parent) { 2942f7df2e56Smrg (*pScreen->MarkWindow) (ptmp); 2943f7df2e56Smrg ptmp = ptmp->parent; 2944f7df2e56Smrg } 294505b261ecSmrg pHead = pWin->firstChild; 2946f7df2e56Smrg } 2947f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); 2948f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2949f7df2e56Smrg if (pScreen->PostValidateTree) 2950f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, 2951f7df2e56Smrg VTUnmap); 2952f7df2e56Smrg } 2953f7df2e56Smrg } 2954f7df2e56Smrg if (wasRealized) { 2955f7df2e56Smrg WindowsRestructured(); 2956f7df2e56Smrg WindowGone(pWin); 295705b261ecSmrg } 295805b261ecSmrg} 295905b261ecSmrg 296005b261ecSmrgvoid 296105b261ecSmrgHandleSaveSet(ClientPtr client) 296205b261ecSmrg{ 296305b261ecSmrg WindowPtr pParent, pWin; 296405b261ecSmrg int j; 296505b261ecSmrg 2966f7df2e56Smrg for (j = 0; j < client->numSaved; j++) { 2967f7df2e56Smrg pWin = SaveSetWindow(client->saveSet[j]); 2968f7df2e56Smrg if (SaveSetToRoot(client->saveSet[j])) 2969f7df2e56Smrg pParent = pWin->drawable.pScreen->root; 2970f7df2e56Smrg else 2971f7df2e56Smrg { 2972f7df2e56Smrg pParent = pWin->parent; 2973f7df2e56Smrg while (pParent && (wClient(pParent) == client)) 2974f7df2e56Smrg pParent = pParent->parent; 2975f7df2e56Smrg } 2976f7df2e56Smrg if (pParent) { 2977f7df2e56Smrg if (pParent != pWin->parent) { 2978f7df2e56Smrg /* unmap first so that ReparentWindow doesn't remap */ 2979f7df2e56Smrg if (!SaveSetShouldMap(client->saveSet[j])) 2980f7df2e56Smrg UnmapWindow(pWin, FALSE); 2981f7df2e56Smrg ReparentWindow(pWin, pParent, 2982f7df2e56Smrg pWin->drawable.x - wBorderWidth(pWin) - 2983f7df2e56Smrg pParent->drawable.x, 2984f7df2e56Smrg pWin->drawable.y - wBorderWidth(pWin) - 2985f7df2e56Smrg pParent->drawable.y, client); 2986f7df2e56Smrg if (!pWin->realized && pWin->mapped) 2987f7df2e56Smrg pWin->mapped = FALSE; 2988f7df2e56Smrg } 2989f7df2e56Smrg if (SaveSetShouldMap(client->saveSet[j])) 2990f7df2e56Smrg MapWindow(pWin, client); 2991f7df2e56Smrg } 299205b261ecSmrg } 29934202a189Smrg free(client->saveSet); 299405b261ecSmrg client->numSaved = 0; 2995f7df2e56Smrg client->saveSet = NULL; 299605b261ecSmrg} 299705b261ecSmrg 299805b261ecSmrg/** 299905b261ecSmrg * 300005b261ecSmrg * \param x,y in root 300105b261ecSmrg */ 300205b261ecSmrgBool 300305b261ecSmrgPointInWindowIsVisible(WindowPtr pWin, int x, int y) 300405b261ecSmrg{ 300505b261ecSmrg BoxRec box; 300605b261ecSmrg 300705b261ecSmrg if (!pWin->realized) 3008f7df2e56Smrg return FALSE; 3009f7df2e56Smrg if (RegionContainsPoint(&pWin->borderClip, x, y, &box) 3010f7df2e56Smrg && (!wInputShape(pWin) || 3011f7df2e56Smrg RegionContainsPoint(wInputShape(pWin), 3012f7df2e56Smrg x - pWin->drawable.x, 3013f7df2e56Smrg y - pWin->drawable.y, &box))) 3014f7df2e56Smrg return TRUE; 30154202a189Smrg return FALSE; 301605b261ecSmrg} 301705b261ecSmrg 30184202a189SmrgRegionPtr 301905b261ecSmrgNotClippedByChildren(WindowPtr pWin) 302005b261ecSmrg{ 30214202a189Smrg RegionPtr pReg = RegionCreate(NullBox, 1); 3022f7df2e56Smrg 302305b261ecSmrg if (pWin->parent || 3024f7df2e56Smrg screenIsSaved != SCREEN_SAVER_ON || 3025f7df2e56Smrg !HasSaverWindow(pWin->drawable.pScreen)) { 3026f7df2e56Smrg RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); 302705b261ecSmrg } 30284202a189Smrg return pReg; 302905b261ecSmrg} 303005b261ecSmrg 3031637ac9abSmrgvoid 303205b261ecSmrgSendVisibilityNotify(WindowPtr pWin) 303305b261ecSmrg{ 303405b261ecSmrg xEvent event; 30354202a189Smrg unsigned int visibility = pWin->visibility; 30364202a189Smrg 303705b261ecSmrg#ifdef PANORAMIX 303805b261ecSmrg /* This is not quite correct yet, but it's close */ 3039f7df2e56Smrg if (!noPanoramiXExtension) { 3040f7df2e56Smrg PanoramiXRes *win; 3041f7df2e56Smrg WindowPtr pWin2; 3042f7df2e56Smrg int rc, i, Scrnum; 3043f7df2e56Smrg 3044f7df2e56Smrg Scrnum = pWin->drawable.pScreen->myNum; 3045f7df2e56Smrg 3046f7df2e56Smrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); 3047f7df2e56Smrg 3048f7df2e56Smrg if (!win || (win->u.win.visibility == visibility)) 3049f7df2e56Smrg return; 3050f7df2e56Smrg 3051f7df2e56Smrg switch (visibility) { 3052f7df2e56Smrg case VisibilityUnobscured: 3053f7df2e56Smrg FOR_NSCREENS(i) { 3054f7df2e56Smrg if (i == Scrnum) 3055f7df2e56Smrg continue; 3056f7df2e56Smrg 3057f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3058f7df2e56Smrg DixWriteAccess); 3059f7df2e56Smrg 3060f7df2e56Smrg if (rc == Success) { 3061f7df2e56Smrg if (pWin2->visibility == VisibilityPartiallyObscured) 3062f7df2e56Smrg return; 3063f7df2e56Smrg 3064f7df2e56Smrg if (!i) 3065f7df2e56Smrg pWin = pWin2; 3066f7df2e56Smrg } 3067f7df2e56Smrg } 3068f7df2e56Smrg break; 3069f7df2e56Smrg case VisibilityPartiallyObscured: 3070f7df2e56Smrg if (Scrnum) { 3071f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, 3072f7df2e56Smrg DixWriteAccess); 3073f7df2e56Smrg if (rc == Success) 3074f7df2e56Smrg pWin = pWin2; 3075f7df2e56Smrg } 3076f7df2e56Smrg break; 3077f7df2e56Smrg case VisibilityFullyObscured: 3078f7df2e56Smrg FOR_NSCREENS(i) { 3079f7df2e56Smrg if (i == Scrnum) 3080f7df2e56Smrg continue; 3081f7df2e56Smrg 3082f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3083f7df2e56Smrg DixWriteAccess); 3084f7df2e56Smrg 3085f7df2e56Smrg if (rc == Success) { 3086f7df2e56Smrg if (pWin2->visibility != VisibilityFullyObscured) 3087f7df2e56Smrg return; 3088f7df2e56Smrg 3089f7df2e56Smrg if (!i) 3090f7df2e56Smrg pWin = pWin2; 3091f7df2e56Smrg } 3092f7df2e56Smrg } 3093f7df2e56Smrg break; 3094f7df2e56Smrg } 3095f7df2e56Smrg 3096f7df2e56Smrg win->u.win.visibility = visibility; 309705b261ecSmrg } 309805b261ecSmrg#endif 309905b261ecSmrg 3100f7df2e56Smrg event = (xEvent) { 3101f7df2e56Smrg .u.visibility.window = pWin->drawable.id, 3102f7df2e56Smrg .u.visibility.state = visibility 3103f7df2e56Smrg }; 310405b261ecSmrg event.u.u.type = VisibilityNotify; 310505b261ecSmrg DeliverEvents(pWin, &event, 1, NullWindow); 310605b261ecSmrg} 310705b261ecSmrg 310805b261ecSmrg#define RANDOM_WIDTH 32 31094202a189Smrgint 3110637ac9abSmrgdixSaveScreens(ClientPtr client, int on, int mode) 311105b261ecSmrg{ 3112637ac9abSmrg int rc, i, what, type; 311305b261ecSmrg 3114f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) { 3115f7df2e56Smrg if (mode == ScreenSaverReset) 3116f7df2e56Smrg what = SCREEN_SAVER_OFF; 3117f7df2e56Smrg else 3118f7df2e56Smrg what = SCREEN_SAVER_ON; 3119f7df2e56Smrg type = what; 312005b261ecSmrg } 3121f7df2e56Smrg else { 3122f7df2e56Smrg what = on; 3123f7df2e56Smrg type = what; 3124f7df2e56Smrg if (what == screenIsSaved) 3125f7df2e56Smrg type = SCREEN_SAVER_CYCLE; 312605b261ecSmrg } 3127637ac9abSmrg 3128637ac9abSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3129f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3130f7df2e56Smrg DixShowAccess | DixHideAccess); 3131f7df2e56Smrg if (rc != Success) 3132f7df2e56Smrg return rc; 3133637ac9abSmrg } 3134f7df2e56Smrg for (i = 0; i < screenInfo.numScreens; i++) { 3135f7df2e56Smrg ScreenPtr pScreen = screenInfo.screens[i]; 3136f7df2e56Smrg 3137f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) 3138f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, on); 3139f7df2e56Smrg if (pScreen->screensaver.ExternalScreenSaver) { 3140f7df2e56Smrg if ((*pScreen->screensaver.ExternalScreenSaver) 3141f7df2e56Smrg (pScreen, type, on == SCREEN_SAVER_FORCER)) 3142f7df2e56Smrg continue; 3143f7df2e56Smrg } 3144f7df2e56Smrg if (type == screenIsSaved) 3145f7df2e56Smrg continue; 3146f7df2e56Smrg switch (type) { 3147f7df2e56Smrg case SCREEN_SAVER_OFF: 3148f7df2e56Smrg if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { 3149f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, what); 3150f7df2e56Smrg } 3151f7df2e56Smrg else if (HasSaverWindow(pScreen)) { 3152f7df2e56Smrg pScreen->screensaver.pWindow = NullWindow; 3153f7df2e56Smrg FreeResource(pScreen->screensaver.wid, RT_NONE); 3154f7df2e56Smrg } 3155f7df2e56Smrg break; 3156f7df2e56Smrg case SCREEN_SAVER_CYCLE: 3157f7df2e56Smrg if (pScreen->screensaver.blanked == SCREEN_IS_TILED) { 3158f7df2e56Smrg WindowPtr pWin = pScreen->screensaver.pWindow; 3159f7df2e56Smrg 3160f7df2e56Smrg /* make it look like screen saver is off, so that 3161f7df2e56Smrg * NotClippedByChildren will compute a clip list 3162f7df2e56Smrg * for the root window, so PaintWindow works 3163f7df2e56Smrg */ 3164f7df2e56Smrg screenIsSaved = SCREEN_SAVER_OFF; 3165f7df2e56Smrg (*pWin->drawable.pScreen->MoveWindow) (pWin, 3166f7df2e56Smrg (short) (- 3167f7df2e56Smrg (rand() % 3168f7df2e56Smrg RANDOM_WIDTH)), 3169f7df2e56Smrg (short) (- 3170f7df2e56Smrg (rand() % 3171f7df2e56Smrg RANDOM_WIDTH)), 3172f7df2e56Smrg pWin->nextSib, VTMove); 3173f7df2e56Smrg screenIsSaved = SCREEN_SAVER_ON; 3174f7df2e56Smrg } 3175f7df2e56Smrg /* 3176f7df2e56Smrg * Call the DDX saver in case it wants to do something 3177f7df2e56Smrg * at cycle time 3178f7df2e56Smrg */ 3179f7df2e56Smrg else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { 3180f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, type); 3181f7df2e56Smrg } 3182f7df2e56Smrg break; 3183f7df2e56Smrg case SCREEN_SAVER_ON: 3184f7df2e56Smrg if (ScreenSaverBlanking != DontPreferBlanking) { 3185f7df2e56Smrg if ((*pScreen->SaveScreen) (pScreen, what)) { 3186f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_BLANKED; 3187f7df2e56Smrg continue; 3188f7df2e56Smrg } 3189f7df2e56Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3190f7df2e56Smrg TileScreenSaver(pScreen, SCREEN_IS_BLACK)) { 3191f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_BLACK; 3192f7df2e56Smrg continue; 3193f7df2e56Smrg } 3194f7df2e56Smrg } 3195f7df2e56Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3196f7df2e56Smrg TileScreenSaver(pScreen, SCREEN_IS_TILED)) { 3197f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_TILED; 3198f7df2e56Smrg } 3199f7df2e56Smrg else 3200f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_ISNT_SAVED; 3201f7df2e56Smrg break; 3202f7df2e56Smrg } 320305b261ecSmrg } 320405b261ecSmrg screenIsSaved = what; 32054202a189Smrg if (mode == ScreenSaverReset) { 3206f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) { 3207f7df2e56Smrg DeviceIntPtr dev; 3208f7df2e56Smrg UpdateCurrentTimeIf(); 3209f7df2e56Smrg nt_list_for_each_entry(dev, inputInfo.devices, next) 3210f7df2e56Smrg NoticeTime(dev, currentTime); 3211f7df2e56Smrg } 3212f7df2e56Smrg SetScreenSaverTimer(); 32134202a189Smrg } 3214637ac9abSmrg return Success; 3215637ac9abSmrg} 3216637ac9abSmrg 32174202a189Smrgint 3218637ac9abSmrgSaveScreens(int on, int mode) 3219637ac9abSmrg{ 3220637ac9abSmrg return dixSaveScreens(serverClient, on, mode); 322105b261ecSmrg} 322205b261ecSmrg 322305b261ecSmrgstatic Bool 32244202a189SmrgTileScreenSaver(ScreenPtr pScreen, int kind) 322505b261ecSmrg{ 322605b261ecSmrg int j; 322705b261ecSmrg int result; 322805b261ecSmrg XID attributes[3]; 322905b261ecSmrg Mask mask; 3230f7df2e56Smrg WindowPtr pWin; 323105b261ecSmrg CursorMetricRec cm; 323205b261ecSmrg unsigned char *srcbits, *mskbits; 323305b261ecSmrg CursorPtr cursor; 3234f7df2e56Smrg XID cursorID = 0; 3235f7df2e56Smrg int attri; 323605b261ecSmrg 323705b261ecSmrg mask = 0; 323805b261ecSmrg attri = 0; 323905b261ecSmrg switch (kind) { 324005b261ecSmrg case SCREEN_IS_TILED: 3241f7df2e56Smrg switch (pScreen->root->backgroundState) { 3242f7df2e56Smrg case BackgroundPixel: 3243f7df2e56Smrg attributes[attri++] = pScreen->root->background.pixel; 3244f7df2e56Smrg mask |= CWBackPixel; 3245f7df2e56Smrg break; 3246f7df2e56Smrg case BackgroundPixmap: 3247f7df2e56Smrg attributes[attri++] = None; 3248f7df2e56Smrg mask |= CWBackPixmap; 3249f7df2e56Smrg break; 3250f7df2e56Smrg default: 3251f7df2e56Smrg break; 3252f7df2e56Smrg } 3253f7df2e56Smrg break; 325405b261ecSmrg case SCREEN_IS_BLACK: 3255f7df2e56Smrg attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; 3256f7df2e56Smrg mask |= CWBackPixel; 3257f7df2e56Smrg break; 325805b261ecSmrg } 325905b261ecSmrg mask |= CWOverrideRedirect; 326005b261ecSmrg attributes[attri++] = xTrue; 326105b261ecSmrg 326205b261ecSmrg /* 326305b261ecSmrg * create a blank cursor 326405b261ecSmrg */ 326505b261ecSmrg 3266f7df2e56Smrg cm.width = 16; 3267f7df2e56Smrg cm.height = 16; 3268f7df2e56Smrg cm.xhot = 8; 3269f7df2e56Smrg cm.yhot = 8; 3270f7df2e56Smrg srcbits = malloc(BitmapBytePad(32) * 16); 3271f7df2e56Smrg mskbits = malloc(BitmapBytePad(32) * 16); 3272f7df2e56Smrg if (!srcbits || !mskbits) { 3273f7df2e56Smrg free(srcbits); 3274f7df2e56Smrg free(mskbits); 3275f7df2e56Smrg cursor = 0; 327605b261ecSmrg } 3277f7df2e56Smrg else { 3278f7df2e56Smrg for (j = 0; j < BitmapBytePad(32) * 16; j++) 3279f7df2e56Smrg srcbits[j] = mskbits[j] = 0x0; 3280f7df2e56Smrg result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, 3281f7df2e56Smrg &cursor, serverClient, (XID) 0); 3282f7df2e56Smrg if (cursor) { 3283f7df2e56Smrg cursorID = FakeClientID(0); 3284f7df2e56Smrg if (AddResource(cursorID, RT_CURSOR, (void *) cursor)) { 3285f7df2e56Smrg attributes[attri] = cursorID; 3286f7df2e56Smrg mask |= CWCursor; 3287f7df2e56Smrg } 3288f7df2e56Smrg else 3289f7df2e56Smrg cursor = 0; 3290f7df2e56Smrg } 3291f7df2e56Smrg else { 3292f7df2e56Smrg free(srcbits); 3293f7df2e56Smrg free(mskbits); 3294f7df2e56Smrg } 329505b261ecSmrg } 329605b261ecSmrg 32974202a189Smrg pWin = pScreen->screensaver.pWindow = 3298f7df2e56Smrg CreateWindow(pScreen->screensaver.wid, 3299f7df2e56Smrg pScreen->root, 3300f7df2e56Smrg -RANDOM_WIDTH, -RANDOM_WIDTH, 3301f7df2e56Smrg (unsigned short) pScreen->width + RANDOM_WIDTH, 3302f7df2e56Smrg (unsigned short) pScreen->height + RANDOM_WIDTH, 3303f7df2e56Smrg 0, InputOutput, mask, attributes, 0, serverClient, 3304f7df2e56Smrg wVisual(pScreen->root), &result); 330505b261ecSmrg 330605b261ecSmrg if (cursor) 3307f7df2e56Smrg FreeResource(cursorID, RT_NONE); 330805b261ecSmrg 330905b261ecSmrg if (!pWin) 3310f7df2e56Smrg return FALSE; 331105b261ecSmrg 331205b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, 3313f7df2e56Smrg (void *) pScreen->screensaver.pWindow)) 3314f7df2e56Smrg return FALSE; 331505b261ecSmrg 3316f7df2e56Smrg if (mask & CWBackPixmap) { 3317f7df2e56Smrg MakeRootTile(pWin); 3318f7df2e56Smrg (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap); 331905b261ecSmrg } 332005b261ecSmrg MapWindow(pWin, serverClient); 332105b261ecSmrg return TRUE; 332205b261ecSmrg} 332305b261ecSmrg 332405b261ecSmrg/* 332505b261ecSmrg * FindWindowWithOptional 332605b261ecSmrg * 332705b261ecSmrg * search ancestors of the given window for an entry containing 332805b261ecSmrg * a WindowOpt structure. Assumptions: some parent will 332905b261ecSmrg * contain the structure. 333005b261ecSmrg */ 333105b261ecSmrg 33324202a189SmrgWindowPtr 3333f7df2e56SmrgFindWindowWithOptional(WindowPtr w) 333405b261ecSmrg{ 333505b261ecSmrg do 3336f7df2e56Smrg w = w->parent; 333705b261ecSmrg while (!w->optional); 333805b261ecSmrg return w; 333905b261ecSmrg} 334005b261ecSmrg 334105b261ecSmrg/* 334205b261ecSmrg * CheckWindowOptionalNeed 334305b261ecSmrg * 334405b261ecSmrg * check each optional entry in the given window to see if 334505b261ecSmrg * the value is satisfied by the default rules. If so, 334605b261ecSmrg * release the optional record 334705b261ecSmrg */ 334805b261ecSmrg 33494202a189Smrgvoid 3350f7df2e56SmrgCheckWindowOptionalNeed(WindowPtr w) 335105b261ecSmrg{ 335205b261ecSmrg WindowOptPtr optional; 335305b261ecSmrg WindowOptPtr parentOptional; 335405b261ecSmrg 33554202a189Smrg if (!w->parent || !w->optional) 3356f7df2e56Smrg return; 335705b261ecSmrg optional = w->optional; 335805b261ecSmrg if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) 3359f7df2e56Smrg return; 336005b261ecSmrg if (optional->otherEventMasks != 0) 3361f7df2e56Smrg return; 336205b261ecSmrg if (optional->otherClients != NULL) 3363f7df2e56Smrg return; 336405b261ecSmrg if (optional->passiveGrabs != NULL) 3365f7df2e56Smrg return; 336605b261ecSmrg if (optional->userProps != NULL) 3367f7df2e56Smrg return; 3368f7df2e56Smrg if (optional->backingBitPlanes != (CARD32)~0L) 3369f7df2e56Smrg return; 337005b261ecSmrg if (optional->backingPixel != 0) 3371f7df2e56Smrg return; 337205b261ecSmrg if (optional->boundingShape != NULL) 3373f7df2e56Smrg return; 337405b261ecSmrg if (optional->clipShape != NULL) 3375f7df2e56Smrg return; 337605b261ecSmrg if (optional->inputShape != NULL) 3377f7df2e56Smrg return; 337805b261ecSmrg if (optional->inputMasks != NULL) 3379f7df2e56Smrg return; 3380f7df2e56Smrg if (optional->deviceCursors != NULL) { 3381637ac9abSmrg DevCursNodePtr pNode = optional->deviceCursors; 3382f7df2e56Smrg 3383f7df2e56Smrg while (pNode) { 3384637ac9abSmrg if (pNode->cursor != None) 3385637ac9abSmrg return; 3386637ac9abSmrg pNode = pNode->next; 3387637ac9abSmrg } 3388637ac9abSmrg } 3389637ac9abSmrg 339005b261ecSmrg parentOptional = FindWindowWithOptional(w)->optional; 339105b261ecSmrg if (optional->visual != parentOptional->visual) 3392f7df2e56Smrg return; 339305b261ecSmrg if (optional->cursor != None && 3394f7df2e56Smrg (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone)) 3395f7df2e56Smrg return; 339605b261ecSmrg if (optional->colormap != parentOptional->colormap) 3397f7df2e56Smrg return; 3398f7df2e56Smrg DisposeWindowOptional(w); 339905b261ecSmrg} 340005b261ecSmrg 340105b261ecSmrg/* 340205b261ecSmrg * MakeWindowOptional 340305b261ecSmrg * 340405b261ecSmrg * create an optional record and initialize it with the default 340505b261ecSmrg * values. 340605b261ecSmrg */ 340705b261ecSmrg 34084202a189SmrgBool 3409f7df2e56SmrgMakeWindowOptional(WindowPtr pWin) 341005b261ecSmrg{ 341105b261ecSmrg WindowOptPtr optional; 341205b261ecSmrg WindowOptPtr parentOptional; 341305b261ecSmrg 341405b261ecSmrg if (pWin->optional) 3415f7df2e56Smrg return TRUE; 3416f7df2e56Smrg optional = malloc(sizeof(WindowOptRec)); 341705b261ecSmrg if (!optional) 3418f7df2e56Smrg return FALSE; 341905b261ecSmrg optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; 342005b261ecSmrg optional->otherEventMasks = 0; 342105b261ecSmrg optional->otherClients = NULL; 342205b261ecSmrg optional->passiveGrabs = NULL; 342305b261ecSmrg optional->userProps = NULL; 342405b261ecSmrg optional->backingBitPlanes = ~0L; 342505b261ecSmrg optional->backingPixel = 0; 342605b261ecSmrg optional->boundingShape = NULL; 342705b261ecSmrg optional->clipShape = NULL; 342805b261ecSmrg optional->inputShape = NULL; 342905b261ecSmrg optional->inputMasks = NULL; 3430637ac9abSmrg optional->deviceCursors = NULL; 3431637ac9abSmrg 343205b261ecSmrg parentOptional = FindWindowWithOptional(pWin)->optional; 343305b261ecSmrg optional->visual = parentOptional->visual; 3434f7df2e56Smrg if (!pWin->cursorIsNone) { 3435f7df2e56Smrg optional->cursor = RefCursor(parentOptional->cursor); 343605b261ecSmrg } 3437f7df2e56Smrg else { 3438f7df2e56Smrg optional->cursor = None; 343905b261ecSmrg } 344005b261ecSmrg optional->colormap = parentOptional->colormap; 344105b261ecSmrg pWin->optional = optional; 344205b261ecSmrg return TRUE; 344305b261ecSmrg} 344405b261ecSmrg 3445637ac9abSmrg/* 3446637ac9abSmrg * Changes the cursor struct for the given device and the given window. 3447637ac9abSmrg * A cursor that does not have a device cursor set will use whatever the 3448637ac9abSmrg * standard cursor is for the window. If all devices have a cursor set, 3449637ac9abSmrg * changing the window cursor (e.g. using XDefineCursor()) will not have any 3450637ac9abSmrg * visible effect. Only when one of the device cursors is set to None again, 3451637ac9abSmrg * this device's cursor will display the changed standard cursor. 3452f7df2e56Smrg * 3453637ac9abSmrg * CursorIsNone of the window struct is NOT modified if you set a device 3454f7df2e56Smrg * cursor. 3455637ac9abSmrg * 3456637ac9abSmrg * Assumption: If there is a node for a device in the list, the device has a 3457637ac9abSmrg * cursor. If the cursor is set to None, it is inherited by the parent. 3458637ac9abSmrg */ 34594202a189Smrgint 3460f7df2e56SmrgChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) 3461637ac9abSmrg{ 3462637ac9abSmrg DevCursNodePtr pNode, pPrev; 3463637ac9abSmrg CursorPtr pOldCursor = NULL; 3464637ac9abSmrg ScreenPtr pScreen; 3465637ac9abSmrg WindowPtr pChild; 3466637ac9abSmrg 3467637ac9abSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 3468637ac9abSmrg return BadAlloc; 3469637ac9abSmrg 3470637ac9abSmrg /* 1) Check if window has device cursor set 3471637ac9abSmrg * Yes: 1.1) swap cursor with given cursor if parent does not have same 3472637ac9abSmrg * cursor, free old cursor 3473637ac9abSmrg * 1.2) free old cursor, use parent cursor 3474637ac9abSmrg * No: 1.1) add node to beginning of list. 3475637ac9abSmrg * 1.2) add cursor to node if parent does not have same cursor 3476637ac9abSmrg * 1.3) use parent cursor if parent does not have same cursor 3477637ac9abSmrg * 2) Patch up children if child has a devcursor 3478637ac9abSmrg * 2.1) if child has cursor None, it inherited from parent, set to old 3479637ac9abSmrg * cursor 3480637ac9abSmrg * 2.2) if child has same cursor as new cursor, remove and set to None 3481637ac9abSmrg */ 3482637ac9abSmrg 3483637ac9abSmrg pScreen = pWin->drawable.pScreen; 3484637ac9abSmrg 3485f7df2e56Smrg if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) { 3486637ac9abSmrg /* has device cursor */ 3487637ac9abSmrg 3488637ac9abSmrg if (pNode->cursor == pCursor) 3489637ac9abSmrg return Success; 3490637ac9abSmrg 3491637ac9abSmrg pOldCursor = pNode->cursor; 3492637ac9abSmrg 3493f7df2e56Smrg if (!pCursor) { /* remove from list */ 3494f7df2e56Smrg if (pPrev) 3495f7df2e56Smrg pPrev->next = pNode->next; 3496f7df2e56Smrg else 3497f7df2e56Smrg /* first item in list */ 3498f7df2e56Smrg pWin->optional->deviceCursors = pNode->next; 3499637ac9abSmrg 35004202a189Smrg free(pNode); 35014202a189Smrg goto out; 3502637ac9abSmrg } 3503637ac9abSmrg 3504f7df2e56Smrg } 3505f7df2e56Smrg else { 3506637ac9abSmrg /* no device cursor yet */ 3507637ac9abSmrg DevCursNodePtr pNewNode; 3508637ac9abSmrg 3509637ac9abSmrg if (!pCursor) 3510637ac9abSmrg return Success; 3511637ac9abSmrg 35124202a189Smrg pNewNode = malloc(sizeof(DevCursNodeRec)); 3513637ac9abSmrg pNewNode->dev = pDev; 3514637ac9abSmrg pNewNode->next = pWin->optional->deviceCursors; 3515637ac9abSmrg pWin->optional->deviceCursors = pNewNode; 3516637ac9abSmrg pNode = pNewNode; 3517637ac9abSmrg 3518637ac9abSmrg } 3519637ac9abSmrg 3520637ac9abSmrg if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) 3521637ac9abSmrg pNode->cursor = None; 3522f7df2e56Smrg else { 3523f7df2e56Smrg pNode->cursor = RefCursor(pCursor); 3524637ac9abSmrg } 3525637ac9abSmrg 3526637ac9abSmrg pNode = pPrev = NULL; 3527637ac9abSmrg /* fix up children */ 3528f7df2e56Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 3529f7df2e56Smrg if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) { 3530f7df2e56Smrg if (pNode->cursor == None) { /* inherited from parent */ 3531f7df2e56Smrg pNode->cursor = RefCursor(pOldCursor); 3532f7df2e56Smrg } 3533f7df2e56Smrg else if (pNode->cursor == pCursor) { 3534637ac9abSmrg pNode->cursor = None; 3535f7df2e56Smrg FreeCursor(pCursor, (Cursor) 0); /* fix up refcnt */ 3536637ac9abSmrg } 3537637ac9abSmrg } 3538637ac9abSmrg } 3539637ac9abSmrg 3540f7df2e56Smrg out: 3541f7df2e56Smrg CursorVisible = TRUE; 3542f7df2e56Smrg 3543637ac9abSmrg if (pWin->realized) 3544637ac9abSmrg WindowHasNewCursor(pWin); 3545637ac9abSmrg 3546637ac9abSmrg if (pOldCursor) 3547f7df2e56Smrg FreeCursor(pOldCursor, (Cursor) 0); 3548637ac9abSmrg 3549f7df2e56Smrg /* FIXME: We SHOULD check for an error value here XXX 3550637ac9abSmrg (comment taken from ChangeWindowAttributes) */ 3551f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, CWCursor); 3552637ac9abSmrg 3553637ac9abSmrg return Success; 3554637ac9abSmrg} 3555637ac9abSmrg 3556637ac9abSmrg/* Get device cursor for given device or None if none is set */ 35574202a189SmrgCursorPtr 3558637ac9abSmrgWindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) 3559637ac9abSmrg{ 3560637ac9abSmrg DevCursorList pList; 3561637ac9abSmrg 3562637ac9abSmrg if (!pWin->optional || !pWin->optional->deviceCursors) 3563637ac9abSmrg return NULL; 3564637ac9abSmrg 3565637ac9abSmrg pList = pWin->optional->deviceCursors; 3566637ac9abSmrg 3567f7df2e56Smrg while (pList) { 3568f7df2e56Smrg if (pList->dev == pDev) { 3569f7df2e56Smrg if (pList->cursor == None) /* inherited from parent */ 3570637ac9abSmrg return WindowGetDeviceCursor(pWin->parent, pDev); 3571637ac9abSmrg else 3572637ac9abSmrg return pList->cursor; 3573637ac9abSmrg } 3574637ac9abSmrg pList = pList->next; 3575637ac9abSmrg } 3576637ac9abSmrg return NULL; 3577637ac9abSmrg} 3578637ac9abSmrg 3579637ac9abSmrg/* Searches for a DevCursorNode for the given window and device. If one is 3580637ac9abSmrg * found, return True and set pNode and pPrev to the node and to the node 3581637ac9abSmrg * before the node respectively. Otherwise return False. 3582637ac9abSmrg * If the device is the first in list, pPrev is set to NULL. 3583637ac9abSmrg */ 3584f7df2e56Smrgstatic Bool 3585f7df2e56SmrgWindowSeekDeviceCursor(WindowPtr pWin, 3586f7df2e56Smrg DeviceIntPtr pDev, 3587f7df2e56Smrg DevCursNodePtr * pNode, DevCursNodePtr * pPrev) 3588637ac9abSmrg{ 3589637ac9abSmrg DevCursorList pList; 3590637ac9abSmrg 3591637ac9abSmrg if (!pWin->optional) 3592637ac9abSmrg return FALSE; 3593637ac9abSmrg 3594637ac9abSmrg pList = pWin->optional->deviceCursors; 3595637ac9abSmrg 3596f7df2e56Smrg if (pList && pList->dev == pDev) { 3597637ac9abSmrg *pNode = pList; 3598637ac9abSmrg *pPrev = NULL; 3599637ac9abSmrg return TRUE; 3600637ac9abSmrg } 3601637ac9abSmrg 3602f7df2e56Smrg while (pList) { 3603f7df2e56Smrg if (pList->next) { 3604f7df2e56Smrg if (pList->next->dev == pDev) { 3605637ac9abSmrg *pNode = pList->next; 3606637ac9abSmrg *pPrev = pList; 3607637ac9abSmrg return TRUE; 3608637ac9abSmrg } 3609637ac9abSmrg } 3610637ac9abSmrg pList = pList->next; 3611637ac9abSmrg } 3612637ac9abSmrg return FALSE; 3613637ac9abSmrg} 3614637ac9abSmrg 3615637ac9abSmrg/* Return True if a parent has the same device cursor set or False if 3616f7df2e56Smrg * otherwise 3617f7df2e56Smrg */ 3618f7df2e56Smrgstatic Bool 3619f7df2e56SmrgWindowParentHasDeviceCursor(WindowPtr pWin, 3620f7df2e56Smrg DeviceIntPtr pDev, CursorPtr pCursor) 3621637ac9abSmrg{ 3622637ac9abSmrg WindowPtr pParent; 3623637ac9abSmrg DevCursNodePtr pParentNode, pParentPrev; 3624637ac9abSmrg 3625637ac9abSmrg pParent = pWin->parent; 3626f7df2e56Smrg while (pParent) { 3627f7df2e56Smrg if (WindowSeekDeviceCursor(pParent, pDev, &pParentNode, &pParentPrev)) { 3628637ac9abSmrg /* if there is a node in the list, the win has a dev cursor */ 3629f7df2e56Smrg if (!pParentNode->cursor) /* inherited. */ 36301b684552Smrg pParent = pParent->parent; 3631f7df2e56Smrg else if (pParentNode->cursor == pCursor) /* inherit */ 3632637ac9abSmrg return TRUE; 3633f7df2e56Smrg else /* different cursor */ 3634637ac9abSmrg return FALSE; 3635f7df2e56Smrg } 3636f7df2e56Smrg else 3637637ac9abSmrg /* parent does not have a device cursor for our device */ 3638637ac9abSmrg return FALSE; 3639637ac9abSmrg } 3640637ac9abSmrg return FALSE; 3641637ac9abSmrg} 3642f7df2e56Smrg 3643f7df2e56Smrg/* 3644f7df2e56Smrg * SetRootClip -- 3645f7df2e56Smrg * Enable or disable rendering to the screen by 3646f7df2e56Smrg * setting the root clip list and revalidating 3647f7df2e56Smrg * all of the windows 3648f7df2e56Smrg */ 3649f7df2e56Smrgvoid 3650f7df2e56SmrgSetRootClip(ScreenPtr pScreen, int enable) 3651f7df2e56Smrg{ 3652f7df2e56Smrg WindowPtr pWin = pScreen->root; 3653f7df2e56Smrg WindowPtr pChild; 3654f7df2e56Smrg Bool WasViewable; 3655f7df2e56Smrg Bool anyMarked = FALSE; 3656f7df2e56Smrg WindowPtr pLayerWin; 3657f7df2e56Smrg BoxRec box; 3658f7df2e56Smrg enum RootClipMode mode = enable; 3659f7df2e56Smrg 3660f7df2e56Smrg if (!pWin) 3661f7df2e56Smrg return; 3662f7df2e56Smrg WasViewable = (Bool) (pWin->viewable); 3663f7df2e56Smrg if (WasViewable) { 3664f7df2e56Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 3665f7df2e56Smrg (void) (*pScreen->MarkOverlappedWindows) (pChild, 3666f7df2e56Smrg pChild, &pLayerWin); 3667f7df2e56Smrg } 3668f7df2e56Smrg (*pScreen->MarkWindow) (pWin); 3669f7df2e56Smrg anyMarked = TRUE; 3670f7df2e56Smrg if (pWin->valdata) { 3671f7df2e56Smrg if (HasBorder(pWin)) { 3672f7df2e56Smrg RegionPtr borderVisible; 3673f7df2e56Smrg 3674f7df2e56Smrg borderVisible = RegionCreate(NullBox, 1); 3675f7df2e56Smrg RegionSubtract(borderVisible, 3676f7df2e56Smrg &pWin->borderClip, &pWin->winSize); 3677f7df2e56Smrg pWin->valdata->before.borderVisible = borderVisible; 3678f7df2e56Smrg } 3679f7df2e56Smrg pWin->valdata->before.resized = TRUE; 3680f7df2e56Smrg } 3681f7df2e56Smrg } 3682f7df2e56Smrg 3683f7df2e56Smrg if (mode != ROOT_CLIP_NONE) { 3684f7df2e56Smrg pWin->drawable.width = pScreen->width; 3685f7df2e56Smrg pWin->drawable.height = pScreen->height; 3686f7df2e56Smrg 3687f7df2e56Smrg box.x1 = 0; 3688f7df2e56Smrg box.y1 = 0; 3689f7df2e56Smrg box.x2 = pScreen->width; 3690f7df2e56Smrg box.y2 = pScreen->height; 3691f7df2e56Smrg 3692f7df2e56Smrg RegionInit(&pWin->winSize, &box, 1); 3693f7df2e56Smrg RegionInit(&pWin->borderSize, &box, 1); 3694f7df2e56Smrg 3695f7df2e56Smrg /* 3696f7df2e56Smrg * Use REGION_BREAK to avoid optimizations in ValidateTree 3697f7df2e56Smrg * that assume the root borderClip can't change well, normally 3698f7df2e56Smrg * it doesn't...) 3699f7df2e56Smrg */ 3700f7df2e56Smrg RegionBreak(&pWin->clipList); 3701f7df2e56Smrg 3702f7df2e56Smrg /* For INPUT_ONLY, empty the borderClip so no rendering will ever 3703f7df2e56Smrg * be attempted to the screen pixmap (only redirected windows), 3704f7df2e56Smrg * but we keep borderSize as full regardless. */ 3705f7df2e56Smrg if (WasViewable && mode == ROOT_CLIP_FULL) 3706f7df2e56Smrg RegionReset(&pWin->borderClip, &box); 3707f7df2e56Smrg else 3708f7df2e56Smrg RegionEmpty(&pWin->borderClip); 3709f7df2e56Smrg } 3710f7df2e56Smrg else { 3711f7df2e56Smrg RegionEmpty(&pWin->borderClip); 3712f7df2e56Smrg RegionBreak(&pWin->clipList); 3713f7df2e56Smrg } 3714f7df2e56Smrg 3715f7df2e56Smrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 3716f7df2e56Smrg 3717f7df2e56Smrg if (WasViewable) { 3718f7df2e56Smrg if (pWin->firstChild) { 3719f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin->firstChild, 3720f7df2e56Smrg pWin->firstChild, 3721f7df2e56Smrg NULL); 3722f7df2e56Smrg } 3723f7df2e56Smrg else { 3724f7df2e56Smrg (*pScreen->MarkWindow) (pWin); 3725f7df2e56Smrg anyMarked = TRUE; 3726f7df2e56Smrg } 3727f7df2e56Smrg 3728f7df2e56Smrg if (anyMarked) { 3729f7df2e56Smrg (*pScreen->ValidateTree) (pWin, NullWindow, VTOther); 3730f7df2e56Smrg (*pScreen->HandleExposures) (pWin); 3731f7df2e56Smrg if (pScreen->PostValidateTree) 3732f7df2e56Smrg (*pScreen->PostValidateTree) (pWin, NullWindow, VTOther); 3733f7df2e56Smrg } 3734f7df2e56Smrg } 3735f7df2e56Smrg if (pWin->realized) 3736f7df2e56Smrg WindowsRestructured(); 3737f7df2e56Smrg FlushAllOutput(); 3738f7df2e56Smrg} 3739f7df2e56Smrg 3740f7df2e56SmrgVisualPtr 3741f7df2e56SmrgWindowGetVisual(WindowPtr pWin) 3742f7df2e56Smrg{ 3743f7df2e56Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 3744f7df2e56Smrg VisualID vid = wVisual(pWin); 3745f7df2e56Smrg int i; 3746f7df2e56Smrg 3747f7df2e56Smrg for (i = 0; i < pScreen->numVisuals; i++) 3748f7df2e56Smrg if (pScreen->visuals[i].vid == vid) 3749f7df2e56Smrg return &pScreen->visuals[i]; 3750f7df2e56Smrg return 0; 3751f7df2e56Smrg} 3752