summaryrefslogtreecommitdiff
path: root/src/touch-dev.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-01-02 11:00:52 +0100
committerHenrik Rydberg <rydberg@euromail.se>2011-01-02 12:39:07 +0100
commitc0666a895e7fe8e488332263fd106ced0ed7cab7 (patch)
treefca88fbee4aaed6e1eed050a749ce6246a7f1966 /src/touch-dev.c
parent1e07054fbeab6e90f104c279d3246097dd838a17 (diff)
Replace touch logic with utouch frame engine
The original grail uses an internal touch framework and exports some touch information as extended attributes to gesture events. This was never quite the intention, but rather to expose gestures and touches on a similar footing, such that grail can be input agnostic. This patch starts off by replacing the internal touch framework with the utouch-frame engine. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/touch-dev.c')
-rw-r--r--src/touch-dev.c264
1 files changed, 0 insertions, 264 deletions
diff --git a/src/touch-dev.c b/src/touch-dev.c
deleted file mode 100644
index d8e192e..0000000
--- a/src/touch-dev.c
+++ /dev/null
@@ -1,264 +0,0 @@
1/*****************************************************************************
2 *
3 * grail - Gesture Recognition And Instantiation Library
4 *
5 * Copyright (C) 2010 Canonical Ltd.
6 * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23#include <grail-touch.h>
24#include <malloc.h>
25#include <string.h>
26#include <errno.h>
27
28/* see mtdev-mapping.h */
29#define MTDEV_TOUCH_MINOR 1
30
31#define SET_PROP(name, value) \
32 if (t->name != value) { \
33 t->name = value; \
34 frame->nmodify++; \
35 }
36
37static void finish_touch(struct touch_dev *dev, struct touch_frame *frame)
38{
39 struct touch *t = &frame->touch[dev->slot];
40 if (t->touch_major && !t->touch_minor ||
41 !dev->mtdev.caps.has_abs[MTDEV_TOUCH_MINOR])
42 SET_PROP(touch_minor, t->touch_major);
43 if (dev->state > 0) {
44 t->active = 1;
45 grail_mask_set(frame->touches, dev->slot);
46 frame->ncreate++;
47 }
48 if (dev->state < 0) {
49 t->active = 0;
50 grail_mask_clear(frame->touches, dev->slot);
51 frame->ndestroy++;
52 }
53 dev->state = 0;
54}
55
56static void finish_legacy(struct touch_dev *dev, struct touch_frame *frame)
57{
58 static int trkid;
59 int i;
60 for (i = 0; i < frame->nactive; i++) {
61 struct touch *t = &frame->touch[i];
62 t->active = 1;
63 if (t->id < 0) {
64 t->id = trkid++ & 0xffff;
65 frame->ncreate++;
66 }
67 if (i > 0) {
68 SET_PROP(x, frame->touch[0].x);
69 SET_PROP(y, frame->touch[0].y);
70 SET_PROP(pressure, frame->touch[0].pressure);
71 }
72 grail_mask_set(frame->touches, i);
73 }
74 for (i = frame->nactive; i < DIM_TOUCH; i++) {
75 struct touch *t = &frame->touch[i];
76 t->active = 0;
77 if (t->id >= 0) {
78 t->id = -1;
79 frame->ndestroy++;
80 }
81 grail_mask_clear(frame->touches, i);
82 }
83}
84
85static void finish_packet(struct touch_dev *dev,
86 const struct input_event *syn)
87{
88 static const touch_time_t ms = 1000;
89 struct touch_frame *frame = &dev->frame;
90 int i, nslot = 0;
91 if (dev->mtdev.caps.has_mtdata)
92 finish_touch(dev, frame);
93 else
94 finish_legacy(dev, frame);
95 grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES)
96 frame->active[nslot++] = &frame->touch[i];
97 frame->nactive = nslot;
98 frame->time = syn->time.tv_usec / ms + syn->time.tv_sec * ms;
99 if (dev->sync)
100 dev->sync(dev, syn);
101 frame->ncreate = 0;
102 frame->nmodify = 0;
103 frame->ndestroy = 0;
104}
105
106static int handle_abs_event(struct touch_dev *dev,
107 const struct input_event *ev)
108{
109 struct touch_frame *frame = &dev->frame;
110 struct touch *t = &frame->touch[dev->slot];
111 switch (ev->code) {
112 case ABS_X:
113 if (dev->mtdev.caps.has_mtdata)
114 return 0;
115 SET_PROP(x, ev->value);
116 return 0;
117 case ABS_Y:
118 if (dev->mtdev.caps.has_mtdata)
119 return 0;
120 SET_PROP(y, ev->value);
121 return 0;
122 case ABS_PRESSURE:
123 if (dev->mtdev.caps.has_mtdata)
124 return 0;
125 SET_PROP(pressure, ev->value);
126 return 0;
127 case ABS_MT_SLOT:
128 if (ev->value >= 0 && ev->value < DIM_TOUCH) {
129 if (dev->slot != ev->value)
130 finish_touch(dev, frame);
131 dev->slot = ev->value;
132 t = &frame->touch[dev->slot];
133 }
134 return 1;
135 case ABS_MT_POSITION_X:
136 SET_PROP(x, ev->value);
137 return 1;
138 case ABS_MT_POSITION_Y:
139 SET_PROP(y, ev->value);
140 return 1;
141 case ABS_MT_TOUCH_MAJOR:
142 SET_PROP(touch_major, ev->value);
143 return 1;
144 case ABS_MT_TOUCH_MINOR:
145 SET_PROP(touch_minor, ev->value);
146 return 1;
147 case ABS_MT_WIDTH_MAJOR:
148 SET_PROP(width_major, ev->value);
149 return 1;
150 case ABS_MT_WIDTH_MINOR:
151 SET_PROP(width_minor, ev->value);
152 return 1;
153 case ABS_MT_ORIENTATION:
154 SET_PROP(orientation, ev->value);
155 return 1;
156 case ABS_MT_PRESSURE:
157 SET_PROP(pressure, ev->value);
158 return 1;
159 case ABS_MT_TOOL_TYPE:
160 SET_PROP(tool_type, ev->value);
161 return 1;
162 case ABS_MT_TRACKING_ID:
163 if (t->id != ev->value) {
164 if (t->id != MT_ID_NULL) {
165 dev->state = -1;
166 finish_touch(dev, frame);
167 }
168 if (ev->value != MT_ID_NULL)
169 dev->state = 1;
170 t->id = ev->value;
171 }
172 return 1;
173 default:
174 return 0;
175 }
176}
177
178static int handle_key_event(struct touch_dev *dev,
179 const struct input_event *ev)
180{
181 struct touch_frame *frame = &dev->frame;
182 if (dev->mtdev.caps.has_mtdata)
183 return 0;
184 switch (ev->code) {
185 case BTN_TOUCH:
186 if (ev->value && !frame->nactive)
187 frame->nactive = 1;
188 else if (!ev->value && frame->nactive)
189 frame->nactive = 0;
190 return 0;
191 case BTN_TOOL_FINGER:
192 if (ev->value)
193 frame->nactive = 1;
194 return 0;
195 case BTN_TOOL_DOUBLETAP:
196 if (ev->value)
197 frame->nactive = 2;
198 return 0;
199 case BTN_TOOL_TRIPLETAP:
200 if (ev->value)
201 frame->nactive = 3;
202 return 0;
203 case BTN_TOOL_QUADTAP:
204 if (ev->value)
205 frame->nactive = 4;
206 return 0;
207 default:
208 return 0;
209 }
210}
211
212int touch_dev_open(struct touch_dev *dev, int fd)
213{
214 struct touch_frame *frame = &dev->frame;
215 int ret, i;
216 memset(dev, 0, sizeof(*dev));
217 for (i = 0; i < DIM_TOUCH; i++) {
218 struct touch *t = &frame->touch[i];
219 t->slot = i;
220 t->id = MT_ID_NULL;
221 }
222 ret = mtdev_open(&dev->mtdev, fd);
223 if (!ret && !touch_caps_is_supported(dev, fd))
224 ret = -ENODEV;
225 if (ret)
226 goto error;
227 touch_caps_init(dev);
228 return 0;
229 error:
230 return ret;
231}
232
233int touch_dev_idle(struct touch_dev *dev, int fd, int ms)
234{
235 return mtdev_idle(&dev->mtdev, fd, ms);
236}
237
238int touch_dev_pull(struct touch_dev *dev, int fd)
239{
240 struct input_event ev;
241 int ret, count = 0, consumed;
242 while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) {
243 consumed = 0;
244 if (ev.type == EV_SYN) {
245 if (ev.code == SYN_REPORT)
246 finish_packet(dev, &ev);
247 consumed++;
248 } else if (ev.type == EV_ABS) {
249 consumed += handle_abs_event(dev, &ev);
250 } else if (ev.type == EV_KEY) {
251 consumed += handle_key_event(dev, &ev);
252 }
253 if (!consumed && dev->event)
254 dev->event(dev, &ev);
255 count++;
256 }
257 return count > 0 ? count : ret;
258}
259
260void touch_dev_close(struct touch_dev *dev, int fd)
261{
262 mtdev_close(&dev->mtdev);
263 memset(dev, 0, sizeof(*dev));
264}