Merge lp:~oif-team/grail/trunk.touch into lp:grail
- trunk.touch
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~oif-team/grail/trunk.touch |
Merge into: | lp:grail |
Diff against target: |
474 lines (+199/-35) 12 files modified
include/grail-types.h (+28/-0) src/Makefile.am (+1/-0) src/gestures-drag.c (+4/-8) src/gestures-pinch.c (+2/-6) src/gestures-rotate.c (+2/-6) src/gestures-touch.c (+94/-0) src/grail-gestures.c (+6/-7) src/grail-gestures.h (+4/-0) src/grail-inserter.c (+51/-8) src/grail-inserter.h (+3/-0) src/grail-recognizer.c (+2/-0) src/grail-recognizer.h (+2/-0) |
To merge this branch: | bzr merge lp:~oif-team/grail/trunk.touch |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Approve | ||
Stephen M. Webb | Pending | ||
Review via email: mp+55215@code.launchpad.net |
This proposal supersedes a proposal from 2011-03-26.
This proposal has been superseded by a proposal from 2011-03-28.
Commit message
Description of the change
This patchset introduces gesture touch events.
Chase Douglas (chasedouglas) wrote : Posted in a previous version of this proposal | # |
Henrik Rydberg (rydberg) wrote : Posted in a previous version of this proposal | # |
Seems like a mid-air collision - it seems they are present now.
Henrik Rydberg (rydberg) wrote : Posted in a previous version of this proposal | # |
Removed a stale variable and fixed one whitespace error, looks all good to me now.
Chase Douglas (chasedouglas) wrote : Posted in a previous version of this proposal | # |
In the grail-types.h file there's an old comment that should be removed:
+/* touch event types use drag properties */
I now seem unable to trigger any non-touch gestures when a touch gesture is performed, though...
Stephen M. Webb (bregma) wrote : Posted in a previous version of this proposal | # |
The code looks OK stylistically and seems to work as I expected through geistest (once installed correctly). I do not have a problem with this.
Henrik Rydberg (rydberg) wrote : | # |
There were some confusion as to what was a bug and what was expected behavior, but hopefully that is all straightened out now. This version seem to solve the known issues. Also see 744391 for another bugfix that goes on top of these.
Chase Douglas (chasedouglas) wrote : | # |
Still has the touch types comment that should be removed :).
- 133. By Henrik Rydberg
-
Introduce touch gesture events
Touch gesture events follow the same logic as drags, except they
cannot be held back but are emitted immediately.Signed-off-by: Henrik Rydberg <email address hidden>
- 134. By Henrik Rydberg
-
Decouple timeout from discard
Move the actual gesture discard from the recognition phase
to the instantiation phase.Signed-off-by: Henrik Rydberg <email address hidden>
- 135. By Henrik Rydberg
-
Do not timeout gestures overlapping touch gestures
The notion of listening to touch gestures implies that the
touches of those gestures never timeout. Hence, any pending
gesture that overlaps those touches should not timeout.Signed-off-by: Henrik Rydberg <email address hidden>
- 136. By Henrik Rydberg
-
Never active gestures below activation threshold
Currently, all gestures activate after a certain time, such that
the smallest change result in gesture events. This was designed
to minimize disruption in pointer movement. Since grail no longer
handles pointers, the logic can be simplified to only activate when
the threshold is reached.Signed-off-by: Henrik Rydberg <email address hidden>
- 137. By Henrik Rydberg
-
Do not treat single finger activation differently
Single-finger drags should no longer behave differently from
any other drag gesture. Fixed with this patch.Signed-off-by: Henrik Rydberg <email address hidden>
- 138. By Henrik Rydberg
-
Do not hold back active gestures
Gestures that has once been sent should never be held back. The
current code would under some circumstance hold the gesture end
event and later discard it. This oneliner solves the problem, which
has been around since 241c5ec, Aug 2010. LP: #744391.Signed-off-by: Henrik Rydberg <email address hidden>
Chase Douglas (chasedouglas) wrote : | # |
All my comments have been addressed, and it appears to be working properly through gesturetest and geistest (with the new and improved utouch-geis :).
Unmerged revisions
Preview Diff
1 | === modified file 'include/grail-types.h' |
2 | --- include/grail-types.h 2010-08-19 20:36:11 +0000 |
3 | +++ include/grail-types.h 2011-03-28 20:03:33 +0000 |
4 | @@ -59,11 +59,20 @@ |
5 | |
6 | #define GRAIL_TYPE_SYSFLAG1 26 /* reserved system flag */ |
7 | |
8 | +#define GRAIL_TYPE_TOUCH1 32 /* one-finger touch */ |
9 | +#define GRAIL_TYPE_TOUCH2 33 /* two-finger touch */ |
10 | +#define GRAIL_TYPE_TOUCH3 34 /* three-finger touch */ |
11 | +#define GRAIL_TYPE_TOUCH4 35 /* four-finger touch */ |
12 | +#define GRAIL_TYPE_TOUCH5 36 /* five-finger touch */ |
13 | +#define GRAIL_TYPE_ETOUCH 37 /* three-finger environment touch */ |
14 | +#define GRAIL_TYPE_MTOUCH 38 /* four-finger meta touch */ |
15 | + |
16 | #define GRAIL_MAIN_DRAG 0 |
17 | #define GRAIL_MAIN_PINCH 1 |
18 | #define GRAIL_MAIN_ROTATE 2 |
19 | #define GRAIL_MAIN_TAP 3 |
20 | #define GRAIL_MAIN_SYSFLAG 4 |
21 | +#define GRAIL_MAIN_TOUCH 5 |
22 | |
23 | #define GRAIL_PROP_DRAG_DX 0 /* horizontal position delta */ |
24 | #define GRAIL_PROP_DRAG_DY 1 /* vertical position delta */ |
25 | @@ -160,5 +169,24 @@ |
26 | #define GRAIL_PROP_TAP_X_T4 20 |
27 | #define GRAIL_PROP_TAP_Y_T4 21 |
28 | |
29 | +#define GRAIL_PROP_TOUCH_X1 0 /* bounding box x1 */ |
30 | +#define GRAIL_PROP_TOUCH_Y1 1 /* bounding box y1 */ |
31 | +#define GRAIL_PROP_TOUCH_X2 2 /* bounding box x2 */ |
32 | +#define GRAIL_PROP_TOUCH_Y2 3 /* bounding box y2 */ |
33 | +#define GRAIL_PROP_TOUCH_ID_T0 4 /* first touch id */ |
34 | +#define GRAIL_PROP_TOUCH_X_T0 5 /* first touch horizontal position */ |
35 | +#define GRAIL_PROP_TOUCH_Y_T0 6 /* first touch vertical position */ |
36 | +#define GRAIL_PROP_TOUCH_ID_T1 7 |
37 | +#define GRAIL_PROP_TOUCH_X_T1 8 |
38 | +#define GRAIL_PROP_TOUCH_Y_T1 9 |
39 | +#define GRAIL_PROP_TOUCH_ID_T2 10 |
40 | +#define GRAIL_PROP_TOUCH_X_T2 11 |
41 | +#define GRAIL_PROP_TOUCH_Y_T2 12 |
42 | +#define GRAIL_PROP_TOUCH_ID_T3 13 |
43 | +#define GRAIL_PROP_TOUCH_X_T3 14 |
44 | +#define GRAIL_PROP_TOUCH_Y_T3 15 |
45 | +#define GRAIL_PROP_TOUCH_ID_T4 16 |
46 | +#define GRAIL_PROP_TOUCH_X_T4 17 |
47 | +#define GRAIL_PROP_TOUCH_Y_T4 18 |
48 | |
49 | #endif |
50 | |
51 | === modified file 'src/Makefile.am' |
52 | --- src/Makefile.am 2011-01-02 12:08:42 +0000 |
53 | +++ src/Makefile.am 2011-03-28 20:03:33 +0000 |
54 | @@ -17,6 +17,7 @@ |
55 | grail-inserter.h \ |
56 | grail-gestures.c \ |
57 | grail-gestures.h \ |
58 | + gestures-touch.c \ |
59 | gestures-drag.c \ |
60 | gestures-pinch.c \ |
61 | gestures-rotate.c \ |
62 | |
63 | === modified file 'src/gestures-drag.c' |
64 | --- src/gestures-drag.c 2011-03-17 09:48:13 +0000 |
65 | +++ src/gestures-drag.c 2011-03-28 20:03:33 +0000 |
66 | @@ -70,10 +70,8 @@ |
67 | } |
68 | if ((move->timeout & fm_mask) == fm_mask) { |
69 | if (state->active) { |
70 | - gin_gid_discard(ge, state->gid); |
71 | - state->active = 0; |
72 | + gin_gid_timeout(ge, state->gid); |
73 | } |
74 | - return 0; |
75 | } |
76 | if (!state->active) { |
77 | int type = getype[move->ntouch]; |
78 | @@ -84,7 +82,7 @@ |
79 | } |
80 | if (!(move->tickle & mask)) |
81 | return 0; |
82 | - if (!move->single && !(move->active & fm_mask)) |
83 | + if (!(move->active & fm_mask)) |
84 | return 0; |
85 | set_props(ge->gin, state, move, frame); |
86 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
87 | @@ -107,10 +105,8 @@ |
88 | } |
89 | if ((move->timeout & fm_mask) == fm_mask) { |
90 | if (state->active) { |
91 | - gin_gid_discard(ge, state->gid); |
92 | - state->active = 0; |
93 | + gin_gid_timeout(ge, state->gid); |
94 | } |
95 | - return 0; |
96 | } |
97 | if (!state->active) { |
98 | if (move->ntouch == 4) { |
99 | @@ -131,7 +127,7 @@ |
100 | } |
101 | if (!(move->tickle & mask)) |
102 | return 0; |
103 | - if (!move->single && !(move->active & fm_mask)) |
104 | + if (!(move->active & fm_mask)) |
105 | return 0; |
106 | set_props(ge->gin, state, move, frame); |
107 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
108 | |
109 | === modified file 'src/gestures-pinch.c' |
110 | --- src/gestures-pinch.c 2011-03-17 09:48:13 +0000 |
111 | +++ src/gestures-pinch.c 2011-03-28 20:03:33 +0000 |
112 | @@ -64,10 +64,8 @@ |
113 | } |
114 | if ((move->timeout & fm_mask) == fm_mask) { |
115 | if (state->active) { |
116 | - gin_gid_discard(ge, state->gid); |
117 | - state->active = 0; |
118 | + gin_gid_timeout(ge, state->gid); |
119 | } |
120 | - return 0; |
121 | } |
122 | if (!(move->tickle & mask)) |
123 | return 0; |
124 | @@ -102,10 +100,8 @@ |
125 | } |
126 | if ((move->timeout & fm_mask) == fm_mask) { |
127 | if (state->active) { |
128 | - gin_gid_discard(ge, state->gid); |
129 | - state->active = 0; |
130 | + gin_gid_timeout(ge, state->gid); |
131 | } |
132 | - return 0; |
133 | } |
134 | if (!(move->tickle & mask)) |
135 | return 0; |
136 | |
137 | === modified file 'src/gestures-rotate.c' |
138 | --- src/gestures-rotate.c 2011-02-24 22:51:33 +0000 |
139 | +++ src/gestures-rotate.c 2011-03-28 20:03:33 +0000 |
140 | @@ -63,10 +63,8 @@ |
141 | } |
142 | if ((move->timeout & fm_mask) == fm_mask) { |
143 | if (state->active) { |
144 | - gin_gid_discard(ge, state->gid); |
145 | - state->active = 0; |
146 | + gin_gid_timeout(ge, state->gid); |
147 | } |
148 | - return 0; |
149 | } |
150 | if (!(move->tickle & mask)) |
151 | return 0; |
152 | @@ -101,10 +99,8 @@ |
153 | } |
154 | if ((move->timeout & fm_mask) == fm_mask) { |
155 | if (state->active) { |
156 | - gin_gid_discard(ge, state->gid); |
157 | - state->active = 0; |
158 | + gin_gid_timeout(ge, state->gid); |
159 | } |
160 | - return 0; |
161 | } |
162 | if (!(move->tickle & mask)) |
163 | return 0; |
164 | |
165 | === added file 'src/gestures-touch.c' |
166 | --- src/gestures-touch.c 1970-01-01 00:00:00 +0000 |
167 | +++ src/gestures-touch.c 2011-03-28 20:03:33 +0000 |
168 | @@ -0,0 +1,94 @@ |
169 | +/***************************************************************************** |
170 | + * |
171 | + * grail - Gesture Recognition And Instantiation Library |
172 | + * |
173 | + * Copyright (C) 2010 Canonical Ltd. |
174 | + * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> |
175 | + * |
176 | + * This program is free software: you can redistribute it and/or modify it |
177 | + * under the terms of the GNU General Public License as published by the |
178 | + * Free Software Foundation, either version 3 of the License, or (at your |
179 | + * option) any later version. |
180 | + * |
181 | + * This program is distributed in the hope that it will be useful, but |
182 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
183 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
184 | + * General Public License for more details. |
185 | + * |
186 | + * You should have received a copy of the GNU General Public License along |
187 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
188 | + * |
189 | + ****************************************************************************/ |
190 | + |
191 | +#include "grail-recognizer.h" |
192 | +#include <math.h> |
193 | +#include <stdio.h> |
194 | + |
195 | +static const int getype[DIM_TOUCH + 1] = { |
196 | + -1, |
197 | + GRAIL_TYPE_TOUCH1, |
198 | + GRAIL_TYPE_TOUCH2, |
199 | + GRAIL_TYPE_TOUCH3, |
200 | + GRAIL_TYPE_TOUCH4, |
201 | + GRAIL_TYPE_TOUCH5, |
202 | +}; |
203 | + |
204 | +int gru_touch(struct grail *ge, |
205 | + const struct utouch_frame *frame) |
206 | +{ |
207 | + struct gesture_recognizer *gru = ge->gru; |
208 | + struct combo_model *state = &gru->touch; |
209 | + struct move_model *move = &gru->move; |
210 | + if (frame->slot_revision != frame->prev->slot_revision) { |
211 | + if (state->active) { |
212 | + gru_end(ge, state->gid, move, |
213 | + state->prop, state->nprop); |
214 | + state->active = 0; |
215 | + } |
216 | + } |
217 | + if (!state->active) { |
218 | + int type = getype[move->ntouch]; |
219 | + if (type <= 0) |
220 | + return 0; |
221 | + state->gid = gin_gid_begin(ge, type, -PRIO_GESTURE, frame); |
222 | + state->active = 1; |
223 | + } |
224 | + state->nprop = gin_add_contact_props(ge->gin, state->prop, frame); |
225 | + gru_event(ge, state->gid, move, state->prop, state->nprop); |
226 | + return 1; |
227 | +} |
228 | + |
229 | +int gru_wintouch(struct grail *ge, |
230 | + const struct utouch_frame *frame) |
231 | +{ |
232 | + struct gesture_recognizer *gru = ge->gru; |
233 | + struct combo_model *state = &gru->wintouch; |
234 | + struct move_model *move = &gru->move; |
235 | + if (frame->slot_revision != frame->prev->slot_revision) { |
236 | + if (state->active && out_of_bounds(state, move)) { |
237 | + gru_end(ge, state->gid, move, |
238 | + state->prop, state->nprop); |
239 | + state->active = 0; |
240 | + } |
241 | + } |
242 | + if (!state->active) { |
243 | + if (move->ntouch == 4) { |
244 | + state->gid = gin_gid_begin(ge, GRAIL_TYPE_MTOUCH, |
245 | + -PRIO_META, frame); |
246 | + state->mintouch = 1; |
247 | + state->maxtouch = 4; |
248 | + state->active = 1; |
249 | + } else if (move->ntouch == 3) { |
250 | + state->gid = gin_gid_begin(ge, GRAIL_TYPE_ETOUCH, |
251 | + -PRIO_ENV, frame); |
252 | + state->mintouch = 1; |
253 | + state->maxtouch = 3; |
254 | + state->active = 1; |
255 | + } else { |
256 | + return 0; |
257 | + } |
258 | + } |
259 | + state->nprop = gin_add_contact_props(ge->gin, state->prop, frame); |
260 | + gru_event(ge, state->gid, move, state->prop, state->nprop); |
261 | + return 1; |
262 | +} |
263 | |
264 | === modified file 'src/grail-gestures.c' |
265 | --- src/grail-gestures.c 2011-03-17 09:48:13 +0000 |
266 | +++ src/grail-gestures.c 2011-03-28 20:03:33 +0000 |
267 | @@ -133,15 +133,14 @@ |
268 | m->tickle &= ~(1 << i); |
269 | if (m->active & (1 << i)) |
270 | return; |
271 | - fm->action_delta = x - fm->original; |
272 | - if (t - fm->original_ms > fm->hold_ms && |
273 | - fabs(fm->action_delta) > fm->bar) { |
274 | - m->active |= (1 << i); |
275 | + fm->action_delta = 0; |
276 | + if (fabs(x - fm->original) > fm->bar) { |
277 | + if (t - fm->original_ms > fm->hold_ms) { |
278 | + m->active |= (1 << i); |
279 | + fm->action_delta = x - fm->original; |
280 | + } |
281 | } else if (t - fm->original_ms > fm->bar_ms) { |
282 | - m->active |= (1 << i); |
283 | m->timeout |= (1 << i); |
284 | - } else { |
285 | - fm->action_delta = 0; |
286 | } |
287 | } |
288 | |
289 | |
290 | === modified file 'src/grail-gestures.h' |
291 | --- src/grail-gestures.h 2011-02-24 22:51:17 +0000 |
292 | +++ src/grail-gestures.h 2011-03-28 20:03:33 +0000 |
293 | @@ -77,6 +77,8 @@ |
294 | grail_prop_t prop[DIM_GRAIL_PROP]; |
295 | }; |
296 | |
297 | +int gru_touch(struct grail *ge, |
298 | + const struct utouch_frame *frame); |
299 | int gru_drag(struct grail *ge, |
300 | const struct utouch_frame *frame); |
301 | int gru_pinch(struct grail *ge, |
302 | @@ -90,6 +92,8 @@ |
303 | return m->ntouch < s->mintouch || m->ntouch > s->maxtouch; |
304 | } |
305 | |
306 | +int gru_wintouch(struct grail *ge, |
307 | + const struct utouch_frame *frame); |
308 | int gru_windrag(struct grail *ge, |
309 | const struct utouch_frame *frame); |
310 | int gru_winpinch(struct grail *ge, |
311 | |
312 | === modified file 'src/grail-inserter.c' |
313 | --- src/grail-inserter.c 2011-03-17 09:48:13 +0000 |
314 | +++ src/grail-inserter.c 2011-03-28 20:03:33 +0000 |
315 | @@ -38,6 +38,18 @@ |
316 | return -1; |
317 | } |
318 | |
319 | +static int mask_overlap(const grail_mask_t *a, const grail_mask_t *b, |
320 | + int bytes) |
321 | +{ |
322 | + int i; |
323 | + |
324 | + for (i = 0; i < bytes; i++) |
325 | + if (a[i] & b[i]) |
326 | + return 1; |
327 | + |
328 | + return 0; |
329 | +} |
330 | + |
331 | // todo: spanning tree for multi-user case |
332 | static void setup_new_gestures(struct grail *ge, |
333 | const struct utouch_frame *frame) |
334 | @@ -114,33 +126,50 @@ |
335 | void gin_frame_end(struct grail *ge, const struct utouch_frame *frame) |
336 | { |
337 | struct gesture_inserter *gin = ge->gin; |
338 | - int i, hold = 0, discard = 0; |
339 | + grail_mask_t keep[DIM_TOUCH_BYTES]; |
340 | + int i, hold[2] = { 0, 0 }, discard[2] = { 0, 0 }; |
341 | |
342 | + memset(keep, 0, sizeof(keep)); |
343 | setup_new_gestures(ge, frame); |
344 | |
345 | grail_mask_foreach(i, gin->used, sizeof(gin->used)) { |
346 | struct slot_state *s = &gin->state[i]; |
347 | if (!s->nclient) |
348 | continue; |
349 | - if (s->priority > hold) |
350 | - hold = s->priority; |
351 | + if (s->priority > hold[s->slice]) |
352 | + hold[s->slice] = s->priority; |
353 | if (s->status != GRAIL_STATUS_UPDATE) |
354 | continue; |
355 | - if (s->priority > discard) |
356 | - discard = s->priority; |
357 | + if (s->priority > discard[s->slice]) |
358 | + discard[s->slice] = s->priority; |
359 | } |
360 | |
361 | grail_mask_foreach(i, gin->used, sizeof(gin->used)) { |
362 | struct slot_state *s = &gin->state[i]; |
363 | - if (!s->nclient || s->priority < discard) |
364 | + if (!s->nclient || s->priority < discard[s->slice]) |
365 | gin_gid_discard(ge, s->id); |
366 | } |
367 | |
368 | grail_mask_foreach(i, gin->used, sizeof(gin->used)) { |
369 | struct slot_state *s = &gin->state[i]; |
370 | + if (s->slice == 1) |
371 | + grail_mask_set_mask(keep, s->span, sizeof(keep)); |
372 | + } |
373 | + |
374 | + grail_mask_foreach(i, gin->used, sizeof(gin->used)) { |
375 | + struct slot_state *s = &gin->state[i]; |
376 | + if (!s->timeout) |
377 | + continue; |
378 | + if (mask_overlap(keep, s->span, sizeof(keep))) |
379 | + continue; |
380 | + gin_gid_discard(ge, s->id); |
381 | + } |
382 | + |
383 | + grail_mask_foreach(i, gin->used, sizeof(gin->used)) { |
384 | + struct slot_state *s = &gin->state[i]; |
385 | struct gesture_event ev; |
386 | grail_mask_set(gin->types, s->type); |
387 | - if (s->priority < hold) |
388 | + if (s->priority < hold[s->slice]) |
389 | continue; |
390 | while (!gebuf_empty(&s->buf)) { |
391 | gebuf_get(&s->buf, &ev); |
392 | @@ -166,7 +195,14 @@ |
393 | return -1; |
394 | s = &gin->state[i]; |
395 | s->type = type; |
396 | - s->priority = priority; |
397 | + if (priority < 0) { |
398 | + s->priority = -priority; |
399 | + s->slice = 1; |
400 | + } else { |
401 | + s->priority = priority; |
402 | + s->slice = 0; |
403 | + } |
404 | + s->timeout = 0; |
405 | s->id = gin->gestureid++ & MAX_GESTURE_ID; |
406 | s->status = GRAIL_STATUS_BEGIN; |
407 | s->nclient = 0; |
408 | @@ -193,6 +229,13 @@ |
409 | grail_mask_set(gin->unused, i); |
410 | } |
411 | |
412 | +void gin_gid_timeout(struct grail *ge, int gid) |
413 | +{ |
414 | + int i = find_gslot(ge->gin, gid); |
415 | + if (i >= 0) |
416 | + ge->gin->state[i].timeout = 1; |
417 | +} |
418 | + |
419 | void gin_gid_event(struct grail *ge, int gid, |
420 | float x, float y, int ntouch, |
421 | const grail_prop_t *prop, int nprop, |
422 | |
423 | === modified file 'src/grail-inserter.h' |
424 | --- src/grail-inserter.h 2011-03-17 09:48:13 +0000 |
425 | +++ src/grail-inserter.h 2011-03-28 20:03:33 +0000 |
426 | @@ -37,6 +37,8 @@ |
427 | struct slot_state { |
428 | int type; |
429 | int priority; |
430 | + int slice; |
431 | + int timeout; |
432 | int id; |
433 | int status; |
434 | int nclient; |
435 | @@ -78,6 +80,7 @@ |
436 | int gin_gid_begin(struct grail *ge, int type, int priority, |
437 | const struct utouch_frame *frame); |
438 | void gin_gid_discard(struct grail *ge, int gid); |
439 | +void gin_gid_timeout(struct grail *ge, int gid); |
440 | |
441 | void gin_gid_event(struct grail *ge, int gid, |
442 | float x, float y, int ntouch, |
443 | |
444 | === modified file 'src/grail-recognizer.c' |
445 | --- src/grail-recognizer.c 2011-01-02 12:08:08 +0000 |
446 | +++ src/grail-recognizer.c 2011-03-28 20:03:33 +0000 |
447 | @@ -47,9 +47,11 @@ |
448 | if (!ge->gin || !ge->gru) |
449 | return; |
450 | gru_motion(ge, frame); |
451 | + gru_touch(ge, frame); |
452 | gru_drag(ge, frame); |
453 | gru_pinch(ge, frame); |
454 | gru_rotate(ge, frame); |
455 | + gru_wintouch(ge, frame); |
456 | gru_windrag(ge, frame); |
457 | gru_winpinch(ge, frame); |
458 | gru_winrotate(ge, frame); |
459 | |
460 | === modified file 'src/grail-recognizer.h' |
461 | --- src/grail-recognizer.h 2011-02-24 22:49:22 +0000 |
462 | +++ src/grail-recognizer.h 2011-03-28 20:03:33 +0000 |
463 | @@ -27,9 +27,11 @@ |
464 | |
465 | struct gesture_recognizer { |
466 | struct move_model move; |
467 | + struct combo_model touch; |
468 | struct combo_model drag; |
469 | struct combo_model pinch; |
470 | struct combo_model rotate; |
471 | + struct combo_model wintouch; |
472 | struct combo_model windrag; |
473 | struct combo_model winpinch; |
474 | struct combo_model winrotate; |
I'm guessing the functionality is correct, but the header file is missing the TOUCH event attributes (just like there are separate DRAG, PINCH, ROTATE, etc. attributes).