mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-08 13:38:40 +02:00
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.
This commit is contained in:
parent
1625aa0fc2
commit
51e2c3f40e
1 changed files with 26 additions and 28 deletions
54
src/evdev.c
54
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;
|
||||||
|
*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];
|
||||||
|
|
||||||
if (!device->abs.apply_calibration)
|
*y = device->abs.x * device->abs.calibration[3] +
|
||||||
return;
|
device->abs.y * device->abs.calibration[4] +
|
||||||
|
device->abs.calibration[5];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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…
Add table
Reference in a new issue