Merge lp:~oif-team/grail/trunk.touches into lp:grail

Proposed by Henrik Rydberg
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
Reviewer Review Type Date Requested Status
Chase Douglas (community) Needs Fixing
Review via email: mp+33152@code.launchpad.net

Description of the change

The last big change before release

1. Simplify the touch frame handling
2. Add the grail_get_contacts() function to the api
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.

To post a comment you must log in.
Revision history for this message
Chase Douglas (chasedouglas) wrote :

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.

review: Approve
Revision history for this message
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.

review: Needs Fixing
Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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[])

Subscribers

People subscribed via source and target branches

to all changes: