PageRenderTime 77ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/nx-3.5.0/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c

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