xserver: Branch 'mpx' - 6 commits

Peter Hutterer whot at kemper.freedesktop.org
Tue Jan 15 00:53:25 PST 2008


 Xi/exevents.c    |   49 --------
 dix/events.c     |  318 ++++++++++++++++++++++++++++++++-----------------------
 xkb/xkbAccessX.c |    5 
 3 files changed, 194 insertions(+), 178 deletions(-)

New commits:
commit b0bf4308acb706abc87c51658c2251fa86231c35
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Jan 15 19:15:09 2008 +1030

    dix: print out an error when core type can't be converted.
    
    Helps a bit in tracking down bugs.

diff --git a/dix/events.c b/dix/events.c
index 4006c29..59688c7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -304,6 +304,9 @@ XItoCoreType(int xitype)
         coretype = KeyPress;
     else if (xitype == DeviceKeyRelease)
         coretype = KeyRelease;
+
+    if (coretype == 0)
+        ErrorF("[dix] Cannot convert type %d to core.\n", xitype);
     return coretype;
 }
 
commit 2a988ed75b7634d7cb6e83bb7aa89bc8768d3a58
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Jan 15 19:14:46 2008 +1030

    xkb: don't do core key repeats, XI only is the path to light.

diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index a035d8d..975b2eb 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -318,9 +318,8 @@ BOOL            is_core;
 
     is_core = (dev == inputInfo.keyboard);
     key = xkbi->repeatKey;
-    AccessXKeyboardEvent(dev, is_core ? KeyRelease : DeviceKeyRelease, key,
-                         True);
-    AccessXKeyboardEvent(dev, is_core ? KeyPress : DeviceKeyPress, key, True);
+    AccessXKeyboardEvent(dev, DeviceKeyRelease, key, True);
+    AccessXKeyboardEvent(dev, DeviceKeyPress, key, True);
     return xkbi->desc->ctrls->repeat_interval;
 }
 
commit 4fd0885978be286a68b689824f1d910f929a52b0
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Jan 15 18:58:42 2008 +1030

    Xi: remove some leftovers from ProcessOtherEvents.
    
    Core handling not needed anymore here.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 23d0c47..faf391f 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -595,10 +595,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
 /**
  * Main device event processing function.
  * Called from when processing the events from the event queue.
- * Generates core events for XI events as needed.
  *
- * Note that these core events are then delivered first. For passive grabs, XI
- * events have preference over core.
  */
 void
 ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
@@ -612,8 +609,6 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
     KeyClassPtr k;
     ValuatorClassPtr v;
     deviceValuator *xV  = (deviceValuator *) xE;
-    BOOL sendCore = FALSE;
-    xEvent core;
     int coretype = 0;
     int ret = 0;
 
@@ -625,10 +620,6 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
     b = device->button;
     k = device->key;
 
-    coretype = XItoCoreType(xE->u.u.type);
-    if (device->isMaster && device->coreEvents && coretype)
-        sendCore = TRUE;
-
     if (device->isMaster)
         CheckMotion(xE, device);
 
commit 32aa252e988be8cbfd4f7e373fb7b7736ef1f5f2
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Jan 15 15:22:39 2008 +1030

    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.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d32a55f..23d0c47 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 4de3b01..4006c29 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
commit 0969a9f7497e10794a6534321c10a0e1ac680ad7
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Jan 15 11:31:12 2008 +1030

    dix: Emulate core events within CheckDeviceGrabs and ComputeFreezes.
    
    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.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index fa39565..d32a55f 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -697,12 +697,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
 	    }
 	    return;
 	}
