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