It appears that some software may not be entirely compatible with the
expanded 65K pressure level range that was introduced in version 0.34.0.
Although our driver advertises the larger range in XI2 (and toolkits
like GTK+2/3 and Qt3/4/5 make use of it), there have been reports of
other software (e.g. The Foundry's "NUKE") misbehaving.

As a workaround, this patch introduces a new boolean config option named
"Pressure2K". If enabled, it causes the driver to revert to its prior
behavior of using a pressure range of 0-2047. This option is disabled by
default, but can be turned on by adding the following configuration
snippet to a new file in the /etc/X11/xorg.conf.d directory:

Section "InputClass"
    Identifier "Wacom pressure compatibility"
    MatchDriver "wacom"
    Option "Pressure2K" "true"
EndSection

Ref: https://sourceforge.net/p/linuxwacom/mailman/message/35857403/
Ref: 3e56ce4429 (Increase full-scale pressure range from 0..2047 to 0..65535)
Signed-off-by: Jason Gerecke <jason.gere...@wacom.com>
---
 src/wcmCommon.c         | 16 ++++++++--------
 src/wcmConfig.c         |  1 +
 src/wcmFilter.c         |  2 +-
 src/wcmValidateDevice.c |  4 ++++
 src/wcmXCommand.c       | 22 ++++++++++++----------
 src/xf86Wacom.c         |  2 +-
 src/xf86WacomDefs.h     |  5 +++--
 7 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index f6cfd3d..dc6ecbd 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -1056,7 +1056,7 @@ rebasePressure(const WacomDevicePtr priv, const 
WacomDeviceState *ds)
 
 /**
  * Instead of reporting the raw pressure, we normalize
- * the pressure from 0 to FILTER_PRESSURE_RES. This is
+ * the pressure from 0 to maxCurve. This is
  * mainly to deal with the case where heavily used
  * stylus may have a "pre-loaded" initial pressure. To
  * do so, we keep the in-prox pressure and subtract it
@@ -1081,14 +1081,14 @@ normalizePressure(const WacomDevicePtr priv, const int 
raw_pressure)
                p -= priv->minPressure;
                range_left -= priv->minPressure;
        }
-       /* normalize pressure to 0..FILTER_PRESSURE_RES */
+       /* normalize pressure to 0..maxCurve */
        if (range_left >= 1)
                pressure = xf86ScaleAxis(p,
-                                        FILTER_PRESSURE_RES, 0,
+                                        priv->maxCurve, 0,
                                         range_left,
                                         0);
        else
-               pressure = FILTER_PRESSURE_RES;
+               pressure = priv->maxCurve;
 
        return (int)pressure;
 }
@@ -1117,8 +1117,8 @@ setPressureButton(const WacomDevicePtr priv, int buttons, 
const int pressure)
                {
                        /* don't set it off if it is within the tolerance
                           and threshold is larger than the tolerance */
-                       if ((common->wcmThreshold > THRESHOLD_TOLERANCE) &&
-                           (pressure > common->wcmThreshold - 
THRESHOLD_TOLERANCE))
+                       if ((common->wcmThreshold > (priv->maxCurve * 
THRESHOLD_TOLERANCE)) &&
+                           (pressure > common->wcmThreshold - (priv->maxCurve 
* THRESHOLD_TOLERANCE)))
                                buttons |= button;
                }
        }
