PageRenderTime 82ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 1ms

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

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