-        /* XI grabs have priority */
-        core = *xE;
-        core.u.u.type = coretype;
-	if (!grab &&
-              (CheckDeviceGrabs(device, xE, 0, count) ||
-                 (sendCore && CheckDeviceGrabs(device, &core, 0, 1)))) {
+	if (!grab && CheckDeviceGrabs(device, xE, 0, count)) {
 	    device->deviceGrab.activatingKey = key;
 	    return;
 	}
@@ -714,17 +709,11 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
 	xE->u.u.detail = key;
 	if (xE->u.u.detail == 0)
 	    return;
-        if (!grab)
+        if (!grab && CheckDeviceGrabs(device, xE, 0, count))
         {
-            core = *xE;
-            core.u.u.type = coretype;
-            if (CheckDeviceGrabs(device, xE, 0, count) ||
-                    (sendCore && CheckDeviceGrabs(device, &core, 0, 1)))
-            {
-                /* if a passive grab was activated, the event has been sent
-                 * already */
-                return;
-            }
+            /* if a passive grab was activated, the event has been sent
+             * already */
+            return;
         }
 
     } else if (xE->u.u.type == DeviceButtonRelease) {
diff --git a/dix/events.c b/dix/events.c
index ca5bae5..4de3b01 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1359,6 +1359,9 @@ FreezeThaw(DeviceIntPtr dev, Bool frozen)
  * runs up the sprite tree (spriteTrace) and searches for the window to replay
  * the events from. If it is found, it checks for passive grabs one down from
  * the window or delivers the events.
+ *
+ * Since the events in the EQ are always XI events, we need to emulate core
+ * events here.
  */
 static void
 ComputeFreezes(void)
@@ -1391,30 +1394,10 @@ ComputeFreezes(void)
 		replayDev->spriteInfo->sprite->spriteTrace[i])
 	    {
 		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
-                    /* There is no other client that gets a passive grab on
-                     * the event anymore. Emulate core event if necessary and
-                     * deliver it too.
-                     * However, we might get here with a core event, in which
-                     * case we mustn't emulate a core event.
-                     */
-                    sendCore = (replayDev->coreEvents &&
-                        (xE->u.u.type & EXTENSION_EVENT_BASE &&
-                         XItoCoreType(xE->u.u.type)));
-
-
-                    if (sendCore)
-                    {
-                        core = *xE;
-                        core.u.u.type = XItoCoreType(xE->u.u.type);
-                        /* * XXX: Not sure if this is correct: we need to
-                         * check inferior windows for core passive grabs.
-                         */
-                        if (CheckDeviceGrabs(replayDev, &core, i+1, 1))
-                        {
-                            syncEvents.playingEvents = FALSE;
-                            return;
-                        }
-                    }
+                    sendCore = (replayDev->coreEvents && replayDev->isMaster);
+                    core = *xE;
+                    core.u.u.type = XItoCoreType(xE->u.u.type);
+
 		    if (replayDev->focus)
                     {
                         if (sendCore)
@@ -3367,7 +3350,9 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
  * @param pWin The window that may be subject to a passive grab.
  * @param device Device that caused the event.
  * @param xE List of events (multiple ones for DeviceMotionNotify)
- * @count number of elements in xE.
+ * @param count number of elements in xE.
+ * @param store The event that will be stored on the device (always XI)
+ * @param scount number of elements in store.
  */
 
 static Bool
@@ -3375,7 +3360,9 @@ CheckPassiveGrabsOnWindow(
     WindowPtr pWin,
     DeviceIntPtr device,
     xEvent *xE,
-    int count)
+    int count,
+    xEvent *store,
+    int scount)
 {
     GrabPtr grab = wPassiveGrabs(pWin);
     GrabRec tempGrab;
@@ -3494,17 +3481,18 @@ CheckPassiveGrabsOnWindow(
 
 	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 	    {
-		if (grabinfo->sync.evcount < count)
+		if (grabinfo->sync.evcount < scount)
 		{
 		    Must_have_memory = TRUE; /* XXX */
 		    grabinfo->sync.event = (xEvent *)xrealloc(grabinfo->sync.event,
-							    count*
+							    scount*
 							    sizeof(xEvent));
 		    Must_have_memory = FALSE; /* XXX */
 		}
-		grabinfo->sync.evcount = count;
-		for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
-		    *dxE = *xE;
+		grabinfo->sync.evcount = scount;
+                /* we always store the XI event, never the core event */
+		for (dxE = grabinfo->sync.event; --scount >= 0; dxE++, store++)
+		    *dxE = *store;
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
 	    return TRUE;
@@ -3530,8 +3518,11 @@ CheckPassiveGrabsOnWindow(
  *
  * If a grab is activated, the event has been sent to the client already!
  *
+ * The event we pass in must always be an XI event. From this, we then emulate
+ * the core event and then check for grabs.
+ *
  * @param device The device that caused the event.
- * @param xE The event to handle (most likely {Device}ButtonPress).
+ * @param xE The event to handle (Device{Button|Key}Press).
  * @param count Number of events in list.
  * @return TRUE if a grab has been activated or false otherwise.
 */
@@ -3543,11 +3534,26 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
     int i;
     WindowPtr pWin = NULL;
     FocusClassPtr focus = device->focus;
+    xEvent core;
+    BOOL sendCore = (device->isMaster && device->coreEvents);
 
-    if (((xE->u.u.type == ButtonPress) || (xE->u.u.type == DeviceButtonPress))
+    if ((xE->u.u.type == DeviceButtonPress)
             && (device->button->buttonsDown != 1))
 	return FALSE;
 
+    if (xE->u.u.type < EXTENSION_EVENT_BASE)
+    {
+        ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n");
+        return FALSE;
+    }
+
+
+    if (sendCore)
+    {
+        core = *xE;
+        core.u.u.type = XItoCoreType(xE->u.u.type);
+    }
+
     i = checkFirst;
 
     if (focus)
@@ -3555,8 +3561,11 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
 	for (; i < focus->traceGood; i++)
 	{
 	    pWin = focus->trace[i];
+            /* XI grabs have precendence */
 	    if (pWin->optional &&
-		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	       (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count)
+                || (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core,
+                        1, xE, count))))
 		return TRUE;
 	}
 
@@ -3571,7 +3580,9 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
     {
 	pWin = device->spriteInfo->sprite->spriteTrace[i];
 	if (pWin->optional &&
-	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) ||
+             (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1,
+                                                    xE, count))))
 	    return TRUE;
     }
 
commit a83a0c5a144da67dab96a857b849a5692b73245d
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Jan 13 16:14:29 2008 +1030

    dix: remove obsolete comment.
    
    Pairings don't exist anymore and the documented issue is a non-issue now.

diff --git a/dix/events.c b/dix/events.c
index 0ce07d5..ca5bae5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3446,10 +3446,8 @@ CheckPassiveGrabsOnWindow(
                than it is assigned to at this point in time.
                Update the grab's device and modifier device to reflect the
                current state.
-               XXX: Since XGrabDeviceButton requires to specify the
+               Since XGrabDeviceButton requires to specify the
                modifierDevice explicitly, we don't override this choice.
-               This essentially requires a client to re-create all
-               passiveGrabs when the pairing changes... oh well.
              */
             if (xE->u.u.type < LASTEvent)
             {


More information about the xorg-commit mailing list