home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / dix / events.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  90.2 KB  |  3,463 lines

  1. /************************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ********************************************************/
  24.  
  25.  
  26. /* $XConsortium: events.c,v 5.54 92/03/19 11:30:46 rws Exp $ */
  27.  
  28. #include "X.h"
  29. #include "misc.h"
  30. #include "resource.h"
  31. #define NEED_EVENTS
  32. #define NEED_REPLIES
  33. #include "Xproto.h"
  34. #include "windowstr.h"
  35. #include "inputstr.h"
  36. #include "scrnintstr.h"
  37. #include "cursorstr.h"
  38.  
  39. #include "dixstruct.h"
  40.  
  41. extern WindowPtr *WindowTable;
  42.  
  43. extern void (* EventSwapVector[128]) ();
  44. extern void (* ReplySwapVector[256]) ();
  45. extern void SetCriticalOutputPending();
  46.  
  47. #define EXTENSION_EVENT_BASE  64
  48.  
  49. #define NoSuchEvent 0x80000000    /* so doesn't match NoEventMask */
  50. #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
  51. #define AllButtonsMask ( \
  52.     Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
  53. #define MotionMask ( \
  54.     PointerMotionMask | Button1MotionMask | \
  55.     Button2MotionMask | Button3MotionMask | Button4MotionMask | \
  56.     Button5MotionMask | ButtonMotionMask )
  57. #define PropagateMask ( \
  58.     KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
  59.     MotionMask )
  60. #define PointerGrabMask ( \
  61.     ButtonPressMask | ButtonReleaseMask | \
  62.     EnterWindowMask | LeaveWindowMask | \
  63.     PointerMotionHintMask | KeymapStateMask | \
  64.     MotionMask )
  65. #define AllModifiersMask ( \
  66.     ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
  67.     Mod3Mask | Mod4Mask | Mod5Mask )
  68. #define AllEventMasks (lastEventMask|(lastEventMask-1))
  69. /*
  70.  * The following relies on the fact that the Button<n>MotionMasks are equal
  71.  * to the corresponding Button<n>Masks from the current modifier/button state.
  72.  */
  73. #define Motion_Filter(class) (PointerMotionMask | \
  74.                   (class)->state | (class)->motionMask)
  75.  
  76.  
  77. #define WID(w) ((w) ? ((w)->drawable.id) : 0)
  78.  
  79. #define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
  80.  
  81. #define DNPMCOUNT 8
  82.  
  83. Mask DontPropagateMasks[DNPMCOUNT];
  84. static int DontPropagateRefCnts[DNPMCOUNT];
  85.  
  86. #ifdef DEBUG
  87. static debug_events = 0;
  88. #endif
  89. InputInfo inputInfo;
  90.  
  91. static struct {
  92.     QdEventPtr        pending, *pendtail;
  93.     DeviceIntPtr    replayDev;    /* kludgy rock to put flag for */
  94.     WindowPtr        replayWin;    /*   ComputeFreezes            */
  95.     Bool        playingEvents;
  96.     TimeStamp        time;
  97. } syncEvents;
  98.  
  99. /*
  100.  * The window trace information is used to avoid having to compute all the
  101.  * windows between the root and the current pointer window each time a button
  102.  * or key goes down. The grabs on each of those windows must be checked.
  103.  */
  104. static WindowPtr *spriteTrace = (WindowPtr *)NULL;
  105. #define ROOT spriteTrace[0]
  106. static int spriteTraceSize = 0;
  107. static int spriteTraceGood;
  108.  
  109. typedef struct {
  110.     int        x, y;
  111.     ScreenPtr    pScreen;
  112. } HotSpot;
  113.  
  114. static  struct {
  115.     CursorPtr    current;
  116.     BoxRec    hotLimits;    /* logical constraints of hot spot */
  117. #ifdef SHAPE
  118.     RegionPtr    hotShape;    /* additional logical shape constraint */
  119. #endif
  120.     BoxRec    physLimits;    /* physical constraints of hot spot */
  121.     WindowPtr    win;        /* window of logical position */
  122.     HotSpot    hot;        /* logical pointer position */
  123.     HotSpot    hotPhys;    /* physical pointer position */
  124. } sprite;            /* info about the cursor sprite */
  125.  
  126. static void DoEnterLeaveEvents();    /* merely forward declarations */
  127. static WindowPtr XYToWindow();
  128. void DeliverFocusedEvent();
  129. int DeliverDeviceEvents();
  130. void DoFocusEvents();
  131. Mask EventMaskForClient();
  132. void WriteEventsToClient();
  133. Bool CheckDeviceGrabs();
  134. void NewCurrentScreen();
  135. void EnqueueEvent();
  136.  
  137. extern void MaybeStopHint();
  138.  
  139. extern GrabPtr CreateGrab();        /* Defined in grabs.c */
  140. extern Bool GrabMatchesSecond();
  141. extern Bool DeletePassiveGrabFromList();
  142. extern int AddPassiveGrabToList();
  143.  
  144. extern Bool permitOldBugs;
  145. extern Bool Must_have_memory;
  146.  
  147. static Mask lastEventMask;
  148.  
  149. #define CantBeFiltered NoEventMask
  150. static Mask filters[128] =
  151. {
  152.     NoSuchEvent,               /* 0 */
  153.     NoSuchEvent,               /* 1 */
  154.     KeyPressMask,               /* KeyPress */
  155.     KeyReleaseMask,               /* KeyRelease */
  156.     ButtonPressMask,           /* ButtonPress */
  157.     ButtonReleaseMask,           /* ButtonRelease */
  158.     PointerMotionMask,           /* MotionNotify (initial state) */
  159.     EnterWindowMask,           /* EnterNotify */
  160.     LeaveWindowMask,           /* LeaveNotify */
  161.     FocusChangeMask,           /* FocusIn */
  162.     FocusChangeMask,           /* FocusOut */
  163.     KeymapStateMask,           /* KeymapNotify */
  164.     ExposureMask,               /* Expose */
  165.     CantBeFiltered,               /* GraphicsExpose */
  166.     CantBeFiltered,               /* NoExpose */
  167.     VisibilityChangeMask,           /* VisibilityNotify */
  168.     SubstructureNotifyMask,           /* CreateNotify */
  169.     StructureAndSubMask,           /* DestroyNotify */
  170.     StructureAndSubMask,           /* UnmapNotify */
  171.     StructureAndSubMask,           /* MapNotify */
  172.     SubstructureRedirectMask,      /* MapRequest */
  173.     StructureAndSubMask,           /* ReparentNotify */
  174.     StructureAndSubMask,           /* ConfigureNotify */
  175.     SubstructureRedirectMask,      /* ConfigureRequest */
  176.     StructureAndSubMask,           /* GravityNotify */
  177.     ResizeRedirectMask,           /* ResizeRequest */
  178.     StructureAndSubMask,           /* CirculateNotify */
  179.     SubstructureRedirectMask,      /* CirculateRequest */
  180.     PropertyChangeMask,           /* PropertyNotify */
  181.     CantBeFiltered,               /* SelectionClear */
  182.     CantBeFiltered,               /* SelectionRequest */
  183.     CantBeFiltered,               /* SelectionNotify */
  184.     ColormapChangeMask,           /* ColormapNotify */
  185.     CantBeFiltered,               /* ClientMessage */
  186.     CantBeFiltered               /* MappingNotify */
  187. };
  188.  
  189. static CARD8 criticalEvents[32] =
  190. {
  191.     0x3c                /* key and button events */
  192. };
  193.  
  194. Mask
  195. GetNextEventMask()
  196. {
  197.     lastEventMask <<= 1;
  198.     return lastEventMask;
  199. }
  200.  
  201. void
  202. SetMaskForEvent(mask, event)
  203.     Mask mask;
  204.     int event;
  205. {
  206.     if ((event < LASTEvent) || (event >= 128))
  207.     FatalError("SetMaskForEvent: bogus event number");
  208.     filters[event] = mask;
  209. }
  210.  
  211. void
  212. SetCriticalEvent(event)
  213.     int event;
  214. {
  215.     if (event >= 128)
  216.     FatalError("SetCriticalEvent: bogus event number");
  217.     criticalEvents[event >> 3] |= 1 << (event & 7);
  218. }
  219.  
  220. static void
  221. SyntheticMotion(x, y)
  222.     int x, y;
  223. {
  224.     xEvent xE;
  225.  
  226.     xE.u.keyButtonPointer.rootX = x;
  227.     xE.u.keyButtonPointer.rootY = y;
  228.     if (syncEvents.playingEvents)
  229.     xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
  230.     else
  231.     xE.u.keyButtonPointer.time = currentTime.milliseconds;
  232.     xE.u.u.type = MotionNotify;
  233.     (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
  234. }
  235.  
  236. #ifdef SHAPE
  237. static void
  238. ConfineToShape(shape, px, py)
  239.     RegionPtr shape;
  240.     int *px, *py;
  241. {
  242.     BoxRec box;
  243.     int x = *px, y = *py;
  244.     int incx = 1, incy = 1;
  245.  
  246.     if ((*sprite.hot.pScreen->PointInRegion)(shape, x, y, &box))
  247.     return;
  248.     box = *(*sprite.hot.pScreen->RegionExtents)(shape);
  249.     /* this is rather crude */
  250.     do {
  251.     x += incx;
  252.     if (x >= box.x2)
  253.     {
  254.         incx = -1;
  255.         x = *px - 1;
  256.     }
  257.     else if (x < box.x1)
  258.     {
  259.         incx = 1;
  260.         x = *px;
  261.         y += incy;
  262.         if (y >= box.y2)
  263.         {
  264.         incy = -1;
  265.         y = *py - 1;
  266.         }
  267.         else if (y < box.y1)
  268.         return; /* should never get here! */
  269.     }
  270.     } while (!(*sprite.hot.pScreen->PointInRegion)(shape, x, y, &box));
  271.     *px = x;
  272.     *py = y;
  273. }
  274. #endif
  275.  
  276. static void
  277. CheckPhysLimits(cursor, generateEvents, pScreen)
  278.     CursorPtr cursor;
  279.     Bool generateEvents;
  280.     ScreenPtr pScreen;
  281. {
  282.     HotSpot new;
  283.  
  284.     if (!cursor)
  285.     return;
  286.     new = sprite.hotPhys;
  287.     if (pScreen)
  288.     new.pScreen = pScreen;
  289.     else
  290.     pScreen = new.pScreen;
  291.     (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
  292.                   &sprite.physLimits);
  293.     (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
  294.     if (new.x < sprite.physLimits.x1)
  295.     new.x = sprite.physLimits.x1;
  296.     else
  297.     if (new.x >= sprite.physLimits.x2)
  298.         new.x = sprite.physLimits.x2 - 1;
  299.     if (new.y < sprite.physLimits.y1)
  300.     new.y = sprite.physLimits.y1;
  301.     else
  302.     if (new.y >= sprite.physLimits.y2)
  303.         new.y = sprite.physLimits.y2 - 1;
  304. #ifdef SHAPE
  305.     if (sprite.hotShape)
  306.     ConfineToShape(sprite.hotShape, &new.x, &new.y);
  307. #endif
  308.     if ((pScreen != sprite.hotPhys.pScreen) ||
  309.     (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
  310.     {
  311.     if (pScreen != sprite.hotPhys.pScreen)
  312.         sprite.hotPhys = new;
  313.     (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
  314.     if (!generateEvents)
  315.         SyntheticMotion(new.x, new.y);
  316.     }
  317. }
  318.  
  319. static void
  320. CheckVirtualMotion(qe, pWin)
  321.     register QdEventPtr qe;
  322.     register WindowPtr pWin;
  323. {
  324.  
  325.     if (qe)
  326.     {
  327.     sprite.hot.pScreen = qe->pScreen;
  328.     sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
  329.     sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
  330.     pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
  331.                      NullWindow;
  332.     }
  333.     if (pWin)
  334.     {
  335.     BoxRec lims;
  336.  
  337.     if (sprite.hot.pScreen != pWin->drawable.pScreen)
  338.     {
  339.         sprite.hot.pScreen = pWin->drawable.pScreen;
  340.         sprite.hot.x = sprite.hot.y = 0;
  341.     }
  342.     lims = *(*pWin->drawable.pScreen->RegionExtents)(&pWin->borderSize);
  343.     if (sprite.hot.x < lims.x1)
  344.         sprite.hot.x = lims.x1;
  345.     else if (sprite.hot.x >= lims.x2)
  346.         sprite.hot.x = lims.x2 - 1;
  347.     if (sprite.hot.y < lims.y1)
  348.         sprite.hot.y = lims.y1;
  349.     else if (sprite.hot.y >= lims.y2)
  350.         sprite.hot.y = lims.y2 - 1;
  351. #ifdef SHAPE
  352.     if (wBoundingShape(pWin))
  353.         ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
  354. #endif
  355.     if (qe)
  356.     {
  357.         qe->pScreen = sprite.hot.pScreen;
  358.         qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
  359.         qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
  360.     }
  361.     }
  362.     ROOT = WindowTable[sprite.hot.pScreen->myNum];
  363. }
  364.  
  365. static void
  366. ConfineCursorToWindow(pWin, generateEvents)
  367.     WindowPtr pWin;
  368.     Bool generateEvents;
  369. {
  370.     ScreenPtr pScreen = pWin->drawable.pScreen;
  371.  
  372.     if (syncEvents.playingEvents)
  373.     {
  374.     CheckVirtualMotion((QdEventPtr)NULL, pWin);
  375.     SyntheticMotion(sprite.hot.x, sprite.hot.y);
  376.     }
  377.     else
  378.     {
  379.     sprite.hotLimits = *(* pScreen->RegionExtents)(&pWin->borderSize);
  380. #ifdef SHAPE
  381.     sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
  382.                            : NullRegion;
  383. #endif
  384.     CheckPhysLimits(sprite.current, generateEvents, pScreen);
  385.     }
  386. }
  387.  
  388. Bool
  389. PointerConfinedToScreen()
  390. {
  391.     register GrabPtr grab = inputInfo.pointer->grab;
  392.  
  393.     return (grab && grab->confineTo);
  394. }
  395.  
  396. static void
  397. ChangeToCursor(cursor)
  398.     CursorPtr cursor;
  399. {
  400.     if (cursor != sprite.current)
  401.     {
  402.     if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
  403.         (sprite.current->bits->yhot != cursor->bits->yhot))
  404.         CheckPhysLimits(cursor, FALSE, (ScreenPtr)NULL);
  405.     (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
  406.                           cursor);
  407.     sprite.current = cursor;
  408.     }
  409. }
  410.  
  411. /* returns true if b is a descendent of a */
  412. Bool
  413. IsParent(a, b)
  414.     register WindowPtr a, b;
  415. {
  416.     for (b = b->parent; b; b = b->parent)
  417.     if (b == a) return TRUE;
  418.     return FALSE;
  419. }
  420.  
  421. static void
  422. PostNewCursor()
  423. {
  424.     register    WindowPtr win;
  425.     register    GrabPtr grab = inputInfo.pointer->grab;
  426.  
  427.     if (syncEvents.playingEvents)
  428.     return;
  429.     if (grab)
  430.     {
  431.     if (grab->cursor)
  432.     {
  433.         ChangeToCursor(grab->cursor);
  434.         return;
  435.     }
  436.     if (IsParent(grab->window, sprite.win))
  437.         win = sprite.win;
  438.     else
  439.         win = grab->window;
  440.     }
  441.     else
  442.     win = sprite.win;
  443.     for (; win; win = win->parent)
  444.     if (win->optional && win->optional->cursor != NullCursor)
  445.     {
  446.         ChangeToCursor(win->optional->cursor);
  447.         return;
  448.     }
  449. }
  450.  
  451. WindowPtr
  452. GetCurrentRootWindow()
  453. {
  454.     return ROOT;
  455. }
  456.  
  457. WindowPtr
  458. GetSpriteWindow()
  459. {
  460.     return sprite.win;
  461. }
  462.  
  463. CursorPtr
  464. GetSpriteCursor()
  465. {
  466.     return sprite.current;
  467. }
  468.  
  469. void
  470. GetSpritePosition(px, py)
  471.     int *px, *py;
  472. {
  473.     *px = sprite.hotPhys.x;
  474.     *py = sprite.hotPhys.y;
  475. }
  476.  
  477. #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
  478.  
  479. static void
  480. MonthChangedOrBadTime(xE)
  481.     register xEvent *xE;
  482. {
  483.     /* If the ddx/OS is careless about not processing timestamped events from
  484.      * different sources in sorted order, then it's possible for time to go
  485.      * backwards when it should not.  Here we ensure a decent time.
  486.      */
  487.     if ((currentTime.milliseconds - xE->u.keyButtonPointer.time) > TIMESLOP)
  488.     currentTime.months++;
  489.     else
  490.     xE->u.keyButtonPointer.time = currentTime.milliseconds;
  491. }
  492.  
  493. #define NoticeTime(xE) { \
  494.     if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
  495.     MonthChangedOrBadTime(xE); \
  496.     currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
  497.     lastDeviceEventTime = currentTime; }
  498.  
  499. void
  500. NoticeEventTime(xE)
  501.     register xEvent *xE;
  502. {
  503.     if (!syncEvents.playingEvents)
  504.     NoticeTime(xE);
  505. }
  506.  
  507. /**************************************************************************
  508.  *            The following procedures deal with synchronous events       *
  509.  **************************************************************************/
  510.  
  511. void
  512. EnqueueEvent(xE, device, count)
  513.     xEvent        *xE;
  514.     DeviceIntPtr    device;
  515.     int            count;
  516. {
  517.     register QdEventPtr tail = *syncEvents.pendtail;
  518.     register QdEventPtr qe;
  519.     xEvent        *qxE;
  520.  
  521.     NoticeTime(xE)
  522.     if (xE->u.u.type == MotionNotify)
  523.     {
  524.     sprite.hotPhys.x = xE->u.keyButtonPointer.rootX;
  525.     sprite.hotPhys.y = xE->u.keyButtonPointer.rootY;
  526.     /* do motion compression */
  527.     if (tail &&
  528.         (tail->event->u.u.type == MotionNotify) &&
  529.         (tail->pScreen == sprite.hotPhys.pScreen))
  530.     {
  531.         tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
  532.         tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
  533.         tail->event->u.keyButtonPointer.time = xE->u.keyButtonPointer.time;
  534.         tail->months = currentTime.months;
  535.         return;
  536.     }
  537.     }
  538.     qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
  539.     if (!qe)
  540.     return;
  541.     qe->next = (QdEventPtr)NULL;
  542.     qe->device = device;
  543.     qe->pScreen = sprite.hotPhys.pScreen;
  544.     qe->months = currentTime.months;
  545.     qe->event = (xEvent *)(qe + 1);
  546.     qe->evcount = count;
  547.     for (qxE = qe->event; --count >= 0; qxE++, xE++)
  548.     *qxE = *xE;
  549.     if (tail)
  550.     syncEvents.pendtail = &tail->next;
  551.     *syncEvents.pendtail = qe;
  552. }
  553.  
  554. static void
  555. PlayReleasedEvents()
  556. {
  557.     register QdEventPtr *prev, qe;
  558.     register DeviceIntPtr dev;
  559.  
  560.     prev = &syncEvents.pending;
  561.     while (qe = *prev)
  562.     {
  563.     if (!qe->device->sync.frozen)
  564.     {
  565.         *prev = qe->next;
  566.         if (*syncEvents.pendtail == *prev)
  567.         syncEvents.pendtail = prev;
  568.         if (qe->event->u.u.type == MotionNotify)
  569.         CheckVirtualMotion(qe, NullWindow);
  570.         syncEvents.time.months = qe->months;
  571.         syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
  572.         (*qe->device->public.processInputProc)(qe->event, qe->device,
  573.                            qe->evcount);
  574.         xfree(qe);
  575.         for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
  576.         ;
  577.         if (!dev)
  578.         break;
  579.         /* Playing the event may have unfrozen another device. */
  580.         /* So to play it safe, restart at the head of the queue */
  581.         prev = &syncEvents.pending;
  582.     }
  583.     else
  584.         prev = &qe->next;
  585.     } 
  586. }
  587.  
  588. static void
  589. FreezeThaw(dev, frozen)
  590.     register DeviceIntPtr dev;
  591.     Bool frozen;
  592. {
  593.     dev->sync.frozen = frozen;
  594.     if (frozen)
  595.     dev->public.processInputProc = dev->public.enqueueInputProc;
  596.     else
  597.     dev->public.processInputProc = dev->public.realInputProc;
  598. }
  599.  
  600. void
  601. ComputeFreezes()
  602. {
  603.     register DeviceIntPtr replayDev = syncEvents.replayDev;
  604.     register int i;
  605.     WindowPtr w;
  606.     register xEvent *xE;
  607.     int count;
  608.     GrabPtr grab;
  609.     register DeviceIntPtr dev;
  610.  
  611.     for (dev = inputInfo.devices; dev; dev = dev->next)
  612.     FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
  613.     if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
  614.     return;
  615.     syncEvents.playingEvents = TRUE;
  616.     if (replayDev)
  617.     {
  618.     xE = replayDev->sync.event;
  619.     count = replayDev->sync.evcount;
  620.     syncEvents.replayDev = (DeviceIntPtr)NULL;
  621.     w = XYToWindow(
  622.         xE->u.keyButtonPointer.rootX, xE->u.keyButtonPointer.rootY);
  623.     for (i = 0; i < spriteTraceGood; i++)
  624.         if (syncEvents.replayWin == spriteTrace[i])
  625.         {
  626.         if (!CheckDeviceGrabs(replayDev, xE, i+1, count))
  627.             if (replayDev->focus)
  628.             DeliverFocusedEvent(replayDev, xE, w, count);
  629.             else
  630.             DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
  631.                         replayDev, count);
  632.         goto playmore;
  633.         }
  634.     /* must not still be in the same stack */
  635.     if (replayDev->focus)
  636.         DeliverFocusedEvent(replayDev, xE, w, count);
  637.     else
  638.         DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
  639.     }
  640. playmore:
  641.     for (dev = inputInfo.devices; dev; dev = dev->next)
  642.     {
  643.     if (!dev->sync.frozen)
  644.     {
  645.         PlayReleasedEvents();
  646.         break;
  647.     }
  648.     }
  649.     syncEvents.playingEvents = FALSE;
  650.     /* the following may have been skipped during replay, so do it now */
  651.     if ((grab = inputInfo.pointer->grab) && grab->confineTo)
  652.     {
  653.     if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  654.         sprite.hotPhys.x = sprite.hotPhys.y = 0;
  655.     ConfineCursorToWindow(grab->confineTo, TRUE);
  656.     }
  657.     else
  658.     ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
  659.                   TRUE);
  660.     PostNewCursor();
  661. }
  662.  
  663. void
  664. CheckGrabForSyncs(thisDev, thisMode, otherMode)
  665.     register DeviceIntPtr thisDev;
  666.     Bool thisMode, otherMode;
  667. {
  668.     register GrabPtr grab = thisDev->grab;
  669.     register DeviceIntPtr dev;
  670.  
  671.     if (thisMode == GrabModeSync)
  672.     thisDev->sync.state = FROZEN_NO_EVENT;
  673.     else
  674.     {    /* free both if same client owns both */
  675.     thisDev->sync.state = THAWED;
  676.     if (thisDev->sync.other &&
  677.         (CLIENT_BITS(thisDev->sync.other->resource) ==
  678.          CLIENT_BITS(grab->resource)))
  679.         thisDev->sync.other = NullGrab;
  680.     }
  681.     for (dev = inputInfo.devices; dev; dev = dev->next)
  682.     {
  683.     if (dev != thisDev)
  684.     {
  685.         if (otherMode == GrabModeSync)
  686.         dev->sync.other = grab;
  687.         else
  688.         {    /* free both if same client owns both */
  689.         if (dev->sync.other &&
  690.             (CLIENT_BITS(dev->sync.other->resource) ==
  691.              CLIENT_BITS(grab->resource)))
  692.             dev->sync.other = NullGrab;
  693.         }
  694.     }
  695.     }
  696.     ComputeFreezes();
  697. }
  698.  
  699. void
  700. ActivatePointerGrab(mouse, grab, time, autoGrab)
  701.     register GrabPtr grab;
  702.     register DeviceIntPtr mouse;
  703.     TimeStamp time;
  704.     Bool autoGrab;
  705. {
  706.     WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
  707.                      : sprite.win;
  708.  
  709.     if (grab->confineTo)
  710.     {
  711.     if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
  712.         sprite.hotPhys.x = sprite.hotPhys.y = 0;
  713.     ConfineCursorToWindow(grab->confineTo, FALSE);
  714.     }
  715.     DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
  716.     mouse->valuator->motionHintWindow = NullWindow;
  717.     if (syncEvents.playingEvents)
  718.     mouse->grabTime = syncEvents.time;
  719.     else
  720.     mouse->grabTime = time;
  721.     if (grab->cursor)
  722.     grab->cursor->refcnt++;
  723.     mouse->activeGrab = *grab;
  724.     mouse->grab = &mouse->activeGrab;
  725.     mouse->fromPassiveGrab = autoGrab;
  726.     PostNewCursor();
  727.     CheckGrabForSyncs(mouse,
  728.               (Bool)grab->pointerMode, (Bool)grab->keyboardMode);
  729. }
  730.  
  731. void
  732. DeactivatePointerGrab(mouse)
  733.     register DeviceIntPtr mouse;
  734. {
  735.     register GrabPtr grab = mouse->grab;
  736.     register DeviceIntPtr dev;
  737.  
  738.     mouse->valuator->motionHintWindow = NullWindow;
  739.     mouse->grab = NullGrab;
  740.     mouse->sync.state = NOT_GRABBED;
  741.     mouse->fromPassiveGrab = FALSE;
  742.     for (dev = inputInfo.devices; dev; dev = dev->next)
  743.     {
  744.     if (dev->sync.other == grab)
  745.         dev->sync.other = NullGrab;
  746.     }
  747.     DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
  748.     if (grab->confineTo)
  749.     ConfineCursorToWindow(ROOT, FALSE);
  750.     PostNewCursor();
  751.     if (grab->cursor)
  752.     FreeCursor(grab->cursor, (Cursor)0);
  753.     ComputeFreezes();
  754. }
  755.  
  756. void
  757. ActivateKeyboardGrab(keybd, grab, time, passive)
  758.     GrabPtr grab;
  759.     register DeviceIntPtr keybd;
  760.     TimeStamp time;
  761.     Bool passive;
  762. {
  763.     WindowPtr oldWin;
  764.  
  765.     if (keybd->grab)
  766.     oldWin = keybd->grab->window;
  767.     else if (keybd->focus)
  768.     oldWin = keybd->focus->win;
  769.     else
  770.     oldWin = sprite.win;
  771.     if (oldWin == FollowKeyboardWin)
  772.     oldWin = inputInfo.keyboard->focus->win;
  773.     if (keybd->valuator)
  774.     keybd->valuator->motionHintWindow = NullWindow;
  775.     DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
  776.     if (syncEvents.playingEvents)
  777.     keybd->grabTime = syncEvents.time;
  778.     else
  779.     keybd->grabTime = time;
  780.     keybd->activeGrab = *grab;
  781.     keybd->grab = &keybd->activeGrab;
  782.     keybd->fromPassiveGrab = passive;
  783.     CheckGrabForSyncs(keybd,
  784.               (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
  785. }
  786.  
  787. void
  788. DeactivateKeyboardGrab(keybd)
  789.     register DeviceIntPtr keybd;
  790. {
  791.     register GrabPtr grab = keybd->grab;
  792.     register DeviceIntPtr dev;
  793.     register WindowPtr focusWin = keybd->focus ? keybd->focus->win
  794.                            : sprite.win;
  795.  
  796.     if (focusWin == FollowKeyboardWin)
  797.     focusWin = inputInfo.keyboard->focus->win;
  798.     if (keybd->valuator)
  799.     keybd->valuator->motionHintWindow = NullWindow;
  800.     keybd->grab = NullGrab;
  801.     keybd->sync.state = NOT_GRABBED;
  802.     keybd->fromPassiveGrab = FALSE;
  803.     for (dev = inputInfo.devices; dev; dev = dev->next)
  804.     {
  805.     if (dev->sync.other == grab)
  806.         dev->sync.other = NullGrab;
  807.     }
  808.     DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
  809.     ComputeFreezes();
  810. }
  811.  
  812. void
  813. AllowSome(client, time, thisDev, newState)
  814.     ClientPtr        client;
  815.     TimeStamp        time;
  816.     register DeviceIntPtr thisDev;
  817.     int            newState;
  818. {
  819.     Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
  820.     TimeStamp grabTime;
  821.     register DeviceIntPtr dev;
  822.  
  823.     thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
  824.     thisSynced = FALSE;
  825.     otherGrabbed = FALSE;
  826.     othersFrozen = TRUE;
  827.     grabTime = thisDev->grabTime;
  828.     for (dev = inputInfo.devices; dev; dev = dev->next)
  829.     {
  830.     if (dev == thisDev)
  831.         continue;
  832.     if (dev->grab && SameClient(dev->grab, client))
  833.     {
  834.         if (!(thisGrabbed || otherGrabbed) ||
  835.         (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
  836.         grabTime = dev->grabTime;
  837.         otherGrabbed = TRUE;
  838.         if (thisDev->sync.other == dev->grab)
  839.         thisSynced = TRUE;
  840.         if (dev->sync.state < FROZEN)
  841.         othersFrozen = FALSE;
  842.     }
  843.     else if (!dev->sync.other || !SameClient(dev->sync.other, client))
  844.         othersFrozen = FALSE;
  845.     }
  846.     if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
  847.     return;
  848.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  849.     (CompareTimeStamps(time, grabTime) == EARLIER))
  850.     return;
  851.     switch (newState)
  852.     {
  853.     case THAWED:                /* Async */
  854.         if (thisGrabbed)
  855.         thisDev->sync.state = THAWED;
  856.         if (thisSynced)
  857.         thisDev->sync.other = NullGrab;
  858.         ComputeFreezes();
  859.         break;
  860.     case FREEZE_NEXT_EVENT:        /* Sync */
  861.         if (thisGrabbed)
  862.         {
  863.         thisDev->sync.state = FREEZE_NEXT_EVENT;
  864.         if (thisSynced)
  865.             thisDev->sync.other = NullGrab;
  866.         ComputeFreezes();
  867.         }
  868.         break;
  869.     case THAWED_BOTH:        /* AsyncBoth */
  870.         if (othersFrozen)
  871.         {
  872.         for (dev = inputInfo.devices; dev; dev = dev->next)
  873.         {
  874.             if (dev->grab && SameClient(dev->grab, client))
  875.             dev->sync.state = THAWED;
  876.             else
  877.             dev->sync.other = NullGrab;
  878.         }
  879.         ComputeFreezes();
  880.         }
  881.         break;
  882.     case FREEZE_BOTH_NEXT_EVENT:    /* SyncBoth */
  883.         if (othersFrozen)
  884.         {
  885.         for (dev = inputInfo.devices; dev; dev = dev->next)
  886.         {
  887.             if (dev->grab && SameClient(dev->grab, client))
  888.             dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
  889.             else
  890.             dev->sync.other = NullGrab;
  891.         }
  892.         ComputeFreezes();
  893.         }
  894.         break;
  895.     case NOT_GRABBED:        /* Replay */
  896.         if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
  897.         {
  898.         if (thisSynced)
  899.             thisDev->sync.other = NullGrab;
  900.         syncEvents.replayDev = thisDev;
  901.         syncEvents.replayWin = thisDev->grab->window;
  902.         (*thisDev->DeactivateGrab)(thisDev);
  903.         syncEvents.replayDev = (DeviceIntPtr)NULL;
  904.         }
  905.         break;
  906.     case THAW_OTHERS:        /* AsyncOthers */
  907.         if (othersFrozen)
  908.         {
  909.         for (dev = inputInfo.devices; dev; dev = dev->next)
  910.         {
  911.             if (dev == thisDev)
  912.             continue;
  913.             if (dev->grab && SameClient(dev->grab, client))
  914.             dev->sync.state = THAWED;
  915.             else
  916.             dev->sync.other = NullGrab;
  917.         }
  918.         ComputeFreezes();
  919.         }
  920.         break;
  921.     }
  922. }
  923.  
  924. int
  925. ProcAllowEvents(client)
  926.     register ClientPtr client;
  927. {
  928.     TimeStamp        time;
  929.     DeviceIntPtr    mouse = inputInfo.pointer;
  930.     DeviceIntPtr    keybd = inputInfo.keyboard;
  931.     REQUEST(xAllowEventsReq);
  932.  
  933.     REQUEST_SIZE_MATCH(xAllowEventsReq);
  934.     time = ClientTimeToServerTime(stuff->time);
  935.     switch (stuff->mode)
  936.     {
  937.     case ReplayPointer:
  938.         AllowSome(client, time, mouse, NOT_GRABBED);
  939.         break;
  940.     case SyncPointer: 
  941.         AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
  942.         break;
  943.     case AsyncPointer: 
  944.         AllowSome(client, time, mouse, THAWED);
  945.         break;
  946.     case ReplayKeyboard: 
  947.         AllowSome(client, time, keybd, NOT_GRABBED);
  948.         break;
  949.     case SyncKeyboard: 
  950.         AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
  951.         break;
  952.     case AsyncKeyboard: 
  953.         AllowSome(client, time, keybd, THAWED);
  954.         break;
  955.     case SyncBoth:
  956.         AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
  957.         break;
  958.     case AsyncBoth:
  959.         AllowSome(client, time, keybd, THAWED_BOTH);
  960.         break;
  961.     default: 
  962.         client->errorValue = stuff->mode;
  963.         return BadValue;
  964.     }
  965.     return Success;
  966. }
  967.  
  968. void
  969. ReleaseActiveGrabs(client)
  970.     ClientPtr client;
  971. {
  972.     register DeviceIntPtr dev;
  973.     Bool    done;
  974.  
  975.     /* XXX CloseDownClient should remove passive grabs before
  976.      * releasing active grabs.
  977.      */
  978.     do {
  979.         done = TRUE;
  980.         for (dev = inputInfo.devices; dev; dev = dev->next)
  981.         {
  982.         if (dev->grab && SameClient(dev->grab, client))
  983.         {
  984.             (*dev->DeactivateGrab)(dev);
  985.             done = FALSE;
  986.         }
  987.         }
  988.     } while (!done);
  989. }
  990.  
  991. /**************************************************************************
  992.  *            The following procedures deal with delivering events        *
  993.  **************************************************************************/
  994.  
  995. int
  996. TryClientEvents (client, pEvents, count, mask, filter, grab)
  997.     ClientPtr client;
  998.     GrabPtr grab;
  999.     xEvent *pEvents;
  1000.     int count;
  1001.     Mask mask, filter;
  1002. {
  1003.     int i;
  1004.     int type;
  1005.  
  1006. #ifdef DEBUG
  1007.     if (debug_events) ErrorF(
  1008.     "Event([%d, %d], mask=0x%x), client=%d",
  1009.     pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
  1010. #endif
  1011.     if ((client) && (client != serverClient) && (!client->clientGone) &&
  1012.     ((filter == CantBeFiltered) || (mask & filter)))
  1013.     {
  1014.     if (grab && !SameClient(grab, client))
  1015.         return -1; /* don't send, but notify caller */
  1016.     type = pEvents->u.u.type;
  1017.     if (type == MotionNotify)
  1018.     {
  1019.         if (mask & PointerMotionHintMask)
  1020.         {
  1021.         if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
  1022.             pEvents->u.keyButtonPointer.event)
  1023.         {
  1024. #ifdef DEBUG
  1025.             if (debug_events) ErrorF("\n");
  1026. #endif
  1027.             return 1; /* don't send, but pretend we did */
  1028.         }
  1029.         pEvents->u.u.detail = NotifyHint;
  1030.         }
  1031.         else
  1032.         {
  1033.         pEvents->u.u.detail = NotifyNormal;
  1034.         }
  1035.     }
  1036. #ifdef XINPUT
  1037.     else
  1038.     {
  1039.         extern int DeviceMotionNotify;
  1040.  
  1041.         if ((type == DeviceMotionNotify) &&
  1042.         MaybeSendDeviceMotionNotifyHint (pEvents, mask) != 0)
  1043.         return 1;
  1044.     }
  1045. #endif
  1046.     type &= 0177;
  1047.     if (type != KeymapNotify)
  1048.     {
  1049.         /* all extension events must have a sequence number */
  1050.         for (i = 0; i < count; i++)
  1051.         pEvents[i].u.u.sequenceNumber = client->sequence;
  1052.     }
  1053.  
  1054.     if (BitIsOn(criticalEvents, type))
  1055.         SetCriticalOutputPending();
  1056.  
  1057.     WriteEventsToClient(client, count, pEvents);
  1058. #ifdef DEBUG
  1059.     if (debug_events) ErrorF(  " delivered\n");
  1060. #endif
  1061.     return 1;
  1062.     }
  1063.     else
  1064.     {
  1065. #ifdef DEBUG
  1066.     if (debug_events) ErrorF("\n");
  1067. #endif
  1068.     return 0;
  1069.     }
  1070. }
  1071.  
  1072. int
  1073. DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
  1074.     register WindowPtr pWin;
  1075.     GrabPtr grab;
  1076.     xEvent *pEvents;
  1077.     int count;
  1078.     Mask filter;
  1079.     int mskidx;
  1080. {
  1081.     int deliveries = 0, nondeliveries = 0;
  1082.     int attempt;
  1083.     register InputClients *other;
  1084.     ClientPtr client = NullClient;
  1085.     Mask deliveryMask;     /* If a grab occurs due to a button press, then
  1086.                       this mask is the mask of the grab. */
  1087.     int type = pEvents->u.u.type;
  1088.  
  1089.     /* CantBeFiltered means only window owner gets the event */
  1090.     if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
  1091.     {
  1092.     /* if nobody ever wants to see this event, skip some work */
  1093.     if (filter != CantBeFiltered &&
  1094.         !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
  1095.         return 0;
  1096.     if (attempt = TryClientEvents(wClient(pWin), pEvents, count,
  1097.                       pWin->eventMask, filter, grab))
  1098.     {
  1099.         if (attempt > 0)
  1100.         {
  1101.         deliveries++;
  1102.         client = wClient(pWin);
  1103.         deliveryMask = pWin->eventMask;
  1104.         } else
  1105.         nondeliveries--;
  1106.     }
  1107.     }
  1108.     if (filter != CantBeFiltered)
  1109.     {
  1110.     if (type & EXTENSION_EVENT_BASE)
  1111.     {
  1112.         OtherInputMasks *inputMasks;
  1113.  
  1114.         inputMasks = wOtherInputMasks(pWin);
  1115.         if (!inputMasks ||
  1116.         !(inputMasks->inputEvents[mskidx] & filter))
  1117.         return 0;
  1118.         other = inputMasks->inputClients;
  1119.     }
  1120.     else
  1121.         other = (InputClients *)wOtherClients(pWin);
  1122.     for (; other; other = other->next)
  1123.     {
  1124.         if (attempt = TryClientEvents(rClient(other), pEvents, count,
  1125.                       other->mask[mskidx], filter, grab))
  1126.         {
  1127.         if (attempt > 0)
  1128.         {
  1129.             deliveries++;
  1130.             client = rClient(other);
  1131.             deliveryMask = other->mask[mskidx];
  1132.         } else
  1133.             nondeliveries--;
  1134.         }
  1135.     }
  1136.     }
  1137.     if ((type == ButtonPress) && deliveries && (!grab))
  1138.     {
  1139.     GrabRec tempGrab;
  1140.  
  1141.     tempGrab.device = inputInfo.pointer;
  1142.     tempGrab.resource = client->clientAsMask;
  1143.     tempGrab.window = pWin;
  1144.     tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
  1145.     tempGrab.eventMask = deliveryMask;
  1146.     tempGrab.keyboardMode = GrabModeAsync;
  1147.     tempGrab.pointerMode = GrabModeAsync;
  1148.     tempGrab.confineTo = NullWindow;
  1149.     tempGrab.cursor = NullCursor;
  1150.     (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
  1151.                        currentTime, TRUE);
  1152.     }
  1153.     else if ((type == MotionNotify) && deliveries)
  1154.     inputInfo.pointer->valuator->motionHintWindow = pWin;
  1155. #ifdef XINPUT
  1156.     else
  1157.     {
  1158.     extern int DeviceMotionNotify, DeviceButtonPress;
  1159.  
  1160.     if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
  1161.         deliveries)
  1162.         CheckDeviceGrabAndHintWindow (pWin, type, pEvents, grab, client, 
  1163.                       deliveryMask);
  1164.     }
  1165. #endif
  1166.     if (deliveries)
  1167.     return deliveries;
  1168.     return nondeliveries;
  1169. }
  1170.  
  1171. /* If the event goes to dontClient, don't send it and return 0.  if
  1172.    send works,  return 1 or if send didn't work, return 2.
  1173.    Only works for core events.
  1174. */
  1175.  
  1176. int
  1177. MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
  1178.     register WindowPtr pWin;
  1179.     xEvent *pEvents;
  1180.     int count;
  1181.     Mask filter;
  1182.     ClientPtr dontClient;
  1183. {
  1184.     register OtherClients *other;
  1185.  
  1186.     if (pWin->eventMask & filter)
  1187.     {
  1188.         if (wClient(pWin) == dontClient)
  1189.         return 0;
  1190.     return TryClientEvents(wClient(pWin), pEvents, count,
  1191.                    pWin->eventMask, filter, NullGrab);
  1192.     }
  1193.     for (other = wOtherClients(pWin); other; other = other->next)
  1194.     {
  1195.     if (other->mask & filter)
  1196.     {
  1197.             if (SameClient(other, dontClient))
  1198.         return 0;
  1199.         return TryClientEvents(rClient(other), pEvents, count,
  1200.                    other->mask, filter, NullGrab);
  1201.     }
  1202.     }
  1203.     return 2;
  1204. }
  1205.  
  1206. static void
  1207. FixUpEventFromWindow(xE, pWin, child, calcChild)
  1208.     xEvent *xE;
  1209.     WindowPtr pWin;
  1210.     Window child;
  1211.     Bool calcChild;
  1212. {
  1213.     if (calcChild)
  1214.     {
  1215.         WindowPtr w=spriteTrace[spriteTraceGood-1];
  1216.  
  1217.     /* If the search ends up past the root should the child field be 
  1218.          set to none or should the value in the argument be passed 
  1219.         through. It probably doesn't matter since everyone calls 
  1220.         this function with child == None anyway. */
  1221.  
  1222.         while (w) 
  1223.         {
  1224.             /* If the source window is same as event window, child should be
  1225.         none.  Don't bother going all all the way back to the root. */
  1226.  
  1227.          if (w == pWin)
  1228.         { 
  1229.            child = None;
  1230.          break;
  1231.         }
  1232.         
  1233.         if (w->parent == pWin)
  1234.         {
  1235.         child = w->drawable.id;
  1236.         break;
  1237.             }
  1238.          w = w->parent;
  1239.         }         
  1240.     }
  1241.     xE->u.keyButtonPointer.root = ROOT->drawable.id;
  1242.     xE->u.keyButtonPointer.event = pWin->drawable.id;
  1243.     if (sprite.hot.pScreen == pWin->drawable.pScreen)
  1244.     {
  1245.     xE->u.keyButtonPointer.sameScreen = xTrue;
  1246.     xE->u.keyButtonPointer.child = child;
  1247.     xE->u.keyButtonPointer.eventX =
  1248.         xE->u.keyButtonPointer.rootX - pWin->drawable.x;
  1249.     xE->u.keyButtonPointer.eventY =
  1250.         xE->u.keyButtonPointer.rootY - pWin->drawable.y;
  1251.     }
  1252.     else
  1253.     {
  1254.     xE->u.keyButtonPointer.sameScreen = xFalse;
  1255.     xE->u.keyButtonPointer.child = None;
  1256.     xE->u.keyButtonPointer.eventX = 0;
  1257.     xE->u.keyButtonPointer.eventY = 0;
  1258.     }
  1259. }
  1260.  
  1261. int
  1262. DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
  1263.     register WindowPtr pWin, stopAt;
  1264.     register xEvent *xE;
  1265.     GrabPtr grab;
  1266.     DeviceIntPtr dev;
  1267.     int count;
  1268. {
  1269.     Window child = None;
  1270.     int type = xE->u.u.type;
  1271.     Mask filter = filters[type];
  1272.     int deliveries = 0;
  1273.  
  1274.     if (type & EXTENSION_EVENT_BASE)
  1275.     {
  1276.     register OtherInputMasks *inputMasks;
  1277.     int mskidx = dev->id;
  1278.  
  1279.     inputMasks = wOtherInputMasks(pWin);
  1280.     if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
  1281.         return 0;
  1282.     while (pWin)
  1283.     {
  1284.         if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
  1285.         {
  1286.         FixUpEventFromWindow(xE, pWin, child, FALSE);
  1287.         deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1288.                            grab, mskidx);
  1289.         if (deliveries > 0)
  1290.             return deliveries;
  1291.         }
  1292.         if ((deliveries < 0) ||
  1293.         (pWin == stopAt) ||
  1294.         (inputMasks &&
  1295.          (filter & inputMasks->dontPropagateMask[mskidx])))
  1296.         return 0;
  1297.         child = pWin->drawable.id;
  1298.         pWin = pWin->parent;
  1299.         if (pWin)
  1300.         inputMasks = wOtherInputMasks(pWin);
  1301.     }
  1302.     }
  1303.     else
  1304.     {
  1305.     if (!(filter & pWin->deliverableEvents))
  1306.         return 0;
  1307.     while (pWin)
  1308.     {
  1309.         if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
  1310.         {
  1311.         FixUpEventFromWindow(xE, pWin, child, FALSE);
  1312.         deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
  1313.                            grab, 0);
  1314.         if (deliveries > 0)
  1315.             return deliveries;
  1316.         }
  1317.         if ((deliveries < 0) ||
  1318.         (pWin == stopAt) ||
  1319.         (filter & wDontPropagateMask(pWin)))
  1320.         return 0;
  1321.         child = pWin->drawable.id;
  1322.         pWin = pWin->parent;
  1323.     }
  1324.     }
  1325.     return 0;
  1326. }
  1327.  
  1328. /* not useful for events that propagate up the tree or extension events */
  1329. int
  1330. DeliverEvents(pWin, xE, count, otherParent)
  1331.     register WindowPtr pWin, otherParent;
  1332.     register xEvent *xE;
  1333.     int count;
  1334. {
  1335.     Mask filter;
  1336.     int     deliveries;
  1337.  
  1338.     if (!count)
  1339.     return 0;
  1340.     filter = filters[xE->u.u.type];
  1341.     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
  1342.     xE->u.destroyNotify.event = pWin->drawable.id;
  1343.     if (filter != StructureAndSubMask)
  1344.     return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
  1345.     deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
  1346.                        NullGrab, 0);
  1347.     if (pWin->parent)
  1348.     {
  1349.     xE->u.destroyNotify.event = pWin->parent->drawable.id;
  1350.     deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
  1351.                         SubstructureNotifyMask, NullGrab,
  1352.                         0);
  1353.     if (xE->u.u.type == ReparentNotify)
  1354.     {
  1355.         xE->u.destroyNotify.event = otherParent->drawable.id;
  1356.         deliveries += DeliverEventsToWindow(otherParent, xE, count,
  1357.                         SubstructureNotifyMask,
  1358.                         NullGrab, 0);
  1359.     }
  1360.     }
  1361.     return deliveries;
  1362. }
  1363.  
  1364. static WindowPtr 
  1365. XYToWindow(x, y)
  1366.     int x, y;
  1367. {
  1368.     register WindowPtr  pWin;
  1369. #ifdef SHAPE
  1370.     BoxRec        box;
  1371. #endif
  1372.  
  1373.     spriteTraceGood = 1;    /* root window still there */
  1374.     pWin = ROOT->firstChild;
  1375.     while (pWin)
  1376.     {
  1377.     if ((pWin->mapped) &&
  1378.         (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
  1379.         (x < pWin->drawable.x + (int)pWin->drawable.width +
  1380.             wBorderWidth(pWin)) &&
  1381.         (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
  1382.         (y < pWin->drawable.y + (int)pWin->drawable.height +
  1383.             wBorderWidth (pWin))
  1384. #ifdef SHAPE
  1385.         /* When a window is shaped, a further check
  1386.          * is made to see if the point is inside
  1387.          * borderSize
  1388.          */
  1389.         && (!wBoundingShape(pWin) ||
  1390.             (*pWin->drawable.pScreen->PointInRegion)
  1391.                 (&pWin->borderSize, x, y, &box))
  1392. #endif
  1393.         )
  1394.     {
  1395.         if (spriteTraceGood >= spriteTraceSize)
  1396.         {
  1397.         spriteTraceSize += 10;
  1398.         Must_have_memory = TRUE; /* XXX */
  1399.         spriteTrace = (WindowPtr *)xrealloc(
  1400.             spriteTrace, spriteTraceSize*sizeof(WindowPtr));
  1401.         Must_have_memory = FALSE; /* XXX */
  1402.         }
  1403.         spriteTrace[spriteTraceGood++] = pWin;
  1404.         pWin = pWin->firstChild;
  1405.     }
  1406.     else
  1407.         pWin = pWin->nextSib;
  1408.     }
  1409.     return spriteTrace[spriteTraceGood-1];
  1410. }
  1411.  
  1412. static Bool
  1413. CheckMotion(xE)
  1414.     xEvent *xE;
  1415. {
  1416.     WindowPtr prevSpriteWin = sprite.win;
  1417.  
  1418.     if (xE && !syncEvents.playingEvents)
  1419.     {
  1420.     if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
  1421.     {
  1422.         sprite.hot.pScreen = sprite.hotPhys.pScreen;
  1423.         ROOT = WindowTable[sprite.hot.pScreen->myNum];
  1424.     }
  1425.     sprite.hot.x = xE->u.keyButtonPointer.rootX;
  1426.     sprite.hot.y = xE->u.keyButtonPointer.rootY;
  1427.     if (sprite.hot.x < sprite.physLimits.x1)
  1428.         sprite.hot.x = sprite.physLimits.x1;
  1429.     else if (sprite.hot.x >= sprite.physLimits.x2)
  1430.         sprite.hot.x = sprite.physLimits.x2 - 1;
  1431.     if (sprite.hot.y < sprite.physLimits.y1)
  1432.         sprite.hot.y = sprite.physLimits.y1;
  1433.     else if (sprite.hot.y >= sprite.physLimits.y2)
  1434.         sprite.hot.y = sprite.physLimits.y2 - 1;
  1435. #ifdef SHAPE
  1436.     if (sprite.hotShape)
  1437.         ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
  1438. #endif
  1439.     sprite.hotPhys = sprite.hot;
  1440.     if ((sprite.hotPhys.x != xE->u.keyButtonPointer.rootX) ||
  1441.         (sprite.hotPhys.y != xE->u.keyButtonPointer.rootY))
  1442.         (*sprite.hotPhys.pScreen->SetCursorPosition)(
  1443.         sprite.hotPhys.pScreen,
  1444.         sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
  1445.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1446.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1447.     }
  1448.  
  1449.     sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
  1450. #ifdef notyet
  1451.     if (!(sprite.win->deliverableEvents &
  1452.       Motion_Filter(inputInfo.pointer->button))
  1453.     !syncEvents.playingEvents)
  1454.     {
  1455.     /* XXX Do PointerNonInterestBox here */
  1456.     }
  1457. #endif
  1458.     if (sprite.win != prevSpriteWin)
  1459.     {
  1460.     if (prevSpriteWin != NullWindow) {
  1461.         if (!xE)
  1462.         UpdateCurrentTimeIf();
  1463.         DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
  1464.     }
  1465.     PostNewCursor();
  1466.         return FALSE;
  1467.     }
  1468.     return TRUE;
  1469. }
  1470.  
  1471. WindowsRestructured()
  1472. {
  1473.     (void) CheckMotion((xEvent *)NULL);
  1474. }
  1475.  
  1476. void
  1477. DefineInitialRootWindow(win)
  1478.     register WindowPtr win;
  1479. {
  1480.     register ScreenPtr pScreen = win->drawable.pScreen;
  1481.  
  1482.     sprite.hotPhys.pScreen = pScreen;
  1483.     sprite.hotPhys.x = pScreen->width / 2;
  1484.     sprite.hotPhys.y = pScreen->height / 2;
  1485.     sprite.hot = sprite.hotPhys;
  1486.     sprite.hotLimits.x2 = pScreen->width;
  1487.     sprite.hotLimits.y2 = pScreen->height;
  1488.     sprite.win = win;
  1489.     sprite.current = wCursor (win);
  1490.     spriteTraceGood = 1;
  1491.     ROOT = win;
  1492.     (*pScreen->CursorLimits) (
  1493.     pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
  1494.     (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
  1495.     (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
  1496.     (*pScreen->DisplayCursor) (pScreen, sprite.current);
  1497. }
  1498.  
  1499. /*
  1500.  * This does not take any shortcuts, and even ignores its argument, since
  1501.  * it does not happen very often, and one has to walk up the tree since
  1502.  * this might be a newly instantiated cursor for an intermediate window
  1503.  * between the one the pointer is in and the one that the last cursor was
  1504.  * instantiated from.
  1505.  */
  1506. /*ARGSUSED*/
  1507. void
  1508. WindowHasNewCursor(pWin)
  1509.     WindowPtr pWin;
  1510. {
  1511.     PostNewCursor();
  1512. }
  1513.  
  1514. void
  1515. NewCurrentScreen(newScreen, x, y)
  1516.     ScreenPtr newScreen;
  1517.     int x,y;
  1518. {
  1519.     sprite.hotPhys.x = x;
  1520.     sprite.hotPhys.y = y;
  1521.     if (newScreen != sprite.hotPhys.pScreen)
  1522.     ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE);
  1523. }
  1524.  
  1525. int
  1526. ProcWarpPointer(client)
  1527.     ClientPtr client;
  1528. {
  1529.     WindowPtr    dest = NULL;
  1530.     int        x, y;
  1531.     ScreenPtr    newScreen;
  1532.  
  1533.     REQUEST(xWarpPointerReq);
  1534.  
  1535.     REQUEST_SIZE_MATCH(xWarpPointerReq);
  1536.     if (stuff->dstWid != None)
  1537.     {
  1538.     dest = LookupWindow(stuff->dstWid, client);
  1539.     if (!dest)
  1540.         return BadWindow;
  1541.     }
  1542.     x = sprite.hotPhys.x;
  1543.     y = sprite.hotPhys.y;
  1544.     if (stuff->srcWid != None)
  1545.     {
  1546.     int     winX, winY;
  1547.         WindowPtr source = LookupWindow(stuff->srcWid, client);
  1548.     if (!source)
  1549.         return BadWindow;
  1550.     winX = source->drawable.x;
  1551.     winY = source->drawable.y;
  1552.     if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
  1553.         x < winX + stuff->srcX ||
  1554.         y < winY + stuff->srcY ||
  1555.         (stuff->srcWidth != 0 &&
  1556.          winX + stuff->srcX + (int)stuff->srcWidth < x) ||
  1557.         (stuff->srcHeight != 0 &&
  1558.          winY + stuff->srcY + (int)stuff->srcHeight < y) ||
  1559.         !PointInWindowIsVisible(source, x, y))
  1560.         return Success;
  1561.     }
  1562.     if (dest)
  1563.     {
  1564.     x = dest->drawable.x;
  1565.     y = dest->drawable.y;
  1566.     newScreen = dest->drawable.pScreen;
  1567.     }
  1568.     else
  1569.     newScreen = sprite.hotPhys.pScreen;
  1570.     x += stuff->dstX;
  1571.     y += stuff->dstY;
  1572.     if (x < 0)
  1573.     x = 0;
  1574.     else if (x >= newScreen->width)
  1575.     x = newScreen->width - 1;
  1576.     if (y < 0)
  1577.     y = 0;
  1578.     else if (y >= newScreen->height)
  1579.     y = newScreen->height - 1;
  1580.  
  1581.     if (newScreen == sprite.hotPhys.pScreen)
  1582.     {
  1583.     if (x < sprite.physLimits.x1)
  1584.         x = sprite.physLimits.x1;
  1585.     else if (x >= sprite.physLimits.x2)
  1586.         x = sprite.physLimits.x2 - 1;
  1587.     if (y < sprite.physLimits.y1)
  1588.         y = sprite.physLimits.y1;
  1589.     else if (y >= sprite.physLimits.y2)
  1590.         y = sprite.physLimits.y2 - 1;
  1591. #ifdef SHAPE
  1592.     if (sprite.hotShape)
  1593.         ConfineToShape(sprite.hotShape, &x, &y);
  1594. #endif
  1595.     (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
  1596.     }
  1597.     else if (!PointerConfinedToScreen())
  1598.     {
  1599.     NewCurrentScreen(newScreen, x, y);
  1600.     }
  1601.     return Success;
  1602. }
  1603.  
  1604. /* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
  1605.     passive grab set on the window to be activated. */
  1606.  
  1607. static Bool
  1608. CheckPassiveGrabsOnWindow(pWin, device, xE, count)
  1609.     WindowPtr pWin;
  1610.     register DeviceIntPtr device;
  1611.     register xEvent *xE;
  1612.     int count;
  1613. {
  1614.     register GrabPtr grab = wPassiveGrabs(pWin);
  1615.     GrabRec tempGrab;
  1616.     register xEvent *dxE;
  1617.  
  1618.     if (!grab)
  1619.     return FALSE;
  1620.     tempGrab.window = pWin;
  1621.     tempGrab.device = device;
  1622.     tempGrab.type = xE->u.u.type;
  1623.     tempGrab.detail.exact = xE->u.u.detail;
  1624.     tempGrab.detail.pMask = NULL;
  1625.     tempGrab.modifiersDetail.pMask = NULL;
  1626.     for (; grab; grab = grab->next)
  1627.     {
  1628.     tempGrab.modifierDevice = grab->modifierDevice;
  1629.     tempGrab.modifiersDetail.exact = xE->u.keyButtonPointer.state;
  1630.     if (GrabMatchesSecond(&tempGrab, grab))
  1631.     {
  1632.         (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  1633.  
  1634.         FixUpEventFromWindow(xE, grab->window, None, TRUE);
  1635.  
  1636.         (void) TryClientEvents(rClient(grab), xE, count,
  1637.                    filters[xE->u.u.type],
  1638.                    filters[xE->u.u.type],  grab);
  1639.  
  1640.         if (device->sync.state == FROZEN_NO_EVENT)
  1641.         {
  1642.         Must_have_memory = TRUE; /* XXX */
  1643.             device->sync.event = (xEvent *)xrealloc(device->sync.event,
  1644.                             count*sizeof(xEvent));
  1645.         Must_have_memory = FALSE; /* XXX */
  1646.         device->sync.evcount = count;
  1647.         for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
  1648.             *dxE = *xE;
  1649.             device->sync.state = FROZEN_WITH_EVENT;
  1650.             }    
  1651.         return TRUE;
  1652.     }
  1653.     }
  1654.     return FALSE;
  1655. }
  1656.  
  1657. /*
  1658. "CheckDeviceGrabs" handles both keyboard and pointer events that may cause
  1659. a passive grab to be activated.  If the event is a keyboard event, the
  1660. ancestors of the focus window are traced down and tried to see if they have
  1661. any passive grabs to be activated.  If the focus window itself is reached and
  1662. it's descendants contain they pointer, the ancestors of the window that the
  1663. pointer is in are then traced down starting at the focus window, otherwise no
  1664. grabs are activated.  If the event is a pointer event, the ancestors of the
  1665. window that the pointer is in are traced down starting at the root until
  1666. CheckPassiveGrabs causes a passive grab to activate or all the windows are
  1667. tried. PRH
  1668. */
  1669.  
  1670. Bool
  1671. CheckDeviceGrabs(device, xE, checkFirst, count)
  1672.     register DeviceIntPtr device;
  1673.     register xEvent *xE;
  1674.     int checkFirst;
  1675.     int count;
  1676. {
  1677.     register int i;
  1678.     register WindowPtr pWin;
  1679.     register FocusClassPtr focus = device->focus;
  1680.  
  1681.     i = checkFirst;
  1682.  
  1683.     if (focus)
  1684.     {
  1685.     for (; i < focus->traceGood; i++)
  1686.     {
  1687.         pWin = focus->trace[i];
  1688.         if (pWin->optional &&
  1689.         CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  1690.         return TRUE;
  1691.     }
  1692.   
  1693.     if ((focus->win == NoneWin) ||
  1694.         (i >= spriteTraceGood) ||
  1695.         ((i > 0) && (pWin != spriteTrace[i-1])))
  1696.         return FALSE;
  1697.     }
  1698.         
  1699.     for (; i < spriteTraceGood; i++)
  1700.     {
  1701.     pWin = spriteTrace[i];
  1702.     if (pWin->optional &&
  1703.         CheckPassiveGrabsOnWindow(pWin, device, xE, count))
  1704.         return TRUE;
  1705.     }
  1706.  
  1707.     return FALSE;
  1708. }
  1709.  
  1710. void
  1711. DeliverFocusedEvent(keybd, xE, window, count)
  1712.     xEvent *xE;
  1713.     DeviceIntPtr keybd;
  1714.     WindowPtr window;
  1715.     int count;
  1716. {
  1717.     WindowPtr focus = keybd->focus->win;
  1718.     int mskidx = 0;
  1719.  
  1720.     if (focus == FollowKeyboardWin)
  1721.     focus = inputInfo.keyboard->focus->win;
  1722.     if (!focus)
  1723.     return;
  1724.     if (focus == PointerRootWin)
  1725.     {
  1726.     DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
  1727.     return;
  1728.     }
  1729.     if ((focus == window) || IsParent(focus, window))
  1730.     {
  1731.     if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
  1732.         return;
  1733.     }
  1734.     /* just deliver it to the focus window */
  1735.     FixUpEventFromWindow(xE, focus, None, FALSE);
  1736.     if (xE->u.u.type & EXTENSION_EVENT_BASE)
  1737.     mskidx = keybd->id;
  1738.     (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
  1739.                 NullGrab, mskidx);
  1740. }
  1741.  
  1742. void
  1743. DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
  1744.     register xEvent *xE;
  1745.     register DeviceIntPtr thisDev;
  1746.     Bool deactivateGrab;
  1747.     int count;
  1748. {
  1749.     register GrabPtr grab = thisDev->grab;
  1750.     int deliveries = 0;
  1751.     register DeviceIntPtr dev;
  1752.     register xEvent *dxE;
  1753.  
  1754.     if (grab->ownerEvents)
  1755.     {
  1756.     WindowPtr focus;
  1757.  
  1758.     if (thisDev->focus)
  1759.     {
  1760.         focus = thisDev->focus->win;
  1761.         if (focus == FollowKeyboardWin)
  1762.         focus = inputInfo.keyboard->focus->win;
  1763.     }
  1764.     else
  1765.         focus = PointerRootWin;
  1766.     if (focus == PointerRootWin)
  1767.         deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
  1768.                          thisDev, count);
  1769.     else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
  1770.         deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
  1771.                          thisDev, count);
  1772.     else if (focus)
  1773.         deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
  1774.                          thisDev, count);
  1775.     }
  1776.     if (!deliveries)
  1777.     {
  1778.     FixUpEventFromWindow(xE, grab->window, None, TRUE);
  1779.     deliveries = TryClientEvents(rClient(grab), xE, count,
  1780.                      (Mask)grab->eventMask,
  1781.                      filters[xE->u.u.type], grab);
  1782.     if (deliveries && (xE->u.u.type == MotionNotify))
  1783.         thisDev->valuator->motionHintWindow = grab->window;
  1784.     }
  1785.     if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify))
  1786.     switch (thisDev->sync.state)
  1787.     {
  1788.     case FREEZE_BOTH_NEXT_EVENT:
  1789.         for (dev = inputInfo.devices; dev; dev = dev->next)
  1790.         {
  1791.         if (dev == thisDev)
  1792.             continue;
  1793.         FreezeThaw(dev, TRUE);
  1794.         if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
  1795.             (CLIENT_BITS(dev->grab->resource) ==
  1796.              CLIENT_BITS(thisDev->grab->resource)))
  1797.             dev->sync.state = FROZEN_NO_EVENT;
  1798.         else
  1799.             dev->sync.other = thisDev->grab;
  1800.         }
  1801.         /* fall through */
  1802.     case FREEZE_NEXT_EVENT:
  1803.         thisDev->sync.state = FROZEN_WITH_EVENT;
  1804.         FreezeThaw(thisDev, TRUE);
  1805.         Must_have_memory = TRUE; /* XXX */
  1806.         thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
  1807.                              count*sizeof(xEvent));
  1808.         Must_have_memory = FALSE; /* XXX */
  1809.         thisDev->sync.evcount = count;
  1810.         for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
  1811.         *dxE = *xE;
  1812.         break;
  1813.     }
  1814. }
  1815.  
  1816. void
  1817. ProcessKeyboardEvent (xE, keybd, count)
  1818.     register xEvent *xE;
  1819.     register DeviceIntPtr keybd;
  1820.     int count;
  1821. {
  1822.     int             key, bit;
  1823.     register BYTE   *kptr;
  1824.     register int    i;
  1825.     register CARD8  modifiers;
  1826.     register CARD16 mask;
  1827.     GrabPtr         grab = keybd->grab;
  1828.     Bool            deactivateGrab = FALSE;
  1829.     register KeyClassPtr keyc = keybd->key;
  1830.  
  1831.     if (!syncEvents.playingEvents)
  1832.     NoticeTime(xE)
  1833.     xE->u.keyButtonPointer.state = (keyc->state |
  1834.                     inputInfo.pointer->button->state);
  1835.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1836.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1837.     key = xE->u.u.detail;
  1838.     kptr = &keyc->down[key >> 3];
  1839.     bit = 1 << (key & 7);
  1840.     modifiers = keyc->modifierMap[key];
  1841.     switch (xE->u.u.type)
  1842.     {
  1843.     case KeyPress: 
  1844.         if (*kptr & bit) /* allow ddx to generate multiple downs */
  1845.         {   
  1846.         if (!modifiers)
  1847.         {
  1848.             xE->u.u.type = KeyRelease;
  1849.             ProcessKeyboardEvent(xE, keybd, count);
  1850.             xE->u.u.type = KeyPress;
  1851.             /* release can have side effects, don't fall through */
  1852.             ProcessKeyboardEvent(xE, keybd, count);
  1853.         }
  1854.         return;
  1855.         }
  1856.         inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  1857.         *kptr |= bit;
  1858.         for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  1859.         {
  1860.         if (mask & modifiers)
  1861.         {
  1862.             /* This key affects modifier "i" */
  1863.             keyc->modifierKeyCount[i]++;
  1864.             keyc->state |= mask;
  1865.             modifiers &= ~mask;
  1866.         }
  1867.         }
  1868.         if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
  1869.         {
  1870.         keybd->activatingKey = key;
  1871.         return;
  1872.         }
  1873.         break;
  1874.     case KeyRelease: 
  1875.         if (!(*kptr & bit)) /* guard against duplicates */
  1876.         return;
  1877.         inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  1878.         *kptr &= ~bit;
  1879.         for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  1880.         {
  1881.         if (mask & modifiers) {
  1882.             /* This key affects modifier "i" */
  1883.             if (--keyc->modifierKeyCount[i] <= 0) {
  1884.             keyc->state &= ~mask;
  1885.             keyc->modifierKeyCount[i] = 0;
  1886.             }
  1887.             modifiers &= ~mask;
  1888.         }
  1889.         }
  1890.         if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
  1891.         deactivateGrab = TRUE;
  1892.         break;
  1893.     default: 
  1894.         FatalError("Impossible keyboard event");
  1895.     }
  1896.     if (grab)
  1897.     DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
  1898.     else
  1899.     DeliverFocusedEvent(keybd, xE, sprite.win, count);
  1900.     if (deactivateGrab)
  1901.         (*keybd->DeactivateGrab)(keybd);
  1902. }
  1903.  
  1904. void
  1905. ProcessPointerEvent (xE, mouse, count)
  1906.     register xEvent         *xE;
  1907.     register DeviceIntPtr     mouse;
  1908.     int                count;
  1909. {
  1910.     register GrabPtr    grab = mouse->grab;
  1911.     Bool                deactivateGrab = FALSE;
  1912.     register ButtonClassPtr butc = mouse->button;
  1913.  
  1914.     if (!syncEvents.playingEvents)
  1915.     NoticeTime(xE)
  1916.     xE->u.keyButtonPointer.state = (butc->state |
  1917.                     inputInfo.keyboard->key->state);
  1918.     if (xE->u.u.type != MotionNotify)
  1919.     {
  1920.     register int  key;
  1921.     register BYTE *kptr;
  1922.     int           bit;
  1923.  
  1924.     xE->u.keyButtonPointer.rootX = sprite.hot.x;
  1925.     xE->u.keyButtonPointer.rootY = sprite.hot.y;
  1926.     key = xE->u.u.detail;
  1927.     kptr = &butc->down[key >> 3];
  1928.     bit = 1 << (key & 7);
  1929.     switch (xE->u.u.type)
  1930.     {
  1931.     case ButtonPress: 
  1932.         mouse->valuator->motionHintWindow = NullWindow;
  1933.         butc->buttonsDown++;
  1934.         butc->motionMask = ButtonMotionMask;
  1935.         *kptr |= bit;
  1936.         xE->u.u.detail = butc->map[key];
  1937.         if (xE->u.u.detail == 0)
  1938.         return;
  1939.         if (xE->u.u.detail <= 5)
  1940.         butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
  1941.         filters[MotionNotify] = Motion_Filter(butc);
  1942.         if (!grab)
  1943.         if (CheckDeviceGrabs(mouse, xE, 0, count))
  1944.             return;
  1945.         break;
  1946.     case ButtonRelease: 
  1947.         mouse->valuator->motionHintWindow = NullWindow;
  1948.         if (!--butc->buttonsDown)
  1949.         butc->motionMask = 0;
  1950.         *kptr &= ~bit;
  1951.         xE->u.u.detail = butc->map[key];
  1952.         if (xE->u.u.detail == 0)
  1953.         return;
  1954.         if (xE->u.u.detail <= 5)
  1955.         butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
  1956.         filters[MotionNotify] = Motion_Filter(butc);
  1957.         if (!butc->state && mouse->fromPassiveGrab)
  1958.         deactivateGrab = TRUE;
  1959.         break;
  1960.     default: 
  1961.         FatalError("bogus pointer event from ddx");
  1962.     }
  1963.     }
  1964.     else if (!CheckMotion(xE))
  1965.     return;
  1966.     if (grab)
  1967.     DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
  1968.     else
  1969.     DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
  1970.                 mouse, count);
  1971.     if (deactivateGrab)
  1972.         (*mouse->DeactivateGrab)(mouse);
  1973. }
  1974.  
  1975. #define AtMostOneClient \
  1976.     (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
  1977.  
  1978. void
  1979. RecalculateDeliverableEvents(pWin)
  1980.     register WindowPtr pWin;
  1981. {
  1982.     register OtherClients *others;
  1983.     register WindowPtr pChild;
  1984.  
  1985.     pChild = pWin;
  1986.     while (1)
  1987.     {
  1988.     if (pChild->optional)
  1989.     {
  1990.         pChild->optional->otherEventMasks = 0;
  1991.         for (others = wOtherClients(pChild); others; others = others->next)
  1992.         {
  1993.         pChild->optional->otherEventMasks |= others->mask;
  1994.         }
  1995.     }
  1996.     pChild->deliverableEvents = pChild->eventMask|
  1997.                     wOtherEventMasks(pChild);
  1998.     if (pChild->parent)
  1999.         pChild->deliverableEvents |=
  2000.         (pChild->parent->deliverableEvents &
  2001.          ~wDontPropagateMask(pChild) & PropagateMask);
  2002.     if (pChild->firstChild)
  2003.     {
  2004.         pChild = pChild->firstChild;
  2005.         continue;
  2006.     }
  2007.     while (!pChild->nextSib && (pChild != pWin))
  2008.         pChild = pChild->parent;
  2009.     if (pChild == pWin)
  2010.         break;
  2011.     pChild = pChild->nextSib;
  2012.     }
  2013. }
  2014.  
  2015. int
  2016. OtherClientGone(pWin, id)
  2017.     register WindowPtr pWin;
  2018.     XID   id;
  2019. {
  2020.     register OtherClientsPtr other, prev;
  2021.  
  2022.     prev = 0;
  2023.     for (other = wOtherClients(pWin); other; other = other->next)
  2024.     {
  2025.     if (other->resource == id)
  2026.     {
  2027.         if (prev)
  2028.         prev->next = other->next;
  2029.         else
  2030.         {
  2031.         if (!(pWin->optional->otherClients = other->next))
  2032.             CheckWindowOptionalNeed (pWin);
  2033.         }
  2034.         xfree(other);
  2035.         RecalculateDeliverableEvents(pWin);
  2036.         return(Success);
  2037.     }
  2038.     prev = other;
  2039.     }
  2040.     FatalError("client not on event list");
  2041.     /*NOTREACHED*/
  2042. }
  2043.  
  2044. int
  2045. EventSelectForWindow(pWin, client, mask)
  2046.     register WindowPtr pWin;
  2047.     register ClientPtr client;
  2048.     Mask mask;
  2049. {
  2050.     Mask check;
  2051.     OtherClients * others;
  2052.  
  2053.     if (mask & ~AllEventMasks)
  2054.     {
  2055.     client->errorValue = mask;
  2056.     return BadValue;
  2057.     }
  2058.     check = (mask & AtMostOneClient);
  2059.     if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
  2060.     {                       /* It is illegal for two different
  2061.                           clients to select on any of the
  2062.                           events for AtMostOneClient. However,
  2063.                           it is OK, for some client to
  2064.                           continue selecting on one of those
  2065.                           events.  */
  2066.     if ((wClient(pWin) != client) && (check & pWin->eventMask))
  2067.         return BadAccess;
  2068.     for (others = wOtherClients (pWin); others; others = others->next)
  2069.     {
  2070.         if (!SameClient(others, client) && (check & others->mask))
  2071.         return BadAccess;
  2072.     }
  2073.     }
  2074.     if (wClient (pWin) == client)
  2075.     {
  2076.     check = pWin->eventMask;
  2077.     pWin->eventMask = mask;
  2078.     }
  2079.     else
  2080.     {
  2081.     for (others = wOtherClients (pWin); others; others = others->next)
  2082.     {
  2083.         if (SameClient(others, client))
  2084.         {
  2085.         check = others->mask;
  2086.         if (mask == 0)
  2087.         {
  2088.             FreeResource(others->resource, RT_NONE);
  2089.             return Success;
  2090.         }
  2091.         else
  2092.             others->mask = mask;
  2093.         goto maskSet;
  2094.         }
  2095.     }
  2096.     check = 0;
  2097.     if (!pWin->optional && !MakeWindowOptional (pWin))
  2098.         return BadAlloc;
  2099.     others = (OtherClients *) xalloc(sizeof(OtherClients));
  2100.     if (!others)
  2101.         return BadAlloc;
  2102.     others->mask = mask;
  2103.     others->resource = FakeClientID(client->index);
  2104.     others->next = pWin->optional->otherClients;
  2105.     pWin->optional->otherClients = others;
  2106.     if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
  2107.         return BadAlloc;
  2108.     }
  2109. maskSet: 
  2110.     if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
  2111.     (mask & PointerMotionHintMask) &&
  2112.     !(check & PointerMotionHintMask) &&
  2113.     !inputInfo.pointer->grab)
  2114.     inputInfo.pointer->valuator->motionHintWindow = NullWindow;
  2115.     RecalculateDeliverableEvents(pWin);
  2116.     return Success;
  2117. }
  2118.  
  2119. /*ARGSUSED*/
  2120. int
  2121. EventSuppressForWindow(pWin, client, mask, checkOptional)
  2122.     register WindowPtr pWin;
  2123.     register ClientPtr client;
  2124.     Mask mask;
  2125.     Bool *checkOptional;
  2126. {
  2127.     register int i, free;
  2128.  
  2129.     if ((mask & ~PropagateMask) && !permitOldBugs)
  2130.     {
  2131.     client->errorValue = mask;
  2132.     return BadValue;
  2133.     }
  2134.     if (pWin->dontPropagate)
  2135.     DontPropagateRefCnts[pWin->dontPropagate]--;
  2136.     if (!mask)
  2137.     i = 0;
  2138.     else
  2139.     {
  2140.     for (i = DNPMCOUNT, free = 0; --i > 0; )
  2141.     {
  2142.         if (!DontPropagateRefCnts[i])
  2143.         free = i;
  2144.         else if (mask == DontPropagateMasks[i])
  2145.         break;
  2146.     }
  2147.     if (!i && free)
  2148.     {
  2149.         i = free;
  2150.         DontPropagateMasks[i] = mask;
  2151.     }
  2152.     }
  2153.     if (i || !mask)
  2154.     {
  2155.     pWin->dontPropagate = i;
  2156.     if (i)
  2157.         DontPropagateRefCnts[i]++;
  2158.     if (pWin->optional)
  2159.     {
  2160.         pWin->optional->dontPropagateMask = mask;
  2161.         *checkOptional = TRUE;
  2162.     }
  2163.     }
  2164.     else
  2165.     {
  2166.     if (!pWin->optional && !MakeWindowOptional (pWin))
  2167.     {
  2168.         if (pWin->dontPropagate)
  2169.         DontPropagateRefCnts[pWin->dontPropagate]++;
  2170.         return BadAlloc;
  2171.     }
  2172.     pWin->dontPropagate = 0;
  2173.         pWin->optional->dontPropagateMask = mask;
  2174.     }
  2175.     RecalculateDeliverableEvents(pWin);
  2176.     return Success;
  2177. }
  2178.  
  2179. static WindowPtr 
  2180. CommonAncestor(a, b)
  2181.     register WindowPtr a, b;
  2182. {
  2183.     for (b = b->parent; b; b = b->parent)
  2184.     if (IsParent(b, a)) return b;
  2185.     return NullWindow;
  2186. }
  2187.  
  2188. static void
  2189. EnterLeaveEvent(type, mode, detail, pWin, child)
  2190.     int type, mode, detail;
  2191.     register WindowPtr pWin;
  2192.     Window child;
  2193. {
  2194.     xEvent        event;
  2195.     register DeviceIntPtr keybd = inputInfo.keyboard;
  2196.     WindowPtr        focus;
  2197.     register DeviceIntPtr mouse = inputInfo.pointer;
  2198.     register GrabPtr    grab = mouse->grab;
  2199.     Mask        mask;
  2200.  
  2201.     if ((pWin == mouse->valuator->motionHintWindow) &&
  2202.     (detail != NotifyInferior))
  2203.     mouse->valuator->motionHintWindow = NullWindow;
  2204.     if (grab)
  2205.     {
  2206.     mask = (pWin == grab->window) ? grab->eventMask : 0;
  2207.     if (grab->ownerEvents)
  2208.         mask |= EventMaskForClient(pWin, rClient(grab));
  2209.     }
  2210.     else
  2211.     {
  2212.     mask = pWin->eventMask | wOtherEventMasks(pWin);
  2213.     }
  2214.     if (mask & filters[type])
  2215.     {
  2216.     event.u.u.type = type;
  2217.     event.u.u.detail = detail;
  2218.     event.u.enterLeave.time = currentTime.milliseconds;
  2219.     event.u.enterLeave.rootX = sprite.hot.x;
  2220.     event.u.enterLeave.rootY = sprite.hot.y;
  2221.     /* Counts on the same initial structure of crossing & button events! */
  2222.     FixUpEventFromWindow(&event, pWin, None, FALSE);
  2223.     /* Enter/Leave events always set child */
  2224.     event.u.enterLeave.child = child;
  2225.     event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
  2226.                         ELFlagSameScreen : 0;
  2227.     event.u.enterLeave.state = keybd->key->state | mouse->button->state;
  2228.     event.u.enterLeave.mode = mode;
  2229.     focus = keybd->focus->win;
  2230.     if ((focus != NoneWin) &&
  2231.         ((pWin == focus) || (focus == PointerRootWin) ||
  2232.          IsParent(focus, pWin)))
  2233.         event.u.enterLeave.flags |= ELFlagFocus;
  2234.     if (grab)
  2235.         (void)TryClientEvents(rClient(grab), &event, 1, mask,
  2236.                   filters[type], grab);
  2237.     else
  2238.         (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
  2239.                     NullGrab, 0);
  2240.     }
  2241.     if ((type == EnterNotify) && (mask & KeymapStateMask))
  2242.     {
  2243.     xKeymapEvent ke;
  2244.     ke.type = KeymapNotify;
  2245.     bcopy((char *)&keybd->key->down[1], (char *)&ke.map[0], 31);
  2246.     if (grab)
  2247.         (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
  2248.                   KeymapStateMask, grab);
  2249.     else
  2250.         (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  2251.                     KeymapStateMask, NullGrab, 0);
  2252.     }
  2253. }
  2254.  
  2255. static void
  2256. EnterNotifies(ancestor, child, mode, detail)
  2257.     WindowPtr ancestor, child;
  2258.     int mode, detail;
  2259. {
  2260.     WindowPtr    parent = child->parent;
  2261.  
  2262.     if (ancestor == parent)
  2263.     return;
  2264.     EnterNotifies(ancestor, parent, mode, detail);
  2265.     EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
  2266. }
  2267.  
  2268. static void
  2269. LeaveNotifies(child, ancestor, mode, detail)
  2270.     WindowPtr child, ancestor;
  2271.     int detail, mode;
  2272. {
  2273.     register WindowPtr  pWin, prev;
  2274.  
  2275.     if (ancestor == child)
  2276.     return;
  2277.     for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
  2278.     {
  2279.     EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
  2280.     child = pWin;
  2281.     }
  2282. }
  2283.  
  2284. static void
  2285. DoEnterLeaveEvents(fromWin, toWin, mode)
  2286.     WindowPtr fromWin, toWin;
  2287.     int mode;
  2288. {
  2289.     if (fromWin == toWin)
  2290.     return;
  2291.     if (IsParent(fromWin, toWin))
  2292.     {
  2293.     EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
  2294.     EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
  2295.     EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
  2296.     }
  2297.     else if (IsParent(toWin, fromWin))
  2298.     {
  2299.     EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
  2300.     LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
  2301.     EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
  2302.     }
  2303.     else
  2304.     { /* neither fromWin nor toWin is descendent of the other */
  2305.     WindowPtr common = CommonAncestor(toWin, fromWin);
  2306.     /* common == NullWindow ==> different screens */
  2307.     EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
  2308.     LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
  2309.     EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
  2310.     EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
  2311.     }
  2312. }
  2313.  
  2314. static void
  2315. FocusEvent(dev, type, mode, detail, pWin)
  2316.     DeviceIntPtr dev;
  2317.     int type, mode, detail;
  2318.     register WindowPtr pWin;
  2319. {
  2320.     xEvent event;
  2321.  
  2322. #ifdef XINPUT
  2323.     if (dev != inputInfo.keyboard)
  2324.     {
  2325.     DeviceFocusEvent(dev, type, mode, detail, pWin);
  2326.     return;
  2327.     }
  2328. #endif
  2329.     event.u.focus.mode = mode;
  2330.     event.u.u.type = type;
  2331.     event.u.u.detail = detail;
  2332.     event.u.focus.window = pWin->drawable.id;
  2333.     (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
  2334.                 0);
  2335.     if ((type == FocusIn) &&
  2336.     ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
  2337.     {
  2338.     xKeymapEvent ke;
  2339.     ke.type = KeymapNotify;
  2340.     bcopy((char *)&dev->key->down[1], (char *)&ke.map[0], 31);
  2341.     (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
  2342.                     KeymapStateMask, NullGrab, 0);
  2343.     }
  2344. }
  2345.  
  2346.  /*
  2347.   * recursive because it is easier
  2348.   * no-op if child not descended from ancestor
  2349.   */
  2350. static Bool
  2351. FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
  2352.     DeviceIntPtr dev;
  2353.     WindowPtr ancestor, child, skipChild;
  2354.     int mode, detail;
  2355.     Bool doAncestor;
  2356. {
  2357.     if (child == NullWindow)
  2358.     return ancestor == NullWindow;
  2359.     if (ancestor == child)
  2360.     {
  2361.     if (doAncestor)
  2362.         FocusEvent(dev, FocusIn, mode, detail, child);
  2363.     return TRUE;
  2364.     }
  2365.     if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
  2366.               doAncestor))
  2367.     {
  2368.     if (child != skipChild)
  2369.         FocusEvent(dev, FocusIn, mode, detail, child);
  2370.     return TRUE;
  2371.     }
  2372.     return FALSE;
  2373. }
  2374.  
  2375. /* dies horribly if ancestor is not an ancestor of child */
  2376. static void
  2377. FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
  2378.     DeviceIntPtr dev;
  2379.     WindowPtr child, ancestor;
  2380.     int detail;
  2381.     Bool doAncestor;
  2382. {
  2383.     register WindowPtr  pWin;
  2384.  
  2385.     for (pWin = child; pWin != ancestor; pWin = pWin->parent)
  2386.     FocusEvent(dev, FocusOut, mode, detail, pWin);
  2387.     if (doAncestor)
  2388.     FocusEvent(dev, FocusOut, mode, detail, ancestor);
  2389. }
  2390.  
  2391. void
  2392. DoFocusEvents(dev, fromWin, toWin, mode)
  2393.     DeviceIntPtr dev;
  2394.     WindowPtr fromWin, toWin;
  2395.     int mode;
  2396. {
  2397.     int     out, in;               /* for holding details for to/from
  2398.                           PointerRoot/None */
  2399.     int     i;
  2400.  
  2401.     if (fromWin == toWin)
  2402.     return;
  2403.     out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  2404.     in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
  2405.  /* wrong values if neither, but then not referenced */
  2406.  
  2407.     if ((toWin == NullWindow) || (toWin == PointerRootWin))
  2408.     {
  2409.     if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  2410.        {
  2411.         if (fromWin == PointerRootWin)
  2412.         FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  2413.                    TRUE);
  2414.         /* Notify all the roots */
  2415.         for (i=0; i<screenInfo.numScreens; i++)
  2416.             FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  2417.     }
  2418.     else
  2419.     {
  2420.         if (IsParent(fromWin, sprite.win))
  2421.           FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
  2422.                  FALSE);
  2423.         FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  2424.         /* next call catches the root too, if the screen changed */
  2425.         FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
  2426.                NotifyNonlinearVirtual, FALSE);
  2427.     }
  2428.     /* Notify all the roots */
  2429.     for (i=0; i<screenInfo.numScreens; i++)
  2430.         FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
  2431.     if (toWin == PointerRootWin)
  2432.         (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
  2433.                 NotifyPointer, TRUE);
  2434.     }
  2435.     else
  2436.     {
  2437.     if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
  2438.     {
  2439.         if (fromWin == PointerRootWin)
  2440.         FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
  2441.                    TRUE);
  2442.         for (i=0; i<screenInfo.numScreens; i++)
  2443.           FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
  2444.         if (toWin->parent != NullWindow)
  2445.           (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
  2446.                   NotifyNonlinearVirtual, TRUE);
  2447.         FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  2448.         if (IsParent(toWin, sprite.win))
  2449.                (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
  2450.                    NotifyPointer, FALSE);
  2451.     }
  2452.     else
  2453.     {
  2454.         if (IsParent(toWin, fromWin))
  2455.         {
  2456.         FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
  2457.         FocusOutEvents(dev, fromWin->parent, toWin, mode,
  2458.                    NotifyVirtual, FALSE);
  2459.         FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
  2460.         if ((IsParent(toWin, sprite.win)) &&
  2461.             (sprite.win != fromWin) &&
  2462.             (!IsParent(fromWin, sprite.win)) &&
  2463.             (!IsParent(sprite.win, fromWin)))
  2464.             (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  2465.                     mode, NotifyPointer, FALSE);
  2466.         }
  2467.         else
  2468.         if (IsParent(fromWin, toWin))
  2469.         {
  2470.             if ((IsParent(fromWin, sprite.win)) &&
  2471.                 (sprite.win != fromWin) &&
  2472.                 (!IsParent(toWin, sprite.win)) &&
  2473.                 (!IsParent(sprite.win, toWin)))
  2474.             FocusOutEvents(dev, sprite.win, fromWin, mode,
  2475.                        NotifyPointer, FALSE);
  2476.             FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
  2477.             (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
  2478.                     NotifyVirtual, FALSE);
  2479.             FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
  2480.         }
  2481.         else
  2482.         {
  2483.         /* neither fromWin or toWin is child of other */
  2484.             WindowPtr common = CommonAncestor(toWin, fromWin);
  2485.         /* common == NullWindow ==> different screens */
  2486.             if (IsParent(fromWin, sprite.win))
  2487.             FocusOutEvents(dev, sprite.win, fromWin, mode,
  2488.                        NotifyPointer, FALSE);
  2489.             FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
  2490.             if (fromWin->parent != NullWindow)
  2491.               FocusOutEvents(dev, fromWin->parent, common, mode,
  2492.                      NotifyNonlinearVirtual, FALSE);
  2493.             if (toWin->parent != NullWindow)
  2494.               (void)FocusInEvents(dev, common, toWin, toWin, mode,
  2495.                       NotifyNonlinearVirtual, FALSE);
  2496.             FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
  2497.             if (IsParent(toWin, sprite.win))
  2498.             (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
  2499.                         mode, NotifyPointer, FALSE);
  2500.         }
  2501.     }
  2502.     }
  2503. }
  2504.  
  2505. int
  2506. SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
  2507.     ClientPtr client;
  2508.     DeviceIntPtr dev;
  2509.     Window focusID;
  2510.     CARD8 revertTo;
  2511.     Time ctime;
  2512.     Bool followOK;
  2513. {
  2514.     register FocusClassPtr focus;
  2515.     register WindowPtr focusWin;
  2516.     int mode;
  2517.     TimeStamp time;
  2518.  
  2519.     UpdateCurrentTime();
  2520.     if ((revertTo != RevertToParent) &&
  2521.     (revertTo != RevertToPointerRoot) &&
  2522.     (revertTo != RevertToNone) &&
  2523.     ((revertTo != RevertToFollowKeyboard) || !followOK))
  2524.     {
  2525.     client->errorValue = revertTo;
  2526.     return BadValue;
  2527.     }
  2528.     time = ClientTimeToServerTime(ctime);
  2529.     if ((focusID == None) || (focusID == PointerRoot))
  2530.     focusWin = (WindowPtr)focusID;
  2531.     else if ((focusID == FollowKeyboard) && followOK)
  2532.     focusWin = inputInfo.keyboard->focus->win;
  2533.     else if (!(focusWin = LookupWindow(focusID, client)))
  2534.     return BadWindow;
  2535.     else
  2536.     {
  2537.      /* It is a match error to try to set the input focus to an 
  2538.     unviewable window. */
  2539.  
  2540.     if(!focusWin->realized)
  2541.         return(BadMatch);
  2542.     }
  2543.     focus = dev->focus;
  2544.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2545.     (CompareTimeStamps(time, focus->time) == EARLIER))
  2546.     return Success;
  2547.     mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
  2548.     if (focus->win == FollowKeyboardWin)
  2549.     DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
  2550.     else
  2551.     DoFocusEvents(dev, focus->win, focusWin, mode);
  2552.     focus->time = time;
  2553.     focus->revert = revertTo;
  2554.     if (focusID == FollowKeyboard)
  2555.     focus->win = FollowKeyboardWin;
  2556.     else
  2557.     focus->win = focusWin;
  2558.     if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
  2559.     focus->traceGood = 0;
  2560.     else
  2561.     {
  2562.         int depth = 0;
  2563.     register WindowPtr pWin;
  2564.  
  2565.         for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
  2566.         if (depth > focus->traceSize)
  2567.         {
  2568.         focus->traceSize = depth+1;
  2569.         Must_have_memory = TRUE; /* XXX */
  2570.         focus->trace = (WindowPtr *)xrealloc(focus->trace,
  2571.                          focus->traceSize *
  2572.                          sizeof(WindowPtr));
  2573.         Must_have_memory = FALSE; /* XXX */
  2574.     }
  2575.     focus->traceGood = depth;
  2576.         for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
  2577.         focus->trace[depth] = pWin;
  2578.     }
  2579.     return Success;
  2580. }
  2581.  
  2582. int
  2583. ProcSetInputFocus(client)
  2584.     ClientPtr client;
  2585. {
  2586.     REQUEST(xSetInputFocusReq);
  2587.  
  2588.     REQUEST_SIZE_MATCH(xSetInputFocusReq);
  2589.     return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
  2590.              stuff->revertTo, stuff->time, FALSE);
  2591. }
  2592.  
  2593. int
  2594. ProcGetInputFocus(client)
  2595.     ClientPtr client;
  2596. {
  2597.     xGetInputFocusReply rep;
  2598.     REQUEST(xReq);
  2599.     FocusClassPtr focus = inputInfo.keyboard->focus;
  2600.  
  2601.     REQUEST_SIZE_MATCH(xReq);
  2602.     rep.type = X_Reply;
  2603.     rep.length = 0;
  2604.     rep.sequenceNumber = client->sequence;
  2605.     if (focus->win == NoneWin)
  2606.     rep.focus = None;
  2607.     else if (focus->win == PointerRootWin)
  2608.     rep.focus = PointerRoot;
  2609.     else rep.focus = focus->win->drawable.id;
  2610.     rep.revertTo = focus->revert;
  2611.     WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
  2612.     return Success;
  2613. }
  2614.  
  2615. int
  2616. ProcGrabPointer(client)
  2617.     ClientPtr client;
  2618. {
  2619.     xGrabPointerReply rep;
  2620.     DeviceIntPtr device = inputInfo.pointer;
  2621.     GrabPtr grab;
  2622.     WindowPtr pWin, confineTo;
  2623.     CursorPtr cursor;
  2624.     REQUEST(xGrabPointerReq);
  2625.     TimeStamp time;
  2626.  
  2627.     REQUEST_SIZE_MATCH(xGrabPointerReq);
  2628.     UpdateCurrentTime();
  2629.     if ((stuff->pointerMode != GrabModeSync) &&
  2630.     (stuff->pointerMode != GrabModeAsync))
  2631.     {
  2632.     client->errorValue = stuff->pointerMode;
  2633.         return BadValue;
  2634.     }
  2635.     if ((stuff->keyboardMode != GrabModeSync) &&
  2636.     (stuff->keyboardMode != GrabModeAsync))
  2637.     {
  2638.     client->errorValue = stuff->keyboardMode;
  2639.         return BadValue;
  2640.     }
  2641.     if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  2642.     {
  2643.     client->errorValue = stuff->ownerEvents;
  2644.         return BadValue;
  2645.     }
  2646.     if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  2647.     {
  2648.     client->errorValue = stuff->eventMask;
  2649.         return BadValue;
  2650.     }
  2651.     pWin = LookupWindow(stuff->grabWindow, client);
  2652.     if (!pWin)
  2653.     return BadWindow;
  2654.     if (stuff->confineTo == None)
  2655.     confineTo = NullWindow;
  2656.     else
  2657.     {
  2658.     confineTo = LookupWindow(stuff->confineTo, client);
  2659.     if (!confineTo)
  2660.         return BadWindow;
  2661.     }
  2662.     if (stuff->cursor == None)
  2663.     cursor = NullCursor;
  2664.     else
  2665.     {
  2666.     cursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  2667.     if (!cursor)
  2668.     {
  2669.         client->errorValue = stuff->cursor;
  2670.         return BadCursor;
  2671.     }
  2672.     }
  2673.     /* at this point, some sort of reply is guaranteed. */
  2674.     time = ClientTimeToServerTime(stuff->time);
  2675.     rep.type = X_Reply;
  2676.     rep.sequenceNumber = client->sequence;
  2677.     rep.length = 0;
  2678.     grab = device->grab;
  2679.     if ((grab) && !SameClient(grab, client))
  2680.     rep.status = AlreadyGrabbed;
  2681.     else if ((!pWin->realized) ||
  2682.          (confineTo &&
  2683.         !(confineTo->realized &&
  2684.           (* confineTo->drawable.pScreen->RegionNotEmpty)
  2685.             (&confineTo->borderSize))))
  2686.     rep.status = GrabNotViewable;
  2687.     else if (device->sync.frozen &&
  2688.          device->sync.other && !SameClient(device->sync.other, client))
  2689.     rep.status = GrabFrozen;
  2690.     else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2691.          (CompareTimeStamps(time, device->grabTime) == EARLIER))
  2692.     rep.status = GrabInvalidTime;
  2693.     else
  2694.     {
  2695.     GrabRec tempGrab;
  2696.  
  2697.     if (grab && grab->confineTo && !confineTo)
  2698.         ConfineCursorToWindow(ROOT, FALSE);
  2699.     tempGrab.cursor = cursor;
  2700.     tempGrab.resource = client->clientAsMask;
  2701.     tempGrab.ownerEvents = stuff->ownerEvents;
  2702.     tempGrab.eventMask = stuff->eventMask;
  2703.     tempGrab.confineTo = confineTo;
  2704.     tempGrab.window = pWin;
  2705.     tempGrab.keyboardMode = stuff->keyboardMode;
  2706.     tempGrab.pointerMode = stuff->pointerMode;
  2707.     tempGrab.device = device;
  2708.     (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
  2709.     rep.status = GrabSuccess;
  2710.     }
  2711.     WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
  2712.     return Success;
  2713. }
  2714.  
  2715. int
  2716. ProcChangeActivePointerGrab(client)
  2717.     ClientPtr client;
  2718. {
  2719.     DeviceIntPtr device = inputInfo.pointer;
  2720.     register GrabPtr grab = device->grab;
  2721.     CursorPtr newCursor, oldCursor;
  2722.     REQUEST(xChangeActivePointerGrabReq);
  2723.     TimeStamp time;
  2724.  
  2725.     REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
  2726.     if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
  2727.     {
  2728.     client->errorValue = stuff->eventMask;
  2729.         return BadValue;
  2730.     }
  2731.     if (stuff->cursor == None)
  2732.     newCursor = NullCursor;
  2733.     else
  2734.     {
  2735.     newCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  2736.     if (!newCursor)
  2737.     {
  2738.         client->errorValue = stuff->cursor;
  2739.         return BadCursor;
  2740.     }
  2741.     }
  2742.     if (!grab)
  2743.     return Success;
  2744.     if (!SameClient(grab, client))
  2745.     return Success;
  2746.     time = ClientTimeToServerTime(stuff->time);
  2747.     if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2748.          (CompareTimeStamps(time, device->grabTime) == EARLIER))
  2749.     return Success;
  2750.     oldCursor = grab->cursor;
  2751.     grab->cursor = newCursor;
  2752.     if (newCursor)
  2753.     newCursor->refcnt++;
  2754.     PostNewCursor();
  2755.     if (oldCursor)
  2756.     FreeCursor(oldCursor, (Cursor)0);
  2757.     grab->eventMask = stuff->eventMask;
  2758.     return Success;
  2759. }
  2760.  
  2761. int
  2762. ProcUngrabPointer(client)
  2763.     ClientPtr client;
  2764. {
  2765.     DeviceIntPtr device = inputInfo.pointer;
  2766.     GrabPtr grab;
  2767.     TimeStamp time;
  2768.     REQUEST(xResourceReq);
  2769.  
  2770.     REQUEST_SIZE_MATCH(xResourceReq);
  2771.     UpdateCurrentTime();
  2772.     grab = device->grab;
  2773.     time = ClientTimeToServerTime(stuff->id);
  2774.     if ((CompareTimeStamps(time, currentTime) != LATER) &&
  2775.         (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  2776.         (grab) && SameClient(grab, client))
  2777.     (*device->DeactivateGrab)(device);
  2778.     return Success;
  2779. }
  2780.  
  2781. int
  2782. GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
  2783.        mask, status)
  2784.     register ClientPtr client;
  2785.     register DeviceIntPtr dev;
  2786.     unsigned this_mode;
  2787.     unsigned other_mode;
  2788.     Window grabWindow;
  2789.     unsigned ownerEvents;
  2790.     Time ctime;
  2791.     Mask mask;
  2792.     CARD8 *status;
  2793. {
  2794.     register WindowPtr pWin;
  2795.     register GrabPtr grab;
  2796.     TimeStamp time;
  2797.  
  2798.     UpdateCurrentTime();
  2799.     if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
  2800.     {
  2801.     client->errorValue = this_mode;
  2802.         return BadValue;
  2803.     }
  2804.     if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
  2805.     {
  2806.     client->errorValue = other_mode;
  2807.         return BadValue;
  2808.     }
  2809.     if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
  2810.     {
  2811.     client->errorValue = ownerEvents;
  2812.         return BadValue;
  2813.     }
  2814.     pWin = LookupWindow(grabWindow, client);
  2815.     if (!pWin)
  2816.     return BadWindow;
  2817.     time = ClientTimeToServerTime(ctime);
  2818.     grab = dev->grab;
  2819.     if (grab && !SameClient(grab, client))
  2820.     *status = AlreadyGrabbed;
  2821.     else if (!pWin->realized)
  2822.     *status = GrabNotViewable;
  2823.     else if ((CompareTimeStamps(time, currentTime) == LATER) ||
  2824.          (CompareTimeStamps(time, dev->grabTime) == EARLIER))
  2825.     *status = GrabInvalidTime;
  2826.     else if (dev->sync.frozen &&
  2827.          dev->sync.other && !SameClient(dev->sync.other, client))
  2828.     *status = GrabFrozen;
  2829.     else
  2830.     {
  2831.     GrabRec tempGrab;
  2832.  
  2833.     tempGrab.window = pWin;
  2834.     tempGrab.resource = client->clientAsMask;
  2835.     tempGrab.ownerEvents = ownerEvents;
  2836.     tempGrab.keyboardMode = this_mode;
  2837.     tempGrab.pointerMode = other_mode;
  2838.     tempGrab.eventMask = mask;
  2839.     tempGrab.device = dev;
  2840.     (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
  2841.     *status = GrabSuccess;
  2842.     }
  2843.     return Success;
  2844. }
  2845.  
  2846. int
  2847. ProcGrabKeyboard(client)
  2848.     ClientPtr client;
  2849. {
  2850.     xGrabKeyboardReply rep;
  2851.     REQUEST(xGrabKeyboardReq);
  2852.     int result;
  2853.  
  2854.     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
  2855.     result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
  2856.             stuff->pointerMode, stuff->grabWindow,
  2857.             stuff->ownerEvents, stuff->time,
  2858.             KeyPressMask | KeyReleaseMask, &rep.status);
  2859.     if (result != Success)
  2860.     return result;
  2861.     rep.type = X_Reply;
  2862.     rep.sequenceNumber = client->sequence;
  2863.     rep.length = 0;
  2864.     WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
  2865.     return Success;
  2866. }
  2867.  
  2868. int
  2869. ProcUngrabKeyboard(client)
  2870.     ClientPtr client;
  2871. {
  2872.     DeviceIntPtr device = inputInfo.keyboard;
  2873.     GrabPtr grab;
  2874.     TimeStamp time;
  2875.     REQUEST(xResourceReq);
  2876.  
  2877.     REQUEST_SIZE_MATCH(xResourceReq);
  2878.     UpdateCurrentTime();
  2879.     grab = device->grab;
  2880.     time = ClientTimeToServerTime(stuff->id);
  2881.     if ((CompareTimeStamps(time, currentTime) != LATER) &&
  2882.     (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
  2883.     (grab) && SameClient(grab, client))
  2884.     (*device->DeactivateGrab)(device);
  2885.     return Success;
  2886. }
  2887.  
  2888. int
  2889. ProcQueryPointer(client)
  2890.     ClientPtr client;
  2891. {
  2892.     xQueryPointerReply rep;
  2893.     WindowPtr pWin, t;
  2894.     REQUEST(xResourceReq);
  2895.     DeviceIntPtr mouse = inputInfo.pointer;
  2896.  
  2897.     REQUEST_SIZE_MATCH(xResourceReq);
  2898.     pWin = LookupWindow(stuff->id, client);
  2899.     if (!pWin)
  2900.     return BadWindow;
  2901.     if (mouse->valuator->motionHintWindow)
  2902.     MaybeStopHint(mouse, client);
  2903.     rep.type = X_Reply;
  2904.     rep.sequenceNumber = client->sequence;
  2905.     rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
  2906.     rep.length = 0;
  2907.     rep.root = (ROOT)->drawable.id;
  2908.     rep.rootX = sprite.hot.x;
  2909.     rep.rootY = sprite.hot.y;
  2910.     rep.child = None;
  2911.     if (sprite.hot.pScreen == pWin->drawable.pScreen)
  2912.     {
  2913.     rep.sameScreen = xTrue;
  2914.     rep.winX = sprite.hot.x - pWin->drawable.x;
  2915.     rep.winY = sprite.hot.y - pWin->drawable.y;
  2916.     for (t = sprite.win; t; t = t->parent)
  2917.         if (t->parent == pWin)
  2918.         {
  2919.         rep.child = t->drawable.id;
  2920.         break;
  2921.         }
  2922.     }
  2923.     else
  2924.     {
  2925.     rep.sameScreen = xFalse;
  2926.     rep.winX = 0;
  2927.     rep.winY = 0;
  2928.     }
  2929.     WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
  2930.  
  2931.     return(Success);    
  2932. }
  2933.  
  2934. void
  2935. InitEvents()
  2936. {
  2937.     int i;
  2938.  
  2939.     sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
  2940.     inputInfo.numDevices = 0;
  2941.     inputInfo.devices = (DeviceIntPtr)NULL;
  2942.     inputInfo.off_devices = (DeviceIntPtr)NULL;
  2943.     inputInfo.keyboard = (DeviceIntPtr)NULL;
  2944.     inputInfo.pointer = (DeviceIntPtr)NULL;
  2945.     if (spriteTraceSize == 0)
  2946.     {
  2947.     spriteTraceSize = 32;
  2948.     spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
  2949.     if (!spriteTrace)
  2950.         FatalError("failed to allocate spriteTrace");
  2951.     }
  2952.     spriteTraceGood = 0;
  2953.     lastEventMask = OwnerGrabButtonMask;
  2954.     filters[MotionNotify] = PointerMotionMask;
  2955.     sprite.win = NullWindow;
  2956.     sprite.current = NullCursor;
  2957.     sprite.hotLimits.x1 = 0;
  2958.     sprite.hotLimits.y1 = 0;
  2959.     sprite.hotLimits.x2 = 0;
  2960.     sprite.hotLimits.y2 = 0;
  2961.     syncEvents.replayDev = (DeviceIntPtr)NULL;
  2962.     syncEvents.replayWin = NullWindow;
  2963.     while (syncEvents.pending)
  2964.     {
  2965.     QdEventPtr next = syncEvents.pending->next;
  2966.     xfree(syncEvents.pending);
  2967.     syncEvents.pending = next;
  2968.     }
  2969.     syncEvents.pendtail = &syncEvents.pending;
  2970.     syncEvents.playingEvents = FALSE;
  2971.     syncEvents.time.months = 0;
  2972.     syncEvents.time.milliseconds = 0;    /* hardly matters */
  2973.     currentTime.months = 0;
  2974.     currentTime.milliseconds = GetTimeInMillis();
  2975.     lastDeviceEventTime = currentTime;
  2976.     for (i = 0; i < DNPMCOUNT; i++)
  2977.     {
  2978.     DontPropagateMasks[i] = 0;
  2979.     DontPropagateRefCnts[i] = 0;
  2980.     }
  2981. }
  2982.  
  2983. int
  2984. ProcSendEvent(client)
  2985.     ClientPtr client;
  2986. {
  2987.     extern int lastEvent;         /* Defined in extension.c */
  2988.     WindowPtr pWin;
  2989.     WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
  2990.     REQUEST(xSendEventReq);
  2991.  
  2992.     REQUEST_SIZE_MATCH(xSendEventReq);
  2993.  
  2994.     /* The client's event type must be a core event type or one defined by an
  2995.     extension. */
  2996.  
  2997.     if ( ! ((stuff->event.u.u.type > X_Reply &&
  2998.          stuff->event.u.u.type < LASTEvent) || 
  2999.         (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
  3000.          stuff->event.u.u.type < lastEvent)))
  3001.     {
  3002.     client->errorValue = stuff->event.u.u.type;
  3003.     return BadValue;
  3004.     }
  3005.     if (stuff->event.u.u.type == ClientMessage &&
  3006.     stuff->event.u.u.detail != 8 &&
  3007.     stuff->event.u.u.detail != 16 &&
  3008.     stuff->event.u.u.detail != 32 &&
  3009.     !permitOldBugs)
  3010.     {
  3011.     client->errorValue = stuff->event.u.u.detail;
  3012.     return BadValue;
  3013.     }
  3014.     if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
  3015.     {
  3016.     client->errorValue = stuff->eventMask;
  3017.     return BadValue;
  3018.     }
  3019.  
  3020.     if (stuff->destination == PointerWindow)
  3021.     pWin = sprite.win;
  3022.     else if (stuff->destination == InputFocus)
  3023.     {
  3024.     WindowPtr inputFocus = inputInfo.keyboard->focus->win;
  3025.  
  3026.     if (inputFocus == NoneWin)
  3027.         return Success;
  3028.  
  3029.     /* If the input focus is PointerRootWin, send the event to where
  3030.     the pointer is if possible, then perhaps propogate up to root. */
  3031.        if (inputFocus == PointerRootWin)
  3032.         inputFocus = ROOT;
  3033.  
  3034.     if (IsParent(inputFocus, sprite.win))
  3035.     {
  3036.         effectiveFocus = inputFocus;
  3037.         pWin = sprite.win;
  3038.     }
  3039.     else
  3040.         effectiveFocus = pWin = inputFocus;
  3041.     }
  3042.     else
  3043.     pWin = LookupWindow(stuff->destination, client);
  3044.     if (!pWin)
  3045.     return BadWindow;
  3046.     if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
  3047.     {
  3048.     client->errorValue = stuff->propagate;
  3049.     return BadValue;
  3050.     }
  3051.     stuff->event.u.u.type |= 0x80;
  3052.     if (stuff->propagate)
  3053.     {
  3054.     for (;pWin; pWin = pWin->parent)
  3055.     {
  3056.         if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  3057.                       NullGrab, 0))
  3058.         return Success;
  3059.         if (pWin == effectiveFocus)
  3060.         return Success;
  3061.         stuff->eventMask &= ~wDontPropagateMask(pWin);
  3062.         if (!stuff->eventMask)
  3063.         break;
  3064.     }
  3065.     }
  3066.     else
  3067.     (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
  3068.                     NullGrab, 0);
  3069.     return Success;
  3070. }
  3071.  
  3072. int
  3073. ProcUngrabKey(client)
  3074.     ClientPtr client;
  3075. {
  3076.     REQUEST(xUngrabKeyReq);
  3077.     WindowPtr pWin;
  3078.     GrabRec tempGrab;
  3079.     DeviceIntPtr keybd = inputInfo.keyboard;
  3080.  
  3081.     REQUEST_SIZE_MATCH(xUngrabKeyReq);
  3082.     pWin = LookupWindow(stuff->grabWindow, client);
  3083.     if (!pWin)
  3084.     return BadWindow;
  3085.     if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
  3086.      (stuff->key < keybd->key->curKeySyms.minKeyCode))
  3087.     && (stuff->key != AnyKey))
  3088.     {
  3089.     client->errorValue = stuff->key;
  3090.         return BadValue;
  3091.     }
  3092.     if ((stuff->modifiers != AnyModifier) &&
  3093.     (stuff->modifiers & ~AllModifiersMask))
  3094.     {
  3095.     client->errorValue = stuff->modifiers;
  3096.     return BadValue;
  3097.     }
  3098.  
  3099.     tempGrab.resource = client->clientAsMask;
  3100.     tempGrab.device = keybd;
  3101.     tempGrab.window = pWin;
  3102.     tempGrab.modifiersDetail.exact = stuff->modifiers;
  3103.     tempGrab.modifiersDetail.pMask = NULL;
  3104.     tempGrab.modifierDevice = inputInfo.keyboard;
  3105.     tempGrab.type = KeyPress;
  3106.     tempGrab.detail.exact = stuff->key;
  3107.     tempGrab.detail.pMask = NULL;
  3108.  
  3109.     if (!DeletePassiveGrabFromList(&tempGrab))
  3110.     return(BadAlloc);
  3111.     return(Success);
  3112. }
  3113.  
  3114. int
  3115. ProcGrabKey(client)
  3116.     ClientPtr client;
  3117. {
  3118.     WindowPtr pWin;
  3119.     REQUEST(xGrabKeyReq);
  3120.     GrabPtr grab;
  3121.     DeviceIntPtr keybd = inputInfo.keyboard;
  3122.  
  3123.     REQUEST_SIZE_MATCH(xGrabKeyReq);
  3124.     if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
  3125.     {
  3126.     client->errorValue = stuff->ownerEvents;
  3127.     return(BadValue);
  3128.     }
  3129.     if ((stuff->pointerMode != GrabModeSync) &&
  3130.     (stuff->pointerMode != GrabModeAsync))
  3131.     {
  3132.     client->errorValue = stuff->pointerMode;
  3133.         return BadValue;
  3134.     }
  3135.     if ((stuff->keyboardMode != GrabModeSync) &&
  3136.     (stuff->keyboardMode != GrabModeAsync))
  3137.     {
  3138.     client->errorValue = stuff->keyboardMode;
  3139.         return BadValue;
  3140.     }
  3141.     if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
  3142.      (stuff->key < keybd->key->curKeySyms.minKeyCode))
  3143.     && (stuff->key != AnyKey))
  3144.     {
  3145.     client->errorValue = stuff->key;
  3146.         return BadValue;
  3147.     }
  3148.     if ((stuff->modifiers != AnyModifier) &&
  3149.     (stuff->modifiers & ~AllModifiersMask))
  3150.     {
  3151.     client->errorValue = stuff->modifiers;
  3152.     return BadValue;
  3153.     }
  3154.     pWin = LookupWindow(stuff->grabWindow, client);
  3155.     if (!pWin)
  3156.     return BadWindow;
  3157.  
  3158.     grab = CreateGrab(client->index, keybd, pWin, 
  3159.     (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
  3160.     (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
  3161.     keybd, stuff->modifiers, KeyPress, stuff->key, NullWindow, NullCursor);
  3162.     if (!grab)
  3163.     return BadAlloc;
  3164.     return AddPassiveGrabToList(grab);
  3165. }
  3166.  
  3167. int
  3168. ProcGrabButton(client)
  3169.     ClientPtr client;
  3170. {
  3171.     WindowPtr pWin, confineTo;
  3172.     REQUEST(xGrabButtonReq);
  3173.     CursorPtr cursor;
  3174.     GrabPtr grab;
  3175.  
  3176.     REQUEST_SIZE_MATCH(xGrabButtonReq);
  3177.     if ((stuff->pointerMode != GrabModeSync) &&
  3178.     (stuff->pointerMode != GrabModeAsync))
  3179.     {
  3180.     client->errorValue = stuff->pointerMode;
  3181.         return BadValue;
  3182.     }
  3183.     if ((stuff->keyboardMode != GrabModeSync) &&
  3184.     (stuff->keyboardMode != GrabModeAsync))
  3185.     {
  3186.     client->errorValue = stuff->keyboardMode;
  3187.         return BadValue;
  3188.     }
  3189.     if ((stuff->modifiers != AnyModifier) &&
  3190.     (stuff->modifiers & ~AllModifiersMask))
  3191.     {
  3192.     client->errorValue = stuff->modifiers;
  3193.     return BadValue;
  3194.     }
  3195.     if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
  3196.     {
  3197.     client->errorValue = stuff->ownerEvents;
  3198.     return BadValue;
  3199.     }
  3200.     if (stuff->eventMask & ~PointerGrabMask)
  3201.     {
  3202.     client->errorValue = stuff->eventMask;
  3203.         return BadValue;
  3204.     }
  3205.     pWin = LookupWindow(stuff->grabWindow, client);
  3206.     if (!pWin)
  3207.     return BadWindow;
  3208.     if (stuff->confineTo == None)
  3209.     confineTo = NullWindow;
  3210.     else
  3211.     {
  3212.     confineTo = LookupWindow(stuff->confineTo, client);
  3213.     if (!confineTo)
  3214.         return BadWindow;
  3215.     }
  3216.     if (stuff->cursor == None)
  3217.     cursor = NullCursor;
  3218.     else
  3219.     {
  3220.     cursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  3221.     if (!cursor)
  3222.     {
  3223.         client->errorValue = stuff->cursor;
  3224.         return BadCursor;
  3225.     }
  3226.     }
  3227.  
  3228.     grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
  3229.     permitOldBugs ? (Mask)(stuff->eventMask |
  3230.                    ButtonPressMask | ButtonReleaseMask) :
  3231.             (Mask)stuff->eventMask,
  3232.     (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
  3233.     (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
  3234.     ButtonPress, stuff->button, confineTo, cursor);
  3235.     if (!grab)
  3236.     return BadAlloc;
  3237.     return AddPassiveGrabToList(grab);
  3238. }
  3239.  
  3240. int
  3241. ProcUngrabButton(client)
  3242.     ClientPtr client;
  3243. {
  3244.     REQUEST(xUngrabButtonReq);
  3245.     WindowPtr pWin;
  3246.     GrabRec tempGrab;
  3247.  
  3248.     REQUEST_SIZE_MATCH(xUngrabButtonReq);
  3249.     if ((stuff->modifiers != AnyModifier) &&
  3250.     (stuff->modifiers & ~AllModifiersMask))
  3251.     {
  3252.     client->errorValue = stuff->modifiers;
  3253.     return BadValue;
  3254.     }
  3255.     pWin = LookupWindow(stuff->grabWindow, client);
  3256.     if (!pWin)
  3257.     return BadWindow;
  3258.  
  3259.     tempGrab.resource = client->clientAsMask;
  3260.     tempGrab.device = inputInfo.pointer;
  3261.     tempGrab.window = pWin;
  3262.     tempGrab.modifiersDetail.exact = stuff->modifiers;
  3263.     tempGrab.modifiersDetail.pMask = NULL;
  3264.     tempGrab.modifierDevice = inputInfo.keyboard;
  3265.     tempGrab.type = ButtonPress;
  3266.     tempGrab.detail.exact = stuff->button;
  3267.     tempGrab.detail.pMask = NULL;
  3268.  
  3269.     if (!DeletePassiveGrabFromList(&tempGrab))
  3270.     return(BadAlloc);
  3271.     return(Success);
  3272. }
  3273.  
  3274. void
  3275. DeleteWindowFromAnyEvents(pWin, freeResources)
  3276.     WindowPtr        pWin;
  3277.     Bool        freeResources;
  3278. {
  3279.     WindowPtr        parent;
  3280.     DeviceIntPtr    mouse = inputInfo.pointer;
  3281.     DeviceIntPtr    keybd = inputInfo.keyboard;
  3282.     FocusClassPtr    focus = keybd->focus;
  3283.     OtherClientsPtr    oc;
  3284.     GrabPtr        passive;
  3285.  
  3286.  
  3287.     /* Deactivate any grabs performed on this window, before making any
  3288.     input focus changes. */
  3289.  
  3290.     if (mouse->grab &&
  3291.     ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
  3292.     (*mouse->DeactivateGrab)(mouse);
  3293.  
  3294.     /* Deactivating a keyboard grab should cause focus events. */
  3295.  
  3296.     if (keybd->grab && (keybd->grab->window == pWin))
  3297.     (*keybd->DeactivateGrab)(keybd);
  3298.  
  3299.     /* If the focus window is a root window (ie. has no parent) then don't 
  3300.     delete the focus from it. */
  3301.     
  3302.     if ((pWin == focus->win) && (pWin->parent != NullWindow))
  3303.     {
  3304.     int focusEventMode = NotifyNormal;
  3305.  
  3306.      /* If a grab is in progress, then alter the mode of focus events. */
  3307.  
  3308.     if (keybd->grab)
  3309.         focusEventMode = NotifyWhileGrabbed;
  3310.  
  3311.     switch (focus->revert)
  3312.     {
  3313.     case RevertToNone:
  3314.         DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
  3315.         focus->win = NoneWin;
  3316.         focus->traceGood = 0;
  3317.         break;
  3318.     case RevertToParent:
  3319.         parent = pWin;
  3320.         do
  3321.         {
  3322.         parent = parent->parent;
  3323.         focus->traceGood--;
  3324.         } while (!parent->realized
  3325. /* This would be a good protocol change -- windows being reparented
  3326.    during SaveSet processing would cause the focus to revert to the
  3327.    nearest enclosing window which will survive the death of the exiting
  3328.    client, instead of ending up reverting to a dying window and thence
  3329.    to None
  3330.  */
  3331. #ifdef NOTDEF
  3332.            || clients[CLIENT_ID(parent->drawable.id)]->clientGone
  3333. #endif
  3334.         );
  3335.         DoFocusEvents(keybd, pWin, parent, focusEventMode);
  3336.         focus->win = parent;
  3337.         focus->revert = RevertToNone;
  3338.         break;
  3339.     case RevertToPointerRoot:
  3340.         DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
  3341.         focus->win = PointerRootWin;
  3342.         focus->traceGood = 0;
  3343.         break;
  3344.     }
  3345.     }
  3346.  
  3347.     if (mouse->valuator->motionHintWindow == pWin)
  3348.     mouse->valuator->motionHintWindow = NullWindow;
  3349.  
  3350.     if (freeResources)
  3351.     {
  3352.     if (pWin->dontPropagate)
  3353.         DontPropagateRefCnts[pWin->dontPropagate]--;
  3354.     while (oc = wOtherClients(pWin))
  3355.         FreeResource(oc->resource, RT_NONE);
  3356.     while (passive = wPassiveGrabs(pWin))
  3357.         FreeResource(passive->resource, RT_NONE);
  3358.      }
  3359. #ifdef XINPUT
  3360.     DeleteWindowFromAnyExtEvents(pWin, freeResources);
  3361. #endif
  3362. }
  3363.  
  3364. /* Call this whenever some window at or below pWin has changed geometry */
  3365.  
  3366. /*ARGSUSED*/
  3367. void
  3368. CheckCursorConfinement(pWin)
  3369.     WindowPtr pWin;
  3370. {
  3371.     GrabPtr grab = inputInfo.pointer->grab;
  3372.     WindowPtr confineTo;
  3373.  
  3374.     if (grab && (confineTo = grab->confineTo))
  3375.     {
  3376.     if (!(* confineTo->drawable.pScreen->RegionNotEmpty)
  3377.             (&confineTo->borderSize))
  3378.         (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
  3379.     else if ((pWin == confineTo) || IsParent(pWin, confineTo))
  3380.         ConfineCursorToWindow(confineTo, TRUE);
  3381.     }
  3382. }
  3383.  
  3384. Mask
  3385. EventMaskForClient(pWin, client)
  3386.     WindowPtr        pWin;
  3387.     ClientPtr        client;
  3388. {
  3389.     register OtherClientsPtr    other;
  3390.  
  3391.     if (wClient (pWin) == client)
  3392.     return pWin->eventMask;
  3393.     for (other = wOtherClients(pWin); other; other = other->next)
  3394.     {
  3395.     if (SameClient(other, client))
  3396.         return other->mask;
  3397.     }
  3398.     return 0;
  3399. }
  3400.  
  3401. int
  3402. ProcRecolorCursor(client)
  3403.     ClientPtr client;
  3404. {
  3405.     CursorPtr pCursor;
  3406.     int        nscr;
  3407.     ScreenPtr    pscr;
  3408.     REQUEST(xRecolorCursorReq);
  3409.  
  3410.     REQUEST_SIZE_MATCH(xRecolorCursorReq);
  3411.     pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
  3412.     if ( !pCursor) 
  3413.     {
  3414.     client->errorValue = stuff->cursor;
  3415.     return (BadCursor);
  3416.     }
  3417.  
  3418.     pCursor->foreRed = stuff->foreRed;
  3419.     pCursor->foreGreen = stuff->foreGreen;
  3420.     pCursor->foreBlue = stuff->foreBlue;
  3421.  
  3422.     pCursor->backRed = stuff->backRed;
  3423.     pCursor->backGreen = stuff->backGreen;
  3424.     pCursor->backBlue = stuff->backBlue;
  3425.  
  3426.     for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
  3427.     {
  3428.     pscr = screenInfo.screens[nscr];
  3429.     ( *pscr->RecolorCursor)(pscr, pCursor,
  3430.                 (pCursor == sprite.current) &&
  3431.                 (pscr == sprite.hotPhys.pScreen));
  3432.     }
  3433.     return (Success);
  3434. }
  3435.  
  3436. void
  3437. WriteEventsToClient(pClient, count, events)
  3438.     ClientPtr    pClient;
  3439.     int        count;
  3440.     xEvent    *events;
  3441. {
  3442.     if(pClient->swapped)
  3443.     {
  3444.         int    i;
  3445.         xEvent    eventTo, *eventFrom;
  3446.  
  3447.     for(i = 0; i < count; i++)
  3448.     {
  3449.         eventFrom = &events[i];
  3450.         /* Remember to strip off the leading bit of type in case
  3451.            this event was sent with "SendEvent." */
  3452.         (*EventSwapVector[eventFrom->u.u.type & 0177])
  3453.         (eventFrom, &eventTo);
  3454.         (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
  3455.     }
  3456.     }
  3457.  
  3458.     else
  3459.     {
  3460.     (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
  3461.     }
  3462. }
  3463.