summaryrefslogtreecommitdiff
path: root/src/touch-dev.c
diff options
context:
space:
mode:
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}