summaryrefslogtreecommitdiff
path: root/test/grail.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/grail.c')
-rw-r--r--test/grail.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/test/grail.c b/test/grail.c
new file mode 100644
index 0000000..3fe20ee
--- /dev/null
+++ b/test/grail.c
@@ -0,0 +1,177 @@
1/*****************************************************************************
2 *
3 * grail - Gesture Recognition And Instantiation Library
4 *
5 * Copyright (C) 2010 Canonical Ltd.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Authors:
21 * Henrik Rydberg <rydberg@bitmath.org>
22 *
23 ****************************************************************************/
24
25#include <grail.h>
26#include <string.h>
27#include <stdio.h>
28#include <unistd.h>
29#include <fcntl.h>
30
31struct gesture_handler {
32 struct touch_frame frame;
33 struct gesture_client client;
34 struct gesture_dev dev;
35 touch_time_t last_scroll;
36};
37
38static void gh_gesture(struct gesture_client *client,
39 const struct gesture_event *ev)
40{
41 int i;
42 fprintf(stderr, "gesture %d %lld\n",
43 ev->type, ev->time);
44 switch (ev->type) {
45 case GE_MOVE:
46 fprintf(stderr, " %d\n", ev->prop[0]);
47 fprintf(stderr, " %d\n", ev->prop[1]);
48 break;
49 case GE_VSCROLL:
50 fprintf(stderr, " %d\n", ev->prop[0]);
51 break;
52 }
53}
54
55static void gh_init(struct gesture_handler *gh)
56{
57 memset(gh, 0, sizeof(*gh));
58 gedev_init(&gh->dev, 0);
59 client_init(&gh->client, gh);
60 gh->client.gesture = gh_gesture;
61 gh->client.priority[GE_MOVE] = 1;
62 gh->client.priority[GE_VSCROLL] = 2;
63 gedev_attach_client(&gh->dev, &gh->client);
64}
65
66static void gh_handle(struct gesture_handler *gh,
67 const struct touch_frame *frame,
68 touch_time_t time)
69{
70 struct gesture_flag flag;
71 struct gesture_event ev;
72 if (frame->ntouch == 1 || frame->ntouch == 2) {
73 flag.type = GE_MOVE;
74 flag.time = time;
75 flag.state = GS_BEGIN;
76 gedev_flag(&gh->dev, &flag);
77
78 ev.type = GE_MOVE;
79 ev.time = time;
80 ev.prop[0] =
81 frame->touch[0].prop[TP_POS_X] -
82 gh->frame.touch[0].prop[TP_POS_X];
83 ev.prop[1] =
84 frame->touch[0].prop[TP_POS_Y] -
85 gh->frame.touch[0].prop[TP_POS_Y];
86 if (ev.prop[0] || ev.prop[1])
87 gedev_event(&gh->dev, &ev);
88
89 flag.time = time + 1;
90 flag.state = GS_END;
91 gedev_flag(&gh->dev, &flag);
92 }
93 if (frame->ntouch == 2) {
94 flag.type = GE_VSCROLL;
95 flag.time = time;
96 flag.state = GS_BEGIN;
97 gedev_flag(&gh->dev, &flag);
98
99 ev.type = GE_VSCROLL;
100 ev.time = time;
101 ev.prop[0] =
102 frame->touch[0].prop[TP_POS_Y] -
103 gh->frame.touch[0].prop[TP_POS_Y];
104
105 if (ev.prop[0])
106 gedev_event(&gh->dev, &ev);
107
108 if (time > gh->last_scroll + 100) {
109 flag.time = time + 1;
110 flag.state = GS_END;
111 gedev_flag(&gh->dev, &flag);
112 gh->last_scroll = time;
113 }
114 } else {
115 flag.type = GE_VSCROLL;
116 flag.time = time;
117 flag.state = GS_CANCEL;
118 gedev_flag(&gh->dev, &flag);
119 }
120 gedev_sync(&gh->dev);
121 gh->frame = *frame;
122}
123
124static void gh_destroy(struct gesture_handler *gh)
125{
126 gedev_detach_client(&gh->dev, &gh->client);
127 client_destroy(&gh->client);
128 gedev_destroy(&gh->dev);
129}
130
131static void tp_sync(struct touch_engine *engine, touch_time_t time)
132{
133 struct gesture_handler *gh = engine->priv;
134 struct touch_frame *frame = &engine->frame;
135 gh_handle(gh, frame, time);
136}
137
138static void loop_device(struct touch_dev *dev, int fd)
139{
140 struct gesture_handler gh;
141 struct touch_engine engine;
142 gh_init(&gh);
143 touch_engine_init(&engine, tp_sync, &gh);
144 touch_engine_attach(&engine, dev);
145 while (!touch_dev_idle(dev, fd, 5000))
146 touch_dev_pull(dev, fd);
147 touch_engine_detach(&engine, dev);
148 gh_destroy(&gh);
149}
150
151int main(int argc, char *argv[])
152{
153 struct touch_dev dev;
154 int fd;
155 if (argc < 2) {
156 fprintf(stderr, "Usage: mtdev <device>\n");
157 return -1;
158 }
159 fd = open(argv[1], O_RDONLY | O_NONBLOCK);
160 if (fd < 0) {
161 fprintf(stderr, "error: could not open device\n");
162 return -1;
163 }
164 if (ioctl(fd, EVIOCGRAB, 1)) {
165 fprintf(stderr, "error: could not grab the device\n");
166 return -1;
167 }
168 if (touch_dev_open(&dev, fd)) {
169 fprintf(stderr, "error: could not open touch device\n");
170 return -1;
171 }
172 loop_device(&dev, fd);
173 touch_dev_close(&dev, fd);
174 ioctl(fd, EVIOCGRAB, 0);
175 close(fd);
176 return 0;
177}