mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-05 09:50:28 +01:00
evdev: split out mt event flushing
No functional changes, this is prep work for being able to release touch points on the fly. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
This commit is contained in:
parent
df781aad2f
commit
b26d8f9122
1 changed files with 252 additions and 144 deletions
396
src/evdev.c
396
src/evdev.c
|
|
@ -391,173 +391,281 @@ fallback_rotate_relative(struct fallback_dispatch *dispatch,
|
|||
dispatch->rel = rel;
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
struct libinput_device *base = &device->base;
|
||||
struct normalized_coords accel, unaccel;
|
||||
struct device_float_coords raw;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
|
||||
return;
|
||||
|
||||
fallback_rotate_relative(dispatch, device);
|
||||
|
||||
normalize_delta(device, &dispatch->rel, &unaccel);
|
||||
raw.x = dispatch->rel.x;
|
||||
raw.y = dispatch->rel.y;
|
||||
dispatch->rel.x = 0;
|
||||
dispatch->rel.y = 0;
|
||||
|
||||
/* Use unaccelerated deltas for pointing stick scroll */
|
||||
if (evdev_post_trackpoint_scroll(device, unaccel, time))
|
||||
return;
|
||||
|
||||
if (device->pointer.filter) {
|
||||
/* Apply pointer acceleration. */
|
||||
accel = filter_dispatch(device->pointer.filter,
|
||||
&unaccel,
|
||||
device,
|
||||
time);
|
||||
} else {
|
||||
log_bug_libinput(libinput,
|
||||
"%s: accel filter missing\n",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
accel = unaccel;
|
||||
}
|
||||
|
||||
if (normalized_is_zero(accel) && normalized_is_zero(unaccel))
|
||||
return;
|
||||
|
||||
pointer_notify_motion(base, time, &accel, &raw);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_absolute_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
|
||||
return;
|
||||
|
||||
point = dispatch->abs.point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
pointer_notify_motion_absolute(base, time, &point);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_mt_down(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
struct device_coords point;
|
||||
struct mt_slot *slot;
|
||||
int seat_slot;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
return;
|
||||
|
||||
slot = &dispatch->mt.slots[slot_idx];
|
||||
if (slot->seat_slot != -1) {
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
|
||||
log_bug_kernel(libinput,
|
||||
"%s: Driver sent multiple touch down for the "
|
||||
"same slot",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
return;
|
||||
}
|
||||
|
||||
seat_slot = ffs(~seat->slot_map) - 1;
|
||||
slot->seat_slot = seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
seat->slot_map |= 1 << seat_slot;
|
||||
point = slot->point;
|
||||
slot->hysteresis_center = point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
touch_notify_touch_down(base, time, slot_idx, seat_slot,
|
||||
&point);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_mt_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
struct mt_slot *slot;
|
||||
int seat_slot;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
return;
|
||||
|
||||
slot = &dispatch->mt.slots[slot_idx];
|
||||
seat_slot = slot->seat_slot;
|
||||
point = slot->point;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
if (fallback_filter_defuzz_touch(dispatch, device, slot))
|
||||
return;
|
||||
|
||||
evdev_transform_absolute(device, &point);
|
||||
touch_notify_touch_motion(base, time, slot_idx, seat_slot,
|
||||
&point);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_mt_up(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
struct mt_slot *slot;
|
||||
int seat_slot;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
return;
|
||||
|
||||
slot = &dispatch->mt.slots[slot_idx];
|
||||
seat_slot = slot->seat_slot;
|
||||
slot->seat_slot = -1;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
seat->slot_map &= ~(1 << seat_slot);
|
||||
|
||||
touch_notify_touch_up(base, time, slot_idx, seat_slot);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_st_down(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
struct device_coords point;
|
||||
int seat_slot;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
return;
|
||||
|
||||
if (dispatch->abs.seat_slot != -1) {
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
|
||||
log_bug_kernel(libinput,
|
||||
"%s: Driver sent multiple touch down for the "
|
||||
"same slot",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
return;
|
||||
}
|
||||
|
||||
seat_slot = ffs(~seat->slot_map) - 1;
|
||||
dispatch->abs.seat_slot = seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
seat->slot_map |= 1 << seat_slot;
|
||||
|
||||
point = dispatch->abs.point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
touch_notify_touch_down(base, time, -1, seat_slot, &point);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_st_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
int seat_slot;
|
||||
|
||||
point = dispatch->abs.point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
seat_slot = dispatch->abs.seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
touch_notify_touch_motion(base, time, -1, seat_slot, &point);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_st_up(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
int seat_slot;
|
||||
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
return;
|
||||
|
||||
seat_slot = dispatch->abs.seat_slot;
|
||||
dispatch->abs.seat_slot = -1;
|
||||
|
||||
if (seat_slot == -1)
|
||||
return;
|
||||
|
||||
seat->slot_map &= ~(1 << seat_slot);
|
||||
|
||||
touch_notify_touch_up(base, time, -1, seat_slot);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_pending_event(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
int slot_idx;
|
||||
int seat_slot;
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
struct normalized_coords accel, unaccel;
|
||||
struct device_coords point;
|
||||
struct device_float_coords raw;
|
||||
struct mt_slot *slot = NULL;
|
||||
|
||||
slot_idx = dispatch->mt.slot;
|
||||
if (dispatch->mt.slots)
|
||||
slot = &dispatch->mt.slots[slot_idx];
|
||||
|
||||
switch (dispatch->pending_event) {
|
||||
case EVDEV_NONE:
|
||||
return;
|
||||
case EVDEV_RELATIVE_MOTION:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
|
||||
break;
|
||||
|
||||
fallback_rotate_relative(dispatch, device);
|
||||
|
||||
normalize_delta(device, &dispatch->rel, &unaccel);
|
||||
raw.x = dispatch->rel.x;
|
||||
raw.y = dispatch->rel.y;
|
||||
dispatch->rel.x = 0;
|
||||
dispatch->rel.y = 0;
|
||||
|
||||
/* Use unaccelerated deltas for pointing stick scroll */
|
||||
if (evdev_post_trackpoint_scroll(device, unaccel, time))
|
||||
break;
|
||||
|
||||
if (device->pointer.filter) {
|
||||
/* Apply pointer acceleration. */
|
||||
accel = filter_dispatch(device->pointer.filter,
|
||||
&unaccel,
|
||||
device,
|
||||
time);
|
||||
} else {
|
||||
log_bug_libinput(libinput,
|
||||
"%s: accel filter missing\n",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
accel = unaccel;
|
||||
}
|
||||
|
||||
if (normalized_is_zero(accel) && normalized_is_zero(unaccel))
|
||||
break;
|
||||
|
||||
pointer_notify_motion(base, time, &accel, &raw);
|
||||
fallback_flush_relative_motion(dispatch, device, time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_MT_DOWN:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
break;
|
||||
|
||||
if (slot->seat_slot != -1) {
|
||||
log_bug_kernel(libinput,
|
||||
"%s: Driver sent multiple touch down for the "
|
||||
"same slot",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
break;
|
||||
}
|
||||
|
||||
seat_slot = ffs(~seat->slot_map) - 1;
|
||||
slot->seat_slot = seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
seat->slot_map |= 1 << seat_slot;
|
||||
point = slot->point;
|
||||
slot->hysteresis_center = point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
touch_notify_touch_down(base, time, slot_idx, seat_slot,
|
||||
&point);
|
||||
slot_idx = dispatch->mt.slot;
|
||||
fallback_flush_mt_down(dispatch, device, slot_idx, time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_MT_MOTION:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
break;
|
||||
|
||||
seat_slot = slot->seat_slot;
|
||||
point = slot->point;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
if (fallback_filter_defuzz_touch(dispatch, device, slot))
|
||||
break;
|
||||
|
||||
evdev_transform_absolute(device, &point);
|
||||
touch_notify_touch_motion(base, time, slot_idx, seat_slot,
|
||||
&point);
|
||||
slot_idx = dispatch->mt.slot;
|
||||
fallback_flush_mt_motion(dispatch, device, slot_idx, time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_MT_UP:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
break;
|
||||
|
||||
seat_slot = slot->seat_slot;
|
||||
slot->seat_slot = -1;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
seat->slot_map &= ~(1 << seat_slot);
|
||||
|
||||
touch_notify_touch_up(base, time, slot_idx, seat_slot);
|
||||
slot_idx = dispatch->mt.slot;
|
||||
fallback_flush_mt_up(dispatch, device, slot_idx, time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_TOUCH_DOWN:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
break;
|
||||
|
||||
if (dispatch->abs.seat_slot != -1) {
|
||||
log_bug_kernel(libinput,
|
||||
"%s: Driver sent multiple touch down for the "
|
||||
"same slot",
|
||||
udev_device_get_devnode(device->udev_device));
|
||||
break;
|
||||
}
|
||||
|
||||
seat_slot = ffs(~seat->slot_map) - 1;
|
||||
dispatch->abs.seat_slot = seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
seat->slot_map |= 1 << seat_slot;
|
||||
|
||||
point = dispatch->abs.point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
touch_notify_touch_down(base, time, -1, seat_slot, &point);
|
||||
fallback_flush_st_down(dispatch, device, time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_MOTION:
|
||||
point = dispatch->abs.point;
|
||||
evdev_transform_absolute(device, &point);
|
||||
|
||||
if (device->seat_caps & EVDEV_DEVICE_TOUCH) {
|
||||
seat_slot = dispatch->abs.seat_slot;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
touch_notify_touch_motion(base, time, -1, seat_slot,
|
||||
&point);
|
||||
} else if (device->seat_caps & EVDEV_DEVICE_POINTER) {
|
||||
pointer_notify_motion_absolute(base, time, &point);
|
||||
}
|
||||
if (device->seat_caps & EVDEV_DEVICE_TOUCH)
|
||||
fallback_flush_st_motion(dispatch, device, time);
|
||||
else if (device->seat_caps & EVDEV_DEVICE_POINTER)
|
||||
fallback_flush_absolute_motion(dispatch,
|
||||
device,
|
||||
time);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_TOUCH_UP:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
break;
|
||||
|
||||
seat_slot = dispatch->abs.seat_slot;
|
||||
dispatch->abs.seat_slot = -1;
|
||||
|
||||
if (seat_slot == -1)
|
||||
break;
|
||||
|
||||
seat->slot_map &= ~(1 << seat_slot);
|
||||
|
||||
touch_notify_touch_up(base, time, -1, seat_slot);
|
||||
fallback_flush_st_up(dispatch, device, time);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unknown pending event type");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue