Blame SOURCES/0001-Introduce-Pressure2K-config-option-for-incompatible-.patch

2ff16f
From d958ab79d21b57141415650daac88f9369a1c861 Mon Sep 17 00:00:00 2001
2ff16f
From: Jason Gerecke <killertofu@gmail.com>
2ff16f
Date: Wed, 31 May 2017 10:57:12 +1000
2ff16f
Subject: [PATCH] Introduce "Pressure2K" config option for incompatible
2ff16f
 software
2ff16f
2ff16f
It appears that some software may not be entirely compatible with the
2ff16f
expanded 65K pressure level range that was introduced in version 0.34.0.
2ff16f
Although our driver advertises the larger range in XI2 (and toolkits
2ff16f
like GTK+2/3 and Qt3/4/5 make use of it), there have been reports of
2ff16f
other software (e.g. The Foundry's "NUKE") misbehaving.
2ff16f
2ff16f
As a workaround, this patch introduces a new boolean config option named
2ff16f
"Pressure2K". If enabled, it causes the driver to revert to its prior
2ff16f
behavior of using a pressure range of 0-2047. This option is disabled by
2ff16f
default, but can be turned on by adding the following configuration
2ff16f
snippet to a new file in the /etc/X11/xorg.conf.d directory:
2ff16f
2ff16f
Section "InputClass"
2ff16f
    Identifier "Wacom pressure compatibility"
2ff16f
    MatchDriver "wacom"
2ff16f
    Option "Pressure2K" "true"
2ff16f
EndSection
2ff16f
2ff16f
Ref: https://sourceforge.net/p/linuxwacom/mailman/message/35857403/
2ff16f
Ref: 3e56ce4429 (Increase full-scale pressure range from 0..2047 to 0..65535)
2ff16f
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
2ff16f
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
2ff16f
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2ff16f
---
2ff16f
 man/wacom.man           | 21 +++++++++++++++++++++
2ff16f
 src/wcmCommon.c         | 16 ++++++++--------
2ff16f
 src/wcmConfig.c         |  1 +
2ff16f
 src/wcmFilter.c         |  2 +-
2ff16f
 src/wcmValidateDevice.c |  5 +++++
2ff16f
 src/wcmXCommand.c       | 22 ++++++++++++----------
2ff16f
 src/xf86Wacom.c         |  2 +-
2ff16f
 src/xf86WacomDefs.h     |  5 +++--
2ff16f
 8 files changed, 52 insertions(+), 22 deletions(-)
2ff16f
2ff16f
diff --git a/man/wacom.man b/man/wacom.man
2ff16f
index cd33438..3693c94 100644
2ff16f
--- a/man/wacom.man
2ff16f
+++ b/man/wacom.man
2ff16f
@@ -185,6 +185,14 @@ slightly raised curve (softer) might be "0,5,95,100".
2ff16f
 The pressure curve is only applicable to devices of type stylus or eraser,
2ff16f
 other devices do not honor this setting.
2ff16f
 .TP 4
2ff16f
+.B Option \fI"Pressure2K"\fP \fI"bool"\fP
2ff16f
+reduces the pressure range to the range of 0 to 2048 for backwards
2ff16f
+compatibility with applications that have this range hardcoded.
2ff16f
+See section
2ff16f
+.B BUGS.
2ff16f
+This option should not be used unless the user runs one or more
2ff16f
+applications that rely on a hardcoded pressure range.
2ff16f
+.TP 4
2ff16f
 .B Option \fI"DebugLevel"\fP \fI"number"\fP
2ff16f
 sets the level of debugging info for tool-specific messages.  There are 12
2ff16f
 levels, specified by the integers between 1 and 12.  All debug messages with
2ff16f
@@ -303,6 +311,19 @@ two separated fingers side by side, bring together i.e. pinch.
2ff16f
 \fBZoom out:\fR
2ff16f
 two fingers side by side, spread.  Not all applications support zoom.
2ff16f
 .PP
2ff16f
+.SH "BUGS"
2ff16f
+.SS "Pressure range increase leads to unexpected behavior"
2ff16f
+In version 0.34, the driver's pressure range increased from
2ff16f
+2048 steps to 65536 steps. The pressure axis range is advertised through the
2ff16f
+X Input Protocol but some applications have the previous pressure range
2ff16f
+hardcoded and cannot handle pressure values above 2048. This is an
2ff16f
+application bug but for backwards-compatibility with such applications, this
2ff16f
+driver provides the
2ff16f
+.B Pressure2K
2ff16f
+option to reduce the range to 2048 steps. Note that this setting applies to
2ff16f
+the device. Once applied, all applications will see the reduced pressure
2ff16f
+range. It is not possible to provide this setting on a per-application
2ff16f
+basis.
2ff16f
 .SH "SEE ALSO"
2ff16f
 __xservername__(__appmansuffix__), xorg.conf(__filemansuffix__),
2ff16f
 xorg.conf.d(__filemansuffix__), X(__miscmansuffix__)
2ff16f
diff --git a/src/wcmCommon.c b/src/wcmCommon.c
2ff16f
index f6cfd3d..dc6ecbd 100644
2ff16f
--- a/src/wcmCommon.c
2ff16f
+++ b/src/wcmCommon.c
2ff16f
@@ -1056,7 +1056,7 @@ rebasePressure(const WacomDevicePtr priv, const WacomDeviceState *ds)
2ff16f
 
2ff16f
 /**
2ff16f
  * Instead of reporting the raw pressure, we normalize
2ff16f
- * the pressure from 0 to FILTER_PRESSURE_RES. This is
2ff16f
+ * the pressure from 0 to maxCurve. This is
2ff16f
  * mainly to deal with the case where heavily used
2ff16f
  * stylus may have a "pre-loaded" initial pressure. To
2ff16f
  * do so, we keep the in-prox pressure and subtract it
2ff16f
@@ -1081,14 +1081,14 @@ normalizePressure(const WacomDevicePtr priv, const int raw_pressure)
2ff16f
 		p -= priv->minPressure;
2ff16f
 		range_left -= priv->minPressure;
2ff16f
 	}
2ff16f
-	/* normalize pressure to 0..FILTER_PRESSURE_RES */
2ff16f
+	/* normalize pressure to 0..maxCurve */
2ff16f
 	if (range_left >= 1)
2ff16f
 		pressure = xf86ScaleAxis(p,
2ff16f
-					 FILTER_PRESSURE_RES, 0,
2ff16f
+					 priv->maxCurve, 0,
2ff16f
 					 range_left,
2ff16f
 					 0);
2ff16f
 	else
2ff16f
-		pressure = FILTER_PRESSURE_RES;
2ff16f
+		pressure = priv->maxCurve;
2ff16f
 
2ff16f
 	return (int)pressure;
2ff16f
 }
