dix: fix up device enter/leave for XI_Enter/XI_Leave.

This commit is contained in:
Peter Hutterer 2009-02-23 16:14:51 +10:00
parent 0befeb36c1
commit 181e41511d
3 changed files with 53 additions and 46 deletions

View File

@ -602,20 +602,28 @@ SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to
}
static void
SDeviceLeaveNotifyEvent (deviceLeaveNotify *from, deviceLeaveNotify *to)
SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
{
char n;
*to = *from;
swaps(&to->sequenceNumber,n);
swapl(&to->length, n);
swaps(&to->evtype, n);
swaps(&to->deviceid, n);
swapl(&to->time, n);
swapl(&to->root, n);
swapl(&to->event, n);
swapl(&to->child, n);
swaps(&to->rootX, n);
swaps(&to->rootY, n);
swaps(&to->eventX, n);
swaps(&to->eventY, n);
swaps(&to->root_x.integral, n);
swaps(&to->root_x.frac, n);
swaps(&to->root_y.integral, n);
swaps(&to->root_y.frac, n);
swaps(&to->event_x.integral, n);
swaps(&to->event_x.frac, n);
swaps(&to->event_y.integral, n);
swaps(&to->event_y.frac, n);
swaps(&to->sourceid, n);
}
static void
@ -669,6 +677,13 @@ SDeviceClassesChangedEvent(deviceClassesChangedEvent* from,
static void
XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
{
switch(from->evtype)
{
case XI_Enter:
case XI_Leave:
SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
break;
}
}
/**************************************************************************
@ -1025,10 +1040,6 @@ SEventIDispatch(xEvent * from, xEvent * to)
DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
else if (type == DevicePropertyNotify)
DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify);
else if (type == DeviceEnterNotify)
DO_SWAP(SDeviceLeaveNotifyEvent, deviceEnterNotify);
else if (type == DeviceLeaveNotify)
DO_SWAP(SDeviceLeaveNotifyEvent, deviceLeaveNotify);
else {
FatalError("XInputExtension: Impossible event!\n");
}
@ -1084,8 +1095,6 @@ XInputExtensionInit(void)
EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
EventSwapVector[DeviceEnterNotify] = SEventIDispatch;
EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
GERegisterExtension(IReqCode, XI2EventSwap);
} else {

View File

@ -29,6 +29,7 @@
#endif
#include <X11/X.h>
#include <X11/extensions/XI2.h>
#include "windowstr.h"
#include "scrnintstr.h"
#include "exglobals.h"
@ -228,7 +229,7 @@ DeviceEnterNotifies(DeviceIntPtr dev,
if (ancestor == parent)
return;
DeviceEnterNotifies(dev, ancestor, parent, mode, detail);
DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, detail, parent,
DeviceEnterLeaveEvent(dev, XI_Enter, mode, detail, parent,
child->drawable.id);
}
@ -334,7 +335,7 @@ DeviceLeaveNotifies(DeviceIntPtr dev,
return;
for (win = child->parent; win != ancestor; win = win->parent)
{
DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, detail, win,
DeviceEnterLeaveEvent(dev, XI_Leave, mode, detail, win,
child->drawable.id);
child = win;
}
@ -568,24 +569,24 @@ DeviceEnterLeaveEvents(DeviceIntPtr dev,
{
if (IsParent(from, to))
{
DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyInferior, from, None);
DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyInferior, from, None);
DeviceEnterNotifies(dev, from, to, mode, NotifyVirtual);
DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyAncestor, to, None);
DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyAncestor, to, None);
}
else if (IsParent(to, from))
{
DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyAncestor, from, None);
DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyAncestor, from, None);
DeviceLeaveNotifies(dev, from, to, mode, NotifyVirtual);
DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyInferior, to, None);
DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyInferior, to, None);
}
else
{ /* neither from nor to is descendent of the other */
WindowPtr common = CommonAncestor(to, from);
/* common == NullWindow ==> different screens */
DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyNonlinear, from, None);
DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyNonlinear, from, None);
DeviceLeaveNotifies(dev, from, common, mode, NotifyNonlinearVirtual);
DeviceEnterNotifies(dev, common, to, mode, NotifyNonlinearVirtual);
DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyNonlinear, to, None);
DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyNonlinear, to, None);
}
}

