mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 14:40:26 +01:00
touchpad: Create fake touches for BTN_TOOL_FOO on multi-touch pads too
Multi-touch pads may track less touches then they can report fingers being present through BTN_TOOL_FOO. So create fake touches for fingers reported by BTN_TOOL_FOO on multi-touch pads too (when necessary). This fixes e.g. 3 finger tap not working on the T440s. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
9720c16ecc
commit
64f431c303
2 changed files with 40 additions and 38 deletions
|
|
@ -247,7 +247,7 @@ tp_process_fake_touch(struct tp_dispatch *tp,
|
|||
struct tp_touch *t;
|
||||
unsigned int fake_touches;
|
||||
unsigned int nfake_touches;
|
||||
unsigned int i;
|
||||
unsigned int i, start;
|
||||
unsigned int shift;
|
||||
|
||||
if (e->code != BTN_TOUCH &&
|
||||
|
|
@ -268,16 +268,18 @@ tp_process_fake_touch(struct tp_dispatch *tp,
|
|||
fake_touches >>= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < tp->ntouches; i++) {
|
||||
/* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
|
||||
start = tp->has_mt ? tp->real_touches : 0;
|
||||
for (i = start; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
if (i < nfake_touches) {
|
||||
if (i < nfake_touches)
|
||||
tp_begin_touch(tp, t, time);
|
||||
t->fake =true;
|
||||
} else
|
||||
else
|
||||
tp_end_touch(tp, t, time);
|
||||
}
|
||||
|
||||
assert(tp->nfingers_down == nfake_touches);
|
||||
/* On mt the actual touch info may arrive after BTN_TOOL_FOO */
|
||||
assert(tp->has_mt || tp->nfingers_down == nfake_touches);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -295,8 +297,7 @@ tp_process_key(struct tp_dispatch *tp,
|
|||
case BTN_TOOL_DOUBLETAP:
|
||||
case BTN_TOOL_TRIPLETAP:
|
||||
case BTN_TOOL_QUADTAP:
|
||||
if (!tp->has_mt)
|
||||
tp_process_fake_touch(tp, e, time);
|
||||
tp_process_fake_touch(tp, e, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -401,9 +402,11 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
{
|
||||
struct tp_touch *t;
|
||||
struct tp_touch *first = tp_get_touch(tp, 0);
|
||||
unsigned int i;
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (!tp->has_mt && t != first && first->fake) {
|
||||
for (i = 0; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
if (i >= tp->real_touches && t->state != TOUCH_NONE) {
|
||||
t->x = first->x;
|
||||
t->y = first->y;
|
||||
if (!t->dirty)
|
||||
|
|
@ -443,10 +446,9 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
if (!t->dirty)
|
||||
continue;
|
||||
|
||||
if (t->state == TOUCH_END) {
|
||||
if (t->state == TOUCH_END)
|
||||
t->state = TOUCH_NONE;
|
||||
t->fake = false;
|
||||
} else if (t->state == TOUCH_BEGIN)
|
||||
else if (t->state == TOUCH_BEGIN)
|
||||
t->state = TOUCH_UPDATE;
|
||||
|
||||
t->dirty = false;
|
||||
|
|
@ -642,41 +644,41 @@ static int
|
|||
tp_init_slots(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
size_t i;
|
||||
const struct input_absinfo *absinfo;
|
||||
struct map {
|
||||
unsigned int code;
|
||||
int ntouches;
|
||||
} max_touches[] = {
|
||||
{ BTN_TOOL_QUINTTAP, 5 },
|
||||
{ BTN_TOOL_QUADTAP, 4 },
|
||||
{ BTN_TOOL_TRIPLETAP, 3 },
|
||||
{ BTN_TOOL_DOUBLETAP, 2 },
|
||||
};
|
||||
struct map *m;
|
||||
unsigned int i, n_btn_tool_touches = 1;
|
||||
|
||||
absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
|
||||
if (absinfo) {
|
||||
tp->ntouches = absinfo->maximum + 1;
|
||||
tp->real_touches = absinfo->maximum + 1;
|
||||
tp->slot = absinfo->value;
|
||||
tp->has_mt = true;
|
||||
} else {
|
||||
struct map {
|
||||
unsigned int code;
|
||||
int ntouches;
|
||||
} max_touches[] = {
|
||||
{ BTN_TOOL_QUINTTAP, 5 },
|
||||
{ BTN_TOOL_QUADTAP, 4 },
|
||||
{ BTN_TOOL_TRIPLETAP, 3 },
|
||||
{ BTN_TOOL_DOUBLETAP, 2 },
|
||||
};
|
||||
struct map *m;
|
||||
|
||||
tp->real_touches = 1;
|
||||
tp->slot = 0;
|
||||
tp->has_mt = false;
|
||||
tp->ntouches = 1;
|
||||
}
|
||||
|
||||
ARRAY_FOR_EACH(max_touches, m) {
|
||||
if (libevdev_has_event_code(device->evdev,
|
||||
EV_KEY,
|
||||
m->code)) {
|
||||
tp->ntouches = m->ntouches;
|
||||
break;
|
||||
}
|
||||
ARRAY_FOR_EACH(max_touches, m) {
|
||||
if (libevdev_has_event_code(device->evdev,
|
||||
EV_KEY,
|
||||
m->code)) {
|
||||
n_btn_tool_touches = m->ntouches;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tp->touches = calloc(tp->ntouches,
|
||||
sizeof(struct tp_touch));
|
||||
|
||||
tp->ntouches = max(tp->real_touches, n_btn_tool_touches);
|
||||
tp->touches = calloc(tp->ntouches, sizeof(struct tp_touch));
|
||||
if (!tp->touches)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ struct tp_touch {
|
|||
struct tp_dispatch *tp;
|
||||
enum touch_state state;
|
||||
bool dirty;
|
||||
bool fake; /* a fake touch */
|
||||
bool is_pointer; /* the pointer-controlling touch */
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
@ -156,7 +155,8 @@ struct tp_dispatch {
|
|||
unsigned int slot; /* current slot */
|
||||
bool has_mt;
|
||||
|
||||
unsigned int ntouches; /* number of slots */
|
||||
unsigned int real_touches; /* number of slots */
|
||||
unsigned int ntouches; /* no slots inc. fakes */
|
||||
struct tp_touch *touches; /* len == ntouches */
|
||||
unsigned int fake_touches; /* fake touch mask */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue