Instead of a simple counter, use bits to keep track of which device is where
etc. When device enters a window (or sets focus), the bit matching the device
is set, when it leaves again, it is unset. If there are 0 bits set, then
Leave/Enter/Focus events may be sent to the client.
Same theory as before, but this should get around the insanity with
Grab/Ungrab special cases. Those cases are basically untested though.
Blindly copying will override the focus setting of the master. If there's XI
applications running, they may set the SD focus, while leaving the
MD's focus as it was. In this case, after a class swap we still want to get
the MD's events to the same window as before.
If an pointer event is being processed during a device grab, don't deliver it
to the focus window, even if the device has a focus class. Reason being that
some pointers may have a focus class, thus killing drag-and-drop.
Some pointer devices send key events [1], blindly getting the paired device
crashes the server. So let's check if the device is a pointer before we try to
get the paired device.
[1] The MS Wireless Optical Desktop 2000's multimedia keys are sent through
the pointer device, not through the keyboard device.
Floating SDs are paired with themselves, so the paired device may not be a
proper keyboard or mouse. Put some extra checks in to avoid dereferencing a
nullpointer later.
InitializeSprite won't create a new one if it already exists, with the result
of overwriting the master's sprite. This master sprite is then assigned to the
floating slave, and freed when the slave is reattached later.
Setting the sprite to NULL forces InitializeSprite to alloc a new one, and
this one can be freed without further repercussions.
Some pointer devices have key classes (e.g. MS Optical Desktop 2000). The
previous test was performed as Error if ptr -> keybd or keybd -> ptr. This
doesnt work with such devices. New test is Succeed if ptr->ptr or
keybd->keybd.
XkbFinishDeviceInit is called once when the device is initialised, but also
when a class copy causes the key class of a device to change. In this case, overwriting the CtrlProc of the KeybdFeedbackClass with XkbDDXKeybdCtrlProc sets up a nice recursive loop of XkbDDXKeybdCtrlProc calling itself until the cows come home.
For non-Linux, _POSIX_C_SOURCE and friends restrict symbols defined rather
than enabling defines of symbols. Additionally, CLOCK_MONOTONIC was
apparently added to the standard around 2000 anyway, not 1993.