summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-08-28 22:12:24 -0700
committerKristian Høgsberg <krh@bitplanet.net>2013-08-28 23:08:05 -0700
commitc6b6e78c0d3b7e790f5c46db08868507b7b3ceb1 (patch)
tree7dc9534760678fa117985ec959f8e8c4fccdc934
parent3dbbf321dd0a3e26eab62ad5c77aaf95a593699c (diff)
evdev: Don't transform device->abs.x/y in place
We don't always get both an X and an Y event in a SYN report, so we end up transforming the coordinate we don't get twice. For example, if we only receive an ABS_X event, we transform the already transformed device->abs.y again in transform_absolute() when applying the calibration.
-rw-r--r--src/evdev.c58
1 files changed, 28 insertions, 30 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 71399892..51b99e63 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -236,33 +236,32 @@ is_motion_event(struct input_event *e)
}
static void
-transform_absolute(struct evdev_device *device)
+transform_absolute(struct evdev_device *device, int32_t *x, int32_t *y)
{
- int32_t x, y;
-
- if (!device->abs.apply_calibration)
- return;
-
- x = device->abs.x * device->abs.calibration[0] +
- device->abs.y * device->abs.calibration[1] +
- device->abs.calibration[2];
-
- y = device->abs.x * device->abs.calibration[3] +
- device->abs.y * device->abs.calibration[4] +
- device->abs.calibration[5];
-
- device->abs.x = x;
- device->abs.y = y;
+ if (!device->abs.apply_calibration) {
+ *x = device->abs.x;
+ *y = device->abs.y;
+ return;
+ } else {
+ *x = device->abs.x * device->abs.calibration[0] +
+ device->abs.y * device->abs.calibration[1] +
+ device->abs.calibration[2];
+
+ *y = device->abs.x * device->abs.calibration[3] +
+ device->abs.y * device->abs.calibration[4] +
+ device->abs.calibration[5];
+ }
}
static void
evdev_flush_motion(struct evdev_device *device, uint32_t time)
{
- struct weston_seat *master = device->seat;
- wl_fixed_t x, y;
- int slot;
+ struct weston_seat *master = device->seat;
+ wl_fixed_t x, y;
+ int32_t cx, cy;
+ int slot;
- if (!(device->pending_events & EVDEV_SYN))
+ if (!(device->pending_events & EVDEV_SYN))
return;
slot = device->mt.slot;
@@ -296,16 +295,15 @@ evdev_flush_motion(struct evdev_device *device, uint32_t time)
if (device->pending_events & EVDEV_ABSOLUTE_MT_UP) {
notify_touch(master, time, device->mt.slot, 0, 0,
WL_TOUCH_UP);
- device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
- }
- if (device->pending_events & EVDEV_ABSOLUTE_MOTION) {
- transform_absolute(device);
- weston_output_transform_coordinate(device->output,
- device->abs.x,
- device->abs.y, &x, &y);
-
- if (device->caps & EVDEV_TOUCH) {
- if (master->num_tp == 0)
+ device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
+ }
+ if (device->pending_events & EVDEV_ABSOLUTE_MOTION) {
+ transform_absolute(device, &cx, &cy);
+ weston_output_transform_coordinate(device->output,
+ cx, cy, &x, &y);
+
+ if (device->caps & EVDEV_TOUCH) {
+ if (master->num_tp == 0)
notify_touch(master, time, 0,
x, y, WL_TOUCH_DOWN);
else