PageRenderTime 97ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

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

#
C | 4797 lines | 4105 code | 395 blank | 297 comment | 1019 complexity | 2592f6e76138f6850ae592fa324b3ac3 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0
  1. #ifdef NXAGENT_UPGRADE
  2. #include "X/NXevents.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. /* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
  21. /************************************************************
  22. Copyright 1987, 1998 The Open Group
  23. Permission to use, copy, modify, distribute, and sell this software and its
  24. documentation for any purpose is hereby granted without fee, provided that
  25. the above copyright notice appear in all copies and that both that
  26. copyright notice and this permission notice appear in supporting
  27. documentation.
  28. The above copyright notice and this permission notice shall be included in
  29. all copies or substantial portions of the Software.
  30. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  31. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  32. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  33. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  34. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  35. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  36. Except as contained in this notice, the name of The Open Group shall not be
  37. used in advertising or otherwise to promote the sale, use or other dealings
  38. in this Software without prior written authorization from The Open Group.
  39. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  40. All Rights Reserved
  41. Permission to use, copy, modify, and distribute this software and its
  42. documentation for any purpose and without fee is hereby granted,
  43. provided that the above copyright notice appear in all copies and that
  44. both that copyright notice and this permission notice appear in
  45. supporting documentation, and that the name of Digital not be
  46. used in advertising or publicity pertaining to distribution of the
  47. software without specific, written prior permission.
  48. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  49. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  50. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  51. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  52. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  53. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  54. SOFTWARE.
  55. ********************************************************/
  56. /* The panoramix components contained the following notice */
  57. /****************************************************************
  58. * *
  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. /* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
  78. #include "X.h"
  79. #include "Xlib.h"
  80. #include "misc.h"
  81. #include "resource.h"
  82. #define NEED_EVENTS
  83. #define NEED_REPLIES
  84. #include "Xproto.h"
  85. #include "windowstr.h"
  86. #include "inputstr.h"
  87. #include "scrnintstr.h"
  88. #include "cursorstr.h"
  89. #include "dixstruct.h"
  90. #ifdef PANORAMIX
  91. #include "panoramiX.h"
  92. #include "panoramiXsrv.h"
  93. #endif
  94. #include "globals.h"
  95. #ifdef XKB
  96. #include "XKBsrv.h"
  97. #if NeedFunctionPrototypes
  98. extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
  99. #else
  100. extern Bool XkbFilterEvents();
  101. #endif
  102. #endif
  103. #ifdef XCSECURITY
  104. #define _SECURITY_SERVER
  105. #include "security.h"
  106. #endif
  107. #include "XIproto.h"
  108. #include "exevents.h"
  109. #include "extnsionst.h"
  110. #include "dixevents.h"
  111. #include "dixgrabs.h"
  112. #include "../../dix/dispatch.h"
  113. #include "NXlib.h"
  114. #include "Events.h"
  115. #include "Windows.h"
  116. extern Display *nxagentDisplay;
  117. extern WindowPtr nxagentLastEnteredWindow;
  118. #define EXTENSION_EVENT_BASE 64
  119. #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
  120. #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
  121. #define AllButtonsMask ( \
  122. Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
  123. #define MotionMask ( \
  124. PointerMotionMask | Button1MotionMask | \
  125. Button2MotionMask | Button3MotionMask | Button4MotionMask | \
  126. Button5MotionMask | ButtonMotionMask )
  127. #define PropagateMask ( \
  128. KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
  129. MotionMask )
  130. #define PointerGrabMask ( \
  131. ButtonPressMask | ButtonReleaseMask | \
  132. EnterWindowMask | LeaveWindowMask | \
  133. PointerMotionHintMask | KeymapStateMask | \
  134. MotionMask )
  135. #define AllModifiersMask ( \
  136. ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
  137. Mod3Mask | Mod4Mask | Mod5Mask )
  138. #define AllEventMasks (lastEventMask|(lastEventMask-1))
  139. /*
  140. * The following relies on the fact that the Button<n>MotionMasks are equal
  141. * to the corresponding Button<n>Masks from the current modifier/button state.
  142. */
  143. #define Motion_Filter(class) (PointerMotionMask | \
  144. (class)->state | (class)->motionMask)
  145. #define WID(w) ((w) ? ((w)->drawable.id) : 0)
  146. #define XE_KBPTR (xE->u.keyButtonPointer)
  147. #define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
  148. CallbackListPtr EventCallback;
  149. CallbackListPtr DeviceEventCallback;
  150. #define DNPMCOUNT 8
  151. Mask DontPropagateMasks[DNPMCOUNT];
  152. static int DontPropagateRefCnts[DNPMCOUNT];
  153. #ifdef DEBUG
  154. static debug_events = 0;
  155. #endif
  156. InputInfo inputInfo;
  157. static struct {
  158. QdEventPtr pending, *pendtail;
  159. DeviceIntPtr replayDev; /* kludgy rock to put flag for */
  160. WindowPtr replayWin; /* ComputeFreezes */
  161. Bool playingEvents;
  162. TimeStamp time;
  163. } syncEvents;
  164. /*
  165. * The window trace information is used to avoid having to compute all the
  166. * windows between the root and the current pointer window each time a button
  167. * or key goes down. The grabs on each of those windows must be checked.
  168. */
  169. static WindowPtr *spriteTrace = (WindowPtr *)NULL;
  170. #define ROOT spriteTrace[0]
  171. static int spriteTraceSize = 0;
  172. static int spriteTraceGood;
  173. typedef struct {
  174. int x, y;
  175. ScreenPtr pScreen;
  176. } HotSpot;
  177. static struct {
  178. CursorPtr current;
  179. BoxRec hotLimits; /* logical constraints of hot spot */
  180. Bool confined; /* confined to screen */
  181. #if defined(SHAPE) || defined(PANORAMIX)
  182. RegionPtr hotShape; /* additional logical shape constraint */
  183. #endif
  184. BoxRec physLimits; /* physical constraints of hot spot */
  185. WindowPtr win; /* window of logical position */
  186. HotSpot hot; /* logical pointer position */
  187. HotSpot hotPhys; /* physical pointer position */
  188. #ifdef PANORAMIX
  189. ScreenPtr screen; /* all others are in Screen 0 coordinates */
  190. RegionRec Reg1; /* Region 1 for confining motion */
  191. RegionRec Reg2; /* Region 2 for confining virtual motion */
  192. WindowPtr windows[MAXSCREENS];
  193. WindowPtr confineWin; /* confine window */
  194. #endif
  195. } sprite; /* info about the cursor sprite */
  196. static void DoEnterLeaveEvents(
  197. #if NeedFunctionPrototypes
  198. WindowPtr /*fromWin*/,
  199. WindowPtr /*toWin*/,
  200. int /*mode*/
  201. #endif
  202. );
  203. static WindowPtr XYToWindow(
  204. #if NeedFunctionPrototypes
  205. int /*x*/,
  206. int /*y*/
  207. #endif
  208. );
  209. extern int lastEvent;
  210. static Mask lastEventMask;
  211. #ifdef XINPUT
  212. extern int DeviceMotionNotify;
  213. #endif
  214. #define CantBeFiltered NoEventMask
  215. static Mask filters[128] =
  216. {
  217. NoSuchEvent, /* 0 */
  218. NoSuchEvent, /* 1 */
  219. KeyPressMask, /* KeyPress */
  220. KeyReleaseMask, /* KeyRelease */
  221. ButtonPressMask, /* ButtonPress */
  222. ButtonReleaseMask, /* ButtonRelease */
  223. PointerMotionMask, /* MotionNotify (initial state) */
  224. EnterWindowMask, /* EnterNotify */
  225. LeaveWindowMask, /* LeaveNotify */
  226. FocusChangeMask, /* FocusIn */
  227. FocusChangeMask, /* FocusOut */
  228. KeymapStateMask, /* KeymapNotify */
  229. ExposureMask, /* Expose */
  230. CantBeFiltered, /* GraphicsExpose */
  231. CantBeFiltered, /* NoExpose */
  232. VisibilityChangeMask, /* VisibilityNotify */
  233. SubstructureNotifyMask, /* CreateNotify */
  234. StructureAndSubMask, /* DestroyNotify */
  235. StructureAndSubMask, /* UnmapNotify */
  236. StructureAndSubMask, /* MapNotify */
  237. SubstructureRedirectMask, /* MapRequest */
  238. StructureAndSubMask, /* ReparentNotify */
  239. StructureAndSubMask, /* ConfigureNotify */
  240. SubstructureRedirectMask, /* ConfigureRequest */
  241. StructureAndSubMask, /* GravityNotify */
  242. ResizeRedirectMask, /* ResizeRequest */
  243. StructureAndSubMask, /* CirculateNotify */
  244. SubstructureRedirectMask, /* CirculateRequest */
  245. PropertyChangeMask, /* PropertyNotify */
  246. CantBeFiltered, /* SelectionClear */
  247. CantBeFiltered, /* SelectionRequest */
  248. CantBeFiltered, /* SelectionNotify */
  249. ColormapChangeMask, /* ColormapNotify */
  250. CantBeFiltered, /* ClientMessage */
  251. CantBeFiltered /* MappingNotify */
  252. };
  253. static CARD8 criticalEvents[32] =
  254. {
  255. 0x7c /* key and button events */
  256. };
  257. #ifdef PANORAMIX
  258. static void ConfineToShape(RegionPtr shape, int *px, int *py);
  259. static void SyntheticMotion(int x, int y);
  260. static void PostNewCursor(void);
  261. static Bool
  262. XineramaSetCursorPosition(
  263. int x,
  264. int y,
  265. Bool generateEvent
  266. ){
  267. ScreenPtr pScreen;
  268. BoxRec box;
  269. int i;
  270. /* x,y are in Screen 0 coordinates. We need to decide what Screen
  271. to send the message too and what the coordinates relative to
  272. that screen are. */
  273. pScreen = sprite.screen;
  274. x += panoramiXdataPtr[0].x;
  275. y += panoramiXdataPtr[0].y;
  276. if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
  277. x, y, &box))
  278. {
  279. FOR_NSCREENS(i)
  280. {
  281. if(i == pScreen->myNum)
  282. continue;
  283. if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
  284. {
  285. pScreen = screenInfo.screens[i];
  286. break;
  287. }
  288. }
  289. }
  290. sprite.screen = pScreen;
  291. sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
  292. sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
  293. x -= panoramiXdataPtr[pScreen->myNum].x;
  294. y -= panoramiXdataPtr[pScreen->myNum].y;
  295. return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
  296. }
  297. static void
  298. XineramaConstrainCursor(void)
  299. {
  300. ScreenPtr pScreen = sprite.screen;
  301. BoxRec newBox = sprite.physLimits;
  302. /* Translate the constraining box to the screen
  303. the sprite is actually on */
  304. newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
  305. newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
  306. newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
  307. newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
  308. (* pScreen->ConstrainCursor)(pScreen, &newBox);
  309. }
  310. static void
  311. XineramaCheckPhysLimits(
  312. CursorPtr cursor,
  313. Bool generateEvents
  314. ){
  315. HotSpot new;
  316. if (!cursor)
  317. return;
  318. new = sprite.hotPhys;
  319. /* I don't care what the DDX has to say about it */
  320. sprite.physLimits = sprite.hotLimits;
  321. /* constrain the pointer to those limits */
  322. if (new.x < sprite.physLimits.x1)
  323. new.x = sprite.physLimits.x1;
  324. else
  325. if (new.x >= sprite.physLimits.x2)
  326. new.x = sprite.physLimits.x2 - 1;
  327. if (new.y < sprite.physLimits.y1)
  328. new.y = sprite.physLimits.y1;
  329. else
  330. if (new.y >= sprite.physLimits.y2)
  331. new.y = sprite.physLimits.y2 - 1;
  332. if (sprite.hotShape) /* more work if the shape is a mess */
  333. ConfineToShape(sprite.hotShape, &new.x, &new.y);
  334. if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
  335. {
  336. XineramaSetCursorPosition (new.x, new.y, generateEvents);
  337. if (!generateEvents)
  338. SyntheticMotion(new.x, new.y);
  339. }
  340. /* Tell DDX what the limits are */
  341. XineramaConstrainCursor();
  342. }
  343. static Bool
  344. XineramaSetWindowPntrs(WindowPtr pWin)
  345. {
  346. if(pWin == WindowTable[0]) {
  347. memcpy(sprite.windows, WindowTable,
  348. PanoramiXNumScreens*sizeof(WindowPtr));
  349. } else {
  350. PanoramiXRes *win;
  351. int i;
  352. win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
  353. if(!win)
  354. return FALSE;
  355. for(i = 0; i < PanoramiXNumScreens; i++) {
  356. sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
  357. if(!sprite.windows[i]) /* window is being unmapped */
  358. return FALSE;
  359. }
  360. }
  361. return TRUE;
  362. }
  363. static void
  364. XineramaCheckVirtualMotion(
  365. QdEventPtr qe,
  366. WindowPtr pWin
  367. ){
  368. if (qe)
  369. {
  370. sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
  371. sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
  372. sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
  373. pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
  374. NullWindow;
  375. }
  376. if (pWin)
  377. {
  378. int x, y, off_x, off_y, i;
  379. BoxRec lims;
  380. if(!XineramaSetWindowPntrs(pWin))
  381. return;
  382. i = PanoramiXNumScreens - 1;
  383. REGION_COPY(sprite.screen, &sprite.Reg2,
  384. &sprite.windows[i]->borderSize);
  385. off_x = panoramiXdataPtr[i].x;
  386. off_y = panoramiXdataPtr[i].y;
  387. while(i--) {
  388. x = off_x - panoramiXdataPtr[i].x;
  389. y = off_y - panoramiXdataPtr[i].y;
  390. if(x || y)
  391. REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
  392. REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
  393. &sprite.windows[i]->borderSize);
  394. off_x = panoramiXdataPtr[i].x;
  395. off_y = panoramiXdataPtr[i].y;
  396. }
  397. lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
  398. if (sprite.hot.x < lims.x1)
  399. sprite.hot.x = lims.x1;
  400. else if (sprite.hot.x >= lims.x2)
  401. sprite.hot.x = lims.x2 - 1;
  402. if (sprite.hot.y < lims.y1)
  403. sprite.hot.y = lims.y1;
  404. else if (sprite.hot.y >= lims.y2)
  405. sprite.hot.y = lims.y2 - 1;
  406. if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
  407. ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
  408. if (qe)
  409. {
  410. qe->pScreen = sprite.hot.pScreen;
  411. qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
  412. qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
  413. }
  414. }
  415. }
  416. static Bool
  417. XineramaCheckMotion(xEvent *xE)
  418. {
  419. WindowPtr prevSpriteWin = sprite.win;
  420. if (xE && !syncEvents.playingEvents)
  421. {
  422. /* Motion events entering DIX get translated to Screen 0
  423. coordinates. Replayed events have already been
  424. translated since they've entered DIX before */
  425. XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
  426. panoramiXdataPtr[0].x;
  427. XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
  428. panoramiXdataPtr[0].y;
  429. sprite.hot.x = XE_KBPTR.rootX;
  430. sprite.hot.y = XE_KBPTR.rootY;
  431. if (sprite.hot.x < sprite.physLimits.x1)
  432. sprite.hot.x = sprite.physLimits.x1;
  433. else if (sprite.hot.x >= sprite.physLimits.x2)
  434. sprite.hot.x = sprite.physLimits.x2 - 1;
  435. if (sprite.hot.y < sprite.physLimits.y1)
  436. sprite.hot.y = sprite.physLimits.y1;
  437. else if (sprite.hot.y >= sprite.physLimits.y2)
  438. sprite.hot.y = sprite.physLimits.y2 - 1;
  439. if (sprite.hotShape)
  440. ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
  441. sprite.hotPhys = sprite.hot;
  442. if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
  443. (sprite.hotPhys.y != XE_KBPTR.rootY))
  444. {
  445. XineramaSetCursorPosition(
  446. sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
  447. }
  448. XE_KBPTR.rootX = sprite.hot.x;
  449. XE_KBPTR.rootY = sprite.hot.y;
  450. }
  451. sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
  452. if (sprite.win != prevSpriteWin)
  453. {
  454. if (prevSpriteWin != NullWindow) {
  455. if (!xE)
  456. UpdateCurrentTimeIf();
  457. DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
  458. }
  459. PostNewCursor();
  460. return FALSE;
  461. }
  462. return TRUE;
  463. }
  464. static void
  465. XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
  466. {
  467. if (syncEvents.playingEvents)
  468. {
  469. XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
  470. SyntheticMotion(sprite.hot.x, sprite.hot.y);
  471. }
  472. else
  473. {
  474. int x, y, off_x, off_y, i;
  475. if(!XineramaSetWindowPntrs(pWin))
  476. return;
  477. i = PanoramiXNumScreens - 1;
  478. REGION_COPY(sprite.screen, &sprite.Reg1,
  479. &sprite.windows[i]->borderSize);
  480. off_x = panoramiXdataPtr[i].x;
  481. off_y = panoramiXdataPtr[i].y;
  482. while(i--) {
  483. x = off_x - panoramiXdataPtr[i].x;
  484. y = off_y - panoramiXdataPtr[i].y;
  485. if(x || y)
  486. REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
  487. REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
  488. &sprite.windows[i]->borderSize);
  489. off_x = panoramiXdataPtr[i].x;
  490. off_y = panoramiXdataPtr[i].y;
  491. }
  492. sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
  493. if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
  494. sprite.hotShape = &sprite.Reg1;
  495. else
  496. sprite.hotShape = NullRegion;
  497. sprite.confined = FALSE;
  498. sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
  499. XineramaCheckPhysLimits(sprite.current, generateEvents);
  500. }
  501. }
  502. static void
  503. XineramaChangeToCursor(CursorPtr cursor)
  504. {
  505. if (cursor != sprite.current)
  506. {
  507. if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
  508. (sprite.current->bits->yhot != cursor->bits->yhot))
  509. XineramaCheckPhysLimits(cursor, FALSE);
  510. (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
  511. sprite.current = cursor;
  512. }
  513. }
  514. #endif /* PANORAMIX */
  515. void
  516. SetMaskForEvent(mask, event)
  517. Mask mask;
  518. int event;
  519. {
  520. if ((event < LASTEvent) || (event >= 128))
  521. FatalError("SetMaskForEvent: bogus event number");
  522. filters[event] = mask;
  523. }
  524. void
  525. SetCriticalEvent(event)
  526. int event;
  527. {
  528. if (event >= 128)
  529. FatalError("SetCriticalEvent: bogus event number");
  530. criticalEvents[event >> 3] |= 1 << (event & 7);
  531. }
  532. static void
  533. #if NeedFunctionPrototypes
  534. SyntheticMotion(int x, int y)
  535. #else
  536. SyntheticMotion(x, y)
  537. int x, y;
  538. #endif
  539. {
  540. xEvent xE;
  541. #ifdef PANORAMIX
  542. /* Translate back to the sprite screen since processInputProc
  543. will translate from sprite screen to screen 0 upon reentry
  544. to the DIX layer */
  545. if(!noPanoramiXExtension) {
  546. x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
  547. y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
  548. }
  549. #endif
  550. xE.u.keyButtonPointer.rootX = x;
  551. xE.u.keyButtonPointer.rootY = y;
  552. if (syncEvents.playingEvents)
  553. xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
  554. else
  555. xE.u.keyButtonPointer.time = currentTime.milliseconds;
  556. xE.u.u.type = MotionNotify;
  557. (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
  558. }
  559. #ifdef SHAPE
  560. static void
  561. #if NeedFunctionPrototypes
  562. ConfineToShape(RegionPtr shape, int *px, int *py)
  563. #else
  564. ConfineToShape(shape, px, py)
  565. RegionPtr shape;
  566. int *px, *py;
  567. #endif
  568. {
  569. BoxRec box;
  570. int x = *px, y = *py;
  571. int incx = 1, incy = 1;
  572. if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
  573. return;
  574. box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
  575. /* this is rather crude */
  576. do {
  577. x += incx;
  578. if (x >= box.x2)
  579. {
  580. incx = -1;
  581. x = *px - 1;
  582. }
  583. else if (x < box.x1)
  584. {
  585. incx = 1;
  586. x = *px;
  587. y += incy;
  588. if (y >= box.y2)
  589. {
  590. incy = -1;
  591. y = *py - 1;
  592. }
  593. else if (y < box.y1)
  594. return; /* should never get here! */
  595. }
  596. } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
  597. *px = x;
  598. *py = y;
  599. }
  600. #endif
  601. static void
  602. #if NeedFunctionPrototypes
  603. CheckPhysLimits(
  604. CursorPtr cursor,
  605. Bool generateEvents,
  606. Bool confineToScreen,
  607. ScreenPtr pScreen)
  608. #else
  609. CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
  610. CursorPtr cursor;
  611. Bool generateEvents;
  612. Bool confineToScreen;
  613. ScreenPtr pScreen;
  614. #endif
  615. {
  616. HotSpot new;
  617. if (!cursor)
  618. return;
  619. new = sprite.hotPhys;
  620. if (pScreen)
  621. new.pScreen = pScreen;
  622. else
  623. pScreen = new.pScreen;
  624. (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
  625. &sprite.physLimits);
  626. sprite.confined = confineToScreen;
  627. (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
  628. if (new.x < sprite.physLimits.x1)
  629. new.x = sprite.physLimits.x1;
  630. else
  631. if (new.x >= sprite.physLimits.x2)
  632. new.x = sprite.physLimits.x2 - 1;
  633. if (new.y < sprite.physLimits.y1)
  634. new.y = sprite.physLimits.y1;
  635. else
  636. if (new.y >= sprite.physLimits.y2)
  637. new.y = sprite.physLimits.y2 - 1;
  638. #ifdef SHAPE
  639. if (sprite.hotShape)
  640. ConfineToShape(sprite.hotShape, &new.x, &new.y);
  641. #endif
  642. if ((pScreen != sprite.hotPhys.pScreen) ||
  643. (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
  644. {
  645. if (pScreen != sprite.hotPhys.pScreen)
  646. sprite.hotPhys = new;
  647. (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
  648. if (!generateEvents)
  649. SyntheticMotion(new.x, new.y);
  650. }
  651. }
  652. static void
  653. #if NeedFunctionPrototypes
  654. CheckVirtualMotion(
  655. register QdEventPtr qe,
  656. register WindowPtr pWin)
  657. #else
  658. CheckVirtualMotion(qe, pWin)
  659. register QdEventPtr qe;
  660. register WindowPtr pWin;
  661. #endif
  662. {
  663. #ifdef PANORAMIX
  664. if(!noPanoramiXExtension) {
  665. XineramaCheckVirtualMotion(qe, pWin);
  666. return;
  667. }
  668. #endif
  669. if (qe)
  670. {
  671. sprite.hot.pScreen = qe->pScreen;
  672. sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
  673. sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
  674. pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
  675. NullWindow;
  676. }
  677. if (pWin)
  678. {
  679. BoxRec lims;
  680. if (sprite.hot.pScreen != pWin->drawable.pScreen)
  681. {
  682. sprite.hot.pScreen = pWin->drawable.pScreen;
  683. sprite.hot.x = sprite.hot.y = 0;
  684. }
  685. lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
  686. if (sprite.hot.x < lims.x1)
  687. sprite.hot.x = lims.x1;
  688. else if (sprite.hot.x >= lims.x2)
  689. sprite.hot.x = lims.x2 - 1;
  690. if (sprite.hot.y < lims.y1)
  691. sprite.hot.y = lims.y1;
  692. else if (sprite.hot.y >= lims.y2)
  693. sprite.hot.y = lims.y2 - 1;
  694. #ifdef SHAPE
  695. if (wBoundingShape(pWin))
  696. ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
  697. #endif
  698. if (qe)
  699. {
  700. qe->pScreen = sprite.hot.pScreen;
  701. qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
  702. qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
  703. }
  704. }
  705. ROOT = WindowTable[sprite.hot.pScreen->myNum];
  706. }
  707. static void
  708. ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
  709. {
  710. ScreenPtr pScreen = pWin->drawable.pScreen;
  711. #ifdef PANORAMIX
  712. if(!noPanoramiXExtension) {
  713. XineramaConfineCursorToWindow(pWin, generateEvents);
  714. return;
  715. }
  716. #endif
  717. if (syncEvents.playingEvents)
  718. {
  719. CheckVirtualMotion((QdEventPtr)NULL, pWin);
  720. SyntheticMotion(sprite.hot.x, sprite.hot.y);
  721. }
  722. else
  723. {
  724. sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
  725. #ifdef SHAPE
  726. sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
  727. : NullRegion;
  728. #endif
  729. CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
  730. pScreen);
  731. }
  732. }
  733. Bool
  734. PointerConfinedToScreen()
  735. {
  736. return sprite.confined;
  737. }
  738. static void
  739. #if NeedFunctionPrototypes
  740. ChangeToCursor(CursorPtr cursor)
  741. #else
  742. ChangeToCursor(cursor)
  743. CursorPtr cursor;
  744. #endif
  745. {
  746. #ifdef PANORAMIX
  747. if(!noPanoramiXExtension) {
  748. XineramaChangeToCursor(cursor);
  749. return;
  750. }
  751. #endif
  752. if (cursor != sprite.current)
  753. {
  754. if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
  755. (sprite.current->bits->yhot != cursor->bits->yhot))
  756. CheckPhysLimits(cursor, FALSE, sprite.confined,
  757. (ScreenPtr)NULL);
  758. (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
  759. cursor);
  760. sprite.current = cursor;
  761. }
  762. }
  763. /* returns true if b is a descendent of a */
  764. Bool
  765. IsParent(a, b)
  766. register WindowPtr a, b;
  767. {
  768. for (b = b->parent; b; b = b->parent)
  769. if (b == a) return TRUE;
  770. return FALSE;
  771. }
  772. static void
  773. #if NeedFunctionPrototypes
  774. PostNewCursor(void)
  775. #else
  776. PostNewCursor()
  777. #endif
  778. {
  779. register WindowPtr win;
  780. register GrabPtr grab = inputInfo.pointer->grab;
  781. if (syncEvents.playingEvents)
  782. return;
  783. if (grab)
  784. {
  785. if (grab->cursor)
  786. {
  787. ChangeToCursor(grab->cursor);
  788. return;
  789. }
  790. if (IsParent(grab->window, sprite.win))
  791. win = sprite.win;
  792. else
  793. win = grab->window;
  794. }
  795. else
  796. win = sprite.win;
  797. for (; win; win = win->parent)
  798. if (win->optional && win->optional->cursor != NullCursor)
  799. {
  800. ChangeToCursor(win->optional->cursor);
  801. return;
  802. }
  803. }
  804. WindowPtr
  805. GetCurrentRootWindow()
  806. {
  807. return ROOT;
  808. }
  809. WindowPtr
  810. GetSpriteWindow()
  811. {
  812. return sprite.win;
  813. }
  814. CursorPtr
  815. GetSpriteCursor()
  816. {
  817. return sprite.current;
  818. }
  819. void
  820. GetSpritePosition(px, py)
  821. int *px, *py;
  822. {
  823. *px = sprite.hotPhys.x;
  824. *py = sprite.hotPhys.y;
  825. }
  826. #ifdef PANORAMIX
  827. int
  828. XineramaGetCursorScreen()
  829. {
  830. if(!noPanoramiXExtension) {
  831. return sprite.screen->myNum;
  832. } else {
  833. return 0;
  834. }
  835. }
  836. #endif /* PANORAMIX */
  837. #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
  838. static void
  839. #if NeedFunctionPrototypes
  840. MonthChangedOrBadTime(register xEvent *xE)
  841. #else
  842. MonthChangedOrBadTime(xE)
  843. register xEvent *xE;
  844. #endif
  845. {
  846. /* If the ddx/OS is careless about not processing timestamped events from
  847. * different sources in sorted order, then it's possible for time to go
  848. * backwards when it should not. Here we ensure a decent time.
  849. */
  850. if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
  851. currentTime.months++;
  852. else
  853. XE_KBPTR.time = currentTime.milliseconds;
  854. }
  855. #define NoticeTime(xE) { \
  856. if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
  857. MonthChangedOrBadTime(xE); \
  858. currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
  859. lastDeviceEventTime = currentTime; }
  860. void
  861. NoticeEventTime(xE)
  862. register xEvent *xE;
  863. {
  864. if (!syncEvents.playingEvents)
  865. NoticeTime(xE);
  866. }
  867. /**************************************************************************
  868. * The following procedures deal with synchronous events *
  869. **************************************************************************/
  870. void
  871. EnqueueEvent(xE, device, count)
  872. xEvent *xE;
  873. DeviceIntPtr device;
  874. int count;
  875. {
  876. register QdEventPtr tail = *syncEvents.pendtail;
  877. register QdEventPtr qe;
  878. xEvent *qxE;
  879. NoticeTime(xE);
  880. if (DeviceEventCallback)
  881. {
  882. DeviceEventInfoRec eventinfo;
  883. /* The RECORD spec says that the root window field of motion events
  884. * must be valid. At this point, it hasn't been filled in yet, so
  885. * we do it here. The long expression below is necessary to get
  886. * the current root window; the apparently reasonable alternative
  887. * GetCurrentRootWindow()->drawable.id doesn't give you the right
  888. * answer on the first motion event after a screen change because
  889. * the data that GetCurrentRootWindow relies on hasn't been
  890. * updated yet.
  891. */
  892. if (xE->u.u.type == MotionNotify)
  893. XE_KBPTR.root =
  894. WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
  895. eventinfo.events = xE;
  896. eventinfo.count = count;
  897. CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
  898. }
  899. if (xE->u.u.type == MotionNotify)
  900. {
  901. #ifdef PANORAMIX
  902. if(!noPanoramiXExtension) {
  903. XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
  904. panoramiXdataPtr[0].x;
  905. XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
  906. panoramiXdataPtr[0].y;
  907. }
  908. #endif
  909. sprite.hotPhys.x = XE_KBPTR.rootX;
  910. sprite.hotPhys.y = XE_KBPTR.rootY;
  911. /* do motion compression */
  912. if (tail &&
  913. (tail->event->u.u.type == MotionNotify) &&
  914. (tail->pScreen == sprite.hotPhys.pScreen))
  915. {
  916. tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
  917. tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
  918. tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
  919. tail->months = currentTime.months;
  920. return;
  921. }
  922. }
  923. qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
  924. if (!qe)
  925. return;
  926. qe->next = (QdEventPtr)NULL;
  927. qe->device = device;
  928. qe->pScreen = sprite.hotPhys.pScreen;
  929. qe->months = currentTime.months;
  930. qe->event = (xEvent *)(qe + 1);
  931. qe->evcount = count;
  932. for (qxE = qe->event; --count >= 0; qxE++, xE++)
  933. *qxE = *xE;
  934. if (tail)
  935. syncEvents.pendtail = &tail->next;
  936. *syncEvents.pendtail = qe;
  937. }
  938. static void
  939. #if NeedFunctionPrototypes
  940. PlayReleasedEvents(void)
  941. #else
  942. PlayReleasedEvents()
  943. #endif
  944. {
  945. register QdEventPtr *prev, qe;
  946. register DeviceIntPtr dev;
  947. prev = &syncEvents.pending;
  948. while ( (qe = *prev) )
  949. {
  950. if (!qe->device->sync.frozen)
  951. {
  952. *prev = qe->next;
  953. if (*syncEvents.pendtail == *prev)
  954. syncEvents.pendtail = prev;
  955. if (qe->event->u.u.type == MotionNotify)
  956. CheckVirtualMotion(qe, NullWindow);
  957. syncEvents.time.months = qe->months;
  958. syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
  959. #ifdef PANORAMIX
  960. /* Translate back to the sprite screen since processInputProc
  961. will translate from sprite screen to screen 0 upon reentry
  962. to the DIX layer */
  963. if(!noPanoramiXExtension) {
  964. qe->event->u.keyButtonPointer.rootX +=
  965. panoramiXdataPtr[0].x -
  966. panoramiXdataPtr[sprite.screen->myNum].x;
  967. qe->event->u.keyButtonPointer.rootY +=
  968. panoramiXdataPtr[0].y -
  969. panoramiXdataPtr[sprite.screen->myNum].y;
  970. }
  971. #endif
  972. (*qe->device->public.processInputProc)(qe->event, qe->device,
  973. qe->evcount);
  974. xfree(qe);
  975. for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
  976. ;
  977. if (!dev)
  978. break;
  979. /* Playing the event may have unfrozen another device. */
  980. /* So to play it safe, restart at the head of the queue */
  981. prev = &syncEvents.pending;
  982. }
  983. else
  984. prev = &qe->next;
  985. }
  986. }
  987. static void
  988. #if NeedFunctionPrototypes
  989. FreezeThaw(register DeviceIntPtr dev, Bool frozen)
  990. #else
  991. FreezeThaw(dev, frozen)
  992. register DeviceIntPtr dev;
  993. Bool frozen;
  994. #endif
  995. {
  996. dev->sync.frozen = frozen;
  997. if (frozen)
  998. dev->public.processInputProc = dev->public.enqueueInputProc;
  999. else
  1000. dev->public.processInputProc = dev->public.realInputProc;
  1001. }
  1002. void
  1003. ComputeFreezes()
  1004. {
  1005. register DeviceIntPtr replayDev = syncEvents.replayDev;
  1006. register int i;
  1007. WindowPtr w;
  1008. register xEvent *xE;
  1009. int count;
  1010. GrabPtr grab;
  1011. register DeviceIntPtr dev;
  1012. for (dev = inputInfo.devices; dev; dev = dev->next)
  1013. FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
  1014. if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
  1015. return;
  1016. syncEvents.playingEvents = TRUE;
  1017. if (replayDev)
  1018. {
  1019. xE = replayDev->sync.event;
  1020. count = replayDev->sync.evcount;
  1021. syncEvents.replayDev = (DeviceIntPtr)NULL;
  1022. w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
  1023. for (i = 0; i < spriteTraceGood; i++)
  1024. {
  1025. if (syncEvents.replayWin == spriteTrace[i])
  1026. {
  1027. if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
  1028. if (replayDev->focus)
  1029. DeliverFocusedEvent(replayDev, xE, w, count);
  1030. else
  1031. DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
  1032. replayDev, count);
  1033. }
  1034. goto playmore;
  1035. }
  1036. }
  1037. /* must not still be in the same stack */
  1038. if (replayDev->focus)
  1039. DeliverFocusedEvent(replayDev, xE, w, count);
  1040. else
  1041. DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
  1042. }
  1043. playmore:
  1044. for (dev = inputInfo.devices; dev; dev = dev->next)
  1045. {
  1046. if (!dev->sync.frozen)
  1047. {
  1048. PlayReleasedEvents();
  1049. break;
  1050. }
  1051. }
  1052. syncEvents.playingEvents = FALSE;
  1053. /* the following may have been skipped during replay, so do it now */
  1054. if ((grab = inputInfo.pointer->grab) && grab->confineTo)
  1055. {
  1056. if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  1057. sprite.hotPhys.x = sprite.hotPhys.y = 0;
  1058. ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
  1059. }
  1060. else
  1061. ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
  1062. TRUE, FALSE);
  1063. PostNewCursor();
  1064. }
  1065. #ifdef RANDR
  1066. void
  1067. ScreenRestructured (ScreenPtr pScreen)
  1068. {
  1069. GrabPtr grab;
  1070. if ((grab = inputInfo.pointer->grab) && grab->confineTo)
  1071. {
  1072. if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  1073. sprite.hotPhys.x = sprite.hotPhys.y = 0;
  1074. ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
  1075. }
  1076. else
  1077. ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
  1078. TRUE, FALSE);
  1079. }
  1080. #endif
  1081. void
  1082. CheckGrabForSyncs(thisDev, thisMode, otherMode)
  1083. register DeviceIntPtr thisDev;
  1084. Bool thisMode, otherMode;
  1085. {
  1086. register GrabPtr grab = thisDev->grab;
  1087. register DeviceIntPtr dev;
  1088. if (thisMode == GrabModeSync)
  1089. thisDev->sync.state = FROZEN_NO_EVENT;
  1090. else
  1091. { /* free both if same client owns both */
  1092. thisDev->sync.state = THAWED;
  1093. if (thisDev->sync.other &&
  1094. (CLIENT_BITS(thisDev->sync.other->resource) ==
  1095. CLIENT_BITS(grab->resource)))
  1096. thisDev->sync.other = NullGrab;
  1097. }
  1098. for (dev = inputInfo.devices; dev; dev = dev->next)
  1099. {
  1100. if (dev != thisDev)
  1101. {
  1102. if (otherMode == GrabModeSync)
  1103. dev->sync.other = grab;
  1104. else
  1105. { /* free both if same client owns both */
  1106. if (dev->sync.other &&
  1107. (CLIENT_BITS(dev->sync.other->resource) ==
  1108. CLIENT_BITS(grab->resource)))
  1109. dev->sync.other = NullGrab;
  1110. }
  1111. }
  1112. }
  1113. ComputeFreezes();
  1114. }
  1115. void
  1116. ActivatePointerGrab(mouse, grab, time, autoGrab)
  1117. register GrabPtr grab;
  1118. register DeviceIntPtr mouse;
  1119. TimeStamp time;
  1120. Bool autoGrab;
  1121. {
  1122. WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
  1123. : sprite.win;
  1124. if (grab->confineTo)
  1125. {
  1126. if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  1127. sprite.hotPhys.x = sprite.hotPhys.y = 0;
  1128. ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
  1129. }
  1130. DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
  1131. mouse->valuator->motionHintWindow = NullWindow;
  1132. if (syncEvents.playingEvents)
  1133. mouse->grabTime = syncEvents.time;
  1134. else
  1135. mouse->grabTime = time;
  1136. if (grab->cursor)
  1137. grab->cursor->refcnt++;
  1138. mouse->activeGrab = *grab;
  1139. mouse->grab = &mouse->activeGrab;
  1140. mouse->fromPassiveGrab = autoGrab;
  1141. PostNewCursor();
  1142. CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
  1143. #ifdef NXAGENT_SERVER
  1144. /*
  1145. * If grab is synchronous, events are delivered to clients only if they send
  1146. * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the
  1147. * delivered event is saved in a queue and replayed later, when grab is released.
  1148. * We should export sync grab to X as async in order to avoid events to be
  1149. * queued twice, in the agent and in the X server. This solution have a drawback:
  1150. * replayed events are not delivered to that application that are not clients of
  1151. * the agent.
  1152. * A different solution could be to make the grab asynchronous in the agent and
  1153. * to export it as synchronous. But this seems to be less safe.
  1154. *
  1155. * To make internal grab asynchronous, change previous line as follows.
  1156. *
  1157. * if (nxagentOption(Rootless))
  1158. * {
  1159. * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
  1160. * }
  1161. * else
  1162. * {
  1163. * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
  1164. * }
  1165. */
  1166. if (nxagentOption(Rootless) == 1)
  1167. {
  1168. /*
  1169. * FIXME: We should use the correct value
  1170. * for the cursor. Temporarily we set it
  1171. * to None.
  1172. */
  1173. int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
  1174. nxagentCollectGrabPointerPredicate);
  1175. NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
  1176. 1, grab -> eventMask & PointerGrabMask,
  1177. GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
  1178. nxagentWindow(grab -> confineTo) : None,
  1179. None, CurrentTime);
  1180. }
  1181. #endif
  1182. }
  1183. void
  1184. DeactivatePointerGrab(mouse)
  1185. register DeviceIntPtr mouse;
  1186. {
  1187. register GrabPtr grab = mouse->grab;
  1188. register DeviceIntPtr dev;
  1189. mouse->valuator->motionHintWindow = NullWindow;
  1190. mouse->grab = NullGrab;
  1191. mouse->sync.state = NOT_GRABBED;
  1192. mouse->fromPassiveGrab = FALSE;
  1193. for (dev = inputInfo.devices; dev; dev = dev->next)
  1194. {
  1195. if (dev->sync.other == grab)
  1196. dev->sync.other = NullGrab;
  1197. }
  1198. DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
  1199. if (grab->confineTo)
  1200. ConfineCursorToWindow(ROOT, FALSE, FALSE);
  1201. PostNewCursor();
  1202. if (grab->cursor)
  1203. FreeCursor(grab->cursor, (Cursor)0);
  1204. ComputeFreezes();
  1205. #ifdef NXAGENT_SERVER
  1206. if (nxagentOption(Rootless) == 1)
  1207. {
  1208. XUngrabPointer(nxagentDisplay, CurrentTime);
  1209. if (sprite.win == ROOT)
  1210. {
  1211. mouse -> button -> state &=
  1212. ~(Button1Mask | Button2Mask | Button3Mask |
  1213. Button4Mask | Button5Mask);
  1214. }
  1215. }
  1216. #endif
  1217. }
  1218. void
  1219. ActivateKeyboardGrab(keybd, grab, time, passive)
  1220. register DeviceIntPtr keybd;
  1221. GrabPtr grab;
  1222. TimeStamp time;
  1223. Bool passive;
  1224. {
  1225. WindowPtr oldWin;
  1226. if (keybd->grab)
  1227. oldWin = keybd->grab->window;
  1228. else if (keybd->focus)
  1229. oldWin = keybd->focus->win;
  1230. else
  1231. oldWin = sprite.win;
  1232. if (oldWin == FollowKeyboardWin)
  1233. oldWin = inputInfo.keyboard->focus->win;
  1234. if (keybd->valuator)
  1235. keybd->valuator->motionHintWindow = NullWindow;
  1236. DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
  1237. if (syncEvents.playingEvents)
  1238. keybd->grabTime = syncEvents.time;
  1239. else
  1240. keybd->grabTime = time;
  1241. keybd->activeGrab = *grab;
  1242. keybd->grab = &keybd->activeGrab;
  1243. keybd->fromPassiveGrab = passive;
  1244. CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
  1245. }
  1246. void
  1247. DeactivateKeyboardGrab(keybd)
  1248. register DeviceIntPtr keybd;
  1249. {
  1250. register GrabPtr grab = keybd->grab;
  1251. register DeviceIntPtr dev;
  1252. register WindowPtr focusWin = keybd->focus ? keybd->focus->win
  1253. : sprite.win;
  1254. if (focusWin == FollowKeyboardWin)
  1255. focusWin = inputInfo.keyboard->focus->win;
  1256. if (keybd->valuator)
  1257. keybd->valuator->motionHintWindow = NullWindow;
  1258. keybd->grab = NullGrab;
  1259. keybd->sync.state = NOT_GRABBED;
  1260. keybd->fromPassiveGrab = FALSE;
  1261. for (dev = inputInfo.devices; dev; dev = dev->next)
  1262. {
  1263. if (dev->sync.other == grab)
  1264. dev->sync.other = NullGrab;
  1265. }
  1266. DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
  1267. ComputeFreezes();
  1268. }
  1269. void
  1270. AllowSome(client, time, thisDev, newState)
  1271. ClientPtr client;
  1272. TimeStamp time;
  1273. register DeviceIntPtr thisDev;
  1274. int newState;
  1275. {
  1276. Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
  1277. TimeStamp grabTime;
  1278. register DeviceIntPtr dev;
  1279. thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
  1280. thisSynced = FALSE;
  1281. otherGrabbed = FALSE;
  1282. othersFrozen = TRUE;
  1283. grabTime = thisDev->grabTime;
  1284. for (dev = inputInfo.devices; dev; dev = dev->next)
  1285. {
  1286. if (dev == thisDev)
  1287. continue;
  1288. if (dev->grab && SameClient(dev->grab, client))
  1289. {
  1290. if (!(thisGrabbed || otherGrabbed) ||
  1291. (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
  1292. grabTime = dev->grabTime;
  1293. otherGrabbed = TRUE;
  1294. if (thisDev->sync.other == dev->grab)
  1295. thisSynced = TRUE;
  1296. if (dev->sync.state < FROZEN)
  1297. othersFrozen = FALSE;
  1298. }
  1299. else if (!dev->sync.other || !SameClient(dev->sync.other, client))
  1300. othersFrozen = FALSE;
  1301. }
  1302. if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
  1303. return;
  1304. if ((CompareTimeStamps(time, currentTime) == LATER) ||
  1305. (CompareTimeStamps(time, grabTime) == EARLIER))
  1306. return;
  1307. switch (newState)
  1308. {
  1309. case THAWED: /* Async */
  1310. if (thisGrabbed)
  1311. thisDev->sync.state = THAWED;
  1312. if (thisSynced)
  1313. thisDev->sync.other = NullGrab;
  1314. ComputeFreezes();
  1315. break;
  1316. case FREEZE_NEXT_EVENT: /* Sync */
  1317. if (thisGrabbed)
  1318. {
  1319. thisDev->sync.state = FREEZE_NEXT_EVENT;
  1320. if (thisSynced)
  1321. thisDev->sync.other = NullGrab;
  1322. ComputeFreezes();
  1323. }
  1324. break;
  1325. case THAWED_BOTH: /* AsyncBoth */
  1326. if (othersFrozen)
  1327. {
  1328. for (dev = inputInfo.devices; dev; dev = dev->next)
  1329. {
  1330. if (dev->grab && SameClient(dev->grab, client))
  1331. dev->sync.state = THAWED;
  1332. if (dev->sync.other && SameClient(dev->sync.other, client))
  1333. dev->sync.other = NullGrab;
  1334. }
  1335. ComputeFreezes();
  1336. }
  1337. break;
  1338. case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
  1339. if (othersFrozen)
  1340. {
  1341. for (dev = inputInfo.devices; dev; dev = dev->next)
  1342. {
  1343. if (dev->grab && SameClient(dev->grab, client))
  1344. dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
  1345. if (dev->sync.other && SameClient(dev->sync.other, client))
  1346. dev->sync.other = NullGrab;
  1347. }
  1348. ComputeFreezes();
  1349. }
  1350. break;
  1351. case NOT_GRABBED: /* Replay */
  1352. if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
  1353. {
  1354. if (thisSynced)
  1355. thisDev->sync.other = NullGrab;
  1356. syncEvents.replayDev = thisDev;
  1357. syncEvents.replayWin = thisDev->grab->window;
  1358. (*thisDev->DeactivateGrab)(thisDev);
  1359. syncEvents.replayDev = (DeviceIntPtr)NULL;
  1360. }
  1361. break;
  1362. case THAW_OTHERS: /* AsyncOthers */
  1363. if (othersFrozen)
  1364. {
  1365. for (dev = inputInfo.devices; dev; dev = dev->next)
  1366. {
  1367. if (dev == thisDev)
  1368. continue;
  1369. if (dev->grab && SameClient(dev->grab, client))
  1370. dev->sync.state = THAWED;
  1371. if (dev->sync.other && SameClient(dev->sync.other, client))
  1372. dev->sync.other = NullGrab;
  1373. }
  1374. ComputeFreezes();
  1375. }
  1376. break;
  1377. }
  1378. }
  1379. int
  1380. ProcAllowEvents(client)
  1381. register ClientPtr client;
  1382. {
  1383. TimeStamp time;
  1384. DeviceIntPtr mouse = inputInfo.pointer;
  1385. DeviceIntPtr keybd = inputInfo.keyboard;
  1386. REQUEST(xAllowEventsReq);
  1387. REQUEST_SIZE_MATCH(xAllowEventsReq);
  1388. time = ClientTimeToServerTime(stuff->time);
  1389. switch (stuff->mode)
  1390. {
  1391. case ReplayPointer:
  1392. AllowSome(client, time, mouse, NOT_GRABBED);
  1393. break;
  1394. case SyncPointer:
  1395. AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
  1396. break;
  1397. case AsyncPointer:
  1398. AllowSome(client, time, mouse, THAWED);
  1399. break;
  1400. case ReplayKeyboard:
  1401. AllowSome(client, time, keybd, NOT_GRABBED);
  1402. break;
  1403. case SyncKeyboard:
  1404. AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
  1405. break;
  1406. case AsyncKeyboard:
  1407. AllowSome(client, time, keybd, THAWED);
  1408. break;
  1409. case SyncBoth:
  1410. AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
  1411. break;
  1412. case AsyncBoth:
  1413. AllowSome(client, time, keybd, THAWED_BOTH);
  1414. break;
  1415. default:
  1416. client->errorValue = stuff->mode;
  1417. return BadValue;
  1418. }
  1419. /*
  1420. * This is not necessary if we export grab to X as asynchronous.
  1421. *
  1422. * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
  1423. * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
  1424. * {
  1425. * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
  1426. * }
  1427. */
  1428. return Success;
  1429. }
  1430. void
  1431. ReleaseActiveGrabs(client)
  1432. ClientPtr client;
  1433. {
  1434. register DeviceIntPtr dev;
  1435. Bool done;
  1436. /* XXX CloseDownClient should remove passive grabs before
  1437. * releasing active grabs.
  1438. */
  1439. do {
  1440. done = TRUE;
  1441. for (dev = inputInfo.devices; dev; dev = dev->next)
  1442. {
  1443. if (dev->grab && SameClient(dev->grab, client))
  1444. {
  1445. (*dev->DeactivateGrab)(dev);
  1446. done = FALSE;
  1447. }
  1448. }
  1449. } while (!done);
  1450. }
  1451. /**************************************************************************
  1452. * The following procedures deal with delivering events *
  1453. **************************************************************************/
  1454. int
  1455. TryClientEvents (client, pEvents, count, mask, filter, grab)
  1456. ClientPtr client;
  1457. GrabPtr grab;
  1458. xEvent *pEvents;
  1459. int count;
  1460. Mask mask, filter;
  1461. {
  1462. int i;
  1463. int type;
  1464. #ifdef DEBUG
  1465. if (debug_events) ErrorF(
  1466. "Event([%d, %d], mask=0x%x), client=%d",
  1467. pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
  1468. #endif
  1469. if ((client) && (client != serverClient) && (!client->clientGone) &&
  1470. ((filter == CantBeFiltered) || (mask & filter)))
  1471. {
  1472. if (grab && !SameClient(grab, client))
  1473. return -1; /* don't send, but notify caller */
  1474. type = pEvents->u.u.type;
  1475. if (type == MotionNotify)
  1476. {
  1477. if (mask & PointerMotionHintMask)
  1478. {
  1479. if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
  1480. pEvents->u.keyButtonPointer.event)
  1481. {
  1482. #ifdef DEBUG
  1483. if (debug_events) ErrorF("\n");
  1484. fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
  1485. #endif
  1486. return 1; /* don't send, but pretend we did */
  1487. }
  1488. pEvents->u.u.detail = NotifyHint;
  1489. }
  1490. else
  1491. {
  1492. pEvents->u.u.detail = NotifyNormal;
  1493. }
  1494. }
  1495. #ifdef XINPUT
  1496. else
  1497. {
  1498. if ((type == DeviceMotionNotify) &&
  1499. MaybeSendDeviceMotionNotifyHint
  1500. ((deviceKeyButtonPointer*)pEvents, mask) != 0)
  1501. return 1;
  1502. }
  1503. #endif
  1504. type &= 0177;
  1505. if (type != KeymapNotify)
  1506. {
  1507. /* all extension events must have a sequence number */
  1508. for (i = 0; i < count; i++)
  1509. pEvents[i].u.u.sequenceNumber = client->sequence;
  1510. }
  1511. if (BitIsOn(criticalEvents, type))
  1512. {
  1513. #ifdef SMART_SCHEDULE
  1514. if (client->smart_priority < SMART_MAX_PRIORITY)
  1515. client->smart_priority++;
  1516. #endif
  1517. SetCriticalOutputPending();
  1518. }
  1519. WriteEventsToClient(client, count, pEvents);
  1520. #ifdef DEBUG
  1521. if (debug_events) ErrorF( " delivered\n");
  1522. #endif
  1523. return 1;
  1524. }
  1525. else
  1526. {
  1527. #ifdef DEBUG
  1528. if (debug_events) ErrorF("\n");
  1529. #endif
  1530. return 0;
  1531. }
  1532. }
  1533. int
  1534. DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
  1535. register WindowPtr pWin;
  1536. GrabPtr grab;
  1537. xEvent *pEvents;
  1538. int count;
  1539. Mask filter;
  1540. int mskidx;
  1541. {
  1542. int deliveries = 0, nondeliveries = 0;
  1543. int attempt;
  1544. register InputClients *other;
  1545. ClientPtr client = NullClient;
  1546. Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
  1547. this mask is the mask of the grab. */
  1548. int type = pEvents->u.u.type;
  1549. /* CantBeFiltered means only window owner gets the event */
  1550. if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
  1551. {
  1552. /* if nobody ever wants to see this event, skip some work */
  1553. if (filter != CantBeFiltered &&
  1554. !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
  1555. return 0;
  1556. if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
  1557. pWin->eventMask, filter, grab)) )
  1558. {
  1559. if (attempt > 0)
  1560. {
  1561. deliveries++;
  1562. client = wClient(pWin);
  1563. deliveryMask = pWin->eventMask;
  1564. } else
  1565. nondeliveries--;
  1566. }
  1567. }
  1568. if (filter != CantBeFiltered)
  1569. {
  1570. if (type & EXTENSION_EVENT_BASE)
  1571. {
  1572. OtherInputMasks *inputMasks;
  1573. inputMasks = wOtherInputMasks(pWin);
  1574. if (!inputMasks ||
  1575. !(inputMasks->inputEvents[mskidx] & filter))
  1576. return 0;
  1577. other = inputMasks->inputClients;
  1578. }
  1579. else
  1580. other = (InputClients *)wOtherClients(pWin);
  1581. for (; other; other = other->next)
  1582. {
  1583. if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
  1584. other->mask[mskidx], filter, grab)) )
  1585. {
  1586. if (attempt > 0)
  1587. {
  1588. deliveries++;
  1589. client = rClient(other);
  1590. deliveryMask = other->mask[mskidx];
  1591. } else
  1592. nondeliveries--;
  1593. }
  1594. }
  1595. }
  1596. if ((type == ButtonPress) && deliveries && (!grab))
  1597. {
  1598. GrabRec tempGrab;
  1599. tempGrab.device = inputInfo.pointer;
  1600. tempGrab.resource = client->clientAsMask;
  1601. tempGrab.window = pWin;
  1602. tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
  1603. tempGrab.eventMask = deliveryMask;
  1604. tempGrab.keyboardMode = GrabModeAsync;
  1605. tempGrab.pointerMode = GrabModeAsync;
  1606. tempGrab.confineTo = NullWindow;
  1607. tempGrab.cursor = NullCursor;
  1608. (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
  1609. currentTime, TRUE);
  1610. }
  1611. else if ((type == MotionNotify) && deliveries)
  1612. inputInfo.pointer->valuator->motionHintWindow = pWin;
  1613. #ifdef XINPUT
  1614. else
  1615. {
  1616. if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
  1617. deliveries)
  1618. CheckDeviceGrabAndHintWindow (pWin, type,
  1619. (deviceKeyButtonPointer*) pEvents,
  1620. grab, client, deliveryMask);
  1621. }
  1622. #endif
  1623. if (deliveries)
  1624. return deliveries;
  1625. return nondeliveries;
  1626. }
  1627. /* If the event goes to dontClient, don't send it and return 0. if
  1628. send works, return 1 or if send didn't work, return 2.
  1629. Only works for core events.
  1630. */
  1631. #ifdef PANORAMIX
  1632. static int
  1633. XineramaTryClientEventsResult(
  1634. ClientPtr client,
  1635. GrabPtr grab,
  1636. Mask mask,
  1637. Mask filter
  1638. ){
  1639. if ((client) && (client != serverClient) && (!client->clientGone) &&
  1640. ((filter == CantBeFiltered) || (mask & filter)))
  1641. {
  1642. if (grab && !SameClient(grab, client)) return -1;
  1643. else return 1;
  1644. }
  1645. return 0;
  1646. }
  1647. #endif
  1648. int
  1649. MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
  1650. register WindowPtr pWin;
  1651. xEvent *pEvents;
  1652. int count;
  1653. Mask filter;
  1654. ClientPtr dontClient;
  1655. {
  1656. register OtherClients *other;
  1657. if (pWin->eventMask & filter)
  1658. {
  1659. if (wClient(pWin) == dontClient)
  1660. return 0;
  1661. #ifdef PANORAMIX
  1662. if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
  1663. return XineramaTryClientEventsResult(
  1664. wClient(pWin), NullGrab, pWin->eventMask, filter);
  1665. #endif
  1666. return TryClientEvents(wClient(pWin), pEvents, count,
  1667. pWin->eventMask, filter, NullGrab);
  1668. }
  1669. for (other = wOtherClients(pWin); other; other = other->next)
  1670. {
  1671. if (other->mask & filter)
  1672. {
  1673. if (SameClient(other, dontClient))
  1674. return 0;
  1675. #ifdef PANORAMIX
  1676. if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
  1677. return XineramaTryClientEventsResult(
  1678. rClient(other), NullGrab, other->mask, filter);
  1679. #endif
  1680. return TryClientEvents(rClient(other), pEvents, count,
  1681. other->mask, filter, NullGrab);
  1682. }
  1683. }
  1684. return 2;
  1685. }
  1686. static void
  1687. #if NeedFunctionPrototypes
  1688. FixUpEventFromWindow(
  1689. xEvent *xE,
  1690. WindowPtr pWin,
  1691. Window child,
  1692. Bool calcChild)
  1693. #else
  1694. FixUpEventFromWindow(xE, pWin, child, calcChild)
  1695. xEvent *xE;
  1696. WindowPtr pWin;
  1697. Window child;
  1698. Bool calcChild;
  1699. #endif
  1700. {
  1701. if (calcChild)
  1702. {
  1703. WindowPtr w=spriteTrace[spriteTraceGood-1];
  1704. /* If the search ends up past the root should the child field be
  1705. set to none or should the value in the argument be passed
  1706. through. It probably doesn't matter since everyone calls
  1707. this function with child == None anyway. */
  1708. while (w)
  1709. {
  1710. /* If the source window is same as event window, child should be
  1711. none. Don't bother going all all the way back to the root. */
  1712. if (w == pWin)
  1713. {
  1714. child = None;
  1715. break;
  1716. }
  1717. if (w->parent == pWin)
  1718. {
  1719. child = w->drawable.id;
  1720. break;
  1721. }
  1722. w = w->parent;
  1723. }
  1724. }
  1725. XE_KBPTR.root = ROOT->drawable.id;
  1726. XE_KBPTR.event = pWin->drawable.id;
  1727. if (sprite.hot.pScreen == pWin->drawable.pScreen)
  1728. {
  1729. XE_KBPTR.sameScreen = xTrue;
  1730. XE_KBPTR.child = child;
  1731. XE_KBPTR.eventX =
  1732. XE_KBPTR.rootX - pWin->drawable.x;
  1733. XE_KBPTR.eventY =
  1734. XE_KBPTR.rootY - pWin->drawable.y;
  1735. }
  1736. else
  1737. {
  1738. XE_KBPTR.sameScreen = xFalse;
  1739. XE_KBPTR.child = None;
  1740. XE_KBPTR.eventX = 0;
  1741. XE_KBPTR.eventY = 0;
  1742. }
  1743. }
  1744. int
  1745. DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
  1746. register WindowPtr pWin, stopAt;
  1747. register xEvent *xE;
  1748. GrabPtr grab;
  1749. DeviceIntPtr dev;
  1750. int count;
  1751. {
  1752. Window child = None;
  1753. int type = xE->u.u.type;
  1754. Mask filter = filters[type];
  1755. int deliveries = 0;
  1756. if (type & EXTENSION_EVENT_BASE)
  1757. {
  1758. register OtherInputMasks *inputMasks;
  1759. int mskidx = dev->id;
  1760. inputMasks = wOtherInputMasks(pWin);
  1761. if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
  1762. return 0;
  1763. while (pWin)
  1764. {
  1765. if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
  1766. {
  1767. FixUpEventFromWindow(xE, pWin, child, FALSE);
  1768. deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1769. grab, mskidx);
  1770. if (deliveries > 0)
  1771. return deliveries;
  1772. }
  1773. if ((deliveries < 0) ||
  1774. (pWin == stopAt) ||
  1775. (inputMasks &&
  1776. (filter & inputMasks->dontPropagateMask[mskidx])))
  1777. return 0;
  1778. child = pWin->drawable.id;
  1779. pWin = pWin->parent;
  1780. if (pWin)
  1781. inputMasks = wOtherInputMasks(pWin);
  1782. }
  1783. }
  1784. else
  1785. {
  1786. if (!(filter & pWin->deliverableEvents))
  1787. return 0;
  1788. while (pWin)
  1789. {
  1790. if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
  1791. {
  1792. FixUpEventFromWindow(xE, pWin, child, FALSE);
  1793. deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1794. grab, 0);
  1795. if (deliveries > 0)
  1796. return deliveries;
  1797. }
  1798. if ((deliveries < 0) ||
  1799. (pWin == stopAt) ||
  1800. (filter & wDontPropagateMask(pWin)))
  1801. return 0;
  1802. child = pWin->drawable.id;
  1803. pWin = pWin->parent;
  1804. }
  1805. }
  1806. return 0;
  1807. }
  1808. /* not useful for events that propagate up the tree or extension events */
  1809. int
  1810. DeliverEvents(pWin, xE, count, otherParent)
  1811. register WindowPtr pWin, otherParent;
  1812. register xEvent *xE;
  1813. int count;
  1814. {
  1815. Mask filter;
  1816. int deliveries;
  1817. #ifdef PANORAMIX
  1818. if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
  1819. return count;
  1820. #endif
  1821. if (!count)
  1822. return 0;
  1823. filter = filters[xE->u.u.type];
  1824. if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
  1825. xE->u.destroyNotify.event = pWin->drawable.id;
  1826. if (filter != StructureAndSubMask)
  1827. return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
  1828. deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
  1829. NullGrab, 0);
  1830. if (pWin->parent)
  1831. {
  1832. xE->u.destroyNotify.event = pWin->parent->drawable.id;
  1833. deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
  1834. SubstructureNotifyMask, NullGrab,
  1835. 0);
  1836. if (xE->u.u.type == ReparentNotify)
  1837. {
  1838. xE->u.destroyNotify.event = otherParent->drawable.id;
  1839. deliveries += DeliverEventsToWindow(otherParent, xE, count,
  1840. SubstructureNotifyMask,
  1841. NullGrab, 0);
  1842. }
  1843. }
  1844. return deliveries;
  1845. }
  1846. static Bool
  1847. PointInBorderSize(WindowPtr pWin, int x, int y)
  1848. {
  1849. BoxRec box;
  1850. if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
  1851. return TRUE;
  1852. #ifdef PANORAMIX
  1853. if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
  1854. int i;
  1855. for(i = 1; i < PanoramiXNumScreens; i++) {
  1856. if(POINT_IN_REGION(sprite.screen,
  1857. &sprite.windows[i]->borderSize,
  1858. x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
  1859. y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
  1860. &box))
  1861. return TRUE;
  1862. }
  1863. }
  1864. #endif
  1865. return FALSE;
  1866. }
  1867. static WindowPtr
  1868. #if NeedFunctionPrototypes
  1869. XYToWindow(int x, int y)
  1870. #else
  1871. XYToWindow(x, y)
  1872. int x, y;
  1873. #endif
  1874. {
  1875. register WindowPtr pWin;
  1876. spriteTraceGood = 1; /* root window still there */
  1877. if (nxagentOption(Rootless))
  1878. {
  1879. if (nxagentLastEnteredWindow == NULL)
  1880. {
  1881. return ROOT;
  1882. }
  1883. pWin = ROOT->lastChild;
  1884. while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
  1885. {
  1886. pWin = pWin->prevSib;
  1887. }
  1888. }
  1889. else
  1890. {
  1891. pWin = ROOT->firstChild;
  1892. }
  1893. while (pWin)
  1894. {
  1895. if ((pWin->mapped) &&
  1896. (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
  1897. (x < pWin->drawable.x + (int)pWin->drawable.width +
  1898. wBorderWidth(pWin)) &&
  1899. (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
  1900. (y < pWin->drawable.y + (int)pWin->drawable.height +
  1901. wBorderWidth (pWin))
  1902. #ifdef SHAPE
  1903. /* When a window is shaped, a further check
  1904. * is made to see if the point is inside
  1905. * borderSize
  1906. */
  1907. && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
  1908. #endif
  1909. )
  1910. {
  1911. if (spriteTraceGood >= spriteTraceSize)
  1912. {
  1913. spriteTraceSize += 10;
  1914. Must_have_memory = TRUE; /* XXX */
  1915. spriteTrace = (WindowPtr *)xrealloc(
  1916. spriteTrace, spriteTraceSize*sizeof(WindowPtr));
  1917. Must_have_memory = FALSE; /* XXX */
  1918. }
  1919. spriteTrace[spriteTraceGood++] = pWin;
  1920. pWin = pWin->firstChild;
  1921. }
  1922. else
  1923. pWin = pWin->nextSib;
  1924. }
  1925. return spriteTrace[spriteTraceGood-1];
  1926. }
  1927. static Bool
  1928. #if NeedFunctionPrototypes
  1929. CheckMotion(xEvent *xE)
  1930. #else
  1931. CheckMotion(xE)
  1932. xEvent *xE;
  1933. #endif
  1934. {
  1935. WindowPtr prevSpriteWin = sprite.win;
  1936. #ifdef PANORAMIX
  1937. if(!noPanoramiXExtension)
  1938. return XineramaCheckMotion(xE);
  1939. #endif
  1940. if (xE && !syncEvents.playingEvents)
  1941. {
  1942. if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
  1943. {
  1944. sprite.hot.pScreen = sprite.hotPhys.pScreen;
  1945. ROOT = WindowTable[sprite.hot.pScreen->myNum];
  1946. }
  1947. sprite.hot.x = XE_KBPTR.rootX;
  1948. sprite.hot.y = XE_KBPTR.rootY;
  1949. if (sprite.hot.x < sprite.physLimits.x1)
  1950. sprite.hot.x = sprite.physLimits.x1;
  1951. else if (sprite.hot.x >= sprite.physLimits.x2)
  1952. sprite.hot.x = sprite.physLimits.x2 - 1;
  1953. if (sprite.hot.y < sprite.physLimits.y1)
  1954. sprite.hot.y = sprite.physLimits.y1;
  1955. else if (sprite.hot.y >= sprite.physLimits.y2)
  1956. sprite.hot.y = sprite.physLimits.y2 - 1;
  1957. #ifdef SHAPE
  1958. if (sprite.hotShape)
  1959. ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
  1960. #endif
  1961. sprite.hotPhys = sprite.hot;
  1962. /*
  1963. * This code force cursor position to be inside the
  1964. * root window of the agent. We can't view a reason
  1965. * to do this and it interacts in an undesirable way
  1966. * with toggling fullscreen.
  1967. *
  1968. * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
  1969. * (sprite.hotPhys.y != XE_KBPTR.rootY))
  1970. * {
  1971. * (*sprite.hotPhys.pScreen->SetCursorPosition)(
  1972. * sprite.hotPhys.pScreen,
  1973. * sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
  1974. * }
  1975. */
  1976. XE_KBPTR.rootX = sprite.hot.x;
  1977. XE_KBPTR.rootY = sprite.hot.y;
  1978. }
  1979. sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
  1980. #ifdef notyet
  1981. if (!(sprite.win->deliverableEvents &
  1982. Motion_Filter(inputInfo.pointer->button))
  1983. !syncEvents.playingEvents)
  1984. {
  1985. /* XXX Do PointerNonInterestBox here */
  1986. }
  1987. #endif
  1988. if (sprite.win != prevSpriteWin)
  1989. {
  1990. if (prevSpriteWin != NullWindow) {
  1991. if (!xE)
  1992. UpdateCurrentTimeIf();
  1993. DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
  1994. }
  1995. PostNewCursor();
  1996. return FALSE;
  1997. }
  1998. return TRUE;
  1999. }
  2000. void
  2001. WindowsRestructured()
  2002. {
  2003. (void) CheckMotion((xEvent *)NULL);
  2004. }
  2005. void
  2006. DefineInitialRootWindow(win)
  2007. register WindowPtr win;
  2008. {
  2009. register ScreenPtr pScreen = win->drawable.pScreen;
  2010. extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
  2011. extern int nxagentShadowInit(ScreenPtr, WindowPtr);
  2012. sprite.hotPhys.pScreen = pScreen;
  2013. sprite.hotPhys.x = pScreen->width / 2;
  2014. sprite.hotPhys.y = pScreen->height / 2;
  2015. sprite.hot = sprite.hotPhys;
  2016. sprite.hotLimits.x2 = pScreen->width;
  2017. sprite.hotLimits.y2 = pScreen->height;
  2018. sprite.win = win;
  2019. sprite.current = wCursor (win);
  2020. spriteTraceGood = 1;
  2021. ROOT = win;
  2022. (*pScreen->CursorLimits) (
  2023. pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
  2024. sprite.confined = FALSE;
  2025. (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
  2026. (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
  2027. (*pScreen->DisplayCursor) (pScreen, sprite.current);
  2028. #ifdef PANORAMIX
  2029. if(!noPanoramiXExtension) {
  2030. sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
  2031. sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
  2032. sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
  2033. sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
  2034. sprite.physLimits = sprite.hotLimits;
  2035. sprite.confineWin = NullWindow;
  2036. sprite.screen = pScreen;
  2037. /* gotta UNINIT these someplace */
  2038. REGION_INIT(pScreen, &sprite.Reg1, NullBox, 1);
  2039. REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
  2040. }
  2041. #endif
  2042. nxagentInitViewportFrame(pScreen, win);
  2043. if (nxagentOption(Shadow))
  2044. {
  2045. if (nxagentShadowInit(pScreen, win) == -1)
  2046. {
  2047. GiveUp(0);
  2048. }
  2049. }
  2050. }
  2051. /*
  2052. * This does not take any shortcuts, and even ignores its argument, since
  2053. * it does not happen very often, and one has to walk up the tree since
  2054. * this might be a newly instantiated cursor for an intermediate window
  2055. * between the one the pointer is in and the one that the last cursor was
  2056. * instantiated from.
  2057. */
  2058. /*ARGSUSED*/
  2059. void
  2060. WindowHasNewCursor(pWin)
  2061. WindowPtr pWin;
  2062. {
  2063. PostNewCursor();
  2064. }
  2065. void
  2066. NewCurrentScreen(newScreen, x, y)
  2067. ScreenPtr newScreen;
  2068. int x,y;
  2069. {
  2070. sprite.hotPhys.x = x;
  2071. sprite.hotPhys.y = y;
  2072. #ifdef PANORAMIX
  2073. if(!noPanoramiXExtension) {
  2074. sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
  2075. panoramiXdataPtr[0].x;
  2076. sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
  2077. panoramiXdataPtr[0].y;
  2078. if (newScreen != sprite.screen) {
  2079. sprite.screen = newScreen;
  2080. /* Make sure we tell the DDX to update its copy of the screen */
  2081. if(sprite.confineWin)
  2082. XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
  2083. else
  2084. XineramaConfineCursorToWindow(WindowTable[0], TRUE);
  2085. /* if the pointer wasn't confined, the DDX won't get
  2086. told of the pointer warp so we reposition it here */
  2087. if(!syncEvents.playingEvents)
  2088. (*sprite.screen->SetCursorPosition)(sprite.screen,
  2089. sprite.hotPhys.x + panoramiXdataPtr[0].x -
  2090. panoramiXdataPtr[sprite.screen->myNum].x,
  2091. sprite.hotPhys.y + panoramiXdataPtr[0].y -
  2092. panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
  2093. }
  2094. } else
  2095. #endif
  2096. if (newScreen != sprite.hotPhys.pScreen)
  2097. ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
  2098. }
  2099. #ifdef PANORAMIX
  2100. static Bool
  2101. XineramaPointInWindowIsVisible(
  2102. WindowPtr pWin,
  2103. int x,
  2104. int y
  2105. )
  2106. {
  2107. ScreenPtr pScreen = pWin->drawable.pScreen;
  2108. BoxRec box;
  2109. int i, xoff, yoff;
  2110. if (!pWin->realized) return FALSE;
  2111. if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
  2112. return TRUE;
  2113. if(!XineramaSetWindowPntrs(pWin)) return FALSE;
  2114. xoff = x + panoramiXdataPtr[0].x;
  2115. yoff = y + panoramiXdataPtr[0].y;
  2116. for(i = 1; i < PanoramiXNumScreens; i++) {
  2117. pWin = sprite.windows[i];
  2118. pScreen = pWin->drawable.pScreen;
  2119. x = xoff - panoramiXdataPtr[i].x;
  2120. y = yoff - panoramiXdataPtr[i].y;
  2121. if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
  2122. return TRUE;
  2123. }
  2124. return FALSE;
  2125. }
  2126. static int
  2127. XineramaWarpPointer(ClientPtr client)
  2128. {
  2129. WindowPtr dest = NULL;
  2130. int x, y;
  2131. REQUEST(xWarpPointerReq);
  2132. if (stuff->dstWid != None)
  2133. {
  2134. dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
  2135. if (!dest)
  2136. return BadWindow;
  2137. }
  2138. x = sprite.hotPhys.x;
  2139. y = sprite.hotPhys.y;
  2140. if (stuff->srcWid != None)
  2141. {
  2142. int winX, winY;
  2143. XID winID = stuff->srcWid;
  2144. WindowPtr source;
  2145. source = SecurityLookupWindow(winID, client, SecurityReadAccess);
  2146. if (!source) return BadWindow;
  2147. winX = source->drawable.x;
  2148. winY = source->drawable.y;
  2149. if(source == WindowTable[0]) {
  2150. winX -= panoramiXdataPtr[0].x;
  2151. winY -= panoramiXdataPtr[0].y;
  2152. }
  2153. if (x < winX + stuff->srcX ||
  2154. y < winY + stuff->srcY ||
  2155. (stuff->srcWidth != 0 &&
  2156. winX + stuff->srcX + (int)stuff->srcWidth < x) ||
  2157. (stuff->srcHeight != 0 &&
  2158. winY + stuff->srcY + (int)stuff->srcHeight < y) ||
  2159. !XineramaPointInWindowIsVisible(source, x, y))
  2160. return Success;
  2161. }
  2162. if (dest) {
  2163. x = dest->drawable.x;
  2164. y = dest->drawable.y;
  2165. if(dest == WindowTable[0]) {
  2166. x -= panoramiXdataPtr[0].x;
  2167. y -= panoramiXdataPtr[0].y;
  2168. }
  2169. }
  2170. x += stuff->dstX;
  2171. y += stuff->dstY;
  2172. if (x < sprite.physLimits.x1)
  2173. x = sprite.physLimits.x1;
  2174. else if (x >= sprite.physLimits.x2)
  2175. x = sprite.physLimits.x2 - 1;
  2176. if (y < sprite.physLimits.y1)
  2177. y = sprite.physLimits.y1;
  2178. else if (y >= sprite.physLimits.y2)
  2179. y = sprite.physLimits.y2 - 1;
  2180. if (sprite.hotShape)
  2181. ConfineToShape(sprite.hotShape, &x, &y);
  2182. XineramaSetCursorPosition(x, y, TRUE);
  2183. return Success;
  2184. }
  2185. #endif
  2186. int
  2187. ProcWarpPointer(client)
  2188. ClientPtr client;
  2189. {
  2190. WindowPtr dest = NULL;
  2191. int x, y;
  2192. ScreenPtr newScreen;
  2193. REQUEST(xWarpPointerReq);
  2194. REQUEST_SIZE_MATCH(xWarpPointerReq);
  2195. #ifdef PANORAMIX
  2196. if(!noPanoramiXExtension)
  2197. return XineramaWarpPointer(client);
  2198. #endif
  2199. if (stuff->dstWid != None)
  2200. {
  2201. dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
  2202. if (!dest)
  2203. return BadWindow;
  2204. }
  2205. x = sprite.hotPhys.x;
  2206. y = sprite.hotPhys.y;
  2207. if (stuff->srcWid != None)
  2208. {
  2209. int winX, winY;
  2210. XID winID = stuff->srcWid;
  2211. WindowPtr source;
  2212. source = SecurityLookupWindow(winID, client, SecurityReadAccess);
  2213. if (!source) return BadWindow;
  2214. winX = source->drawable.x;
  2215. winY = source->drawable.y;
  2216. if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
  2217. x < winX + stuff->srcX ||
  2218. y < winY + stuff->srcY ||
  2219. (stuff->srcWidth != 0 &&
  2220. winX + stuff->srcX + (int)stuff->srcWidth < x) ||
  2221. (stuff->srcHeight != 0 &&
  2222. winY + stuff->srcY + (int)stuff->srcHeight < y) ||
  2223. !PointInWindowIsVisible(source, x, y))
  2224. return Success;
  2225. }
  2226. if (dest)
  2227. {
  2228. x = dest->drawable.x;
  2229. y = dest->drawable.y;
  2230. newScreen = dest->drawable.pScreen;
  2231. } else
  2232. newScreen = sprite.hotPhys.pScreen;
  2233. x += stuff->dstX;
  2234. y += stuff->dstY;
  2235. if (x < 0)
  2236. x = 0;
  2237. else if (x >= newScreen->width)
  2238. x = newScreen->width - 1;
  2239. if (y < 0)
  2240. y = 0;
  2241. else if (y >= newScreen->height)
  2242. y = newScreen->height - 1;
  2243. if (newScreen == sprite.hotPhys.pScreen)
  2244. {
  2245. if (x < sprite.physLimits.x1)
  2246. x = sprite.physLimits.x1;
  2247. else if (x >= sprite.physLimits.x2)
  2248. x = sprite.physLimits.x2 - 1;
  2249. if (y < sprite.physLimits.y1)
  2250. y = sprite.physLimits.y1;
  2251. else if (y >= sprite.physLimits.y2)
  2252. y = sprite.physLimits.y2 - 1;
  2253. #if defined(SHAPE)
  2254. if (sprite.hotShape)
  2255. ConfineToShape(sprite.hotShape, &x, &y);
  2256. #endif
  2257. (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
  2258. }
  2259. else if (!PointerConfinedToScreen())
  2260. {
  2261. NewCurrentScreen(newScreen, x, y);
  2262. }
  2263. return Success;
  2264. }
  2265. static Bool
  2266. BorderSizeNotEmpty(WindowPtr pWin)
  2267. {
  2268. if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
  2269. return TRUE;
  2270. #ifdef PANORAMIX
  2271. if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
  2272. int i;
  2273. for(i = 1; i < PanoramiXNumScreens; i++) {
  2274. if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
  2275. return TRUE;
  2276. }
  2277. }
  2278. #endif
  2279. return FALSE;
  2280. }
  2281. /* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
  2282. passive grab set on the window to be activated. */
  2283. static Bool
  2284. #if NeedFunctionPrototypes
  2285. CheckPassiveGrabsOnWindow(
  2286. WindowPtr pWin,
  2287. register DeviceIntPtr device,
  2288. register xEvent *xE,
  2289. int count)
  2290. #else
  2291. CheckPassiveGrabsOnWindow(pWin, device, xE, count)
  2292. WindowPtr pWin;
  2293. register DeviceIntPtr device;
  2294. register xEvent *xE;
  2295. int count;
  2296. #endif
  2297. {
  2298. register GrabPtr grab = wPassiveGrabs(pWin);
  2299. GrabRec tempGrab;
  2300. register xEvent *dxE;
  2301. if (!grab)
  2302. return FALSE;
  2303. tempGrab.window = pWin;
  2304. tempGrab.device = device;
  2305. tempGrab.type = xE->u.u.type;
  2306. tempGrab.detail.exact = xE->u.u.detail;
  2307. tempGrab.detail.pMask = NULL;
  2308. tempGrab.modifiersDetail.pMask = NULL;
  2309. for (; grab; grab = grab->next)
  2310. {
  2311. #ifdef XKB
  2312. DeviceIntPtr gdev;
  2313. XkbSrvInfoPtr xkbi;
  2314. gdev= grab->modifierDevice;
  2315. xkbi= gdev->key->xkbInfo;
  2316. #endif
  2317. tempGrab.modifierDevice = grab->modifierDevice;
  2318. if (device == grab->modifierDevice &&
  2319. (xE->u.u.type == KeyPress
  2320. #ifdef XINPUT
  2321. || xE->u.u.type == DeviceKeyPress
  2322. #endif
  2323. ))
  2324. tempGrab.modifiersDetail.exact =
  2325. #ifdef XKB
  2326. (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
  2327. #else
  2328. grab->modifierDevice->key->prev_state;
  2329. #endif
  2330. else
  2331. tempGrab.modifiersDetail.exact =
  2332. #ifdef XKB
  2333. (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
  2334. #else
  2335. grab->modifierDevice->key->state;
  2336. #endif
  2337. if (GrabMatchesSecond(&tempGrab, grab) &&
  2338. (!grab->confineTo ||
  2339. (grab->confineTo->realized &&
  2340. BorderSizeNotEmpty(grab->confineTo))))
  2341. {
  2342. #ifdef XCSECURITY
  2343. if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
  2344. return FALSE;
  2345. #endif
  2346. #ifdef XKB
  2347. if (!noXkbExtension) {
  2348. XE_KBPTR.state &= 0x1f00;
  2349. XE_KBPTR.state |=
  2350. tempGrab.modifiersDetail.exact&(~0x1f00);
  2351. }
  2352. #endif
  2353. (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  2354. FixUpEventFromWindow(xE, grab->window, None, TRUE);
  2355. (void) TryClientEvents(rClient(grab), xE, count,
  2356. filters[xE->u.u.type],
  2357. filters[xE->u.u.type], grab);
  2358. if (device->sync.state == FROZEN_NO_EVENT)
  2359. {
  2360. if (device->sync.evcount < count)
  2361. {
  2362. Must_have_memory = TRUE; /* XXX */
  2363. device->sync.event = (xEvent *)xrealloc(device->sync.event,
  2364. count*
  2365. sizeof(xEvent));
  2366. Must_have_memory = FALSE; /* XXX */
  2367. }
  2368. device->sync.evcount = count;
  2369. for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
  2370. *dxE = *xE;
  2371. device->sync.state = FROZEN_WITH_EVENT;
  2372. }
  2373. return TRUE;
  2374. }
  2375. }
  2376. return FALSE;
  2377. }
  2378. /*
  2379. "CheckDeviceGrabs" handles both keyboard and pointer events that may cause
  2380. a passive grab to be activated. If the event is a keyboard event, the
  2381. ancestors of the focus window are traced down and tried to see if they have
  2382. any passive grabs to be activated. If the focus window itself is reached and
  2383. it's descendants contain they pointer, the ancestors of the window that the
  2384. pointer is in are then traced down starting at the focus window, otherwise no
  2385. grabs are activated. If the event is a pointer event, the ancestors of the
  2386. window that the pointer is in are traced down starting at the root until
  2387. CheckPassiveGrabs causes a passive grab to activate or all the windows are
  2388. tried. PRH
  2389. */
  2390. Bool
  2391. CheckDeviceGrabs(device, xE, checkFirst, count)
  2392. register DeviceIntPtr device;
  2393. register xEvent *xE;
  2394. int checkFirst;
  2395. int count;
  2396. {
  2397. register int i;
  2398. register WindowPtr pWin = NULL;
  2399. register FocusClassPtr focus = device->focus;
  2400. if ((xE->u.u.type == ButtonPress
  2401. #ifdef XINPUT
  2402. || xE->u.u.type == DeviceButtonPress
  2403. #endif
  2404. ) && device->button->buttonsDown != 1)
  2405. return FALSE;
  2406. i = checkFirst;
  2407. if (focus)
  2408. {
  2409. for (; i < focus->traceGood; i++)
  2410. {
  2411. pWin = focus->trace[i];
  2412. if (pWin->optional &&
  2413. CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  2414. return TRUE;
  2415. }
  2416. if ((focus->win == NoneWin) ||
  2417. (i >= spriteTraceGood) ||
  2418. ((i > checkFirst) && (pWin != spriteTrace[i-1])))
  2419. return FALSE;
  2420. }
  2421. for (; i < spriteTraceGood; i++)
  2422. {
  2423. pWin = spriteTrace[i];
  2424. if (pWin->optional &&
  2425. CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  2426. return TRUE;
  2427. }
  2428. return FALSE;
  2429. }
  2430. void
  2431. DeliverFocusedEvent(keybd, xE, window, count)
  2432. xEvent *xE;
  2433. DeviceIntPtr keybd;
  2434. WindowPtr window;
  2435. int count;
  2436. {
  2437. WindowPtr focus = keybd->focus->win;
  2438. int mskidx = 0;
  2439. if (focus == FollowKeyboardWin)
  2440. focus = inputInfo.keyboard->focus->win;
  2441. if (!focus)
  2442. return;
  2443. if (focus == PointerRootWin)
  2444. {
  2445. DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
  2446. return;
  2447. }
  2448. if ((focus == window) || IsParent(focus, window))
  2449. {
  2450. if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
  2451. return;
  2452. }
  2453. /* just deliver it to the focus window */
  2454. FixUpEventFromWindow(xE, focus, None, FALSE);
  2455. if (xE->u.u.type & EXTENSION_EVENT_BASE)
  2456. mskidx = keybd->id;
  2457. (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
  2458. NullGrab, mskidx);
  2459. }
  2460. void
  2461. DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
  2462. register xEvent *xE;
  2463. register DeviceIntPtr thisDev;
  2464. Bool deactivateGrab;
  2465. int count;
  2466. {
  2467. register GrabPtr grab = thisDev->grab;
  2468. int deliveries = 0;
  2469. register DeviceIntPtr dev;
  2470. register xEvent *dxE;
  2471. if (grab->ownerEvents)
  2472. {
  2473. WindowPtr focus;
  2474. if (thisDev->focus)
  2475. {
  2476. focus = thisDev->focus->win;
  2477. if (focus == FollowKeyboardWin)
  2478. focus = inputInfo.keyboard->focus->win;
  2479. }
  2480. else
  2481. focus = PointerRootWin;
  2482. if (focus == PointerRootWin)
  2483. deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
  2484. thisDev, count);
  2485. else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
  2486. deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
  2487. thisDev, count);
  2488. else if (focus)
  2489. deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
  2490. thisDev, count);
  2491. }
  2492. if (!deliveries)
  2493. {
  2494. FixUpEventFromWindow(xE, grab->window, None, TRUE);
  2495. deliveries = TryClientEvents(rClient(grab), xE, count,
  2496. (Mask)grab->eventMask,
  2497. filters[xE->u.u.type], grab);
  2498. if (deliveries && (xE->u.u.type == MotionNotify
  2499. #ifdef XINPUT
  2500. || xE->u.u.type == DeviceMotionNotify
  2501. #endif
  2502. ))
  2503. thisDev->valuator->motionHintWindow = grab->window;
  2504. }
  2505. if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
  2506. #ifdef XINPUT
  2507. && xE->u.u.type != DeviceMotionNotify
  2508. #endif
  2509. ))
  2510. switch (thisDev->sync.state)
  2511. {
  2512. case FREEZE_BOTH_NEXT_EVENT:
  2513. for (dev = inputInfo.devices; dev; dev = dev->next)
  2514. {
  2515. if (dev == thisDev)
  2516. continue;
  2517. FreezeThaw(dev, TRUE);
  2518. if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
  2519. (CLIENT_BITS(dev->grab->resource) ==
  2520. CLIENT_BITS(thisDev->grab->resource)))
  2521. dev->sync.state = FROZEN_NO_EVENT;
  2522. else
  2523. dev->sync.other = thisDev->grab;
  2524. }
  2525. /* fall through */
  2526. case FREEZE_NEXT_EVENT:
  2527. thisDev->sync.state = FROZEN_WITH_EVENT;
  2528. FreezeThaw(thisDev, TRUE);
  2529. if (thisDev->sync.evcount < count)
  2530. {
  2531. Must_have_memory = TRUE; /* XXX */
  2532. thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
  2533. count*sizeof(xEvent));
  2534. Must_have_memory = FALSE; /* XXX */
  2535. }
  2536. thisDev->sync.evcount = count;
  2537. for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
  2538. *dxE = *xE;
  2539. break;
  2540. }
  2541. }
  2542. void
  2543. #ifdef XKB
  2544. CoreProcessKeyboardEvent (xE, keybd, count)
  2545. #else
  2546. ProcessKeyboardEvent (xE, keybd, count)
  2547. #endif
  2548. register xEvent *xE;
  2549. register DeviceIntPtr keybd;
  2550. int count;
  2551. {
  2552. int key, bit;
  2553. register BYTE *kptr;
  2554. register int i;
  2555. register CARD8 modifiers;
  2556. register CARD16 mask;
  2557. GrabPtr grab = keybd->grab;
  2558. Bool deactivateGrab = FALSE;
  2559. register KeyClassPtr keyc = keybd->key;
  2560. if (!syncEvents.playingEvents)
  2561. {
  2562. NoticeTime(xE);
  2563. if (DeviceEventCallback)
  2564. {
  2565. DeviceEventInfoRec eventinfo;
  2566. eventinfo.events = xE;
  2567. eventinfo.count = count;
  2568. CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
  2569. }
  2570. }
  2571. XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
  2572. XE_KBPTR.rootX = sprite.hot.x;
  2573. XE_KBPTR.rootY = sprite.hot.y;
  2574. key = xE->u.u.detail;
  2575. kptr = &keyc->down[key >> 3];
  2576. bit = 1 << (key & 7);
  2577. modifiers = keyc->modifierMap[key];
  2578. #ifdef DEBUG
  2579. if ((xkbDebugFlags&0x4)&&
  2580. ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
  2581. ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
  2582. (xE->u.u.type==KeyPress?"down":"up"));
  2583. }
  2584. #endif
  2585. switch (xE->u.u.type)
  2586. {
  2587. case KeyPress:
  2588. if (*kptr & bit) /* allow ddx to generate multiple downs */
  2589. {
  2590. if (!modifiers)
  2591. {
  2592. xE->u.u.type = KeyRelease;
  2593. (*keybd->public.processInputProc)(xE, keybd, count);
  2594. xE->u.u.type = KeyPress;
  2595. /* release can have side effects, don't fall through */
  2596. (*keybd->public.processInputProc)(xE, keybd, count);
  2597. }
  2598. return;
  2599. }
  2600. inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  2601. *kptr |= bit;
  2602. keyc->prev_state = keyc->state;
  2603. for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  2604. {
  2605. if (mask & modifiers)
  2606. {
  2607. /* This key affects modifier "i" */
  2608. keyc->modifierKeyCount[i]++;
  2609. keyc->state |= mask;
  2610. modifiers &= ~mask;
  2611. }
  2612. }
  2613. if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
  2614. {
  2615. keybd->activatingKey = key;
  2616. return;
  2617. }
  2618. break;
  2619. case KeyRelease:
  2620. if (!(*kptr & bit)) /* guard against duplicates */
  2621. return;
  2622. inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  2623. *kptr &= ~bit;
  2624. keyc->prev_state = keyc->state;
  2625. for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  2626. {
  2627. if (mask & modifiers) {
  2628. /* This key affects modifier "i" */
  2629. if (--keyc->modifierKeyCount[i] <= 0) {
  2630. keyc->state &= ~mask;
  2631. keyc->modifierKeyCount[i] = 0;
  2632. }
  2633. modifiers &= ~mask;
  2634. }
  2635. }
  2636. if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
  2637. deactivateGrab = TRUE;
  2638. break;
  2639. default:
  2640. FatalError("Impossible keyboard event");
  2641. }
  2642. if (grab)
  2643. DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
  2644. else
  2645. DeliverFocusedEvent(keybd, xE, sprite.win, count);
  2646. if (deactivateGrab)
  2647. (*keybd->DeactivateGrab)(keybd);
  2648. }
  2649. #ifdef XKB
  2650. /* This function is used to set the key pressed or key released state -
  2651. this is only used when the pressing of keys does not cause
  2652. CoreProcessKeyEvent to be called, as in for example Mouse Keys.
  2653. */
  2654. void
  2655. FixKeyState (xE, keybd)
  2656. register xEvent *xE;
  2657. register DeviceIntPtr keybd;
  2658. {
  2659. int key, bit;
  2660. register BYTE *kptr;
  2661. register KeyClassPtr keyc = keybd->key;
  2662. key = xE->u.u.detail;
  2663. kptr = &keyc->down[key >> 3];
  2664. bit = 1 << (key & 7);
  2665. #ifdef DEBUG
  2666. if ((xkbDebugFlags&0x4)&&
  2667. ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
  2668. ErrorF("FixKeyState: Key %d %s\n",key,
  2669. (xE->u.u.type==KeyPress?"down":"up"));
  2670. }
  2671. #endif
  2672. switch (xE->u.u.type)
  2673. {
  2674. case KeyPress:
  2675. *kptr |= bit;
  2676. break;
  2677. case KeyRelease:
  2678. *kptr &= ~bit;
  2679. break;
  2680. default:
  2681. FatalError("Impossible keyboard event");
  2682. }
  2683. }
  2684. #endif
  2685. void
  2686. #ifdef XKB
  2687. CoreProcessPointerEvent (xE, mouse, count)
  2688. #else
  2689. ProcessPointerEvent (xE, mouse, count)
  2690. #endif
  2691. register xEvent *xE;
  2692. register DeviceIntPtr mouse;
  2693. int count;
  2694. {
  2695. register GrabPtr grab = mouse->grab;
  2696. Bool deactivateGrab = FALSE;
  2697. register ButtonClassPtr butc = mouse->button;
  2698. #ifdef XKB
  2699. XkbSrvInfoPtr xkbi;
  2700. xkbi = inputInfo.keyboard->key->xkbInfo;
  2701. #endif
  2702. if (!syncEvents.playingEvents)
  2703. NoticeTime(xE)
  2704. XE_KBPTR.state = (butc->state | (
  2705. #ifdef XKB
  2706. (noXkbExtension ?
  2707. inputInfo.keyboard->key->state :
  2708. xkbi->state.grab_mods)
  2709. #else
  2710. inputInfo.keyboard->key->state
  2711. #endif
  2712. ));
  2713. {
  2714. NoticeTime(xE);
  2715. if (DeviceEventCallback)
  2716. {
  2717. DeviceEventInfoRec eventinfo;
  2718. /* see comment in EnqueueEvents regarding the next three lines */
  2719. if (xE->u.u.type == MotionNotify)
  2720. XE_KBPTR.root =
  2721. WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
  2722. eventinfo.events = xE;
  2723. eventinfo.count = count;
  2724. CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
  2725. }
  2726. }
  2727. if (xE->u.u.type != MotionNotify)
  2728. {
  2729. register int key;
  2730. register BYTE *kptr;
  2731. int bit;
  2732. XE_KBPTR.rootX = sprite.hot.x;
  2733. XE_KBPTR.rootY = sprite.hot.y;
  2734. key = xE->u.u.detail;
  2735. kptr = &butc->down[key >> 3];
  2736. bit = 1 << (key & 7);
  2737. switch (xE->u.u.type)
  2738. {
  2739. case ButtonPress:
  2740. mouse->valuator->motionHintWindow = NullWindow;
  2741. if (!(*kptr & bit))
  2742. butc->buttonsDown++;
  2743. butc->motionMask = ButtonMotionMask;
  2744. *kptr |= bit;
  2745. #if !defined(XFree86Server) || !defined(XINPUT)
  2746. xE->u.u.detail = butc->map[key];
  2747. #endif
  2748. if (xE->u.u.detail == 0)
  2749. return;
  2750. if (xE->u.u.detail <= 5)
  2751. butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
  2752. filters[MotionNotify] = Motion_Filter(butc);
  2753. if (!grab)
  2754. if (CheckDeviceGrabs(mouse, xE, 0, count))
  2755. return;
  2756. break;
  2757. case ButtonRelease:
  2758. mouse->valuator->motionHintWindow = NullWindow;
  2759. if (*kptr & bit)
  2760. --butc->buttonsDown;
  2761. if (!butc->buttonsDown)
  2762. butc->motionMask = 0;
  2763. *kptr &= ~bit;
  2764. #if !defined(XFree86Server) || !defined(XINPUT)
  2765. xE->u.u.detail = butc->map[key];
  2766. #endif
  2767. if (xE->u.u.detail == 0)
  2768. return;
  2769. if (xE->u.u.detail <= 5)
  2770. butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
  2771. filters[MotionNotify] = Motion_Filter(butc);
  2772. if (!butc->state && mouse->fromPassiveGrab)
  2773. deactivateGrab = TRUE;
  2774. break;
  2775. default:
  2776. FatalError("bogus pointer event from ddx");
  2777. }
  2778. }
  2779. else if (!CheckMotion(xE))
  2780. return;
  2781. if (grab)
  2782. DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
  2783. else
  2784. DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
  2785. mouse, count);
  2786. if (deactivateGrab)
  2787. (*mouse->DeactivateGrab)(mouse);
  2788. }
  2789. #define AtMostOneClient \
  2790. (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
  2791. void
  2792. RecalculateDeliverableEvents(pWin)
  2793. register WindowPtr pWin;
  2794. {
  2795. register OtherClients *others;
  2796. register WindowPtr pChild;
  2797. pChild = pWin;
  2798. while (1)
  2799. {
  2800. if (pChild->optional)
  2801. {
  2802. pChild->optional->otherEventMasks = 0;
  2803. for (others = wOtherClients(pChild); others; others = others->next)
  2804. {
  2805. pChild->optional->otherEventMasks |= others->mask;
  2806. }
  2807. }
  2808. pChild->deliverableEvents = pChild->eventMask|
  2809. wOtherEventMasks(pChild);
  2810. if (pChild->parent)
  2811. pChild->deliverableEvents |=
  2812. (pChild->parent->deliverableEvents &
  2813. ~wDontPropagateMask(pChild) & PropagateMask);
  2814. if (pChild->firstChild)
  2815. {
  2816. pChild = pChild->firstChild;
  2817. continue;
  2818. }
  2819. while (!pChild->nextSib && (pChild != pWin))
  2820. pChild = pChild->parent;
  2821. if (pChild == pWin)
  2822. break;
  2823. pChild = pChild->nextSib;
  2824. }
  2825. }
  2826. int
  2827. OtherClientGone(value, id)
  2828. pointer value; /* must conform to DeleteType */
  2829. XID id;
  2830. {
  2831. register OtherClientsPtr other, prev;
  2832. register WindowPtr pWin = (WindowPtr)value;
  2833. prev = 0;
  2834. for (other = wOtherClients(pWin); other; other = other->next)
  2835. {
  2836. if (other->resource == id)
  2837. {
  2838. if (prev)
  2839. prev->next = other->next;
  2840. else
  2841. {
  2842. if (!(pWin->optional->otherClients = other->next))
  2843. CheckWindowOptionalNeed (pWin);
  2844. }
  2845. xfree(other);
  2846. RecalculateDeliverableEvents(pWin);
  2847. return(Success);
  2848. }
  2849. prev = other;
  2850. }
  2851. FatalError("client not on event list");
  2852. /*NOTREACHED*/
  2853. return -1; /* make compiler happy */
  2854. }
  2855. int
  2856. EventSelectForWindow(pWin, client, mask)
  2857. register WindowPtr pWin;
  2858. register ClientPtr client;
  2859. Mask mask;
  2860. {
  2861. Mask check;
  2862. OtherClients * others;
  2863. if (mask & ~AllEventMasks)
  2864. {
  2865. client->errorValue = mask;
  2866. return BadValue;
  2867. }
  2868. check = (mask & AtMostOneClient);
  2869. if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
  2870. { /* It is illegal for two different
  2871. clients to select on any of the
  2872. events for AtMostOneClient. However,
  2873. it is OK, for some client to
  2874. continue selecting on one of those
  2875. events. */
  2876. if ((wClient(pWin) != client) && (check & pWin->eventMask))
  2877. return BadAccess;
  2878. for (others = wOtherClients (pWin); others; others = others->next)
  2879. {
  2880. if (!SameClient(others, client) && (check & others->mask))
  2881. return BadAccess;
  2882. }
  2883. }
  2884. if (wClient (pWin) == client)
  2885. {
  2886. check = pWin->eventMask;
  2887. #ifdef SGIMISC
  2888. pWin->eventMask =
  2889. (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
  2890. #else
  2891. pWin->eventMask = mask;
  2892. #endif
  2893. }
  2894. else
  2895. {
  2896. for (others = wOtherClients (pWin); others; others = others->next)
  2897. {
  2898. if (SameClient(others, client))
  2899. {
  2900. check = others->mask;
  2901. #ifdef SGIMISC
  2902. mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
  2903. #endif
  2904. if (mask == 0)
  2905. {
  2906. FreeResource(others->resource, RT_NONE);
  2907. return Success;
  2908. }
  2909. else
  2910. others->mask = mask;
  2911. goto maskSet;
  2912. }
  2913. }
  2914. check = 0;
  2915. if (!pWin->optional && !MakeWindowOptional (pWin))
  2916. return BadAlloc;
  2917. others = (OtherClients *) xalloc(sizeof(OtherClients));
  2918. if (!others)
  2919. return BadAlloc;
  2920. others->mask = mask;
  2921. others->resource = FakeClientID(client->index);
  2922. others->next = pWin->optional->otherClients;
  2923. pWin->optional->otherClients = others;
  2924. if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
  2925. return BadAlloc;
  2926. }
  2927. maskSet:
  2928. if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
  2929. (mask & PointerMotionHintMask) &&
  2930. !(check & PointerMotionHintMask) &&
  2931. !inputInfo.pointer->grab)
  2932. inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  2933. RecalculateDeliverableEvents(pWin);
  2934. return Success;
  2935. }
  2936. /*ARGSUSED*/
  2937. int
  2938. EventSuppressForWindow(pWin, client, mask, checkOptional)
  2939. register WindowPtr pWin;
  2940. register ClientPtr client;
  2941. Mask mask;
  2942. Bool *checkOptional;
  2943. {
  2944. register int i, free;
  2945. if ((mask & ~PropagateMask) && !permitOldBugs)
  2946. {
  2947. client->errorValue = mask;
  2948. return BadValue;
  2949. }
  2950. if (pWin->dontPropagate)
  2951. DontPropagateRefCnts[pWin->dontPropagate]--;
  2952. if (!mask)
  2953. i = 0;
  2954. else
  2955. {
  2956. for (i = DNPMCOUNT, free = 0; --i > 0; )
  2957. {
  2958. if (!DontPropagateRefCnts[i])
  2959. free = i;
  2960. else if (mask == DontPropagateMasks[i])
  2961. break;
  2962. }
  2963. if (!i && free)
  2964. {
  2965. i = free;
  2966. DontPropagateMasks[i] = mask;
  2967. }
  2968. }
  2969. if (i || !mask)
  2970. {
  2971. pWin->dontPropagate = i;
  2972. if (i)
  2973. DontPropagateRefCnts[i]++;
  2974. if (pWin->optional)
  2975. {
  2976. pWin->optional->dontPropagateMask = mask;
  2977. *checkOptional = TRUE;
  2978. }
  2979. }
  2980. else
  2981. {
  2982. if (!pWin->optional && !MakeWindowOptional (pWin))
  2983. {
  2984. if (pWin->dontPropagate)
  2985. DontPropagateRefCnts[pWin->dontPropagate]++;
  2986. return BadAlloc;
  2987. }
  2988. pWin->dontPropagate = 0;
  2989. pWin->optional->dontPropagateMask = mask;
  2990. }
  2991. RecalculateDeliverableEvents(pWin);
  2992. return Success;
  2993. }
  2994. static WindowPtr
  2995. #if NeedFunctionPrototypes
  2996. CommonAncestor(
  2997. register WindowPtr a,
  2998. register WindowPtr b)
  2999. #else
  3000. CommonAncestor(a, b)
  3001. register WindowPtr a, b;
  3002. #endif
  3003. {
  3004. for (b = b->parent; b; b = b->parent)
  3005. if (IsParent(b, a)) return b;
  3006. return NullWindow;
  3007. }
  3008. static void
  3009. #if NeedFunctionPrototypes
  3010. EnterLeaveEvent(
  3011. int type,
  3012. int mode,
  3013. int detail,
  3014. register WindowPtr pWin,
  3015. Window child)
  3016. #else
  3017. EnterLeaveEvent(type, mode, detail, pWin, child)
  3018. int type, mode, detail;
  3019. register WindowPtr pWin;
  3020. Window child;
  3021. #endif
  3022. {
  3023. xEvent event;
  3024. register DeviceIntPtr keybd = inputInfo.keyboard;
  3025. WindowPtr focus;
  3026. register DeviceIntPtr mouse = inputInfo.pointer;
  3027. register GrabPtr grab = mouse->grab;
  3028. Mask mask;
  3029. if ((pWin == mouse->valuator->motionHintWindow) &&
  3030. (detail != NotifyInferior))
  3031. mouse->valuator->motionHintWindow = NullWindow;
  3032. if (grab)
  3033. {
  3034. mask = (pWin == grab->window) ? grab->eventMask : 0;
  3035. if (grab->ownerEvents)
  3036. mask |= EventMaskForClient(pWin, rClient(grab));
  3037. }
  3038. else
  3039. {
  3040. mask = pWin->eventMask | wOtherEventMasks(pWin);
  3041. }
  3042. if (mask & filters[type])
  3043. {
  3044. event.u.u.type = type;
  3045. event.u.u.detail = detail;
  3046. event.u.enterLeave.time = currentTime.milliseconds;
  3047. event.u.enterLeave.rootX = sprite.hot.x;
  3048. event.u.enterLeave.rootY = sprite.hot.y;
  3049. /* Counts on the same initial structure of crossing & button events! */
  3050. FixUpEventFromWindow(&event, pWin, None, FALSE);
  3051. /* Enter/Leave events always set child */
  3052. event.u.enterLeave.child = child;
  3053. event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
  3054. ELFlagSameScreen : 0;
  3055. #ifdef XKB
  3056. if (!noXkbExtension) {
  3057. event.u.enterLeave.state = mouse->button->state & 0x1f00;
  3058. event.u.enterLeave.state |=
  3059. XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
  3060. } else
  3061. #endif
  3062. event.u.enterLeave.state = keybd->key->state | mouse->button->state;
  3063. event.u.enterLeave.mode = mode;
  3064. focus = keybd->focus->win;
  3065. if ((focus != NoneWin) &&
  3066. ((pWin == focus) || (focus == PointerRootWin) ||
  3067. IsParent(focus, pWin)))
  3068. event.u.enterLeave.flags |= ELFlagFocus;
  3069. if (grab)
  3070. (void)TryClientEvents(rClient(grab), &event, 1, mask,
  3071. filters[type], grab);
  3072. else
  3073. (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
  3074. NullGrab, 0);
  3075. }
  3076. if ((type == EnterNotify) && (mask & KeymapStateMask))
  3077. {
  3078. xKeymapEvent ke;
  3079. #ifdef XCSECURITY
  3080. ClientPtr client = grab ? rClient(grab)
  3081. : clients[CLIENT_ID(pWin->drawable.id)];
  3082. if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
  3083. {
  3084. bzero((char *)&ke.map[0], 31);
  3085. }
  3086. else
  3087. #endif
  3088. memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
  3089. ke.type = KeymapNotify;
  3090. if (grab)
  3091. (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
  3092. KeymapStateMask, grab);
  3093. else
  3094. (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  3095. KeymapStateMask, NullGrab, 0);
  3096. }
  3097. }
  3098. static void
  3099. #if NeedFunctionPrototypes
  3100. EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
  3101. #else
  3102. EnterNotifies(ancestor, child, mode, detail)
  3103. WindowPtr ancestor, child;
  3104. int mode, detail;
  3105. #endif
  3106. {
  3107. WindowPtr parent = child->parent;
  3108. if (ancestor == parent)
  3109. return;
  3110. EnterNotifies(ancestor, parent, mode, detail);
  3111. EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
  3112. }
  3113. static void
  3114. #if NeedFunctionPrototypes
  3115. LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
  3116. #else
  3117. LeaveNotifies(child, ancestor, mode, detail)
  3118. WindowPtr child, ancestor;
  3119. int detail, mode;
  3120. #endif
  3121. {
  3122. register WindowPtr pWin;
  3123. if (ancestor == child)
  3124. return;
  3125. for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
  3126. {
  3127. EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
  3128. child = pWin;
  3129. }
  3130. }
  3131. static void
  3132. #if NeedFunctionPrototypes
  3133. DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
  3134. #else
  3135. DoEnterLeaveEvents(fromWin, toWin, mode)
  3136. WindowPtr fromWin, toWin;
  3137. int mode;
  3138. #endif
  3139. {
  3140. if (fromWin == toWin)
  3141. return;
  3142. if (IsParent(fromWin, toWin))
  3143. {
  3144. EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
  3145. EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
  3146. EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
  3147. }
  3148. else if (IsParent(toWin, fromWin))
  3149. {
  3150. EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
  3151. LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
  3152. EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
  3153. }
  3154. else
  3155. { /* neither fromWin nor toWin is descendent of the other */
  3156. WindowPtr common = CommonAncestor(toWin, fromWin);
  3157. /* common == NullWindow ==> different screens */
  3158. EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
  3159. LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
  3160. EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
  3161. EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
  3162. }
  3163. }
  3164. static void
  3165. #if NeedFunctionPrototypes
  3166. FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
  3167. #else
  3168. FocusEvent(dev, type, mode, detail, pWin)
  3169. DeviceIntPtr dev;
  3170. int type, mode, detail;
  3171. register WindowPtr pWin;
  3172. #endif
  3173. {
  3174. xEvent event;
  3175. #ifdef XINPUT
  3176. if (dev != inputInfo.keyboard)
  3177. {
  3178. DeviceFocusEvent(dev, type, mode, detail, pWin);
  3179. return;
  3180. }
  3181. #endif
  3182. event.u.focus.mode = mode;
  3183. event.u.u.type = type;
  3184. event.u.u.detail = detail;
  3185. event.u.focus.window = pWin->drawable.id;
  3186. (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
  3187. 0);
  3188. if ((type == FocusIn) &&
  3189. ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
  3190. {
  3191. xKeymapEvent ke;
  3192. #ifdef XCSECURITY
  3193. ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
  3194. if (!SecurityCheckDeviceAccess(client, dev, FALSE))
  3195. {
  3196. bzero((char *)&ke.map[0], 31);
  3197. }
  3198. else
  3199. #endif
  3200. memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
  3201. ke.type = KeymapNotify;
  3202. (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  3203. KeymapStateMask, NullGrab, 0);
  3204. }
  3205. }
  3206. /*
  3207. * recursive because it is easier
  3208. * no-op if child not descended from ancestor
  3209. */
  3210. static Bool
  3211. #if NeedFunctionPrototypes
  3212. FocusInEvents(
  3213. DeviceIntPtr dev,
  3214. WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
  3215. int mode, int detail,
  3216. Bool doAncestor)
  3217. #else
  3218. FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
  3219. DeviceIntPtr dev;
  3220. WindowPtr ancestor, child, skipChild;
  3221. int mode, detail;
  3222. Bool doAncestor;
  3223. #endif
  3224. {
  3225. if (child == NullWindow)
  3226. return ancestor == NullWindow;
  3227. if (ancestor == child)
  3228. {
  3229. if (doAncestor)
  3230. FocusEvent(dev, FocusIn, mode, detail, child);
  3231. return TRUE;
  3232. }
  3233. if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
  3234. doAncestor))
  3235. {
  3236. if (child != skipChild)
  3237. FocusEvent(dev, FocusIn, mode, detail, child);
  3238. return TRUE;
  3239. }
  3240. return FALSE;
  3241. }
  3242. /* dies horribly if ancestor is not an ancestor of child */
  3243. static void
  3244. #if NeedFunctionPrototypes
  3245. FocusOutEvents(
  3246. DeviceIntPtr dev,
  3247. WindowPtr child, WindowPtr ancestor,
  3248. int mode, int detail,
  3249. Bool doAncestor)
  3250. #else
  3251. FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
  3252. DeviceIntPtr dev;
  3253. WindowPtr child, ancestor;
  3254. int mode;
  3255. int detail;
  3256. Bool doAncestor;
  3257. #endif
  3258. {
  3259. register WindowPtr pWin;
  3260. for (pWin = child; pWin != ancestor; pWin = pWin->parent)
  3261. FocusEvent(dev, FocusOut, mode, detail, pWin);
  3262. if (doAncestor)
  3263. FocusEvent(dev, FocusOut, mode, detail, ancestor);
  3264. }
  3265. void
  3266. DoFocusEvents(dev, fromWin, toWin, mode)
  3267. DeviceIntPtr dev;
  3268. WindowPtr fromWin, toWin;
  3269. int mode;
  3270. {
  3271. int out, in; /* for holding details for to/from
  3272. PointerRoot/None */
  3273. int i;
  3274. if (fromWin == toWin)
  3275. return;
  3276. out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  3277. in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  3278. /* wrong values if neither, but then not referenced */
  3279. if ((toWin == NullWindow) || (toWin == PointerRootWin))
  3280. {
  3281. if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  3282. {
  3283. if (fromWin == PointerRootWin)
  3284. FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  3285. TRUE);
  3286. /* Notify all the roots */
  3287. #ifdef PANORAMIX
  3288. if ( !noPanoramiXExtension )
  3289. FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
  3290. else
  3291. #endif
  3292. for (i=0; i<screenInfo.numScreens; i++)
  3293. FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  3294. }
  3295. else
  3296. {
  3297. if (IsParent(fromWin, sprite.win))
  3298. FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
  3299. FALSE);
  3300. FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  3301. /* next call catches the root too, if the screen changed */
  3302. FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
  3303. NotifyNonlinearVirtual, FALSE);
  3304. }
  3305. /* Notify all the roots */
  3306. #ifdef PANORAMIX
  3307. if ( !noPanoramiXExtension )
  3308. FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
  3309. else
  3310. #endif
  3311. for (i=0; i<screenInfo.numScreens; i++)
  3312. FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
  3313. if (toWin == PointerRootWin)
  3314. (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
  3315. NotifyPointer, TRUE);
  3316. }
  3317. else
  3318. {
  3319. if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  3320. {
  3321. if (fromWin == PointerRootWin)
  3322. FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  3323. TRUE);
  3324. #ifdef PANORAMIX
  3325. if ( !noPanoramiXExtension )
  3326. FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
  3327. else
  3328. #endif
  3329. for (i=0; i<screenInfo.numScreens; i++)
  3330. FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  3331. if (toWin->parent != NullWindow)
  3332. (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
  3333. NotifyNonlinearVirtual, TRUE);
  3334. FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  3335. if (IsParent(toWin, sprite.win))
  3336. (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
  3337. NotifyPointer, FALSE);
  3338. }
  3339. else
  3340. {
  3341. if (IsParent(toWin, fromWin))
  3342. {
  3343. FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
  3344. FocusOutEvents(dev, fromWin->parent, toWin, mode,
  3345. NotifyVirtual, FALSE);
  3346. FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
  3347. if ((IsParent(toWin, sprite.win)) &&
  3348. (sprite.win != fromWin) &&
  3349. (!IsParent(fromWin, sprite.win)) &&
  3350. (!IsParent(sprite.win, fromWin)))
  3351. (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  3352. mode, NotifyPointer, FALSE);
  3353. }
  3354. else
  3355. if (IsParent(fromWin, toWin))
  3356. {
  3357. if ((IsParent(fromWin, sprite.win)) &&
  3358. (sprite.win != fromWin) &&
  3359. (!IsParent(toWin, sprite.win)) &&
  3360. (!IsParent(sprite.win, toWin)))
  3361. FocusOutEvents(dev, sprite.win, fromWin, mode,
  3362. NotifyPointer, FALSE);
  3363. FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
  3364. (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
  3365. NotifyVirtual, FALSE);
  3366. FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
  3367. }
  3368. else
  3369. {
  3370. /* neither fromWin or toWin is child of other */
  3371. WindowPtr common = CommonAncestor(toWin, fromWin);
  3372. /* common == NullWindow ==> different screens */
  3373. if (IsParent(fromWin, sprite.win))
  3374. FocusOutEvents(dev, sprite.win, fromWin, mode,
  3375. NotifyPointer, FALSE);
  3376. FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  3377. if (fromWin->parent != NullWindow)
  3378. FocusOutEvents(dev, fromWin->parent, common, mode,
  3379. NotifyNonlinearVirtual, FALSE);
  3380. if (toWin->parent != NullWindow)
  3381. (void)FocusInEvents(dev, common, toWin, toWin, mode,
  3382. NotifyNonlinearVirtual, FALSE);
  3383. FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  3384. if (IsParent(toWin, sprite.win))
  3385. (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  3386. mode, NotifyPointer, FALSE);
  3387. }
  3388. }
  3389. }
  3390. }
  3391. int
  3392. #if NeedFunctionPrototypes
  3393. SetInputFocus(
  3394. ClientPtr client,
  3395. DeviceIntPtr dev,
  3396. Window focusID,
  3397. CARD8 revertTo,
  3398. Time ctime,
  3399. Bool followOK)
  3400. #else
  3401. SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
  3402. ClientPtr client;
  3403. DeviceIntPtr dev;
  3404. Window focusID;
  3405. CARD8 revertTo;
  3406. Time ctime;
  3407. Bool followOK;
  3408. #endif
  3409. {
  3410. register FocusClassPtr focus;
  3411. register WindowPtr focusWin;
  3412. int mode;
  3413. TimeStamp time;
  3414. UpdateCurrentTime();
  3415. if ((revertTo != RevertToParent) &&
  3416. (revertTo != RevertToPointerRoot) &&
  3417. (revertTo != RevertToNone) &&
  3418. ((revertTo != RevertToFollowKeyboard) || !followOK))
  3419. {
  3420. client->errorValue = revertTo;
  3421. return BadValue;
  3422. }
  3423. time = ClientTimeToServerTime(ctime);
  3424. if ((focusID == None) || (focusID == PointerRoot))
  3425. focusWin = (WindowPtr)(long)focusID;
  3426. else if ((focusID == FollowKeyboard) && followOK)
  3427. focusWin = inputInfo.keyboard->focus->win;
  3428. else if (!(focusWin = SecurityLookupWindow(focusID, client,
  3429. SecurityReadAccess)))
  3430. return BadWindow;
  3431. else
  3432. {
  3433. /* It is a match error to try to set the input focus to an
  3434. unviewable window. */
  3435. if(!focusWin->realized)
  3436. return(BadMatch);
  3437. }
  3438. focus = dev->focus;
  3439. if ((CompareTimeStamps(time, currentTime) == LATER) ||
  3440. (CompareTimeStamps(time, focus->time) == EARLIER))
  3441. return Success;
  3442. mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
  3443. if (focus->win == FollowKeyboardWin)
  3444. DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
  3445. else
  3446. DoFocusEvents(dev, focus->win, focusWin, mode);
  3447. focus->time = time;
  3448. focus->revert = revertTo;
  3449. if (focusID == FollowKeyboard)
  3450. focus->win = FollowKeyboardWin;
  3451. else
  3452. focus->win = focusWin;
  3453. if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
  3454. focus->traceGood = 0;
  3455. else
  3456. {
  3457. int depth = 0;
  3458. register WindowPtr pWin;
  3459. for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
  3460. if (depth > focus->traceSize)
  3461. {
  3462. focus->traceSize = depth+1;
  3463. Must_have_memory = TRUE; /* XXX */
  3464. focus->trace = (WindowPtr *)xrealloc(focus->trace,
  3465. focus->traceSize *
  3466. sizeof(WindowPtr));
  3467. Must_have_memory = FALSE; /* XXX */
  3468. }
  3469. focus->traceGood = depth;
  3470. for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
  3471. focus->trace[depth] = pWin;
  3472. }
  3473. return Success;
  3474. }
  3475. int
  3476. ProcSetInputFocus(client)
  3477. ClientPtr client;
  3478. {
  3479. REQUEST(xSetInputFocusReq);
  3480. REQUEST_SIZE_MATCH(xSetInputFocusReq);
  3481. #ifdef XCSECURITY
  3482. if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
  3483. return Success;
  3484. #endif
  3485. return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
  3486. stuff->revertTo, stuff->time, FALSE);
  3487. }
  3488. int
  3489. ProcGetInputFocus(client)
  3490. ClientPtr client;
  3491. {
  3492. xGetInputFocusReply rep;
  3493. /* REQUEST(xReq); */
  3494. FocusClassPtr focus = inputInfo.keyboard->focus;
  3495. REQUEST_SIZE_MATCH(xReq);
  3496. rep.type = X_Reply;
  3497. rep.length = 0;
  3498. rep.sequenceNumber = client->sequence;
  3499. if (focus->win == NoneWin)
  3500. rep.focus = None;
  3501. else if (focus->win == PointerRootWin)
  3502. rep.focus = PointerRoot;
  3503. else rep.focus = focus->win->drawable.id;
  3504. rep.revertTo = focus->revert;
  3505. WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
  3506. return Success;
  3507. }
  3508. int
  3509. ProcGrabPointer(client)
  3510. ClientPtr client;
  3511. {
  3512. xGrabPointerReply rep;
  3513. DeviceIntPtr device = inputInfo.pointer;
  3514. GrabPtr grab;
  3515. WindowPtr pWin, confineTo;
  3516. CursorPtr cursor, oldCursor;
  3517. REQUEST(xGrabPointerReq);
  3518. TimeStamp time;
  3519. REQUEST_SIZE_MATCH(xGrabPointerReq);
  3520. UpdateCurrentTime();
  3521. if ((stuff->pointerMode != GrabModeSync) &&
  3522. (stuff->pointerMode != GrabModeAsync))
  3523. {
  3524. client->errorValue = stuff->pointerMode;
  3525. return BadValue;
  3526. }
  3527. if ((stuff->keyboardMode != GrabModeSync) &&
  3528. (stuff->keyboardMode != GrabModeAsync))
  3529. {
  3530. client->errorValue = stuff->keyboardMode;
  3531. return BadValue;
  3532. }
  3533. if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  3534. {
  3535. client->errorValue = stuff->ownerEvents;
  3536. return BadValue;
  3537. }
  3538. if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  3539. {
  3540. client->errorValue = stuff->eventMask;
  3541. return BadValue;
  3542. }
  3543. pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
  3544. if (!pWin)
  3545. return BadWindow;
  3546. if (stuff->confineTo == None)
  3547. confineTo = NullWindow;
  3548. else
  3549. {
  3550. confineTo = SecurityLookupWindow(stuff->confineTo, client,
  3551. SecurityReadAccess);
  3552. if (!confineTo)
  3553. return BadWindow;
  3554. }
  3555. if (stuff->cursor == None)
  3556. cursor = NullCursor;
  3557. else
  3558. {
  3559. cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
  3560. RT_CURSOR, SecurityReadAccess);
  3561. if (!cursor)
  3562. {
  3563. client->errorValue = stuff->cursor;
  3564. return BadCursor;
  3565. }
  3566. }
  3567. /* at this point, some sort of reply is guaranteed. */
  3568. time = ClientTimeToServerTime(stuff->time);
  3569. rep.type = X_Reply;
  3570. rep.sequenceNumber = client->sequence;
  3571. rep.length = 0;
  3572. grab = device->grab;
  3573. if ((grab) && !SameClient(grab, client))
  3574. rep.status = AlreadyGrabbed;
  3575. else if ((!pWin->realized) ||
  3576. (confineTo &&
  3577. !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
  3578. rep.status = GrabNotViewable;
  3579. else if (device->sync.frozen &&
  3580. device->sync.other && !SameClient(device->sync.other, client))
  3581. rep.status = GrabFrozen;
  3582. else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  3583. (CompareTimeStamps(time, device->grabTime) == EARLIER))
  3584. rep.status = GrabInvalidTime;
  3585. else
  3586. {
  3587. GrabRec tempGrab;
  3588. oldCursor = NullCursor;
  3589. if (grab)
  3590. {
  3591. if (grab->confineTo && !confineTo)
  3592. ConfineCursorToWindow(ROOT, FALSE, FALSE);
  3593. oldCursor = grab->cursor;
  3594. }
  3595. tempGrab.cursor = cursor;
  3596. tempGrab.resource = client->clientAsMask;
  3597. tempGrab.ownerEvents = stuff->ownerEvents;
  3598. tempGrab.eventMask = stuff->eventMask;
  3599. tempGrab.confineTo = confineTo;
  3600. tempGrab.window = pWin;
  3601. tempGrab.keyboardMode = stuff->keyboardMode;
  3602. tempGrab.pointerMode = stuff->pointerMode;
  3603. tempGrab.device = device;
  3604. (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
  3605. if (oldCursor)
  3606. FreeCursor (oldCursor, (Cursor)0);
  3607. rep.status = GrabSuccess;
  3608. }
  3609. WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
  3610. return Success;
  3611. }
  3612. int
  3613. ProcChangeActivePointerGrab(client)
  3614. ClientPtr client;
  3615. {
  3616. DeviceIntPtr device = inputInfo.pointer;
  3617. register GrabPtr grab = device->grab;
  3618. CursorPtr newCursor, oldCursor;
  3619. REQUEST(xChangeActivePointerGrabReq);
  3620. TimeStamp time;
  3621. REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
  3622. if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  3623. {
  3624. client->errorValue = stuff->eventMask;
  3625. return BadValue;
  3626. }
  3627. if (stuff->cursor == None)
  3628. newCursor = NullCursor;
  3629. else
  3630. {
  3631. newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
  3632. RT_CURSOR, SecurityReadAccess);
  3633. if (!newCursor)
  3634. {
  3635. client->errorValue = stuff->cursor;
  3636. return BadCursor;
  3637. }
  3638. }
  3639. if (!grab)
  3640. return Success;
  3641. if (!SameClient(grab, client))
  3642. return Success;
  3643. time = ClientTimeToServerTime(stuff->time);
  3644. if ((CompareTimeStamps(time, currentTime) == LATER) ||
  3645. (CompareTimeStamps(time, device->grabTime) == EARLIER))
  3646. return Success;
  3647. oldCursor = grab->cursor;
  3648. grab->cursor = newCursor;
  3649. if (newCursor)
  3650. newCursor->refcnt++;
  3651. PostNewCursor();
  3652. if (oldCursor)
  3653. FreeCursor(oldCursor, (Cursor)0);
  3654. grab->eventMask = stuff->eventMask;
  3655. return Success;
  3656. }
  3657. int
  3658. ProcUngrabPointer(client)
  3659. ClientPtr client;
  3660. {
  3661. DeviceIntPtr device = inputInfo.pointer;
  3662. GrabPtr grab;
  3663. TimeStamp time;
  3664. REQUEST(xResourceReq);
  3665. REQUEST_SIZE_MATCH(xResourceReq);
  3666. UpdateCurrentTime();
  3667. grab = device->grab;
  3668. time = ClientTimeToServerTime(stuff->id);
  3669. if ((CompareTimeStamps(time, currentTime) != LATER) &&
  3670. (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  3671. (grab) && SameClient(grab, client))
  3672. (*device->DeactivateGrab)(device);
  3673. return Success;
  3674. }
  3675. int
  3676. GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
  3677. mask, status)
  3678. register ClientPtr client;
  3679. register DeviceIntPtr dev;
  3680. unsigned this_mode;
  3681. unsigned other_mode;
  3682. Window grabWindow;
  3683. unsigned ownerEvents;
  3684. Time ctime;
  3685. Mask mask;
  3686. CARD8 *status;
  3687. {
  3688. register WindowPtr pWin;
  3689. register GrabPtr grab;
  3690. TimeStamp time;
  3691. UpdateCurrentTime();
  3692. if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
  3693. {
  3694. client->errorValue = this_mode;
  3695. return BadValue;
  3696. }
  3697. if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
  3698. {
  3699. client->errorValue = other_mode;
  3700. return BadValue;
  3701. }
  3702. if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
  3703. {
  3704. client->errorValue = ownerEvents;
  3705. return BadValue;
  3706. }
  3707. pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
  3708. if (!pWin)
  3709. return BadWindow;
  3710. time = ClientTimeToServerTime(ctime);
  3711. grab = dev->grab;
  3712. if (grab && !SameClient(grab, client))
  3713. *status = AlreadyGrabbed;
  3714. else if (!pWin->realized)
  3715. *status = GrabNotViewable;
  3716. else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  3717. (CompareTimeStamps(time, dev->grabTime) == EARLIER))
  3718. *status = GrabInvalidTime;
  3719. else if (dev->sync.frozen &&
  3720. dev->sync.other && !SameClient(dev->sync.other, client))
  3721. *status = GrabFrozen;
  3722. else
  3723. {
  3724. GrabRec tempGrab;
  3725. tempGrab.window = pWin;
  3726. tempGrab.resource = client->clientAsMask;
  3727. tempGrab.ownerEvents = ownerEvents;
  3728. tempGrab.keyboardMode = this_mode;
  3729. tempGrab.pointerMode = other_mode;
  3730. tempGrab.eventMask = mask;
  3731. tempGrab.device = dev;
  3732. (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
  3733. *status = GrabSuccess;
  3734. }
  3735. return Success;
  3736. }
  3737. int
  3738. ProcGrabKeyboard(client)
  3739. ClientPtr client;
  3740. {
  3741. xGrabKeyboardReply rep;
  3742. REQUEST(xGrabKeyboardReq);
  3743. int result;
  3744. REQUEST_SIZE_MATCH(xGrabKeyboardReq);
  3745. #ifdef XCSECURITY
  3746. if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
  3747. {
  3748. result = Success;
  3749. rep.status = AlreadyGrabbed;
  3750. }
  3751. else
  3752. #endif
  3753. result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
  3754. stuff->pointerMode, stuff->grabWindow,
  3755. stuff->ownerEvents, stuff->time,
  3756. KeyPressMask | KeyReleaseMask, &rep.status);
  3757. if (result != Success)
  3758. return result;
  3759. rep.type = X_Reply;
  3760. rep.sequenceNumber = client->sequence;
  3761. rep.length = 0;
  3762. WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
  3763. return Success;
  3764. }
  3765. int
  3766. ProcUngrabKeyboard(client)
  3767. ClientPtr client;
  3768. {
  3769. DeviceIntPtr device = inputInfo.keyboard;
  3770. GrabPtr grab;
  3771. TimeStamp time;
  3772. REQUEST(xResourceReq);
  3773. REQUEST_SIZE_MATCH(xResourceReq);
  3774. UpdateCurrentTime();
  3775. grab = device->grab;
  3776. time = ClientTimeToServerTime(stuff->id);
  3777. if ((CompareTimeStamps(time, currentTime) != LATER) &&
  3778. (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  3779. (grab) && SameClient(grab, client))
  3780. (*device->DeactivateGrab)(device);
  3781. return Success;
  3782. }
  3783. int
  3784. ProcQueryPointer(client)
  3785. ClientPtr client;
  3786. {
  3787. xQueryPointerReply rep;
  3788. WindowPtr pWin, t;
  3789. REQUEST(xResourceReq);
  3790. DeviceIntPtr mouse = inputInfo.pointer;
  3791. REQUEST_SIZE_MATCH(xResourceReq);
  3792. pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
  3793. if (!pWin)
  3794. return BadWindow;
  3795. if (mouse->valuator->motionHintWindow)
  3796. MaybeStopHint(mouse, client);
  3797. rep.type = X_Reply;
  3798. rep.sequenceNumber = client->sequence;
  3799. rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
  3800. rep.length = 0;
  3801. rep.root = (ROOT)->drawable.id;
  3802. rep.rootX = sprite.hot.x;
  3803. rep.rootY = sprite.hot.y;
  3804. rep.child = None;
  3805. if (sprite.hot.pScreen == pWin->drawable.pScreen)
  3806. {
  3807. rep.sameScreen = xTrue;
  3808. rep.winX = sprite.hot.x - pWin->drawable.x;
  3809. rep.winY = sprite.hot.y - pWin->drawable.y;
  3810. for (t = sprite.win; t; t = t->parent)
  3811. if (t->parent == pWin)
  3812. {
  3813. rep.child = t->drawable.id;
  3814. break;
  3815. }
  3816. }
  3817. else
  3818. {
  3819. rep.sameScreen = xFalse;
  3820. rep.winX = 0;
  3821. rep.winY = 0;
  3822. }
  3823. #ifdef PANORAMIX
  3824. if(!noPanoramiXExtension) {
  3825. rep.rootX += panoramiXdataPtr[0].x;
  3826. rep.rootY += panoramiXdataPtr[0].y;
  3827. if(stuff->id == rep.root) {
  3828. rep.winX += panoramiXdataPtr[0].x;
  3829. rep.winY += panoramiXdataPtr[0].y;
  3830. }
  3831. }
  3832. #endif
  3833. WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
  3834. return(Success);
  3835. }
  3836. void
  3837. InitEvents()
  3838. {
  3839. int i;
  3840. sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
  3841. inputInfo.numDevices = 0;
  3842. inputInfo.devices = (DeviceIntPtr)NULL;
  3843. inputInfo.off_devices = (DeviceIntPtr)NULL;
  3844. inputInfo.keyboard = (DeviceIntPtr)NULL;
  3845. inputInfo.pointer = (DeviceIntPtr)NULL;
  3846. if (spriteTraceSize == 0)
  3847. {
  3848. spriteTraceSize = 32;
  3849. spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
  3850. if (!spriteTrace)
  3851. FatalError("failed to allocate spriteTrace");
  3852. }
  3853. spriteTraceGood = 0;
  3854. lastEventMask = OwnerGrabButtonMask;
  3855. filters[MotionNotify] = PointerMotionMask;
  3856. sprite.win = NullWindow;
  3857. sprite.current = NullCursor;
  3858. sprite.hotLimits.x1 = 0;
  3859. sprite.hotLimits.y1 = 0;
  3860. sprite.hotLimits.x2 = 0;
  3861. sprite.hotLimits.y2 = 0;
  3862. sprite.confined = FALSE;
  3863. syncEvents.replayDev = (DeviceIntPtr)NULL;
  3864. syncEvents.replayWin = NullWindow;
  3865. while (syncEvents.pending)
  3866. {
  3867. QdEventPtr next = syncEvents.pending->next;
  3868. xfree(syncEvents.pending);
  3869. syncEvents.pending = next;
  3870. }
  3871. syncEvents.pendtail = &syncEvents.pending;
  3872. syncEvents.playingEvents = FALSE;
  3873. syncEvents.time.months = 0;
  3874. syncEvents.time.milliseconds = 0; /* hardly matters */
  3875. currentTime.months = 0;
  3876. currentTime.milliseconds = GetTimeInMillis();
  3877. lastDeviceEventTime = currentTime;
  3878. for (i = 0; i < DNPMCOUNT; i++)
  3879. {
  3880. DontPropagateMasks[i] = 0;
  3881. DontPropagateRefCnts[i] = 0;
  3882. }
  3883. }
  3884. void
  3885. CloseDownEvents(void)
  3886. {
  3887. xfree(spriteTrace);
  3888. spriteTrace = NULL;
  3889. spriteTraceSize = 0;
  3890. }
  3891. int
  3892. ProcSendEvent(client)
  3893. ClientPtr client;
  3894. {
  3895. WindowPtr pWin;
  3896. WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
  3897. REQUEST(xSendEventReq);
  3898. REQUEST_SIZE_MATCH(xSendEventReq);
  3899. /* The client's event type must be a core event type or one defined by an
  3900. extension. */
  3901. #ifdef NXAGENT_CLIPBOARD
  3902. if (stuff -> event.u.u.type == SelectionNotify)
  3903. {
  3904. extern int nxagentSendNotify(xEvent*);
  3905. if (nxagentSendNotify(&stuff->event) == 1)
  3906. return Success;
  3907. }
  3908. #endif
  3909. if ( ! ((stuff->event.u.u.type > X_Reply &&
  3910. stuff->event.u.u.type < LASTEvent) ||
  3911. (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
  3912. stuff->event.u.u.type < (unsigned)lastEvent)))
  3913. {
  3914. client->errorValue = stuff->event.u.u.type;
  3915. return BadValue;
  3916. }
  3917. if (stuff->event.u.u.type == ClientMessage &&
  3918. stuff->event.u.u.detail != 8 &&
  3919. stuff->event.u.u.detail != 16 &&
  3920. stuff->event.u.u.detail != 32 &&
  3921. !permitOldBugs)
  3922. {
  3923. client->errorValue = stuff->event.u.u.detail;
  3924. return BadValue;
  3925. }
  3926. if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
  3927. {
  3928. client->errorValue = stuff->eventMask;
  3929. return BadValue;
  3930. }
  3931. if (stuff->destination == PointerWindow)
  3932. pWin = sprite.win;
  3933. else if (stuff->destination == InputFocus)
  3934. {
  3935. WindowPtr inputFocus = inputInfo.keyboard->focus->win;
  3936. if (inputFocus == NoneWin)
  3937. return Success;
  3938. /* If the input focus is PointerRootWin, send the event to where
  3939. the pointer is if possible, then perhaps propogate up to root. */
  3940. if (inputFocus == PointerRootWin)
  3941. inputFocus = ROOT;
  3942. if (IsParent(inputFocus, sprite.win))
  3943. {
  3944. effectiveFocus = inputFocus;
  3945. pWin = sprite.win;
  3946. }
  3947. else
  3948. effectiveFocus = pWin = inputFocus;
  3949. }
  3950. else
  3951. pWin = SecurityLookupWindow(stuff->destination, client,
  3952. SecurityReadAccess);
  3953. if (!pWin)
  3954. return BadWindow;
  3955. if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
  3956. {
  3957. client->errorValue = stuff->propagate;
  3958. return BadValue;
  3959. }
  3960. stuff->event.u.u.type |= 0x80;
  3961. if (stuff->propagate)
  3962. {
  3963. for (;pWin; pWin = pWin->parent)
  3964. {
  3965. if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  3966. NullGrab, 0))
  3967. return Success;
  3968. if (pWin == effectiveFocus)
  3969. return Success;
  3970. stuff->eventMask &= ~wDontPropagateMask(pWin);
  3971. if (!stuff->eventMask)
  3972. break;
  3973. }
  3974. }
  3975. else
  3976. (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  3977. NullGrab, 0);
  3978. return Success;
  3979. }
  3980. int
  3981. ProcUngrabKey(client)
  3982. ClientPtr client;
  3983. {
  3984. REQUEST(xUngrabKeyReq);
  3985. WindowPtr pWin;
  3986. GrabRec tempGrab;
  3987. DeviceIntPtr keybd = inputInfo.keyboard;
  3988. REQUEST_SIZE_MATCH(xUngrabKeyReq);
  3989. pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
  3990. if (!pWin)
  3991. return BadWindow;
  3992. if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
  3993. (stuff->key < keybd->key->curKeySyms.minKeyCode))
  3994. && (stuff->key != AnyKey))
  3995. {
  3996. client->errorValue = stuff->key;
  3997. return BadValue;
  3998. }
  3999. if ((stuff->modifiers != AnyModifier) &&
  4000. (stuff->modifiers & ~AllModifiersMask))
  4001. {
  4002. client->errorValue = stuff->modifiers;
  4003. return BadValue;
  4004. }
  4005. tempGrab.resource = client->clientAsMask;
  4006. tempGrab.device = keybd;
  4007. tempGrab.window = pWin;
  4008. tempGrab.modifiersDetail.exact = stuff->modifiers;
  4009. tempGrab.modifiersDetail.pMask = NULL;
  4010. tempGrab.modifierDevice = inputInfo.keyboard;
  4011. tempGrab.type = KeyPress;
  4012. tempGrab.detail.exact = stuff->key;
  4013. tempGrab.detail.pMask = NULL;
  4014. if (!DeletePassiveGrabFromList(&tempGrab))
  4015. return(BadAlloc);
  4016. return(Success);
  4017. }
  4018. int
  4019. ProcGrabKey(client)
  4020. ClientPtr client;
  4021. {
  4022. WindowPtr pWin;
  4023. REQUEST(xGrabKeyReq);
  4024. GrabPtr grab;
  4025. DeviceIntPtr keybd = inputInfo.keyboard;
  4026. REQUEST_SIZE_MATCH(xGrabKeyReq);
  4027. if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
  4028. {
  4029. client->errorValue = stuff->ownerEvents;
  4030. return(BadValue);
  4031. }
  4032. if ((stuff->pointerMode != GrabModeSync) &&
  4033. (stuff->pointerMode != GrabModeAsync))
  4034. {
  4035. client->errorValue = stuff->pointerMode;
  4036. return BadValue;
  4037. }
  4038. if ((stuff->keyboardMode != GrabModeSync) &&
  4039. (stuff->keyboardMode != GrabModeAsync))
  4040. {
  4041. client->errorValue = stuff->keyboardMode;
  4042. return BadValue;
  4043. }
  4044. if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
  4045. (stuff->key < keybd->key->curKeySyms.minKeyCode))
  4046. && (stuff->key != AnyKey))
  4047. {
  4048. client->errorValue = stuff->key;
  4049. return BadValue;
  4050. }
  4051. if ((stuff->modifiers != AnyModifier) &&
  4052. (stuff->modifiers & ~AllModifiersMask))
  4053. {
  4054. client->errorValue = stuff->modifiers;
  4055. return BadValue;
  4056. }
  4057. pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
  4058. if (!pWin)
  4059. return BadWindow;
  4060. grab = CreateGrab(client->index, keybd, pWin,
  4061. (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
  4062. (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
  4063. keybd, stuff->modifiers, KeyPress, stuff->key,
  4064. NullWindow, NullCursor);
  4065. if (!grab)
  4066. return BadAlloc;
  4067. return AddPassiveGrabToList(grab);
  4068. }
  4069. int
  4070. ProcGrabButton(client)
  4071. ClientPtr client;
  4072. {
  4073. WindowPtr pWin, confineTo;
  4074. REQUEST(xGrabButtonReq);
  4075. CursorPtr cursor;
  4076. GrabPtr grab;
  4077. REQUEST_SIZE_MATCH(xGrabButtonReq);
  4078. if ((stuff->pointerMode != GrabModeSync) &&
  4079. (stuff->pointerMode != GrabModeAsync))
  4080. {
  4081. client->errorValue = stuff->pointerMode;
  4082. return BadValue;
  4083. }
  4084. if ((stuff->keyboardMode != GrabModeSync) &&
  4085. (stuff->keyboardMode != GrabModeAsync))
  4086. {
  4087. client->errorValue = stuff->keyboardMode;
  4088. return BadValue;
  4089. }
  4090. if ((stuff->modifiers != AnyModifier) &&
  4091. (stuff->modifiers & ~AllModifiersMask))
  4092. {
  4093. client->errorValue = stuff->modifiers;
  4094. return BadValue;
  4095. }
  4096. if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  4097. {
  4098. client->errorValue = stuff->ownerEvents;
  4099. return BadValue;
  4100. }
  4101. if (stuff->eventMask & ~PointerGrabMask)
  4102. {
  4103. client->errorValue = stuff->eventMask;
  4104. return BadValue;
  4105. }
  4106. pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
  4107. if (!pWin)
  4108. return BadWindow;
  4109. if (stuff->confineTo == None)
  4110. confineTo = NullWindow;
  4111. else {
  4112. confineTo = SecurityLookupWindow(stuff->confineTo, client,
  4113. SecurityReadAccess);
  4114. if (!confineTo)
  4115. return BadWindow;
  4116. }
  4117. if (stuff->cursor == None)
  4118. cursor = NullCursor;
  4119. else
  4120. {
  4121. cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
  4122. RT_CURSOR, SecurityReadAccess);
  4123. if (!cursor)
  4124. {
  4125. client->errorValue = stuff->cursor;
  4126. return BadCursor;
  4127. }
  4128. }
  4129. grab = CreateGrab(client->index, inputInfo.pointer, pWin,
  4130. permitOldBugs ? (Mask)(stuff->eventMask |
  4131. ButtonPressMask | ButtonReleaseMask) :
  4132. (Mask)stuff->eventMask,
  4133. (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
  4134. (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
  4135. ButtonPress, stuff->button, confineTo, cursor);
  4136. if (!grab)
  4137. return BadAlloc;
  4138. return AddPassiveGrabToList(grab);
  4139. }
  4140. int
  4141. ProcUngrabButton(client)
  4142. ClientPtr client;
  4143. {
  4144. REQUEST(xUngrabButtonReq);
  4145. WindowPtr pWin;
  4146. GrabRec tempGrab;
  4147. REQUEST_SIZE_MATCH(xUngrabButtonReq);
  4148. if ((stuff->modifiers != AnyModifier) &&
  4149. (stuff->modifiers & ~AllModifiersMask))
  4150. {
  4151. client->errorValue = stuff->modifiers;
  4152. return BadValue;
  4153. }
  4154. pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
  4155. if (!pWin)
  4156. return BadWindow;
  4157. tempGrab.resource = client->clientAsMask;
  4158. tempGrab.device = inputInfo.pointer;
  4159. tempGrab.window = pWin;
  4160. tempGrab.modifiersDetail.exact = stuff->modifiers;
  4161. tempGrab.modifiersDetail.pMask = NULL;
  4162. tempGrab.modifierDevice = inputInfo.keyboard;
  4163. tempGrab.type = ButtonPress;
  4164. tempGrab.detail.exact = stuff->button;
  4165. tempGrab.detail.pMask = NULL;
  4166. if (!DeletePassiveGrabFromList(&tempGrab))
  4167. return(BadAlloc);
  4168. return(Success);
  4169. }
  4170. void
  4171. DeleteWindowFromAnyEvents(pWin, freeResources)
  4172. WindowPtr pWin;
  4173. Bool freeResources;
  4174. {
  4175. WindowPtr parent;
  4176. DeviceIntPtr mouse = inputInfo.pointer;
  4177. DeviceIntPtr keybd = inputInfo.keyboard;
  4178. FocusClassPtr focus = keybd->focus;
  4179. OtherClientsPtr oc;
  4180. GrabPtr passive;
  4181. /* Deactivate any grabs performed on this window, before making any
  4182. input focus changes. */
  4183. if (mouse->grab &&
  4184. ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
  4185. (*mouse->DeactivateGrab)(mouse);
  4186. /* Deactivating a keyboard grab should cause focus events. */
  4187. if (keybd->grab && (keybd->grab->window == pWin))
  4188. (*keybd->DeactivateGrab)(keybd);
  4189. /* If the focus window is a root window (ie. has no parent) then don't
  4190. delete the focus from it. */
  4191. if ((pWin == focus->win) && (pWin->parent != NullWindow))
  4192. {
  4193. int focusEventMode = NotifyNormal;
  4194. /* If a grab is in progress, then alter the mode of focus events. */
  4195. if (keybd->grab)
  4196. focusEventMode = NotifyWhileGrabbed;
  4197. switch (focus->revert)
  4198. {
  4199. case RevertToNone:
  4200. DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
  4201. focus->win = NoneWin;
  4202. focus->traceGood = 0;
  4203. break;
  4204. case RevertToParent:
  4205. parent = pWin;
  4206. do
  4207. {
  4208. parent = parent->parent;
  4209. focus->traceGood--;
  4210. } while (!parent->realized
  4211. /* This would be a good protocol change -- windows being reparented
  4212. during SaveSet processing would cause the focus to revert to the
  4213. nearest enclosing window which will survive the death of the exiting
  4214. client, instead of ending up reverting to a dying window and thence
  4215. to None
  4216. */
  4217. #ifdef NOTDEF
  4218. || clients[CLIENT_ID(parent->drawable.id)]->clientGone
  4219. #endif
  4220. );
  4221. DoFocusEvents(keybd, pWin, parent, focusEventMode);
  4222. focus->win = parent;
  4223. focus->revert = RevertToNone;
  4224. break;
  4225. case RevertToPointerRoot:
  4226. DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
  4227. focus->win = PointerRootWin;
  4228. focus->traceGood = 0;
  4229. break;
  4230. }
  4231. }
  4232. if (mouse->valuator->motionHintWindow == pWin)
  4233. mouse->valuator->motionHintWindow = NullWindow;
  4234. if (freeResources)
  4235. {
  4236. if (pWin->dontPropagate)
  4237. DontPropagateRefCnts[pWin->dontPropagate]--;
  4238. while ( (oc = wOtherClients(pWin)) )
  4239. FreeResource(oc->resource, RT_NONE);
  4240. while ( (passive = wPassiveGrabs(pWin)) )
  4241. FreeResource(passive->resource, RT_NONE);
  4242. }
  4243. #ifdef XINPUT
  4244. DeleteWindowFromAnyExtEvents(pWin, freeResources);
  4245. #endif
  4246. }
  4247. /* Call this whenever some window at or below pWin has changed geometry */
  4248. /*ARGSUSED*/
  4249. void
  4250. CheckCursorConfinement(pWin)
  4251. WindowPtr pWin;
  4252. {
  4253. GrabPtr grab = inputInfo.pointer->grab;
  4254. WindowPtr confineTo;
  4255. #ifdef PANORAMIX
  4256. if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
  4257. #endif
  4258. if (grab && (confineTo = grab->confineTo))
  4259. {
  4260. if (!BorderSizeNotEmpty(confineTo))
  4261. (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
  4262. else if ((pWin == confineTo) || IsParent(pWin, confineTo))
  4263. ConfineCursorToWindow(confineTo, TRUE, TRUE);
  4264. }
  4265. }
  4266. Mask
  4267. EventMaskForClient(pWin, client)
  4268. WindowPtr pWin;
  4269. ClientPtr client;
  4270. {
  4271. register OtherClientsPtr other;
  4272. if (wClient (pWin) == client)
  4273. return pWin->eventMask;
  4274. for (other = wOtherClients(pWin); other; other = other->next)
  4275. {
  4276. if (SameClient(other, client))
  4277. return other->mask;
  4278. }
  4279. return 0;
  4280. }
  4281. int
  4282. ProcRecolorCursor(client)
  4283. ClientPtr client;
  4284. {
  4285. CursorPtr pCursor;
  4286. int nscr;
  4287. ScreenPtr pscr;
  4288. Bool displayed;
  4289. REQUEST(xRecolorCursorReq);
  4290. REQUEST_SIZE_MATCH(xRecolorCursorReq);
  4291. pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
  4292. RT_CURSOR, SecurityWriteAccess);
  4293. if ( !pCursor)
  4294. {
  4295. client->errorValue = stuff->cursor;
  4296. return (BadCursor);
  4297. }
  4298. pCursor->foreRed = stuff->foreRed;
  4299. pCursor->foreGreen = stuff->foreGreen;
  4300. pCursor->foreBlue = stuff->foreBlue;
  4301. pCursor->backRed = stuff->backRed;
  4302. pCursor->backGreen = stuff->backGreen;
  4303. pCursor->backBlue = stuff->backBlue;
  4304. for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
  4305. {
  4306. pscr = screenInfo.screens[nscr];
  4307. #ifdef PANORAMIX
  4308. if(!noPanoramiXExtension)
  4309. displayed = (pscr == sprite.screen);
  4310. else
  4311. #endif
  4312. displayed = (pscr == sprite.hotPhys.pScreen);
  4313. ( *pscr->RecolorCursor)(pscr, pCursor,
  4314. (pCursor == sprite.current) && displayed);
  4315. }
  4316. return (Success);
  4317. }
  4318. void
  4319. WriteEventsToClient(pClient, count, events)
  4320. ClientPtr pClient;
  4321. int count;
  4322. xEvent *events;
  4323. {
  4324. #ifdef PANORAMIX
  4325. xEvent eventCopy;
  4326. #endif
  4327. xEvent eventTo, *eventFrom;
  4328. int i;
  4329. #ifdef XKB
  4330. if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
  4331. return;
  4332. #endif
  4333. #ifdef PANORAMIX
  4334. if(!noPanoramiXExtension &&
  4335. (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
  4336. {
  4337. switch(events->u.u.type) {
  4338. case MotionNotify:
  4339. case ButtonPress:
  4340. case ButtonRelease:
  4341. case KeyPress:
  4342. case KeyRelease:
  4343. case EnterNotify:
  4344. case LeaveNotify:
  4345. /*
  4346. When multiple clients want the same event DeliverEventsToWindow
  4347. passes the same event structure multiple times so we can't
  4348. modify the one passed to us
  4349. */
  4350. count = 1; /* should always be 1 */
  4351. memcpy(&eventCopy, events, sizeof(xEvent));
  4352. eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
  4353. eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
  4354. if(eventCopy.u.keyButtonPointer.event ==
  4355. eventCopy.u.keyButtonPointer.root)
  4356. {
  4357. eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
  4358. eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
  4359. }
  4360. events = &eventCopy;
  4361. break;
  4362. default: break;
  4363. }
  4364. }
  4365. #endif
  4366. if (EventCallback)
  4367. {
  4368. EventInfoRec eventinfo;
  4369. eventinfo.client = pClient;
  4370. eventinfo.events = events;
  4371. eventinfo.count = count;
  4372. CallCallbacks(&EventCallback, (pointer)&eventinfo);
  4373. }
  4374. if(pClient->swapped)
  4375. {
  4376. for(i = 0; i < count; i++)
  4377. {
  4378. eventFrom = &events[i];
  4379. /* Remember to strip off the leading bit of type in case
  4380. this event was sent with "SendEvent." */
  4381. (*EventSwapVector[eventFrom->u.u.type & 0177])
  4382. (eventFrom, &eventTo);
  4383. (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
  4384. }
  4385. }
  4386. else
  4387. {
  4388. (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
  4389. }
  4390. }
  4391. #endif /* #ifdef NXAGENT_UPGRADE */