@@ -1350,7 +1350,7 @@ int wcmInitTablet(InputInfoPtr pInfo, const char* id, 
float version)
        if (common->wcmThreshold <= 0 && IsPen(priv))
        {
                /* Threshold for counting pressure as a button */
-               common->wcmThreshold = DEFAULT_THRESHOLD;
+               common->wcmThreshold = priv->maxCurve * DEFAULT_THRESHOLD;
 
                xf86Msg(X_PROBED, "%s: using pressure threshold of %d for 
button 1\n",
                        pInfo->name, common->wcmThreshold);
@@ -1401,7 +1401,7 @@ static int applyPressureCurve(WacomDevicePtr pDev, const 
WacomDeviceStatePtr pSt
        /* clip the pressure */
        int p = max(0, pState->pressure);
 
-       p = min(FILTER_PRESSURE_RES, p);
+       p = min(pDev->maxCurve, p);
 
        /* apply pressure curve function */
        if (pDev->pPressCurve == NULL)
diff --git a/src/wcmConfig.c b/src/wcmConfig.c
index 0924c43..6b269bb 100644
--- a/src/wcmConfig.c
+++ b/src/wcmConfig.c
@@ -63,6 +63,7 @@ static int wcmAllocate(InputInfoPtr pInfo)
        priv->pInfo = pInfo;
        priv->common = common;       /* common info pointer */
        priv->oldCursorHwProx = 0;   /* previous cursor hardware proximity */
+       priv->maxCurve = FILTER_PRESSURE_RES;
        priv->nPressCtrl [0] = 0;    /* pressure curve x0 */
        priv->nPressCtrl [1] = 0;    /* pressure curve y0 */
        priv->nPressCtrl [2] = 100;  /* pressure curve x1 */
diff --git a/src/wcmFilter.c b/src/wcmFilter.c
index aca5cd9..e7ddb37 100644
--- a/src/wcmFilter.c
+++ b/src/wcmFilter.c
@@ -78,7 +78,7 @@ void wcmSetPressureCurve(WacomDevicePtr pDev, int x0, int y0,
 
        if (pDev->pPressCurve)
                filterCurveToLine(pDev->pPressCurve,
-                               FILTER_PRESSURE_RES,
+                               pDev->maxCurve,
                                0.0, 0.0,               /* bottom left  */
                                x0/100.0, y0/100.0,     /* control point 1 */
                                x1/100.0, y1/100.0,     /* control point 2 */
diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
index 0b8387c..61acefd 100644
--- a/src/wcmValidateDevice.c
+++ b/src/wcmValidateDevice.c
@@ -866,6 +866,10 @@ Bool wcmPreInitParseOptions(InputInfoPtr pInfo, Bool 
is_primary,
                        wcmSetPressureCurve(priv,a,b,c,d);
        }
        free(s);
+       if (xf86SetBoolOption(pInfo->options, "Pressure2K", 0)) {
+               xf86Msg(X_CONFIG, "%s: Using 2K pressure levels\n", 
pInfo->name);
+               priv->maxCurve = 2048;
+       }
 
        /*Serials of tools we want hotpluged*/
        if (wcmParseSerials (pInfo) != 0)
diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c
index 0e1d657..e18fb8f 100644
--- a/src/wcmXCommand.c
+++ b/src/wcmXCommand.c
@@ -106,21 +106,23 @@ static Atom prop_debuglevels;
 /**
  * Calculate a user-visible pressure level from a driver-internal pressure
  * level. Pressure settings exposed to the user assume a range of 0-2047
- * while the driver scales everything to a range of 0-FILTER_PRESSURE_RES.
+ * while the driver scales everything to a range of 0-maxCurve.
  */
-static inline int wcmInternalToUserPressure(int pressure)
+static inline int wcmInternalToUserPressure(InputInfoPtr pInfo, int pressure)
 {
-       return pressure / (FILTER_PRESSURE_RES / 2048);
+       WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
+       return pressure / (priv->maxCurve / 2048);
 }
 
 /**
  * Calculate a driver-internal pressure level from a user-visible pressure
  * level. Pressure settings exposed to the user assume a range of 0-2047
- * while the driver scales everything to a range of 0-FILTER_PRESSURE_RES.
+ * while the driver scales everything to a range of 0-maxCurve.
  */
-static inline int wcmUserToInternalPressure(int pressure)
+static inline int wcmUserToInternalPressure(InputInfoPtr pInfo, int pressure)
 {
-       return pressure * (FILTER_PRESSURE_RES / 2048);
+       WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
+       return pressure * (priv->maxCurve / 2048);
 }
 
 /**
@@ -276,7 +278,7 @@ void InitWcmDeviceProperties(InputInfoPtr pInfo)
        }
 
        values[0] = (!common->wcmMaxZ) ? 0 : common->wcmThreshold;
-       values[0] = wcmInternalToUserPressure(values[0]);
+       values[0] = wcmInternalToUserPressure(pInfo, values[0]);
        prop_threshold = InitWcmAtom(pInfo->dev, WACOM_PROP_PRESSURE_THRESHOLD, 
XA_INTEGER, 32, 1, values);
 
        values[0] = common->wcmSuppress;
@@ -846,7 +848,7 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, 
XIPropertyValuePtr prop,
                        common->wcmCursorProxoutDist = value;
        } else if (property == prop_threshold)
        {
-               const INT32 MAXIMUM = 
wcmInternalToUserPressure(FILTER_PRESSURE_RES);
+               const INT32 MAXIMUM = wcmInternalToUserPressure(pInfo, 
priv->maxCurve);
                INT32 value;
 
                if (prop->size != 1 || prop->format != 32)
@@ -855,11 +857,11 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, 
XIPropertyValuePtr prop,
                value = *(INT32*)prop->data;
 
                if (value == -1)
-                       value = DEFAULT_THRESHOLD;
+                       value = priv->maxCurve * DEFAULT_THRESHOLD;
                else if ((value < 1) || (value > MAXIMUM))
                        return BadValue;
                else
-                       value = wcmUserToInternalPressure(value);
+                       value = wcmUserToInternalPressure(pInfo, value);
 
                if (!checkonly)
                        common->wcmThreshold = value;
diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c
index a511fd2..738690f 100644
--- a/src/xf86Wacom.c
+++ b/src/xf86Wacom.c
@@ -200,7 +200,7 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
        if (!IsPad(priv))
        {
                label = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
-               max = FILTER_PRESSURE_RES;
+               max = priv->maxCurve;
        }
 
        wcmInitAxis(pInfo->dev, index, label, min, max, res, min_res, max_res, 
mode);
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index b10a114..ec34211 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -182,8 +182,8 @@ struct _WacomModel
 
 #define FILTER_PRESSURE_RES    65536   /* maximum points in pressure curve */
 /* Tested result for setting the pressure threshold to a reasonable value */
-#define THRESHOLD_TOLERANCE (FILTER_PRESSURE_RES / 125)
-#define DEFAULT_THRESHOLD (FILTER_PRESSURE_RES / 75)
+#define THRESHOLD_TOLERANCE (0.008f)
+#define DEFAULT_THRESHOLD (0.013f)
 
 #define WCM_MAX_BUTTONS                32      /* maximum number of tablet 
buttons */
 #define WCM_MAX_X11BUTTON      127     /* maximum button number X11 can handle 
*/
@@ -285,6 +285,7 @@ struct _WacomDeviceRec
        struct _WacomDeviceState oldState; /* previous state information */
        int oldCursorHwProx;    /* previous cursor hardware proximity */
 
+       int maxCurve;           /* maximum pressure curve value */
        int *pPressCurve;       /* pressure curve */
        int nPressCtrl[4];      /* control points for curve */
        int minPressure;        /* the minimum pressure a pen may hold */
-- 
2.13.0


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to