summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-04-12 14:04:37 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-05-13 09:41:34 +1000
commit236ed6f50675dc0303a505ac6f0418c515438fe1 (patch)
tree0dfd2a09abee6825aacd25228604831e5e45b012
parent536ca28f1b0b4d8715a41b8acc5f30364c833f9b (diff)
dix: split out client delivery from DeliverEventsToWindow
No real functional changes, this is just for improved readability. DeliverEventsToWindow used to return an int to specify the number of deliveries (or rejected deliveries if negative). The number wasn't used by any caller other than for > 0 comparison. This patch also changes the return value to be -1 or 1 even in case of multiple deliveries/rejections. The comment was updated accordingly. A future patch should probably use the enum EventDeliveryState for DeliverEventsToWindow. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Jamey Sharp <jamey@minilop.net>
-rw-r--r--dix/events.c130
1 files changed, 87 insertions, 43 deletions
diff --git a/dix/events.c b/dix/events.c
index 4e9af8df4..77f871564 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2025,6 +2025,75 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
}
/**
+ * Deliver events to clients registered on the window.
+ *
+ * @param client_return On successful delivery, set to the recipient.
+ * @param mask_return On successful delivery, set to the recipient's event
+ * mask for this event.
+ */
+static enum EventDeliveryState
+DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
+ int count, Mask filter, GrabPtr grab,
+ ClientPtr *client_return, Mask *mask_return)
+{
+ int attempt;
+ enum EventDeliveryState rc = EVENT_SKIP;
+ InputClients *other;
+
+ if (CORE_EVENT(events))
+ other = (InputClients *)wOtherClients(win);
+ else if (XI2_EVENT(events))
+ {
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ /* Has any client selected for the event? */
+ if (!GetWindowXI2Mask(dev, win, events))
+ goto out;
+ other = inputMasks->inputClients;
+ } else {
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ /* Has any client selected for the event? */
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[dev->id] & filter))
+ goto out;
+
+ other = inputMasks->inputClients;
+ }
+
+ rc = EVENT_NOT_DELIVERED;
+
+ for (; other; other = other->next)
+ {
+ Mask mask;
+
+ if (IsInterferingGrab(rClient(other), dev, events))
+ continue;
+
+ mask = GetEventMask(dev, events, other);
+
+ if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), win,
+ events, count))
+ /* do nothing */;
+ else if ( (attempt = TryClientEvents(rClient(other), dev,
+ events, count,
+ mask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ rc = EVENT_DELIVERED;
+ *client_return = rClient(other);
+ *mask_return = mask;
+ /* Success overrides non-success, so if we've been
+ * successful on one client, return that */
+ } else if (rc == EVENT_NOT_DELIVERED)
+ rc = EVENT_REJECTED;
+ }
+ }
+
+out:
+ return rc;
+}
+
+/**
* Deliver events to a window. At this point, we do not yet know if the event
* actually needs to be delivered. May activate a grab if the event is a
* button press.
@@ -2042,21 +2111,20 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
* @param filter Mask based on event type.
* @param grab Possible grab on the device that caused the event.
*
- * @return Number of events delivered to various clients.
+ * @return a positive number if at least one successful delivery has been
+ * made, 0 if no events were delivered, or a negative number if the event
+ * has not been delivered _and_ rejected by at least one client.
*/
int
DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
*pEvents, int count, Mask filter, GrabPtr grab)
{
int deliveries = 0, nondeliveries = 0;
- int attempt;
- InputClients *other;
ClientPtr client = NullClient;
Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
this mask is the mask of the grab. */
int type = pEvents->u.u.type;
-
/* Deliver to window owner */
if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
{
@@ -2085,50 +2153,26 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
/* CantBeFiltered means only window owner gets the event */
if (filter != CantBeFiltered)
{
- if (CORE_EVENT(pEvents))
- other = (InputClients *)wOtherClients(pWin);
- else if (XI2_EVENT(pEvents))
- {
- OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
- /* Has any client selected for the event? */
- if (!GetWindowXI2Mask(pDev, pWin, pEvents))
- return 0;
- other = inputMasks->inputClients;
- } else {
- OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
- /* Has any client selected for the event? */
- if (!inputMasks ||
- !(inputMasks->inputEvents[pDev->id] & filter))
- return 0;
+ enum EventDeliveryState rc;
- other = inputMasks->inputClients;
- }
+ rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab,
+ &client, &deliveryMask);
- for (; other; other = other->next)
+ switch(rc)
{
- Mask mask;
- if (IsInterferingGrab(rClient(other), pDev, pEvents))
- continue;
-
- mask = GetEventMask(pDev, pEvents, other);
-
- if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
- pEvents, count))
- /* do nothing */;
- else if ( (attempt = TryClientEvents(rClient(other), pDev,
- pEvents, count,
- mask, filter, grab)) )
- {
- if (attempt > 0)
- {
- deliveries++;
- client = rClient(other);
- deliveryMask = mask;
- } else
- nondeliveries--;
- }
+ case EVENT_SKIP:
+ return 0;
+ case EVENT_REJECTED:
+ nondeliveries--;
+ break;
+ case EVENT_DELIVERED:
+ deliveries++;
+ break;
+ case EVENT_NOT_DELIVERED:
+ break;
}
}
+
/*
* Note that since core events are delivered first, an implicit grab may
* be activated on a core grab, stopping the XI events.