X servers pre 1.9 used the data passed in directly and modified it in the
process. A call of e.g.
int valuators[];
xf86PostMotionEventP(..., valuators);
xf86PostButtonEventP(..., valuators);
would thus post garbage data for the button event. Work around this by
copying the valuators before passing them in.
This is only needed for ABI < 11, server 1.9 duplicates the data passed in
before processing.
Signed-off-by: Peter Hutterer <[email protected]>
---
src/wcmCommon.c | 43 +++++++++++++++++++++++++++++++------------
1 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index bf376a9..303be80 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -31,6 +31,23 @@
#define THRESHOLD_TOLERANCE (FILTER_PRESSURE_RES / 125)
#define DEFAULT_THRESHOLD (FILTER_PRESSURE_RES / 75)
+/* 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.
+ */
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 11
+static int *VCOPY(const int *valuators, int nvals)
+{
+ static int v[MAX_VALUATORS];
+ memcpy(v, valuators, nvals * sizeof(int));
+ return v;
+}
+#else /* ABI >= 11 */
+#define VCOPY(vals, nval) (vals)
+#endif
+
+
+
/*****************************************************************************
* Static functions
****************************************************************************/
@@ -273,7 +290,7 @@ static void sendAction(InputInfoPtr pInfo, int press,
xf86PostButtonEventP(pInfo->dev,
is_absolute(pInfo),
btn_no,
is_press,
first_val, num_val,
- valuators);
+ VCOPY(valuators,
num_val));
}
break;
case AC_KEY:
@@ -312,7 +329,8 @@ static void sendAction(InputInfoPtr pInfo, int press,
if (countPresses(btn_no, &keys[i],
nkeys - i))
xf86PostButtonEvent(pInfo->dev,
is_absolute(pInfo), btn_no,
- 0, first_val,
num_val, valuators);
+ 0, first_val,
num_val,
+
VCOPY(valuators, num_val));
}
break;
case AC_KEY:
@@ -355,7 +373,7 @@ static void sendAButton(InputInfoPtr pInfo, int button, int
mask,
{
/* No button action configured, send button */
xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo),
priv->button[button], (mask != 0),
- first_val, num_val, valuators);
+ first_val, num_val, VCOPY(valuators,
num_val));
return;
}
@@ -458,10 +476,10 @@ static void sendWheelStripEvents(InputInfoPtr pInfo,
const WacomDeviceState* ds,
{
/* send both button on/off in the same event for pad */
xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo), fakeButton
& AC_CODE,
- 1, first_val, num_vals, valuators);
+ 1, first_val, num_vals, VCOPY(valuators,
num_vals));
xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo), fakeButton
& AC_CODE,
- 0, first_val, num_vals, valuators);
+ 0, first_val, num_vals, VCOPY(valuators,
num_vals));
return;
}
@@ -720,13 +738,13 @@ void wcmSendEvents(InputInfoPtr pInfo, const
WacomDeviceState* ds)
/* don't emit proximity events if device does not
support proximity */
if ((pInfo->dev->proximity && !priv->oldProximity))
- xf86PostProximityEventP(pInfo->dev, 1, 0,
naxes, valuators);
+ xf86PostProximityEventP(pInfo->dev, 1, 0,
naxes, VCOPY(valuators, naxes));
/* Move the cursor to where it should be before sending
button events */
if(!(priv->flags & BUTTONS_ONLY_FLAG))
{
- xf86PostMotionEventP(pInfo->dev,
is_absolute(pInfo),
- 0, naxes, valuators);
+ xf86PostMotionEventP(pInfo->dev,
is_absolute(pInfo), 0, naxes,
+ VCOPY(valuators, naxes));
/* For relative events, reset the axes as
* we've already moved the device by the
* relative amount. Otherwise, a button
@@ -749,7 +767,7 @@ void wcmSendEvents(InputInfoPtr pInfo, const
WacomDeviceState* ds)
wcmSendButtons(pInfo, buttons, 0, naxes,
valuators);
if (priv->oldProximity)
- xf86PostProximityEventP(pInfo->dev,0, 0, naxes,
valuators);
+ xf86PostProximityEventP(pInfo->dev,0, 0, naxes,
VCOPY(valuators, naxes));
} /* not in proximity */
}
else
@@ -757,7 +775,7 @@ void wcmSendEvents(InputInfoPtr pInfo, const
WacomDeviceState* ds)
int valuators[3] = { v3, v4, v5 };
if (!priv->oldProximity && is_proximity)
- xf86PostProximityEventP(pInfo->dev, 1, 3, 3, valuators);
+ xf86PostProximityEventP(pInfo->dev, 1, 3, 3,
VCOPY(valuators, 3));
if (v3 || v4 || v5 || buttons || ds->relwheel)
{
@@ -766,15 +784,16 @@ void wcmSendEvents(InputInfoPtr pInfo, const
WacomDeviceState* ds)
/* xf86PostMotionEvent is only needed to post the
valuators
* It should NOT move the cursor.
*/
- xf86PostMotionEventP(pInfo->dev, TRUE, 3, 3, valuators);
+ xf86PostMotionEventP(pInfo->dev, TRUE, 3, 3,
VCOPY(valuators, 3));
}
else
{
if (priv->oldButtons)
wcmSendButtons(pInfo, buttons, 3, 3, valuators);
}
+
if (priv->oldProximity && !is_proximity)
- xf86PostProximityEventP(pInfo->dev, 0, 0, 3, valuators);
+ xf86PostProximityEventP(pInfo->dev, 0, 0, 3,
VCOPY(valuators, 3));
}
priv->oldProximity = is_proximity;
priv->old_device_id = id;
--
1.7.3.3
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel