Dereferencing into dev->valuator could crash the server, although it looks
like I could only reproduce this by having a keyboard send an event after it
was created and the WM was still replaying. Or so.
device->button->down used to be a 32-byte bitmask with one bit for each
button. This has changed into a 256-byte array, with one byte assigned for
each button. Some of the callers were still using this array as a bitmask
however, this is fixed with this patch.
Thanks to Keith Packard for pointing this out. See also:
http://lists.freedesktop.org/archives/xorg/2008-June/036202.html
RealizeCursor should be called when the cursor is allocated. However, when the
root cursor is allocated, no devices exist yet, and thus RealizeCursor is
never called. This may lead to segfaults lateron in DDXes like Xnest that
actually need to do something for each cursor, and lateron rely on that
DDX-specific data for each cursor has been initialized.
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.
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.
Add Prox events to the if-clauses with the other events
that are usually sent from the input devices.
Ensure that the event deliverers won't try to deliver
events of type '0' (some extended events doesn't have
an equivalent core-type)
Small modification by Peter Hutterer.
Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
The latter is used to increase the amount of allocated memory for the event
list. This will be needed for ClassesChangedEvents that can be of more or less
arbitrary size (larger than 32 anyway).
Rather than letting the DDX allocate the events, allocate them once in the DIX
and just pass it around when needed.
DDX should call GetEventList() to obtain this list and then pass it into
Get{Pointer|Keyboard}Events.
The correct thing would be to return the ClientPointer. However, if the client
for some reason has a core grab on another device (e.g. as result of a passive
grab), return the coordinates of the grabbed device instead.
This makes the use of nautilus a bit saner.
If the window being changed is set as the motion hint window for any device,
the device's motion hint window is set to NULL. Which is kinda what the old
code did, except that it did it with only the VCP.
This is a significant shift in how input events are perceived. The common
approach was to treat a core event as a different entity than the XI event.
This could result in the XI event being delivered to a different client than
the core event. This doesn't work nicely if they come from the same device.
Instead, we treat an input event as a single event, that is delivered through
two separate APIs. So when delivering an event, we first try the XI event,
then the core event. If the window want's neither, we go to the parent and
repeat. Once either core or XI has been delivered, the processing stops.
Important: Different to the previous method, if a client registers for core
button events, the parent window will not get XI events. This should only
cause problems when you're mixing core and XI events, so don't do that!
Generic events don't fit into this yet, they cause me headaches.
This should restore the correct passive grab processing. When checking for
passive grabs, the core event is emulated and we check first for XI grabs on
the window, then for core grabs. Regardless of which event activates the grab,
the XI event is stored in the device's EQ.
When replaying the event, we take the XI event and replay it on the next
window, again including the emulation of the core event.
If we have one global filter, one pointer may change the filter value and
affect another pointer.
Reproduceable effect:
blackbox and xterm, start dragging xterm then click anywhere with the other
pointer (attached to different masterd device!). The button release resets
the filter[Motion_Filter(button)] value, thus stopping dragging and no event
is sent to the client anymore.
Having the filters set per device gets around this.
In some cases (e.g. using x2x) the previous model broke, with a window ending
not counting down to 0 anymore. Special treatment for NotifyUngrab seems to
help here.
Current solution: If a NotifyGrab is to be sent ignore it. If a NotifyUngrab
enter is sent, only adjust the semaphore if it is on 0. Likewise, do the same
for a NotifyUngrab leave if the semaphore is on 1. This seems to work alright
so far.
This can happen if we check for a passive core grab and our device is a
floating slave device. Doesn't really change anything as SDs can't send core
events but it stops the server from segfaulting.
FixKeyState needs to be able to handle XI events, otherwise we get "impossible
keyboard events" on server zaps and other special key combos.
(cherry picked from commit 5ee409794e)
In some cases a button press may activate a passive core grab. If the client
owning the passive grab already has a core grab on another device, don't
actually activate it. Otherwise the client gets two simultaneous passive
core grabs, and may never ungrab the device again (only if the other grab uses
GrabModeSync).
Reproducable: fire up gnome-session, open up gnome-terminal. Click with the
ClientPointer onto the window decoration, then click with another pointer onto
an application icon in the panel. Drag the icon out, release the button and
voila - you just lost your second mouse.
This is a half-assed attempt at getting rid of some enter-leave problems. When
a grab is activated, the events didn't get sent before, leading to interesting
results. This commit papers over it but doesn't actually fix it properly. The
whole enter/leave (focusin/out) structure needs to be ripped out and changed
for multiple devices.
* dix/events.c, include/dix.h:
(UpdateSpriteForScreen): added this to update the mouse sprite context
when we switch from a pScreen to another.
* mi/mipointer.c:
(miPointerWarpCursor): as we are switching to a new pScreen,
don't forget to update the mouse sprite context.
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
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.
GenericEvents can't be parsed to keyButtonPointer, and there's no guarantee
that it has a time field anyway. PlayReleasedEvent needs to store the millis
when we know it (core events, XI event) and just re-use them for GenericEvents.
Yes, this is a hack. But it looks like the time has zero significance anyway.
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.
delivery of events to windows and clients.
This is tentative. It's likely that an additional last-resort hook will
be necessary for code that calls TryClientEvents or WriteEventsToClient
directly. It's also possible that new xace machinery will be necessary
to classify events and pull useful resource ID's out of them.
The failure case also needs some thinking through. Should event delivery
"succeed" or should it report undeliverable?
Finally, XKB appears to call WriteToClient to pass events. Sigh.
We shouldn't be able to restrict events like Expose, etc. with device based
ACLs. So we just ignore all non-input events when checking for permissions.
A passive core grab doesn't specify the device, and is thus created with the
ClientPointer as device. When this grab is activated later, don't actually
activate the grab on the grab device, but rather change the device to the one
that caused the grab to activate. Same procedure for keyboards.
Makes core apps _A LOT_ more useable and reduces the need to set the
ClientPointer.
Only applies to core grabs!