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.
dev
Kristian Høgsberg 11 years ago
parent c4df4082c2
commit 6c7583de2a
  1. 58
      src/evdev.c

@ -236,33 +236,32 @@ is_motion_event(struct input_event *e)
} }
static void 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) {
*x = device->abs.x;
if (!device->abs.apply_calibration) *y = device->abs.y;
return; return;
} else {
x = device->abs.x * device->abs.calibration[0] + *x = device->abs.x * device->abs.calibration[0] +
device->abs.y * device->abs.calibration[1] + device->abs.y * device->abs.calibration[1] +
device->abs.calibration[2]; device->abs.calibration[2];
y = device->abs.x * device->abs.calibration[3] + *y = device->abs.x * device->abs.calibration[3] +
device->abs.y * device->abs.calibration[4] + device->abs.y * device->abs.calibration[4] +
device->abs.calibration[5]; device->abs.calibration[5];
}
device->abs.x = x;
device->abs.y = y;
} }
static void static void
evdev_flush_motion(struct evdev_device *device, uint32_t time) evdev_flush_motion(struct evdev_device *device, uint32_t time)
{ {
struct weston_seat *master = device->seat; struct weston_seat *master = device->seat;
wl_fixed_t x, y; wl_fixed_t x, y;
int slot; int32_t cx, cy;
int slot;
if (!(device->pending_events & EVDEV_SYN)) if (!(device->pending_events & EVDEV_SYN))
return; return;
slot = device->mt.slot; 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) { if (device->pending_events & EVDEV_ABSOLUTE_MT_UP) {
notify_touch(master, time, device->mt.slot, 0, 0, notify_touch(master, time, device->mt.slot, 0, 0,
WL_TOUCH_UP); WL_TOUCH_UP);
device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP; device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
} }
if (device->pending_events & EVDEV_ABSOLUTE_MOTION) { if (device->pending_events & EVDEV_ABSOLUTE_MOTION) {
transform_absolute(device); transform_absolute(device, &cx, &cy);
weston_output_transform_coordinate(device->output, weston_output_transform_coordinate(device->output,
device->abs.x, cx, cy, &x, &y);
device->abs.y, &x, &y);
if (device->caps & EVDEV_TOUCH) {
if (device->caps & EVDEV_TOUCH) { if (master->num_tp == 0)
if (master->num_tp == 0)
notify_touch(master, time, 0, notify_touch(master, time, 0,
x, y, WL_TOUCH_DOWN); x, y, WL_TOUCH_DOWN);
else else

Loading…
Cancel
Save