From babe344373d036d57a270658d134d6c0b334f280 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 26 Aug 2010 16:23:38 +0200 Subject: Correct abs event handling The current code lets abs events through during one-finger drags, and tapping does not work properly due to abs events not always being present during taps. Track the pointer position and emit abs events only if no gestures are in effect, and only if not explicitly filtered. Signed-off-by: Henrik Rydberg --- src/grail-api.c | 67 ++++++++++++++++++++++++++++++++++++---------------- src/grail-impl.h | 3 ++- test/grail-gesture.c | 4 +--- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/grail-api.c b/src/grail-api.c index f55ac1f..1a60a21 100644 --- a/src/grail-api.c +++ b/src/grail-api.c @@ -35,11 +35,20 @@ static void tp_event(struct touch_dev *dev, { struct grail *ge = dev->priv; struct grail_impl *x = ge->impl; + if (ev->type == EV_ABS) { + if (ev->code == ABS_X) + x->pointer_x = ev->value; + if (ev->code == ABS_Y) + x->pointer_y = ev->value; + } evbuf_put(&x->evbuf, ev); } static int extra_filtered(const struct input_event *ev) { + if (ev->type == EV_ABS) { + return 1; + } if (ev->type == EV_KEY) { switch (ev->code) { case BTN_TOUCH: @@ -53,46 +62,64 @@ static int extra_filtered(const struct input_event *ev) return 0; } +static int handle_abs_events(struct grail *ge, + const struct input_event *syn, + int pointer) +{ + struct grail_impl *impl = ge->impl; + struct input_event ev = *syn; + int nevent = 0; + if (pointer != impl->pointer_status) { + ev.type = EV_KEY; + ev.code = BTN_TOUCH; + ev.value = pointer; + ge->event(ge, &ev); + impl->pointer_status = pointer; + nevent++; + } + if (pointer) { + ev.type = EV_ABS; + ev.code = ABS_X; + ev.value = impl->pointer_x; + ge->event(ge, &ev); + nevent++; + ev.type = EV_ABS; + ev.code = ABS_Y; + ev.value = impl->pointer_y; + ge->event(ge, &ev); + nevent++; + } + return nevent; +} + static void tp_sync(struct touch_dev *dev, const struct input_event *syn) { struct input_event ev; struct grail *ge = dev->priv; - struct grail_impl *x = ge->impl; + struct grail_impl *impl = ge->impl; struct gesture_recognizer *gru = ge->gru; struct touch_frame *frame = &dev->frame; grail_mask_t filtered[DIM_EV_TYPE_BYTES]; - int dofilt, hack, nevent = 0; + int pointer, nevent = 0; gin_frame_begin(ge, frame); gru_recognize(ge, frame); gin_frame_end(ge, filtered, sizeof(filtered), frame); - dofilt = gru->move.multi || gru->move.single && x->filter_abs; - hack = gru->move.single; + pointer = gru->move.single && !grail_mask_get(filtered, EV_ABS); if (!ge->event) { - evbuf_clear(&x->evbuf); + evbuf_clear(&impl->evbuf); return; } - while (!evbuf_empty(&x->evbuf)) { - evbuf_get(&x->evbuf, &ev); - if (!hack && ev.type == EV_ABS) - continue; - if (dofilt && grail_mask_get(filtered, ev.type)) - continue; + if (!impl->filter_abs) + nevent += handle_abs_events(ge, syn, pointer); + while (!evbuf_empty(&impl->evbuf)) { + evbuf_get(&impl->evbuf, &ev); if (extra_filtered(&ev)) continue; ge->event(ge, &ev); nevent++; } - if (hack != x->hack_status) { - ev = *syn; - ev.type = EV_KEY; - ev.code = BTN_TOUCH; - ev.value = hack; - ge->event(ge, &ev); - x->hack_status = hack; - nevent++; - } if (nevent) ge->event(ge, syn); } diff --git a/src/grail-impl.h b/src/grail-impl.h index ba7745a..66fe4c7 100644 --- a/src/grail-impl.h +++ b/src/grail-impl.h @@ -30,7 +30,8 @@ struct grail_impl { struct touch_dev dev; struct evbuf evbuf; int filter_abs; - int hack_status; + int pointer_status; + int pointer_x, pointer_y; }; #endif diff --git a/test/grail-gesture.c b/test/grail-gesture.c index d30e713..d2e0e7d 100644 --- a/test/grail-gesture.c +++ b/test/grail-gesture.c @@ -46,8 +46,6 @@ static int tp_get_clients(struct grail *ge, static void tp_event(struct grail *ge, const struct input_event *ev) { - if (!grail_mask_get(flag_mask, GRAIL_TYPE_DRAG1)) - return; fprintf(stderr, "event %d 0x%x %d\n", ev->type, ev->code, ev->value); } @@ -112,7 +110,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "error: could not open touch device\n"); return -1; } - grail_filter_abs_events(&ge, 1); + //grail_filter_abs_events(&ge, 1); struct grail_coord min = { -2, -1 }, max = { 2, 1 }; grail_set_bbox(&ge, &min, &max); -- cgit v1.2.3