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