dix: Split ActivatePassiveGrab() from CheckPassiveGrab()
The changed logic means we don't require the explicit grab = NULL setting and early exit anymore. Not 100% of it, but if we see that message pop up in a log we know it's broken. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
		
							parent
							
								
									9ee62cd8ce
								
							
						
					
					
						commit
						80816366aa
					
				
							
								
								
									
										199
									
								
								dix/events.c
								
								
								
								
							
							
						
						
									
										199
									
								
								dix/events.c
								
								
								
								
							| 
						 | 
					@ -3634,39 +3634,129 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
 | 
				
			||||||
     return FALSE;
 | 
					     return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Activate the given passive grab. If the grab is activated successfully, the
 | 
				
			||||||
 | 
					 * event has been delivered to the client.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param device The device of the event to check.
 | 
				
			||||||
 | 
					 * @param grab The grab to check.
 | 
				
			||||||
 | 
					 * @param event The current device event.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return Whether the grab has been activated.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					Bool
 | 
				
			||||||
 | 
					ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SpritePtr pSprite = device->spriteInfo->sprite;
 | 
				
			||||||
 | 
					    GrabInfoPtr grabinfo = &device->deviceGrab;
 | 
				
			||||||
 | 
					    xEvent *xE = NULL;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!GetXIType(event->any.type) && !GetCoreType(event->any.type))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
 | 
				
			||||||
 | 
					               " XI 1.x nor core\n", event->any.type);
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* The only consumers of corestate are Xi 1.x and core events, which
 | 
				
			||||||
 | 
					     * are guaranteed to come from DeviceEvents. */
 | 
				
			||||||
 | 
					    if (grab->grabtype == GRABTYPE_XI || grab->grabtype == GRABTYPE_CORE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DeviceIntPtr gdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        event->device_event.corestate &= 0x1f00;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (grab->grabtype == GRABTYPE_CORE)
 | 
				
			||||||
 | 
					            gdev = GetMaster(device, KEYBOARD_OR_FLOAT);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            gdev = grab->modifierDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (gdev && gdev->key && gdev->key->xkbInfo)
 | 
				
			||||||
 | 
					            event->device_event.corestate |=
 | 
				
			||||||
 | 
					                gdev->key->xkbInfo->state.grab_mods & (~0x1f00);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (grab->grabtype == GRABTYPE_CORE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        rc = EventToCore(event, &xE, &count);
 | 
				
			||||||
 | 
					        if (rc != Success)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            BUG_WARN_MSG(rc != BadMatch,"[dix] %s: core conversion failed"
 | 
				
			||||||
 | 
					                         "(%d, %d).\n", device->name, event->any.type, rc);
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if (grab->grabtype == GRABTYPE_XI2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        rc = EventToXI2(event, &xE);
 | 
				
			||||||
 | 
					        if (rc != Success)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (rc != BadMatch)
 | 
				
			||||||
 | 
					                BUG_WARN_MSG(rc != BadMatch,"[dix] %s: XI2 conversion failed"
 | 
				
			||||||
 | 
					                             "(%d, %d).\n", device->name, event->any.type, rc);
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        count = 1;
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        rc = EventToXI(event, &xE, &count);
 | 
				
			||||||
 | 
					        if (rc != Success)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (rc != BadMatch)
 | 
				
			||||||
 | 
					                BUG_WARN_MSG(rc != BadMatch,"[dix] %s: XI conversion failed"
 | 
				
			||||||
 | 
					                             "(%d, %d).\n", device->name, event->any.type, rc);
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (xE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* XXX: XACE? */
 | 
				
			||||||
 | 
					        TryClientEvents(rClient(grab), device, xE, count,
 | 
				
			||||||
 | 
					                        GetEventFilter(device, xE),
 | 
				
			||||||
 | 
					                        GetEventFilter(device, xE), grab);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!grabinfo->sync.event)
 | 
				
			||||||
 | 
					            grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
 | 
				
			||||||
 | 
					        *grabinfo->sync.event = event->device_event;
 | 
				
			||||||
 | 
					        grabinfo->sync.state = FROZEN_WITH_EVENT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(xE);
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Check an individual grab against an event to determine if a passive grab
 | 
					 * Check an individual grab against an event to determine if a passive grab
 | 
				
			||||||
 * should be activated.
 | 
					 * should be activated.
 | 
				
			||||||
 * If activate is true and a passive grab is found, it will be activated, and
 | 
					 | 
				
			||||||
 * the event will be delivered to the client.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param device The device of the event to check.
 | 
					 * @param device The device of the event to check.
 | 
				
			||||||
 * @param grab The grab to check.
 | 
					 * @param grab The grab to check.
 | 
				
			||||||
 * @param event The current device event.
 | 
					 * @param event The current device event.
 | 
				
			||||||
 * @param checkCore Check for core grabs too.
 | 
					 * @param checkCore Check for core grabs too.
 | 
				
			||||||
 * @param activate Whether to activate a matching grab.
 | 
					 | 
				
			||||||
 * @param tempGrab A pre-allocated temporary grab record for matching. This
 | 
					 * @param tempGrab A pre-allocated temporary grab record for matching. This
 | 
				
			||||||
 *        must have the window and device values filled in.
 | 
					 *        must have the window and device values filled in.
 | 
				
			||||||
 * @param[out] grab_return The modified value of grab, to be used in the
 | 
					 | 
				
			||||||
 * caller for grab activation if a this function returns TRUE. May be NULL.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @return Whether the grab matches the event.
 | 
					 * @return Whether the grab matches the event.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
 | 
					CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
 | 
				
			||||||
                 Bool checkCore, Bool activate, GrabPtr tempGrab, GrabPtr *grab_return)
 | 
					                 Bool checkCore, GrabPtr tempGrab)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static const int CORE_MATCH = 0x1;
 | 
					    static const int CORE_MATCH = 0x1;
 | 
				
			||||||
    static const int XI_MATCH = 0x2;
 | 
					    static const int XI_MATCH = 0x2;
 | 
				
			||||||
    static const int XI2_MATCH = 0x4;
 | 
					    static const int XI2_MATCH = 0x4;
 | 
				
			||||||
    SpritePtr pSprite = device->spriteInfo->sprite;
 | 
					 | 
				
			||||||
    GrabInfoPtr grabinfo;
 | 
					 | 
				
			||||||
    DeviceIntPtr gdev;
 | 
					    DeviceIntPtr gdev;
 | 
				
			||||||
    XkbSrvInfoPtr xkbi = NULL;
 | 
					    XkbSrvInfoPtr xkbi = NULL;
 | 
				
			||||||
    xEvent *xE = NULL;
 | 
					 | 
				
			||||||
    int match = 0;
 | 
					    int match = 0;
 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    int rc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gdev = grab->modifierDevice;
 | 
					    gdev = grab->modifierDevice;
 | 
				
			||||||
    if (grab->grabtype == GRABTYPE_CORE)
 | 
					    if (grab->grabtype == GRABTYPE_CORE)
 | 
				
			||||||
| 
						 | 
					@ -3715,8 +3805,6 @@ CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
 | 
				
			||||||
                    !BorderSizeNotEmpty(device, grab->confineTo))))
 | 
					                    !BorderSizeNotEmpty(device, grab->confineTo))))
 | 
				
			||||||
        return FALSE;
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *grab_return = grab;
 | 
					 | 
				
			||||||
    grabinfo = &device->deviceGrab;
 | 
					 | 
				
			||||||
    /* In some cases a passive core grab may exist, but the client
 | 
					    /* In some cases a passive core grab may exist, but the client
 | 
				
			||||||
     * already has a core grab on some other device. In this case we
 | 
					     * already has a core grab on some other device. In this case we
 | 
				
			||||||
     * must not get the grab, otherwise we may never ungrab the
 | 
					     * must not get the grab, otherwise we may never ungrab the
 | 
				
			||||||
| 
						 | 
					@ -3759,79 +3847,6 @@ CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
 | 
				
			||||||
            return FALSE;
 | 
					            return FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!activate)
 | 
					 | 
				
			||||||
        return TRUE;
 | 
					 | 
				
			||||||
    else if (!GetXIType(event->any.type) && !GetCoreType(event->any.type))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
 | 
					 | 
				
			||||||
               " XI 1.x nor core\n", event->any.type);
 | 
					 | 
				
			||||||
        *grab_return = NULL;
 | 
					 | 
				
			||||||
        return TRUE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* The only consumers of corestate are Xi 1.x and core events, which
 | 
					 | 
				
			||||||
     * are guaranteed to come from DeviceEvents. */
 | 
					 | 
				
			||||||
    if (match & (XI_MATCH | CORE_MATCH))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        event->device_event.corestate &= 0x1f00;
 | 
					 | 
				
			||||||
        event->device_event.corestate |= tempGrab->modifiersDetail.exact &
 | 
					 | 
				
			||||||
                                          (~0x1f00);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (match & CORE_MATCH)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        rc = EventToCore(event, &xE, &count);
 | 
					 | 
				
			||||||
        if (rc != Success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (rc != BadMatch)
 | 
					 | 
				
			||||||
                ErrorF("[dix] %s: core conversion failed in CPGFW "
 | 
					 | 
				
			||||||
                        "(%d, %d).\n", device->name, event->any.type, rc);
 | 
					 | 
				
			||||||
            return TRUE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else if (match & XI2_MATCH)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        rc = EventToXI2(event, &xE);
 | 
					 | 
				
			||||||
        if (rc != Success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (rc != BadMatch)
 | 
					 | 
				
			||||||
                ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
 | 
					 | 
				
			||||||
                        "(%d, %d).\n", device->name, event->any.type, rc);
 | 
					 | 
				
			||||||
            return TRUE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        count = 1;
 | 
					 | 
				
			||||||
    } else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        rc = EventToXI(event, &xE, &count);
 | 
					 | 
				
			||||||
        if (rc != Success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (rc != BadMatch)
 | 
					 | 
				
			||||||
                ErrorF("[dix] %s: XI conversion failed in CPGFW "
 | 
					 | 
				
			||||||
                        "(%d, %d).\n", device->name, event->any.type, rc);
 | 
					 | 
				
			||||||
            return TRUE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (xE)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* XXX: XACE? */
 | 
					 | 
				
			||||||
        TryClientEvents(rClient(grab), device, xE, count,
 | 
					 | 
				
			||||||
                        GetEventFilter(device, xE),
 | 
					 | 
				
			||||||
                        GetEventFilter(device, xE), grab);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (!grabinfo->sync.event)
 | 
					 | 
				
			||||||
            grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
 | 
					 | 
				
			||||||
        *grabinfo->sync.event = event->device_event;
 | 
					 | 
				
			||||||
        grabinfo->sync.state = FROZEN_WITH_EVENT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    free(xE);
 | 
					 | 
				
			||||||
    return TRUE;
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3887,9 +3902,15 @@ CheckPassiveGrabsOnWindow(
 | 
				
			||||||
    tempGrab->next = NULL;
 | 
					    tempGrab->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (; grab; grab = grab->next)
 | 
					    for (; grab; grab = grab->next)
 | 
				
			||||||
        if (CheckPassiveGrab(device, grab, event, checkCore, activate,
 | 
					    {
 | 
				
			||||||
                             tempGrab, &grab))
 | 
					        if (!CheckPassiveGrab(device, grab, event, checkCore, tempGrab))
 | 
				
			||||||
            break;
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (activate && !ActivatePassiveGrab(device, grab, event))
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FreeGrab(tempGrab);
 | 
					    FreeGrab(tempGrab);
 | 
				
			||||||
    return grab;
 | 
					    return grab;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -548,6 +548,8 @@ void FixUpEventFromWindow(SpritePtr pSprite,
 | 
				
			||||||
extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
 | 
					extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
 | 
				
			||||||
extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event,
 | 
					extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event,
 | 
				
			||||||
                              WindowPtr win);
 | 
					                              WindowPtr win);
 | 
				
			||||||
 | 
					extern Bool ActivatePassiveGrab(DeviceIntPtr dev, GrabPtr grab,
 | 
				
			||||||
 | 
					                                InternalEvent *ev);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Masks specifying the type of event to deliver for an InternalEvent; used
 | 
					 * Masks specifying the type of event to deliver for an InternalEvent; used
 | 
				
			||||||
 * by EventIsDeliverable.
 | 
					 * by EventIsDeliverable.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue