touchpad: support single-touch touchpads

Touchpads without ABS_MT_SLOT create 5 slots by default (for up to QUINTTAP)
and ABS_X/Y is mapped to the 0-slot touchpoint. This commit adds handling for
a single finger, no BTN_TOOL_DOUBLETAP or similar is being processed yet.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2014-02-14 14:18:27 +10:00
parent 8ea5cb75c1
commit efc8d95171
2 changed files with 54 additions and 8 deletions

View file

@ -225,6 +225,28 @@ tp_process_absolute(struct tp_dispatch *tp,
}
}
static void
tp_process_absolute_st(struct tp_dispatch *tp,
const struct input_event *e,
uint32_t time)
{
struct tp_touch *t = tp_current_touch(tp);
switch(e->code) {
case ABS_X:
t->x = e->value;
t->millis = time;
t->dirty = true;
break;
case ABS_Y:
t->y = e->value;
t->millis = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
}
}
static void
tp_process_key(struct tp_dispatch *tp,
const struct input_event *e,
@ -245,6 +267,18 @@ tp_process_key(struct tp_dispatch *tp,
tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
}
break;
case BTN_TOUCH:
if (!tp->has_mt) {
struct tp_touch *t = tp_current_touch(tp);
if (e->value) {
tp_begin_touch(tp, t);
t->fake = true;
} else {
tp_end_touch(tp, t);
}
t->millis = time;
}
break;
}
}
@ -271,9 +305,10 @@ tp_post_process_state(struct tp_dispatch *tp, uint32_t time)
if (!t->dirty)
continue;
if (t->state == TOUCH_END)
if (t->state == TOUCH_END) {
t->state = TOUCH_NONE;
else if (t->state == TOUCH_BEGIN)
t->fake = false;
} else if (t->state == TOUCH_BEGIN)
t->state = TOUCH_UPDATE;
t->dirty = false;
@ -443,7 +478,10 @@ tp_process(struct evdev_dispatch *dispatch,
switch (e->type) {
case EV_ABS:
tp_process_absolute(tp, e, time);
if (tp->has_mt)
tp_process_absolute(tp, e, time);
else
tp_process_absolute_st(tp, e, time);
break;
case EV_KEY:
tp_process_key(tp, e, time);
@ -477,14 +515,20 @@ static int
tp_init_slots(struct tp_dispatch *tp,
struct evdev_device *device)
{
struct input_absinfo absinfo = {0};
const struct input_absinfo *absinfo;
ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), &absinfo);
tp->ntouches = absinfo.maximum + 1;
absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
if (absinfo) {
tp->ntouches = absinfo->maximum + 1;
tp->slot = absinfo->value;
tp->has_mt = true;
} else {
tp->ntouches = 5; /* FIXME: based on DOUBLETAP, etc. */
tp->slot = 0;
tp->has_mt = false;
}
tp->touches = calloc(tp->ntouches,
sizeof(struct tp_touch));
tp->slot = absinfo.value;
return 0;
}

View file

@ -75,6 +75,7 @@ struct tp_motion {
struct tp_touch {
enum touch_state state;
bool dirty;
bool fake; /* a fake touch */
int32_t x;
int32_t y;
uint32_t millis;
@ -96,6 +97,7 @@ struct tp_dispatch {
struct evdev_device *device;
unsigned int nfingers_down; /* number of fingers down */
unsigned int slot; /* current slot */
bool has_mt;
unsigned int ntouches; /* number of slots */
struct tp_touch *touches; /* len == ntouches */