window.c revision 5a112b11
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 to force no backing store */ 472f7df2e56SmrgBool disableBackingStore = FALSE; 473f7df2e56SmrgBool enableBackingStore = FALSE; 47405b261ecSmrg 47505b261ecSmrgstatic void 47605b261ecSmrgSetWindowToDefaults(WindowPtr pWin) 47705b261ecSmrg{ 47805b261ecSmrg pWin->prevSib = NullWindow; 47905b261ecSmrg pWin->firstChild = NullWindow; 48005b261ecSmrg pWin->lastChild = NullWindow; 48105b261ecSmrg 482f7df2e56Smrg pWin->valdata = NULL; 483f7df2e56Smrg pWin->optional = NULL; 48405b261ecSmrg pWin->cursorIsNone = TRUE; 48505b261ecSmrg 48605b261ecSmrg pWin->backingStore = NotUseful; 48705b261ecSmrg 488f7df2e56Smrg pWin->mapped = FALSE; /* off */ 489f7df2e56Smrg pWin->realized = FALSE; /* off */ 49005b261ecSmrg pWin->viewable = FALSE; 49105b261ecSmrg pWin->visibility = VisibilityNotViewable; 49205b261ecSmrg pWin->overrideRedirect = FALSE; 49305b261ecSmrg pWin->saveUnder = FALSE; 49405b261ecSmrg 49505b261ecSmrg pWin->bitGravity = ForgetGravity; 49605b261ecSmrg pWin->winGravity = NorthWestGravity; 49705b261ecSmrg 49805b261ecSmrg pWin->eventMask = 0; 49905b261ecSmrg pWin->deliverableEvents = 0; 50005b261ecSmrg pWin->dontPropagate = 0; 50105b261ecSmrg pWin->redirectDraw = RedirectDrawNone; 502637ac9abSmrg pWin->forcedBG = FALSE; 503f7df2e56Smrg pWin->unhittable = FALSE; 50465b04b38Smrg 50565b04b38Smrg#ifdef COMPOSITE 50665b04b38Smrg pWin->damagedDescendants = FALSE; 50765b04b38Smrg#endif 50805b261ecSmrg} 50905b261ecSmrg 51005b261ecSmrgstatic void 51105b261ecSmrgMakeRootTile(WindowPtr pWin) 51205b261ecSmrg{ 51305b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 51405b261ecSmrg GCPtr pGC; 51505b261ecSmrg unsigned char back[128]; 51605b261ecSmrg int len = BitmapBytePad(sizeof(long)); 51705b261ecSmrg unsigned char *from, *to; 51805b261ecSmrg int i, j; 51905b261ecSmrg 520f7df2e56Smrg pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4, 521f7df2e56Smrg pScreen->rootDepth, 0); 52205b261ecSmrg 52305b261ecSmrg pWin->backgroundState = BackgroundPixmap; 52405b261ecSmrg pGC = GetScratchGC(pScreen->rootDepth, pScreen); 52505b261ecSmrg if (!pWin->background.pixmap || !pGC) 526f7df2e56Smrg FatalError("could not create root tile"); 52705b261ecSmrg 52805b261ecSmrg { 529f7df2e56Smrg ChangeGCVal attributes[2]; 53005b261ecSmrg 531f7df2e56Smrg attributes[0].val = pScreen->whitePixel; 532f7df2e56Smrg attributes[1].val = pScreen->blackPixel; 53305b261ecSmrg 534f7df2e56Smrg (void) ChangeGC(NullClient, pGC, GCForeground | GCBackground, 535f7df2e56Smrg attributes); 53605b261ecSmrg } 53705b261ecSmrg 538f7df2e56Smrg ValidateGC((DrawablePtr) pWin->background.pixmap, pGC); 53905b261ecSmrg 540f7df2e56Smrg from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; 541f7df2e56Smrg to = back; 54205b261ecSmrg 543f7df2e56Smrg for (i = 4; i > 0; i--, from++) 544f7df2e56Smrg for (j = len; j > 0; j--) 545f7df2e56Smrg *to++ = *from; 54605b261ecSmrg 547f7df2e56Smrg (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1, 548f7df2e56Smrg 0, 0, len, 4, 0, XYBitmap, (char *) back); 54905b261ecSmrg 550f7df2e56Smrg FreeScratchGC(pGC); 55105b261ecSmrg 55205b261ecSmrg} 55305b261ecSmrg 55405b261ecSmrg/***** 55505b261ecSmrg * CreateRootWindow 55605b261ecSmrg * Makes a window at initialization time for specified screen 55705b261ecSmrg *****/ 55805b261ecSmrg 55905b261ecSmrgBool 56005b261ecSmrgCreateRootWindow(ScreenPtr pScreen) 56105b261ecSmrg{ 562f7df2e56Smrg WindowPtr pWin; 563f7df2e56Smrg BoxRec box; 56405b261ecSmrg PixmapFormatRec *format; 56505b261ecSmrg 566f7df2e56Smrg pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); 56705b261ecSmrg if (!pWin) 568f7df2e56Smrg return FALSE; 56905b261ecSmrg 5704202a189Smrg pScreen->screensaver.pWindow = NULL; 5714202a189Smrg pScreen->screensaver.wid = FakeClientID(0); 5724202a189Smrg pScreen->screensaver.ExternalScreenSaver = NULL; 57305b261ecSmrg screenIsSaved = SCREEN_SAVER_OFF; 57405b261ecSmrg 5754202a189Smrg pScreen->root = pWin; 57605b261ecSmrg 57705b261ecSmrg pWin->drawable.pScreen = pScreen; 57805b261ecSmrg pWin->drawable.type = DRAWABLE_WINDOW; 57905b261ecSmrg 58005b261ecSmrg pWin->drawable.depth = pScreen->rootDepth; 58105b261ecSmrg for (format = screenInfo.formats; 582f7df2e56Smrg format->depth != pScreen->rootDepth; format++); 58305b261ecSmrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 58405b261ecSmrg 58505b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 58605b261ecSmrg 58705b261ecSmrg pWin->parent = NullWindow; 58805b261ecSmrg SetWindowToDefaults(pWin); 58905b261ecSmrg 590f7df2e56Smrg pWin->optional = malloc(sizeof(WindowOptRec)); 59105b261ecSmrg if (!pWin->optional) 59205b261ecSmrg return FALSE; 59305b261ecSmrg 59405b261ecSmrg pWin->optional->dontPropagateMask = 0; 59505b261ecSmrg pWin->optional->otherEventMasks = 0; 59605b261ecSmrg pWin->optional->otherClients = NULL; 59705b261ecSmrg pWin->optional->passiveGrabs = NULL; 59805b261ecSmrg pWin->optional->userProps = NULL; 59905b261ecSmrg pWin->optional->backingBitPlanes = ~0L; 60005b261ecSmrg pWin->optional->backingPixel = 0; 60105b261ecSmrg pWin->optional->boundingShape = NULL; 60205b261ecSmrg pWin->optional->clipShape = NULL; 60305b261ecSmrg pWin->optional->inputShape = NULL; 60405b261ecSmrg pWin->optional->inputMasks = NULL; 605637ac9abSmrg pWin->optional->deviceCursors = NULL; 60605b261ecSmrg pWin->optional->colormap = pScreen->defColormap; 60705b261ecSmrg pWin->optional->visual = pScreen->rootVisual; 60805b261ecSmrg 60905b261ecSmrg pWin->nextSib = NullWindow; 61005b261ecSmrg 61105b261ecSmrg pWin->drawable.id = FakeClientID(0); 61205b261ecSmrg 61305b261ecSmrg pWin->origin.x = pWin->origin.y = 0; 61405b261ecSmrg pWin->drawable.height = pScreen->height; 61505b261ecSmrg pWin->drawable.width = pScreen->width; 61605b261ecSmrg pWin->drawable.x = pWin->drawable.y = 0; 61705b261ecSmrg 61805b261ecSmrg box.x1 = 0; 61905b261ecSmrg box.y1 = 0; 62005b261ecSmrg box.x2 = pScreen->width; 62105b261ecSmrg box.y2 = pScreen->height; 6224202a189Smrg RegionInit(&pWin->clipList, &box, 1); 6234202a189Smrg RegionInit(&pWin->winSize, &box, 1); 6244202a189Smrg RegionInit(&pWin->borderSize, &box, 1); 6254202a189Smrg RegionInit(&pWin->borderClip, &box, 1); 62605b261ecSmrg 62705b261ecSmrg pWin->drawable.class = InputOutput; 62805b261ecSmrg pWin->optional->visual = pScreen->rootVisual; 62905b261ecSmrg 63005b261ecSmrg pWin->backgroundState = BackgroundPixel; 63105b261ecSmrg pWin->background.pixel = pScreen->whitePixel; 63205b261ecSmrg 63305b261ecSmrg pWin->borderIsPixel = TRUE; 63405b261ecSmrg pWin->border.pixel = pScreen->blackPixel; 63505b261ecSmrg pWin->borderWidth = 0; 63605b261ecSmrg 637637ac9abSmrg /* security creation/labeling check 638637ac9abSmrg */ 639637ac9abSmrg if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id, 640f7df2e56Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess)) 641f7df2e56Smrg return FALSE; 642637ac9abSmrg 643f7df2e56Smrg if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin)) 644f7df2e56Smrg return FALSE; 64505b261ecSmrg 64605b261ecSmrg if (disableBackingStore) 647f7df2e56Smrg pScreen->backingStoreSupport = NotUseful; 64805b261ecSmrg if (enableBackingStore) 649f7df2e56Smrg pScreen->backingStoreSupport = WhenMapped; 650f7df2e56Smrg#ifdef COMPOSITE 651f7df2e56Smrg if (noCompositeExtension) 652f7df2e56Smrg pScreen->backingStoreSupport = NotUseful; 653f7df2e56Smrg#endif 65405b261ecSmrg 655637ac9abSmrg pScreen->saveUnderSupport = NotUseful; 65605b261ecSmrg 65705b261ecSmrg return TRUE; 65805b261ecSmrg} 65905b261ecSmrg 66005b261ecSmrgvoid 66105b261ecSmrgInitRootWindow(WindowPtr pWin) 66205b261ecSmrg{ 66305b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 66405b261ecSmrg int backFlag = CWBorderPixel | CWCursor | CWBackingStore; 66505b261ecSmrg 666f7df2e56Smrg if (!(*pScreen->CreateWindow) (pWin)) 667f7df2e56Smrg return; /* XXX */ 668f7df2e56Smrg (*pScreen->PositionWindow) (pWin, 0, 0); 66905b261ecSmrg 67005b261ecSmrg pWin->cursorIsNone = FALSE; 671f7df2e56Smrg pWin->optional->cursor = RefCursor(rootCursor); 672637ac9abSmrg 673637ac9abSmrg if (party_like_its_1989) { 67405b261ecSmrg MakeRootTile(pWin); 67505b261ecSmrg backFlag |= CWBackPixmap; 676f7df2e56Smrg } 677f7df2e56Smrg else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { 67865b04b38Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 67965b04b38Smrg pWin->background.pixel = pScreen->whitePixel; 68065b04b38Smrg backFlag |= CWBackPixmap; 681f7df2e56Smrg } 682f7df2e56Smrg else { 68365b04b38Smrg pWin->backgroundState = BackgroundPixel; 684f7df2e56Smrg if (whiteRoot) 68505b261ecSmrg pWin->background.pixel = pScreen->whitePixel; 686637ac9abSmrg else 687637ac9abSmrg pWin->background.pixel = pScreen->blackPixel; 68805b261ecSmrg backFlag |= CWBackPixel; 689f7df2e56Smrg } 69005b261ecSmrg 6915a112b11Smrg pWin->backingStore = NotUseful; 69205b261ecSmrg /* We SHOULD check for an error value here XXX */ 693f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, backFlag); 69405b261ecSmrg 69505b261ecSmrg MapWindow(pWin, serverClient); 69605b261ecSmrg} 69705b261ecSmrg 69805b261ecSmrg/* Set the region to the intersection of the rectangle and the 69905b261ecSmrg * window's winSize. The window is typically the parent of the 70005b261ecSmrg * window from which the region came. 70105b261ecSmrg */ 70205b261ecSmrg 70305b261ecSmrgstatic void 704f7df2e56SmrgClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, int x, int y, int w, int h) 70505b261ecSmrg{ 7064202a189Smrg BoxRec box = *RegionExtents(&pWin->winSize); 70705b261ecSmrg 70805b261ecSmrg /* we do these calculations to avoid overflows */ 70905b261ecSmrg if (x > box.x1) 710f7df2e56Smrg box.x1 = x; 71105b261ecSmrg if (y > box.y1) 712f7df2e56Smrg box.y1 = y; 71305b261ecSmrg x += w; 71405b261ecSmrg if (x < box.x2) 715f7df2e56Smrg box.x2 = x; 71605b261ecSmrg y += h; 71705b261ecSmrg if (y < box.y2) 718f7df2e56Smrg box.y2 = y; 71905b261ecSmrg if (box.x1 > box.x2) 720f7df2e56Smrg box.x2 = box.x1; 72105b261ecSmrg if (box.y1 > box.y2) 722f7df2e56Smrg box.y2 = box.y1; 7234202a189Smrg RegionReset(Rgn, &box); 7244202a189Smrg RegionIntersect(Rgn, Rgn, &pWin->winSize); 72505b261ecSmrg} 72605b261ecSmrg 72705b261ecSmrgstatic RealChildHeadProc realChildHeadProc = NULL; 72805b261ecSmrg 72905b261ecSmrgvoid 730f7df2e56SmrgRegisterRealChildHeadProc(RealChildHeadProc proc) 73105b261ecSmrg{ 73205b261ecSmrg realChildHeadProc = proc; 73305b261ecSmrg} 73405b261ecSmrg 73505b261ecSmrgWindowPtr 73605b261ecSmrgRealChildHead(WindowPtr pWin) 73705b261ecSmrg{ 73805b261ecSmrg if (realChildHeadProc) { 739f7df2e56Smrg return realChildHeadProc(pWin); 74005b261ecSmrg } 74105b261ecSmrg 74205b261ecSmrg if (!pWin->parent && 743f7df2e56Smrg (screenIsSaved == SCREEN_SAVER_ON) && 744f7df2e56Smrg (HasSaverWindow(pWin->drawable.pScreen))) 745f7df2e56Smrg return pWin->firstChild; 74605b261ecSmrg else 747f7df2e56Smrg return NullWindow; 74805b261ecSmrg} 74905b261ecSmrg 75005b261ecSmrg/***** 75105b261ecSmrg * CreateWindow 752f7df2e56Smrg * Makes a window in response to client request 75305b261ecSmrg *****/ 75405b261ecSmrg 7554202a189SmrgWindowPtr 75605b261ecSmrgCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, 75705b261ecSmrg unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, 75805b261ecSmrg int depth, ClientPtr client, VisualID visual, int *error) 75905b261ecSmrg{ 76005b261ecSmrg WindowPtr pWin; 76105b261ecSmrg WindowPtr pHead; 76205b261ecSmrg ScreenPtr pScreen; 76305b261ecSmrg int idepth, ivisual; 76405b261ecSmrg Bool fOK; 76505b261ecSmrg DepthPtr pDepth; 76605b261ecSmrg PixmapFormatRec *format; 76705b261ecSmrg WindowOptPtr ancwopt; 76805b261ecSmrg 76905b261ecSmrg if (class == CopyFromParent) 770f7df2e56Smrg class = pParent->drawable.class; 77105b261ecSmrg 772f7df2e56Smrg if ((class != InputOutput) && (class != InputOnly)) { 773f7df2e56Smrg *error = BadValue; 774f7df2e56Smrg client->errorValue = class; 775f7df2e56Smrg return NullWindow; 77605b261ecSmrg } 77705b261ecSmrg 778f7df2e56Smrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) { 779f7df2e56Smrg *error = BadMatch; 780f7df2e56Smrg return NullWindow; 78105b261ecSmrg } 78205b261ecSmrg 783f7df2e56Smrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) { 784f7df2e56Smrg *error = BadMatch; 785f7df2e56Smrg return NullWindow; 78605b261ecSmrg } 78705b261ecSmrg 78805b261ecSmrg pScreen = pParent->drawable.pScreen; 78905b261ecSmrg if ((class == InputOutput) && (depth == 0)) 790f7df2e56Smrg depth = pParent->drawable.depth; 79105b261ecSmrg ancwopt = pParent->optional; 79205b261ecSmrg if (!ancwopt) 793f7df2e56Smrg ancwopt = FindWindowWithOptional(pParent)->optional; 79405b261ecSmrg if (visual == CopyFromParent) { 795f7df2e56Smrg visual = ancwopt->visual; 79605b261ecSmrg } 79705b261ecSmrg 79805b261ecSmrg /* Find out if the depth and visual are acceptable for this Screen */ 799f7df2e56Smrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { 800f7df2e56Smrg fOK = FALSE; 801f7df2e56Smrg for (idepth = 0; idepth < pScreen->numDepths; idepth++) { 802f7df2e56Smrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 803f7df2e56Smrg if ((depth == pDepth->depth) || (depth == 0)) { 804f7df2e56Smrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { 805f7df2e56Smrg if (visual == pDepth->vids[ivisual]) { 806f7df2e56Smrg fOK = TRUE; 807f7df2e56Smrg break; 808f7df2e56Smrg } 809f7df2e56Smrg } 810f7df2e56Smrg } 811f7df2e56Smrg } 812f7df2e56Smrg if (fOK == FALSE) { 813f7df2e56Smrg *error = BadMatch; 814f7df2e56Smrg return NullWindow; 815f7df2e56Smrg } 81605b261ecSmrg } 81705b261ecSmrg 81805b261ecSmrg if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) && 819f7df2e56Smrg (class != InputOnly) && (depth != pParent->drawable.depth)) { 820f7df2e56Smrg *error = BadMatch; 821f7df2e56Smrg return NullWindow; 82205b261ecSmrg } 82305b261ecSmrg 82405b261ecSmrg if (((vmask & CWColormap) == 0) && 825f7df2e56Smrg (class != InputOnly) && 826f7df2e56Smrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) { 827f7df2e56Smrg *error = BadMatch; 828f7df2e56Smrg return NullWindow; 82905b261ecSmrg } 83005b261ecSmrg 831f7df2e56Smrg pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); 832f7df2e56Smrg if (!pWin) { 833f7df2e56Smrg *error = BadAlloc; 834f7df2e56Smrg return NullWindow; 83505b261ecSmrg } 83605b261ecSmrg pWin->drawable = pParent->drawable; 83705b261ecSmrg pWin->drawable.depth = depth; 83805b261ecSmrg if (depth == pParent->drawable.depth) 839f7df2e56Smrg pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; 840f7df2e56Smrg else { 841f7df2e56Smrg for (format = screenInfo.formats; format->depth != depth; format++); 842f7df2e56Smrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 84305b261ecSmrg } 84405b261ecSmrg if (class == InputOnly) 845f7df2e56Smrg pWin->drawable.type = (short) UNDRAWABLE_WINDOW; 84605b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 84705b261ecSmrg 84805b261ecSmrg pWin->drawable.id = wid; 84905b261ecSmrg pWin->drawable.class = class; 85005b261ecSmrg 85105b261ecSmrg pWin->parent = pParent; 85205b261ecSmrg SetWindowToDefaults(pWin); 85305b261ecSmrg 854f7df2e56Smrg if (visual != ancwopt->visual) { 855f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 856f7df2e56Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 857f7df2e56Smrg *error = BadAlloc; 858f7df2e56Smrg return NullWindow; 859f7df2e56Smrg } 860f7df2e56Smrg pWin->optional->visual = visual; 861f7df2e56Smrg pWin->optional->colormap = None; 86205b261ecSmrg } 86305b261ecSmrg 86405b261ecSmrg pWin->borderWidth = bw; 86505b261ecSmrg 866637ac9abSmrg /* security creation/labeling check 86705b261ecSmrg */ 868637ac9abSmrg *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin, 869f7df2e56Smrg RT_WINDOW, pWin->parent, 870f7df2e56Smrg DixCreateAccess | DixSetAttrAccess); 871637ac9abSmrg if (*error != Success) { 872f7df2e56Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 873f7df2e56Smrg return NullWindow; 87405b261ecSmrg } 87505b261ecSmrg 876637ac9abSmrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 877637ac9abSmrg pWin->background.pixel = pScreen->whitePixel; 878637ac9abSmrg 87905b261ecSmrg pWin->borderIsPixel = pParent->borderIsPixel; 88005b261ecSmrg pWin->border = pParent->border; 88105b261ecSmrg if (pWin->borderIsPixel == FALSE) 882f7df2e56Smrg pWin->border.pixmap->refcnt++; 883f7df2e56Smrg 884f7df2e56Smrg pWin->origin.x = x + (int) bw; 885f7df2e56Smrg pWin->origin.y = y + (int) bw; 88605b261ecSmrg pWin->drawable.width = w; 88705b261ecSmrg pWin->drawable.height = h; 888f7df2e56Smrg pWin->drawable.x = pParent->drawable.x + x + (int) bw; 889f7df2e56Smrg pWin->drawable.y = pParent->drawable.y + y + (int) bw; 89005b261ecSmrg 891f7df2e56Smrg /* set up clip list correctly for unobscured WindowPtr */ 8924202a189Smrg RegionNull(&pWin->clipList); 8934202a189Smrg RegionNull(&pWin->borderClip); 8944202a189Smrg RegionNull(&pWin->winSize); 8954202a189Smrg RegionNull(&pWin->borderSize); 89605b261ecSmrg 89705b261ecSmrg pHead = RealChildHead(pParent); 898f7df2e56Smrg if (pHead) { 899f7df2e56Smrg pWin->nextSib = pHead->nextSib; 900f7df2e56Smrg if (pHead->nextSib) 901f7df2e56Smrg pHead->nextSib->prevSib = pWin; 902f7df2e56Smrg else 903f7df2e56Smrg pParent->lastChild = pWin; 904f7df2e56Smrg pHead->nextSib = pWin; 905f7df2e56Smrg pWin->prevSib = pHead; 90605b261ecSmrg } 907f7df2e56Smrg else { 908f7df2e56Smrg pWin->nextSib = pParent->firstChild; 909f7df2e56Smrg if (pParent->firstChild) 910f7df2e56Smrg pParent->firstChild->prevSib = pWin; 911f7df2e56Smrg else 912f7df2e56Smrg pParent->lastChild = pWin; 913f7df2e56Smrg pParent->firstChild = pWin; 91405b261ecSmrg } 91505b261ecSmrg 916f7df2e56Smrg SetWinSize(pWin); 917f7df2e56Smrg SetBorderSize(pWin); 91805b261ecSmrg 91905b261ecSmrg /* We SHOULD check for an error value here XXX */ 920f7df2e56Smrg if (!(*pScreen->CreateWindow) (pWin)) { 921f7df2e56Smrg *error = BadAlloc; 922f7df2e56Smrg DeleteWindow(pWin, None); 923f7df2e56Smrg return NullWindow; 92405b261ecSmrg } 92505b261ecSmrg /* We SHOULD check for an error value here XXX */ 926f7df2e56Smrg (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); 92705b261ecSmrg 92805b261ecSmrg if (!(vmask & CWEventMask)) 929f7df2e56Smrg RecalculateDeliverableEvents(pWin); 93005b261ecSmrg 93105b261ecSmrg if (vmask) 932f7df2e56Smrg *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin)); 93305b261ecSmrg else 934f7df2e56Smrg *error = Success; 93505b261ecSmrg 936f7df2e56Smrg if (*error != Success) { 937f7df2e56Smrg DeleteWindow(pWin, None); 938f7df2e56Smrg return NullWindow; 939f7df2e56Smrg } 940f7df2e56Smrg 941f7df2e56Smrg if (SubSend(pParent)) { 942f7df2e56Smrg xEvent event = { 943f7df2e56Smrg .u.createNotify.window = wid, 944f7df2e56Smrg .u.createNotify.parent = pParent->drawable.id, 945f7df2e56Smrg .u.createNotify.x = x, 946f7df2e56Smrg .u.createNotify.y = y, 947f7df2e56Smrg .u.createNotify.width = w, 948f7df2e56Smrg .u.createNotify.height = h, 949f7df2e56Smrg .u.createNotify.borderWidth = bw, 950f7df2e56Smrg .u.createNotify.override = pWin->overrideRedirect 951f7df2e56Smrg }; 952f7df2e56Smrg event.u.u.type = CreateNotify; 953f7df2e56Smrg DeliverEvents(pParent, &event, 1, NullWindow); 95405b261ecSmrg } 95505b261ecSmrg return pWin; 95605b261ecSmrg} 95705b261ecSmrg 95805b261ecSmrgstatic void 959f7df2e56SmrgDisposeWindowOptional(WindowPtr pWin) 96005b261ecSmrg{ 96105b261ecSmrg if (!pWin->optional) 962f7df2e56Smrg return; 96305b261ecSmrg /* 96405b261ecSmrg * everything is peachy. Delete the optional record 96505b261ecSmrg * and clean up 96605b261ecSmrg */ 967f7df2e56Smrg if (pWin->optional->cursor) { 968f7df2e56Smrg FreeCursor(pWin->optional->cursor, (Cursor) 0); 969f7df2e56Smrg pWin->cursorIsNone = FALSE; 97005b261ecSmrg } 97105b261ecSmrg else 972f7df2e56Smrg pWin->cursorIsNone = TRUE; 973637ac9abSmrg 974f7df2e56Smrg if (pWin->optional->deviceCursors) { 975637ac9abSmrg DevCursorList pList; 976637ac9abSmrg DevCursorList pPrev; 977f7df2e56Smrg 978637ac9abSmrg pList = pWin->optional->deviceCursors; 979f7df2e56Smrg while (pList) { 980637ac9abSmrg if (pList->cursor) 981f7df2e56Smrg FreeCursor(pList->cursor, (XID) 0); 982637ac9abSmrg pPrev = pList; 983637ac9abSmrg pList = pList->next; 9844202a189Smrg free(pPrev); 985637ac9abSmrg } 986637ac9abSmrg pWin->optional->deviceCursors = NULL; 987637ac9abSmrg } 988637ac9abSmrg 9894202a189Smrg free(pWin->optional); 99005b261ecSmrg pWin->optional = NULL; 99105b261ecSmrg} 99205b261ecSmrg 99305b261ecSmrgstatic void 99405b261ecSmrgFreeWindowResources(WindowPtr pWin) 99505b261ecSmrg{ 99605b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 99705b261ecSmrg 99805b261ecSmrg DeleteWindowFromAnySaveSet(pWin); 99905b261ecSmrg DeleteWindowFromAnySelections(pWin); 100005b261ecSmrg DeleteWindowFromAnyEvents(pWin, TRUE); 10014202a189Smrg RegionUninit(&pWin->clipList); 10024202a189Smrg RegionUninit(&pWin->winSize); 10034202a189Smrg RegionUninit(&pWin->borderClip); 10044202a189Smrg RegionUninit(&pWin->borderSize); 1005f7df2e56Smrg if (wBoundingShape(pWin)) 1006f7df2e56Smrg RegionDestroy(wBoundingShape(pWin)); 1007f7df2e56Smrg if (wClipShape(pWin)) 1008f7df2e56Smrg RegionDestroy(wClipShape(pWin)); 1009f7df2e56Smrg if (wInputShape(pWin)) 1010f7df2e56Smrg RegionDestroy(wInputShape(pWin)); 101105b261ecSmrg if (pWin->borderIsPixel == FALSE) 1012f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 101305b261ecSmrg if (pWin->backgroundState == BackgroundPixmap) 1014f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 101505b261ecSmrg 101605b261ecSmrg DeleteAllWindowProperties(pWin); 101705b261ecSmrg /* We SHOULD check for an error value here XXX */ 1018f7df2e56Smrg (*pScreen->DestroyWindow) (pWin); 1019f7df2e56Smrg DisposeWindowOptional(pWin); 102005b261ecSmrg} 102105b261ecSmrg 102205b261ecSmrgstatic void 102305b261ecSmrgCrushTree(WindowPtr pWin) 102405b261ecSmrg{ 102505b261ecSmrg WindowPtr pChild, pSib, pParent; 102605b261ecSmrg UnrealizeWindowProcPtr UnrealizeWindow; 102705b261ecSmrg 102805b261ecSmrg if (!(pChild = pWin->firstChild)) 1029f7df2e56Smrg return; 103005b261ecSmrg UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; 1031f7df2e56Smrg while (1) { 1032f7df2e56Smrg if (pChild->firstChild) { 1033f7df2e56Smrg pChild = pChild->firstChild; 1034f7df2e56Smrg continue; 1035f7df2e56Smrg } 1036f7df2e56Smrg while (1) { 1037f7df2e56Smrg pParent = pChild->parent; 1038f7df2e56Smrg if (SubStrSend(pChild, pParent)) { 1039f7df2e56Smrg xEvent event = { .u.u.type = DestroyNotify }; 1040f7df2e56Smrg event.u.destroyNotify.window = pChild->drawable.id; 1041f7df2e56Smrg DeliverEvents(pChild, &event, 1, NullWindow); 1042f7df2e56Smrg } 1043f7df2e56Smrg FreeResource(pChild->drawable.id, RT_WINDOW); 1044f7df2e56Smrg pSib = pChild->nextSib; 1045f7df2e56Smrg pChild->viewable = FALSE; 1046f7df2e56Smrg if (pChild->realized) { 1047f7df2e56Smrg pChild->realized = FALSE; 1048f7df2e56Smrg (*UnrealizeWindow) (pChild); 1049f7df2e56Smrg } 1050f7df2e56Smrg FreeWindowResources(pChild); 1051f7df2e56Smrg dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW); 1052f7df2e56Smrg if ((pChild = pSib)) 1053f7df2e56Smrg break; 1054f7df2e56Smrg pChild = pParent; 1055f7df2e56Smrg pChild->firstChild = NullWindow; 1056f7df2e56Smrg pChild->lastChild = NullWindow; 1057f7df2e56Smrg if (pChild == pWin) 1058f7df2e56Smrg return; 1059f7df2e56Smrg } 1060f7df2e56Smrg } 1061f7df2e56Smrg} 1062f7df2e56Smrg 106305b261ecSmrg/***** 106405b261ecSmrg * DeleteWindow 106505b261ecSmrg * Deletes child of window then window itself 106605b261ecSmrg * If wid is None, don't send any events 106705b261ecSmrg *****/ 106805b261ecSmrg 106905b261ecSmrgint 1070f7df2e56SmrgDeleteWindow(void *value, XID wid) 1071f7df2e56Smrg{ 107205b261ecSmrg WindowPtr pParent; 1073f7df2e56Smrg WindowPtr pWin = (WindowPtr) value; 107405b261ecSmrg 107505b261ecSmrg UnmapWindow(pWin, FALSE); 107605b261ecSmrg 107705b261ecSmrg CrushTree(pWin); 107805b261ecSmrg 107905b261ecSmrg pParent = pWin->parent; 1080f7df2e56Smrg if (wid && pParent && SubStrSend(pWin, pParent)) { 1081f7df2e56Smrg xEvent event = { .u.u.type = DestroyNotify }; 1082f7df2e56Smrg event.u.destroyNotify.window = pWin->drawable.id; 1083f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 108405b261ecSmrg } 108505b261ecSmrg 108605b261ecSmrg FreeWindowResources(pWin); 1087f7df2e56Smrg if (pParent) { 1088f7df2e56Smrg if (pParent->firstChild == pWin) 1089f7df2e56Smrg pParent->firstChild = pWin->nextSib; 1090f7df2e56Smrg if (pParent->lastChild == pWin) 1091f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1092f7df2e56Smrg if (pWin->nextSib) 1093f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1094f7df2e56Smrg if (pWin->prevSib) 1095f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 109605b261ecSmrg } 10974202a189Smrg else 1098f7df2e56Smrg pWin->drawable.pScreen->root = NULL; 10994202a189Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 110005b261ecSmrg return Success; 110105b261ecSmrg} 110205b261ecSmrg 1103637ac9abSmrgint 110405b261ecSmrgDestroySubwindows(WindowPtr pWin, ClientPtr client) 110505b261ecSmrg{ 110605b261ecSmrg /* XXX 110705b261ecSmrg * The protocol is quite clear that each window should be 110805b261ecSmrg * destroyed in turn, however, unmapping all of the first 110905b261ecSmrg * eliminates most of the calls to ValidateTree. So, 111005b261ecSmrg * this implementation is incorrect in that all of the 111105b261ecSmrg * UnmapNotifies occur before all of the DestroyNotifies. 111205b261ecSmrg * If you care, simply delete the call to UnmapSubwindows. 111305b261ecSmrg */ 111405b261ecSmrg UnmapSubwindows(pWin); 1115637ac9abSmrg while (pWin->lastChild) { 1116f7df2e56Smrg int rc = XaceHook(XACE_RESOURCE_ACCESS, client, 1117f7df2e56Smrg pWin->lastChild->drawable.id, RT_WINDOW, 1118f7df2e56Smrg pWin->lastChild, RT_NONE, NULL, DixDestroyAccess); 1119f7df2e56Smrg 1120f7df2e56Smrg if (rc != Success) 1121f7df2e56Smrg return rc; 1122f7df2e56Smrg FreeResource(pWin->lastChild->drawable.id, RT_NONE); 1123637ac9abSmrg } 1124637ac9abSmrg return Success; 112505b261ecSmrg} 112605b261ecSmrg 112765b04b38Smrgstatic void 112865b04b38SmrgSetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) 112965b04b38Smrg{ 113065b04b38Smrg /* following the protocol: "Changing the background of a root window to 113165b04b38Smrg * None or ParentRelative restores the default background pixmap" */ 113265b04b38Smrg if (bgNoneRoot) { 1133f7df2e56Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 1134f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 113565b04b38Smrg } 113665b04b38Smrg else if (party_like_its_1989) 1137f7df2e56Smrg MakeRootTile(pWin); 113865b04b38Smrg else { 113965b04b38Smrg pWin->backgroundState = BackgroundPixel; 1140f7df2e56Smrg if (whiteRoot) 1141f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 1142f7df2e56Smrg else 1143f7df2e56Smrg pWin->background.pixel = pScreen->blackPixel; 1144f7df2e56Smrg *index2 = CWBackPixel; 114565b04b38Smrg } 114665b04b38Smrg} 114765b04b38Smrg 114805b261ecSmrg/***** 114905b261ecSmrg * ChangeWindowAttributes 1150f7df2e56Smrg * 115105b261ecSmrg * The value-mask specifies which attributes are to be changed; the 115205b261ecSmrg * value-list contains one value for each one bit in the mask, from least 1153f7df2e56Smrg * to most significant bit in the mask. 115405b261ecSmrg *****/ 1155f7df2e56Smrg 11564202a189Smrgint 115705b261ecSmrgChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) 115805b261ecSmrg{ 115905b261ecSmrg XID *pVlist; 116005b261ecSmrg PixmapPtr pPixmap; 116105b261ecSmrg Pixmap pixID; 116205b261ecSmrg CursorPtr pCursor, pOldCursor; 116305b261ecSmrg Cursor cursorID; 116405b261ecSmrg WindowPtr pChild; 116505b261ecSmrg Colormap cmap; 1166f7df2e56Smrg ColormapPtr pCmap; 116705b261ecSmrg xEvent xE; 1168637ac9abSmrg int error, rc; 116905b261ecSmrg ScreenPtr pScreen; 1170637ac9abSmrg Mask index2, tmask, vmaskCopy = 0; 117105b261ecSmrg unsigned int val; 1172637ac9abSmrg Bool checkOptional = FALSE, borderRelative = FALSE; 117305b261ecSmrg 1174f7df2e56Smrg if ((pWin->drawable.class == InputOnly) && 1175f7df2e56Smrg (vmask & (~INPUTONLY_LEGAL_MASK))) 1176f7df2e56Smrg return BadMatch; 117705b261ecSmrg 117805b261ecSmrg error = Success; 117905b261ecSmrg pScreen = pWin->drawable.pScreen; 118005b261ecSmrg pVlist = vlist; 118105b261ecSmrg tmask = vmask; 1182f7df2e56Smrg while (tmask) { 1183f7df2e56Smrg index2 = (Mask) lowbit(tmask); 1184f7df2e56Smrg tmask &= ~index2; 1185f7df2e56Smrg switch (index2) { 1186f7df2e56Smrg case CWBackPixmap: 1187f7df2e56Smrg pixID = (Pixmap) * pVlist; 1188f7df2e56Smrg pVlist++; 1189f7df2e56Smrg if (pWin->backgroundState == ParentRelative) 1190f7df2e56Smrg borderRelative = TRUE; 1191f7df2e56Smrg if (pixID == None) { 1192f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1193f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1194f7df2e56Smrg if (!pWin->parent) 1195f7df2e56Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1196f7df2e56Smrg else { 1197f7df2e56Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 1198f7df2e56Smrg pWin->background.pixel = pScreen->whitePixel; 1199f7df2e56Smrg } 1200f7df2e56Smrg } 1201f7df2e56Smrg else if (pixID == ParentRelative) { 1202f7df2e56Smrg if (pWin->parent && 1203f7df2e56Smrg pWin->drawable.depth != pWin->parent->drawable.depth) { 1204f7df2e56Smrg error = BadMatch; 1205f7df2e56Smrg goto PatchUp; 1206f7df2e56Smrg } 1207f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1208f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1209f7df2e56Smrg if (!pWin->parent) 1210f7df2e56Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1211f7df2e56Smrg else 1212f7df2e56Smrg pWin->backgroundState = ParentRelative; 1213f7df2e56Smrg borderRelative = TRUE; 1214f7df2e56Smrg /* Note that the parent's backgroundTile's refcnt is NOT 1215f7df2e56Smrg * incremented. */ 1216f7df2e56Smrg } 1217f7df2e56Smrg else { 1218f7df2e56Smrg rc = dixLookupResourceByType((void **) &pPixmap, pixID, 1219f7df2e56Smrg RT_PIXMAP, client, DixReadAccess); 1220f7df2e56Smrg if (rc == Success) { 1221f7df2e56Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1222f7df2e56Smrg (pPixmap->drawable.pScreen != pScreen)) { 1223f7df2e56Smrg error = BadMatch; 1224f7df2e56Smrg goto PatchUp; 1225f7df2e56Smrg } 1226f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1227f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1228f7df2e56Smrg pWin->backgroundState = BackgroundPixmap; 1229f7df2e56Smrg pWin->background.pixmap = pPixmap; 1230f7df2e56Smrg pPixmap->refcnt++; 1231f7df2e56Smrg } 1232f7df2e56Smrg else { 1233f7df2e56Smrg error = rc; 1234f7df2e56Smrg client->errorValue = pixID; 1235f7df2e56Smrg goto PatchUp; 1236f7df2e56Smrg } 1237f7df2e56Smrg } 1238f7df2e56Smrg break; 1239f7df2e56Smrg case CWBackPixel: 1240f7df2e56Smrg if (pWin->backgroundState == ParentRelative) 1241f7df2e56Smrg borderRelative = TRUE; 1242f7df2e56Smrg if (pWin->backgroundState == BackgroundPixmap) 1243f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->background.pixmap); 1244f7df2e56Smrg pWin->backgroundState = BackgroundPixel; 1245f7df2e56Smrg pWin->background.pixel = (CARD32) *pVlist; 1246f7df2e56Smrg /* background pixel overrides background pixmap, 1247f7df2e56Smrg so don't let the ddx layer see both bits */ 1248f7df2e56Smrg vmaskCopy &= ~CWBackPixmap; 1249f7df2e56Smrg pVlist++; 1250f7df2e56Smrg break; 1251f7df2e56Smrg case CWBorderPixmap: 1252f7df2e56Smrg pixID = (Pixmap) * pVlist; 1253f7df2e56Smrg pVlist++; 1254f7df2e56Smrg if (pixID == CopyFromParent) { 1255f7df2e56Smrg if (!pWin->parent || 1256f7df2e56Smrg (pWin->drawable.depth != pWin->parent->drawable.depth)) { 1257f7df2e56Smrg error = BadMatch; 1258f7df2e56Smrg goto PatchUp; 1259f7df2e56Smrg } 1260f7df2e56Smrg if (pWin->parent->borderIsPixel == TRUE) { 1261f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1262f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1263f7df2e56Smrg pWin->border = pWin->parent->border; 1264f7df2e56Smrg pWin->borderIsPixel = TRUE; 1265f7df2e56Smrg index2 = CWBorderPixel; 1266f7df2e56Smrg break; 1267f7df2e56Smrg } 1268f7df2e56Smrg else { 1269f7df2e56Smrg pixID = pWin->parent->border.pixmap->drawable.id; 1270f7df2e56Smrg } 1271f7df2e56Smrg } 1272f7df2e56Smrg rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP, 1273f7df2e56Smrg client, DixReadAccess); 1274f7df2e56Smrg if (rc == Success) { 1275f7df2e56Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1276f7df2e56Smrg (pPixmap->drawable.pScreen != pScreen)) { 1277f7df2e56Smrg error = BadMatch; 1278f7df2e56Smrg goto PatchUp; 1279f7df2e56Smrg } 1280f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1281f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1282f7df2e56Smrg pWin->borderIsPixel = FALSE; 1283f7df2e56Smrg pWin->border.pixmap = pPixmap; 1284f7df2e56Smrg pPixmap->refcnt++; 1285f7df2e56Smrg } 1286f7df2e56Smrg else { 1287f7df2e56Smrg error = rc; 1288f7df2e56Smrg client->errorValue = pixID; 1289f7df2e56Smrg goto PatchUp; 1290f7df2e56Smrg } 1291f7df2e56Smrg break; 1292f7df2e56Smrg case CWBorderPixel: 1293f7df2e56Smrg if (pWin->borderIsPixel == FALSE) 1294f7df2e56Smrg (*pScreen->DestroyPixmap) (pWin->border.pixmap); 1295f7df2e56Smrg pWin->borderIsPixel = TRUE; 1296f7df2e56Smrg pWin->border.pixel = (CARD32) *pVlist; 1297f7df2e56Smrg /* border pixel overrides border pixmap, 1298f7df2e56Smrg so don't let the ddx layer see both bits */ 1299f7df2e56Smrg vmaskCopy &= ~CWBorderPixmap; 1300f7df2e56Smrg pVlist++; 1301f7df2e56Smrg break; 1302f7df2e56Smrg case CWBitGravity: 1303f7df2e56Smrg val = (CARD8) *pVlist; 1304f7df2e56Smrg pVlist++; 1305f7df2e56Smrg if (val > StaticGravity) { 1306f7df2e56Smrg error = BadValue; 1307f7df2e56Smrg client->errorValue = val; 1308f7df2e56Smrg goto PatchUp; 1309f7df2e56Smrg } 1310f7df2e56Smrg pWin->bitGravity = val; 1311f7df2e56Smrg break; 1312f7df2e56Smrg case CWWinGravity: 1313f7df2e56Smrg val = (CARD8) *pVlist; 1314f7df2e56Smrg pVlist++; 1315f7df2e56Smrg if (val > StaticGravity) { 1316f7df2e56Smrg error = BadValue; 1317f7df2e56Smrg client->errorValue = val; 1318f7df2e56Smrg goto PatchUp; 1319f7df2e56Smrg } 1320f7df2e56Smrg pWin->winGravity = val; 1321f7df2e56Smrg break; 1322f7df2e56Smrg case CWBackingStore: 1323f7df2e56Smrg val = (CARD8) *pVlist; 1324f7df2e56Smrg pVlist++; 1325f7df2e56Smrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) { 1326f7df2e56Smrg error = BadValue; 1327f7df2e56Smrg client->errorValue = val; 1328f7df2e56Smrg goto PatchUp; 1329f7df2e56Smrg } 13305a112b11Smrg /* if we're not actually changing the window's state, hide 13315a112b11Smrg * CWBackingStore from vmaskCopy so it doesn't get passed to 13325a112b11Smrg * ->ChangeWindowAttributes below 13335a112b11Smrg */ 13345a112b11Smrg if (pWin->backingStore == val) 13355a112b11Smrg continue; 1336f7df2e56Smrg pWin->backingStore = val; 1337f7df2e56Smrg break; 1338f7df2e56Smrg case CWBackingPlanes: 1339f7df2e56Smrg if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) { 1340f7df2e56Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) { 1341f7df2e56Smrg error = BadAlloc; 1342f7df2e56Smrg goto PatchUp; 1343f7df2e56Smrg } 1344f7df2e56Smrg pWin->optional->backingBitPlanes = (CARD32) *pVlist; 1345f7df2e56Smrg if ((CARD32) *pVlist == (CARD32) ~0L) 1346f7df2e56Smrg checkOptional = TRUE; 1347f7df2e56Smrg } 1348f7df2e56Smrg pVlist++; 1349f7df2e56Smrg break; 1350f7df2e56Smrg case CWBackingPixel: 1351f7df2e56Smrg if (pWin->optional || (CARD32) *pVlist) { 1352f7df2e56Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) { 1353f7df2e56Smrg error = BadAlloc; 1354f7df2e56Smrg goto PatchUp; 1355f7df2e56Smrg } 1356f7df2e56Smrg pWin->optional->backingPixel = (CARD32) *pVlist; 1357f7df2e56Smrg if (!*pVlist) 1358f7df2e56Smrg checkOptional = TRUE; 1359f7df2e56Smrg } 1360f7df2e56Smrg pVlist++; 1361f7df2e56Smrg break; 1362f7df2e56Smrg case CWSaveUnder: 1363f7df2e56Smrg val = (BOOL) * pVlist; 1364f7df2e56Smrg pVlist++; 1365f7df2e56Smrg if ((val != xTrue) && (val != xFalse)) { 1366f7df2e56Smrg error = BadValue; 1367f7df2e56Smrg client->errorValue = val; 1368f7df2e56Smrg goto PatchUp; 1369f7df2e56Smrg } 1370f7df2e56Smrg pWin->saveUnder = val; 1371f7df2e56Smrg break; 1372f7df2e56Smrg case CWEventMask: 1373f7df2e56Smrg rc = EventSelectForWindow(pWin, client, (Mask) *pVlist); 1374f7df2e56Smrg if (rc) { 1375f7df2e56Smrg error = rc; 1376f7df2e56Smrg goto PatchUp; 1377f7df2e56Smrg } 1378f7df2e56Smrg pVlist++; 1379f7df2e56Smrg break; 1380f7df2e56Smrg case CWDontPropagate: 1381f7df2e56Smrg rc = EventSuppressForWindow(pWin, client, (Mask) *pVlist, 1382f7df2e56Smrg &checkOptional); 1383f7df2e56Smrg if (rc) { 1384f7df2e56Smrg error = rc; 1385f7df2e56Smrg goto PatchUp; 1386f7df2e56Smrg } 1387f7df2e56Smrg pVlist++; 1388f7df2e56Smrg break; 1389f7df2e56Smrg case CWOverrideRedirect: 1390f7df2e56Smrg val = (BOOL) * pVlist; 1391f7df2e56Smrg pVlist++; 1392f7df2e56Smrg if ((val != xTrue) && (val != xFalse)) { 1393f7df2e56Smrg error = BadValue; 1394f7df2e56Smrg client->errorValue = val; 1395f7df2e56Smrg goto PatchUp; 1396f7df2e56Smrg } 1397f7df2e56Smrg if (val == xTrue) { 1398f7df2e56Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, 1399f7df2e56Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess); 1400f7df2e56Smrg if (rc != Success) { 1401f7df2e56Smrg error = rc; 1402f7df2e56Smrg client->errorValue = pWin->drawable.id; 1403f7df2e56Smrg goto PatchUp; 1404f7df2e56Smrg } 1405f7df2e56Smrg } 1406f7df2e56Smrg pWin->overrideRedirect = val; 1407f7df2e56Smrg break; 1408f7df2e56Smrg case CWColormap: 1409f7df2e56Smrg cmap = (Colormap) * pVlist; 1410f7df2e56Smrg pVlist++; 1411f7df2e56Smrg if (cmap == CopyFromParent) { 1412f7df2e56Smrg if (pWin->parent && 1413f7df2e56Smrg (!pWin->optional || 1414f7df2e56Smrg pWin->optional->visual == wVisual(pWin->parent))) { 1415f7df2e56Smrg cmap = wColormap(pWin->parent); 1416f7df2e56Smrg } 1417f7df2e56Smrg else 1418f7df2e56Smrg cmap = None; 1419f7df2e56Smrg } 1420f7df2e56Smrg if (cmap == None) { 1421f7df2e56Smrg error = BadMatch; 1422f7df2e56Smrg goto PatchUp; 1423f7df2e56Smrg } 1424f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP, 1425f7df2e56Smrg client, DixUseAccess); 1426f7df2e56Smrg if (rc != Success) { 1427f7df2e56Smrg error = rc; 1428f7df2e56Smrg client->errorValue = cmap; 1429f7df2e56Smrg goto PatchUp; 1430f7df2e56Smrg } 1431f7df2e56Smrg if (pCmap->pVisual->vid != wVisual(pWin) || 1432f7df2e56Smrg pCmap->pScreen != pScreen) { 1433f7df2e56Smrg error = BadMatch; 1434f7df2e56Smrg goto PatchUp; 1435f7df2e56Smrg } 1436f7df2e56Smrg if (cmap != wColormap(pWin)) { 1437f7df2e56Smrg if (!pWin->optional) { 1438f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 1439f7df2e56Smrg error = BadAlloc; 1440f7df2e56Smrg goto PatchUp; 1441f7df2e56Smrg } 1442f7df2e56Smrg } 1443f7df2e56Smrg else if (pWin->parent && cmap == wColormap(pWin->parent)) 1444f7df2e56Smrg checkOptional = TRUE; 1445f7df2e56Smrg 1446f7df2e56Smrg /* 1447f7df2e56Smrg * propagate the original colormap to any children 1448f7df2e56Smrg * inheriting it 1449f7df2e56Smrg */ 1450f7df2e56Smrg 1451f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1452f7df2e56Smrg pChild = pChild->nextSib) { 1453f7df2e56Smrg if (!pChild->optional && !MakeWindowOptional(pChild)) { 1454f7df2e56Smrg error = BadAlloc; 1455f7df2e56Smrg goto PatchUp; 1456f7df2e56Smrg } 1457f7df2e56Smrg } 1458f7df2e56Smrg 1459f7df2e56Smrg pWin->optional->colormap = cmap; 1460f7df2e56Smrg 1461f7df2e56Smrg /* 1462f7df2e56Smrg * check on any children now matching the new colormap 1463f7df2e56Smrg */ 1464f7df2e56Smrg 1465f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1466f7df2e56Smrg pChild = pChild->nextSib) { 1467f7df2e56Smrg if (pChild->optional->colormap == cmap) 1468f7df2e56Smrg CheckWindowOptionalNeed(pChild); 1469f7df2e56Smrg } 1470f7df2e56Smrg 1471f7df2e56Smrg xE = (xEvent) { 1472f7df2e56Smrg .u.colormap.window = pWin->drawable.id, 1473f7df2e56Smrg .u.colormap.colormap = cmap, 1474f7df2e56Smrg .u.colormap.new = xTrue, 1475f7df2e56Smrg .u.colormap.state = IsMapInstalled(cmap, pWin) 1476f7df2e56Smrg }; 1477f7df2e56Smrg xE.u.u.type = ColormapNotify; 1478f7df2e56Smrg DeliverEvents(pWin, &xE, 1, NullWindow); 1479f7df2e56Smrg } 1480f7df2e56Smrg break; 1481f7df2e56Smrg case CWCursor: 1482f7df2e56Smrg cursorID = (Cursor) * pVlist; 1483f7df2e56Smrg pVlist++; 1484f7df2e56Smrg /* 1485f7df2e56Smrg * install the new 1486f7df2e56Smrg */ 1487f7df2e56Smrg if (cursorID == None) { 1488f7df2e56Smrg if (pWin == pWin->drawable.pScreen->root) 1489f7df2e56Smrg pCursor = rootCursor; 1490f7df2e56Smrg else 1491f7df2e56Smrg pCursor = (CursorPtr) None; 1492f7df2e56Smrg } 1493f7df2e56Smrg else { 1494f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCursor, cursorID, 1495f7df2e56Smrg RT_CURSOR, client, DixUseAccess); 1496f7df2e56Smrg if (rc != Success) { 1497f7df2e56Smrg error = rc; 1498f7df2e56Smrg client->errorValue = cursorID; 1499f7df2e56Smrg goto PatchUp; 1500f7df2e56Smrg } 1501f7df2e56Smrg } 1502f7df2e56Smrg 1503f7df2e56Smrg if (pCursor != wCursor(pWin)) { 1504f7df2e56Smrg /* 1505f7df2e56Smrg * patch up child windows so they don't lose cursors. 1506f7df2e56Smrg */ 1507f7df2e56Smrg 1508f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1509f7df2e56Smrg pChild = pChild->nextSib) { 1510f7df2e56Smrg if (!pChild->optional && !pChild->cursorIsNone && 1511f7df2e56Smrg !MakeWindowOptional(pChild)) { 1512f7df2e56Smrg error = BadAlloc; 1513f7df2e56Smrg goto PatchUp; 1514f7df2e56Smrg } 1515f7df2e56Smrg } 1516f7df2e56Smrg 1517f7df2e56Smrg pOldCursor = 0; 1518f7df2e56Smrg if (pCursor == (CursorPtr) None) { 1519f7df2e56Smrg pWin->cursorIsNone = TRUE; 1520f7df2e56Smrg if (pWin->optional) { 1521f7df2e56Smrg pOldCursor = pWin->optional->cursor; 1522f7df2e56Smrg pWin->optional->cursor = (CursorPtr) None; 1523f7df2e56Smrg checkOptional = TRUE; 1524f7df2e56Smrg } 1525f7df2e56Smrg } 1526f7df2e56Smrg else { 1527f7df2e56Smrg if (!pWin->optional) { 1528f7df2e56Smrg if (!MakeWindowOptional(pWin)) { 1529f7df2e56Smrg error = BadAlloc; 1530f7df2e56Smrg goto PatchUp; 1531f7df2e56Smrg } 1532f7df2e56Smrg } 1533f7df2e56Smrg else if (pWin->parent && pCursor == wCursor(pWin->parent)) 1534f7df2e56Smrg checkOptional = TRUE; 1535f7df2e56Smrg pOldCursor = pWin->optional->cursor; 1536f7df2e56Smrg pWin->optional->cursor = RefCursor(pCursor); 1537f7df2e56Smrg pWin->cursorIsNone = FALSE; 1538f7df2e56Smrg /* 1539f7df2e56Smrg * check on any children now matching the new cursor 1540f7df2e56Smrg */ 1541f7df2e56Smrg 1542f7df2e56Smrg for (pChild = pWin->firstChild; pChild; 1543f7df2e56Smrg pChild = pChild->nextSib) { 1544f7df2e56Smrg if (pChild->optional && 1545f7df2e56Smrg (pChild->optional->cursor == pCursor)) 1546f7df2e56Smrg CheckWindowOptionalNeed(pChild); 1547f7df2e56Smrg } 1548f7df2e56Smrg } 1549f7df2e56Smrg 1550f7df2e56Smrg CursorVisible = TRUE; 1551f7df2e56Smrg 1552f7df2e56Smrg if (pWin->realized) 1553f7df2e56Smrg WindowHasNewCursor(pWin); 1554f7df2e56Smrg 1555f7df2e56Smrg /* Can't free cursor until here - old cursor 1556f7df2e56Smrg * is needed in WindowHasNewCursor 1557f7df2e56Smrg */ 1558f7df2e56Smrg if (pOldCursor) 1559f7df2e56Smrg FreeCursor(pOldCursor, (Cursor) 0); 1560f7df2e56Smrg } 1561f7df2e56Smrg break; 1562f7df2e56Smrg default: 1563f7df2e56Smrg error = BadValue; 1564f7df2e56Smrg client->errorValue = vmask; 1565f7df2e56Smrg goto PatchUp; 1566f7df2e56Smrg } 1567f7df2e56Smrg vmaskCopy |= index2; 1568f7df2e56Smrg } 1569f7df2e56Smrg PatchUp: 157005b261ecSmrg if (checkOptional) 1571f7df2e56Smrg CheckWindowOptionalNeed(pWin); 157205b261ecSmrg 1573f7df2e56Smrg /* We SHOULD check for an error value here XXX */ 1574f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy); 157505b261ecSmrg 1576f7df2e56Smrg /* 1577f7df2e56Smrg If the border contents have changed, redraw the border. 1578f7df2e56Smrg Note that this has to be done AFTER pScreen->ChangeWindowAttributes 1579f7df2e56Smrg for the tile to be rotated, and the correct function selected. 1580f7df2e56Smrg */ 158105b261ecSmrg if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) 1582f7df2e56Smrg && pWin->viewable && HasBorder(pWin)) { 1583f7df2e56Smrg RegionRec exposed; 158405b261ecSmrg 1585f7df2e56Smrg RegionNull(&exposed); 1586f7df2e56Smrg RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); 1587f7df2e56Smrg pWin->drawable.pScreen->PaintWindow(pWin, &exposed, PW_BORDER); 1588f7df2e56Smrg RegionUninit(&exposed); 158905b261ecSmrg } 159005b261ecSmrg return error; 159105b261ecSmrg} 159205b261ecSmrg 159305b261ecSmrg/***** 159405b261ecSmrg * GetWindowAttributes 159505b261ecSmrg * Notice that this is different than ChangeWindowAttributes 159605b261ecSmrg *****/ 159705b261ecSmrg 159805b261ecSmrgvoid 1599f7df2e56SmrgGetWindowAttributes(WindowPtr pWin, ClientPtr client, 1600f7df2e56Smrg xGetWindowAttributesReply * wa) 160105b261ecSmrg{ 160205b261ecSmrg wa->type = X_Reply; 160305b261ecSmrg wa->bitGravity = pWin->bitGravity; 160405b261ecSmrg wa->winGravity = pWin->winGravity; 16055a112b11Smrg wa->backingStore = pWin->backingStore; 16064202a189Smrg wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - 1607f7df2e56Smrg sizeof(xGenericReply)); 160805b261ecSmrg wa->sequenceNumber = client->sequence; 1609f7df2e56Smrg wa->backingBitPlanes = wBackingBitPlanes(pWin); 1610f7df2e56Smrg wa->backingPixel = wBackingPixel(pWin); 1611f7df2e56Smrg wa->saveUnder = (BOOL) pWin->saveUnder; 161205b261ecSmrg wa->override = pWin->overrideRedirect; 161305b261ecSmrg if (!pWin->mapped) 1614f7df2e56Smrg wa->mapState = IsUnmapped; 161505b261ecSmrg else if (pWin->realized) 1616f7df2e56Smrg wa->mapState = IsViewable; 161705b261ecSmrg else 1618f7df2e56Smrg wa->mapState = IsUnviewable; 161905b261ecSmrg 1620f7df2e56Smrg wa->colormap = wColormap(pWin); 162105b261ecSmrg wa->mapInstalled = (wa->colormap == None) ? xFalse 1622f7df2e56Smrg : IsMapInstalled(wa->colormap, pWin); 162305b261ecSmrg 162405b261ecSmrg wa->yourEventMask = EventMaskForClient(pWin, client); 1625f7df2e56Smrg wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin); 1626f7df2e56Smrg wa->doNotPropagateMask = wDontPropagateMask(pWin); 162705b261ecSmrg wa->class = pWin->drawable.class; 1628f7df2e56Smrg wa->visualID = wVisual(pWin); 162905b261ecSmrg} 163005b261ecSmrg 1631637ac9abSmrgWindowPtr 163205b261ecSmrgMoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) 163305b261ecSmrg{ 163405b261ecSmrg WindowPtr pParent = pWin->parent; 1635f7df2e56Smrg WindowPtr pFirstChange = pWin; /* highest window where list changes */ 1636f7df2e56Smrg 1637f7df2e56Smrg if (pWin->nextSib != pNextSib) { 1638f7df2e56Smrg WindowPtr pOldNextSib = pWin->nextSib; 1639f7df2e56Smrg 1640f7df2e56Smrg if (!pNextSib) { /* move to bottom */ 1641f7df2e56Smrg if (pParent->firstChild == pWin) 1642f7df2e56Smrg pParent->firstChild = pWin->nextSib; 1643f7df2e56Smrg /* if (pWin->nextSib) *//* is always True: pNextSib == NULL 1644f7df2e56Smrg * and pWin->nextSib != pNextSib 1645f7df2e56Smrg * therefore pWin->nextSib != NULL */ 1646f7df2e56Smrg pFirstChange = pWin->nextSib; 1647f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1648f7df2e56Smrg if (pWin->prevSib) 1649f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1650f7df2e56Smrg pParent->lastChild->nextSib = pWin; 1651f7df2e56Smrg pWin->prevSib = pParent->lastChild; 1652f7df2e56Smrg pWin->nextSib = NullWindow; 1653f7df2e56Smrg pParent->lastChild = pWin; 1654f7df2e56Smrg } 1655f7df2e56Smrg else if (pParent->firstChild == pNextSib) { /* move to top */ 1656f7df2e56Smrg pFirstChange = pWin; 1657f7df2e56Smrg if (pParent->lastChild == pWin) 1658f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1659f7df2e56Smrg if (pWin->nextSib) 1660f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1661f7df2e56Smrg if (pWin->prevSib) 1662f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1663f7df2e56Smrg pWin->nextSib = pParent->firstChild; 1664f7df2e56Smrg pWin->prevSib = NULL; 1665f7df2e56Smrg pNextSib->prevSib = pWin; 1666f7df2e56Smrg pParent->firstChild = pWin; 1667f7df2e56Smrg } 1668f7df2e56Smrg else { /* move in middle of list */ 166905b261ecSmrg 1670f7df2e56Smrg WindowPtr pOldNext = pWin->nextSib; 1671f7df2e56Smrg 1672f7df2e56Smrg pFirstChange = NullWindow; 1673f7df2e56Smrg if (pParent->firstChild == pWin) 1674f7df2e56Smrg pFirstChange = pParent->firstChild = pWin->nextSib; 1675f7df2e56Smrg if (pParent->lastChild == pWin) { 1676f7df2e56Smrg pFirstChange = pWin; 1677f7df2e56Smrg pParent->lastChild = pWin->prevSib; 1678f7df2e56Smrg } 1679f7df2e56Smrg if (pWin->nextSib) 1680f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 1681f7df2e56Smrg if (pWin->prevSib) 1682f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 1683f7df2e56Smrg pWin->nextSib = pNextSib; 1684f7df2e56Smrg pWin->prevSib = pNextSib->prevSib; 1685f7df2e56Smrg if (pNextSib->prevSib) 1686f7df2e56Smrg pNextSib->prevSib->nextSib = pWin; 1687f7df2e56Smrg pNextSib->prevSib = pWin; 1688f7df2e56Smrg if (!pFirstChange) { /* do we know it yet? */ 1689f7df2e56Smrg pFirstChange = pParent->firstChild; /* no, search from top */ 1690f7df2e56Smrg while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) 1691f7df2e56Smrg pFirstChange = pFirstChange->nextSib; 1692f7df2e56Smrg } 1693f7df2e56Smrg } 1694f7df2e56Smrg if (pWin->drawable.pScreen->RestackWindow) 1695f7df2e56Smrg (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib); 169605b261ecSmrg } 169705b261ecSmrg 169805b261ecSmrg#ifdef ROOTLESS 169905b261ecSmrg /* 170005b261ecSmrg * In rootless mode we can't optimize away window restacks. 170105b261ecSmrg * There may be non-X windows around, so even if the window 170205b261ecSmrg * is in the correct position from X's point of view, 170305b261ecSmrg * the underlying window system may want to reorder it. 170405b261ecSmrg */ 170505b261ecSmrg else if (pWin->drawable.pScreen->RestackWindow) 1706f7df2e56Smrg (*pWin->drawable.pScreen->RestackWindow) (pWin, pWin->nextSib); 170705b261ecSmrg#endif 170805b261ecSmrg 17094202a189Smrg return pFirstChange; 171005b261ecSmrg} 171105b261ecSmrg 1712637ac9abSmrgvoid 1713f7df2e56SmrgSetWinSize(WindowPtr pWin) 171405b261ecSmrg{ 171505b261ecSmrg#ifdef COMPOSITE 1716f7df2e56Smrg if (pWin->redirectDraw != RedirectDrawNone) { 1717f7df2e56Smrg BoxRec box; 1718f7df2e56Smrg 1719f7df2e56Smrg /* 1720f7df2e56Smrg * Redirected clients get clip list equal to their 1721f7df2e56Smrg * own geometry, not clipped to their parent 1722f7df2e56Smrg */ 1723f7df2e56Smrg box.x1 = pWin->drawable.x; 1724f7df2e56Smrg box.y1 = pWin->drawable.y; 1725f7df2e56Smrg box.x2 = pWin->drawable.x + pWin->drawable.width; 1726f7df2e56Smrg box.y2 = pWin->drawable.y + pWin->drawable.height; 1727f7df2e56Smrg RegionReset(&pWin->winSize, &box); 172805b261ecSmrg } 172905b261ecSmrg else 173005b261ecSmrg#endif 1731f7df2e56Smrg ClippedRegionFromBox(pWin->parent, &pWin->winSize, 1732f7df2e56Smrg pWin->drawable.x, pWin->drawable.y, 1733f7df2e56Smrg (int) pWin->drawable.width, 1734f7df2e56Smrg (int) pWin->drawable.height); 1735f7df2e56Smrg if (wBoundingShape(pWin) || wClipShape(pWin)) { 1736f7df2e56Smrg RegionTranslate(&pWin->winSize, -pWin->drawable.x, -pWin->drawable.y); 1737f7df2e56Smrg if (wBoundingShape(pWin)) 1738f7df2e56Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, 1739f7df2e56Smrg wBoundingShape(pWin)); 1740f7df2e56Smrg if (wClipShape(pWin)) 1741f7df2e56Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, wClipShape(pWin)); 1742f7df2e56Smrg RegionTranslate(&pWin->winSize, pWin->drawable.x, pWin->drawable.y); 174305b261ecSmrg } 174405b261ecSmrg} 174505b261ecSmrg 1746637ac9abSmrgvoid 1747f7df2e56SmrgSetBorderSize(WindowPtr pWin) 174805b261ecSmrg{ 1749f7df2e56Smrg int bw; 175005b261ecSmrg 1751f7df2e56Smrg if (HasBorder(pWin)) { 1752f7df2e56Smrg bw = wBorderWidth(pWin); 175305b261ecSmrg#ifdef COMPOSITE 1754f7df2e56Smrg if (pWin->redirectDraw != RedirectDrawNone) { 1755f7df2e56Smrg BoxRec box; 1756f7df2e56Smrg 1757f7df2e56Smrg /* 1758f7df2e56Smrg * Redirected clients get clip list equal to their 1759f7df2e56Smrg * own geometry, not clipped to their parent 1760f7df2e56Smrg */ 1761f7df2e56Smrg box.x1 = pWin->drawable.x - bw; 1762f7df2e56Smrg box.y1 = pWin->drawable.y - bw; 1763f7df2e56Smrg box.x2 = pWin->drawable.x + pWin->drawable.width + bw; 1764f7df2e56Smrg box.y2 = pWin->drawable.y + pWin->drawable.height + bw; 1765f7df2e56Smrg RegionReset(&pWin->borderSize, &box); 1766f7df2e56Smrg } 1767f7df2e56Smrg else 176805b261ecSmrg#endif 1769f7df2e56Smrg ClippedRegionFromBox(pWin->parent, &pWin->borderSize, 1770f7df2e56Smrg pWin->drawable.x - bw, pWin->drawable.y - bw, 1771f7df2e56Smrg (int) (pWin->drawable.width + (bw << 1)), 1772f7df2e56Smrg (int) (pWin->drawable.height + (bw << 1))); 1773f7df2e56Smrg if (wBoundingShape(pWin)) { 1774f7df2e56Smrg RegionTranslate(&pWin->borderSize, -pWin->drawable.x, 1775f7df2e56Smrg -pWin->drawable.y); 1776f7df2e56Smrg RegionIntersect(&pWin->borderSize, &pWin->borderSize, 1777f7df2e56Smrg wBoundingShape(pWin)); 1778f7df2e56Smrg RegionTranslate(&pWin->borderSize, pWin->drawable.x, 1779f7df2e56Smrg pWin->drawable.y); 1780f7df2e56Smrg RegionUnion(&pWin->borderSize, &pWin->borderSize, &pWin->winSize); 1781f7df2e56Smrg } 1782f7df2e56Smrg } 1783f7df2e56Smrg else { 1784f7df2e56Smrg RegionCopy(&pWin->borderSize, &pWin->winSize); 178505b261ecSmrg } 178605b261ecSmrg} 178705b261ecSmrg 178805b261ecSmrg/** 178905b261ecSmrg * 179005b261ecSmrg * \param x,y new window position 179105b261ecSmrg * \param oldx,oldy old window position 179205b261ecSmrg * \param destx,desty position relative to gravity 179305b261ecSmrg */ 179405b261ecSmrg 17954202a189Smrgvoid 1796f7df2e56SmrgGravityTranslate(int x, int y, int oldx, int oldy, 1797f7df2e56Smrg int dw, int dh, unsigned gravity, int *destx, int *desty) 179805b261ecSmrg{ 179905b261ecSmrg switch (gravity) { 180005b261ecSmrg case NorthGravity: 1801f7df2e56Smrg *destx = x + dw / 2; 1802f7df2e56Smrg *desty = y; 1803f7df2e56Smrg break; 180405b261ecSmrg case NorthEastGravity: 1805f7df2e56Smrg *destx = x + dw; 1806f7df2e56Smrg *desty = y; 1807f7df2e56Smrg break; 180805b261ecSmrg case WestGravity: 1809f7df2e56Smrg *destx = x; 1810f7df2e56Smrg *desty = y + dh / 2; 1811f7df2e56Smrg break; 181205b261ecSmrg case CenterGravity: 1813f7df2e56Smrg *destx = x + dw / 2; 1814f7df2e56Smrg *desty = y + dh / 2; 1815f7df2e56Smrg break; 181605b261ecSmrg case EastGravity: 1817f7df2e56Smrg *destx = x + dw; 1818f7df2e56Smrg *desty = y + dh / 2; 1819f7df2e56Smrg break; 182005b261ecSmrg case SouthWestGravity: 1821f7df2e56Smrg *destx = x; 1822f7df2e56Smrg *desty = y + dh; 1823f7df2e56Smrg break; 182405b261ecSmrg case SouthGravity: 1825f7df2e56Smrg *destx = x + dw / 2; 1826f7df2e56Smrg *desty = y + dh; 1827f7df2e56Smrg break; 182805b261ecSmrg case SouthEastGravity: 1829f7df2e56Smrg *destx = x + dw; 1830f7df2e56Smrg *desty = y + dh; 1831f7df2e56Smrg break; 183205b261ecSmrg case StaticGravity: 1833f7df2e56Smrg *destx = oldx; 1834f7df2e56Smrg *desty = oldy; 1835f7df2e56Smrg break; 183605b261ecSmrg default: 1837f7df2e56Smrg *destx = x; 1838f7df2e56Smrg *desty = y; 1839f7df2e56Smrg break; 184005b261ecSmrg } 184105b261ecSmrg} 184205b261ecSmrg 184305b261ecSmrg/* XXX need to retile border on each window with ParentRelative origin */ 1844637ac9abSmrgvoid 184505b261ecSmrgResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) 184605b261ecSmrg{ 184705b261ecSmrg ScreenPtr pScreen; 184805b261ecSmrg WindowPtr pSib, pChild; 184905b261ecSmrg Bool resized = (dw || dh); 185005b261ecSmrg 185105b261ecSmrg pScreen = pWin->drawable.pScreen; 185205b261ecSmrg 1853f7df2e56Smrg for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) { 1854f7df2e56Smrg if (resized && (pSib->winGravity > NorthWestGravity)) { 1855f7df2e56Smrg int cwsx, cwsy; 1856f7df2e56Smrg 1857f7df2e56Smrg cwsx = pSib->origin.x; 1858f7df2e56Smrg cwsy = pSib->origin.y; 1859f7df2e56Smrg GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, 1860f7df2e56Smrg pSib->winGravity, &cwsx, &cwsy); 1861f7df2e56Smrg if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) { 1862f7df2e56Smrg xEvent event = { 1863f7df2e56Smrg .u.gravity.window = pSib->drawable.id, 1864f7df2e56Smrg .u.gravity.x = cwsx - wBorderWidth(pSib), 1865f7df2e56Smrg .u.gravity.y = cwsy - wBorderWidth(pSib) 1866f7df2e56Smrg }; 1867f7df2e56Smrg event.u.u.type = GravityNotify; 1868f7df2e56Smrg DeliverEvents(pSib, &event, 1, NullWindow); 1869f7df2e56Smrg pSib->origin.x = cwsx; 1870f7df2e56Smrg pSib->origin.y = cwsy; 1871f7df2e56Smrg } 1872f7df2e56Smrg } 1873f7df2e56Smrg pSib->drawable.x = pWin->drawable.x + pSib->origin.x; 1874f7df2e56Smrg pSib->drawable.y = pWin->drawable.y + pSib->origin.y; 1875f7df2e56Smrg SetWinSize(pSib); 1876f7df2e56Smrg SetBorderSize(pSib); 1877f7df2e56Smrg (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y); 1878f7df2e56Smrg 1879f7df2e56Smrg if ((pChild = pSib->firstChild)) { 1880f7df2e56Smrg while (1) { 1881f7df2e56Smrg pChild->drawable.x = pChild->parent->drawable.x + 1882f7df2e56Smrg pChild->origin.x; 1883f7df2e56Smrg pChild->drawable.y = pChild->parent->drawable.y + 1884f7df2e56Smrg pChild->origin.y; 1885f7df2e56Smrg SetWinSize(pChild); 1886f7df2e56Smrg SetBorderSize(pChild); 1887f7df2e56Smrg (*pScreen->PositionWindow) (pChild, 1888f7df2e56Smrg pChild->drawable.x, 1889f7df2e56Smrg pChild->drawable.y); 1890f7df2e56Smrg if (pChild->firstChild) { 1891f7df2e56Smrg pChild = pChild->firstChild; 1892f7df2e56Smrg continue; 1893f7df2e56Smrg } 1894f7df2e56Smrg while (!pChild->nextSib && (pChild != pSib)) 1895f7df2e56Smrg pChild = pChild->parent; 1896f7df2e56Smrg if (pChild == pSib) 1897f7df2e56Smrg break; 1898f7df2e56Smrg pChild = pChild->nextSib; 1899f7df2e56Smrg } 1900f7df2e56Smrg } 190105b261ecSmrg } 190205b261ecSmrg} 190305b261ecSmrg 190405b261ecSmrg#define GET_INT16(m, f) \ 190505b261ecSmrg if (m & mask) \ 190605b261ecSmrg { \ 190705b261ecSmrg f = (INT16) *pVlist;\ 190805b261ecSmrg pVlist++; \ 190905b261ecSmrg } 191005b261ecSmrg#define GET_CARD16(m, f) \ 191105b261ecSmrg if (m & mask) \ 191205b261ecSmrg { \ 191305b261ecSmrg f = (CARD16) *pVlist;\ 191405b261ecSmrg pVlist++;\ 191505b261ecSmrg } 191605b261ecSmrg 191705b261ecSmrg#define GET_CARD8(m, f) \ 191805b261ecSmrg if (m & mask) \ 191905b261ecSmrg { \ 192005b261ecSmrg f = (CARD8) *pVlist;\ 192105b261ecSmrg pVlist++;\ 192205b261ecSmrg } 192305b261ecSmrg 192405b261ecSmrg#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight)) 192505b261ecSmrg 192605b261ecSmrg/* 192705b261ecSmrg * IsSiblingAboveMe 1928f7df2e56Smrg * returns Above if pSib above pMe in stack or Below otherwise 192905b261ecSmrg */ 193005b261ecSmrg 193105b261ecSmrgstatic int 1932f7df2e56SmrgIsSiblingAboveMe(WindowPtr pMe, WindowPtr pSib) 193305b261ecSmrg{ 193405b261ecSmrg WindowPtr pWin; 193505b261ecSmrg 193605b261ecSmrg pWin = pMe->parent->firstChild; 1937f7df2e56Smrg while (pWin) { 1938f7df2e56Smrg if (pWin == pSib) 1939f7df2e56Smrg return Above; 1940f7df2e56Smrg else if (pWin == pMe) 1941f7df2e56Smrg return Below; 1942f7df2e56Smrg pWin = pWin->nextSib; 194305b261ecSmrg } 19444202a189Smrg return Below; 194505b261ecSmrg} 194605b261ecSmrg 194705b261ecSmrgstatic BoxPtr 1948f7df2e56SmrgWindowExtents(WindowPtr pWin, BoxPtr pBox) 1949f7df2e56Smrg{ 1950f7df2e56Smrg pBox->x1 = pWin->drawable.x - wBorderWidth(pWin); 1951f7df2e56Smrg pBox->y1 = pWin->drawable.y - wBorderWidth(pWin); 1952f7df2e56Smrg pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width 1953f7df2e56Smrg + wBorderWidth(pWin); 1954f7df2e56Smrg pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height 1955f7df2e56Smrg + wBorderWidth(pWin); 19564202a189Smrg return pBox; 195705b261ecSmrg} 195805b261ecSmrg 1959f7df2e56Smrg#define IS_SHAPED(pWin) (wBoundingShape (pWin) != NULL) 196005b261ecSmrg 196105b261ecSmrgstatic RegionPtr 1962f7df2e56SmrgMakeBoundingRegion(WindowPtr pWin, BoxPtr pBox) 196305b261ecSmrg{ 1964f7df2e56Smrg RegionPtr pRgn = RegionCreate(pBox, 1); 1965f7df2e56Smrg 1966f7df2e56Smrg if (wBoundingShape(pWin)) { 1967f7df2e56Smrg RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); 1968f7df2e56Smrg RegionIntersect(pRgn, pRgn, wBoundingShape(pWin)); 1969f7df2e56Smrg RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); 197005b261ecSmrg } 197105b261ecSmrg return pRgn; 197205b261ecSmrg} 197305b261ecSmrg 197405b261ecSmrgstatic Bool 1975f7df2e56SmrgShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox) 197605b261ecSmrg{ 1977f7df2e56Smrg RegionPtr pWinRgn, pSibRgn; 1978f7df2e56Smrg Bool ret; 197905b261ecSmrg 198005b261ecSmrg if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib)) 1981f7df2e56Smrg return TRUE; 1982f7df2e56Smrg pWinRgn = MakeBoundingRegion(pWin, pWinBox); 1983f7df2e56Smrg pSibRgn = MakeBoundingRegion(pSib, pSibBox); 19844202a189Smrg RegionIntersect(pWinRgn, pWinRgn, pSibRgn); 19854202a189Smrg ret = RegionNotEmpty(pWinRgn); 19864202a189Smrg RegionDestroy(pWinRgn); 19874202a189Smrg RegionDestroy(pSibRgn); 198805b261ecSmrg return ret; 198905b261ecSmrg} 199005b261ecSmrg 199105b261ecSmrgstatic Bool 1992f7df2e56SmrgAnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box) 199305b261ecSmrg{ 199405b261ecSmrg WindowPtr pSib; 199505b261ecSmrg BoxRec sboxrec; 199605b261ecSmrg BoxPtr sbox; 199705b261ecSmrg 1998f7df2e56Smrg for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) { 1999f7df2e56Smrg if (pSib->mapped) { 2000f7df2e56Smrg sbox = WindowExtents(pSib, &sboxrec); 2001f7df2e56Smrg if (BOXES_OVERLAP(sbox, box) 2002f7df2e56Smrg && ShapeOverlap(pWin, box, pSib, sbox)) 2003f7df2e56Smrg return TRUE; 2004f7df2e56Smrg } 200505b261ecSmrg } 20064202a189Smrg return FALSE; 200705b261ecSmrg} 200805b261ecSmrg 200905b261ecSmrgstatic Bool 2010f7df2e56SmrgIOverlapAnyWindow(WindowPtr pWin, BoxPtr box) 201105b261ecSmrg{ 201205b261ecSmrg WindowPtr pSib; 201305b261ecSmrg BoxRec sboxrec; 201405b261ecSmrg BoxPtr sbox; 201505b261ecSmrg 2016f7df2e56Smrg for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) { 2017f7df2e56Smrg if (pSib->mapped) { 2018f7df2e56Smrg sbox = WindowExtents(pSib, &sboxrec); 2019f7df2e56Smrg if (BOXES_OVERLAP(sbox, box) 2020f7df2e56Smrg && ShapeOverlap(pWin, box, pSib, sbox)) 2021f7df2e56Smrg return TRUE; 2022f7df2e56Smrg } 202305b261ecSmrg } 20244202a189Smrg return FALSE; 202505b261ecSmrg} 202605b261ecSmrg 202705b261ecSmrg/* 2028f7df2e56Smrg * WhereDoIGoInTheStack() 202905b261ecSmrg * Given pWin and pSib and the relationshipe smode, return 203005b261ecSmrg * the window that pWin should go ABOVE. 203105b261ecSmrg * If a pSib is specified: 203205b261ecSmrg * Above: pWin is placed just above pSib 203305b261ecSmrg * Below: pWin is placed just below pSib 203405b261ecSmrg * TopIf: if pSib occludes pWin, then pWin is placed 203505b261ecSmrg * at the top of the stack 2036f7df2e56Smrg * BottomIf: if pWin occludes pSib, then pWin is 203705b261ecSmrg * placed at the bottom of the stack 203805b261ecSmrg * Opposite: if pSib occludes pWin, then pWin is placed at the 203905b261ecSmrg * top of the stack, else if pWin occludes pSib, then 204005b261ecSmrg * pWin is placed at the bottom of the stack 204105b261ecSmrg * 204205b261ecSmrg * If pSib is NULL: 204305b261ecSmrg * Above: pWin is placed at the top of the stack 204405b261ecSmrg * Below: pWin is placed at the bottom of the stack 204505b261ecSmrg * TopIf: if any sibling occludes pWin, then pWin is placed at 204605b261ecSmrg * the top of the stack 204705b261ecSmrg * BottomIf: if pWin occludes any sibline, then pWin is placed at 204805b261ecSmrg * the bottom of the stack 204905b261ecSmrg * Opposite: if any sibling occludes pWin, then pWin is placed at 205005b261ecSmrg * the top of the stack, else if pWin occludes any 205105b261ecSmrg * sibling, then pWin is placed at the bottom of the stack 205205b261ecSmrg * 205305b261ecSmrg */ 205405b261ecSmrg 205505b261ecSmrgstatic WindowPtr 2056f7df2e56SmrgWhereDoIGoInTheStack(WindowPtr pWin, 2057f7df2e56Smrg WindowPtr pSib, 2058f7df2e56Smrg short x, 2059f7df2e56Smrg short y, unsigned short w, unsigned short h, int smode) 206005b261ecSmrg{ 206105b261ecSmrg BoxRec box; 206205b261ecSmrg WindowPtr pHead, pFirst; 206305b261ecSmrg 2064f7df2e56Smrg if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild)) 2065f7df2e56Smrg return NULL; 206605b261ecSmrg pHead = RealChildHead(pWin->parent); 206705b261ecSmrg pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; 206805b261ecSmrg box.x1 = x; 206905b261ecSmrg box.y1 = y; 2070f7df2e56Smrg box.x2 = x + (int) w; 2071f7df2e56Smrg box.y2 = y + (int) h; 2072f7df2e56Smrg switch (smode) { 2073f7df2e56Smrg case Above: 2074f7df2e56Smrg if (pSib) 2075f7df2e56Smrg return pSib; 2076f7df2e56Smrg else if (pWin == pFirst) 2077f7df2e56Smrg return pWin->nextSib; 2078f7df2e56Smrg else 2079f7df2e56Smrg return pFirst; 2080f7df2e56Smrg case Below: 2081f7df2e56Smrg if (pSib) 2082f7df2e56Smrg if (pSib->nextSib != pWin) 2083f7df2e56Smrg return pSib->nextSib; 2084f7df2e56Smrg else 2085f7df2e56Smrg return pWin->nextSib; 2086f7df2e56Smrg else 2087f7df2e56Smrg return NullWindow; 2088f7df2e56Smrg case TopIf: 2089f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2090f7df2e56Smrg return pWin->nextSib; 2091f7df2e56Smrg else if (pSib) { 2092f7df2e56Smrg if ((IsSiblingAboveMe(pWin, pSib) == Above) && 2093f7df2e56Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2094f7df2e56Smrg return pFirst; 2095f7df2e56Smrg else 2096f7df2e56Smrg return pWin->nextSib; 2097f7df2e56Smrg } 2098f7df2e56Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) 2099f7df2e56Smrg return pFirst; 2100f7df2e56Smrg else 2101f7df2e56Smrg return pWin->nextSib; 2102f7df2e56Smrg case BottomIf: 2103f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2104f7df2e56Smrg return pWin->nextSib; 2105f7df2e56Smrg else if (pSib) { 2106f7df2e56Smrg if ((IsSiblingAboveMe(pWin, pSib) == Below) && 2107f7df2e56Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2108f7df2e56Smrg return NullWindow; 2109f7df2e56Smrg else 2110f7df2e56Smrg return pWin->nextSib; 2111f7df2e56Smrg } 2112f7df2e56Smrg else if (IOverlapAnyWindow(pWin, &box)) 2113f7df2e56Smrg return NullWindow; 2114f7df2e56Smrg else 2115f7df2e56Smrg return pWin->nextSib; 2116f7df2e56Smrg case Opposite: 2117f7df2e56Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2118f7df2e56Smrg return pWin->nextSib; 2119f7df2e56Smrg else if (pSib) { 2120f7df2e56Smrg if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) { 2121f7df2e56Smrg if (IsSiblingAboveMe(pWin, pSib) == Above) 2122f7df2e56Smrg return pFirst; 2123f7df2e56Smrg else 2124f7df2e56Smrg return NullWindow; 2125f7df2e56Smrg } 2126f7df2e56Smrg else 2127f7df2e56Smrg return pWin->nextSib; 2128f7df2e56Smrg } 2129f7df2e56Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) { 2130f7df2e56Smrg /* If I'm occluded, I can't possibly be the first child 2131f7df2e56Smrg * if (pWin == pWin->parent->firstChild) 2132f7df2e56Smrg * return pWin->nextSib; 2133f7df2e56Smrg */ 2134f7df2e56Smrg return pFirst; 2135f7df2e56Smrg } 2136f7df2e56Smrg else if (IOverlapAnyWindow(pWin, &box)) 2137f7df2e56Smrg return NullWindow; 2138f7df2e56Smrg else 2139f7df2e56Smrg return pWin->nextSib; 2140f7df2e56Smrg default: 214105b261ecSmrg { 2142f7df2e56Smrg /* should never happen; make something up. */ 2143f7df2e56Smrg return pWin->nextSib; 2144f7df2e56Smrg } 214505b261ecSmrg } 214605b261ecSmrg} 214705b261ecSmrg 214805b261ecSmrgstatic void 2149f7df2e56SmrgReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) 215005b261ecSmrg{ 215105b261ecSmrg/* Note that pSib might be NULL */ 215205b261ecSmrg 2153f7df2e56Smrg Bool WasViewable = (Bool) pWin->viewable; 215405b261ecSmrg Bool anyMarked; 215505b261ecSmrg WindowPtr pFirstChange; 2156f7df2e56Smrg WindowPtr pLayerWin; 215705b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 215805b261ecSmrg 215905b261ecSmrg /* if this is a root window, can't be restacked */ 216005b261ecSmrg if (!pWin->parent) 2161f7df2e56Smrg return; 216205b261ecSmrg 216305b261ecSmrg pFirstChange = MoveWindowInStack(pWin, pSib); 216405b261ecSmrg 2165f7df2e56Smrg if (WasViewable) { 2166f7df2e56Smrg anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, 2167f7df2e56Smrg &pLayerWin); 2168f7df2e56Smrg if (pLayerWin != pWin) 2169f7df2e56Smrg pFirstChange = pLayerWin; 2170f7df2e56Smrg if (anyMarked) { 2171f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind); 2172f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2173f7df2e56Smrg if (pWin->drawable.pScreen->PostValidateTree) 2174f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, 2175f7df2e56Smrg kind); 2176f7df2e56Smrg } 217705b261ecSmrg } 217805b261ecSmrg if (pWin->realized) 2179f7df2e56Smrg WindowsRestructured(); 218005b261ecSmrg} 218105b261ecSmrg 218205b261ecSmrg/***** 218305b261ecSmrg * ConfigureWindow 218405b261ecSmrg *****/ 218505b261ecSmrg 218605b261ecSmrgint 218705b261ecSmrgConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) 218805b261ecSmrg{ 218905b261ecSmrg#define RESTACK_WIN 0 219005b261ecSmrg#define MOVE_WIN 1 219105b261ecSmrg#define RESIZE_WIN 2 219205b261ecSmrg#define REBORDER_WIN 3 219305b261ecSmrg WindowPtr pSib = NullWindow; 219405b261ecSmrg WindowPtr pParent = pWin->parent; 219505b261ecSmrg Window sibwid = 0; 219605b261ecSmrg Mask index2, tmask; 219705b261ecSmrg XID *pVlist; 2198f7df2e56Smrg short x, y, beforeX, beforeY; 219905b261ecSmrg unsigned short w = pWin->drawable.width, 2200f7df2e56Smrg h = pWin->drawable.height, bw = pWin->borderWidth; 2201637ac9abSmrg int rc, action, smode = Above; 220205b261ecSmrg 2203f7df2e56Smrg if ((pWin->drawable.class == InputOnly) && (mask & CWBorderWidth)) 2204f7df2e56Smrg return BadMatch; 220505b261ecSmrg 220605b261ecSmrg if ((mask & CWSibling) && !(mask & CWStackMode)) 2207f7df2e56Smrg return BadMatch; 220805b261ecSmrg 220905b261ecSmrg pVlist = vlist; 221005b261ecSmrg 2211f7df2e56Smrg if (pParent) { 2212f7df2e56Smrg x = pWin->drawable.x - pParent->drawable.x - (int) bw; 2213f7df2e56Smrg y = pWin->drawable.y - pParent->drawable.y - (int) bw; 221405b261ecSmrg } 2215f7df2e56Smrg else { 2216f7df2e56Smrg x = pWin->drawable.x; 2217f7df2e56Smrg y = pWin->drawable.y; 221805b261ecSmrg } 221905b261ecSmrg beforeX = x; 222005b261ecSmrg beforeY = y; 2221f7df2e56Smrg action = RESTACK_WIN; 2222f7df2e56Smrg if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) { 2223f7df2e56Smrg GET_INT16(CWX, x); 2224f7df2e56Smrg GET_INT16(CWY, y); 2225f7df2e56Smrg action = MOVE_WIN; 2226f7df2e56Smrg } 2227f7df2e56Smrg /* or should be resized */ 2228f7df2e56Smrg else if (mask & (CWX | CWY | CWWidth | CWHeight)) { 2229f7df2e56Smrg GET_INT16(CWX, x); 2230f7df2e56Smrg GET_INT16(CWY, y); 2231f7df2e56Smrg GET_CARD16(CWWidth, w); 2232f7df2e56Smrg GET_CARD16(CWHeight, h); 2233f7df2e56Smrg if (!w || !h) { 2234f7df2e56Smrg client->errorValue = 0; 2235f7df2e56Smrg return BadValue; 2236f7df2e56Smrg } 2237f7df2e56Smrg action = RESIZE_WIN; 223805b261ecSmrg } 223905b261ecSmrg tmask = mask & ~ChangeMask; 2240f7df2e56Smrg while (tmask) { 2241f7df2e56Smrg index2 = (Mask) lowbit(tmask); 2242f7df2e56Smrg tmask &= ~index2; 2243f7df2e56Smrg switch (index2) { 2244f7df2e56Smrg case CWBorderWidth: 2245f7df2e56Smrg GET_CARD16(CWBorderWidth, bw); 2246f7df2e56Smrg break; 2247f7df2e56Smrg case CWSibling: 2248f7df2e56Smrg sibwid = (Window) *pVlist; 2249f7df2e56Smrg pVlist++; 2250f7df2e56Smrg rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess); 2251f7df2e56Smrg if (rc != Success) { 2252f7df2e56Smrg client->errorValue = sibwid; 2253f7df2e56Smrg return rc; 2254f7df2e56Smrg } 2255f7df2e56Smrg if (pSib->parent != pParent) 2256f7df2e56Smrg return BadMatch; 2257f7df2e56Smrg if (pSib == pWin) 2258f7df2e56Smrg return BadMatch; 2259f7df2e56Smrg break; 2260f7df2e56Smrg case CWStackMode: 2261f7df2e56Smrg GET_CARD8(CWStackMode, smode); 2262f7df2e56Smrg if ((smode != TopIf) && (smode != BottomIf) && 2263f7df2e56Smrg (smode != Opposite) && (smode != Above) && (smode != Below)) { 2264f7df2e56Smrg client->errorValue = smode; 2265f7df2e56Smrg return BadValue; 2266f7df2e56Smrg } 2267f7df2e56Smrg break; 2268f7df2e56Smrg default: 2269f7df2e56Smrg client->errorValue = mask; 2270f7df2e56Smrg return BadValue; 2271f7df2e56Smrg } 2272f7df2e56Smrg } 2273f7df2e56Smrg /* root really can't be reconfigured, so just return */ 227405b261ecSmrg if (!pParent) 2275f7df2e56Smrg return Success; 227605b261ecSmrg 22775a112b11Smrg /* Figure out if the window should be moved. Doesn't 22785a112b11Smrg make the changes to the window if event sent. */ 227905b261ecSmrg 228005b261ecSmrg if (mask & CWStackMode) 2281f7df2e56Smrg pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, 2282f7df2e56Smrg pParent->drawable.y + y, 2283f7df2e56Smrg w + (bw << 1), h + (bw << 1), smode); 228405b261ecSmrg else 2285f7df2e56Smrg pSib = pWin->nextSib; 2286f7df2e56Smrg 2287f7df2e56Smrg if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) { 2288f7df2e56Smrg xEvent event = { 2289f7df2e56Smrg .u.configureRequest.window = pWin->drawable.id, 2290f7df2e56Smrg .u.configureRequest.sibling = (mask & CWSibling) ? sibwid : None, 2291f7df2e56Smrg .u.configureRequest.x = x, 2292f7df2e56Smrg .u.configureRequest.y = y, 2293f7df2e56Smrg .u.configureRequest.width = w, 2294f7df2e56Smrg .u.configureRequest.height = h, 2295f7df2e56Smrg .u.configureRequest.borderWidth = bw, 2296f7df2e56Smrg .u.configureRequest.valueMask = mask, 2297f7df2e56Smrg .u.configureRequest.parent = pParent->drawable.id 2298f7df2e56Smrg }; 2299f7df2e56Smrg event.u.u.type = ConfigureRequest; 2300f7df2e56Smrg event.u.u.detail = (mask & CWStackMode) ? smode : Above; 230105b261ecSmrg#ifdef PANORAMIX 2302f7df2e56Smrg if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { 23034202a189Smrg event.u.configureRequest.x += screenInfo.screens[0]->x; 23044202a189Smrg event.u.configureRequest.y += screenInfo.screens[0]->y; 2305f7df2e56Smrg } 230605b261ecSmrg#endif 2307f7df2e56Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2308f7df2e56Smrg SubstructureRedirectMask, client) == 1) 2309f7df2e56Smrg return Success; 231005b261ecSmrg } 2311f7df2e56Smrg if (action == RESIZE_WIN) { 2312f7df2e56Smrg Bool size_change = (w != pWin->drawable.width) 2313f7df2e56Smrg || (h != pWin->drawable.height); 2314f7df2e56Smrg 2315f7df2e56Smrg if (size_change && 2316f7df2e56Smrg ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) { 2317f7df2e56Smrg xEvent eventT = { 2318f7df2e56Smrg .u.resizeRequest.window = pWin->drawable.id, 2319f7df2e56Smrg .u.resizeRequest.width = w, 2320f7df2e56Smrg .u.resizeRequest.height = h 2321f7df2e56Smrg }; 2322f7df2e56Smrg eventT.u.u.type = ResizeRequest; 2323f7df2e56Smrg if (MaybeDeliverEventsToClient(pWin, &eventT, 1, 2324f7df2e56Smrg ResizeRedirectMask, client) == 1) { 2325f7df2e56Smrg /* if event is delivered, leave the actual size alone. */ 2326f7df2e56Smrg w = pWin->drawable.width; 2327f7df2e56Smrg h = pWin->drawable.height; 2328f7df2e56Smrg size_change = FALSE; 2329f7df2e56Smrg } 2330f7df2e56Smrg } 2331f7df2e56Smrg if (!size_change) { 2332f7df2e56Smrg if (mask & (CWX | CWY)) 2333f7df2e56Smrg action = MOVE_WIN; 2334f7df2e56Smrg else if (mask & (CWStackMode | CWBorderWidth)) 2335f7df2e56Smrg action = RESTACK_WIN; 2336f7df2e56Smrg else /* really nothing to do */ 2337f7df2e56Smrg return (Success); 2338f7df2e56Smrg } 233905b261ecSmrg } 234005b261ecSmrg 234105b261ecSmrg if (action == RESIZE_WIN) 2342f7df2e56Smrg /* we've already checked whether there's really a size change */ 2343f7df2e56Smrg goto ActuallyDoSomething; 234405b261ecSmrg if ((mask & CWX) && (x != beforeX)) 2345f7df2e56Smrg goto ActuallyDoSomething; 234605b261ecSmrg if ((mask & CWY) && (y != beforeY)) 2347f7df2e56Smrg goto ActuallyDoSomething; 2348f7df2e56Smrg if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin))) 2349f7df2e56Smrg goto ActuallyDoSomething; 2350f7df2e56Smrg if (mask & CWStackMode) { 235105b261ecSmrg#ifndef ROOTLESS 235205b261ecSmrg /* See above for why we always reorder in rootless mode. */ 2353f7df2e56Smrg if (pWin->nextSib != pSib) 235405b261ecSmrg#endif 2355f7df2e56Smrg goto ActuallyDoSomething; 235605b261ecSmrg } 23574202a189Smrg return Success; 235805b261ecSmrg 2359f7df2e56Smrg ActuallyDoSomething: 2360f7df2e56Smrg if (pWin->drawable.pScreen->ConfigNotify) { 2361f7df2e56Smrg int ret; 2362f7df2e56Smrg 2363f7df2e56Smrg ret = 2364f7df2e56Smrg (*pWin->drawable.pScreen->ConfigNotify) (pWin, x, y, w, h, bw, 2365f7df2e56Smrg pSib); 2366f7df2e56Smrg if (ret) { 2367f7df2e56Smrg client->errorValue = 0; 2368f7df2e56Smrg return ret; 2369f7df2e56Smrg } 23704202a189Smrg } 23714202a189Smrg 2372f7df2e56Smrg if (SubStrSend(pWin, pParent)) { 2373f7df2e56Smrg xEvent event = { 2374f7df2e56Smrg .u.configureNotify.window = pWin->drawable.id, 2375f7df2e56Smrg .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None, 2376f7df2e56Smrg .u.configureNotify.x = x, 2377f7df2e56Smrg .u.configureNotify.y = y, 2378f7df2e56Smrg .u.configureNotify.width = w, 2379f7df2e56Smrg .u.configureNotify.height = h, 2380f7df2e56Smrg .u.configureNotify.borderWidth = bw, 2381f7df2e56Smrg .u.configureNotify.override = pWin->overrideRedirect 2382f7df2e56Smrg }; 2383f7df2e56Smrg event.u.u.type = ConfigureNotify; 238405b261ecSmrg#ifdef PANORAMIX 2385f7df2e56Smrg if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { 2386f7df2e56Smrg event.u.configureNotify.x += screenInfo.screens[0]->x; 2387f7df2e56Smrg event.u.configureNotify.y += screenInfo.screens[0]->y; 2388f7df2e56Smrg } 238905b261ecSmrg#endif 2390f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 239105b261ecSmrg } 2392f7df2e56Smrg if (mask & CWBorderWidth) { 2393f7df2e56Smrg if (action == RESTACK_WIN) { 2394f7df2e56Smrg action = MOVE_WIN; 2395f7df2e56Smrg pWin->borderWidth = bw; 2396f7df2e56Smrg } 2397f7df2e56Smrg else if ((action == MOVE_WIN) && 2398f7df2e56Smrg (beforeX + wBorderWidth(pWin) == x + (int) bw) && 2399f7df2e56Smrg (beforeY + wBorderWidth(pWin) == y + (int) bw)) { 2400f7df2e56Smrg action = REBORDER_WIN; 2401f7df2e56Smrg (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw); 2402f7df2e56Smrg } 2403f7df2e56Smrg else 2404f7df2e56Smrg pWin->borderWidth = bw; 240505b261ecSmrg } 240605b261ecSmrg if (action == MOVE_WIN) 2407f7df2e56Smrg (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib, 2408f7df2e56Smrg (mask & CWBorderWidth) ? VTOther 2409f7df2e56Smrg : VTMove); 241005b261ecSmrg else if (action == RESIZE_WIN) 2411f7df2e56Smrg (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); 241205b261ecSmrg else if (mask & CWStackMode) 2413f7df2e56Smrg ReflectStackChange(pWin, pSib, VTOther); 241405b261ecSmrg 241505b261ecSmrg if (action != RESTACK_WIN) 2416f7df2e56Smrg CheckCursorConfinement(pWin); 24174202a189Smrg return Success; 241805b261ecSmrg#undef RESTACK_WIN 241905b261ecSmrg#undef MOVE_WIN 242005b261ecSmrg#undef RESIZE_WIN 242105b261ecSmrg#undef REBORDER_WIN 242205b261ecSmrg} 242305b261ecSmrg 242405b261ecSmrg/****** 242505b261ecSmrg * 242605b261ecSmrg * CirculateWindow 242705b261ecSmrg * For RaiseLowest, raises the lowest mapped child (if any) that is 242805b261ecSmrg * obscured by another child to the top of the stack. For LowerHighest, 242905b261ecSmrg * lowers the highest mapped child (if any) that is obscuring another 2430f7df2e56Smrg * child to the bottom of the stack. Exposure processing is performed 243105b261ecSmrg * 243205b261ecSmrg ******/ 243305b261ecSmrg 243405b261ecSmrgint 243505b261ecSmrgCirculateWindow(WindowPtr pParent, int direction, ClientPtr client) 243605b261ecSmrg{ 243705b261ecSmrg WindowPtr pWin, pHead, pFirst; 243805b261ecSmrg xEvent event; 243905b261ecSmrg BoxRec box; 244005b261ecSmrg 244105b261ecSmrg pHead = RealChildHead(pParent); 244205b261ecSmrg pFirst = pHead ? pHead->nextSib : pParent->firstChild; 2443f7df2e56Smrg if (direction == RaiseLowest) { 2444f7df2e56Smrg for (pWin = pParent->lastChild; 2445f7df2e56Smrg (pWin != pHead) && 2446f7df2e56Smrg !(pWin->mapped && 2447f7df2e56Smrg AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); 2448f7df2e56Smrg pWin = pWin->prevSib); 2449f7df2e56Smrg if (pWin == pHead) 2450f7df2e56Smrg return Success; 2451f7df2e56Smrg } 2452f7df2e56Smrg else { 2453f7df2e56Smrg for (pWin = pFirst; 2454f7df2e56Smrg pWin && 2455f7df2e56Smrg !(pWin->mapped && 2456f7df2e56Smrg IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); 2457f7df2e56Smrg pWin = pWin->nextSib); 2458f7df2e56Smrg if (!pWin) 2459f7df2e56Smrg return Success; 246005b261ecSmrg } 246105b261ecSmrg 2462f7df2e56Smrg event = (xEvent) { 2463f7df2e56Smrg .u.circulate.window = pWin->drawable.id, 2464f7df2e56Smrg .u.circulate.parent = pParent->drawable.id, 2465f7df2e56Smrg .u.circulate.event = pParent->drawable.id, 2466f7df2e56Smrg .u.circulate.place = (direction == RaiseLowest) ? 2467f7df2e56Smrg PlaceOnTop : PlaceOnBottom, 2468f7df2e56Smrg }; 2469f7df2e56Smrg 2470f7df2e56Smrg if (RedirectSend(pParent)) { 2471f7df2e56Smrg event.u.u.type = CirculateRequest; 2472f7df2e56Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2473f7df2e56Smrg SubstructureRedirectMask, client) == 1) 2474f7df2e56Smrg return Success; 247505b261ecSmrg } 247605b261ecSmrg 247705b261ecSmrg event.u.u.type = CirculateNotify; 247805b261ecSmrg DeliverEvents(pWin, &event, 1, NullWindow); 247905b261ecSmrg ReflectStackChange(pWin, 2480f7df2e56Smrg (direction == RaiseLowest) ? pFirst : NullWindow, 2481f7df2e56Smrg VTStack); 248205b261ecSmrg 24834202a189Smrg return Success; 248405b261ecSmrg} 248505b261ecSmrg 248605b261ecSmrgstatic int 2487f7df2e56SmrgCompareWIDs(WindowPtr pWin, void *value) 2488f7df2e56Smrg{ /* must conform to VisitWindowProcPtr */ 2489f7df2e56Smrg Window *wid = (Window *) value; 249005b261ecSmrg 249105b261ecSmrg if (pWin->drawable.id == *wid) 2492f7df2e56Smrg return WT_STOPWALKING; 249305b261ecSmrg else 2494f7df2e56Smrg return WT_WALKCHILDREN; 249505b261ecSmrg} 249605b261ecSmrg 249705b261ecSmrg/***** 249805b261ecSmrg * ReparentWindow 249905b261ecSmrg *****/ 250005b261ecSmrg 250105b261ecSmrgint 250205b261ecSmrgReparentWindow(WindowPtr pWin, WindowPtr pParent, 250305b261ecSmrg int x, int y, ClientPtr client) 250405b261ecSmrg{ 250505b261ecSmrg WindowPtr pPrev, pPriorParent; 2506f7df2e56Smrg Bool WasMapped = (Bool) (pWin->mapped); 250705b261ecSmrg xEvent event; 2508f7df2e56Smrg int bw = wBorderWidth(pWin); 250905b261ecSmrg ScreenPtr pScreen; 251005b261ecSmrg 251105b261ecSmrg pScreen = pWin->drawable.pScreen; 2512f7df2e56Smrg if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) == 2513f7df2e56Smrg WT_STOPWALKING) 2514f7df2e56Smrg return BadMatch; 251505b261ecSmrg if (!MakeWindowOptional(pWin)) 2516f7df2e56Smrg return BadAlloc; 251705b261ecSmrg 251805b261ecSmrg if (WasMapped) 2519f7df2e56Smrg UnmapWindow(pWin, FALSE); 2520f7df2e56Smrg 2521f7df2e56Smrg event = (xEvent) { 2522f7df2e56Smrg .u.reparent.window = pWin->drawable.id, 2523f7df2e56Smrg .u.reparent.parent = pParent->drawable.id, 2524f7df2e56Smrg .u.reparent.x = x, 2525f7df2e56Smrg .u.reparent.y = y, 2526f7df2e56Smrg .u.reparent.override = pWin->overrideRedirect 2527f7df2e56Smrg }; 252805b261ecSmrg event.u.u.type = ReparentNotify; 252905b261ecSmrg#ifdef PANORAMIX 2530f7df2e56Smrg if (!noPanoramiXExtension && !pParent->parent) { 2531f7df2e56Smrg event.u.reparent.x += screenInfo.screens[0]->x; 2532f7df2e56Smrg event.u.reparent.y += screenInfo.screens[0]->y; 253305b261ecSmrg } 253405b261ecSmrg#endif 253505b261ecSmrg DeliverEvents(pWin, &event, 1, pParent); 253605b261ecSmrg 253705b261ecSmrg /* take out of sibling chain */ 253805b261ecSmrg 253905b261ecSmrg pPriorParent = pPrev = pWin->parent; 254005b261ecSmrg if (pPrev->firstChild == pWin) 2541f7df2e56Smrg pPrev->firstChild = pWin->nextSib; 254205b261ecSmrg if (pPrev->lastChild == pWin) 2543f7df2e56Smrg pPrev->lastChild = pWin->prevSib; 254405b261ecSmrg 254505b261ecSmrg if (pWin->nextSib) 2546f7df2e56Smrg pWin->nextSib->prevSib = pWin->prevSib; 254705b261ecSmrg if (pWin->prevSib) 2548f7df2e56Smrg pWin->prevSib->nextSib = pWin->nextSib; 254905b261ecSmrg 25505a112b11Smrg /* insert at beginning of pParent */ 255105b261ecSmrg pWin->parent = pParent; 255205b261ecSmrg pPrev = RealChildHead(pParent); 2553f7df2e56Smrg if (pPrev) { 2554f7df2e56Smrg pWin->nextSib = pPrev->nextSib; 2555f7df2e56Smrg if (pPrev->nextSib) 2556f7df2e56Smrg pPrev->nextSib->prevSib = pWin; 2557f7df2e56Smrg else 2558f7df2e56Smrg pParent->lastChild = pWin; 2559f7df2e56Smrg pPrev->nextSib = pWin; 2560f7df2e56Smrg pWin->prevSib = pPrev; 256105b261ecSmrg } 2562f7df2e56Smrg else { 2563f7df2e56Smrg pWin->nextSib = pParent->firstChild; 2564f7df2e56Smrg pWin->prevSib = NullWindow; 2565f7df2e56Smrg if (pParent->firstChild) 2566f7df2e56Smrg pParent->firstChild->prevSib = pWin; 2567f7df2e56Smrg else 2568f7df2e56Smrg pParent->lastChild = pWin; 2569f7df2e56Smrg pParent->firstChild = pWin; 257005b261ecSmrg } 257105b261ecSmrg 257205b261ecSmrg pWin->origin.x = x + bw; 257305b261ecSmrg pWin->origin.y = y + bw; 257405b261ecSmrg pWin->drawable.x = x + bw + pParent->drawable.x; 257505b261ecSmrg pWin->drawable.y = y + bw + pParent->drawable.y; 257605b261ecSmrg 257705b261ecSmrg /* clip to parent */ 2578f7df2e56Smrg SetWinSize(pWin); 2579f7df2e56Smrg SetBorderSize(pWin); 258005b261ecSmrg 258105b261ecSmrg if (pScreen->ReparentWindow) 2582f7df2e56Smrg (*pScreen->ReparentWindow) (pWin, pPriorParent); 2583f7df2e56Smrg (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); 258405b261ecSmrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 258505b261ecSmrg 258605b261ecSmrg CheckWindowOptionalNeed(pWin); 258705b261ecSmrg 258805b261ecSmrg if (WasMapped) 2589f7df2e56Smrg MapWindow(pWin, client); 259005b261ecSmrg RecalculateDeliverableEvents(pWin); 25914202a189Smrg return Success; 259205b261ecSmrg} 259305b261ecSmrg 259405b261ecSmrgstatic void 259505b261ecSmrgRealizeTree(WindowPtr pWin) 259605b261ecSmrg{ 259705b261ecSmrg WindowPtr pChild; 259805b261ecSmrg RealizeWindowProcPtr Realize; 259905b261ecSmrg 260005b261ecSmrg Realize = pWin->drawable.pScreen->RealizeWindow; 260105b261ecSmrg pChild = pWin; 2602f7df2e56Smrg while (1) { 2603f7df2e56Smrg if (pChild->mapped) { 2604f7df2e56Smrg pChild->realized = TRUE; 2605f7df2e56Smrg pChild->viewable = (pChild->drawable.class == InputOutput); 2606f7df2e56Smrg (*Realize) (pChild); 2607f7df2e56Smrg if (pChild->firstChild) { 2608f7df2e56Smrg pChild = pChild->firstChild; 2609f7df2e56Smrg continue; 2610f7df2e56Smrg } 2611f7df2e56Smrg } 2612f7df2e56Smrg while (!pChild->nextSib && (pChild != pWin)) 2613f7df2e56Smrg pChild = pChild->parent; 2614f7df2e56Smrg if (pChild == pWin) 2615f7df2e56Smrg return; 2616f7df2e56Smrg pChild = pChild->nextSib; 2617f7df2e56Smrg } 261805b261ecSmrg} 261905b261ecSmrg 2620f7df2e56Smrgstatic Bool 2621f7df2e56SmrgMaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client) 262205b261ecSmrg{ 2623f7df2e56Smrg xEvent event = { 2624f7df2e56Smrg .u.mapRequest.window = pWin->drawable.id, 2625f7df2e56Smrg .u.mapRequest.parent = pParent->drawable.id 2626f7df2e56Smrg }; 2627f7df2e56Smrg event.u.u.type = MapRequest; 2628f7df2e56Smrg 2629f7df2e56Smrg return MaybeDeliverEventsToClient(pParent, &event, 1, 2630f7df2e56Smrg SubstructureRedirectMask, 2631f7df2e56Smrg client) == 1; 263205b261ecSmrg} 263305b261ecSmrg 2634f7df2e56Smrgstatic void 2635f7df2e56SmrgDeliverMapNotify(WindowPtr pWin) 263605b261ecSmrg{ 2637f7df2e56Smrg xEvent event = { 2638f7df2e56Smrg .u.mapNotify.window = pWin->drawable.id, 2639f7df2e56Smrg .u.mapNotify.override = pWin->overrideRedirect, 2640f7df2e56Smrg }; 2641f7df2e56Smrg event.u.u.type = MapNotify; 2642f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 264305b261ecSmrg} 264405b261ecSmrg 264505b261ecSmrg/***** 264605b261ecSmrg * MapWindow 264705b261ecSmrg * If some other client has selected SubStructureReDirect on the parent 264805b261ecSmrg * and override-redirect is xFalse, then a MapRequest event is generated, 264905b261ecSmrg * but the window remains unmapped. Otherwise, the window is mapped and a 265005b261ecSmrg * MapNotify event is generated. 265105b261ecSmrg *****/ 265205b261ecSmrg 26534202a189Smrgint 265405b261ecSmrgMapWindow(WindowPtr pWin, ClientPtr client) 265505b261ecSmrg{ 265605b261ecSmrg ScreenPtr pScreen; 265705b261ecSmrg 265805b261ecSmrg WindowPtr pParent; 2659f7df2e56Smrg WindowPtr pLayerWin; 266005b261ecSmrg 266105b261ecSmrg if (pWin->mapped) 2662f7df2e56Smrg return Success; 266305b261ecSmrg 2664f7df2e56Smrg /* general check for permission to map window */ 2665637ac9abSmrg if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, 2666f7df2e56Smrg pWin, RT_NONE, NULL, DixShowAccess) != Success) 2667f7df2e56Smrg return Success; 266805b261ecSmrg 266905b261ecSmrg pScreen = pWin->drawable.pScreen; 2670f7df2e56Smrg if ((pParent = pWin->parent)) { 2671f7df2e56Smrg Bool anyMarked; 2672f7df2e56Smrg 2673f7df2e56Smrg if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) 2674f7df2e56Smrg if (MaybeDeliverMapRequest(pWin, pParent, client)) 2675f7df2e56Smrg return Success; 2676f7df2e56Smrg 2677f7df2e56Smrg pWin->mapped = TRUE; 2678f7df2e56Smrg if (SubStrSend(pWin, pParent)) 2679f7df2e56Smrg DeliverMapNotify(pWin); 2680f7df2e56Smrg 2681f7df2e56Smrg if (!pParent->realized) 2682f7df2e56Smrg return Success; 2683f7df2e56Smrg RealizeTree(pWin); 2684f7df2e56Smrg if (pWin->viewable) { 2685f7df2e56Smrg anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, 2686f7df2e56Smrg &pLayerWin); 2687f7df2e56Smrg if (anyMarked) { 2688f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap); 2689f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2690f7df2e56Smrg if (pScreen->PostValidateTree) 2691f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, 2692f7df2e56Smrg VTMap); 2693f7df2e56Smrg } 2694f7df2e56Smrg } 2695f7df2e56Smrg WindowsRestructured(); 269605b261ecSmrg } 2697f7df2e56Smrg else { 2698f7df2e56Smrg RegionRec temp; 2699f7df2e56Smrg 2700f7df2e56Smrg pWin->mapped = TRUE; 2701f7df2e56Smrg pWin->realized = TRUE; /* for roots */ 2702f7df2e56Smrg pWin->viewable = pWin->drawable.class == InputOutput; 2703f7df2e56Smrg /* We SHOULD check for an error value here XXX */ 2704f7df2e56Smrg (*pScreen->RealizeWindow) (pWin); 2705f7df2e56Smrg if (pScreen->ClipNotify) 2706f7df2e56Smrg (*pScreen->ClipNotify) (pWin, 0, 0); 2707f7df2e56Smrg if (pScreen->PostValidateTree) 2708f7df2e56Smrg (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap); 2709f7df2e56Smrg RegionNull(&temp); 2710f7df2e56Smrg RegionCopy(&temp, &pWin->clipList); 2711f7df2e56Smrg (*pScreen->WindowExposures) (pWin, &temp); 2712f7df2e56Smrg RegionUninit(&temp); 271305b261ecSmrg } 271405b261ecSmrg 27154202a189Smrg return Success; 271605b261ecSmrg} 271705b261ecSmrg 271805b261ecSmrg/***** 271905b261ecSmrg * MapSubwindows 272005b261ecSmrg * Performs a MapWindow all unmapped children of the window, in top 272105b261ecSmrg * to bottom stacking order. 272205b261ecSmrg *****/ 272305b261ecSmrg 272405b261ecSmrgvoid 272505b261ecSmrgMapSubwindows(WindowPtr pParent, ClientPtr client) 272605b261ecSmrg{ 2727f7df2e56Smrg WindowPtr pWin; 2728f7df2e56Smrg WindowPtr pFirstMapped = NullWindow; 2729f7df2e56Smrg ScreenPtr pScreen; 2730f7df2e56Smrg Mask parentRedirect; 2731f7df2e56Smrg Mask parentNotify; 2732f7df2e56Smrg Bool anyMarked; 2733f7df2e56Smrg WindowPtr pLayerWin; 273405b261ecSmrg 273505b261ecSmrg pScreen = pParent->drawable.pScreen; 273605b261ecSmrg parentRedirect = RedirectSend(pParent); 273705b261ecSmrg parentNotify = SubSend(pParent); 273805b261ecSmrg anyMarked = FALSE; 2739f7df2e56Smrg for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) { 2740f7df2e56Smrg if (!pWin->mapped) { 2741f7df2e56Smrg if (parentRedirect && !pWin->overrideRedirect) 2742f7df2e56Smrg if (MaybeDeliverMapRequest(pWin, pParent, client)) 2743f7df2e56Smrg continue; 2744f7df2e56Smrg 2745f7df2e56Smrg pWin->mapped = TRUE; 2746f7df2e56Smrg if (parentNotify || StrSend(pWin)) 2747f7df2e56Smrg DeliverMapNotify(pWin); 2748f7df2e56Smrg 2749f7df2e56Smrg if (!pFirstMapped) 2750f7df2e56Smrg pFirstMapped = pWin; 2751f7df2e56Smrg if (pParent->realized) { 2752f7df2e56Smrg RealizeTree(pWin); 2753f7df2e56Smrg if (pWin->viewable) { 2754f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, 2755f7df2e56Smrg NULL); 2756f7df2e56Smrg } 2757f7df2e56Smrg } 2758f7df2e56Smrg } 2759f7df2e56Smrg } 2760f7df2e56Smrg 2761f7df2e56Smrg if (pFirstMapped) { 2762f7df2e56Smrg pLayerWin = (*pScreen->GetLayerWindow) (pParent); 2763f7df2e56Smrg if (pLayerWin->parent != pParent) { 2764f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin, 2765f7df2e56Smrg pLayerWin, NULL); 2766f7df2e56Smrg pFirstMapped = pLayerWin; 2767f7df2e56Smrg } 2768f7df2e56Smrg if (anyMarked) { 2769f7df2e56Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap); 2770f7df2e56Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 2771f7df2e56Smrg if (pScreen->PostValidateTree) 2772f7df2e56Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped, 2773f7df2e56Smrg VTMap); 2774f7df2e56Smrg } 2775f7df2e56Smrg WindowsRestructured(); 277605b261ecSmrg } 277705b261ecSmrg} 277805b261ecSmrg 277905b261ecSmrgstatic void 2780f7df2e56SmrgUnrealizeTree(WindowPtr pWin, Bool fromConfigure) 278105b261ecSmrg{ 278205b261ecSmrg WindowPtr pChild; 278305b261ecSmrg UnrealizeWindowProcPtr Unrealize; 278405b261ecSmrg MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; 278505b261ecSmrg 278605b261ecSmrg Unrealize = pWin->drawable.pScreen->UnrealizeWindow; 278705b261ecSmrg MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; 278805b261ecSmrg pChild = pWin; 2789f7df2e56Smrg while (1) { 2790f7df2e56Smrg if (pChild->realized) { 2791f7df2e56Smrg pChild->realized = FALSE; 2792f7df2e56Smrg pChild->visibility = VisibilityNotViewable; 279305b261ecSmrg#ifdef PANORAMIX 2794f7df2e56Smrg if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { 2795f7df2e56Smrg PanoramiXRes *win; 2796f7df2e56Smrg int rc = dixLookupResourceByType((void **) &win, 2797f7df2e56Smrg pChild->drawable.id, 2798f7df2e56Smrg XRT_WINDOW, 2799f7df2e56Smrg serverClient, DixWriteAccess); 2800f7df2e56Smrg 2801f7df2e56Smrg if (rc == Success) 2802f7df2e56Smrg win->u.win.visibility = VisibilityNotViewable; 2803f7df2e56Smrg } 280405b261ecSmrg#endif 2805f7df2e56Smrg (*Unrealize) (pChild); 2806f7df2e56Smrg DeleteWindowFromAnyEvents(pChild, FALSE); 2807f7df2e56Smrg if (pChild->viewable) { 2808f7df2e56Smrg pChild->viewable = FALSE; 2809f7df2e56Smrg (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); 2810f7df2e56Smrg pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; 2811f7df2e56Smrg } 2812f7df2e56Smrg if (pChild->firstChild) { 2813f7df2e56Smrg pChild = pChild->firstChild; 2814f7df2e56Smrg continue; 2815f7df2e56Smrg } 2816f7df2e56Smrg } 2817f7df2e56Smrg while (!pChild->nextSib && (pChild != pWin)) 2818f7df2e56Smrg pChild = pChild->parent; 2819f7df2e56Smrg if (pChild == pWin) 2820f7df2e56Smrg return; 2821f7df2e56Smrg pChild = pChild->nextSib; 282205b261ecSmrg } 282305b261ecSmrg} 282405b261ecSmrg 2825f7df2e56Smrgstatic void 2826f7df2e56SmrgDeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure) 2827f7df2e56Smrg{ 2828f7df2e56Smrg xEvent event = { 2829f7df2e56Smrg .u.unmapNotify.window = pWin->drawable.id, 2830f7df2e56Smrg .u.unmapNotify.fromConfigure = fromConfigure 2831f7df2e56Smrg }; 2832f7df2e56Smrg event.u.u.type = UnmapNotify; 2833f7df2e56Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2834f7df2e56Smrg} 2835f7df2e56Smrg 283605b261ecSmrg/***** 283705b261ecSmrg * UnmapWindow 283805b261ecSmrg * If the window is already unmapped, this request has no effect. 283905b261ecSmrg * Otherwise, the window is unmapped and an UnMapNotify event is 284005b261ecSmrg * generated. Cannot unmap a root window. 284105b261ecSmrg *****/ 284205b261ecSmrg 28434202a189Smrgint 284405b261ecSmrgUnmapWindow(WindowPtr pWin, Bool fromConfigure) 284505b261ecSmrg{ 284605b261ecSmrg WindowPtr pParent; 2847f7df2e56Smrg Bool wasRealized = (Bool) pWin->realized; 2848f7df2e56Smrg Bool wasViewable = (Bool) pWin->viewable; 284905b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 285005b261ecSmrg WindowPtr pLayerWin = pWin; 285105b261ecSmrg 285205b261ecSmrg if ((!pWin->mapped) || (!(pParent = pWin->parent))) 2853f7df2e56Smrg return Success; 2854f7df2e56Smrg if (SubStrSend(pWin, pParent)) 2855f7df2e56Smrg DeliverUnmapNotify(pWin, fromConfigure); 2856f7df2e56Smrg if (wasViewable && !fromConfigure) { 2857f7df2e56Smrg pWin->valdata = UnmapValData; 2858f7df2e56Smrg (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); 2859f7df2e56Smrg (*pScreen->MarkWindow) (pLayerWin->parent); 286005b261ecSmrg } 286105b261ecSmrg pWin->mapped = FALSE; 286205b261ecSmrg if (wasRealized) 2863f7df2e56Smrg UnrealizeTree(pWin, fromConfigure); 28645a112b11Smrg if (wasViewable && !fromConfigure) { 28655a112b11Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); 28665a112b11Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 28675a112b11Smrg if (pScreen->PostValidateTree) 28685a112b11Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); 2869f7df2e56Smrg } 2870f7df2e56Smrg if (wasRealized && !fromConfigure) { 2871f7df2e56Smrg WindowsRestructured(); 2872f7df2e56Smrg WindowGone(pWin); 2873f7df2e56Smrg } 28744202a189Smrg return Success; 287505b261ecSmrg} 287605b261ecSmrg 287705b261ecSmrg/***** 287805b261ecSmrg * UnmapSubwindows 287905b261ecSmrg * Performs an UnmapWindow request with the specified mode on all mapped 288005b261ecSmrg * children of the window, in bottom to top stacking order. 288105b261ecSmrg *****/ 288205b261ecSmrg 288305b261ecSmrgvoid 288405b261ecSmrgUnmapSubwindows(WindowPtr pWin) 288505b261ecSmrg{ 288605b261ecSmrg WindowPtr pChild, pHead; 2887f7df2e56Smrg Bool wasRealized = (Bool) pWin->realized; 2888f7df2e56Smrg Bool wasViewable = (Bool) pWin->viewable; 288905b261ecSmrg Bool anyMarked = FALSE; 289005b261ecSmrg Mask parentNotify; 289105b261ecSmrg WindowPtr pLayerWin = NULL; 289205b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 289305b261ecSmrg 289405b261ecSmrg if (!pWin->firstChild) 2895f7df2e56Smrg return; 289605b261ecSmrg parentNotify = SubSend(pWin); 289705b261ecSmrg pHead = RealChildHead(pWin); 289805b261ecSmrg 289905b261ecSmrg if (wasViewable) 2900f7df2e56Smrg pLayerWin = (*pScreen->GetLayerWindow) (pWin); 2901f7df2e56Smrg 2902f7df2e56Smrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { 2903f7df2e56Smrg if (pChild->mapped) { 2904f7df2e56Smrg if (parentNotify || StrSend(pChild)) 2905f7df2e56Smrg DeliverUnmapNotify(pChild, xFalse); 2906f7df2e56Smrg if (pChild->viewable) { 2907f7df2e56Smrg pChild->valdata = UnmapValData; 2908f7df2e56Smrg anyMarked = TRUE; 2909f7df2e56Smrg } 2910f7df2e56Smrg pChild->mapped = FALSE; 2911f7df2e56Smrg if (pChild->realized) 2912f7df2e56Smrg UnrealizeTree(pChild, FALSE); 2913f7df2e56Smrg } 291405b261ecSmrg } 29155a112b11Smrg if (wasViewable && anyMarked) { 29165a112b11Smrg if (pLayerWin->parent == pWin) 29175a112b11Smrg (*pScreen->MarkWindow) (pWin); 29185a112b11Smrg else { 29195a112b11Smrg WindowPtr ptmp; 2920f7df2e56Smrg 29215a112b11Smrg (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); 29225a112b11Smrg (*pScreen->MarkWindow) (pLayerWin->parent); 2923f7df2e56Smrg 29245a112b11Smrg /* Windows between pWin and pLayerWin may not have been marked */ 29255a112b11Smrg ptmp = pWin; 2926f7df2e56Smrg 29275a112b11Smrg while (ptmp != pLayerWin->parent) { 29285a112b11Smrg (*pScreen->MarkWindow) (ptmp); 29295a112b11Smrg ptmp = ptmp->parent; 2930f7df2e56Smrg } 29315a112b11Smrg pHead = pWin->firstChild; 2932f7df2e56Smrg } 29335a112b11Smrg (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); 29345a112b11Smrg (*pScreen->HandleExposures) (pLayerWin->parent); 29355a112b11Smrg if (pScreen->PostValidateTree) 29365a112b11Smrg (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, VTUnmap); 2937f7df2e56Smrg } 2938f7df2e56Smrg if (wasRealized) { 2939f7df2e56Smrg WindowsRestructured(); 2940f7df2e56Smrg WindowGone(pWin); 294105b261ecSmrg } 294205b261ecSmrg} 294305b261ecSmrg 294405b261ecSmrgvoid 294505b261ecSmrgHandleSaveSet(ClientPtr client) 294605b261ecSmrg{ 294705b261ecSmrg WindowPtr pParent, pWin; 294805b261ecSmrg int j; 294905b261ecSmrg 2950f7df2e56Smrg for (j = 0; j < client->numSaved; j++) { 2951f7df2e56Smrg pWin = SaveSetWindow(client->saveSet[j]); 2952f7df2e56Smrg if (SaveSetToRoot(client->saveSet[j])) 2953f7df2e56Smrg pParent = pWin->drawable.pScreen->root; 2954f7df2e56Smrg else 2955f7df2e56Smrg { 2956f7df2e56Smrg pParent = pWin->parent; 2957f7df2e56Smrg while (pParent && (wClient(pParent) == client)) 2958f7df2e56Smrg pParent = pParent->parent; 2959f7df2e56Smrg } 2960f7df2e56Smrg if (pParent) { 2961f7df2e56Smrg if (pParent != pWin->parent) { 2962f7df2e56Smrg /* unmap first so that ReparentWindow doesn't remap */ 2963f7df2e56Smrg if (!SaveSetShouldMap(client->saveSet[j])) 2964f7df2e56Smrg UnmapWindow(pWin, FALSE); 2965f7df2e56Smrg ReparentWindow(pWin, pParent, 2966f7df2e56Smrg pWin->drawable.x - wBorderWidth(pWin) - 2967f7df2e56Smrg pParent->drawable.x, 2968f7df2e56Smrg pWin->drawable.y - wBorderWidth(pWin) - 2969f7df2e56Smrg pParent->drawable.y, client); 2970f7df2e56Smrg if (!pWin->realized && pWin->mapped) 2971f7df2e56Smrg pWin->mapped = FALSE; 2972f7df2e56Smrg } 2973f7df2e56Smrg if (SaveSetShouldMap(client->saveSet[j])) 2974f7df2e56Smrg MapWindow(pWin, client); 2975f7df2e56Smrg } 297605b261ecSmrg } 29774202a189Smrg free(client->saveSet); 297805b261ecSmrg client->numSaved = 0; 2979f7df2e56Smrg client->saveSet = NULL; 298005b261ecSmrg} 298105b261ecSmrg 298205b261ecSmrg/** 298305b261ecSmrg * 298405b261ecSmrg * \param x,y in root 298505b261ecSmrg */ 298605b261ecSmrgBool 298705b261ecSmrgPointInWindowIsVisible(WindowPtr pWin, int x, int y) 298805b261ecSmrg{ 298905b261ecSmrg BoxRec box; 299005b261ecSmrg 299105b261ecSmrg if (!pWin->realized) 2992f7df2e56Smrg return FALSE; 2993f7df2e56Smrg if (RegionContainsPoint(&pWin->borderClip, x, y, &box) 2994f7df2e56Smrg && (!wInputShape(pWin) || 2995f7df2e56Smrg RegionContainsPoint(wInputShape(pWin), 2996f7df2e56Smrg x - pWin->drawable.x, 2997f7df2e56Smrg y - pWin->drawable.y, &box))) 2998f7df2e56Smrg return TRUE; 29994202a189Smrg return FALSE; 300005b261ecSmrg} 300105b261ecSmrg 30024202a189SmrgRegionPtr 300305b261ecSmrgNotClippedByChildren(WindowPtr pWin) 300405b261ecSmrg{ 30054202a189Smrg RegionPtr pReg = RegionCreate(NullBox, 1); 3006f7df2e56Smrg 300705b261ecSmrg if (pWin->parent || 3008f7df2e56Smrg screenIsSaved != SCREEN_SAVER_ON || 3009f7df2e56Smrg !HasSaverWindow(pWin->drawable.pScreen)) { 3010f7df2e56Smrg RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); 301105b261ecSmrg } 30124202a189Smrg return pReg; 301305b261ecSmrg} 301405b261ecSmrg 3015637ac9abSmrgvoid 301605b261ecSmrgSendVisibilityNotify(WindowPtr pWin) 301705b261ecSmrg{ 301805b261ecSmrg xEvent event; 30194202a189Smrg unsigned int visibility = pWin->visibility; 30204202a189Smrg 302105b261ecSmrg#ifdef PANORAMIX 302205b261ecSmrg /* This is not quite correct yet, but it's close */ 3023f7df2e56Smrg if (!noPanoramiXExtension) { 3024f7df2e56Smrg PanoramiXRes *win; 3025f7df2e56Smrg WindowPtr pWin2; 3026f7df2e56Smrg int rc, i, Scrnum; 3027f7df2e56Smrg 3028f7df2e56Smrg Scrnum = pWin->drawable.pScreen->myNum; 3029f7df2e56Smrg 3030f7df2e56Smrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); 3031f7df2e56Smrg 3032f7df2e56Smrg if (!win || (win->u.win.visibility == visibility)) 3033f7df2e56Smrg return; 3034f7df2e56Smrg 3035f7df2e56Smrg switch (visibility) { 3036f7df2e56Smrg case VisibilityUnobscured: 3037f7df2e56Smrg FOR_NSCREENS(i) { 3038f7df2e56Smrg if (i == Scrnum) 3039f7df2e56Smrg continue; 3040f7df2e56Smrg 3041f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3042f7df2e56Smrg DixWriteAccess); 3043f7df2e56Smrg 3044f7df2e56Smrg if (rc == Success) { 3045f7df2e56Smrg if (pWin2->visibility == VisibilityPartiallyObscured) 3046f7df2e56Smrg return; 3047f7df2e56Smrg 3048f7df2e56Smrg if (!i) 3049f7df2e56Smrg pWin = pWin2; 3050f7df2e56Smrg } 3051f7df2e56Smrg } 3052f7df2e56Smrg break; 3053f7df2e56Smrg case VisibilityPartiallyObscured: 3054f7df2e56Smrg if (Scrnum) { 3055f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, 3056f7df2e56Smrg DixWriteAccess); 3057f7df2e56Smrg if (rc == Success) 3058f7df2e56Smrg pWin = pWin2; 3059f7df2e56Smrg } 3060f7df2e56Smrg break; 3061f7df2e56Smrg case VisibilityFullyObscured: 3062f7df2e56Smrg FOR_NSCREENS(i) { 3063f7df2e56Smrg if (i == Scrnum) 3064f7df2e56Smrg continue; 3065f7df2e56Smrg 3066f7df2e56Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3067f7df2e56Smrg DixWriteAccess); 3068f7df2e56Smrg 3069f7df2e56Smrg if (rc == Success) { 3070f7df2e56Smrg if (pWin2->visibility != VisibilityFullyObscured) 3071f7df2e56Smrg return; 3072f7df2e56Smrg 3073f7df2e56Smrg if (!i) 3074f7df2e56Smrg pWin = pWin2; 3075f7df2e56Smrg } 3076f7df2e56Smrg } 3077f7df2e56Smrg break; 3078f7df2e56Smrg } 3079f7df2e56Smrg 3080f7df2e56Smrg win->u.win.visibility = visibility; 308105b261ecSmrg } 308205b261ecSmrg#endif 308305b261ecSmrg 3084f7df2e56Smrg event = (xEvent) { 3085f7df2e56Smrg .u.visibility.window = pWin->drawable.id, 3086f7df2e56Smrg .u.visibility.state = visibility 3087f7df2e56Smrg }; 308805b261ecSmrg event.u.u.type = VisibilityNotify; 308905b261ecSmrg DeliverEvents(pWin, &event, 1, NullWindow); 309005b261ecSmrg} 309105b261ecSmrg 309205b261ecSmrg#define RANDOM_WIDTH 32 30934202a189Smrgint 3094637ac9abSmrgdixSaveScreens(ClientPtr client, int on, int mode) 309505b261ecSmrg{ 3096637ac9abSmrg int rc, i, what, type; 30975a112b11Smrg XID vlist[2]; 309805b261ecSmrg 3099f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) { 3100f7df2e56Smrg if (mode == ScreenSaverReset) 3101f7df2e56Smrg what = SCREEN_SAVER_OFF; 3102f7df2e56Smrg else 3103f7df2e56Smrg what = SCREEN_SAVER_ON; 3104f7df2e56Smrg type = what; 310505b261ecSmrg } 3106f7df2e56Smrg else { 3107f7df2e56Smrg what = on; 3108f7df2e56Smrg type = what; 3109f7df2e56Smrg if (what == screenIsSaved) 3110f7df2e56Smrg type = SCREEN_SAVER_CYCLE; 311105b261ecSmrg } 3112637ac9abSmrg 3113637ac9abSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3114f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3115f7df2e56Smrg DixShowAccess | DixHideAccess); 3116f7df2e56Smrg if (rc != Success) 3117f7df2e56Smrg return rc; 3118637ac9abSmrg } 3119f7df2e56Smrg for (i = 0; i < screenInfo.numScreens; i++) { 3120f7df2e56Smrg ScreenPtr pScreen = screenInfo.screens[i]; 3121f7df2e56Smrg 3122f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) 3123f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, on); 3124f7df2e56Smrg if (pScreen->screensaver.ExternalScreenSaver) { 3125f7df2e56Smrg if ((*pScreen->screensaver.ExternalScreenSaver) 3126f7df2e56Smrg (pScreen, type, on == SCREEN_SAVER_FORCER)) 3127f7df2e56Smrg continue; 3128f7df2e56Smrg } 3129f7df2e56Smrg if (type == screenIsSaved) 3130f7df2e56Smrg continue; 3131f7df2e56Smrg switch (type) { 3132f7df2e56Smrg case SCREEN_SAVER_OFF: 3133f7df2e56Smrg if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { 3134f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, what); 3135f7df2e56Smrg } 3136f7df2e56Smrg else if (HasSaverWindow(pScreen)) { 3137f7df2e56Smrg pScreen->screensaver.pWindow = NullWindow; 3138f7df2e56Smrg FreeResource(pScreen->screensaver.wid, RT_NONE); 3139f7df2e56Smrg } 3140f7df2e56Smrg break; 3141f7df2e56Smrg case SCREEN_SAVER_CYCLE: 3142f7df2e56Smrg if (pScreen->screensaver.blanked == SCREEN_IS_TILED) { 3143f7df2e56Smrg WindowPtr pWin = pScreen->screensaver.pWindow; 3144f7df2e56Smrg 3145f7df2e56Smrg /* make it look like screen saver is off, so that 3146f7df2e56Smrg * NotClippedByChildren will compute a clip list 3147f7df2e56Smrg * for the root window, so PaintWindow works 3148f7df2e56Smrg */ 3149f7df2e56Smrg screenIsSaved = SCREEN_SAVER_OFF; 31505a112b11Smrg 31515a112b11Smrg vlist[0] = -(rand() % RANDOM_WIDTH); 31525a112b11Smrg vlist[1] = -(rand() % RANDOM_WIDTH); 31535a112b11Smrg ConfigureWindow(pWin, CWX | CWY, vlist, client); 31545a112b11Smrg 3155f7df2e56Smrg screenIsSaved = SCREEN_SAVER_ON; 3156f7df2e56Smrg } 3157f7df2e56Smrg /* 3158f7df2e56Smrg * Call the DDX saver in case it wants to do something 3159f7df2e56Smrg * at cycle time 3160f7df2e56Smrg */ 3161f7df2e56Smrg else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { 3162f7df2e56Smrg (*pScreen->SaveScreen) (pScreen, type); 3163f7df2e56Smrg } 3164f7df2e56Smrg break; 3165f7df2e56Smrg case SCREEN_SAVER_ON: 3166f7df2e56Smrg if (ScreenSaverBlanking != DontPreferBlanking) { 3167f7df2e56Smrg if ((*pScreen->SaveScreen) (pScreen, what)) { 3168f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_BLANKED; 3169f7df2e56Smrg continue; 3170f7df2e56Smrg } 3171f7df2e56Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3172f7df2e56Smrg TileScreenSaver(pScreen, SCREEN_IS_BLACK)) { 3173f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_BLACK; 3174f7df2e56Smrg continue; 3175f7df2e56Smrg } 3176f7df2e56Smrg } 3177f7df2e56Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3178f7df2e56Smrg TileScreenSaver(pScreen, SCREEN_IS_TILED)) { 3179f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_IS_TILED; 3180f7df2e56Smrg } 3181f7df2e56Smrg else 3182f7df2e56Smrg pScreen->screensaver.blanked = SCREEN_ISNT_SAVED; 3183f7df2e56Smrg break; 3184f7df2e56Smrg } 318505b261ecSmrg } 318605b261ecSmrg screenIsSaved = what; 31874202a189Smrg if (mode == ScreenSaverReset) { 3188f7df2e56Smrg if (on == SCREEN_SAVER_FORCER) { 3189f7df2e56Smrg DeviceIntPtr dev; 3190f7df2e56Smrg UpdateCurrentTimeIf(); 3191f7df2e56Smrg nt_list_for_each_entry(dev, inputInfo.devices, next) 3192f7df2e56Smrg NoticeTime(dev, currentTime); 3193f7df2e56Smrg } 3194f7df2e56Smrg SetScreenSaverTimer(); 31954202a189Smrg } 3196637ac9abSmrg return Success; 3197637ac9abSmrg} 3198637ac9abSmrg 31994202a189Smrgint 3200637ac9abSmrgSaveScreens(int on, int mode) 3201637ac9abSmrg{ 3202637ac9abSmrg return dixSaveScreens(serverClient, on, mode); 320305b261ecSmrg} 320405b261ecSmrg 320505b261ecSmrgstatic Bool 32064202a189SmrgTileScreenSaver(ScreenPtr pScreen, int kind) 320705b261ecSmrg{ 320805b261ecSmrg int j; 320905b261ecSmrg int result; 321005b261ecSmrg XID attributes[3]; 321105b261ecSmrg Mask mask; 3212f7df2e56Smrg WindowPtr pWin; 321305b261ecSmrg CursorMetricRec cm; 321405b261ecSmrg unsigned char *srcbits, *mskbits; 321505b261ecSmrg CursorPtr cursor; 3216f7df2e56Smrg XID cursorID = 0; 3217f7df2e56Smrg int attri; 321805b261ecSmrg 321905b261ecSmrg mask = 0; 322005b261ecSmrg attri = 0; 322105b261ecSmrg switch (kind) { 322205b261ecSmrg case SCREEN_IS_TILED: 3223f7df2e56Smrg switch (pScreen->root->backgroundState) { 3224f7df2e56Smrg case BackgroundPixel: 3225f7df2e56Smrg attributes[attri++] = pScreen->root->background.pixel; 3226f7df2e56Smrg mask |= CWBackPixel; 3227f7df2e56Smrg break; 3228f7df2e56Smrg case BackgroundPixmap: 3229f7df2e56Smrg attributes[attri++] = None; 3230f7df2e56Smrg mask |= CWBackPixmap; 3231f7df2e56Smrg break; 3232f7df2e56Smrg default: 3233f7df2e56Smrg break; 3234f7df2e56Smrg } 3235f7df2e56Smrg break; 323605b261ecSmrg case SCREEN_IS_BLACK: 3237f7df2e56Smrg attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; 3238f7df2e56Smrg mask |= CWBackPixel; 3239f7df2e56Smrg break; 324005b261ecSmrg } 324105b261ecSmrg mask |= CWOverrideRedirect; 324205b261ecSmrg attributes[attri++] = xTrue; 324305b261ecSmrg 324405b261ecSmrg /* 324505b261ecSmrg * create a blank cursor 324605b261ecSmrg */ 324705b261ecSmrg 3248f7df2e56Smrg cm.width = 16; 3249f7df2e56Smrg cm.height = 16; 3250f7df2e56Smrg cm.xhot = 8; 3251f7df2e56Smrg cm.yhot = 8; 3252f7df2e56Smrg srcbits = malloc(BitmapBytePad(32) * 16); 3253f7df2e56Smrg mskbits = malloc(BitmapBytePad(32) * 16); 3254f7df2e56Smrg if (!srcbits || !mskbits) { 3255f7df2e56Smrg free(srcbits); 3256f7df2e56Smrg free(mskbits); 3257f7df2e56Smrg cursor = 0; 325805b261ecSmrg } 3259f7df2e56Smrg else { 3260f7df2e56Smrg for (j = 0; j < BitmapBytePad(32) * 16; j++) 3261f7df2e56Smrg srcbits[j] = mskbits[j] = 0x0; 3262f7df2e56Smrg result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, 3263f7df2e56Smrg &cursor, serverClient, (XID) 0); 3264f7df2e56Smrg if (cursor) { 3265f7df2e56Smrg cursorID = FakeClientID(0); 3266f7df2e56Smrg if (AddResource(cursorID, RT_CURSOR, (void *) cursor)) { 3267f7df2e56Smrg attributes[attri] = cursorID; 3268f7df2e56Smrg mask |= CWCursor; 3269f7df2e56Smrg } 3270f7df2e56Smrg else 3271f7df2e56Smrg cursor = 0; 3272f7df2e56Smrg } 3273f7df2e56Smrg else { 3274f7df2e56Smrg free(srcbits); 3275f7df2e56Smrg free(mskbits); 3276f7df2e56Smrg } 327705b261ecSmrg } 327805b261ecSmrg 32794202a189Smrg pWin = pScreen->screensaver.pWindow = 3280f7df2e56Smrg CreateWindow(pScreen->screensaver.wid, 3281f7df2e56Smrg pScreen->root, 3282f7df2e56Smrg -RANDOM_WIDTH, -RANDOM_WIDTH, 3283f7df2e56Smrg (unsigned short) pScreen->width + RANDOM_WIDTH, 3284f7df2e56Smrg (unsigned short) pScreen->height + RANDOM_WIDTH, 3285f7df2e56Smrg 0, InputOutput, mask, attributes, 0, serverClient, 3286f7df2e56Smrg wVisual(pScreen->root), &result); 328705b261ecSmrg 328805b261ecSmrg if (cursor) 3289f7df2e56Smrg FreeResource(cursorID, RT_NONE); 329005b261ecSmrg 329105b261ecSmrg if (!pWin) 3292f7df2e56Smrg return FALSE; 329305b261ecSmrg 329405b261ecSmrg if (!AddResource(pWin->drawable.id, RT_WINDOW, 3295f7df2e56Smrg (void *) pScreen->screensaver.pWindow)) 3296f7df2e56Smrg return FALSE; 329705b261ecSmrg 3298f7df2e56Smrg if (mask & CWBackPixmap) { 3299f7df2e56Smrg MakeRootTile(pWin); 3300f7df2e56Smrg (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap); 330105b261ecSmrg } 330205b261ecSmrg MapWindow(pWin, serverClient); 330305b261ecSmrg return TRUE; 330405b261ecSmrg} 330505b261ecSmrg 330605b261ecSmrg/* 330705b261ecSmrg * FindWindowWithOptional 330805b261ecSmrg * 330905b261ecSmrg * search ancestors of the given window for an entry containing 331005b261ecSmrg * a WindowOpt structure. Assumptions: some parent will 331105b261ecSmrg * contain the structure. 331205b261ecSmrg */ 331305b261ecSmrg 33144202a189SmrgWindowPtr 3315f7df2e56SmrgFindWindowWithOptional(WindowPtr w) 331605b261ecSmrg{ 331705b261ecSmrg do 3318f7df2e56Smrg w = w->parent; 331905b261ecSmrg while (!w->optional); 332005b261ecSmrg return w; 332105b261ecSmrg} 332205b261ecSmrg 332305b261ecSmrg/* 332405b261ecSmrg * CheckWindowOptionalNeed 332505b261ecSmrg * 332605b261ecSmrg * check each optional entry in the given window to see if 332705b261ecSmrg * the value is satisfied by the default rules. If so, 332805b261ecSmrg * release the optional record 332905b261ecSmrg */ 333005b261ecSmrg 33314202a189Smrgvoid 3332f7df2e56SmrgCheckWindowOptionalNeed(WindowPtr w) 333305b261ecSmrg{ 333405b261ecSmrg WindowOptPtr optional; 333505b261ecSmrg WindowOptPtr parentOptional; 333605b261ecSmrg 33374202a189Smrg if (!w->parent || !w->optional) 3338f7df2e56Smrg return; 333905b261ecSmrg optional = w->optional; 334005b261ecSmrg if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) 3341f7df2e56Smrg return; 334205b261ecSmrg if (optional->otherEventMasks != 0) 3343f7df2e56Smrg return; 334405b261ecSmrg if (optional->otherClients != NULL) 3345f7df2e56Smrg return; 334605b261ecSmrg if (optional->passiveGrabs != NULL) 3347f7df2e56Smrg return; 334805b261ecSmrg if (optional->userProps != NULL) 3349f7df2e56Smrg return; 3350f7df2e56Smrg if (optional->backingBitPlanes != (CARD32)~0L) 3351f7df2e56Smrg return; 335205b261ecSmrg if (optional->backingPixel != 0) 3353f7df2e56Smrg return; 335405b261ecSmrg if (optional->boundingShape != NULL) 3355f7df2e56Smrg return; 335605b261ecSmrg if (optional->clipShape != NULL) 3357f7df2e56Smrg return; 335805b261ecSmrg if (optional->inputShape != NULL) 3359f7df2e56Smrg return; 336005b261ecSmrg if (optional->inputMasks != NULL) 3361f7df2e56Smrg return; 3362f7df2e56Smrg if (optional->deviceCursors != NULL) { 3363637ac9abSmrg DevCursNodePtr pNode = optional->deviceCursors; 3364f7df2e56Smrg 3365f7df2e56Smrg while (pNode) { 3366637ac9abSmrg if (pNode->cursor != None) 3367637ac9abSmrg return; 3368637ac9abSmrg pNode = pNode->next; 3369637ac9abSmrg } 3370637ac9abSmrg } 3371637ac9abSmrg 337205b261ecSmrg parentOptional = FindWindowWithOptional(w)->optional; 337305b261ecSmrg if (optional->visual != parentOptional->visual) 3374f7df2e56Smrg return; 337505b261ecSmrg if (optional->cursor != None && 3376f7df2e56Smrg (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone)) 3377f7df2e56Smrg return; 337805b261ecSmrg if (optional->colormap != parentOptional->colormap) 3379f7df2e56Smrg return; 3380f7df2e56Smrg DisposeWindowOptional(w); 338105b261ecSmrg} 338205b261ecSmrg 338305b261ecSmrg/* 338405b261ecSmrg * MakeWindowOptional 338505b261ecSmrg * 338605b261ecSmrg * create an optional record and initialize it with the default 338705b261ecSmrg * values. 338805b261ecSmrg */ 338905b261ecSmrg 33904202a189SmrgBool 3391f7df2e56SmrgMakeWindowOptional(WindowPtr pWin) 339205b261ecSmrg{ 339305b261ecSmrg WindowOptPtr optional; 339405b261ecSmrg WindowOptPtr parentOptional; 339505b261ecSmrg 339605b261ecSmrg if (pWin->optional) 3397f7df2e56Smrg return TRUE; 3398f7df2e56Smrg optional = malloc(sizeof(WindowOptRec)); 339905b261ecSmrg if (!optional) 3400f7df2e56Smrg return FALSE; 340105b261ecSmrg optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; 340205b261ecSmrg optional->otherEventMasks = 0; 340305b261ecSmrg optional->otherClients = NULL; 340405b261ecSmrg optional->passiveGrabs = NULL; 340505b261ecSmrg optional->userProps = NULL; 340605b261ecSmrg optional->backingBitPlanes = ~0L; 340705b261ecSmrg optional->backingPixel = 0; 340805b261ecSmrg optional->boundingShape = NULL; 340905b261ecSmrg optional->clipShape = NULL; 341005b261ecSmrg optional->inputShape = NULL; 341105b261ecSmrg optional->inputMasks = NULL; 3412637ac9abSmrg optional->deviceCursors = NULL; 3413637ac9abSmrg 341405b261ecSmrg parentOptional = FindWindowWithOptional(pWin)->optional; 341505b261ecSmrg optional->visual = parentOptional->visual; 3416f7df2e56Smrg if (!pWin->cursorIsNone) { 3417f7df2e56Smrg optional->cursor = RefCursor(parentOptional->cursor); 341805b261ecSmrg } 3419f7df2e56Smrg else { 3420f7df2e56Smrg optional->cursor = None; 342105b261ecSmrg } 342205b261ecSmrg optional->colormap = parentOptional->colormap; 342305b261ecSmrg pWin->optional = optional; 342405b261ecSmrg return TRUE; 342505b261ecSmrg} 342605b261ecSmrg 3427637ac9abSmrg/* 3428637ac9abSmrg * Changes the cursor struct for the given device and the given window. 3429637ac9abSmrg * A cursor that does not have a device cursor set will use whatever the 3430637ac9abSmrg * standard cursor is for the window. If all devices have a cursor set, 3431637ac9abSmrg * changing the window cursor (e.g. using XDefineCursor()) will not have any 3432637ac9abSmrg * visible effect. Only when one of the device cursors is set to None again, 3433637ac9abSmrg * this device's cursor will display the changed standard cursor. 3434f7df2e56Smrg * 3435637ac9abSmrg * CursorIsNone of the window struct is NOT modified if you set a device 3436f7df2e56Smrg * cursor. 3437637ac9abSmrg * 3438637ac9abSmrg * Assumption: If there is a node for a device in the list, the device has a 3439637ac9abSmrg * cursor. If the cursor is set to None, it is inherited by the parent. 3440637ac9abSmrg */ 34414202a189Smrgint 3442f7df2e56SmrgChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) 3443637ac9abSmrg{ 3444637ac9abSmrg DevCursNodePtr pNode, pPrev; 3445637ac9abSmrg CursorPtr pOldCursor = NULL; 3446637ac9abSmrg ScreenPtr pScreen; 3447637ac9abSmrg WindowPtr pChild; 3448637ac9abSmrg 3449637ac9abSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 3450637ac9abSmrg return BadAlloc; 3451637ac9abSmrg 3452637ac9abSmrg /* 1) Check if window has device cursor set 3453637ac9abSmrg * Yes: 1.1) swap cursor with given cursor if parent does not have same 3454637ac9abSmrg * cursor, free old cursor 3455637ac9abSmrg * 1.2) free old cursor, use parent cursor 3456637ac9abSmrg * No: 1.1) add node to beginning of list. 3457637ac9abSmrg * 1.2) add cursor to node if parent does not have same cursor 3458637ac9abSmrg * 1.3) use parent cursor if parent does not have same cursor 3459637ac9abSmrg * 2) Patch up children if child has a devcursor 3460637ac9abSmrg * 2.1) if child has cursor None, it inherited from parent, set to old 3461637ac9abSmrg * cursor 3462637ac9abSmrg * 2.2) if child has same cursor as new cursor, remove and set to None 3463637ac9abSmrg */ 3464637ac9abSmrg 3465637ac9abSmrg pScreen = pWin->drawable.pScreen; 3466637ac9abSmrg 3467f7df2e56Smrg if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) { 3468637ac9abSmrg /* has device cursor */ 3469637ac9abSmrg 3470637ac9abSmrg if (pNode->cursor == pCursor) 3471637ac9abSmrg return Success; 3472637ac9abSmrg 3473637ac9abSmrg pOldCursor = pNode->cursor; 3474637ac9abSmrg 3475f7df2e56Smrg if (!pCursor) { /* remove from list */ 3476f7df2e56Smrg if (pPrev) 3477f7df2e56Smrg pPrev->next = pNode->next; 3478f7df2e56Smrg else 3479f7df2e56Smrg /* first item in list */ 3480f7df2e56Smrg pWin->optional->deviceCursors = pNode->next; 3481637ac9abSmrg 34824202a189Smrg free(pNode); 34834202a189Smrg goto out; 3484637ac9abSmrg } 3485637ac9abSmrg 3486f7df2e56Smrg } 3487f7df2e56Smrg else { 3488637ac9abSmrg /* no device cursor yet */ 3489637ac9abSmrg DevCursNodePtr pNewNode; 3490637ac9abSmrg 3491637ac9abSmrg if (!pCursor) 3492637ac9abSmrg return Success; 3493637ac9abSmrg 34944202a189Smrg pNewNode = malloc(sizeof(DevCursNodeRec)); 3495637ac9abSmrg pNewNode->dev = pDev; 3496637ac9abSmrg pNewNode->next = pWin->optional->deviceCursors; 3497637ac9abSmrg pWin->optional->deviceCursors = pNewNode; 3498637ac9abSmrg pNode = pNewNode; 3499637ac9abSmrg 3500637ac9abSmrg } 3501637ac9abSmrg 3502637ac9abSmrg if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) 3503637ac9abSmrg pNode->cursor = None; 3504f7df2e56Smrg else { 3505f7df2e56Smrg pNode->cursor = RefCursor(pCursor); 3506637ac9abSmrg } 3507637ac9abSmrg 3508637ac9abSmrg pNode = pPrev = NULL; 3509637ac9abSmrg /* fix up children */ 3510f7df2e56Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 3511f7df2e56Smrg if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) { 3512f7df2e56Smrg if (pNode->cursor == None) { /* inherited from parent */ 3513f7df2e56Smrg pNode->cursor = RefCursor(pOldCursor); 3514f7df2e56Smrg } 3515f7df2e56Smrg else if (pNode->cursor == pCursor) { 3516637ac9abSmrg pNode->cursor = None; 3517f7df2e56Smrg FreeCursor(pCursor, (Cursor) 0); /* fix up refcnt */ 3518637ac9abSmrg } 3519637ac9abSmrg } 3520637ac9abSmrg } 3521637ac9abSmrg 3522f7df2e56Smrg out: 3523f7df2e56Smrg CursorVisible = TRUE; 3524f7df2e56Smrg 3525637ac9abSmrg if (pWin->realized) 3526637ac9abSmrg WindowHasNewCursor(pWin); 3527637ac9abSmrg 3528637ac9abSmrg if (pOldCursor) 3529f7df2e56Smrg FreeCursor(pOldCursor, (Cursor) 0); 3530637ac9abSmrg 3531f7df2e56Smrg /* FIXME: We SHOULD check for an error value here XXX 3532637ac9abSmrg (comment taken from ChangeWindowAttributes) */ 3533f7df2e56Smrg (*pScreen->ChangeWindowAttributes) (pWin, CWCursor); 3534637ac9abSmrg 3535637ac9abSmrg return Success; 3536637ac9abSmrg} 3537637ac9abSmrg 3538637ac9abSmrg/* Get device cursor for given device or None if none is set */ 35394202a189SmrgCursorPtr 3540637ac9abSmrgWindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) 3541637ac9abSmrg{ 3542637ac9abSmrg DevCursorList pList; 3543637ac9abSmrg 3544637ac9abSmrg if (!pWin->optional || !pWin->optional->deviceCursors) 3545637ac9abSmrg return NULL; 3546637ac9abSmrg 3547637ac9abSmrg pList = pWin->optional->deviceCursors; 3548637ac9abSmrg 3549f7df2e56Smrg while (pList) { 3550f7df2e56Smrg if (pList->dev == pDev) { 3551f7df2e56Smrg if (pList->cursor == None) /* inherited from parent */ 3552637ac9abSmrg return WindowGetDeviceCursor(pWin->parent, pDev); 3553637ac9abSmrg else 3554637ac9abSmrg return pList->cursor; 3555637ac9abSmrg } 3556637ac9abSmrg pList = pList->next; 3557637ac9abSmrg } 3558637ac9abSmrg return NULL; 3559637ac9abSmrg} 3560637ac9abSmrg 3561637ac9abSmrg/* Searches for a DevCursorNode for the given window and device. If one is 3562637ac9abSmrg * found, return True and set pNode and pPrev to the node and to the node 3563637ac9abSmrg * before the node respectively. Otherwise return False. 3564637ac9abSmrg * If the device is the first in list, pPrev is set to NULL. 3565637ac9abSmrg */ 3566f7df2e56Smrgstatic Bool 3567f7df2e56SmrgWindowSeekDeviceCursor(WindowPtr pWin, 3568f7df2e56Smrg DeviceIntPtr pDev, 3569f7df2e56Smrg DevCursNodePtr * pNode, DevCursNodePtr * pPrev) 3570637ac9abSmrg{ 3571637ac9abSmrg DevCursorList pList; 3572637ac9abSmrg 3573637ac9abSmrg if (!pWin->optional) 3574637ac9abSmrg return FALSE; 3575637ac9abSmrg 3576637ac9abSmrg pList = pWin->optional->deviceCursors; 3577637ac9abSmrg 3578f7df2e56Smrg if (pList && pList->dev == pDev) { 3579637ac9abSmrg *pNode = pList; 3580637ac9abSmrg *pPrev = NULL; 3581637ac9abSmrg return TRUE; 3582637ac9abSmrg } 3583637ac9abSmrg 3584f7df2e56Smrg while (pList) { 3585f7df2e56Smrg if (pList->next) { 3586f7df2e56Smrg if (pList->next->dev == pDev) { 3587637ac9abSmrg *pNode = pList->next; 3588637ac9abSmrg *pPrev = pList; 3589637ac9abSmrg return TRUE; 3590637ac9abSmrg } 3591637ac9abSmrg } 3592637ac9abSmrg pList = pList->next; 3593637ac9abSmrg } 3594637ac9abSmrg return FALSE; 3595637ac9abSmrg} 3596637ac9abSmrg 3597637ac9abSmrg/* Return True if a parent has the same device cursor set or False if 3598f7df2e56Smrg * otherwise 3599f7df2e56Smrg */ 3600f7df2e56Smrgstatic Bool 3601f7df2e56SmrgWindowParentHasDeviceCursor(WindowPtr pWin, 3602f7df2e56Smrg DeviceIntPtr pDev, CursorPtr pCursor) 3603637ac9abSmrg{ 3604637ac9abSmrg WindowPtr pParent; 3605637ac9abSmrg DevCursNodePtr pParentNode, pParentPrev; 3606637ac9abSmrg 3607637ac9abSmrg pParent = pWin->parent; 3608f7df2e56Smrg while (pParent) { 3609f7df2e56Smrg if (WindowSeekDeviceCursor(pParent, pDev, &pParentNode, &pParentPrev)) { 3610637ac9abSmrg /* if there is a node in the list, the win has a dev cursor */ 3611f7df2e56Smrg if (!pParentNode->cursor) /* inherited. */ 36121b684552Smrg pParent = pParent->parent; 3613f7df2e56Smrg else if (pParentNode->cursor == pCursor) /* inherit */ 3614637ac9abSmrg return TRUE; 3615f7df2e56Smrg else /* different cursor */ 3616637ac9abSmrg return FALSE; 3617f7df2e56Smrg } 3618f7df2e56Smrg else 3619637ac9abSmrg /* parent does not have a device cursor for our device */ 3620637ac9abSmrg return FALSE; 3621637ac9abSmrg } 3622637ac9abSmrg return FALSE; 3623637ac9abSmrg} 3624f7df2e56Smrg 3625f7df2e56Smrg/* 3626f7df2e56Smrg * SetRootClip -- 3627f7df2e56Smrg * Enable or disable rendering to the screen by 3628f7df2e56Smrg * setting the root clip list and revalidating 3629f7df2e56Smrg * all of the windows 3630f7df2e56Smrg */ 3631f7df2e56Smrgvoid 3632f7df2e56SmrgSetRootClip(ScreenPtr pScreen, int enable) 3633f7df2e56Smrg{ 3634f7df2e56Smrg WindowPtr pWin = pScreen->root; 3635f7df2e56Smrg WindowPtr pChild; 3636f7df2e56Smrg Bool WasViewable; 3637f7df2e56Smrg Bool anyMarked = FALSE; 3638f7df2e56Smrg WindowPtr pLayerWin; 3639f7df2e56Smrg BoxRec box; 3640f7df2e56Smrg enum RootClipMode mode = enable; 3641f7df2e56Smrg 3642f7df2e56Smrg if (!pWin) 3643f7df2e56Smrg return; 3644f7df2e56Smrg WasViewable = (Bool) (pWin->viewable); 3645f7df2e56Smrg if (WasViewable) { 3646f7df2e56Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 3647f7df2e56Smrg (void) (*pScreen->MarkOverlappedWindows) (pChild, 3648f7df2e56Smrg pChild, &pLayerWin); 3649f7df2e56Smrg } 3650f7df2e56Smrg (*pScreen->MarkWindow) (pWin); 3651f7df2e56Smrg anyMarked = TRUE; 3652f7df2e56Smrg if (pWin->valdata) { 3653f7df2e56Smrg if (HasBorder(pWin)) { 3654f7df2e56Smrg RegionPtr borderVisible; 3655f7df2e56Smrg 3656f7df2e56Smrg borderVisible = RegionCreate(NullBox, 1); 3657f7df2e56Smrg RegionSubtract(borderVisible, 3658f7df2e56Smrg &pWin->borderClip, &pWin->winSize); 3659f7df2e56Smrg pWin->valdata->before.borderVisible = borderVisible; 3660f7df2e56Smrg } 3661f7df2e56Smrg pWin->valdata->before.resized = TRUE; 3662f7df2e56Smrg } 3663f7df2e56Smrg } 3664f7df2e56Smrg 3665f7df2e56Smrg if (mode != ROOT_CLIP_NONE) { 3666f7df2e56Smrg pWin->drawable.width = pScreen->width; 3667f7df2e56Smrg pWin->drawable.height = pScreen->height; 3668f7df2e56Smrg 3669f7df2e56Smrg box.x1 = 0; 3670f7df2e56Smrg box.y1 = 0; 3671f7df2e56Smrg box.x2 = pScreen->width; 3672f7df2e56Smrg box.y2 = pScreen->height; 3673f7df2e56Smrg 3674f7df2e56Smrg RegionInit(&pWin->winSize, &box, 1); 3675f7df2e56Smrg RegionInit(&pWin->borderSize, &box, 1); 3676f7df2e56Smrg 3677f7df2e56Smrg /* 3678f7df2e56Smrg * Use REGION_BREAK to avoid optimizations in ValidateTree 3679f7df2e56Smrg * that assume the root borderClip can't change well, normally 3680f7df2e56Smrg * it doesn't...) 3681f7df2e56Smrg */ 3682f7df2e56Smrg RegionBreak(&pWin->clipList); 3683f7df2e56Smrg 3684f7df2e56Smrg /* For INPUT_ONLY, empty the borderClip so no rendering will ever 3685f7df2e56Smrg * be attempted to the screen pixmap (only redirected windows), 3686f7df2e56Smrg * but we keep borderSize as full regardless. */ 3687f7df2e56Smrg if (WasViewable && mode == ROOT_CLIP_FULL) 3688f7df2e56Smrg RegionReset(&pWin->borderClip, &box); 3689f7df2e56Smrg else 3690f7df2e56Smrg RegionEmpty(&pWin->borderClip); 3691f7df2e56Smrg } 3692f7df2e56Smrg else { 3693f7df2e56Smrg RegionEmpty(&pWin->borderClip); 3694f7df2e56Smrg RegionBreak(&pWin->clipList); 3695f7df2e56Smrg } 3696f7df2e56Smrg 3697f7df2e56Smrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 3698f7df2e56Smrg 3699f7df2e56Smrg if (WasViewable) { 3700f7df2e56Smrg if (pWin->firstChild) { 3701f7df2e56Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin->firstChild, 3702f7df2e56Smrg pWin->firstChild, 3703f7df2e56Smrg NULL); 3704f7df2e56Smrg } 3705f7df2e56Smrg else { 3706f7df2e56Smrg (*pScreen->MarkWindow) (pWin); 3707f7df2e56Smrg anyMarked = TRUE; 3708f7df2e56Smrg } 3709f7df2e56Smrg 3710f7df2e56Smrg if (anyMarked) { 3711f7df2e56Smrg (*pScreen->ValidateTree) (pWin, NullWindow, VTOther); 3712f7df2e56Smrg (*pScreen->HandleExposures) (pWin); 3713f7df2e56Smrg if (pScreen->PostValidateTree) 3714f7df2e56Smrg (*pScreen->PostValidateTree) (pWin, NullWindow, VTOther); 3715f7df2e56Smrg } 3716f7df2e56Smrg } 3717f7df2e56Smrg if (pWin->realized) 3718f7df2e56Smrg WindowsRestructured(); 3719f7df2e56Smrg FlushAllOutput(); 3720f7df2e56Smrg} 3721f7df2e56Smrg 3722f7df2e56SmrgVisualPtr 3723f7df2e56SmrgWindowGetVisual(WindowPtr pWin) 3724f7df2e56Smrg{ 3725f7df2e56Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 3726f7df2e56Smrg VisualID vid = wVisual(pWin); 3727f7df2e56Smrg int i; 3728f7df2e56Smrg 3729f7df2e56Smrg for (i = 0; i < pScreen->numVisuals; i++) 3730f7df2e56Smrg if (pScreen->visuals[i].vid == vid) 3731f7df2e56Smrg return &pScreen->visuals[i]; 3732f7df2e56Smrg return 0; 3733f7df2e56Smrg} 3734