summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2010-08-16 14:18:45 +1000
committerKeith Packard <keithp@keithp.com>2010-08-18 13:10:54 -0700
commitfc091936e2bddbbab9c9a501edc5a5f08388617e (patch)
treeaf78ec7f2dd0cba2129c72cf3f894f90c26b1bb8
parent6e3e559e9fa63069a10eb834a6dab9a4cfc140ee (diff)
dix: copy the valuators passed into GPE/GKVE/GProxE.
GPE and friends modify the valuators array passed in. Which means any driver using e.g. xf86PostButtonEventP(..., valuators) twice to emulate a button click will provide garbage data on the second run. This is currently affecting the wacom driver, xf86PostButtonEventP() with valuators is required to have input events with device-specific axis values. Passing the same valuators in twice, once with press, once with release, will see the valuators modified in the first call and garbage submitted in the next one. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--dix/getevents.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/dix/getevents.c b/dix/getevents.c
index 20bcf7e8a..e5134d34b 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -912,17 +912,19 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code)
int
GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
int key_code, int first_valuator,
- int num_valuators, int *valuators) {
+ int num_valuators, int *valuators_in) {
int num_events = 0;
CARD32 ms = 0;
DeviceEvent *event;
RawDeviceEvent *raw;
+ int valuators[MAX_VALUATORS];
/* refuse events from disabled devices */
if (!pDev->enabled)
return 0;
if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+ num_valuators > MAX_VALUATORS ||
(type != KeyPress && type != KeyRelease) ||
(key_code < 8 || key_code > 255))
return 0;
@@ -947,6 +949,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
events++;
num_events++;
+ memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+
init_raw(pDev, raw, ms, type, key_code);
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data_raw);
@@ -1067,7 +1071,7 @@ transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
int
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
int flags, int first_valuator, int num_valuators,
- int *valuators) {
+ int *valuators_in) {
int num_events = 1;
CARD32 ms;
DeviceEvent *event;
@@ -1076,6 +1080,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
cx, cy; /* only screen coordinates */
float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
ScreenPtr scr = miPointerGetScreen(pDev);
+ int valuators[MAX_VALUATORS];
/* refuse events from disabled devices */
if (!pDev->enabled)
@@ -1084,6 +1089,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
ms = GetTimeInMillis(); /* before pointer update to help precision */
if (!scr || !pDev->valuator || first_valuator < 0 ||
+ num_valuators > MAX_VALUATORS ||
((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
(type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
(type != MotionNotify && !pDev->button) ||
@@ -1097,6 +1103,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
events++;
num_events++;
+ memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+
init_raw(pDev, raw, ms, type, buttons);
set_raw_valuators(raw, first_valuator, num_valuators, valuators,
raw->valuators.data_raw);
@@ -1183,10 +1191,11 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
*/
int
GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
- int first_valuator, int num_valuators, int *valuators)
+ int first_valuator, int num_valuators, int *valuators_in)
{
int num_events = 1;
DeviceEvent *event;
+ int valuators[MAX_VALUATORS];
/* refuse events from disabled devices */
if (!pDev->enabled)
@@ -1202,7 +1211,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
num_valuators = 0;
/* You fail. */
- if (first_valuator < 0 ||
+ if (first_valuator < 0 || num_valuators > MAX_VALUATORS ||
(num_valuators + first_valuator) > pDev->valuator->numAxes)
return 0;
@@ -1212,8 +1221,10 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
init_event(pDev, event, GetTimeInMillis());
event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
- if (num_valuators)
+ if (num_valuators) {
+ memcpy(valuators, valuators_in, num_valuators * sizeof(int));
clipValuators(pDev, first_valuator, num_valuators, valuators);
+ }
set_valuators(pDev, event, first_valuator, num_valuators, valuators);