summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-01-15 15:22:39 +1030
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-01-15 18:41:51 +1030
commit32aa252e988be8cbfd4f7e373fb7b7736ef1f5f2 (patch)
tree9cdb35c47602bd67416a4bd2768d4e400ef22ce1
parent0969a9f7497e10794a6534321c10a0e1ac680ad7 (diff)
dix: Process an input event as a single event, instead of two separate ones.
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.
-rw-r--r--Xi/exevents.c19
-rw-r--r--dix/events.c238
2 files changed, 141 insertions, 116 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index d32a55fd1..23d0c47b6 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -724,32 +724,13 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
deactivateDeviceGrab = TRUE;
}
- if (sendCore)
- {
- core = *xE;
- core.u.u.type = coretype;
- }
-
if (grab)
- {
- if (sendCore) /* never deactivate from core */
- DeliverGrabbedEvent(&core, device, FALSE , 1);
DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
- }
else if (device->focus)
- {
- if (sendCore)
- DeliverFocusedEvent(device, &core, GetSpriteWindow(device), 1);
DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count);
- }
else
- {
- if (sendCore)
- DeliverDeviceEvents(GetSpriteWindow(device), &core, NullGrab,
- NullWindow, device, 1);
DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow,
device, count);
- }
if (deactivateDeviceGrab == TRUE)
(*device->deviceGrab.DeactivateGrab) (device);
diff --git a/dix/events.c b/dix/events.c
index 4de3b01b1..4006c2992 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1369,11 +1369,10 @@ ComputeFreezes(void)
DeviceIntPtr replayDev = syncEvents.replayDev;
int i;
WindowPtr w;
- xEvent *xE, core;
+ xEvent *xE;
int count;
GrabPtr grab;
DeviceIntPtr dev;
- BOOL sendCore;
for (dev = inputInfo.devices; dev; dev = dev->next)
FreezeThaw(dev, dev->deviceGrab.sync.other ||
@@ -1394,24 +1393,11 @@ ComputeFreezes(void)
replayDev->spriteInfo->sprite->spriteTrace[i])
{
if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
- sendCore = (replayDev->coreEvents && replayDev->isMaster);
- core = *xE;
- core.u.u.type = XItoCoreType(xE->u.u.type);
-
if (replayDev->focus)
- {
- if (sendCore)
- DeliverFocusedEvent(replayDev, &core, w, 1);
DeliverFocusedEvent(replayDev, xE, w, count);
- }
else
- {
- if (sendCore)
- DeliverDeviceEvents(w, &core, NullGrab,
- NullWindow, replayDev, 1);
DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
replayDev, count);
- }
}
goto playmore;
}
@@ -2439,92 +2425,97 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
int type = xE->u.u.type;
Mask filter = filters[dev->id][type];
int deliveries = 0;
+ OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+ xEvent core;
if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
return 0;
- if (type & EXTENSION_EVENT_BASE)
+ /* handle generic events */
+ /* XXX: Generic events aren't quite handled correctly yet. They should
+ * eventually fit in with the rest of the stuff
+ */
+ if (type == GenericEvent)
{
- OtherInputMasks *inputMasks;
- int mskidx = dev->id;
+ WindowPtr win = pWin;
+ xGenericEvent* ge = (xGenericEvent*)xE;
- inputMasks = wOtherInputMasks(pWin);
- if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
- return 0;
- while (pWin)
- {
- if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
- {
- FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
- deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter,
- grab, mskidx);
- if (deliveries > 0)
- return deliveries;
- }
- if ((deliveries < 0) ||
- (pWin == stopAt) ||
- (inputMasks &&
- (filter & inputMasks->dontPropagateMask[mskidx])))
- return 0;
- child = pWin->drawable.id;
- pWin = pWin->parent;
- if (pWin)
- inputMasks = wOtherInputMasks(pWin);
- }
- }
- else
- {
- /* handle generic events */
- if (type == GenericEvent)
+ if (count > 1)
{
- xGenericEvent* ge = (xGenericEvent*)xE;
+ ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
+ return 0;
+ }
+ filter = generic_filters[GEEXTIDX(xE)][ge->evtype];
- if (count > 1)
+ while(win)
+ {
+ if (GEMaskIsSet(win, GEEXT(xE), filter))
{
- ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
- return 0;
+ if (GEExtensions[GEEXTIDX(xE)].evfill)
+ GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, win, grab);
+ deliveries = DeliverEventsToWindow(dev, win, xE, count,
+ filter, grab, 0);
+ if (deliveries > 0)
+ return deliveries;
}
- filter = generic_filters[GEEXTIDX(xE)][ge->evtype];
- while(pWin)
- {
- if (GEMaskIsSet(pWin, GEEXT(xE), filter))
- {
- if (GEExtensions[GEEXTIDX(xE)].evfill)
- GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, pWin, grab);
- deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
- filter, grab, 0);
- if (deliveries > 0)
- return deliveries;
- }
+ win = win->parent;
+ }
+ }
+
+ while (pWin && type != GenericEvent)
+ {
+ /* First try XI event delivery */
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && (filter & inputMasks->deliverableEvents[mskidx]))
+ {
- pWin = pWin->parent;
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
+ filter, grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
}
+
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
}
- else
+
+ if (dev->isMaster && dev->coreEvents)
{
- /* core protocol events */
- if (!(filter & pWin->deliverableEvents))
- return 0;
- while (pWin)
+
+ /* no XI event delivered. Try core event */
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+
+ if (filter & pWin->deliverableEvents)
{
if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
{
- FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
- deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter,
- grab, 0);
+ FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+ filter, grab, 0);
if (deliveries > 0)
return deliveries;
}
+
if ((deliveries < 0) ||
(pWin == stopAt) ||
(filter & wDontPropagateMask(pWin)))
return 0;
- child = pWin->drawable.id;
- pWin = pWin->parent;
}
- }
+ }
+
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
}
+
return 0;
}
@@ -3604,7 +3595,10 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
{
DeviceIntPtr pointer;
WindowPtr focus = keybd->focus->win;
- int mskidx = 0;
+ BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
+ xEvent core;
+ int deliveries = 0;
+
if (focus == FollowKeyboardWin)
focus = inputInfo.keyboard->focus->win;
if (!focus)
@@ -3622,13 +3616,29 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
pointer = GetPairedDevice(keybd);
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
return;
+
+ if (sendCore)
+ {
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ }
+
/* just deliver it to the focus window */
FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
- if (xE->u.u.type & EXTENSION_EVENT_BASE)
- mskidx = keybd->id;
- (void)DeliverEventsToWindow(keybd, focus, xE, count,
- filters[keybd->id][xE->u.u.type],
- NullGrab, mskidx);
+ deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
+ filters[keybd->id][xE->u.u.type],
+ NullGrab, keybd->id);
+
+ if (deliveries > 0)
+ return;
+
+ if (sendCore)
+ {
+ FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
+ filters[keybd->id][xE->u.u.type],
+ NullGrab, 0);
+ }
}
/**
@@ -3646,8 +3656,9 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
GrabInfoPtr grabinfo;
int deliveries = 0;
DeviceIntPtr dev;
- xEvent *dxE;
+ xEvent *dxE, core;
SpritePtr pSprite = thisDev->spriteInfo->sprite;
+ BOOL sendCore = FALSE;
grabinfo = &thisDev->deviceGrab;
grab = grabinfo->grab;
@@ -3697,23 +3708,56 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
} else
{
Mask mask = grab->eventMask;
- if (grabinfo->fromPassiveGrab &&
- grabinfo->implicitGrab &&
- (xE->u.u.type & EXTENSION_EVENT_BASE))
- mask = grab->deviceMask;
-
- FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE);
-
- if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, xE,
- count) ||
- XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), grab->window,
- xE, count))
- deliveries = 1; /* don't send, but pretend we did */
- else if (!(!(xE->u.u.type & EXTENSION_EVENT_BASE) &&
- IsInterferingGrab(rClient(grab), thisDev, xE)))
+
+ sendCore = (thisDev->isMaster && thisDev->coreEvents);
+ /* try core event */
+ if (sendCore && grab->coreGrab)
{
- deliveries = TryClientEvents(rClient(grab), xE, count,
- mask, filters[thisDev->id][xE->u.u.type], grab);
+ core = *xE;
+ core.u.u.type = XItoCoreType(xE->u.u.type);
+ FixUpEventFromWindow(thisDev, &core, grab->window,
+ None, TRUE);
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, &core, 1) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window, &count, 1))
+ deliveries = 1; /* don't send, but pretend we did */
+ else if (!IsInterferingGrab(rClient(grab), thisDev,
+ &core))
+ {
+ deliveries = TryClientEvents(rClient(grab), &core, 1,
+ mask,
+ filters[thisDev->id][core.u.u.type],
+ grab);
+ }
+ }
+
+ if (!deliveries)
+ {
+ /* try XI event */
+ if (grabinfo->fromPassiveGrab &&
+ grabinfo->implicitGrab &&
+ (xE->u.u.type & EXTENSION_EVENT_BASE))
+ mask = grab->deviceMask;
+ FixUpEventFromWindow(thisDev, xE, grab->window,
+ None, TRUE);
+
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, xE, count) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window,
+ xE, count))
+ deliveries = 1; /* don't send, but pretend we did */
+ else
+ {
+ deliveries =
+ TryClientEvents(rClient(grab),
+ xE, count,
+ mask,
+ filters[thisDev->id][xE->u.u.type],
+ grab);
+ }
+
}
}
if (deliveries && (xE->u.u.type == MotionNotify