View File

@ -3994,14 +3994,12 @@ DeviceEnterLeaveEvent(
WindowPtr pWin,
Window child)
{
xEvent event;
GrabPtr grab = mouse->deviceGrab.grab;
deviceEnterNotify *devEnterLeave;
xXIEnterEvent event;
int mskidx;
OtherInputMasks *inputMasks;
Mask mask;
DeviceIntPtr keybd = GetPairedDevice(mouse);
BOOL sameScreen;
xEvent dummy;
if (grab) {
mask = (pWin == grab->window) ? grab->eventMask : 0;
@ -4011,41 +4009,40 @@ DeviceEnterLeaveEvent(
mask = pWin->eventMask | wOtherEventMasks(pWin);
}
/* we don't have enough bytes, so we squash flags and mode into
one byte, and use the last byte for the deviceid. */
memset(&event, 0, sizeof(xEvent));
devEnterLeave = (deviceEnterNotify*)&event;
devEnterLeave->type = type;
devEnterLeave->detail = detail;
devEnterLeave->time = currentTime.milliseconds;
devEnterLeave->rootX = mouse->spriteInfo->sprite->hot.x;
devEnterLeave->rootY = mouse->spriteInfo->sprite->hot.y;
FixUpEventFromWindow(mouse, &event, pWin, None, FALSE);
sameScreen = event.u.keyButtonPointer.sameScreen;
memset(&event, 0, sizeof(event));
event.type = GenericEvent;
event.extension = IReqCode;
event.evtype = type;
event.detail = detail;
event.time = currentTime.milliseconds;
event.deviceid = mouse->id;
event.sourceid = 0; /*XXX */
event.mode = mode;
event.root_x.integral = mouse->spriteInfo->sprite->hot.x;
event.root_y.integral = mouse->spriteInfo->sprite->hot.y;
devEnterLeave->child = child;
devEnterLeave->deviceid = mouse->id;
devEnterLeave->mode = mode;
devEnterLeave->mode |= (sameScreen ? (ELFlagSameScreen << 4) : 0);
/* We use FUEFW to fill in dummy, then copy the values */
FixUpEventFromWindow(mouse, &dummy, pWin, None, FALSE);
devEnterLeave->state = mouse->button->state & 0x1f00;
if (keybd && keybd->key)
devEnterLeave->state |= XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
event.same_screen = dummy.u.keyButtonPointer.sameScreen;
event.child = dummy.u.keyButtonPointer.child;
event.event_x.integral = dummy.u.keyButtonPointer.eventX;
event.event_y.integral = dummy.u.keyButtonPointer.eventY;
mskidx = mouse->id;
inputMasks = wOtherInputMasks(pWin);
if (inputMasks &&
(GetEventFilter(mouse, (xEvent*)devEnterLeave) &
(GetEventFilter(mouse, (xEvent*)&event) &
inputMasks->deliverableEvents[mskidx]))
{
if (grab)
TryClientEvents(rClient(grab), mouse,
(xEvent*)devEnterLeave, 1, mask,
GetEventFilter(mouse, (xEvent*)devEnterLeave),
(xEvent*)&event, 1, mask,
GetEventFilter(mouse, (xEvent*)&event),
grab);
else
DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave, 1,
GetEventFilter(mouse, (xEvent*)devEnterLeave),
DeliverEventsToWindow(mouse, pWin, (xEvent*)&event, 1,
GetEventFilter(mouse, (xEvent*)&event),
NullGrab, mouse->id);
}