Merge lp:~oif-team/grail/eventprinter into lp:grail

Proposed by Jussi Pakkanen
Status: Merged
Merged at revision: 167
Proposed branch: lp:~oif-team/grail/eventprinter
Merge into: lp:grail
Diff against target: 253 lines (+240/-0)
2 files modified
tools/Makefile.am (+1/-0)
tools/grail-eventprinter.c (+239/-0)
To merge this branch: bzr merge lp:~oif-team/grail/eventprinter
Reviewer Review Type Date Requested Status
Chase Douglas (community) Approve
Review via email: mp+72400@code.launchpad.net

Description of the change

This branch adds a test application that prints Grail events in plaintext. It is meant as a complement to the existing Grail event printer application. That application prints every piece of information on every event. That makes it useful for detail inspection.

This application prints gesture progression less detailed but more "logical" way. It is meant to quickly answer questions such as "does this trace produce a rotation gesture", "in which order are the drag and pinch gestures detected/reported" and so on.

"Make install" does not install this app, because it is not yet polished enough for end user consumption.

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

I would like to see it cleaned up before merging. If it's in the source tree, then people might look to it as an example of how to use grail.

For the same reason, I would like to get rid of including grail-impl.h. What do you need it for?

review: Needs Fixing
Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

What sorts of cleanups did you have in mind? As an aside: the parts that use Grail are almost directly copypasted from grail-gesture.c.

I #include grail-impl.h because I need to access the private structure to set fast_fileread. I assume that we don't want to expose that in the API. Or if we do, it needs its own branch.

lp:~oif-team/grail/eventprinter updated
171. By Jussi Pakkanen

Removed spurious parentheses.

172. By Jussi Pakkanen

No not install eventprinter. For real this time.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

The thing that stuck out for me was the grail-impl.h include and the line near the end:

//grail_filter_abs_events(&ge, 1);

I think we should delete that line. For grail-impl.h, we should have a comment stating why it's included here so people know that this is an exception for a test tool that ships with the library.

Other than that, if it compiles cleanly with -Wall -Werror that I think it's ready to be merged.

lp:~oif-team/grail/eventprinter updated
173. By Jussi Pakkanen

Clarify that other people should not include Grail's internal headers.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

I clarified the comment. Is it OK now?

Grail itself does not build with -Wall -Werror but building with -Wall did not seem to produce any warnings, so it should be good.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

Please put a note in the comment about why the header is included, i.e. about the fast playback of events. Otherwise, I don't really know why its there, and I'm likely to forget :).

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

How about now?

lp:~oif-team/grail/eventprinter updated
174. By Jussi Pakkanen

Clearer description of private header include.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