2ff16f
@@ -1117,8 +1117,8 @@ setPressureButton(const WacomDevicePtr priv, int buttons, const int pressure)
2ff16f
 		{
2ff16f
 			/* don't set it off if it is within the tolerance
2ff16f
 			   and threshold is larger than the tolerance */
2ff16f
-			if ((common->wcmThreshold > THRESHOLD_TOLERANCE) &&
2ff16f
-			    (pressure > common->wcmThreshold - THRESHOLD_TOLERANCE))
2ff16f
+			if ((common->wcmThreshold > (priv->maxCurve * THRESHOLD_TOLERANCE)) &&
2ff16f
+			    (pressure > common->wcmThreshold - (priv->maxCurve * THRESHOLD_TOLERANCE)))
2ff16f
 				buttons |= button;
2ff16f
 		}
2ff16f
 	}
2ff16f
@@ -1350,7 +1350,7 @@ int wcmInitTablet(InputInfoPtr pInfo, const char* id, float version)
2ff16f
 	if (common->wcmThreshold <= 0 && IsPen(priv))
2ff16f
 	{
2ff16f
 		/* Threshold for counting pressure as a button */
2ff16f
-		common->wcmThreshold = DEFAULT_THRESHOLD;
2ff16f
+		common->wcmThreshold = priv->maxCurve * DEFAULT_THRESHOLD;
2ff16f
 
2ff16f
 		xf86Msg(X_PROBED, "%s: using pressure threshold of %d for button 1\n",
2ff16f
 			pInfo->name, common->wcmThreshold);
2ff16f
@@ -1401,7 +1401,7 @@ static int applyPressureCurve(WacomDevicePtr pDev, const WacomDeviceStatePtr pSt
2ff16f
 	/* clip the pressure */
2ff16f
 	int p = max(0, pState->pressure);
2ff16f
 
2ff16f
-	p = min(FILTER_PRESSURE_RES, p);
2ff16f
+	p = min(pDev->maxCurve, p);
2ff16f
 
2ff16f
 	/* apply pressure curve function */
2ff16f
 	if (pDev->pPressCurve == NULL)
2ff16f
diff --git a/src/wcmConfig.c b/src/wcmConfig.c
2ff16f
index 0924c43..6b269bb 100644
2ff16f
--- a/src/wcmConfig.c
2ff16f
+++ b/src/wcmConfig.c
2ff16f
@@ -63,6 +63,7 @@ static int wcmAllocate(InputInfoPtr pInfo)
2ff16f
 	priv->pInfo = pInfo;
2ff16f
 	priv->common = common;       /* common info pointer */
2ff16f
 	priv->oldCursorHwProx = 0;   /* previous cursor hardware proximity */
2ff16f
+	priv->maxCurve = FILTER_PRESSURE_RES;
2ff16f
 	priv->nPressCtrl [0] = 0;    /* pressure curve x0 */
2ff16f
 	priv->nPressCtrl [1] = 0;    /* pressure curve y0 */
2ff16f
 	priv->nPressCtrl [2] = 100;  /* pressure curve x1 */
2ff16f
diff --git a/src/wcmFilter.c b/src/wcmFilter.c
2ff16f
index aca5cd9..e7ddb37 100644
2ff16f
--- a/src/wcmFilter.c
2ff16f
+++ b/src/wcmFilter.c
2ff16f
@@ -78,7 +78,7 @@ void wcmSetPressureCurve(WacomDevicePtr pDev, int x0, int y0,
2ff16f
 
2ff16f
 	if (pDev->pPressCurve)
2ff16f
 		filterCurveToLine(pDev->pPressCurve,
2ff16f
-				FILTER_PRESSURE_RES,
2ff16f
+				pDev->maxCurve,
2ff16f
 				0.0, 0.0,               /* bottom left  */
2ff16f
 				x0/100.0, y0/100.0,     /* control point 1 */
2ff16f
 				x1/100.0, y1/100.0,     /* control point 2 */
2ff16f
diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
2ff16f
index d2a7723..0da5076 100644
2ff16f
--- a/src/wcmValidateDevice.c
2ff16f
+++ b/src/wcmValidateDevice.c
2ff16f
@@ -875,6 +875,11 @@ Bool wcmPreInitParseOptions(InputInfoPtr pInfo, Bool is_primary,
2ff16f
 	}
2ff16f
 	free(s);
2ff16f
 
2ff16f
+	if (xf86SetBoolOption(pInfo->options, "Pressure2K", 0)) {
2ff16f
+		xf86Msg(X_CONFIG, "%s: Using 2K pressure levels\n", pInfo->name);
2ff16f
+		priv->maxCurve = 2048;
2ff16f
+	}
2ff16f
+
2ff16f
 	/*Serials of tools we want hotpluged*/
2ff16f
 	if (wcmParseSerials (pInfo) != 0)
2ff16f
 		goto error;
2ff16f
diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c
2ff16f
index 0e1d657..e18fb8f 100644
2ff16f
--- a/src/wcmXCommand.c
2ff16f
+++ b/src/wcmXCommand.c
2ff16f
@@ -106,21 +106,23 @@ static Atom prop_debuglevels;
2ff16f
 /**
2ff16f
  * Calculate a user-visible pressure level from a driver-internal pressure
2ff16f
  * level. Pressure settings exposed to the user assume a range of 0-2047
2ff16f
- * while the driver scales everything to a range of 0-FILTER_PRESSURE_RES.
2ff16f
+ * while the driver scales everything to a range of 0-maxCurve.
2ff16f
  */
2ff16f
-static inline int wcmInternalToUserPressure(int pressure)
2ff16f
+static inline int wcmInternalToUserPressure(InputInfoPtr pInfo, int pressure)
2ff16f
 {
2ff16f
-	return pressure / (FILTER_PRESSURE_RES / 2048);
2ff16f
+	WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
2ff16f
+	return pressure / (priv->maxCurve / 2048);
2ff16f
 }
2ff16f
 
2ff16f
 /**
2ff16f
  * Calculate a driver-internal pressure level from a user-visible pressure
2ff16f
  * level. Pressure settings exposed to the user assume a range of 0-2047
2ff16f
- * while the driver scales everything to a range of 0-FILTER_PRESSURE_RES.
2ff16f
+ * while the driver scales everything to a range of 0-maxCurve.
2ff16f
  */
2ff16f
-static inline int wcmUserToInternalPressure(int pressure)
2ff16f
+static inline int wcmUserToInternalPressure(InputInfoPtr pInfo, int pressure)
2ff16f
 {
2ff16f
-	return pressure * (FILTER_PRESSURE_RES / 2048);
2ff16f
+	WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
2ff16f
+	return pressure * (priv->maxCurve / 2048);
2ff16f
 }
2ff16f
 
2ff16f
 /**
2ff16f
@@ -276,7 +278,7 @@ void InitWcmDeviceProperties(InputInfoPtr pInfo)
2ff16f
 	}
2ff16f
 
2ff16f
 	values[0] = (!common->wcmMaxZ) ? 0 : common->wcmThreshold;
2ff16f
-	values[0] = wcmInternalToUserPressure(values[0]);
2ff16f
+	values[0] = wcmInternalToUserPressure(pInfo, values[0]);
2ff16f
 	prop_threshold = InitWcmAtom(pInfo->dev, WACOM_PROP_PRESSURE_THRESHOLD, XA_INTEGER, 32, 1, values);
2ff16f
 
2ff16f
 	values[0] = common->wcmSuppress;
2ff16f
@@ -846,7 +848,7 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
2ff16f
 			common->wcmCursorProxoutDist = value;
2ff16f
 	} else if (property == prop_threshold)
2ff16f
 	{
2ff16f
-		const INT32 MAXIMUM = wcmInternalToUserPressure(FILTER_PRESSURE_RES);
2ff16f
+		const INT32 MAXIMUM = wcmInternalToUserPressure(pInfo, priv->maxCurve);
2ff16f
 		INT32 value;
2ff16f
 
2ff16f
 		if (prop->size != 1 || prop->format != 32)
2ff16f
@@ -855,11 +857,11 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
2ff16f
 		value = *(INT32*)prop->data;
2ff16f
 
2ff16f
 		if (value == -1)
2ff16f
-			value = DEFAULT_THRESHOLD;
2ff16f
+			value = priv->maxCurve * DEFAULT_THRESHOLD;
2ff16f
 		else if ((value < 1) || (value > MAXIMUM))
2ff16f
 			return BadValue;
2ff16f
 		else
2ff16f
-			value = wcmUserToInternalPressure(value);
2ff16f
+			value = wcmUserToInternalPressure(pInfo, value);
2ff16f
 
2ff16f
 		if (!checkonly)
2ff16f
 			common->wcmThreshold = value;
2ff16f
diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c
2ff16f
index a511fd2..738690f 100644
2ff16f
--- a/src/xf86Wacom.c
2ff16f
+++ b/src/xf86Wacom.c
2ff16f
@@ -200,7 +200,7 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
2ff16f
 	if (!IsPad(priv))
2ff16f
 	{
2ff16f
 		label = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
2ff16f
-		max = FILTER_PRESSURE_RES;
2ff16f
+		max = priv->maxCurve;
2ff16f
 	}
2ff16f
 
2ff16f
 	wcmInitAxis(pInfo->dev, index, label, min, max, res, min_res, max_res, mode);
2ff16f
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
2ff16f
index b10a114..ec34211 100644
2ff16f
--- a/src/xf86WacomDefs.h
2ff16f
+++ b/src/xf86WacomDefs.h
2ff16f
@@ -182,8 +182,8 @@ struct _WacomModel
2ff16f
 
2ff16f
 #define FILTER_PRESSURE_RES	65536	/* maximum points in pressure curve */
2ff16f
 /* Tested result for setting the pressure threshold to a reasonable value */
2ff16f
-#define THRESHOLD_TOLERANCE (FILTER_PRESSURE_RES / 125)
2ff16f
-#define DEFAULT_THRESHOLD (FILTER_PRESSURE_RES / 75)
2ff16f
+#define THRESHOLD_TOLERANCE (0.008f)
2ff16f
+#define DEFAULT_THRESHOLD (0.013f)
2ff16f
 
2ff16f
 #define WCM_MAX_BUTTONS		32	/* maximum number of tablet buttons */
2ff16f
 #define WCM_MAX_X11BUTTON	127	/* maximum button number X11 can handle */
2ff16f
@@ -285,6 +285,7 @@ struct _WacomDeviceRec
2ff16f
 	struct _WacomDeviceState oldState; /* previous state information */
2ff16f
 	int oldCursorHwProx;	/* previous cursor hardware proximity */
2ff16f
 
2ff16f
+	int maxCurve;		/* maximum pressure curve value */
2ff16f
 	int *pPressCurve;       /* pressure curve */
2ff16f
 	int nPressCtrl[4];      /* control points for curve */
2ff16f
 	int minPressure;	/* the minimum pressure a pen may hold */
2ff16f
-- 
2ff16f
2.13.0
2ff16f