aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi')
-rw-r--r--xorg-server/Xi/exevents.c57
-rw-r--r--xorg-server/Xi/xiselectev.c80
2 files changed, 89 insertions, 48 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 2caf98c25..4c1aeb4da 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -1409,7 +1409,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
ptrev->device_event.corestate = event_get_corestate(dev, kbd);
if (grab) {
- /* this side-steps the usual activation mechansims, but... */
+ /* this side-steps the usual activation mechanisms, but... */
if (ev->any.type == ET_TouchBegin && !dev->deviceGrab.grab)
ActivatePassiveGrab(dev, grab, ptrev, ev); /* also delivers the event */
else {
@@ -1566,32 +1566,41 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
else
ti = TouchFindByClientID(dev, touchid);
- /* Under the following circumstances we create a new touch record for an
- * existing touch:
- *
- * - The touch may be pointer emulated
- * - An explicit grab is active on the device
- * - The grab is a pointer grab
- *
- * This allows for an explicit grab to receive pointer events for an already
- * active touch.
- */
- if (!ti && type != ET_TouchBegin && emulate_pointer &&
- dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
+ /* Active pointer grab */
+ if (emulate_pointer && dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
(dev->deviceGrab.grab->grabtype == CORE ||
dev->deviceGrab.grab->grabtype == XI ||
- !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) {
- ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
- emulate_pointer);
- if (!ti) {
- DebugF("[Xi] %s: Failed to create new dix record for explicitly "
- "grabbed touchpoint %d\n",
- dev->name, touchid);
- return;
- }
+ !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)))
+ {
+ /* Active pointer grab on touch point and we get a TouchEnd - claim this
+ * touchpoint accepted, otherwise clients waiting for ownership will
+ * wait on this touchpoint until this client ungrabs, or the cows come
+ * home, whichever is earlier */
+ if (ti && type == ET_TouchEnd)
+ TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
+ else if (!ti && type != ET_TouchBegin) {
+ /* Under the following circumstances we create a new touch record for an
+ * existing touch:
+ *
+ * - The touch may be pointer emulated
+ * - An explicit grab is active on the device
+ * - The grab is a pointer grab
+ *
+ * This allows for an explicit grab to receive pointer events for an already
+ * active touch.
+ */
+ ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
+ emulate_pointer);
+ if (!ti) {
+ DebugF("[Xi] %s: Failed to create new dix record for explicitly "
+ "grabbed touchpoint %d\n",
+ dev->name, touchid);
+ return;
+ }
- TouchBuildSprite(dev, ti, ev);
- TouchSetupListeners(dev, ti, ev);
+ TouchBuildSprite(dev, ti, ev);
+ TouchSetupListeners(dev, ti, ev);
+ }
}
if (!ti) {
diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c
index ab1b6245f..45a996e4c 100644
--- a/xorg-server/Xi/xiselectev.c
+++ b/xorg-server/Xi/xiselectev.c
@@ -37,6 +37,57 @@
#include "xiselectev.h"
/**
+ * Ruleset:
+ * - if A has XIAllDevices, B may select on device X
+ * - If A has XIAllDevices, B may select on XIAllMasterDevices
+ * - If A has XIAllMasterDevices, B may select on device X
+ * - If A has XIAllMasterDevices, B may select on XIAllDevices
+ * - if A has device X, B may select on XIAllDevices/XIAllMasterDevices
+ */
+static int check_for_touch_selection_conflicts(ClientPtr B, WindowPtr win, int deviceid)
+{
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ InputClients *A = NULL;
+
+ if (inputMasks)
+ A = inputMasks->inputClients;
+ for (; A; A = A->next) {
+ DeviceIntPtr tmp;
+
+ if (CLIENT_ID(A->resource) == B->index)
+ continue;
+
+ if (deviceid == XIAllDevices)
+ tmp = inputInfo.all_devices;
+ else if (deviceid == XIAllMasterDevices)
+ tmp = inputInfo.all_master_devices;
+ else
+ dixLookupDevice(&tmp, deviceid, serverClient, DixReadAccess);
+ if (!tmp)
+ return BadImplementation; /* this shouldn't happen */
+
+ /* A has XIAllDevices */
+ if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_devices, XI_TouchBegin)) {
+ if (deviceid == XIAllDevices)
+ return BadAccess;
+ }
+
+ /* A has XIAllMasterDevices */
+ if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_master_devices, XI_TouchBegin)) {
+ if (deviceid == XIAllMasterDevices)
+ return BadAccess;
+ }
+
+ /* A has this device */
+ if (xi2mask_isset_for_device(A->xi2mask, tmp, XI_TouchBegin))
+ return BadAccess;
+ }
+
+ return Success;
+}
+
+
+/**
* Check the given mask (in len bytes) for invalid mask bits.
* Invalid mask bits are any bits above XI2LastEvent.
*
@@ -169,30 +220,11 @@ ProcXISelectEvents(ClientPtr client)
* 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 tmp;
-
- if (CLIENT_ID(iclient->resource) == client->index)
- continue;
-
- if (evmask->deviceid == XIAllDevices)
- tmp = inputInfo.all_devices;
- else if (evmask->deviceid == XIAllMasterDevices)
- tmp = inputInfo.all_master_devices;
- else
- dixLookupDevice(&tmp, evmask->deviceid, serverClient,
- DixReadAccess);
- if (!tmp)
- return BadImplementation; /* this shouldn't happen */
-
- if (xi2mask_isset(iclient->xi2mask, tmp, XI_TouchBegin))
- return BadAccess;
- }
+ rc = check_for_touch_selection_conflicts(client,
+ win,
+ evmask->deviceid);
+ if (rc != Success)
+ return rc;
}
}