summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-08-26 16:23:38 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-08-26 16:23:38 +0200
commitbabe344373d036d57a270658d134d6c0b334f280 (patch)
tree28060c18592e11a3a31bd7db02b1f197b7d3b397
parent3b776917d8037bec30a62b802433194ecead929f (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>
-rw-r--r--src/grail-api.c67
-rw-r--r--src/grail-impl.h3
-rw-r--r--test/grail-gesture.c4
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,
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
41static int extra_filtered(const struct input_event *ev) 47static 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
65static 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
56static void tp_sync(struct touch_dev *dev, 95static 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}
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 {
30 struct touch_dev dev; 30 struct touch_dev dev;
31 struct evbuf evbuf; 31 struct evbuf evbuf;
32 int filter_abs; 32 int filter_abs;
33 int hack_status; 33 int pointer_status;
34 int pointer_x, pointer_y;
34}; 35};
35 36
36#endif 37#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,
46 46
47static void tp_event(struct grail *ge, const struct input_event *ev) 47static void tp_event(struct grail *ge, const struct input_event *ev)
48{ 48{
49 if (!grail_mask_get(flag_mask, GRAIL_TYPE_DRAG1))
50 return;
51 fprintf(stderr, "event %d 0x%x %d\n", ev->type, ev->code, ev->value); 49 fprintf(stderr, "event %d 0x%x %d\n", ev->type, ev->code, ev->value);
52} 50}
53 51
@@ -112,7 +110,7 @@ int main(int argc, char *argv[])
112 fprintf(stderr, "error: could not open touch device\n"); 110 fprintf(stderr, "error: could not open touch device\n");
113 return -1; 111 return -1;
114 } 112 }
115 grail_filter_abs_events(&ge, 1); 113 //grail_filter_abs_events(&ge, 1);
116 114
117 struct grail_coord min = { -2, -1 }, max = { 2, 1 }; 115 struct grail_coord min = { -2, -1 }, max = { 2, 1 };
118 grail_set_bbox(&ge, &min, &max); 116 grail_set_bbox(&ge, &min, &max);