Merge lp:~oif-team/grail/trunk.touches into lp:grail
- trunk.touches
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 67 |
Proposed branch: | lp:~oif-team/grail/trunk.touches |
Merge into: | lp:grail |
Diff against target: |
1834 lines (+688/-560) 20 files modified
configure.ac (+1/-1) include/grail-touch.h (+22/-43) include/grail-types.h (+76/-3) include/grail.h (+175/-4) src/Makefile.am (+2/-1) src/gestures-drag.c (+18/-11) src/gestures-pinch.c (+8/-15) src/gestures-rotate.c (+5/-12) src/gestures-tapping.c (+12/-5) src/grail-api.c (+28/-32) src/grail-event.c (+144/-0) src/grail-gestures.c (+12/-37) src/grail-gestures.h (+0/-2) src/grail-impl.h (+36/-0) src/grail-inserter.c (+20/-146) src/grail-inserter.h (+33/-0) src/touch-dev.c (+66/-102) src/touch-engine.c (+0/-135) test/grail-gesture.c (+11/-1) test/grail-touch.c (+19/-10) |
To merge this branch: | bzr merge lp:~oif-team/grail/trunk.touches |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Needs Fixing | ||
Review via email: mp+33152@code.launchpad.net |
Commit message
Description of the change
The last big change before release
1. Simplify the touch frame handling
2. Add the grail_get_
3. Simplify property scaling
4. Add information about the five first contacts to the property list
Point 4 is a suboptimal solution to bring individual touches to unity. The rest
are simplifications to accommodate the changes needed.
Chase Douglas (chasedouglas) wrote : | # |
Hrm, I reviewed the code changes and everything seemed ok. I then tried to make a tarball with make dist and I hit a snag. Revision 58 adds touch-caps.c to src/Makefile.am, but the file doesn't exist. I tried to fix this in lp:~chasedouglas/utouch-grail/trunk. However, now I get compile errors. I also got a different compile error when I imported into a local package branch and attempted to build.
One thing to note: don't even try to rewrite history in bzr. I just tried to find ways for the past two hours, and I haven't found anything that worked.
Henrik Rydberg (rydberg) wrote : | # |
On 08/20/2010 02:57 AM, Chase Douglas wrote:
> Review: Needs Fixing
> Hrm, I reviewed the code changes and everything seemed ok. I then tried to make a tarball with make dist and I hit a snag. Revision 58 adds touch-caps.c to src/Makefile.am, but the file doesn't exist. I tried to fix this in lp:~chasedouglas/utouch-grail/trunk. However, now I get compile errors. I also got a different compile error when I imported into a local package branch and attempted to build.
>
> One thing to note: don't even try to rewrite history in bzr. I just tried to find ways for the past two hours, and I haven't found anything that worked.
Thanks for finding this, new version uploaded.
Henrik
Preview Diff
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2010-08-12 15:56:04 +0000 |
3 | +++ configure.ac 2010-08-19 20:46:41 +0000 |
4 | @@ -1,7 +1,7 @@ |
5 | # Initialize Autoconf |
6 | AC_PREREQ([2.60]) |
7 | AC_INIT([Gesture Recognition And Instantiation Library], |
8 | - [1.0.8], |
9 | + [1.0.9], |
10 | [], |
11 | [utouch-grail]) |
12 | AC_CONFIG_SRCDIR([Makefile.am]) |
13 | |
14 | === modified file 'include/grail-touch.h' |
15 | --- include/grail-touch.h 2010-08-06 20:30:20 +0000 |
16 | +++ include/grail-touch.h 2010-08-19 20:46:41 +0000 |
17 | @@ -29,27 +29,20 @@ |
18 | #define DIM_TOUCH 32 |
19 | #define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3) |
20 | |
21 | -typedef int touch_prop_t; |
22 | typedef __u64 touch_time_t; |
23 | |
24 | -enum touch_prop_list { |
25 | - TP_POS_X, |
26 | - TP_POS_Y, |
27 | - TP_TOUCH_MAJOR, |
28 | - TP_TOUCH_MINOR, |
29 | - TP_WIDTH_MAJOR, |
30 | - TP_WIDTH_MINOR, |
31 | - TP_ORIENTATION, |
32 | - TP_PRESSURE, |
33 | - DIM_TOUCH_PROP |
34 | -}; |
35 | - |
36 | -#define DIM_TOUCH_PROP_BYTES ((DIM_TOUCH_PROP + 7) >> 3) |
37 | - |
38 | struct touch { |
39 | int active; |
40 | int slot; |
41 | - touch_prop_t prop[DIM_TOUCH_PROP]; |
42 | + int id; |
43 | + int tool_type; |
44 | + int x, y; |
45 | + int touch_major; |
46 | + int touch_minor; |
47 | + int width_major; |
48 | + int width_minor; |
49 | + int orientation; |
50 | + int pressure; |
51 | }; |
52 | |
53 | struct touch_frame { |
54 | @@ -61,45 +54,31 @@ |
55 | struct touch touch[DIM_TOUCH]; |
56 | }; |
57 | |
58 | -struct touch_dev_caps { |
59 | - grail_mask_t mask[DIM_TOUCH_PROP_BYTES]; |
60 | - struct input_absinfo info[DIM_TOUCH_PROP]; |
61 | +struct touch_caps { |
62 | + float min_x, max_x; |
63 | + float min_y, max_y; |
64 | + float min_orient, max_orient; |
65 | + float min_press, max_press; |
66 | }; |
67 | |
68 | struct touch_dev { |
69 | void (*event)(struct touch_dev *dev, const struct input_event *ev); |
70 | - void (*create)(struct touch_dev *dev, int slot, |
71 | - const grail_mask_t *mask, const touch_prop_t *prop); |
72 | - void (*modify)(struct touch_dev *dev, int slot, |
73 | - const grail_mask_t *mask, const touch_prop_t *prop); |
74 | - void (*destroy)(struct touch_dev *dev, int slot); |
75 | void (*sync)(struct touch_dev *dev, const struct input_event *syn); |
76 | - struct touch_dev_caps caps; |
77 | - struct touch_dev_impl *impl; |
78 | void *priv; |
79 | -}; |
80 | - |
81 | -struct touch_engine { |
82 | - void (*event)(struct touch_engine *engine, |
83 | - const struct input_event *ev); |
84 | - void (*sync)(struct touch_engine *engine, |
85 | - const struct input_event *syn); |
86 | + struct mtdev mtdev; |
87 | struct touch_frame frame; |
88 | - void *priv; |
89 | + struct touch_caps caps; |
90 | + int slot; |
91 | + int state; |
92 | }; |
93 | |
94 | +void touch_caps_init(struct touch_dev *dev); |
95 | +float touch_angle(const struct touch_dev *dev, int orientation); |
96 | +float touch_pressure(const struct touch_dev *dev, int pressure); |
97 | + |
98 | int touch_dev_open(struct touch_dev *dev, int fd); |
99 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms); |
100 | int touch_dev_pull(struct touch_dev *dev, int fd); |
101 | void touch_dev_close(struct touch_dev *dev, int fd); |
102 | |
103 | -void touch_engine_init(struct touch_engine *engine, |
104 | - void (*event)(struct touch_engine *engine, |
105 | - const struct input_event *ev), |
106 | - void (*sync)(struct touch_engine *engine, |
107 | - const struct input_event *ev), |
108 | - void *priv); |
109 | -void touch_engine_attach(struct touch_engine *engine, struct touch_dev *dev); |
110 | -void touch_engine_detach(struct touch_engine *engine, struct touch_dev *dev); |
111 | - |
112 | #endif |
113 | |
114 | === modified file 'include/grail-types.h' |
115 | --- include/grail-types.h 2010-08-11 17:07:08 +0000 |
116 | +++ include/grail-types.h 2010-08-19 20:46:41 +0000 |
117 | @@ -57,15 +57,40 @@ |
118 | #define GRAIL_TYPE_MPINCH 24 /* four-finger meta drag */ |
119 | #define GRAIL_TYPE_MROTATE 25 /* four-finger meta drag */ |
120 | |
121 | +#define GRAIL_TYPE_SYSFLAG1 26 /* reserved system flag */ |
122 | + |
123 | #define GRAIL_MAIN_DRAG 0 |
124 | +#define GRAIL_MAIN_PINCH 1 |
125 | +#define GRAIL_MAIN_ROTATE 2 |
126 | +#define GRAIL_MAIN_TAP 3 |
127 | +#define GRAIL_MAIN_SYSFLAG 4 |
128 | + |
129 | #define GRAIL_PROP_DRAG_DX 0 /* horizontal position delta */ |
130 | #define GRAIL_PROP_DRAG_DY 1 /* vertical position delta */ |
131 | #define GRAIL_PROP_DRAG_VX 2 /* horizontal velocity */ |
132 | #define GRAIL_PROP_DRAG_VY 3 /* vertical velocity */ |
133 | #define GRAIL_PROP_DRAG_X 4 /* horizontal position */ |
134 | #define GRAIL_PROP_DRAG_Y 5 /* vertical position */ |
135 | +#define GRAIL_PROP_DRAG_X1 6 /* bounding box x1 */ |
136 | +#define GRAIL_PROP_DRAG_Y1 7 /* bounding box y1 */ |
137 | +#define GRAIL_PROP_DRAG_X2 8 /* bounding box x2 */ |
138 | +#define GRAIL_PROP_DRAG_Y2 9 /* bounding box y2 */ |
139 | +#define GRAIL_PROP_DRAG_ID_T0 10 /* first touch id */ |
140 | +#define GRAIL_PROP_DRAG_X_T0 11 /* first touch horizontal position */ |
141 | +#define GRAIL_PROP_DRAG_Y_T0 12 /* first touch vertical position */ |
142 | +#define GRAIL_PROP_DRAG_ID_T1 13 |
143 | +#define GRAIL_PROP_DRAG_X_T1 14 |
144 | +#define GRAIL_PROP_DRAG_Y_T1 15 |
145 | +#define GRAIL_PROP_DRAG_ID_T2 16 |
146 | +#define GRAIL_PROP_DRAG_X_T2 17 |
147 | +#define GRAIL_PROP_DRAG_Y_T2 18 |
148 | +#define GRAIL_PROP_DRAG_ID_T3 19 |
149 | +#define GRAIL_PROP_DRAG_X_T3 20 |
150 | +#define GRAIL_PROP_DRAG_Y_T3 21 |
151 | +#define GRAIL_PROP_DRAG_ID_T4 22 |
152 | +#define GRAIL_PROP_DRAG_X_T4 23 |
153 | +#define GRAIL_PROP_DRAG_Y_T4 24 |
154 | |
155 | -#define GRAIL_MAIN_PINCH 1 |
156 | #define GRAIL_PROP_PINCH_DR 0 /* radius delta */ |
157 | #define GRAIL_PROP_PINCH_VR 1 /* radial velocity */ |
158 | #define GRAIL_PROP_PINCH_R 2 /* radius */ |
159 | @@ -73,8 +98,22 @@ |
160 | #define GRAIL_PROP_PINCH_Y1 4 /* bounding box y1 */ |
161 | #define GRAIL_PROP_PINCH_X2 5 /* bounding box x2 */ |
162 | #define GRAIL_PROP_PINCH_Y2 6 /* bounding box y2 */ |
163 | +#define GRAIL_PROP_PINCH_ID_T0 7 /* first touch id */ |
164 | +#define GRAIL_PROP_PINCH_X_T0 8 /* first touch horizontal position */ |
165 | +#define GRAIL_PROP_PINCH_Y_T0 9 /* first touch vertical position */ |
166 | +#define GRAIL_PROP_PINCH_ID_T1 10 |
167 | +#define GRAIL_PROP_PINCH_X_T1 11 |
168 | +#define GRAIL_PROP_PINCH_Y_T1 12 |
169 | +#define GRAIL_PROP_PINCH_ID_T2 13 |
170 | +#define GRAIL_PROP_PINCH_X_T2 14 |
171 | +#define GRAIL_PROP_PINCH_Y_T2 15 |
172 | +#define GRAIL_PROP_PINCH_ID_T3 16 |
173 | +#define GRAIL_PROP_PINCH_X_T3 17 |
174 | +#define GRAIL_PROP_PINCH_Y_T3 18 |
175 | +#define GRAIL_PROP_PINCH_ID_T4 19 |
176 | +#define GRAIL_PROP_PINCH_X_T4 20 |
177 | +#define GRAIL_PROP_PINCH_Y_T4 21 |
178 | |
179 | -#define GRAIL_MAIN_ROTATE 2 |
180 | #define GRAIL_PROP_ROTATE_DA 0 /* angle delta */ |
181 | #define GRAIL_PROP_ROTATE_VA 1 /* angular velocity */ |
182 | #define GRAIL_PROP_ROTATE_A 2 /* angle */ |
183 | @@ -82,10 +121,44 @@ |
184 | #define GRAIL_PROP_ROTATE_Y1 4 /* bounding box y1 */ |
185 | #define GRAIL_PROP_ROTATE_X2 5 /* bounding box x2 */ |
186 | #define GRAIL_PROP_ROTATE_Y2 6 /* bounding box y2 */ |
187 | +#define GRAIL_PROP_ROTATE_ID_T0 7 /* first touch id */ |
188 | +#define GRAIL_PROP_ROTATE_X_T0 8 /* first touch horizontal position */ |
189 | +#define GRAIL_PROP_ROTATE_Y_T0 9 /* first touch vertical position */ |
190 | +#define GRAIL_PROP_ROTATE_ID_T1 10 |
191 | +#define GRAIL_PROP_ROTATE_X_T1 11 |
192 | +#define GRAIL_PROP_ROTATE_Y_T1 12 |
193 | +#define GRAIL_PROP_ROTATE_ID_T2 13 |
194 | +#define GRAIL_PROP_ROTATE_X_T2 14 |
195 | +#define GRAIL_PROP_ROTATE_Y_T2 15 |
196 | +#define GRAIL_PROP_ROTATE_ID_T3 16 |
197 | +#define GRAIL_PROP_ROTATE_X_T3 17 |
198 | +#define GRAIL_PROP_ROTATE_Y_T3 18 |
199 | +#define GRAIL_PROP_ROTATE_ID_T4 19 |
200 | +#define GRAIL_PROP_ROTATE_X_T4 20 |
201 | +#define GRAIL_PROP_ROTATE_Y_T4 21 |
202 | |
203 | -#define GRAIL_MAIN_TAP 3 |
204 | #define GRAIL_PROP_TAP_DT 0 /* tap time (ms) */ |
205 | #define GRAIL_PROP_TAP_X 1 /* horizontal position */ |
206 | #define GRAIL_PROP_TAP_Y 2 /* vertical position */ |
207 | +#define GRAIL_PROP_TAP_X1 3 /* bounding box x1 */ |
208 | +#define GRAIL_PROP_TAP_Y1 4 /* bounding box y1 */ |
209 | +#define GRAIL_PROP_TAP_X2 5 /* bounding box x2 */ |
210 | +#define GRAIL_PROP_TAP_Y2 6 /* bounding box y2 */ |
211 | +#define GRAIL_PROP_TAP_ID_T0 7 /* first touch id */ |
212 | +#define GRAIL_PROP_TAP_X_T0 8 /* first touch horizontal position */ |
213 | +#define GRAIL_PROP_TAP_Y_T0 9 /* first touch vertical position */ |
214 | +#define GRAIL_PROP_TAP_ID_T1 10 |
215 | +#define GRAIL_PROP_TAP_X_T1 11 |
216 | +#define GRAIL_PROP_TAP_Y_T1 12 |
217 | +#define GRAIL_PROP_TAP_ID_T2 13 |
218 | +#define GRAIL_PROP_TAP_X_T2 14 |
219 | +#define GRAIL_PROP_TAP_Y_T2 15 |
220 | +#define GRAIL_PROP_TAP_ID_T3 16 |
221 | +#define GRAIL_PROP_TAP_X_T3 17 |
222 | +#define GRAIL_PROP_TAP_Y_T3 18 |
223 | +#define GRAIL_PROP_TAP_ID_T4 19 |
224 | +#define GRAIL_PROP_TAP_X_T4 20 |
225 | +#define GRAIL_PROP_TAP_Y_T4 21 |
226 | + |
227 | |
228 | #endif |
229 | |
230 | === modified file 'include/grail.h' |
231 | --- include/grail.h 2010-08-11 17:07:40 +0000 |
232 | +++ include/grail.h 2010-08-19 20:46:41 +0000 |
233 | @@ -30,30 +30,92 @@ |
234 | #define DIM_GRAIL_TYPE 64 |
235 | #define DIM_GRAIL_TYPE_BYTES ((DIM_GRAIL_TYPE + 7) >> 3) |
236 | |
237 | -#define DIM_GRAIL_PROP 16 |
238 | +#define DIM_GRAIL_PROP 32 |
239 | #define DIM_GRAIL_PROP_BYTES ((DIM_GRAIL_PROP + 7) >> 3) |
240 | |
241 | #define GRAIL_STATUS_BEGIN 0 |
242 | #define GRAIL_STATUS_UPDATE 1 |
243 | #define GRAIL_STATUS_END 2 |
244 | |
245 | -typedef float grail_prop_t; |
246 | -typedef __u64 grail_time_t; |
247 | +typedef float grail_prop_t; /* gesture properties */ |
248 | +typedef __u64 grail_time_t; /* time in milliseconds */ |
249 | |
250 | +/** |
251 | + * struct grail_coord - coordinate in bounding box units |
252 | + * @x: the horizontal position (bbox units) |
253 | + * @y: the vertical position (bbox units) |
254 | + */ |
255 | struct grail_coord { |
256 | float x, y; |
257 | }; |
258 | |
259 | +/** |
260 | + * struct grail_contact - MT event information in bounding box units |
261 | + * @id: Contact tracking id |
262 | + * @tool_type: Tool type (ABS_MT_TOOL_TYPE) |
263 | + * @pos: Position of contact (bbox units) |
264 | + * @touch_major: Major axis of contact shape (bbox units) |
265 | + * @touch_minor: Minor axis of contact shape (bbox units) |
266 | + * @width_major: Major axis of perimeter (bbox units) |
267 | + * @width_minor: Minor axis of perimeter (bbox units) |
268 | + * @angle: Angle of orientation (vertical: 0 horizontal: +-M_PI_2) |
269 | + * @pressure: Pressure of contact (min: 0 max: 1) |
270 | + * |
271 | + * Depending on the native support of the underlying device, some or all of |
272 | + * the listed properties may be computed. |
273 | + */ |
274 | +struct grail_contact { |
275 | + int id; |
276 | + int tool_type; |
277 | + struct grail_coord pos; |
278 | + float touch_major; |
279 | + float touch_minor; |
280 | + float width_major; |
281 | + float width_minor; |
282 | + float angle; |
283 | + float pressure; |
284 | +}; |
285 | + |
286 | +/** |
287 | + * struct grail_client_id - Gesture client information |
288 | + * @client: Client id |
289 | + * @root: Root window |
290 | + * @event: Window to route events to |
291 | + * @child: Window the event occured in |
292 | + * |
293 | + * This struct is treated opaquely, and only has meaning to the gesture |
294 | + * client. Details are subject to change. |
295 | + */ |
296 | struct grail_client_id { |
297 | int client; |
298 | int root, event, child; |
299 | }; |
300 | |
301 | +/** |
302 | + * struct grail_client_info - Gesture request information |
303 | + * @id: Gesture client id |
304 | + * @mask: Gestures the client is listening to |
305 | + */ |
306 | struct grail_client_info { |
307 | struct grail_client_id id; |
308 | grail_mask_t mask[DIM_GRAIL_TYPE_BYTES]; |
309 | }; |
310 | |
311 | +/** |
312 | + * struct grail_event - Gesture event |
313 | + * @type: The gesture type |
314 | + * @id: Unique identifier foof the gesture instance |
315 | + * @status: Gesture status (begin, update, end) |
316 | + * @ntouch: Number of current touches |
317 | + * @nprop: Number of properties in the gesture |
318 | + * @pos: Focus point of the gesture (bbox coordinates) |
319 | + * @touch: Array of individual touch information |
320 | + * @client_id: The gesture client to route the gesture to |
321 | + * @time: Time of event (milliseconds) |
322 | + * @prop: Array of properties of the event |
323 | + * |
324 | + * Gesture events are passed to the client via the gesture() callback. |
325 | + */ |
326 | struct grail_event { |
327 | int type; |
328 | int id; |
329 | @@ -66,6 +128,25 @@ |
330 | grail_prop_t prop[DIM_GRAIL_PROP]; |
331 | }; |
332 | |
333 | +/** |
334 | + * struct grail - Main grail device |
335 | + * @get_clients: Called at the onset of new gestures to retrieve the list |
336 | + * of listening clients. |
337 | + * @event: Callback for kernel events passing through grail. |
338 | + * @gesture: Main gesture callback. |
339 | + * @impl: Grail implementation details. |
340 | + * @gin: Gesture instatiation details. |
341 | + * @gru: Gesture recognition details. |
342 | + * @priv: Generic pointer to user-defined content. |
343 | + * |
344 | + * The grail device pulls events from the underlying device, detects |
345 | + * gestures, and passes them on to the client via the gesture() |
346 | + * callback. Events that are not gesture or for other reasons held back are |
347 | + * passed on via the event() callback. The user provides information about |
348 | + * windows and listening clients via the get_clients callback, which is |
349 | + * called during gesture instantiation. |
350 | + * |
351 | + */ |
352 | struct grail { |
353 | int (*get_clients)(struct grail *ge, |
354 | struct grail_client_info *client, int max_clients, |
355 | @@ -81,18 +162,108 @@ |
356 | void *priv; |
357 | }; |
358 | |
359 | +/** |
360 | + * grail_open - open a grail device |
361 | + * @ge: the grail device to open |
362 | + * @fd: file descriptor of the kernel device |
363 | + * |
364 | + * Initialize the internal grail structures and configure it by reading the |
365 | + * protocol capabilities through the file descriptor. |
366 | + * |
367 | + * The callbacks, parameters and priv pointer should be set prior to this |
368 | + * call. |
369 | + * |
370 | + * Returns zero on success, negative error number otherwise. |
371 | + */ |
372 | int grail_open(struct grail *ge, int fd); |
373 | + |
374 | +/** |
375 | + * grail_idle - check state of kernel device |
376 | + * @ge: the grail device in use |
377 | + * @fd: file descriptor of the kernel device |
378 | + * @ms: number of milliseconds to wait for activity |
379 | + * |
380 | + * Returns true if the device is idle, i.e., there are no fetched |
381 | + * events in the pipe and there is nothing to fetch from the device. |
382 | + */ |
383 | int grail_idle(struct grail *ge, int fd, int ms); |
384 | + |
385 | +/** |
386 | + * grail_pull - pull and process available events from the kernel device |
387 | + * @ge: the grail device in use |
388 | + * @fd: file descriptor of the kernel device |
389 | + * |
390 | + * Pull all available events and process them. The grail callbacks are |
391 | + * invoked during this call. |
392 | + * |
393 | + * The underlying file descriptor must have O_NONBLOCK set, or this method |
394 | + * will not return until the file is closed. |
395 | + * |
396 | + * On success, returns the number of events read. Otherwise, |
397 | + * a standard negative error number is returned. |
398 | + */ |
399 | int grail_pull(struct grail *ge, int fd); |
400 | + |
401 | +/** |
402 | + * grail_close - close the grail device |
403 | + * @ge: the grail device to close |
404 | + * @fd: file descriptor of the kernel device |
405 | + * |
406 | + * Deallocates all memory associated with grail, and clears the grail |
407 | + * structure. |
408 | + */ |
409 | void grail_close(struct grail *ge, int fd); |
410 | |
411 | +/** |
412 | + * grail_set_bbox - set the grail unit bounding box |
413 | + * @ge: the grail device in use |
414 | + * @min: the minimum (lower-left) corner of the bounding box |
415 | + * @max: the maximum (upper-right) corner of the bounding box |
416 | + * |
417 | + * Sets the box within which the device coordinates should be presented. |
418 | + */ |
419 | void grail_set_bbox(struct grail *ge, |
420 | const struct grail_coord *min, |
421 | const struct grail_coord *max); |
422 | |
423 | +/** |
424 | + * grail_filter_abs_events - filter kernel motion events |
425 | + * @ge: the grail device in use |
426 | + * @usage: When true, filter kernel motion events. |
427 | + * |
428 | + * Single-finger pointer events are treated as pointer gestures in |
429 | + * grail. When filter_motion_events is non-zero, the kernel events |
430 | + * corresponding to pointer movement are removed from the event |
431 | + * stream. |
432 | + * |
433 | + */ |
434 | +void grail_filter_abs_events(struct grail *ge, int usage); |
435 | + |
436 | +/** |
437 | + * grail_get_units - get device coordinate ranges |
438 | + * @ge: the grail device in use |
439 | + * @min: minimum x and y coordinates |
440 | + * @max: maximum x and y coordinates |
441 | + * |
442 | + * The grail event attributes pos, touch_major, touch_minor, |
443 | + * width_major, and width_minor are all given in device coordinate |
444 | + * units, unless specified otherwise using the grail_set_bbox() |
445 | + * function. This function reports the device coordinate ranges. |
446 | + * |
447 | + */ |
448 | void grail_get_units(const struct grail *ge, |
449 | struct grail_coord *min, struct grail_coord *max); |
450 | |
451 | -void grail_filter_abs_events(struct grail *ge, int usage); |
452 | +/** |
453 | + * grail_get_contacts - get current contact state |
454 | + * @ge: the grail device in use |
455 | + * @touch: array of contacts to be filled in |
456 | + * @max_touch: maximum number of contacts supported by the array |
457 | + * |
458 | + * Extract the contact state as currently seen by grail. |
459 | + * |
460 | + */ |
461 | +int grail_get_contacts(const struct grail *ge, |
462 | + struct grail_contact *touch, int max_touch); |
463 | |
464 | #endif |
465 | |
466 | === modified file 'src/Makefile.am' |
467 | --- src/Makefile.am 2010-08-12 15:55:30 +0000 |
468 | +++ src/Makefile.am 2010-08-19 20:46:41 +0000 |
469 | @@ -9,7 +9,7 @@ |
470 | evbuf.h \ |
471 | gebuf.h \ |
472 | touch-dev.c \ |
473 | - touch-engine.c \ |
474 | + touch-caps.c \ |
475 | grail-bits.c \ |
476 | grail-inserter.c \ |
477 | grail-inserter.h \ |
478 | @@ -21,6 +21,7 @@ |
479 | gestures-tapping.c \ |
480 | grail-recognizer.c \ |
481 | grail-recognizer.h \ |
482 | + grail-event.c \ |
483 | grail-api.c |
484 | |
485 | AM_CFLAGS = $(CWARNFLAGS) |
486 | |
487 | === modified file 'src/gestures-drag.c' |
488 | --- src/gestures-drag.c 2010-08-11 17:04:45 +0000 |
489 | +++ src/gestures-drag.c 2010-08-19 20:46:41 +0000 |
490 | @@ -33,20 +33,27 @@ |
491 | GRAIL_TYPE_DRAG5, |
492 | }; |
493 | |
494 | -static void set_props(struct combo_model *s, const struct move_model *m) |
495 | +static void set_props(const struct gesture_inserter *gin, |
496 | + struct combo_model *s, const struct move_model *m, |
497 | + const struct touch_frame *frame) |
498 | { |
499 | if (m->single) { |
500 | - s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].raw_delta; |
501 | - s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].raw_delta; |
502 | + s->prop[GRAIL_PROP_DRAG_DX] = |
503 | + gin->scale_x * m->fm[FM_X].raw_delta; |
504 | + s->prop[GRAIL_PROP_DRAG_DY] = |
505 | + gin->scale_y * m->fm[FM_Y].raw_delta; |
506 | } else { |
507 | - s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].action_delta; |
508 | - s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].action_delta; |
509 | + s->prop[GRAIL_PROP_DRAG_DX] = |
510 | + gin->scale_x * m->fm[FM_X].action_delta; |
511 | + s->prop[GRAIL_PROP_DRAG_DY] = |
512 | + gin->scale_y * m->fm[FM_Y].action_delta; |
513 | } |
514 | - s->prop[GRAIL_PROP_DRAG_VX] = m->fm[FM_X].velocity; |
515 | - s->prop[GRAIL_PROP_DRAG_VY] = m->fm[FM_Y].velocity; |
516 | - s->prop[GRAIL_PROP_DRAG_X] = m->fm[FM_X].value; |
517 | - s->prop[GRAIL_PROP_DRAG_Y] = m->fm[FM_Y].value; |
518 | + s->prop[GRAIL_PROP_DRAG_VX] = gin->scale_x * m->fm[FM_X].velocity; |
519 | + s->prop[GRAIL_PROP_DRAG_VY] = gin->scale_y * m->fm[FM_Y].velocity; |
520 | + s->prop[GRAIL_PROP_DRAG_X] = gin_prop_x(gin, m->fm[FM_X].value); |
521 | + s->prop[GRAIL_PROP_DRAG_Y] = gin_prop_y(gin, m->fm[FM_Y].value); |
522 | s->nprop = 6; |
523 | + s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame); |
524 | } |
525 | |
526 | static const int fm_mask = 0x03; |
527 | @@ -77,7 +84,7 @@ |
528 | } |
529 | if (!move->single && !(move->active & fm_mask)) |
530 | return 0; |
531 | - set_props(state, move); |
532 | + set_props(ge->gin, state, move, frame); |
533 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
534 | return 1; |
535 | } |
536 | @@ -118,7 +125,7 @@ |
537 | } |
538 | if (!move->single && !(move->active & fm_mask)) |
539 | return 0; |
540 | - set_props(state, move); |
541 | + set_props(ge->gin, state, move, frame); |
542 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
543 | return 1; |
544 | } |
545 | |
546 | === modified file 'src/gestures-pinch.c' |
547 | --- src/gestures-pinch.c 2010-08-11 17:06:36 +0000 |
548 | +++ src/gestures-pinch.c 2010-08-19 20:46:41 +0000 |
549 | @@ -35,23 +35,16 @@ |
550 | |
551 | static const int fm_mask = 0x04; |
552 | |
553 | -static void set_props(struct combo_model *s, |
554 | +static void set_props(const struct gesture_inserter *gin, |
555 | + struct combo_model *s, |
556 | const struct move_model *m, |
557 | const struct touch_frame *frame) |
558 | { |
559 | - struct grail_coord min, max; |
560 | - s->prop[GRAIL_PROP_PINCH_DR] = m->fm[FM_R].action_delta; |
561 | - s->prop[GRAIL_PROP_PINCH_VR] = m->fm[FM_R].velocity; |
562 | - s->prop[GRAIL_PROP_PINCH_R] = m->fm[FM_R].value; |
563 | + s->prop[GRAIL_PROP_PINCH_DR] = gin->scale_r * m->fm[FM_R].action_delta; |
564 | + s->prop[GRAIL_PROP_PINCH_VR] = gin->scale_r * m->fm[FM_R].velocity; |
565 | + s->prop[GRAIL_PROP_PINCH_R] = gin->scale_r * m->fm[FM_R].value; |
566 | s->nprop = 3; |
567 | - if (!frame->nactive) |
568 | - return; |
569 | - gru_compute_bbox(&min, &max, frame); |
570 | - s->prop[GRAIL_PROP_PINCH_X1] = min.x; |
571 | - s->prop[GRAIL_PROP_PINCH_Y1] = min.y; |
572 | - s->prop[GRAIL_PROP_PINCH_X2] = max.x; |
573 | - s->prop[GRAIL_PROP_PINCH_Y2] = max.y; |
574 | - s->nprop = 7; |
575 | + s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame); |
576 | } |
577 | |
578 | int gru_pinch(struct grail *ge, |
579 | @@ -80,7 +73,7 @@ |
580 | } |
581 | if (!(move->active & fm_mask)) |
582 | return 0; |
583 | - set_props(state, move, frame); |
584 | + set_props(ge->gin, state, move, frame); |
585 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
586 | return 1; |
587 | } |
588 | @@ -121,7 +114,7 @@ |
589 | } |
590 | if (!(move->active & fm_mask)) |
591 | return 0; |
592 | - set_props(state, move, frame); |
593 | + set_props(ge->gin, state, move, frame); |
594 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
595 | return 1; |
596 | } |
597 | |
598 | === modified file 'src/gestures-rotate.c' |
599 | --- src/gestures-rotate.c 2010-08-11 17:07:08 +0000 |
600 | +++ src/gestures-rotate.c 2010-08-19 20:46:41 +0000 |
601 | @@ -35,22 +35,15 @@ |
602 | |
603 | static const int fm_mask = 0x08; |
604 | |
605 | -static void set_props(struct combo_model *s, const struct move_model *m, |
606 | +static void set_props(const struct gesture_inserter *gin, |
607 | + struct combo_model *s, const struct move_model *m, |
608 | const struct touch_frame *frame) |
609 | { |
610 | - struct grail_coord min, max; |
611 | s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta; |
612 | s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity; |
613 | s->prop[GRAIL_PROP_ROTATE_A] = m->fm[FM_A].value; |
614 | s->nprop = 3; |
615 | - if (!frame->nactive) |
616 | - return; |
617 | - gru_compute_bbox(&min, &max, frame); |
618 | - s->prop[GRAIL_PROP_ROTATE_X1] = min.x; |
619 | - s->prop[GRAIL_PROP_ROTATE_Y1] = min.y; |
620 | - s->prop[GRAIL_PROP_ROTATE_X2] = max.x; |
621 | - s->prop[GRAIL_PROP_ROTATE_Y2] = max.y; |
622 | - s->nprop = 7; |
623 | + s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame); |
624 | } |
625 | |
626 | int gru_rotate(struct grail *ge, |
627 | @@ -79,7 +72,7 @@ |
628 | } |
629 | if (!(move->active & fm_mask)) |
630 | return 0; |
631 | - set_props(state, move, frame); |
632 | + set_props(ge->gin, state, move, frame); |
633 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
634 | return 1; |
635 | } |
636 | @@ -120,7 +113,7 @@ |
637 | } |
638 | if (!(move->active & fm_mask)) |
639 | return 0; |
640 | - set_props(state, move, frame); |
641 | + set_props(ge->gin, state, move, frame); |
642 | gru_event(ge, state->gid, move, state->prop, state->nprop); |
643 | return 1; |
644 | } |
645 | |
646 | === modified file 'src/gestures-tapping.c' |
647 | --- src/gestures-tapping.c 2010-08-10 16:42:10 +0000 |
648 | +++ src/gestures-tapping.c 2010-08-19 20:46:41 +0000 |
649 | @@ -31,6 +31,17 @@ |
650 | |
651 | static const int fm_mask = 0x03; |
652 | |
653 | +static void set_props(const struct gesture_inserter *gin, |
654 | + struct tapping_model *s, const struct move_model *m, |
655 | + const struct touch_frame *frame) |
656 | +{ |
657 | + s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start; |
658 | + s->prop[GRAIL_PROP_TAP_X] = gin_prop_x(gin, m->fm[FM_X].value); |
659 | + s->prop[GRAIL_PROP_TAP_Y] = gin_prop_y(gin, m->fm[FM_Y].value); |
660 | + s->nprop = 3; |
661 | + s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame); |
662 | +} |
663 | + |
664 | int gru_tapping(struct grail *ge, |
665 | const struct touch_frame *frame) |
666 | { |
667 | @@ -44,11 +55,7 @@ |
668 | if (!state->ntouch) |
669 | state->start = move->time; |
670 | if (move->ntouch >= state->ntouch) { |
671 | - state->prop[GRAIL_PROP_TAP_DT] = |
672 | - move->time - state->start; |
673 | - state->prop[GRAIL_PROP_TAP_X] = move->fm[FM_X].value; |
674 | - state->prop[GRAIL_PROP_TAP_Y] = move->fm[FM_Y].value; |
675 | - state->nprop = 3; |
676 | + set_props(ge->gin, state, move, frame); |
677 | } |
678 | if (move->ntouch > state->ntouch) { |
679 | state->ntouch = move->ntouch; |
680 | |
681 | === modified file 'src/grail-api.c' |
682 | --- src/grail-api.c 2010-08-11 17:05:21 +0000 |
683 | +++ src/grail-api.c 2010-08-19 20:46:41 +0000 |
684 | @@ -22,27 +22,18 @@ |
685 | |
686 | #include "grail-inserter.h" |
687 | #include "grail-recognizer.h" |
688 | -#include <grail.h> |
689 | +#include "grail-impl.h" |
690 | #include <string.h> |
691 | #include <stdio.h> |
692 | #include <unistd.h> |
693 | #include <fcntl.h> |
694 | #include <malloc.h> |
695 | #include <errno.h> |
696 | -#include "evbuf.h" |
697 | - |
698 | -struct grail_impl { |
699 | - struct touch_dev dev; |
700 | - struct touch_engine engine; |
701 | - struct evbuf evbuf; |
702 | - int filter_abs; |
703 | - int hack_status; |
704 | -}; |
705 | - |
706 | -static void tp_event(struct touch_engine *engine, |
707 | + |
708 | +static void tp_event(struct touch_dev *dev, |
709 | const struct input_event *ev) |
710 | { |
711 | - struct grail *ge = engine->priv; |
712 | + struct grail *ge = dev->priv; |
713 | struct grail_impl *x = ge->impl; |
714 | evbuf_put(&x->evbuf, ev); |
715 | } |
716 | @@ -62,14 +53,14 @@ |
717 | return 0; |
718 | } |
719 | |
720 | -static void tp_sync(struct touch_engine *engine, |
721 | +static void tp_sync(struct touch_dev *dev, |
722 | const struct input_event *syn) |
723 | { |
724 | struct input_event ev; |
725 | - struct grail *ge = engine->priv; |
726 | + struct grail *ge = dev->priv; |
727 | struct grail_impl *x = ge->impl; |
728 | struct gesture_recognizer *gru = ge->gru; |
729 | - struct touch_frame *frame = &engine->frame; |
730 | + struct touch_frame *frame = &dev->frame; |
731 | grail_mask_t filtered[DIM_EV_TYPE_BYTES]; |
732 | int dofilt, hack, nevent = 0; |
733 | gin_frame_begin(ge, frame); |
734 | @@ -120,22 +111,27 @@ |
735 | if (!x) |
736 | return -ENOMEM; |
737 | ge->impl = x; |
738 | + |
739 | + ret = touch_dev_open(&x->dev, fd); |
740 | + if (ret) |
741 | + goto freemem; |
742 | + x->dev.event = tp_event; |
743 | + x->dev.sync = tp_sync; |
744 | + x->dev.priv = ge; |
745 | + |
746 | ret = gin_init(ge); |
747 | if (ret) |
748 | - goto freemem; |
749 | - ret = touch_dev_open(&x->dev, fd); |
750 | + goto freedev; |
751 | + |
752 | + ret = gru_init(ge); |
753 | if (ret) |
754 | goto freegin; |
755 | - ret = gru_init(ge); |
756 | - if (ret) |
757 | - goto freedev; |
758 | - touch_engine_init(&x->engine, tp_event, tp_sync, ge); |
759 | - touch_engine_attach(&x->engine, &x->dev); |
760 | + |
761 | return 0; |
762 | + freegin: |
763 | + gin_destroy(ge); |
764 | freedev: |
765 | touch_dev_close(&x->dev, fd); |
766 | - freegin: |
767 | - gin_destroy(ge); |
768 | freemem: |
769 | free(x); |
770 | ge->impl = 0; |
771 | @@ -146,10 +142,9 @@ |
772 | { |
773 | struct grail_impl *x = ge->impl; |
774 | void *status; |
775 | - touch_engine_detach(&x->engine, &x->dev); |
776 | gru_destroy(ge); |
777 | + gin_destroy(ge); |
778 | touch_dev_close(&x->dev, fd); |
779 | - gin_destroy(ge); |
780 | free(ge->impl); |
781 | ge->impl = 0; |
782 | } |
783 | @@ -169,9 +164,10 @@ |
784 | void grail_get_units(const struct grail *ge, |
785 | struct grail_coord *min, struct grail_coord *max) |
786 | { |
787 | - const struct touch_dev_caps *caps = &ge->impl->dev.caps; |
788 | - min->x = caps->info[TP_POS_X].minimum; |
789 | - min->y = caps->info[TP_POS_Y].minimum; |
790 | - max->x = caps->info[TP_POS_X].maximum; |
791 | - max->y = caps->info[TP_POS_Y].maximum; |
792 | + const struct touch_caps *caps = &ge->impl->dev.caps; |
793 | + min->x = caps->min_x; |
794 | + min->y = caps->min_y; |
795 | + max->x = caps->max_x; |
796 | + max->y = caps->max_y; |
797 | } |
798 | + |
799 | |
800 | === added file 'src/grail-event.c' |
801 | --- src/grail-event.c 1970-01-01 00:00:00 +0000 |
802 | +++ src/grail-event.c 2010-08-19 20:46:41 +0000 |
803 | @@ -0,0 +1,144 @@ |
804 | +/***************************************************************************** |
805 | + * |
806 | + * grail - Gesture Recognition And Instantiation Library |
807 | + * |
808 | + * Copyright (C) 2010 Canonical Ltd. |
809 | + * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> |
810 | + * |
811 | + * This program is free software: you can redistribute it and/or modify it |
812 | + * under the terms of the GNU General Public License as published by the |
813 | + * Free Software Foundation, either version 3 of the License, or (at your |
814 | + * option) any later version. |
815 | + * |
816 | + * This program is distributed in the hope that it will be useful, but |
817 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
818 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
819 | + * General Public License for more details. |
820 | + * |
821 | + * You should have received a copy of the GNU General Public License along |
822 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
823 | + * |
824 | + ****************************************************************************/ |
825 | + |
826 | +#include "grail-inserter.h" |
827 | +#include "grail-impl.h" |
828 | +#include <malloc.h> |
829 | +#include <string.h> |
830 | +#include <errno.h> |
831 | +#include <math.h> |
832 | + |
833 | +static void compute_bbox(struct grail_coord *min, struct grail_coord *max, |
834 | + const struct touch_frame *frame) |
835 | +{ |
836 | + float x, y; |
837 | + int i; |
838 | + if (frame->nactive < 1) |
839 | + return; |
840 | + x = frame->active[0]->x; |
841 | + y = frame->active[0]->y; |
842 | + min->x = max->x = x; |
843 | + min->y = max->y = y; |
844 | + for (i = 1; i < frame->nactive; i++) { |
845 | + x = frame->active[i]->x; |
846 | + y = frame->active[i]->y; |
847 | + if (x < min->x) |
848 | + min->x = x; |
849 | + if (y < min->y) |
850 | + min->y = y; |
851 | + if (x > max->x) |
852 | + max->x = x; |
853 | + if (y > max->y) |
854 | + max->y = y; |
855 | + } |
856 | +} |
857 | + |
858 | +int gin_add_contact_props(const struct gesture_inserter *gin, |
859 | + grail_prop_t *prop, const struct touch_frame *frame) |
860 | +{ |
861 | + struct grail_coord min, max; |
862 | + int i, n = 0, ntouch = frame->nactive; |
863 | + if (!ntouch) |
864 | + return n; |
865 | + if (ntouch > 5) |
866 | + ntouch = 5; |
867 | + compute_bbox(&min, &max, frame); |
868 | + prop[n++] = gin_prop_x(gin, min.x); |
869 | + prop[n++] = gin_prop_y(gin, min.y); |
870 | + prop[n++] = gin_prop_x(gin, max.x); |
871 | + prop[n++] = gin_prop_y(gin, max.y); |
872 | + for (i = 0; i < ntouch; i++) { |
873 | + const struct touch *ct = frame->active[i]; |
874 | + prop[n++] = ct->id; |
875 | + prop[n++] = gin_prop_x(gin, ct->x); |
876 | + prop[n++] = gin_prop_y(gin, ct->y); |
877 | + } |
878 | + return n; |
879 | +} |
880 | + |
881 | +int gin_get_clients(struct grail *ge, |
882 | + struct grail_client_info *info, int maxinfo, |
883 | + const grail_mask_t* types, int btypes, |
884 | + const grail_mask_t* span, int bspan, |
885 | + const struct touch_frame *frame) |
886 | +{ |
887 | + struct grail_coord pos[DIM_TOUCH]; |
888 | + int i, npos = 0; |
889 | + if (!ge->get_clients) |
890 | + return 0; |
891 | + grail_mask_foreach(i, span, bspan) { |
892 | + pos[npos].x = gin_prop_x(ge->gin, frame->touch[i].x); |
893 | + pos[npos].y = gin_prop_y(ge->gin, frame->touch[i].y); |
894 | + npos++; |
895 | + } |
896 | + return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes); |
897 | +} |
898 | + |
899 | +void gin_send_event(struct grail *ge, struct slot_state *s, |
900 | + const struct gesture_event *ev, |
901 | + const struct touch_frame *frame) |
902 | +{ |
903 | + const struct gesture_inserter *gin = ge->gin; |
904 | + struct grail_event gev; |
905 | + int i; |
906 | + if (!ge->gesture) |
907 | + return; |
908 | + gev.type = s->type; |
909 | + gev.id = s->id; |
910 | + gev.status = ev->status; |
911 | + gev.ntouch = ev->ntouch; |
912 | + gev.nprop = ev->nprop; |
913 | + gev.time = ev->time; |
914 | + gev.pos.x = gin_prop_x(gin, ev->pos.x); |
915 | + gev.pos.y = gin_prop_y(gin, ev->pos.y); |
916 | + memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t)); |
917 | + for (i = 0; i < s->nclient; i++) { |
918 | + gev.client_id = s->client_id[i]; |
919 | + ge->gesture(ge, &gev); |
920 | + } |
921 | +} |
922 | + |
923 | +int grail_get_contacts(const struct grail *ge, |
924 | + struct grail_contact *touch, int max_touch) |
925 | +{ |
926 | + const struct touch_dev *dev = &ge->impl->dev; |
927 | + const struct gesture_inserter *gin = ge->gin; |
928 | + const struct touch_frame *frame = &dev->frame; |
929 | + int i; |
930 | + if (frame->nactive < max_touch) |
931 | + max_touch = frame->nactive; |
932 | + for (i = 0; i < max_touch; i++) { |
933 | + struct grail_contact *t = &touch[i]; |
934 | + const struct touch *ct = frame->active[i]; |
935 | + t->id = ct->id; |
936 | + t->tool_type = ct->tool_type; |
937 | + t->pos.x = gin_prop_x(gin, ct->x); |
938 | + t->pos.y = gin_prop_y(gin, ct->y); |
939 | + t->touch_major = gin->scale_r * ct->touch_major; |
940 | + t->touch_minor = gin->scale_r * ct->touch_minor; |
941 | + t->width_major = gin->scale_r * ct->width_major; |
942 | + t->width_minor = gin->scale_r * ct->width_minor; |
943 | + t->angle = touch_angle(dev, ct->orientation); |
944 | + t->pressure = touch_pressure(dev, ct->pressure); |
945 | + } |
946 | + return max_touch; |
947 | +} |
948 | |
949 | === modified file 'src/grail-gestures.c' |
950 | --- src/grail-gestures.c 2010-08-11 17:06:36 +0000 |
951 | +++ src/grail-gestures.c 2010-08-19 20:46:41 +0000 |
952 | @@ -21,6 +21,7 @@ |
953 | ****************************************************************************/ |
954 | |
955 | #include "grail-recognizer.h" |
956 | +#include "grail-impl.h" |
957 | #include <math.h> |
958 | |
959 | static const float FM_SN[DIM_FM] = { 1000, 1000, 200, 1000 }; |
960 | @@ -39,8 +40,8 @@ |
961 | return; |
962 | for (i = 0; i < n; i++) { |
963 | const struct touch *t = frame->active[i]; |
964 | - *x += t->prop[TP_POS_X]; |
965 | - *y += t->prop[TP_POS_Y]; |
966 | + *x += t->x; |
967 | + *y += t->y; |
968 | } |
969 | *x /= n; |
970 | *y /= n; |
971 | @@ -55,8 +56,8 @@ |
972 | return r; |
973 | for (i = 0; i < n; i++) { |
974 | const struct touch *t = frame->active[i]; |
975 | - float dx = t->prop[TP_POS_X] - x; |
976 | - float dy = t->prop[TP_POS_Y] - y; |
977 | + float dx = t->x - x; |
978 | + float dy = t->y - y; |
979 | r2 += dx * dx + dy * dy; |
980 | } |
981 | r2 /= n; |
982 | @@ -75,10 +76,10 @@ |
983 | for (i = 0; i < n; i++) { |
984 | const struct touch *t = frame->active[i]; |
985 | const struct touch *ot = &prev->touch[t->slot]; |
986 | - float dx = t->prop[TP_POS_X] - x; |
987 | - float dy = t->prop[TP_POS_Y] - y; |
988 | - float mx = t->prop[TP_POS_X] - ot->prop[TP_POS_X]; |
989 | - float my = t->prop[TP_POS_Y] - ot->prop[TP_POS_Y]; |
990 | + float dx = t->x - x; |
991 | + float dy = t->y - y; |
992 | + float mx = t->x - ot->x; |
993 | + float my = t->y - ot->y; |
994 | darc2 += dx * my - dy * mx; |
995 | } |
996 | darc2 /= n; |
997 | @@ -141,14 +142,13 @@ |
998 | |
999 | void gru_init_motion(struct grail *ge) |
1000 | { |
1001 | + struct touch_caps *caps = &ge->impl->dev.caps; |
1002 | struct gesture_recognizer *gru = ge->gru; |
1003 | struct move_model *m = &gru->move; |
1004 | - struct grail_coord min, max; |
1005 | float D[DIM_FM]; |
1006 | int i; |
1007 | - grail_get_units(ge, &min, &max); |
1008 | - D[FM_X] = max.x - min.x; |
1009 | - D[FM_Y] = max.y - min.y; |
1010 | + D[FM_X] = caps->max_x - caps->min_x; |
1011 | + D[FM_Y] = caps->max_y - caps->min_y; |
1012 | D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]); |
1013 | D[FM_A] = 2 * M_PI; |
1014 | for (i = 0; i < DIM_FM; i++) { |
1015 | @@ -217,28 +217,3 @@ |
1016 | gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch, |
1017 | prop, nprop); |
1018 | } |
1019 | - |
1020 | -void gru_compute_bbox(struct grail_coord *min, struct grail_coord *max, |
1021 | - const struct touch_frame *frame) |
1022 | -{ |
1023 | - float x, y; |
1024 | - int i; |
1025 | - if (frame->nactive < 1) |
1026 | - return; |
1027 | - x = frame->active[0]->prop[TP_POS_X]; |
1028 | - y = frame->active[0]->prop[TP_POS_Y]; |
1029 | - min->x = max->x = x; |
1030 | - min->y = max->y = y; |
1031 | - for (i = 1; i < frame->nactive; i++) { |
1032 | - x = frame->active[i]->prop[TP_POS_X]; |
1033 | - y = frame->active[i]->prop[TP_POS_Y]; |
1034 | - if (x < min->x) |
1035 | - min->x = x; |
1036 | - if (y < min->y) |
1037 | - min->y = y; |
1038 | - if (x > max->x) |
1039 | - max->x = x; |
1040 | - if (y > max->y) |
1041 | - max->y = y; |
1042 | - } |
1043 | -} |
1044 | |
1045 | === modified file 'src/grail-gestures.h' |
1046 | --- src/grail-gestures.h 2010-08-11 17:06:36 +0000 |
1047 | +++ src/grail-gestures.h 2010-08-19 20:46:41 +0000 |
1048 | @@ -68,8 +68,6 @@ |
1049 | void gru_end(struct grail *ge, int gid, |
1050 | const struct move_model *move, |
1051 | const grail_prop_t *prop, int nprop); |
1052 | -void gru_compute_bbox(struct grail_coord *min, struct grail_coord *max, |
1053 | - const struct touch_frame *frame); |
1054 | |
1055 | struct combo_model { |
1056 | int active, gid; |
1057 | |
1058 | === added file 'src/grail-impl.h' |
1059 | --- src/grail-impl.h 1970-01-01 00:00:00 +0000 |
1060 | +++ src/grail-impl.h 2010-08-19 20:46:41 +0000 |
1061 | @@ -0,0 +1,36 @@ |
1062 | +/***************************************************************************** |
1063 | + * |
1064 | + * grail - Gesture Recognition And Instantiation Library |
1065 | + * |
1066 | + * Copyright (C) 2010 Canonical Ltd. |
1067 | + * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> |
1068 | + * |
1069 | + * This program is free software: you can redistribute it and/or modify it |
1070 | + * under the terms of the GNU General Public License as published by the |
1071 | + * Free Software Foundation, either version 3 of the License, or (at your |
1072 | + * option) any later version. |
1073 | + * |
1074 | + * This program is distributed in the hope that it will be useful, but |
1075 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
1076 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1077 | + * General Public License for more details. |
1078 | + * |
1079 | + * You should have received a copy of the GNU General Public License along |
1080 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1081 | + * |
1082 | + ****************************************************************************/ |
1083 | + |
1084 | +#ifndef _GRAIL_IMPL_H |
1085 | +#define _GRAIL_IMPL_H |
1086 | + |
1087 | +#include <grail-touch.h> |
1088 | +#include "evbuf.h" |
1089 | + |
1090 | +struct grail_impl { |
1091 | + struct touch_dev dev; |
1092 | + struct evbuf evbuf; |
1093 | + int filter_abs; |
1094 | + int hack_status; |
1095 | +}; |
1096 | + |
1097 | +#endif |
1098 | |
1099 | === modified file 'src/grail-inserter.c' |
1100 | --- src/grail-inserter.c 2010-08-11 17:07:40 +0000 |
1101 | +++ src/grail-inserter.c 2010-08-19 20:46:41 +0000 |
1102 | @@ -21,6 +21,7 @@ |
1103 | ****************************************************************************/ |
1104 | |
1105 | #include "grail-inserter.h" |
1106 | +#include "grail-impl.h" |
1107 | #include <malloc.h> |
1108 | #include <string.h> |
1109 | #include <errno.h> |
1110 | @@ -28,106 +29,6 @@ |
1111 | |
1112 | static const int MAX_GESTURE_ID = 0xfff; |
1113 | |
1114 | -struct gesture_inserter { |
1115 | - struct slot_state state[DIM_INSTANCE]; |
1116 | - grail_mask_t unused[DIM_INSTANCE_BYTES]; |
1117 | - grail_mask_t fresh[DIM_INSTANCE_BYTES]; |
1118 | - grail_mask_t used[DIM_INSTANCE_BYTES]; |
1119 | - grail_time_t time; |
1120 | - int gestureid; |
1121 | - int transformed; |
1122 | - float scale_x, scale_y, scale_r; |
1123 | - float trans_x, trans_y; |
1124 | -}; |
1125 | - |
1126 | -static const int grail_main_type[DIM_GRAIL_TYPE] = { |
1127 | - GRAIL_MAIN_DRAG, |
1128 | - GRAIL_MAIN_PINCH, |
1129 | - GRAIL_MAIN_ROTATE, |
1130 | - GRAIL_MAIN_DRAG, |
1131 | - GRAIL_MAIN_PINCH, |
1132 | - GRAIL_MAIN_ROTATE, |
1133 | - GRAIL_MAIN_DRAG, |
1134 | - GRAIL_MAIN_PINCH, |
1135 | - GRAIL_MAIN_ROTATE, |
1136 | - GRAIL_MAIN_DRAG, |
1137 | - GRAIL_MAIN_PINCH, |
1138 | - GRAIL_MAIN_ROTATE, |
1139 | - GRAIL_MAIN_DRAG, |
1140 | - GRAIL_MAIN_PINCH, |
1141 | - GRAIL_MAIN_ROTATE, |
1142 | - GRAIL_MAIN_TAP, |
1143 | - GRAIL_MAIN_TAP, |
1144 | - GRAIL_MAIN_TAP, |
1145 | - GRAIL_MAIN_TAP, |
1146 | - GRAIL_MAIN_TAP, |
1147 | - GRAIL_MAIN_DRAG, |
1148 | - GRAIL_MAIN_PINCH, |
1149 | - GRAIL_MAIN_ROTATE, |
1150 | - GRAIL_MAIN_DRAG, |
1151 | - GRAIL_MAIN_PINCH, |
1152 | - GRAIL_MAIN_ROTATE, |
1153 | -}; |
1154 | - |
1155 | -static void transform_pos(const struct gesture_inserter *gin, |
1156 | - struct grail_coord *pos) |
1157 | -{ |
1158 | - if (gin->transformed) { |
1159 | - pos->x *= gin->scale_x; |
1160 | - pos->x += gin->trans_x; |
1161 | - pos->y *= gin->scale_y; |
1162 | - pos->y += gin->trans_y; |
1163 | - } |
1164 | -} |
1165 | - |
1166 | -static void transform_prop(const struct gesture_inserter *gin, int type, |
1167 | - grail_prop_t *prop, int nprop) |
1168 | -{ |
1169 | - if (!gin->transformed) |
1170 | - return; |
1171 | - switch (grail_main_type[type]) { |
1172 | - case GRAIL_MAIN_DRAG: |
1173 | - prop[GRAIL_PROP_DRAG_DX] *= gin->scale_x; |
1174 | - prop[GRAIL_PROP_DRAG_DY] *= gin->scale_y; |
1175 | - prop[GRAIL_PROP_DRAG_VX] *= gin->scale_x; |
1176 | - prop[GRAIL_PROP_DRAG_VY] *= gin->scale_y; |
1177 | - prop[GRAIL_PROP_DRAG_X] *= gin->scale_x; |
1178 | - prop[GRAIL_PROP_DRAG_X] += gin->trans_x; |
1179 | - prop[GRAIL_PROP_DRAG_Y] *= gin->scale_y; |
1180 | - prop[GRAIL_PROP_DRAG_Y] += gin->trans_y; |
1181 | - break; |
1182 | - case GRAIL_MAIN_PINCH: |
1183 | - prop[GRAIL_PROP_PINCH_DR] *= gin->scale_r; |
1184 | - prop[GRAIL_PROP_PINCH_VR] *= gin->scale_r; |
1185 | - prop[GRAIL_PROP_PINCH_R] *= gin->scale_r; |
1186 | - prop[GRAIL_PROP_PINCH_X1] *= gin->scale_x; |
1187 | - prop[GRAIL_PROP_PINCH_X1] += gin->trans_x; |
1188 | - prop[GRAIL_PROP_PINCH_Y1] *= gin->scale_y; |
1189 | - prop[GRAIL_PROP_PINCH_Y1] += gin->trans_y; |
1190 | - prop[GRAIL_PROP_PINCH_X2] *= gin->scale_x; |
1191 | - prop[GRAIL_PROP_PINCH_X2] += gin->trans_x; |
1192 | - prop[GRAIL_PROP_PINCH_Y2] *= gin->scale_y; |
1193 | - prop[GRAIL_PROP_PINCH_Y2] += gin->trans_y; |
1194 | - break; |
1195 | - case GRAIL_MAIN_ROTATE: |
1196 | - prop[GRAIL_PROP_ROTATE_X1] *= gin->scale_x; |
1197 | - prop[GRAIL_PROP_ROTATE_X1] += gin->trans_x; |
1198 | - prop[GRAIL_PROP_ROTATE_Y1] *= gin->scale_y; |
1199 | - prop[GRAIL_PROP_ROTATE_Y1] += gin->trans_y; |
1200 | - prop[GRAIL_PROP_ROTATE_X2] *= gin->scale_x; |
1201 | - prop[GRAIL_PROP_ROTATE_X2] += gin->trans_x; |
1202 | - prop[GRAIL_PROP_ROTATE_Y2] *= gin->scale_y; |
1203 | - prop[GRAIL_PROP_ROTATE_Y2] += gin->trans_y; |
1204 | - break; |
1205 | - case GRAIL_MAIN_TAP: |
1206 | - prop[GRAIL_PROP_TAP_X] *= gin->scale_x; |
1207 | - prop[GRAIL_PROP_TAP_X] += gin->trans_x; |
1208 | - prop[GRAIL_PROP_TAP_Y] *= gin->scale_y; |
1209 | - prop[GRAIL_PROP_TAP_Y] += gin->trans_y; |
1210 | - break; |
1211 | - }; |
1212 | -} |
1213 | - |
1214 | static int find_gslot(const struct gesture_inserter *gin, int gid) |
1215 | { |
1216 | int i; |
1217 | @@ -137,29 +38,6 @@ |
1218 | return -1; |
1219 | } |
1220 | |
1221 | -static void send_event(struct grail *ge, struct slot_state *s, |
1222 | - const struct gesture_event *ev) |
1223 | -{ |
1224 | - struct grail_event gev; |
1225 | - int i; |
1226 | - if (!ge->gesture) |
1227 | - return; |
1228 | - gev.type = s->type; |
1229 | - gev.id = s->id; |
1230 | - gev.status = ev->status; |
1231 | - gev.ntouch = ev->ntouch; |
1232 | - gev.nprop = ev->nprop; |
1233 | - gev.time = ev->time; |
1234 | - gev.pos = ev->pos; |
1235 | - transform_pos(ge->gin, &gev.pos); |
1236 | - memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t)); |
1237 | - transform_prop(ge->gin, gev.type, gev.prop, gev.nprop); |
1238 | - for (i = 0; i < s->nclient; i++) { |
1239 | - gev.client_id = s->client_id[i]; |
1240 | - ge->gesture(ge, &gev); |
1241 | - } |
1242 | -} |
1243 | - |
1244 | // todo: spanning tree for multi-user case |
1245 | static void setup_new_gestures(struct grail *ge, |
1246 | const struct touch_frame *frame) |
1247 | @@ -182,19 +60,8 @@ |
1248 | grail_mask_set_mask(span, s->span, sizeof(span)); |
1249 | } |
1250 | |
1251 | - if (ge->get_clients) { |
1252 | - struct grail_coord coord[DIM_CLIENT]; |
1253 | - int ncoord = 0; |
1254 | - grail_mask_foreach(i, span, sizeof(span)) { |
1255 | - const struct touch *t = &frame->touch[i]; |
1256 | - coord[ncoord].x = t->prop[TP_POS_X]; |
1257 | - coord[ncoord].y = t->prop[TP_POS_Y]; |
1258 | - transform_pos(gin, &coord[ncoord]); |
1259 | - ncoord++; |
1260 | - } |
1261 | - nclient = ge->get_clients(ge, info, DIM_CLIENT, |
1262 | - coord, ncoord, types, sizeof(types)); |
1263 | - } |
1264 | + nclient = gin_get_clients(ge, info, DIM_CLIENT, types, sizeof(types), |
1265 | + span, sizeof(span), frame); |
1266 | |
1267 | grail_mask_foreach(i, gin->fresh, sizeof(gin->fresh)) { |
1268 | struct slot_state *s = &gin->state[i]; |
1269 | @@ -218,6 +85,11 @@ |
1270 | return -ENOMEM; |
1271 | for (i = 0; i < DIM_INSTANCE; i++) |
1272 | grail_mask_set(gin->unused, i); |
1273 | + gin->scale_x = 1; |
1274 | + gin->scale_y = 1; |
1275 | + gin->scale_r = 1; |
1276 | + gin->trans_x = 1; |
1277 | + gin->trans_y = 1; |
1278 | ge->gin = gin; |
1279 | return 0; |
1280 | } |
1281 | @@ -273,7 +145,7 @@ |
1282 | continue; |
1283 | while (!gebuf_empty(&s->buf)) { |
1284 | gebuf_get(&s->buf, &ev); |
1285 | - send_event(ge, s, &ev); |
1286 | + gin_send_event(ge, s, &ev, frame); |
1287 | } |
1288 | } |
1289 | |
1290 | @@ -384,16 +256,18 @@ |
1291 | const struct grail_coord *tmin, |
1292 | const struct grail_coord *tmax) |
1293 | { |
1294 | + struct touch_caps *caps = &ge->impl->dev.caps; |
1295 | struct gesture_inserter *gin = ge->gin; |
1296 | - struct grail_coord dmin, dmax; |
1297 | - double sx, sy; |
1298 | - grail_get_units(ge, &dmin, &dmax); |
1299 | - sx = (tmax->x - tmin->x) / (dmax.x - dmin.x); |
1300 | - sy = (tmax->y - tmin->y) / (dmax.y - dmin.y); |
1301 | + double tx, ty, dx, dy, sx, sy; |
1302 | + tx = tmax->x - tmin->x; |
1303 | + ty = tmax->y - tmin->y; |
1304 | + dx = caps->max_x - caps->min_x; |
1305 | + dy = caps->max_y - caps->min_y; |
1306 | + sx = tx / dx; |
1307 | + sy = ty / dy; |
1308 | gin->scale_x = sx; |
1309 | gin->scale_y = sy; |
1310 | - gin->scale_r = sqrt((sx * sx + sy * sy) / 2); |
1311 | - gin->trans_x = tmin->x - dmin.x * sx; |
1312 | - gin->trans_y = tmin->y - dmin.y * sy; |
1313 | - gin->transformed = 1; |
1314 | + gin->scale_r = sqrt((tx * tx + ty * ty) / (dx * dx + dy * dy)); |
1315 | + gin->trans_x = tmin->x - caps->min_x * sx; |
1316 | + gin->trans_y = tmin->y - caps->min_y * sy; |
1317 | } |
1318 | |
1319 | === modified file 'src/grail-inserter.h' |
1320 | --- src/grail-inserter.h 2010-08-10 16:39:47 +0000 |
1321 | +++ src/grail-inserter.h 2010-08-19 20:46:41 +0000 |
1322 | @@ -46,6 +46,39 @@ |
1323 | struct gebuf buf; |
1324 | }; |
1325 | |
1326 | +struct gesture_inserter { |
1327 | + struct slot_state state[DIM_INSTANCE]; |
1328 | + grail_mask_t unused[DIM_INSTANCE_BYTES]; |
1329 | + grail_mask_t fresh[DIM_INSTANCE_BYTES]; |
1330 | + grail_mask_t used[DIM_INSTANCE_BYTES]; |
1331 | + grail_time_t time; |
1332 | + int gestureid; |
1333 | + float scale_x, scale_y, scale_r; |
1334 | + float trans_x, trans_y; |
1335 | +}; |
1336 | + |
1337 | +static inline float gin_prop_x(const struct gesture_inserter *gin, float x) |
1338 | +{ |
1339 | + return gin->scale_x * x + gin->trans_x; |
1340 | +} |
1341 | + |
1342 | +static inline float gin_prop_y(const struct gesture_inserter *gin, float y) |
1343 | +{ |
1344 | + return gin->scale_y * y + gin->trans_y; |
1345 | +} |
1346 | + |
1347 | +int gin_add_contact_props(const struct gesture_inserter *gin, |
1348 | + grail_prop_t *prop, const struct touch_frame *frame); |
1349 | + |
1350 | +int gin_get_clients(struct grail *ge, |
1351 | + struct grail_client_info *info, int maxinfo, |
1352 | + const grail_mask_t* types, int btypes, |
1353 | + const grail_mask_t* span, int bspan, |
1354 | + const struct touch_frame *frame); |
1355 | +void gin_send_event(struct grail *ge, struct slot_state *s, |
1356 | + const struct gesture_event *ev, |
1357 | + const struct touch_frame *frame); |
1358 | + |
1359 | int gin_init(struct grail *ge); |
1360 | void gin_destroy(struct grail *ge); |
1361 | |
1362 | |
1363 | === modified file 'src/touch-dev.c' |
1364 | --- src/touch-dev.c 2010-08-07 20:13:32 +0000 |
1365 | +++ src/touch-dev.c 2010-08-19 20:46:41 +0000 |
1366 | @@ -25,128 +25,97 @@ |
1367 | #include <string.h> |
1368 | #include <errno.h> |
1369 | |
1370 | -/* from mtdev-mapping.h */ |
1371 | -#define MT_TOUCH_MAJOR 0 |
1372 | -#define MT_TOUCH_MINOR 1 |
1373 | -#define MT_WIDTH_MAJOR 2 |
1374 | -#define MT_WIDTH_MINOR 3 |
1375 | -#define MT_ORIENTATION 4 |
1376 | -#define MT_POSITION_X 5 |
1377 | -#define MT_POSITION_Y 6 |
1378 | -#define MT_TRACKING_ID 9 |
1379 | -#define MT_PRESSURE 10 |
1380 | - |
1381 | -struct touch_dev_impl { |
1382 | - int id[DIM_TOUCH]; |
1383 | - int slot; |
1384 | - int status; |
1385 | - grail_mask_t mask[DIM_TOUCH_BYTES]; |
1386 | - touch_prop_t prop[DIM_TOUCH_PROP]; |
1387 | - struct mtdev mtdev; |
1388 | -}; |
1389 | - |
1390 | -static inline void set_info(struct touch_dev_caps *caps, int code, |
1391 | - const struct input_absinfo *info) |
1392 | -{ |
1393 | - grail_mask_set(caps->mask, code); |
1394 | - caps->info[code] = *info; |
1395 | -} |
1396 | - |
1397 | -static void set_caps(struct touch_dev_caps *caps, |
1398 | - const struct mtdev_caps *mtcaps) |
1399 | -{ |
1400 | - if (mtcaps->has_abs[MT_POSITION_X]) |
1401 | - set_info(caps, TP_POS_X, &mtcaps->abs[MT_POSITION_X]); |
1402 | - if (mtcaps->has_abs[MT_POSITION_Y]) |
1403 | - set_info(caps, TP_POS_Y, &mtcaps->abs[MT_POSITION_Y]); |
1404 | - if (mtcaps->has_abs[MT_TOUCH_MAJOR]) |
1405 | - set_info(caps, TP_TOUCH_MAJOR, &mtcaps->abs[MT_TOUCH_MAJOR]); |
1406 | - if (mtcaps->has_abs[MT_TOUCH_MINOR]) |
1407 | - set_info(caps, TP_TOUCH_MINOR, &mtcaps->abs[MT_TOUCH_MINOR]); |
1408 | - if (mtcaps->has_abs[MT_WIDTH_MAJOR]) |
1409 | - set_info(caps, TP_WIDTH_MAJOR, &mtcaps->abs[MT_WIDTH_MAJOR]); |
1410 | - if (mtcaps->has_abs[MT_WIDTH_MINOR]) |
1411 | - set_info(caps, TP_WIDTH_MINOR, &mtcaps->abs[MT_WIDTH_MINOR]); |
1412 | - if (mtcaps->has_abs[MT_ORIENTATION]) |
1413 | - set_info(caps, TP_ORIENTATION, &mtcaps->abs[MT_ORIENTATION]); |
1414 | - if (mtcaps->has_abs[MT_PRESSURE]) |
1415 | - set_info(caps, TP_PRESSURE, &mtcaps->abs[MT_PRESSURE]); |
1416 | -} |
1417 | - |
1418 | -static inline void set_prop(struct touch_dev_impl *x, int code, int value) |
1419 | -{ |
1420 | - grail_mask_set(x->mask, code); |
1421 | - x->prop[code] = value; |
1422 | -} |
1423 | - |
1424 | -static void finish_touch(struct touch_dev *dev, |
1425 | - struct touch_dev_impl *x) |
1426 | -{ |
1427 | - if (x->status < 0 && dev->destroy) |
1428 | - dev->destroy(dev, x->slot); |
1429 | - if (x->status > 0 && dev->create) |
1430 | - dev->create(dev, x->slot, x->mask, x->prop); |
1431 | - if (x->status == 0 && dev->modify && |
1432 | - grail_mask_count(x->mask, sizeof(x->mask))) |
1433 | - dev->modify(dev, x->slot, x->mask, x->prop); |
1434 | - x->status = 0; |
1435 | - memset(x->mask, 0, sizeof(x->mask)); |
1436 | +#define SET_PROP(name, value) \ |
1437 | + if (t->name != value) { \ |
1438 | + t->name = value; \ |
1439 | + frame->nmodify++; \ |
1440 | + } |
1441 | + |
1442 | +static void finish_touch(struct touch_dev *dev, struct touch_frame *frame) |
1443 | +{ |
1444 | + struct touch *t = &frame->touch[dev->slot]; |
1445 | + if (dev->state > 0) { |
1446 | + t->active = 1; |
1447 | + grail_mask_set(frame->touches, dev->slot); |
1448 | + frame->ncreate++; |
1449 | + } |
1450 | + if (dev->state < 0) { |
1451 | + t->active = 0; |
1452 | + grail_mask_clear(frame->touches, dev->slot); |
1453 | + frame->ndestroy++; |
1454 | + } |
1455 | + dev->state = 0; |
1456 | } |
1457 | |
1458 | static void finish_packet(struct touch_dev *dev, |
1459 | const struct input_event *syn) |
1460 | { |
1461 | - finish_touch(dev, dev->impl); |
1462 | + static const touch_time_t ms = 1000; |
1463 | + struct touch_frame *frame = &dev->frame; |
1464 | + int i, nslot = 0; |
1465 | + finish_touch(dev, frame); |
1466 | + grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) |
1467 | + frame->active[nslot++] = &frame->touch[i]; |
1468 | + frame->nactive = nslot; |
1469 | + frame->time = syn->time.tv_usec / ms + syn->time.tv_sec * ms; |
1470 | if (dev->sync) |
1471 | dev->sync(dev, syn); |
1472 | + frame->ncreate = 0; |
1473 | + frame->nmodify = 0; |
1474 | + frame->ndestroy = 0; |
1475 | } |
1476 | |
1477 | static int handle_abs_event(struct touch_dev *dev, |
1478 | const struct input_event *ev) |
1479 | { |
1480 | - struct touch_dev_impl *x = dev->impl; |
1481 | + struct touch_frame *frame = &dev->frame; |
1482 | + struct touch *t = &frame->touch[dev->slot]; |
1483 | switch (ev->code) { |
1484 | case ABS_MT_SLOT: |
1485 | if (ev->value >= 0 && ev->value < DIM_TOUCH) { |
1486 | - if (x->slot != ev->value) |
1487 | - finish_touch(dev, x); |
1488 | - x->slot = ev->value; |
1489 | + if (dev->slot != ev->value) |
1490 | + finish_touch(dev, frame); |
1491 | + dev->slot = ev->value; |
1492 | + t = &frame->touch[dev->slot]; |
1493 | } |
1494 | return 1; |
1495 | case ABS_MT_POSITION_X: |
1496 | - set_prop(x, TP_POS_X, ev->value); |
1497 | + SET_PROP(x, ev->value); |
1498 | return 1; |
1499 | case ABS_MT_POSITION_Y: |
1500 | - set_prop(x, TP_POS_Y, ev->value); |
1501 | + SET_PROP(y, ev->value); |
1502 | return 1; |
1503 | case ABS_MT_TOUCH_MAJOR: |
1504 | - set_prop(x, TP_TOUCH_MAJOR, ev->value); |
1505 | + SET_PROP(touch_major, ev->value); |
1506 | return 1; |
1507 | case ABS_MT_TOUCH_MINOR: |
1508 | - set_prop(x, TP_TOUCH_MINOR, ev->value); |
1509 | + SET_PROP(touch_minor, ev->value); |
1510 | return 1; |
1511 | case ABS_MT_WIDTH_MAJOR: |
1512 | - set_prop(x, TP_WIDTH_MAJOR, ev->value); |
1513 | + SET_PROP(width_major, ev->value); |
1514 | return 1; |
1515 | case ABS_MT_WIDTH_MINOR: |
1516 | - set_prop(x, TP_WIDTH_MINOR, ev->value); |
1517 | + SET_PROP(width_minor, ev->value); |
1518 | return 1; |
1519 | case ABS_MT_ORIENTATION: |
1520 | - set_prop(x, TP_ORIENTATION, ev->value); |
1521 | + SET_PROP(orientation, ev->value); |
1522 | return 1; |
1523 | case ABS_MT_PRESSURE: |
1524 | - set_prop(x, TP_PRESSURE, ev->value); |
1525 | + SET_PROP(pressure, ev->value); |
1526 | + return 1; |
1527 | + case ABS_MT_TOOL_TYPE: |
1528 | + SET_PROP(tool_type, ev->value); |
1529 | return 1; |
1530 | case ABS_MT_TRACKING_ID: |
1531 | - if (x->id[x->slot] != ev->value) { |
1532 | - if (x->id[x->slot] != MT_ID_NULL) { |
1533 | - x->status = -1; |
1534 | - finish_touch(dev, x); |
1535 | + if (t->id != ev->value) { |
1536 | + if (t->id != MT_ID_NULL) { |
1537 | + dev->state = -1; |
1538 | + finish_touch(dev, frame); |
1539 | } |
1540 | if (ev->value != MT_ID_NULL) |
1541 | - x->status = 1; |
1542 | + dev->state = 1; |
1543 | + t->id = ev->value; |
1544 | } |
1545 | - x->id[x->slot] = ev->value; |
1546 | return 1; |
1547 | default: |
1548 | return 0; |
1549 | @@ -155,38 +124,35 @@ |
1550 | |
1551 | int touch_dev_open(struct touch_dev *dev, int fd) |
1552 | { |
1553 | - struct touch_dev_impl *x; |
1554 | + struct touch_frame *frame = &dev->frame; |
1555 | int ret, i; |
1556 | memset(dev, 0, sizeof(*dev)); |
1557 | - x = calloc(1, sizeof(*x)); |
1558 | - if (!x) |
1559 | - return -ENOMEM; |
1560 | - ret = mtdev_open(&x->mtdev, fd); |
1561 | - if (!ret && !x->mtdev.caps.has_mtdata) |
1562 | + for (i = 0; i < DIM_TOUCH; i++) { |
1563 | + struct touch *t = &frame->touch[i]; |
1564 | + t->slot = i; |
1565 | + t->id = MT_ID_NULL; |
1566 | + } |
1567 | + ret = mtdev_open(&dev->mtdev, fd); |
1568 | + if (!ret && !dev->mtdev.caps.has_mtdata) |
1569 | ret = -ENODEV; |
1570 | if (ret) |
1571 | goto error; |
1572 | - for (i = 0; i < DIM_TOUCH; i++) |
1573 | - x->id[i] = MT_ID_NULL; |
1574 | - set_caps(&dev->caps, &x->mtdev.caps); |
1575 | - dev->impl = x; |
1576 | + touch_caps_init(dev); |
1577 | return 0; |
1578 | error: |
1579 | - free(x); |
1580 | return ret; |
1581 | } |
1582 | |
1583 | int touch_dev_idle(struct touch_dev *dev, int fd, int ms) |
1584 | { |
1585 | - return mtdev_idle(&dev->impl->mtdev, fd, ms); |
1586 | + return mtdev_idle(&dev->mtdev, fd, ms); |
1587 | } |
1588 | |
1589 | int touch_dev_pull(struct touch_dev *dev, int fd) |
1590 | { |
1591 | - struct touch_dev_impl *x = dev->impl; |
1592 | struct input_event ev; |
1593 | int ret, count = 0, consumed; |
1594 | - while ((ret = mtdev_get(&x->mtdev, fd, &ev, 1)) > 0) { |
1595 | + while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) { |
1596 | consumed = 0; |
1597 | if (ev.type == EV_SYN) { |
1598 | if (ev.code == SYN_REPORT) |
1599 | @@ -204,8 +170,6 @@ |
1600 | |
1601 | void touch_dev_close(struct touch_dev *dev, int fd) |
1602 | { |
1603 | - struct touch_dev_impl *x = dev->impl; |
1604 | - mtdev_close(&x->mtdev); |
1605 | - free(x); |
1606 | + mtdev_close(&dev->mtdev); |
1607 | memset(dev, 0, sizeof(*dev)); |
1608 | } |
1609 | |
1610 | === removed file 'src/touch-engine.c' |
1611 | --- src/touch-engine.c 2010-08-06 20:30:20 +0000 |
1612 | +++ src/touch-engine.c 1970-01-01 00:00:00 +0000 |
1613 | @@ -1,135 +0,0 @@ |
1614 | -/***************************************************************************** |
1615 | - * |
1616 | - * grail - Gesture Recognition And Instantiation Library |
1617 | - * |
1618 | - * Copyright (C) 2010 Canonical Ltd. |
1619 | - * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org> |
1620 | - * |
1621 | - * This program is free software: you can redistribute it and/or modify it |
1622 | - * under the terms of the GNU General Public License as published by the |
1623 | - * Free Software Foundation, either version 3 of the License, or (at your |
1624 | - * option) any later version. |
1625 | - * |
1626 | - * This program is distributed in the hope that it will be useful, but |
1627 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
1628 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1629 | - * General Public License for more details. |
1630 | - * |
1631 | - * You should have received a copy of the GNU General Public License along |
1632 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1633 | - * |
1634 | - ****************************************************************************/ |
1635 | - |
1636 | -#include <grail-touch.h> |
1637 | -#include <string.h> |
1638 | - |
1639 | -static void tp_event(struct touch_dev *dev, const struct input_event *ev) |
1640 | -{ |
1641 | - struct touch_engine *engine = dev->priv; |
1642 | - if (engine && engine->event) |
1643 | - engine->event(engine, ev); |
1644 | -} |
1645 | - |
1646 | -static void update_frame(struct touch_frame *frame, |
1647 | - int slot, int active, |
1648 | - const grail_mask_t *mask, |
1649 | - const touch_prop_t *prop) |
1650 | -{ |
1651 | - struct touch *t = &frame->touch[slot]; |
1652 | - int i; |
1653 | - t->active = active; |
1654 | - grail_mask_modify(frame->touches, slot, active); |
1655 | - if (mask && prop) |
1656 | - grail_mask_foreach(i, mask, DIM_TOUCH_PROP_BYTES) |
1657 | - t->prop[i] = prop[i]; |
1658 | -} |
1659 | - |
1660 | -static void finalize_frame(struct touch_frame *frame, touch_time_t time) |
1661 | -{ |
1662 | - int i, nslot = 0; |
1663 | - grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) |
1664 | - frame->active[nslot++] = &frame->touch[i]; |
1665 | - frame->nactive = nslot; |
1666 | - frame->time = time; |
1667 | -} |
1668 | - |
1669 | -static void tp_create(struct touch_dev *dev, int slot, |
1670 | - const grail_mask_t *mask, const touch_prop_t *prop) |
1671 | -{ |
1672 | - struct touch_engine *engine = dev->priv; |
1673 | - if (engine) { |
1674 | - engine->frame.ncreate++; |
1675 | - update_frame(&engine->frame, slot, 1, mask, prop); |
1676 | - } |
1677 | -} |
1678 | - |
1679 | -static void tp_modify(struct touch_dev *dev, int slot, |
1680 | - const grail_mask_t *mask, const touch_prop_t *prop) |
1681 | -{ |
1682 | - struct touch_engine *engine = dev->priv; |
1683 | - if (engine) { |
1684 | - engine->frame.nmodify++; |
1685 | - update_frame(&engine->frame, slot, 1, mask, prop); |
1686 | - } |
1687 | -} |
1688 | - |
1689 | -static void tp_destroy(struct touch_dev *dev, int slot) |
1690 | -{ |
1691 | - struct touch_engine *engine = dev->priv; |
1692 | - if (engine) { |
1693 | - engine->frame.ndestroy++; |
1694 | - update_frame(&engine->frame, slot, 0, 0, 0); |
1695 | - } |
1696 | -} |
1697 | - |
1698 | -static void tp_sync(struct touch_dev *dev, const struct input_event *syn) |
1699 | -{ |
1700 | - static const touch_time_t ms = 1000; |
1701 | - struct touch_engine *engine = dev->priv; |
1702 | - touch_time_t time = syn->time.tv_usec / ms + syn->time.tv_sec * ms; |
1703 | - if (engine) { |
1704 | - finalize_frame(&engine->frame, time); |
1705 | - if (engine->sync) |
1706 | - engine->sync(engine, syn); |
1707 | - engine->frame.ncreate = 0; |
1708 | - engine->frame.nmodify = 0; |
1709 | - engine->frame.ndestroy = 0; |
1710 | - } |
1711 | -} |
1712 | - |
1713 | -void touch_engine_init(struct touch_engine *engine, |
1714 | - void (*event)(struct touch_engine *engine, |
1715 | - const struct input_event *ev), |
1716 | - void (*sync)(struct touch_engine *engine, |
1717 | - const struct input_event *ev), |
1718 | - void *priv) |
1719 | -{ |
1720 | - int i; |
1721 | - memset(engine, 0, sizeof(*engine)); |
1722 | - for (i = 0; i < DIM_TOUCH; i++) |
1723 | - engine->frame.touch[i].slot = i; |
1724 | - engine->event = event; |
1725 | - engine->sync = sync; |
1726 | - engine->priv = priv; |
1727 | -} |
1728 | - |
1729 | -void touch_engine_attach(struct touch_engine *engine, struct touch_dev *dev) |
1730 | -{ |
1731 | - dev->priv = engine; |
1732 | - dev->event = tp_event; |
1733 | - dev->create = tp_create; |
1734 | - dev->modify = tp_modify; |
1735 | - dev->destroy = tp_destroy; |
1736 | - dev->sync = tp_sync; |
1737 | -} |
1738 | - |
1739 | -void touch_engine_detach(struct touch_engine *engine, struct touch_dev *dev) |
1740 | -{ |
1741 | - dev->sync = 0; |
1742 | - dev->destroy = 0; |
1743 | - dev->modify = 0; |
1744 | - dev->create = 0; |
1745 | - dev->event = 0; |
1746 | - dev->priv = 0; |
1747 | -} |
1748 | - |
1749 | |
1750 | === modified file 'test/grail-gesture.c' |
1751 | --- test/grail-gesture.c 2010-08-11 17:07:40 +0000 |
1752 | +++ test/grail-gesture.c 2010-08-19 20:46:41 +0000 |
1753 | @@ -53,11 +53,21 @@ |
1754 | |
1755 | static void tp_gesture(struct grail *ge, const struct grail_event *ev) |
1756 | { |
1757 | - int i; |
1758 | + struct grail_contact touch[32]; |
1759 | + int i, ntouch; |
1760 | fprintf(stderr, "gesture %d %d %d %d - %f %f %d - %d\n", |
1761 | ev->type, ev->id, ev->client_id.client, ev->client_id.event, |
1762 | ev->pos.x, ev->pos.y, ev->ntouch, |
1763 | ev->status); |
1764 | + ntouch = grail_get_contacts(ge, touch, 32); |
1765 | + for (i = 0; i < ntouch; i++) { |
1766 | + const struct grail_contact *t = &touch[i]; |
1767 | + fprintf(stderr, "\t%d: %d %d\n", i, t->id, t->tool_type); |
1768 | + fprintf(stderr, "\t %f %f\n", t->pos.x, t->pos.y); |
1769 | + fprintf(stderr, "\t %f %f %f %f\n", t->touch_major, |
1770 | + t->touch_minor, t->width_major, t->width_minor); |
1771 | + fprintf(stderr, "\t %f %f\n", t->angle, t->pressure); |
1772 | + } |
1773 | for (i = 0; i < ev->nprop; i++) |
1774 | fprintf(stderr, "\t%d: %f\n", i, ev->prop[i]); |
1775 | } |
1776 | |
1777 | === modified file 'test/grail-touch.c' |
1778 | --- test/grail-touch.c 2010-08-06 12:33:32 +0000 |
1779 | +++ test/grail-touch.c 2010-08-19 20:46:41 +0000 |
1780 | @@ -28,22 +28,33 @@ |
1781 | #include <unistd.h> |
1782 | #include <fcntl.h> |
1783 | |
1784 | -static void tp_event(struct touch_engine *engine, |
1785 | +static void tp_event(struct touch_dev *dev, |
1786 | const struct input_event *ev) |
1787 | { |
1788 | fprintf(stderr, "event %d 0x%x %d\n", ev->type, ev->code, ev->value); |
1789 | } |
1790 | |
1791 | -static void tp_sync(struct touch_engine *engine, |
1792 | +static void tp_sync(struct touch_dev *dev, |
1793 | const struct input_event *syn) |
1794 | { |
1795 | - struct touch_frame *frame = &engine->frame; |
1796 | + struct touch_frame *frame = &dev->frame; |
1797 | int i, j; |
1798 | for (i = 0; i < frame->nactive; i++) { |
1799 | struct touch *t = frame->active[i]; |
1800 | - fprintf(stderr, "touch %d %d\n", i, t->slot); |
1801 | - for (j = 0; j < DIM_TOUCH_PROP; j++) |
1802 | - fprintf(stderr, " %d\n", t->prop[j]); |
1803 | + fprintf(stderr, "touch %d\n", i); |
1804 | + fprintf(stderr, " slot: %d\n", t->slot); |
1805 | + fprintf(stderr, " id: %d\n", t->id); |
1806 | + fprintf(stderr, " tool_type: %d\n", t->tool_type); |
1807 | + fprintf(stderr, " x: %d\n", t->x); |
1808 | + fprintf(stderr, " y: %d\n", t->y); |
1809 | + fprintf(stderr, " touch_major: %d\n", t->touch_major); |
1810 | + fprintf(stderr, " touch_minor: %d\n", t->touch_minor); |
1811 | + fprintf(stderr, " width_major: %d\n", t->width_major); |
1812 | + fprintf(stderr, " width_minor: %d\n", t->width_minor); |
1813 | + fprintf(stderr, " angle: %f\n", |
1814 | + touch_angle(dev, t->orientation)); |
1815 | + fprintf(stderr, " pressure: %f\n", |
1816 | + touch_pressure(dev, t->pressure)); |
1817 | } |
1818 | fprintf(stderr, "sync %d %lld %d %d\n", |
1819 | frame->nactive, frame->time, frame->ncreate, frame->ndestroy); |
1820 | @@ -51,12 +62,10 @@ |
1821 | |
1822 | static void loop_device(struct touch_dev *dev, int fd) |
1823 | { |
1824 | - struct touch_engine engine; |
1825 | - touch_engine_init(&engine, tp_event, tp_sync, 0); |
1826 | - touch_engine_attach(&engine, dev); |
1827 | + dev->event = tp_event; |
1828 | + dev->sync = tp_sync; |
1829 | while (!touch_dev_idle(dev, fd, 5000)) |
1830 | touch_dev_pull(dev, fd); |
1831 | - touch_engine_detach(&engine, dev); |
1832 | } |
1833 | |
1834 | int main(int argc, char *argv[]) |
I hadn't reviewed grail before, so I tried to do so before looking at the changes. I think I understand some of the basic concepts of how grail works, and the changes in this merge request seem good.