We free the ValuatorClassRec quite regularly. If a SIGIO is handled while
we're swapping device classes, we can bring the server down when we try to
access lastx/lasty of the master device.
XkbInitKeyboardDefviceStruct may call FatalError if it fails. FatalError then
cleans up all the devices, resulting in a segfault if the pointer is
uninitialised.
Old code was fundamentally broken, fixes now are:
- free the MDs current device classes
- copy the device classes instead of flipping the pointers
- check for the old MD, not the new one.
Anything in dev->key, dev->valuator etc. of a MD must always be a copy of the
original class. The intial classes of an MD (the ones set up before an SD is
attached) as well, as we may have to restore them if no SD is attached
anymore.
Each time a different slave device sends through a master, an
DeviceClassesChangedEvent is enqueued. When this event is processed, all
classes of the matching master device are changed, and the event is sent to
the clients.
Next time the master is queried, it thus shows the evclasses of the last slave
device. The original classes are stored in the devPrivates.
TODO: if all slave devices are removed, the master's original classes need to
be restored.
For pointers: don't try to set master->valuator fields if there is no master.
For keyboards: check if device is valid before trying to access the fields in
miPointerGetScreen (btw. this disables DGA events for floating keyboards).
Also stop the hideous number of ErrorFs if we request the paired device for a
floating dev.
Floating devices get sprites, but still aren't spriteOwners. This prevents
them from getting rendered, and also stops segfaulting.
(not really solving the problems with keyboards though)
Set isMaster for VCP/VCK.
Init sprites for master pointer devices.
Pair master kbds with master pointers (1:1 pairing!).
Attach other devices to VCP/VCK.
For now, we don't allow attaching slaves to other slaves, and we don't allow
pairing slaves with other slaves.
Pairing is for master keyboard->master pointer only.
Attaching is for slave device->master device only.
We re-pair them with the VCP, not a real device! If we would do otherwise,
somebody may change our keyboard focus and thus get us typing where we don't
want to type.
If the pairing client is not set, then the pairing is initiated internally
(e.g. when a new keyboard device is configured). In this case we _must_ pair
regardless of who is the pairing client.
We need it unconditionally in a few places, and the rest checked for NULL and
then set it to VCK anyway. So, fixing up all callers to appreciate the defined
return value.
EnableDevices is (amongst others )called after a VT switch. We must not create
a new sprite or re-pair the device, otherwise we lose the input device setup
that we had before the VT switch.
This requires the devices to be in exactly the same order as before
the VT switch. Removing a device while on a different VT is probably a bad
idea.
The device state needs to be changed while processing the XI event. Core
events are always processed after XI, so by then the device is already set up
properly. However, we now rely on DeviceButtonMotionMask to be equal to
ButtonMotionMask. It already is, but stick a big fat warning in so nobody
attempts to change it.
This commit disables XKB for the VCK, thus essentially for all devices.
Temporarily anyway.
Add keyc->postdown, which represents the key state as of the last mieqEnqueue
call, and use it when we need to know the posted state, instead of the
processed state (keyc->down). Add small functions to getevents.c to query and
modify key state in postdown and use them all through, eliminating previously
broken uses.
Add support for HAL-based hotplugging, in which we just get the list of
input devices and properties from HAL. Requires an FDI which is not yet
in mainline HAL.
Is set when passive grab is implicit as result of a ButtonPress event. If this
is the case, we need to store the XI mask as well as the core mask to ensure
delivery of XI events during the grab's lifetime.
Remove all core grabs on other devices when client issues a GrabPointer or
GrabKeyboard request. Let's assume that the client really only wants one
device to interact, so this seems like a reasonable solution.