summaryrefslogtreecommitdiff
path: root/src/grail-api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/grail-api.c')
-rw-r--r--src/grail-api.c173
1 files changed, 46 insertions, 127 deletions
diff --git a/src/grail-api.c b/src/grail-api.c
index 1071825..6521f84 100644
--- a/src/grail-api.c
+++ b/src/grail-api.c
@@ -34,11 +34,6 @@
34#define DIM_FRAMES 100 34#define DIM_FRAMES 100
35#define FRAME_RATE 100 35#define FRAME_RATE 100
36 36
37/* Wait time (ms) for number of touches to stabilize. */
38static const unsigned int stable_time = 50;
39/* Maximum time (ms) for gesture to be recognized. */
40static const unsigned int recognition_time = 200;
41
42void grail_filter_abs_events(struct grail *ge, int usage) 37void grail_filter_abs_events(struct grail *ge, int usage)
43{ 38{
44 struct grail_impl *x = ge->impl; 39 struct grail_impl *x = ge->impl;
@@ -132,62 +127,37 @@ void grail_get_units(const struct grail *ge,
132 max->y = s->max_y; 127 max->y = s->max_y;
133} 128}
134 129
135/* Check for any potential gestures given the number of touch points and where 130static void flush_events(struct grail *ge)
136 * they occur on screen. */
137static int check_potential_gestures(struct grail *ge,
138 const struct utouch_frame *frame)
139{ 131{
140 grail_mask_t types[DIM_GRAIL_TYPE_BYTES] = {0}; 132 struct grail_impl *impl = ge->impl;
141 struct grail_client_info client; 133 struct input_event ev;
142 struct grail_coord pos[frame->num_active]; 134
143 int i; 135 grailbuf_clear(&impl->gbuf);
144 136 while (!evbuf_empty(&impl->evbuf)) {
145 switch (frame->num_active) { 137 evbuf_get(&impl->evbuf, &ev);
146 case 1: 138 if (ge->event)
147 grail_mask_set(types, GRAIL_TYPE_DRAG1); 139 ge->event(ge, &ev);
148 grail_mask_set(types, GRAIL_TYPE_PINCH1);
149 grail_mask_set(types, GRAIL_TYPE_ROTATE1);
150 grail_mask_set(types, GRAIL_TYPE_TAP1);
151 break;
152 case 2:
153 grail_mask_set(types, GRAIL_TYPE_DRAG2);
154 grail_mask_set(types, GRAIL_TYPE_PINCH2);
155 grail_mask_set(types, GRAIL_TYPE_ROTATE2);
156 grail_mask_set(types, GRAIL_TYPE_TAP2);
157 break;
158 case 3:
159 grail_mask_set(types, GRAIL_TYPE_DRAG3);
160 grail_mask_set(types, GRAIL_TYPE_PINCH3);
161 grail_mask_set(types, GRAIL_TYPE_ROTATE3);
162 grail_mask_set(types, GRAIL_TYPE_TAP3);
163 grail_mask_set(types, GRAIL_TYPE_EDRAG);
164 grail_mask_set(types, GRAIL_TYPE_EPINCH);
165 grail_mask_set(types, GRAIL_TYPE_EROTATE);
166 break;
167 case 4:
168 grail_mask_set(types, GRAIL_TYPE_DRAG4);
169 grail_mask_set(types, GRAIL_TYPE_PINCH4);
170 grail_mask_set(types, GRAIL_TYPE_ROTATE4);
171 grail_mask_set(types, GRAIL_TYPE_TAP4);
172 grail_mask_set(types, GRAIL_TYPE_MDRAG);
173 grail_mask_set(types, GRAIL_TYPE_MPINCH);
174 grail_mask_set(types, GRAIL_TYPE_MROTATE);
175 break;
176 case 5:
177 grail_mask_set(types, GRAIL_TYPE_DRAG5);
178 grail_mask_set(types, GRAIL_TYPE_PINCH5);
179 grail_mask_set(types, GRAIL_TYPE_ROTATE5);
180 grail_mask_set(types, GRAIL_TYPE_TAP5);
181 break;
182 } 140 }
141}
183 142
184 for (i = 0; i < frame->num_active; i++) { 143static void flush_gestures(struct grail *ge)
185 pos[i].x = gin_prop_x(ge->gin, frame->active[i]->x); 144{
186 pos[i].y = gin_prop_y(ge->gin, frame->active[i]->y); 145 struct grail_impl *impl = ge->impl;
146 struct grail_event ev;
147
148 evbuf_clear(&impl->evbuf);
149 while (!grailbuf_empty(&impl->gbuf)) {
150 grailbuf_get(&impl->gbuf, &ev);
151 if (ge->gesture)
152 ge->gesture(ge, &ev);
187 } 153 }
154}
188 155
189 return ge->get_clients(ge, &client, 1, pos, frame->num_active, 156static int gesture_timeout(struct grail *ge, const struct utouch_frame *frame)
190 types, DIM_GRAIL_TYPE_BYTES); 157{
158 struct gesture_inserter *gin = ge->gin;
159
160 return grail_mask_count(gin->used, sizeof(gin->used)) == 0;
191} 161}
192 162
193static void report_frame(struct grail *ge, 163static void report_frame(struct grail *ge,
@@ -195,85 +165,27 @@ static void report_frame(struct grail *ge,
195 const struct input_event *syn) 165 const struct input_event *syn)
196{ 166{
197 struct grail_impl *impl = ge->impl; 167 struct grail_impl *impl = ge->impl;
198 struct gesture_recognizer *gru = ge->gru;
199 struct input_event iev;
200 struct grail_event gev; 168 struct grail_event gev;
201 169
202 ge->impl->frame = frame; 170 ge->impl->frame = frame;
203 171
204 /* Reset timer when number of touches changes. */ 172 if (frame->num_active && !frame->prev->num_active) {
205 if (frame->prev->revision != frame->revision && frame->num_active) { 173 impl->ongoing = 1;
206 gru->start_time = frame->time; 174 impl->gesture = 0;
207 } 175 }
208 176
209 /* Once touches have stabilized, check if there are any potential 177 if (!impl->ongoing)
210 * gestures registered for the number of touches. */ 178 return;
211 if (gru->state == RECOGNIZING &&
212 frame->time > gru->start_time + stable_time &&
213 check_potential_gestures(ge, frame) == 0)
214 gru->state = UNRECOGNIZED;
215
216 /* Process the frame for gestures unless we're sure there are none. */
217 if (gru->state != UNRECOGNIZED) {
218 gin_frame_begin(ge, frame);
219 gru_recognize(ge, frame);
220 gin_frame_end(ge, frame);
221 }
222 179
223 if (gru->state == RECOGNIZING) { 180 gin_frame_begin(ge, frame);
224 /* If a gesture is recognized and either all touches lifted or 181 gru_recognize(ge, frame);
225 * we are within the recognition interval, set state to 182 gin_frame_end(ge, frame);
226 * recognized. Note that taps do not stay in the used array, so
227 * we must check if any gesture events are buffered. */
228 if ((grail_mask_count(ge->gin->used, DIM_INSTANCE_BYTES) ||
229 !grailbuf_empty(&impl->gbuf)) &&
230 (frame->num_active == 0 ||
231 (frame->time > gru->start_time + stable_time &&
232 frame->time <= gru->start_time + recognition_time)))
233 gru->state = RECOGNIZED;
234 /* If there is no gesture and all touches lifted, set state to
235 * unrecognized. */
236 else if (frame->num_active == 0)
237 gru->state = UNRECOGNIZED;
238 }
239 183
240 /* Now we have the state set, process events. */ 184 if (!grailbuf_empty(&impl->gbuf))
241 switch (gru->state) { 185 impl->gesture = 1;
242 case RECOGNIZED: 186
243 while (!grailbuf_empty(&impl->gbuf)) { 187 if (frame->num_active == 0 || gesture_timeout(ge, frame))
244 grailbuf_get(&impl->gbuf, &gev); 188 impl->ongoing &= impl->gesture;
245 if (ge->gesture)
246 ge->gesture(ge, &gev);
247 }
248 evbuf_clear(&impl->evbuf);
249
250 /* Once all touches are lifted and no gestures are
251 * active, reset recognition state. */
252 if (grail_mask_count(ge->gin->used, DIM_INSTANCE_BYTES) == 0 &&
253 frame->num_active == 0)
254 gru->state = RECOGNIZING;
255 break;
256
257 case RECOGNIZING:
258 /* If we're still actively recognizing, stop here. */
259 if (frame->time <= gru->start_time + recognition_time)
260 break;
261 gru->state = UNRECOGNIZED;
262
263 case UNRECOGNIZED:
264 while (!evbuf_empty(&impl->evbuf)) {
265 evbuf_get(&impl->evbuf, &iev);
266 if (ge->event)
267 ge->event(ge, &iev);
268 }
269 grailbuf_clear(&impl->gbuf);
270
271 /* Once all touches are lifted, reset recognition
272 * state. */
273 if (frame->num_active == 0)
274 gru->state = RECOGNIZING;
275 break;
276 }
277} 189}
278 190
279static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev) 191static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev)
@@ -288,6 +200,13 @@ static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev)
288 if (frame) 200 if (frame)
289 report_frame(ge, frame, ev); 201 report_frame(ge, frame, ev);
290 } 202 }
203
204 if (ev->type == EV_SYN) {
205 if (!impl->ongoing)
206 flush_events(ge);
207 if (impl->gesture)
208 flush_gestures(ge);
209 }
291} 210}
292 211
293int grail_pull(struct grail *ge, int fd) 212int grail_pull(struct grail *ge, int fd)