Re: [Linuxwacom-devel] [PATCH 3/3 v2] Centralize pen and touch arbitration

2011-04-03 Thread Peter Hutterer
On Sun, Apr 03, 2011 at 04:07:38PM -0700, Ping Cheng wrote:
> With the introduction of multi-touch, the chances of getting touch
> events while pen is in prox have been increased. One obvious use
> case is that the touch events could be used for gestures while pen
> is in prox. However, we do not want two cursors compete on the screen.
> 
> Link the pen and touch device once during the initialization stage
> instead of every time when we receive a pen event. Then, centralize
> pen and touch arbitration process so we can store the touch data in
> wcmUSB.c instead of discarding them. The touch events will only be
> ignored if it is a single touch event that causes a cursor movement
> while pen is in prox.
> 
> Some cleanup in wcmUSB.c is needed. It will be considered when we
> make MAX_CHANNEL a dynamic value based on MAX_FINGERS. The
> MAX_FINGERS is going to be the maximum of ABS_MT_SLOT that we
> retrieve from the kernel. That brings us to the state to support
> XInput 2.1 and devices that have dynamic number of fingers.
> 
> Note: this patch is based on the assumption that all devices
> connected to the same system have unique product IDs. That is,
> no two or more identical devices are connected. Identical devices
> will be properly linked when we find a decent way to distinguish
> them in the driver.
> 
> Signed-off-by: Ping Cheng 
> ---
> Changes in v2: unlink touch and pen when at least one of them
> is disabled; fixed an if-statement in ignoring touch when pen is
> in prox; and a few coding style suggestions made by Peter.

both applied, thanks.

Cheers,
  Peter

