PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

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

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