home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / server / xinput / xexevents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-24  |  32.1 KB  |  1,263 lines

  1. /************************************************************
  2. Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, California, and the 
  3. 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 Hewlett-Packard or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.
  14.  
  15. HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. HEWLETT-PACKARD 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.  *
  27.  *  Routines to register and initialize extension input devices.
  28.  *  This also contains ProcessOtherEvent, the routine called from DDX
  29.  *  to route extension events.
  30.  *
  31.  */
  32.  
  33. #define     NEED_EVENTS
  34. #include "X.h"
  35. #include "Xproto.h"
  36. #include "XI.h"
  37. #include "XIproto.h"
  38. #include "inputstr.h"
  39. #include "windowstr.h"
  40. #include "miscstruct.h"
  41. #include "region.h"
  42.  
  43. #define WID(w) ((w) ? ((w)->drawable.id) : 0)
  44. #define AllModifiersMask ( \
  45.     ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
  46.     Mod3Mask | Mod4Mask | Mod5Mask )
  47. #define AllButtonsMask ( \
  48.     Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
  49. #define Motion_Filter(class) (DevicePointerMotionMask | \
  50.                   (class)->state | (class)->motionMask)
  51.  
  52. void             ActivateKeyboardGrab();
  53. void             DeactivateKeyboardGrab();
  54. void             ProcessOtherEvent();
  55. void             RecalculateDeviceDeliverableEvents();
  56. static Bool        ShouldFreeInputMasks();
  57. static Bool        MakeInputMasks ();
  58. extern int        DeviceKeyPress;
  59. extern int        DeviceButtonPress;
  60. extern int        DeviceValuator;
  61. extern Mask         DevicePointerMotionMask;
  62. extern Mask         DeviceMappingNotifyMask;
  63. extern Mask         DeviceButton1Mask;
  64. extern Mask         DeviceButtonMotionMask;
  65. extern Mask         DeviceButtonGrabMask;
  66. extern Mask         DeviceOwnerGrabButtonMask;
  67. extern Mask        PropagateMask[];
  68. extern WindowPtr     GetSpriteWindow();
  69. extern InputInfo    inputInfo;
  70.  
  71. /**************************************************************************
  72.  *
  73.  * Procedures for extension device event routing.
  74.  *
  75.  */
  76.  
  77. void
  78. RegisterOtherDevice (device)
  79.     DevicePtr device;
  80.     {
  81.     device->processInputProc = ProcessOtherEvent;
  82.     device->realInputProc = ProcessOtherEvent;
  83.     ((DeviceIntPtr)device)->ActivateGrab = ActivateKeyboardGrab;
  84.     ((DeviceIntPtr)device)->DeactivateGrab = DeactivateKeyboardGrab;
  85.     }
  86.  
  87. extern    int    DeviceMotionNotify;
  88.  
  89. /*ARGSUSED*/
  90. void
  91. ProcessOtherEvent (xE, other, count)
  92.     deviceKeyButtonPointer *xE;
  93.     register DeviceIntPtr other;
  94.     int count;
  95.     {
  96.     extern    int    DeviceKeyRelease;
  97.     extern    int    DeviceButtonRelease;
  98.     extern    int    ProximityIn;
  99.     extern    int    ProximityOut;
  100.     register BYTE       *kptr;
  101.     register int        i;
  102.     register CARD16     modifiers;
  103.     register CARD16     mask;
  104.     GrabPtr             grab = other->grab;
  105.     Bool                deactivateDeviceGrab = FALSE;
  106.     int                 key, bit;
  107.     ButtonClassPtr    b = other->button;
  108.     KeyClassPtr        k = other->key;
  109.     void        NoticeEventTime();
  110.     deviceValuator    *xV = (deviceValuator *) xE;
  111.  
  112.     key = xE->detail;
  113.     NoticeEventTime(xE);
  114.     xE->state = inputInfo.keyboard->key->state | 
  115.         inputInfo.pointer->button->state;
  116.     for (i=1; i<count; i++)
  117.     if ((++xV)->type == DeviceValuator)
  118.         {
  119.         xV->device_state = 0;
  120.         if (k)
  121.         xV->device_state |= k->state;
  122.         if (b)
  123.             xV->device_state |= b->state;
  124.         }
  125.     bit = 1 << (key & 7);
  126.     
  127.     if (xE->type == DeviceKeyPress)
  128.     {
  129.     modifiers = k->modifierMap[key];
  130.         kptr = &k->down[key >> 3];
  131.     if (*kptr & bit) /* allow ddx to generate multiple downs */
  132.         {   
  133.         if (!modifiers)
  134.         {
  135.         xE->type = DeviceKeyRelease;
  136.         ProcessOtherEvent(xE, other, count);
  137.         xE->type = DeviceKeyPress;
  138.         /* release can have side effects, don't fall through */
  139.         ProcessOtherEvent(xE, other, count);
  140.         }
  141.         return;
  142.         }
  143.     if (other->valuator)
  144.         other->valuator->motionHintWindow = NullWindow;
  145.     *kptr |= bit;
  146.     for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  147.         {
  148.         if (mask & modifiers) 
  149.             {
  150.         /* This key affects modifier "i" */
  151.         k->modifierKeyCount[i]++;
  152.         k->state |= mask;
  153.         modifiers &= ~mask;
  154.         }
  155.         }
  156.     if (!grab && CheckDeviceGrabs(other, xE, 0, count))
  157.         {
  158.         other->activatingKey = key;
  159.         return;
  160.         }
  161.     }
  162.     else if (xE->type == DeviceKeyRelease)
  163.     {
  164.         kptr = &k->down[key >> 3];
  165.     if (!(*kptr & bit)) /* guard against duplicates */
  166.         return;
  167.     modifiers = k->modifierMap[key];
  168.     if (other->valuator)
  169.         other->valuator->motionHintWindow = NullWindow;
  170.     *kptr &= ~bit;
  171.     for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
  172.         {
  173.         if (mask & modifiers) 
  174.             {
  175.         /* This key affects modifier "i" */
  176.         if (--k->modifierKeyCount[i] <= 0) 
  177.             {
  178.             k->modifierKeyCount[i] = 0;
  179.             k->state &= ~mask;
  180.             }
  181.         modifiers &= ~mask;
  182.         }
  183.         }
  184.  
  185.     if (other->fromPassiveGrab && (key == other->activatingKey))
  186.         deactivateDeviceGrab = TRUE;
  187.     }
  188.     else if (xE->type == DeviceButtonPress)
  189.     {
  190.         kptr = &b->down[key >> 3];
  191.     *kptr |= bit;
  192.     if (other->valuator)
  193.         other->valuator->motionHintWindow = NullWindow;
  194.     b->buttonsDown++;
  195.     b->motionMask = DeviceButtonMotionMask;
  196.     xE->detail = b->map[key];
  197.     if (xE->detail == 0)
  198.          return;
  199.     if (xE->detail <= 5)
  200.         b->state |= (DeviceButton1Mask >> 1) << xE->detail;
  201.     SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
  202.     if (!grab)
  203.         if (CheckDeviceGrabs(other, xE, 0, count))
  204.         return;
  205.  
  206.     }
  207.     else if (xE->type == DeviceButtonRelease)
  208.     {
  209.         kptr = &b->down[key >> 3];
  210.     *kptr &= ~bit;
  211.     if (other->valuator)
  212.         other->valuator->motionHintWindow = NullWindow;
  213.     if (!--b->buttonsDown)
  214.         b->motionMask = 0;
  215.     xE->detail = b->map[key];
  216.     if (xE->detail == 0)
  217.         return;
  218.     if (xE->detail <= 5)
  219.         b->state &= ~((DeviceButton1Mask >> 1) << xE->detail);
  220.     SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
  221.     if (!b->state && other->fromPassiveGrab)
  222.         deactivateDeviceGrab = TRUE;
  223.     }
  224.     else if (xE->type == ProximityIn)
  225.     other->valuator->mode &= ~OutOfProximity;
  226.     else if (xE->type == ProximityOut)
  227.     other->valuator->mode |= OutOfProximity;
  228.  
  229.     if (grab)
  230.     DeliverGrabbedEvent(xE, other, deactivateDeviceGrab, count);
  231.     else if (other->focus)
  232.     DeliverFocusedEvent(other, xE, GetSpriteWindow(), count);
  233.     else
  234.     DeliverDeviceEvents(GetSpriteWindow(), xE, NullGrab, NullWindow,
  235.                 other, count);
  236.  
  237.     if (deactivateDeviceGrab == TRUE)
  238.         (*other->DeactivateGrab)(other);
  239.     }
  240.  
  241. InitProximityClassDeviceStruct(dev)
  242.     DeviceIntPtr dev;
  243.     {
  244.     register ProximityClassPtr proxc;
  245.  
  246.     proxc = (ProximityClassPtr)xalloc(sizeof(ProximityClassRec));
  247.     if (!proxc)
  248.     return FALSE;
  249.     dev->proximity = proxc;
  250.     return TRUE;
  251.     }
  252.  
  253. InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution, min_res, max_res)
  254.     DeviceIntPtr dev;
  255.     int axnum;
  256.     int minval;
  257.     int maxval;
  258.     int resolution;
  259.     {
  260.     register AxisInfoPtr ax = dev->valuator->axes + axnum;
  261.  
  262.     ax->min_value = minval;
  263.     ax->max_value = maxval;
  264.     ax->resolution = resolution;
  265.     ax->min_resolution = min_res;
  266.     ax->max_resolution = max_res;
  267.     }
  268.  
  269. DeviceFocusEvent(dev, type, mode, detail, pWin)
  270.     DeviceIntPtr dev;
  271.     int type, mode, detail;
  272.     register WindowPtr pWin;
  273.     {
  274.     extern      int     DeviceFocusIn;
  275.     extern      int     DeviceFocusOut;
  276.     extern      int     DeviceStateNotify;
  277.     extern      int     DeviceKeyStateNotify;
  278.     extern      int     DeviceButtonStateNotify;
  279.     extern      int     DeviceValuatorStateNotify;
  280.     extern      Mask    DeviceStateNotifyMask;
  281.     extern      Mask    DeviceFocusChangeMask;
  282.     deviceFocus    event;
  283.  
  284.     if (type == FocusIn)
  285.     type = DeviceFocusIn;
  286.     else
  287.     type = DeviceFocusOut;
  288.  
  289.     event.deviceid = dev->id;
  290.     event.mode = mode;
  291.     event.type = type;
  292.     event.detail = detail;
  293.     event.window = pWin->drawable.id;
  294.     event.time = currentTime.milliseconds;
  295.  
  296.     (void)
  297.     DeliverEventsToWindow(pWin, &event, 1, DeviceFocusChangeMask, NullGrab, 
  298.     dev->id);
  299.  
  300.     if ((type == DeviceFocusIn) && 
  301.     (wOtherInputMasks(pWin)) &&
  302.     (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
  303.         {
  304.     int            i,j;
  305.     int             evcount = 1;
  306.     deviceStateNotify     *ev, *sev;
  307.     deviceKeyStateNotify     *kev;
  308.     deviceButtonStateNotify *bev;
  309.     deviceValuator         *vev;
  310.  
  311.     KeyClassPtr k;
  312.     ButtonClassPtr b;
  313.     ValuatorClassPtr v;
  314.  
  315.     if ((b=dev->button) != NULL)
  316.         {
  317.         if (b->numButtons > 32)
  318.         evcount++;
  319.         }
  320.     if ((v=dev->valuator) != NULL)
  321.         {
  322.         if (v->numAxes > 3)
  323.         evcount += ((v->numAxes-4) / 3) + 1;
  324.         }
  325.     if ((k=dev->key) != NULL)
  326.         {
  327.         if (k->curKeySyms.maxKeyCode > 32)
  328.         evcount++;
  329.         if (b->numButtons != NULL)
  330.         evcount++;
  331.         }
  332.  
  333.     ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent));
  334.  
  335.     ev->type = DeviceStateNotify;
  336.     ev->deviceid = dev->id;
  337.         ev->time = currentTime.milliseconds;
  338.     ev->classes_reported = 0;
  339.     ev->num_keys = 0;
  340.     ev->num_buttons = 0;
  341.     ev->num_valuators = 0;
  342.     sev = ev;
  343.  
  344.     if (b != NULL)
  345.         {
  346.         sev->classes_reported |= (1 << ButtonClass);
  347.         sev->num_buttons = b->numButtons;
  348.         bcopy((char *) b->down, (char *) &sev->buttons[0], 4);
  349.         if (b->numButtons > 32)
  350.         {
  351.         ev->deviceid |= MORE_EVENTS;
  352.         bev = (deviceButtonStateNotify *) ++ev; 
  353.         bev->type = DeviceButtonStateNotify;
  354.         bev->deviceid = dev->id;
  355.         bcopy((char *) &b->down[4], (char *) &bev->buttons[0], 28);
  356.         }
  357.         }
  358.  
  359.     if (v != NULL)
  360.         {
  361.         INT32 *ip B32;
  362.         deviceStateNotify     *tev = sev;
  363.  
  364.         tev->classes_reported |= (1 << ValuatorClass);
  365.         tev->classes_reported |= (dev->valuator->mode << ModeBitsShift);
  366.         for (i=0; i<v->numAxes; i+=6)
  367.         {
  368.         ip = &tev->valuator0;
  369.         for (j=0; j<3 && i+j<v->numAxes; j++)
  370.            *(ip+j) = v->axisVal[i+j]; 
  371.             tev->num_valuators = j;
  372.         if (i+3 < v->numAxes)
  373.             {
  374.             ev->deviceid |= MORE_EVENTS;
  375.             vev = (deviceValuator *) ++ev; 
  376.             vev->type = DeviceValuator;
  377.             vev->deviceid = dev->id;
  378.             vev->num_valuators = v->numAxes < i+6 ? v->numAxes-(i+3) : 3;
  379.             vev->first_valuator = i+3;
  380.             ip = &vev->valuator0;
  381.             for (j=0; j<3 && i+j < v->numAxes; j++)
  382.                 *(ip+j) = v->axisVal[i+3+j]; 
  383.             }
  384.         if (i+6 < v->numAxes)
  385.             {
  386.             tev = (deviceStateNotify *) ++ev;
  387.             tev->type = DeviceStateNotify;
  388.             tev->deviceid = dev->id;
  389.                 tev->time = currentTime.milliseconds;
  390.             tev->classes_reported = (1 << ValuatorClass);
  391.                 tev->classes_reported |= 
  392.             (dev->valuator->mode << ModeBitsShift);
  393.             }
  394.         }
  395.         }
  396.     if (k != NULL)
  397.         {
  398.         deviceStateNotify     *tev;
  399.  
  400.         for (tev=sev; tev <= (deviceStateNotify *) ev; tev++)
  401.         if (tev->type==DeviceStateNotify && 
  402.          !(tev->classes_reported & (1<<ButtonClass))) 
  403.         break;
  404.         if (tev > (deviceStateNotify *) ev)
  405.         {
  406.         tev->type = DeviceStateNotify;
  407.         tev->deviceid = dev->id;
  408.             tev->time = currentTime.milliseconds;
  409.         ev++;
  410.         }
  411.         tev->classes_reported |= (1 << KeyClass);
  412.         tev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
  413.  
  414.         bcopy((char *) k->down, (char *) &tev->keys[0], 4);
  415.         if (tev->num_keys > 32)
  416.         {
  417.         ev->deviceid |= MORE_EVENTS;
  418.         kev = (deviceKeyStateNotify *) ++ev; 
  419.         kev->type = DeviceKeyStateNotify;
  420.         kev->deviceid = dev->id;
  421.         bcopy((char *) &k->down[4], (char *) &kev->keys[0], 28);
  422.         }
  423.         }
  424.  
  425.     (void) DeliverEventsToWindow(pWin, sev, evcount, DeviceStateNotifyMask, 
  426.         NullGrab, dev->id);
  427.     xfree (sev);
  428.         }
  429.     }
  430.  
  431. int
  432. GrabButton(client, dev, this_device_mode, other_devices_mode, modifiers,
  433.     modifier_device, button, grabWindow, ownerEvents, rcursor, rconfineTo,
  434.     eventMask)
  435.     ClientPtr client;
  436.     DeviceIntPtr dev;
  437.     BYTE this_device_mode;
  438.     BYTE other_devices_mode;
  439.     CARD16 modifiers;
  440.     DeviceIntPtr modifier_device;
  441.     CARD8 button;
  442.     Window grabWindow;
  443.     BOOL ownerEvents;
  444.     Cursor rcursor;
  445.     Window rconfineTo;
  446.     Mask eventMask;
  447.    
  448. {
  449.     WindowPtr pWin, confineTo;
  450.     CursorPtr cursor;
  451.     GrabPtr CreateGrab();
  452.     GrabPtr grab;
  453.  
  454.     if ((this_device_mode != GrabModeSync) &&
  455.     (this_device_mode != GrabModeAsync))
  456.     {
  457.     client->errorValue = this_device_mode;
  458.         return BadValue;
  459.     }
  460.     if ((other_devices_mode != GrabModeSync) &&
  461.     (other_devices_mode != GrabModeAsync))
  462.     {
  463.     client->errorValue = other_devices_mode;
  464.         return BadValue;
  465.     }
  466.     if ((modifiers != AnyModifier) &&
  467.     (modifiers & ~AllModifiersMask))
  468.     {
  469.     client->errorValue = modifiers;
  470.     return BadValue;
  471.     }
  472.     if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
  473.     {
  474.     client->errorValue = ownerEvents;
  475.     return BadValue;
  476.     }
  477.     pWin = LookupWindow(grabWindow, client);
  478.     if (!pWin)
  479.     return BadWindow;
  480.     if (rconfineTo == None)
  481.     confineTo = NullWindow;
  482.     else
  483.     {
  484.     confineTo = LookupWindow(rconfineTo, client);
  485.     if (!confineTo)
  486.         return BadWindow;
  487.     }
  488.     if (rcursor == None)
  489.     cursor = NullCursor;
  490.     else
  491.     {
  492.     cursor = (CursorPtr)LookupIDByType(rcursor, RT_CURSOR);
  493.     if (!cursor)
  494.     {
  495.         client->errorValue = rcursor;
  496.         return BadCursor;
  497.     }
  498.     }
  499.  
  500.     grab = CreateGrab(client->index, dev, pWin, eventMask,
  501.     (Bool)ownerEvents, (Bool) other_devices_mode, (Bool)this_device_mode,
  502.     modifier_device, modifiers, DeviceButtonPress, button, confineTo, 
  503.     cursor);
  504.     if (!grab)
  505.     return BadAlloc;
  506.     return AddPassiveGrabToList(grab);
  507.     }
  508.  
  509. int
  510. GrabKey(client, dev, this_device_mode, other_devices_mode, modifiers,
  511.     modifier_device, key, grabWindow, ownerEvents, mask)
  512.     ClientPtr client;
  513.     DeviceIntPtr dev;
  514.     BYTE this_device_mode;
  515.     BYTE other_devices_mode;
  516.     CARD16 modifiers;
  517.     DeviceIntPtr modifier_device;
  518.     CARD8 key;
  519.     Window grabWindow;
  520.     BOOL ownerEvents;
  521.     Mask mask;
  522.    
  523. {
  524.     WindowPtr pWin;
  525.     GrabPtr CreateGrab();
  526.     GrabPtr grab;
  527.     KeyClassPtr k = dev->key;
  528.  
  529.     if (k==NULL)
  530.     return BadMatch;
  531.     if ((other_devices_mode != GrabModeSync) &&
  532.     (other_devices_mode != GrabModeAsync))
  533.     {
  534.     client->errorValue = other_devices_mode;
  535.         return BadValue;
  536.     }
  537.     if ((this_device_mode != GrabModeSync) &&
  538.     (this_device_mode != GrabModeAsync))
  539.     {
  540.     client->errorValue = this_device_mode;
  541.         return BadValue;
  542.     }
  543.     if (((key > k->curKeySyms.maxKeyCode) || 
  544.      (key < k->curKeySyms.minKeyCode))
  545.     && (key != AnyKey))
  546.     {
  547.     client->errorValue = key;
  548.         return BadValue;
  549.     }
  550.     if ((modifiers != AnyModifier) &&
  551.     (modifiers & ~AllModifiersMask))
  552.     {
  553.     client->errorValue = modifiers;
  554.     return BadValue;
  555.     }
  556.     pWin = LookupWindow(grabWindow, client);
  557.     if (!pWin)
  558.     return BadWindow;
  559.  
  560.     grab = CreateGrab(client->index, dev, pWin, 
  561.     mask, ownerEvents, this_device_mode, other_devices_mode, 
  562.     modifier_device, modifiers, DeviceKeyPress, key, NullWindow, 
  563.     NullCursor);
  564.     if (!grab)
  565.     return BadAlloc;
  566.     return AddPassiveGrabToList(grab);
  567.     }
  568.  
  569. extern Mask DevicePointerMotionHintMask;
  570.  
  571. int
  572. SelectForWindow(dev, pWin, client, mask, exclusivemasks, validmasks)
  573.     DeviceIntPtr dev;
  574.     WindowPtr pWin;
  575.     ClientPtr client;
  576.     Mask mask;
  577.     Mask exclusivemasks;
  578.     Mask validmasks;
  579. {
  580.     int mskidx = dev->id;
  581.     int i, ret;
  582.     Mask check;
  583.     InputClientsPtr others;
  584.  
  585.     if (mask & ~validmasks)
  586.     {
  587.     client->errorValue = mask;
  588.     return BadValue;
  589.     }
  590.     check = (mask & exclusivemasks);
  591.     if (wOtherInputMasks(pWin))
  592.     {
  593.     if (check & wOtherInputMasks(pWin)->inputEvents[mskidx])
  594.         {                   /* It is illegal for two different
  595.                           clients to select on any of the
  596.                           events for maskcheck. However,
  597.                           it is OK, for some client to
  598.                           continue selecting on one of those
  599.                           events.  */
  600.         for (others = wOtherInputMasks(pWin)->inputClients; others; 
  601.         others = others->next)
  602.             {
  603.             if (!SameClient(others, client) && (check & 
  604.             others->mask[mskidx]))
  605.             return BadAccess;
  606.             }
  607.             }
  608.     for (others = wOtherInputMasks(pWin)->inputClients; others; 
  609.         others = others->next)
  610.         {
  611.         if (SameClient(others, client))
  612.             {
  613.         check = others->mask[mskidx];
  614.         others->mask[mskidx] = mask;
  615.         if (mask == 0)
  616.             {
  617.             for (i=0; i<EMASKSIZE; i++)
  618.             if (i != mskidx && others->mask[i] != 0)
  619.                 break;
  620.             if (i == EMASKSIZE)
  621.             {
  622.             RecalculateDeviceDeliverableEvents(pWin);
  623.             if (ShouldFreeInputMasks(pWin), FALSE)
  624.                 FreeResource(others->resource, RT_NONE);
  625.                 return Success;
  626.             }
  627.             }
  628.         goto maskSet;
  629.             }
  630.         }
  631.     }
  632.     check = 0;
  633.     if ((ret = AddExtensionClient (pWin, client, mask, mskidx)) != Success)
  634.     return ret;
  635. maskSet: 
  636.     if (dev->valuator)
  637.     if ((dev->valuator->motionHintWindow == pWin) &&
  638.         (mask & DevicePointerMotionHintMask) &&
  639.         !(check & DevicePointerMotionHintMask) &&
  640.         !dev->grab)
  641.         dev->valuator->motionHintWindow = NullWindow;
  642.     RecalculateDeviceDeliverableEvents(pWin);
  643.     return Success;
  644. }
  645.  
  646. int 
  647. AddExtensionClient (pWin, client, mask, mskidx)
  648.     WindowPtr pWin;
  649.     ClientPtr client;
  650.     Mask mask;
  651.     int mskidx;
  652.     {
  653.     extern int RT_INPUTCLIENT;
  654.     InputClientsPtr others;
  655.  
  656.     if (!pWin->optional && !MakeWindowOptional (pWin))
  657.     return BadAlloc;
  658.     others = (InputClients *) xalloc(sizeof(InputClients));
  659.     if (!others)
  660.     return BadAlloc;
  661.     if (!pWin->optional->inputMasks && !MakeInputMasks (pWin))
  662.     return BadAlloc;
  663.     bzero((char *) &others->mask[0], sizeof(Mask)*EMASKSIZE);
  664.     others->mask[mskidx] = mask;
  665.     others->resource = FakeClientID(client->index);
  666.     others->next = pWin->optional->inputMasks->inputClients;
  667.     pWin->optional->inputMasks->inputClients = others;
  668.     if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer)pWin))
  669.     return BadAlloc;
  670.     return Success;
  671.     }
  672.  
  673. static Bool
  674. MakeInputMasks (pWin)
  675.     WindowPtr    pWin;
  676.     {
  677.     struct _OtherInputMasks *imasks;
  678.  
  679.     imasks = (struct _OtherInputMasks *) 
  680.     xalloc (sizeof (struct _OtherInputMasks));
  681.     if (!imasks)
  682.     return FALSE;
  683.     bzero((char *) imasks, sizeof (struct _OtherInputMasks));
  684.     pWin->optional->inputMasks = imasks;
  685.     return TRUE;
  686.     }
  687.  
  688. void
  689. RecalculateDeviceDeliverableEvents(pWin)
  690.     WindowPtr pWin;
  691.     {
  692.     register InputClientsPtr others;
  693.     struct _OtherInputMasks *inputMasks;   /* default: NULL */
  694.     register WindowPtr pChild, tmp;
  695.     int i;
  696.  
  697.     pChild = pWin;
  698.     while (1)
  699.     {
  700.     if (inputMasks = wOtherInputMasks(pChild))
  701.         {
  702.         for (others = inputMasks->inputClients; others; 
  703.         others = others->next)
  704.         {
  705.         for (i=0; i<EMASKSIZE; i++)
  706.             inputMasks->inputEvents[i] |= others->mask[i];
  707.         }
  708.         for (i=0; i<EMASKSIZE; i++)
  709.         inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
  710.         for (tmp = pChild->parent; tmp; tmp=tmp->parent)
  711.         if (wOtherInputMasks(tmp))
  712.             for (i=0; i<EMASKSIZE; i++)
  713.             inputMasks->deliverableEvents[i] |=
  714.             (wOtherInputMasks(tmp)->deliverableEvents[i] 
  715.             & ~inputMasks->dontPropagateMask[i] & PropagateMask[i]);
  716.         }
  717.     if (pChild->firstChild)
  718.         {
  719.         pChild = pChild->firstChild;
  720.         continue;
  721.         }
  722.     while (!pChild->nextSib && (pChild != pWin))
  723.         pChild = pChild->parent;
  724.     if (pChild == pWin)
  725.         break;
  726.     pChild = pChild->nextSib;
  727.     }
  728.     }
  729.  
  730. int
  731. InputClientGone(pWin, id)
  732.     register WindowPtr pWin;
  733.     XID   id;
  734.     {
  735.     register InputClientsPtr other, prev;
  736.     if (!wOtherInputMasks(pWin))
  737.     return(Success);
  738.     prev = 0;
  739.     for (other = wOtherInputMasks(pWin)->inputClients; other; 
  740.     other = other->next)
  741.     {
  742.     if (other->resource == id)
  743.         {
  744.         if (prev)
  745.         {
  746.         prev->next = other->next;
  747.         xfree(other);
  748.         }
  749.         else if (!(other->next))
  750.         {
  751.             if (ShouldFreeInputMasks(pWin), TRUE)
  752.             {
  753.             wOtherInputMasks(pWin)->inputClients = other->next;
  754.             xfree(wOtherInputMasks(pWin));
  755.             pWin->optional->inputMasks = (OtherInputMasks *) NULL;
  756.             CheckWindowOptionalNeed (pWin);
  757.             xfree(other);
  758.             }
  759.         else
  760.             {
  761.             other->resource = FakeClientID(0);
  762.             if (!AddResource(other->resource, RT_INPUTCLIENT, 
  763.             (pointer)pWin))
  764.             return BadAlloc;
  765.             }
  766.         }
  767.         else
  768.         {
  769.         wOtherInputMasks(pWin)->inputClients = other->next;
  770.         xfree(other);
  771.         }
  772.         RecalculateDeviceDeliverableEvents(pWin);
  773.         return(Success);
  774.         }
  775.     prev = other;
  776.         }
  777.     FatalError("client not on device event list");
  778.     /*NOTREACHED*/
  779.     }
  780.  
  781. int
  782. SendEvent (client, d, dest, propagate, ev, mask, count)
  783.     ClientPtr        client;
  784.     DeviceIntPtr    d;
  785.     Window        dest;
  786.     Bool        propagate;
  787.     xEvent        *ev;
  788.     Mask        mask;
  789.     {
  790.     WindowPtr pWin;
  791.     WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
  792.     WindowPtr GetCurrentRootWindow();
  793.     WindowPtr spriteWin=GetSpriteWindow();
  794.  
  795.     if (dest == PointerWindow)
  796.     pWin = spriteWin;
  797.     else if (dest == InputFocus)
  798.     {
  799.     WindowPtr inputFocus;
  800.     
  801.     if (!d->focus)
  802.         inputFocus = spriteWin;
  803.     else
  804.         inputFocus = d->focus->win;
  805.  
  806.     if (inputFocus == FollowKeyboardWin)
  807.         inputFocus = inputInfo.keyboard->focus->win;
  808.  
  809.     if (inputFocus == NoneWin)
  810.         return Success;
  811.  
  812.     /* If the input focus is PointerRootWin, send the event to where
  813.     the pointer is if possible, then perhaps propogate up to root. */
  814.        if (inputFocus == PointerRootWin)
  815.         inputFocus = GetCurrentRootWindow();
  816.  
  817.     if (IsParent(inputFocus, spriteWin))
  818.     {
  819.         effectiveFocus = inputFocus;
  820.         pWin = spriteWin;
  821.     }
  822.     else
  823.         effectiveFocus = pWin = inputFocus;
  824.     }
  825.     else
  826.     pWin = LookupWindow(dest, client);
  827.     if (!pWin)
  828.     return BadWindow;
  829.     if ((propagate != xFalse) && (propagate != xTrue))
  830.     {
  831.     client->errorValue = propagate;
  832.     return BadValue;
  833.     }
  834.     ev->u.u.type |= 0x80;
  835.     if (propagate)
  836.     {
  837.     for (;pWin; pWin = pWin->parent)
  838.     {
  839.         if (DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id))
  840.         return Success;
  841.         if (pWin == effectiveFocus)
  842.         return Success;
  843.         if (wOtherInputMasks(pWin))
  844.         mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
  845.     }
  846.     }
  847.     else
  848.     (void)(DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id));
  849.     return Success;
  850.     }
  851.  
  852. int
  853. SetButtonMapping (client, dev, nElts, map)
  854.     ClientPtr client;
  855.     DeviceIntPtr dev;
  856.     int nElts;
  857.     BYTE *map;
  858.     {
  859.     register int i;
  860.     ButtonClassPtr b = dev->button;
  861.  
  862.     if (b == NULL)
  863.     return BadMatch;
  864.  
  865.     if (nElts != b->numButtons)
  866.     {
  867.     client->errorValue = nElts;
  868.     return BadValue;
  869.     }
  870.     if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
  871.     return BadValue;
  872.     for (i=0; i < nElts; i++)
  873.     if ((b->map[i + 1] != map[i]) &&
  874.         BitIsOn(b->down, i + 1))
  875.             return MappingBusy;
  876.     for (i = 0; i < nElts; i++)
  877.     b->map[i + 1] = map[i];
  878.     return Success;
  879.     }
  880.  
  881. int 
  882. SetModifierMapping(client, dev, len, rlen, numKeyPerModifier, inputMap, k)
  883.     ClientPtr client;
  884.     DeviceIntPtr dev;
  885.     int len;
  886.     int rlen;
  887.     int numKeyPerModifier;
  888.     KeyCode *inputMap;
  889.     KeyClassPtr *k;
  890. {
  891.     KeyCode *map;
  892.     int inputMapLen;
  893.     register int i;
  894.     
  895.     *k = dev->key;
  896.     if (*k == NULL)
  897.     return BadMatch;
  898.     if (len != ((numKeyPerModifier<<1) + rlen))
  899.     return BadLength;
  900.  
  901.     inputMapLen = 8*numKeyPerModifier;
  902.  
  903.     /*
  904.      *    Now enforce the restriction that "all of the non-zero keycodes must be
  905.      *    in the range specified by min-keycode and max-keycode in the
  906.      *    connection setup (else a Value error)"
  907.      */
  908.     i = inputMapLen;
  909.     while (i--) {
  910.     if (inputMap[i]
  911.         && (inputMap[i] < (*k)->curKeySyms.minKeyCode
  912.         || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
  913.         client->errorValue = inputMap[i];
  914.         return BadValue;
  915.         }
  916.     }
  917.  
  918.     /*
  919.      *    Now enforce the restriction that none of the old or new
  920.      *    modifier keys may be down while we change the mapping,  and
  921.      *    that the DDX layer likes the choice.
  922.      */
  923.     if (!AllModifierKeysAreUp (dev, (*k)->modifierKeyMap, 
  924.     (int)(*k)->maxKeysPerModifier, inputMap, (int)numKeyPerModifier)
  925.         ||
  926.     !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
  927.           (*k)->modifierKeyMap, (int)(*k)->maxKeysPerModifier)) {
  928.     return MappingBusy;
  929.     } else {
  930.     for (i = 0; i < inputMapLen; i++) {
  931.         if (inputMap[i] && !LegalModifier(inputMap[i], dev)) {
  932.         return MappingFailed;
  933.         }
  934.     }
  935.     }
  936.  
  937.     /*
  938.      *    Now build the keyboard's modifier bitmap from the
  939.      *    list of keycodes.
  940.      */
  941.     map = (KeyCode *)xalloc(inputMapLen);
  942.     if (!map)
  943.         return BadAlloc;
  944.     if ((*k)->modifierKeyMap)
  945.         xfree((*k)->modifierKeyMap);
  946.     (*k)->modifierKeyMap = map;
  947.     bcopy((char *)inputMap, (char *)(*k)->modifierKeyMap, inputMapLen);
  948.     (*k)->maxKeysPerModifier = numKeyPerModifier;
  949.     for (i = 0; i < MAP_LENGTH; i++)
  950.         (*k)->modifierMap[i] = 0;
  951.     for (i = 0; i < inputMapLen; i++) if (inputMap[i]) {
  952.         (*k)->modifierMap[inputMap[i]]
  953.           |= (1<<(i/ (*k)->maxKeysPerModifier));
  954.     }
  955.  
  956.     return(MappingSuccess);
  957.     }
  958.  
  959. int
  960. SendDeviceMappingNotify(request, firstKeyCode, count, dev)
  961.     CARD8 request, count;
  962.     KeyCode firstKeyCode;
  963.     DeviceIntPtr dev;
  964.     {
  965.     xEvent event;
  966.     deviceMappingNotify         *ev = (deviceMappingNotify *) &event;
  967.     extern                  int     DeviceMappingNotify;
  968.  
  969.     ev->type = DeviceMappingNotify;
  970.     ev->request = request;
  971.     ev->deviceid = dev->id;
  972.     ev->time = currentTime.milliseconds;
  973.     if (request == MappingKeyboard)
  974.     {
  975.     ev->firstKeyCode = firstKeyCode;
  976.     ev->count = count;
  977.     }
  978.  
  979.     SendEventToAllWindows (dev, DeviceMappingNotifyMask, ev, 1);
  980.     }
  981.  
  982. int
  983. ChangeKeyMapping(client, dev, len, type, firstKeyCode, keyCodes, 
  984.     keySymsPerKeyCode, map)
  985.     ClientPtr     client;
  986.     DeviceIntPtr dev;
  987.     unsigned     len;
  988.     int     type;
  989.     KeyCode     firstKeyCode;
  990.     CARD8     keyCodes;
  991.     CARD8     keySymsPerKeyCode;
  992.     KeySym    *map;
  993. {
  994.     KeySymsRec keysyms;
  995.     KeyClassPtr k = dev->key;
  996.  
  997.     if (k == NULL)
  998.     return (BadMatch);
  999.  
  1000.     if (len != (keyCodes * keySymsPerKeyCode))
  1001.             return BadLength;
  1002.  
  1003.     if ((firstKeyCode < k->curKeySyms.minKeyCode) ||
  1004.     (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode))
  1005.     {
  1006.         client->errorValue = firstKeyCode;
  1007.         return BadValue;
  1008.     }
  1009.     if (keySymsPerKeyCode == 0)
  1010.     {
  1011.         client->errorValue = 0;
  1012.             return BadValue;
  1013.     }
  1014.     keysyms.minKeyCode = firstKeyCode;
  1015.     keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
  1016.     keysyms.mapWidth = keySymsPerKeyCode;
  1017.     keysyms.map = map;
  1018.     if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
  1019.     return BadAlloc;
  1020.     SendDeviceMappingNotify(MappingKeyboard, firstKeyCode, keyCodes,
  1021.     dev);
  1022.     return client->noClientException;
  1023.     }
  1024.  
  1025. void
  1026. DeleteWindowFromAnyExtEvents(pWin, freeResources)
  1027.     WindowPtr        pWin;
  1028.     Bool        freeResources;
  1029.     {
  1030.     int            i;
  1031.     DeviceIntPtr    dev;
  1032.     InputClientsPtr    ic;
  1033.     struct _OtherInputMasks *inputMasks;
  1034.  
  1035.     for (dev=inputInfo.devices; dev; dev=dev->next)
  1036.     {
  1037.     if (dev == inputInfo.pointer ||
  1038.         dev == inputInfo.keyboard)
  1039.         continue;
  1040.     DeleteDeviceFromAnyExtEvents(pWin, dev);
  1041.     }
  1042.  
  1043.     for (dev=inputInfo.off_devices; dev; dev=dev->next)
  1044.     DeleteDeviceFromAnyExtEvents(pWin, dev);
  1045.  
  1046.     if (freeResources)
  1047.     while (inputMasks = wOtherInputMasks(pWin))
  1048.         {
  1049.         ic = inputMasks->inputClients;
  1050.         for (i=0; i<EMASKSIZE; i++)
  1051.         inputMasks->dontPropagateMask[i] = 0;
  1052.         FreeResource(ic->resource, RT_NONE);
  1053.         }
  1054.     }
  1055.  
  1056. DeleteDeviceFromAnyExtEvents(pWin, dev)
  1057.     WindowPtr        pWin;
  1058.     DeviceIntPtr    dev;
  1059.     {
  1060.     WindowPtr        parent;
  1061.  
  1062.     /* Deactivate any grabs performed on this window, before making
  1063.     any input focus changes.
  1064.         Deactivating a device grab should cause focus events. */
  1065.  
  1066.     if (dev->grab && (dev->grab->window == pWin))
  1067.     (*dev->DeactivateGrab)(dev);
  1068.  
  1069.     /* If the focus window is a root window (ie. has no parent) 
  1070.     then don't delete the focus from it. */
  1071.     
  1072.     if (dev->focus && (pWin==dev->focus->win) && (pWin->parent != NullWindow))
  1073.     {
  1074.     int focusEventMode = NotifyNormal;
  1075.  
  1076.      /* If a grab is in progress, then alter the mode of focus events. */
  1077.  
  1078.     if (dev->grab)
  1079.         focusEventMode = NotifyWhileGrabbed;
  1080.  
  1081.     switch (dev->focus->revert)
  1082.         {
  1083.         case RevertToNone:
  1084.         DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
  1085.         dev->focus->win = NoneWin;
  1086.         dev->focus->traceGood = 0;
  1087.         break;
  1088.         case RevertToParent:
  1089.         parent = pWin;
  1090.         do
  1091.             {
  1092.             parent = parent->parent;
  1093.             dev->focus->traceGood--;
  1094.             } while (!parent->realized);
  1095.         DoFocusEvents(dev, pWin, parent, focusEventMode);
  1096.         dev->focus->win = parent;
  1097.         dev->focus->revert = RevertToNone;
  1098.         break;
  1099.         case RevertToPointerRoot:
  1100.         DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
  1101.         dev->focus->win = PointerRootWin;
  1102.         dev->focus->traceGood = 0;
  1103.         break;
  1104.         }
  1105.     }
  1106.  
  1107.     if (dev->valuator)
  1108.     if (dev->valuator->motionHintWindow == pWin)
  1109.         dev->valuator->motionHintWindow = NullWindow;
  1110.     }
  1111.  
  1112. int
  1113. MaybeSendDeviceMotionNotifyHint (pEvents, mask)
  1114.     deviceKeyButtonPointer *pEvents;
  1115.     Mask mask;
  1116.     {
  1117.     DeviceIntPtr dev;
  1118.     DeviceIntPtr LookupDeviceIntRec ();
  1119.  
  1120.     dev = LookupDeviceIntRec (pEvents->deviceid & DEVICE_BITS);
  1121.     if (pEvents->type == DeviceMotionNotify)
  1122.     {
  1123.     if (mask & DevicePointerMotionHintMask)
  1124.         {
  1125.         if (WID(dev->valuator->motionHintWindow) == pEvents->event)
  1126.         {
  1127.         return 1; /* don't send, but pretend we did */
  1128.         }
  1129.         pEvents->detail = NotifyHint;
  1130.         }
  1131.      else
  1132.         {
  1133.         pEvents->detail = NotifyNormal;
  1134.         }
  1135.     }
  1136.     return (0);
  1137.     }
  1138.  
  1139. int
  1140. CheckDeviceGrabAndHintWindow (pWin, type, xE, grab, client, deliveryMask)
  1141.     WindowPtr pWin;
  1142.     int type;
  1143.     deviceKeyButtonPointer *xE;
  1144.     GrabPtr grab;
  1145.     ClientPtr client;
  1146.     Mask deliveryMask;
  1147.     {
  1148.     DeviceIntPtr dev;
  1149.     DeviceIntPtr LookupDeviceIntRec ();
  1150.  
  1151.     dev = LookupDeviceIntRec (xE->deviceid & DEVICE_BITS);
  1152.     if (type == DeviceMotionNotify)
  1153.     dev->valuator->motionHintWindow = pWin;
  1154.     else if ((type == DeviceButtonPress) && (!grab) && 
  1155.     (deliveryMask & DeviceButtonGrabMask))
  1156.         {
  1157.     GrabRec tempGrab;
  1158.  
  1159.     tempGrab.device = dev;
  1160.     tempGrab.resource = client->clientAsMask;
  1161.     tempGrab.window = pWin;
  1162.     tempGrab.ownerEvents = (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
  1163.     tempGrab.eventMask = deliveryMask;
  1164.     tempGrab.keyboardMode = GrabModeAsync;
  1165.     tempGrab.pointerMode = GrabModeAsync;
  1166.     tempGrab.confineTo = NullWindow;
  1167.     tempGrab.cursor = NullCursor;
  1168.     (*dev->ActivateGrab)(dev, &tempGrab, currentTime, TRUE);
  1169.         }
  1170.     }
  1171.  
  1172. Mask
  1173. DeviceEventMaskForClient(dev, pWin, client)
  1174.     DeviceIntPtr    dev;
  1175.     WindowPtr        pWin;
  1176.     ClientPtr        client;
  1177.     {
  1178.     register InputClientsPtr other;
  1179.  
  1180.     if (!wOtherInputMasks(pWin))
  1181.     return 0;
  1182.     for (other = wOtherInputMasks(pWin)->inputClients; other; 
  1183.     other = other->next)
  1184.     {
  1185.     if (SameClient(other, client))
  1186.         return other->mask[dev->id];
  1187.     }
  1188.     return 0;
  1189.     }
  1190.  
  1191. void
  1192. MaybeStopDeviceHint(dev, client)
  1193.     register DeviceIntPtr dev;
  1194.     ClientPtr client;
  1195. {
  1196.     WindowPtr pWin;
  1197.     GrabPtr grab = dev->grab;
  1198.     pWin = dev->valuator->motionHintWindow;
  1199.  
  1200.     if ((grab && SameClient(grab, client) &&
  1201.      ((grab->eventMask & DevicePointerMotionHintMask) ||
  1202.       (grab->ownerEvents &&
  1203.        (DeviceEventMaskForClient(dev, pWin, client) &
  1204.         DevicePointerMotionHintMask)))) ||
  1205.     (!grab &&
  1206.      (DeviceEventMaskForClient(dev, pWin, client) &
  1207.       DevicePointerMotionHintMask)))
  1208.     dev->valuator->motionHintWindow = NullWindow;
  1209. }
  1210.  
  1211. int
  1212. DeviceEventSuppressForWindow(pWin, client, mask, maskndx)
  1213.     WindowPtr pWin;
  1214.     ClientPtr client;
  1215.     Mask mask;
  1216.     int maskndx;
  1217.     {
  1218.     struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
  1219.  
  1220.     if (mask & ~PropagateMask[maskndx])
  1221.     {
  1222.     client->errorValue = mask;
  1223.     return BadValue;
  1224.     }
  1225.  
  1226.     if (mask == 0) 
  1227.     {
  1228.     if (inputMasks)
  1229.         inputMasks->dontPropagateMask[maskndx] = mask;
  1230.     } 
  1231.     else 
  1232.     {
  1233.     if (!inputMasks)
  1234.         AddExtensionClient (pWin, client, 0, 0);
  1235.     inputMasks = wOtherInputMasks(pWin);
  1236.     inputMasks->dontPropagateMask[maskndx] = mask;
  1237.     }
  1238.     RecalculateDeviceDeliverableEvents(pWin);
  1239.     if (ShouldFreeInputMasks(pWin), FALSE)
  1240.         FreeResource(inputMasks->inputClients->resource, RT_NONE);
  1241.     return Success;
  1242.     }
  1243.  
  1244. static Bool
  1245. ShouldFreeInputMasks (pWin, ignoreSelectedEvents)
  1246.     WindowPtr pWin;
  1247.     Bool ignoreSelectedEvents;
  1248.     {
  1249.     int i;
  1250.     Mask allInputEventMasks = 0;
  1251.     struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
  1252.  
  1253.     for (i=0; i<EMASKSIZE; i++)
  1254.     allInputEventMasks |= inputMasks->dontPropagateMask[i];
  1255.     if (!ignoreSelectedEvents)
  1256.     for (i=0; i<EMASKSIZE; i++)
  1257.         allInputEventMasks |= inputMasks->inputEvents[i];
  1258.     if (allInputEventMasks == 0)
  1259.     return TRUE;
  1260.     else
  1261.     return FALSE;
  1262.     }
  1263.