Looks good! Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tools/Makefile.am'
2--- tools/Makefile.am 2011-04-28 16:53:53 +0000
3+++ tools/Makefile.am 2011-08-26 07:11:23 +0000
4@@ -1,4 +1,5 @@
5 bin_PROGRAMS = grail-gesture grail-test-mtdev
6+noinst_PROGRAMS = grail-eventprinter
7
8 if HAVE_XI
9
10
11=== added file 'tools/grail-eventprinter.c'
12--- tools/grail-eventprinter.c 1970-01-01 00:00:00 +0000
13+++ tools/grail-eventprinter.c 2011-08-26 07:11:23 +0000
14@@ -0,0 +1,239 @@
15+/*****************************************************************************
16+ *
17+ * grail-eventprinter - pretty prints events as produced by Grail
18+ *
19+ * Copyright (C) 2010-2011 Canonical Ltd.
20+ *
21+ * This program is free software: you can redistribute it and/or modify it
22+ * under the terms of the GNU General Public License as published by the
23+ * Free Software Foundation, either version 3 of the License, or (at your
24+ * option) any later version.
25+ *
26+ * This program is distributed in the hope that it will be useful, but
27+ * WITHOUT ANY WARRANTY; without even the implied warranty of
28+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29+ * General Public License for more details.
30+ *
31+ * You should have received a copy of the GNU General Public License along
32+ * with this program. If not, see <http://www.gnu.org/licenses/>.
33+ *
34+ ****************************************************************************/
35+
36+/* Regular applications must include <grail.h>. Since
37+ * this application needs to access Grail's internals
38+ * to access the private fast_fileread struct element,
39+ * it needs this header.
40+ *
41+ * Only Grail's internal tools are allowed to include
42+ * this header.
43+ */
44+#include "../src/grail-impl.h"
45+
46+#include <string.h>
47+#include <stdio.h>
48+#include <unistd.h>
49+#include <fcntl.h>
50+#include <stdlib.h>
51+#include <sys/stat.h>
52+
53+static grail_mask_t flag_mask[DIM_GRAIL_TYPE_BYTES];
54+
55+/* Order is the same as with defines in grail-types.h */
56+
57+static const char* const grail_event_names[] = {
58+ "Drag1",
59+ "Pinch1",
60+ "Rotate1",
61+ "Drag2",
62+ "Pinch2",
63+ "Rotate2",
64+ "Drag3",
65+ "Pinch3",
66+ "Rotate3",
67+ "Drag4",
68+ "Pinch4",
69+ "Rotate4",
70+ "Drag5",
71+ "Pinch5",
72+ "Rotate5",
73+ "Tap1",
74+ "Tap2",
75+ "Tap3",
76+ "Tap4",
77+ "Tap5",
78+ "Edrag",
79+ "Epinch",
80+ "Erotate",
81+ "Mdrag",
82+ "Mpinch",
83+ "Mrotate",
84+ "Sysflag1",
85+ "Unknown27",
86+ "Unknown28",
87+ "Unknown29",
88+ "Unknown30",
89+ "Unknown31",
90+ "Touch1",
91+ "Touch2",
92+ "Touch3",
93+ "Touch4",
94+ "Touch5",
95+ "Etouch",
96+ "Mtouch"
97+};
98+
99+static int tp_get_clients(struct grail *ge,
100+ struct grail_client_info *clients, int max_clients,
101+ const struct grail_coord *coords, int num_coords,
102+ const grail_mask_t *types, int type_bytes)
103+{
104+ printf("Client query.\n");
105+
106+ memset(&clients[0], 0, sizeof(clients[0]));
107+ clients[0].id.client = 345;
108+ clients[0].id.root = 1;
109+ clients[0].id.event = 2;
110+ clients[0].id.child = 3;
111+ memcpy(clients[0].mask, flag_mask, sizeof(flag_mask));
112+ return 1;
113+}
114+
115+static void tp_event(struct grail *ge, const struct input_event *ev)
116+{
117+ printf("Input event.\n");
118+}
119+
120+static int is_drag_event(const struct grail_event *ev) {
121+ return ev->type == GRAIL_TYPE_DRAG1 ||
122+ ev->type == GRAIL_TYPE_DRAG2 ||
123+ ev->type == GRAIL_TYPE_DRAG3 ||
124+ ev->type == GRAIL_TYPE_DRAG4 ||
125+ ev->type == GRAIL_TYPE_DRAG5;
126+}
127+
128+static void print_drag_stats(const struct grail_event *ev) {
129+ printf(" c = (%f, %f), delta = (%f, %f)\n",
130+ ev->prop[GRAIL_PROP_DRAG_X],
131+ ev->prop[GRAIL_PROP_DRAG_Y],
132+ ev->prop[GRAIL_PROP_DRAG_VX],
133+ ev->prop[GRAIL_PROP_DRAG_VY]);
134+}
135+
136+static int is_rotate_event(const struct grail_event *ev) {
137+ return ev->type == GRAIL_TYPE_ROTATE1 ||
138+ ev->type == GRAIL_TYPE_ROTATE2 ||
139+ ev->type == GRAIL_TYPE_ROTATE3 ||
140+ ev->type == GRAIL_TYPE_ROTATE4 ||
141+ ev->type == GRAIL_TYPE_ROTATE5;
142+}
143+
144+static void print_rotate_stats(const struct grail_event *ev) {
145+ printf(" a = %f, va = %f\n",
146+ ev->prop[GRAIL_PROP_ROTATE_A],
147+ ev->prop[GRAIL_PROP_ROTATE_VA]);
148+}
149+
150+static int is_pinch_event(const struct grail_event *ev) {
151+ return ev->type == GRAIL_TYPE_PINCH1 ||
152+ ev->type == GRAIL_TYPE_PINCH2 ||
153+ ev->type == GRAIL_TYPE_PINCH3 ||
154+ ev->type == GRAIL_TYPE_PINCH4 ||
155+ ev->type == GRAIL_TYPE_PINCH5;
156+}
157+
158+static void print_pinch_stats(const struct grail_event *ev) {
159+ printf(" radius = %f, delta r = %f\n",
160+ ev->prop[GRAIL_PROP_PINCH_R],
161+ ev->prop[GRAIL_PROP_PINCH_VR]);
162+}
163+
164+const char *event_name(const struct grail_event *ev) {
165+ return grail_event_names[ev->type];
166+}
167+
168+static void tp_gesture(struct grail *ge, const struct grail_event *ev)
169+{
170+ if (ev->status == GRAIL_STATUS_BEGIN) {
171+ printf("BEGIN gesture %s\n", event_name(ev));
172+ if (is_drag_event(ev)){
173+ print_drag_stats(ev);
174+ }
175+ if (is_rotate_event(ev)) {
176+ print_rotate_stats(ev);
177+ }
178+ if (is_pinch_event(ev)) {
179+ print_pinch_stats(ev);
180+ }
181+ }
182+ if (ev->status == GRAIL_STATUS_UPDATE) {
183+ printf("UPDATE gesture %s.\n", event_name(ev));
184+ }
185+ if (ev->status == GRAIL_STATUS_END) {
186+ printf("END gesture %s.\n", event_name(ev));
187+ if (is_drag_event(ev)){
188+ print_drag_stats(ev);
189+ }
190+ if (is_rotate_event(ev)) {
191+ print_rotate_stats(ev);
192+ }
193+ if (is_pinch_event(ev)) {
194+ print_pinch_stats(ev);
195+ }
196+ }
197+}
198+
199+static void loop_device(struct grail *ge, int fd)
200+{
201+ while (!grail_idle(ge, fd, 5000))
202+ grail_pull(ge, fd);
203+}
204+
205+int main(int argc, char *argv[])
206+{
207+ struct grail ge;
208+ struct stat fs;
209+ int i, fd;
210+
211+ if (argc < 2) {
212+ fprintf(stderr, "Usage: %s <device or trace file>\n", argv[0]);
213+ return -1;
214+ }
215+
216+ memset(&ge, 0, sizeof(ge));
217+ ge.get_clients = tp_get_clients;
218+ ge.event = tp_event;
219+ ge.gesture = tp_gesture;
220+
221+ unsigned long mask = 0xffffffff; /* Get every gesture type. */
222+ for (i = 0; i < DIM_GRAIL_TYPE; i++)
223+ if ((mask >> i) & 1)
224+ grail_mask_set(flag_mask, i);
225+
226+ fd = open(argv[1], O_RDONLY | O_NONBLOCK);
227+ if (fd < 0) {
228+ fprintf(stderr, "error: could not open device\n");
229+ return -1;
230+ }
231+ if (fstat(fd, &fs)) {
232+ fprintf(stderr, "error: could not stat the device\n");
233+ return -1;
234+ }
235+ if (fs.st_rdev && ioctl(fd, EVIOCGRAB, 1)) {
236+ fprintf(stderr, "error: could not grab the device\n");
237+ return -1;
238+ }
239+
240+ if (grail_open(&ge, fd)) {
241+ fprintf(stderr, "error: could not open touch device\n");
242+ return -1;
243+ }
244+ ge.impl->fast_fileread = 1;
245+
246+ loop_device(&ge, fd);
247+ grail_close(&ge, fd);
248+
249+ if (fs.st_rdev)
250+ ioctl(fd, EVIOCGRAB, 0);
251+ close(fd);
252+ return 0;
253+}

Subscribers

People subscribed via source and target branches

to all changes: