Currently pointer arbitration is taken care of through the use of
a 'wcomPenInProx' variable in the WacomCommonRec. If two devices
share a 'common' variable, the commonDispatchDevice function will
ensure that touches do not move the pointer while the pen is in
proximity.

This patch adds support for cross-device pointer arbitration to
prevent other touches known to the driver from moving the pointer.
This is achieved with the introduction of a 'WACOM_DRIVER' structure
that is shared by all tools. Inside this structure is an 'active'
variable that keeps track of the last tool which was actively
controlling the pointer. When an event from any tool comes in, the
driver will attempt to determine if it should be filtered or not.
In some cases, the new device will be allowed to take control of
the pointer, and become the new active device.

Note that arbitration occurs *after* we store the device state
to pChannel->valid.state. The code in wcmTouchFilter.c assumes
that states are not missing, and can become desynchronized from
reality if (for example) a finger were to go out of prox without
a corresponding state update.

Signed-off-by: Jason Gerecke <killert...@gmail.com>
---
 src/wcmCommon.c     | 69 ++++++++++++++++++++++++++++++++++++-----------------
 src/xf86WacomDefs.h |  8 ++++++-
 2 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index 5bcd755..4e7098a 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -28,6 +28,11 @@
 #include <xkbsrv.h>
 #include <xf86_OSproc.h>
 
+
+struct _WacomDriverRec WACOM_DRIVER = {
+       .active = NULL,
+};
+
 /* X servers pre 1.9 didn't copy data passed into xf86Post*Event.
  * Data passed in would be modified, requiring the driver to copy the
  * data beforehand.
@@ -832,6 +837,34 @@ static WacomToolPtr findTool(const WacomCommonPtr common,
        return tool;
 }
 
+/**
+ * Check if the given device should grab control of the pointer in
+ * preference to whatever tool currently has access.
+ *
+ * @param pInfo  The device to check for access
+ * @param ds     The current state of the device
+ * @returns      'TRUE' if control of the pointer should be granted, FALSE 
otherwise
+ */
+static Bool check_arbitrated_control(InputInfoPtr pInfo, WacomDeviceStatePtr 
ds)
+{
+       WacomDevicePtr active = WACOM_DRIVER.active;
+       WacomDevicePtr priv = pInfo->private;
+
+       if (active == NULL || active->oldState.device_id == ds->device_id) {
+               //DBG(-1, priv, "Same device ID as active; allowing access.\n");
+               return TRUE;
+       }
+
+       if (IsPad(priv)) {
+               // Pad may never be the "active" pointer controller
+               return FALSE;
+       }
+       else {
+               // EMR events may take control from touch at any time
+               return !IsTouch(priv);
+       }
+}
+
 /*****************************************************************************
  * wcmEvent -
  *   Handles suppression, transformation, filtering, and event dispatch.
@@ -933,6 +966,20 @@ void wcmEvent(WacomCommonPtr common, unsigned int channel,
        pChannel->valid.state = ds; /*save last raw sample */
        if (pChannel->nSamples < common->wcmRawSample) ++pChannel->nSamples;
 
+       /* arbitrate pointer control */
+       if (check_arbitrated_control(pInfo, &ds)) {
+               if (WACOM_DRIVER.active != NULL && priv != WACOM_DRIVER.active) 
{
+                       wcmSoftOutEvent(WACOM_DRIVER.active->pInfo);
+               }
+               if (ds.proximity)
+                       WACOM_DRIVER.active = priv;
+               else
+                       WACOM_DRIVER.active = NULL;
+       }
+       else if (!IsPad(priv)) {
+               return;
+       }
+
        if ((ds.device_type == TOUCH_ID) && common->wcmTouch)
        {
                wcmGestureFilter(priv, ds.serial_num - 1);
@@ -1125,28 +1172,6 @@ static void commonDispatchDevice(InputInfoPtr pInfo,
                return;
        }
 
-       if (TabletHasFeature(common, WCM_PENTOUCH))
-       {
-               if (IsTablet(priv))
-               {
-                       common->wcmTouchDevice->common->wcmPenInProx = 
filtered.proximity;
-
-                       /* send touch out when tablet tool coming in-prox for
-                        * devices that provide both pen/puck and touch events
-                        * so system cursor won't jump between tools.
-                        */
-                       if (common->wcmTouchDevice->oldState.proximity)
-                       {
-                               common->wcmGestureMode = 0;
-                               wcmSoftOutEvent(common->wcmTouchDevice->pInfo);
-                               return;
-                       }
-               }
-               else if (IsTouch(priv) && common->wcmPenInProx)
-                       /* Ignore touch events when tablet tool is in prox */
-                       return;
-       }
-
        if ((IsPen(priv) || IsTouch(priv)) && common->wcmMaxZ)
        {
                int prev_min_pressure = priv->oldState.proximity ? 
priv->minPressure : 0;
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 9b81fe0..af1df4e 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -378,6 +378,12 @@ enum WacomProtocol {
        WCM_PROTOCOL_5
 };
 
+struct _WacomDriverRec
+{
+       WacomDevicePtr active;     /* Arbitrate motion through this pointer */
+};
+extern struct _WacomDriverRec WACOM_DRIVER; // Defined in wcmCommon.c
+
 struct _WacomCommonRec 
 {
        /* Do not move device_path, same offset as priv->name. Used by DBG 
macro */
@@ -393,7 +399,7 @@ struct _WacomCommonRec
        unsigned long wcmKeys[NBITS(KEY_MAX)]; /* supported tool types for the 
device */
        WacomDevicePtr wcmTouchDevice; /* The pointer for pen to access the
                                          touch tool of the same device id */
-       Bool wcmPenInProx;      /* Keep pen in-prox state for touch tool */
+
        Bool wcmHasHWTouchSwitch;    /* Tablet has a touch on/off switch */
        int wcmHWTouchSwitchState;   /* touch event disable/enabled by hardware 
switch */
 
-- 
2.0.2


------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to