> 
>  src/wcmCommon.c |   32 +---
>  src/wcmConfig.c |   51 
> +++
>  src/xf86Wacom.c |   43 +++
>  src/xf86WacomDefs.h |4 
>  4 files changed, 111 insertions(+), 19 deletions(-)
> 
> diff --git a/src/wcmCommon.c b/src/wcmCommon.c
> index a370389..fff5a08 100644
> --- a/src/wcmCommon.c
> +++ b/src/wcmCommon.c
> @@ -1138,30 +1138,23 @@ static void commonDispatchDevice(WacomCommonPtr 
> common, unsigned int channel,
>   return;
>   }
>  
> - /* send a touch out for USB Tablet PCs */
> - if (IsUSBDevice(common) && !IsTouch(priv)
> - && common->wcmTouchDefault && !priv->oldProximity)
> + if (TabletHasFeature(common, WCM_PENTOUCH))
>   {
> - InputInfoPtr device = xf86FirstLocalDevice();
> - WacomCommonPtr tempcommon = NULL;
> - WacomDevicePtr temppriv = NULL;
> -
> - /* Lookup to see if associated touch was enabled */
> - for (; device != NULL; device = device->next)
> + if (IsPen(priv))
>   {
> - if (strstr(device->drv->driverName, "wacom"))
> + /* send touch out when pen coming in-prox for devices
> +  * that provideboth pen and touch events so system
> +  * cursor won't jump between tools.
> +  */
> + if (common->wcmTouchDevice->oldProximity)
>   {
> - temppriv = (WacomDevicePtr) device->private;
> - tempcommon = temppriv->common;
> -
> - if ((tempcommon->tablet_id == 
> common->tablet_id) &&
> - IsTouch(temppriv) && 
> temppriv->oldProximity)
> - {
> - /* Send soft prox-out for touch first */
> - wcmSoftOutEvent(device);
> - }
> + wcmSoftOutEvent(common->wcmTouchDevice->pInfo);
> + return;
>   }
>   }
> + else if (IsTouch(priv) && common->wcmPenInProx)
> + /* Ignore touch events when pen is in prox */
> + return;
>   }
>  
>   if (IsPen(priv))
> @@ -1170,6 +1163,7 @@ static void commonDispatchDevice(WacomCommonPtr common, 
> unsigned int channel,
>   filtered.pressure = normalizePressure(priv, &filtered);
>   filtered.buttons = setPressureButton(priv, &filtered);
>   filtered.pressure = applyPressureCurve(priv,&filtered);
> + common->wcmPenInProx = filtered.proximity;
>   }
>  
>   else if (IsCursor(priv) && !priv->oldCursorHwProx)
> diff --git a/src/wcmConfig.c b/src/wcmConfig.c
> index 6235d3c..f989fb0 100644
> --- a/src/wcmConfig.c
> +++ b/src/wcmConfig.c
> @@ -397,6 +397,51 @@ wcmInitModel(InputInfoPtr pInfo)
>   return TRUE;
>  }
>  
> +/**
> + * Link the touch tool to the pen of the same device
> + * so we can arbitrate the events when posting them.
> + */
> +static void wcmLinkTouchAndPen(InputInfoPtr pInfo)
> +{
> + WacomDevicePtr priv = pInfo->private;
> + WacomComm

[Linuxwacom-devel] [PATCH 3/3 v2] Centralize pen and touch arbitration

2011-04-03 Thread Ping Cheng
With the introduction of multi-touch, the chances of getting touch
events while pen is in prox have been increased. One obvious use
case is that the touch events could be used for gestures while pen
is in prox. However, we do not want two cursors compete on the screen.

Link the pen and touch device once during the initialization stage
instead of every time when we receive a pen event. Then, centralize
pen and touch arbitration process so we can store the touch data in
wcmUSB.c instead of discarding them. The touch events will only be
ignored if it is a single touch event that causes a cursor movement
while pen is in prox.

Some cleanup in wcmUSB.c is needed. It will be considered when we
make MAX_CHANNEL a dynamic value based on MAX_FINGERS. The
MAX_FINGERS is going to be the maximum of ABS_MT_SLOT that we
retrieve from the kernel. That brings us to the state to support
XInput 2.1 and devices that have dynamic number of fingers.

Note: this patch is based on the assumption that all devices
connected to the same system have unique product IDs. That is,
no two or more identical devices are connected. Identical devices
will be properly linked when we find a decent way to distinguish
them in the driver.

Signed-off-by: Ping Cheng 
---
Changes in v2: unlink touch and pen when at least one of them
is disabled; fixed an if-statement in ignoring touch when pen is
in prox; and a few coding style suggestions made by Peter.

 src/wcmCommon.c |   32 +---
 src/wcmConfig.c |   51 +++
 src/xf86Wacom.c |   43 +++
 src/xf86WacomDefs.h |4 
 4 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index a370389..fff5a08 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -1138,30 +1138,23 @@ static void commonDispatchDevice(WacomCommonPtr common, 
unsigned int channel,
return;
}
 
-   /* send a touch out for USB Tablet PCs */
-   if (IsUSBDevice(common) && !IsTouch(priv)
-   && common->wcmTouchDefault && !priv->oldProximity)
+   if (TabletHasFeature(common, WCM_PENTOUCH))
{
-   InputInfoPtr device = xf86FirstLocalDevice();
-   WacomCommonPtr tempcommon = NULL;
-   WacomDevicePtr temppriv = NULL;
-
-   /* Lookup to see if associated touch was enabled */
-   for (; device != NULL; device = device->next)
+   if (IsPen(priv))
{
-   if (strstr(device->drv->driverName, "wacom"))
+   /* send touch out when pen coming in-prox for devices
+* that provideboth pen and touch events so system
+* cursor won't jump between tools.
+*/
+   if (common->wcmTouchDevice->oldProximity)
{
-   temppriv = (WacomDevicePtr) device->private;
-   tempcommon = temppriv->common;
-
-   if ((tempcommon->tablet_id == 
common->tablet_id) &&
-   IsTouch(temppriv) && 
temppriv->oldProximity)
-   {
-   /* Send soft prox-out for touch first */
-   wcmSoftOutEvent(device);
-   }
+   wcmSoftOutEvent(common->wcmTouchDevice->pInfo);
+   return;
}
}
+   else if (IsTouch(priv) && common->wcmPenInProx)
+   /* Ignore touch events when pen is in prox */
+   return;
}
 
if (IsPen(priv))
@@ -1170,6 +1163,7 @@ static void commonDispatchDevice(WacomCommonPtr common, 
unsigned int channel,
filtered.pressure = normalizePressure(priv, &filtered);
filtered.buttons = setPressureButton(priv, &filtered);
filtered.pressure = applyPressureCurve(priv,&filtered);
+   common->wcmPenInProx = filtered.proximity;
}
 
else if (IsCursor(priv) && !priv->oldCursorHwProx)
diff --git a/src/wcmConfig.c b/src/wcmConfig.c
index 6235d3c..f989fb0 100644
--- a/src/wcmConfig.c
+++ b/src/wcmConfig.c
@@ -397,6 +397,51 @@ wcmInitModel(InputInfoPtr pInfo)
return TRUE;
 }
 
+/**
+ * Link the touch tool to the pen of the same device
+ * so we can arbitrate the events when posting them.
+ */
+static void wcmLinkTouchAndPen(InputInfoPtr pInfo)
+{
+   WacomDevicePtr priv = pInfo->private;
+   WacomCommonPtr common = priv->common;
+   InputInfoPtr device = xf86FirstLocalDevice();
+   WacomCommonPtr tmpcommon = NULL;
+   WacomDevicePtr tmppriv = NULL;
+   Bool touch_device_assigned = FALSE;
+
+   /* Lookup to fi