[PATCH 21/42] Xi: allow selecting for touch events

Peter Hutterer peter.hutterer at who-t.net
Wed Dec 14 19:01:58 PST 2011


From: Daniel Stone <daniel at fooishbar.org>

Selecting for any of XI_TouchBegin/Update/End/Ownership requires the three
bits for begin/update/end to be set.

Only one client at a time may select for XI_TouchBegin event

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 Xi/xiselectev.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 815a34f..1b6c47a 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -155,6 +155,49 @@ ProcXISelectEvents(ClientPtr client)
             }
         }
 
+        if (evmask->mask_len >= 1)
+        {
+            unsigned char *bits = (unsigned char*)&evmask[1];
+
+            /* All three touch events must be selected at once */
+            if ((BitIsOn(bits, XI_TouchBegin) ||
+                 BitIsOn(bits, XI_TouchUpdate) ||
+                 BitIsOn(bits, XI_TouchOwnership) ||
+                 BitIsOn(bits, XI_TouchEnd)) &&
+                (!BitIsOn(bits, XI_TouchBegin) ||
+                 !BitIsOn(bits, XI_TouchUpdate) ||
+                 !BitIsOn(bits, XI_TouchEnd)))
+            {
+                client->errorValue = XI_TouchBegin;
+                return BadValue;
+            }
+
+            /* Only one client per window may select for touch events on the
+             * same devices, including master devices.
+             * XXX: This breaks if a device goes from floating to attached. */
+            if (BitIsOn(bits, XI_TouchBegin))
+            {
+                OtherInputMasks *inputMasks = wOtherInputMasks(win);
+                InputClients *iclient = NULL;
+                if (inputMasks)
+                    iclient = inputMasks->inputClients;
+                for (; iclient; iclient = iclient->next)
+                {
+                    DeviceIntPtr dummy;
+
+                    if (CLIENT_ID(iclient->resource) == client->index)
+                        continue;
+
+                    dixLookupDevice(&dummy, evmask->deviceid, serverClient, DixReadAccess);
+                    if (!dummy)
+                        return BadImplementation; /* this shouldn't happen */
+
+                    if (xi2mask_isset(iclient->xi2mask, dummy, XI_TouchBegin))
+                        return BadAccess;
+                }
+            }
+        }
+
         if (XICheckInvalidMaskBits(client, (unsigned char*)&evmask[1],
                                    evmask->mask_len * 4) != Success)
             return BadValue;
-- 
1.7.7.1



More information about the xorg-devel mailing list