Turns out it's really really hard synchronising device state across multiple
duplicated events if they all share the same struct. So instead of doing so,
when the SD changes deep-copy all it's classes into the MD. The MD then has
the same capabilities, but the state can be set separately. This should fix
xkb, key state, repeat etc. problems.
Updating the device state allows us to remove the SwitchCoreKeyboard from the
event gathering, it's all done during event processing now.
If a slave device is attached to a master device, then we need to send a
mapping notify to the client.
Mapping notify needs to be sent if
- different slave device but on same master
- different master
This gives you funny behaviour with the ClientPointer. When a
MappingNotify is sent to the client, the client usually responds with a
GetKeyboardMapping. This will retrieve the ClientPointer's keyboard mapping,
regardless of which keyboard sent the last mapping notify request. So
depending on the CP setting, your keyboard may change layout in each app...
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.
Let the drivers only generate XI events and put those into the event queue.
When processing events, generate core events as needed. This fixes a number of
problems with XKB and the DIX in general.
The previous approach was to put core events and XI events as separate events
into the event queue. When being processed, the server had no knowledge of
them coming from the same device state change. Anything that would then change
the state of the device accordingly was in danger of changing it twice,
leading to some funny (i.e. not funny at all) results.
Emulating core events while processing XI events fixes this, there is only one
path that actually changes the device state now. Although we have to be
careful when replaying events from synced devices, otherwise we may lose
events.
Note: XI has precedence over core for passive grabs, but core events are
delivered to the client first.
This removes the wrapping added in 340911d724
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.
This reverts commit 6b055e5d97.
MPX relies on the XI event being delivered before the core event. Device grabs
break, amongst other things. I guess stuck modifiers need to be fixed some
other way.
Conflicts:
dix/getevents.c
Disclaimer: It's 6:51am. I'm trying to be as understandable as possible.
What was happening previously was this:
* Press Alt
* Extended event generated and processed: state is now Alt down once
* Core event generated
- keyboard switched: inherited state is Alt down once
- event processed: Alt down twice
* Release Alt
* Extended event generated and processed: state is now null
* Core event generated and processed: Alt down once
If we switch the order:
* Press Alt
* Core event generated:
- keyboard switched: inherited state is null
- event processed: Alt down once
* Extended event generated and processed: state is now Alt down once
* Release Alt
* Core event generated and processed: state is now null
* Extended event generated and processed: state is now null
When we carry over the previous state, it needs to be the _previous_ state
(state and modifiersPerKey), assuming that we're going to catch now-core
events for any of these. For example, if Ctrl is held down as we pivot, we
need to carry Ctrl over with a count of one, for which an extended + core
release will then clear. Carrying over the union of the previous state _and
the state resulting from the immediate action_ was what broke things.
For some reason, my keyboard has 25 mouse buttons, but zero valuators. This
causes GPE to blow up spectacularly, trying to get (and set) co-ordinates from
devices without valuators. For now, just prevent this from ever happening,
and whack a dirty great FIXME in.
Add RawDeviceEvent (pointers only for now).
This commit changes the event queue to use EventLists instead of xEvent
arrays. Only EQ is affected, event delivery still uses xEvent* (look for
comment in mieqProcessInputEvent).
RawDeviceEvents deliver driver information to the client, without clipping or
acceleration.
Make core events carry the same modifier state as the extended events, so
that holding down Ctrl on keyboard A and pressing Q on keyboard B won't
cause your app to quit.
The former <X11/extensions/XKBsrv.h> has been pulled into the server now as
include/xkbsrv.h, and the world updated to look for it in the new place,
since it made no sense to define server API in an extension header. Any
further work along this line will need to do similar things with XKBgeom.h
and friends.
Adding PointerKeyboardPairingChanged event
Correct error values for XWarpDevicePointer
dix: Adding device argument to SendMappingNotify
Adding spriteOwner flag to devices