PageRenderTime 41ms CodeModel.GetById 1ms 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

Large files files are truncated, but you can click here to view the full file

  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. XineramaTryClientEventsRe

Large files files are truncated, but you can click here to view the full file