diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-08-26 16:23:38 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-08-26 16:23:38 +0200 |
| commit | babe344373d036d57a270658d134d6c0b334f280 (patch) | |
| tree | 28060c18592e11a3a31bd7db02b1f197b7d3b397 /src/grail-api.c | |
| parent | 3b776917d8037bec30a62b802433194ecead929f (diff) | |
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 <rydberg@euromail.se>
Diffstat (limited to 'src/grail-api.c')
| -rw-r--r-- | src/grail-api.c | 67 |
1 files changed, 47 insertions, 20 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, | |||
| 35 | { | 35 | { |
| 36 | struct grail *ge = dev->priv; | 36 | struct grail *ge = dev->priv; |
| 37 | struct grail_impl *x = ge->impl; | 37 | struct grail_impl *x = ge->impl; |
| 38 | if (ev->type == EV_ABS) { | ||
| 39 | if (ev->code == ABS_X) | ||
| 40 | x->pointer_x = ev->value; | ||
| 41 | if (ev->code == ABS_Y) | ||
| 42 | x->pointer_y = ev->value; | ||
| 43 | } | ||
| 38 | evbuf_put(&x->evbuf, ev); | 44 | evbuf_put(&x->evbuf, ev); |
| 39 | } | 45 | } |
| 40 | 46 | ||
| 41 | static int extra_filtered(const struct input_event *ev) | 47 | static int extra_filtered(const struct input_event *ev) |
| 42 | { | 48 | { |
| 49 | if (ev->type == EV_ABS) { | ||
| 50 | return 1; | ||
| 51 | } | ||
| 43 | if (ev->type == EV_KEY) { | 52 | if (ev->type == EV_KEY) { |
| 44 | switch (ev->code) { | 53 | switch (ev->code) { |
| 45 | case BTN_TOUCH: | 54 | case BTN_TOUCH: |
| @@ -53,46 +62,64 @@ static int extra_filtered(const struct input_event *ev) | |||
| 53 | return 0; | 62 | return 0; |
| 54 | } | 63 | } |
| 55 | 64 | ||
| 65 | static int handle_abs_events(struct grail *ge, | ||
| 66 | const struct input_event *syn, | ||
| 67 | int pointer) | ||
| 68 | { | ||
| 69 | struct grail_impl *impl = ge->impl; | ||
| 70 | struct input_event ev = *syn; | ||
| 71 | int nevent = 0; | ||
| 72 | if (pointer != impl->pointer_status) { | ||
| 73 | ev.type = EV_KEY; | ||
| 74 | ev.code = BTN_TOUCH; | ||
| 75 | ev.value = pointer; | ||
| 76 | ge->event(ge, &ev); | ||
| 77 | impl->pointer_status = pointer; | ||
| 78 | nevent++; | ||
| 79 | } | ||
| 80 | if (pointer) { | ||
| 81 | ev.type = EV_ABS; | ||
| 82 | ev.code = ABS_X; | ||
| 83 | ev.value = impl->pointer_x; | ||
| 84 | ge->event(ge, &ev); | ||
| 85 | nevent++; | ||
| 86 | ev.type = EV_ABS; | ||
| 87 | ev.code = ABS_Y; | ||
| 88 | ev.value = impl->pointer_y; | ||
| 89 | ge->event(ge, &ev); | ||
| 90 | nevent++; | ||
| 91 | } | ||
| 92 | return nevent; | ||
| 93 | } | ||
| 94 | |||
| 56 | static void tp_sync(struct touch_dev *dev, | 95 | static void tp_sync(struct touch_dev *dev, |
| 57 | const struct input_event *syn) | 96 | const struct input_event *syn) |
| 58 | { | 97 | { |
| 59 | struct input_event ev; | 98 | struct input_event ev; |
| 60 | struct grail *ge = dev->priv; | 99 | struct grail *ge = dev->priv; |
| 61 | struct grail_impl *x = ge->impl; | 100 | struct grail_impl *impl = ge->impl; |
| 62 | struct gesture_recognizer *gru = ge->gru; | 101 | struct gesture_recognizer *gru = ge->gru; |
| 63 | struct touch_frame *frame = &dev->frame; | 102 | struct touch_frame *frame = &dev->frame; |
| 64 | grail_mask_t filtered[DIM_EV_TYPE_BYTES]; | 103 | grail_mask_t filtered[DIM_EV_TYPE_BYTES]; |
| 65 | int dofilt, hack, nevent = 0; | 104 | int pointer, nevent = 0; |
| 66 | gin_frame_begin(ge, frame); | 105 | gin_frame_begin(ge, frame); |
| 67 | gru_recognize(ge, frame); | 106 | gru_recognize(ge, frame); |
| 68 | gin_frame_end(ge, filtered, sizeof(filtered), frame); | 107 | gin_frame_end(ge, filtered, sizeof(filtered), frame); |
| 69 | dofilt = gru->move.multi || gru->move.single && x->filter_abs; | 108 | pointer = gru->move.single && !grail_mask_get(filtered, EV_ABS); |
| 70 | hack = gru->move.single; | ||
| 71 | 109 | ||
| 72 | if (!ge->event) { | 110 | if (!ge->event) { |
| 73 | evbuf_clear(&x->evbuf); | 111 | evbuf_clear(&impl->evbuf); |
| 74 | return; | 112 | return; |
| 75 | } | 113 | } |
| 76 | while (!evbuf_empty(&x->evbuf)) { | 114 | if (!impl->filter_abs) |
| 77 | evbuf_get(&x->evbuf, &ev); | 115 | nevent += handle_abs_events(ge, syn, pointer); |
| 78 | if (!hack && ev.type == EV_ABS) | 116 | while (!evbuf_empty(&impl->evbuf)) { |
| 79 | continue; | 117 | evbuf_get(&impl->evbuf, &ev); |
| 80 | if (dofilt && grail_mask_get(filtered, ev.type)) | ||
| 81 | continue; | ||
| 82 | if (extra_filtered(&ev)) | 118 | if (extra_filtered(&ev)) |
| 83 | continue; | 119 | continue; |
| 84 | ge->event(ge, &ev); | 120 | ge->event(ge, &ev); |
| 85 | nevent++; | 121 | nevent++; |
| 86 | } | 122 | } |
| 87 | if (hack != x->hack_status) { | ||
| 88 | ev = *syn; | ||
| 89 | ev.type = EV_KEY; | ||
| 90 | ev.code = BTN_TOUCH; | ||
| 91 | ev.value = hack; | ||
| 92 | ge->event(ge, &ev); | ||
| 93 | x->hack_status = hack; | ||
| 94 | nevent++; | ||
| 95 | } | ||
| 96 | if (nevent) | 123 | if (nevent) |
| 97 | ge->event(ge, syn); | 124 | ge->event(ge, syn); |
| 98 | } | 125 | } |
