}
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,
uint32_t time)
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;
}
}
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;
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);
tp_init_slots(struct tp_dispatch *tp,
struct evdev_device *device)
{
- struct input_absinfo absinfo = {0};
-
- ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), &absinfo);
+ const struct input_absinfo *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;
}