summaryrefslogtreecommitdiff
path: root/src/grail-api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/grail-api.c')
-rw-r--r--src/grail-api.c280
1 files changed, 158 insertions, 122 deletions
diff --git a/src/grail-api.c b/src/grail-api.c
index f38ca18..3aca75d 100644
--- a/src/grail-api.c
+++ b/src/grail-api.c
@@ -30,27 +30,124 @@
30#include <malloc.h> 30#include <malloc.h>
31#include <errno.h> 31#include <errno.h>
32 32
33static void tp_event(struct touch_dev *dev, 33#define DIM_FRAMES 100
34 const struct input_event *ev) 34#define FRAME_RATE 100
35
36void grail_filter_abs_events(struct grail *ge, int usage)
35{ 37{
36 struct grail *ge = dev->priv;
37 struct grail_impl *x = ge->impl; 38 struct grail_impl *x = ge->impl;
38 if (ev->type == EV_ABS) { 39 x->filter_abs = usage;
39 return; 40}
41
42static void init_impl(struct grail_impl *x)
43{
44 int i;
45
46 if (evemu_has_event(x->evemu, EV_ABS, ABS_X)) {
47 x->emin_x = evemu_get_abs_minimum(x->evemu, ABS_X);
48 x->emin_y = evemu_get_abs_minimum(x->evemu, ABS_Y);
49 x->emax_x = evemu_get_abs_maximum(x->evemu, ABS_X);
50 x->emax_y = evemu_get_abs_maximum(x->evemu, ABS_Y);
51 } else {
52 struct utouch_surface *s = utouch_frame_get_surface(x->fh);
53 x->emin_x = s->min_x;
54 x->emin_y = s->min_y;
55 x->emax_x = s->max_x;
56 x->emax_y = s->max_y;
40 } 57 }
41 if (ev->type == EV_KEY) { 58}
42 switch (ev->code) { 59
43 case BTN_TOUCH: 60int grail_open(struct grail *ge, int fd)
44 case BTN_TOOL_FINGER: 61{
45 case BTN_TOOL_DOUBLETAP: 62 struct grail_impl *x;
46 case BTN_TOOL_TRIPLETAP: 63 int ret;
47 case BTN_TOOL_QUADTAP: 64 x = calloc(1, sizeof(*x));
48 return; 65 if (!x)
49 } 66 return -ENOMEM;
67
68 x->evemu = evemu_new(0);
69 if (!x->evemu) {
70 ret = -ENOMEM;
71 goto freemem;
50 } 72 }
51 evbuf_put(&x->evbuf, ev); 73 ret = evemu_extract(x->evemu, fd);
74 if (ret)
75 goto freemem;
76 if (!utouch_frame_is_supported_mtdev(x->evemu)) {
77 ret = -ENODEV;
78 goto freemem;
79 }
80 x->mtdev = mtdev_new_open(fd);
81 if (!x->mtdev) {
82 ret = -ENOMEM;
83 goto freemem;
84 }
85
86 x->fh = utouch_frame_new_engine(DIM_FRAMES, DIM_TOUCH, FRAME_RATE);
87 if (!x->fh) {
88 ret = -ENOMEM;
89 goto freedev;
90 }
91 ret = utouch_frame_init_mtdev(x->fh, x->evemu);
92 if (ret)
93 goto freeframe;
94
95 init_impl(x);
96 ge->impl = x;
97
98 ret = gin_init(ge);
99 if (ret)
100 goto freeframe;
101
102 ret = gru_init(ge);
103 if (ret)
104 goto freegin;
105
106 return 0;
107 freegin:
108 gin_destroy(ge);
109 freeframe:
110 utouch_frame_delete_engine(x->fh);
111 freedev:
112 mtdev_close_delete(x->mtdev);
113 freemem:
114 evemu_delete(x->evemu);
115 free(x);
116 ge->impl = 0;
117 return ret;
118}
119
120void grail_close(struct grail *ge, int fd)
121{
122 struct grail_impl *x = ge->impl;
123 void *status;
124 gru_destroy(ge);
125 gin_destroy(ge);
126 utouch_frame_delete_engine(x->fh);
127 mtdev_close_delete(x->mtdev);
128 evemu_delete(x->evemu);
129 free(x);
130 ge->impl = 0;
52} 131}
53 132
133int grail_idle(struct grail *ge, int fd, int ms)
134{
135 struct grail_impl *x = ge->impl;
136 return mtdev_idle(x->mtdev, fd, ms);
137}
138
139void grail_get_units(const struct grail *ge,
140 struct grail_coord *min, struct grail_coord *max)
141{
142 struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
143 min->x = s->min_x;
144 min->y = s->min_y;
145 max->x = s->max_x;
146 max->y = s->max_y;
147}
148
149// legacy glue below
150
54static void evput(struct grail_impl *x, struct timeval time, 151static void evput(struct grail_impl *x, struct timeval time,
55 unsigned type, unsigned code, int value) 152 unsigned type, unsigned code, int value)
56{ 153{
@@ -76,47 +173,19 @@ static void report_up(struct grail_impl *impl, const struct input_event *syn)
76 impl->report_status = 0; 173 impl->report_status = 0;
77} 174}
78 175
79#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
80
81static int getabs(struct input_absinfo *abs, int key, int fd)
82{
83 int rc;
84 SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs));
85 return rc >= 0;
86}
87
88static void set_emulation_caps(struct grail_impl *impl, int fd)
89{
90 struct touch_caps *emu = &impl->emu;
91 struct input_absinfo info;
92
93 memset(emu, 0, sizeof(*emu));
94
95 if (getabs(&info, ABS_X, fd)) {
96 emu->min_x = info.minimum;
97 emu->max_x = info.maximum;
98 }
99 if (getabs(&info, ABS_Y, fd)) {
100 emu->min_y = info.minimum;
101 emu->max_y = info.maximum;
102 }
103}
104
105static void set_pointer(struct grail_impl *impl) 176static void set_pointer(struct grail_impl *impl)
106{ 177{
107 struct touch_dev *dev = &impl->dev; 178 struct utouch_surface *s = utouch_frame_get_surface(impl->fh);
108 struct touch_caps *caps = &dev->caps; 179 const struct utouch_frame *frame = impl->frame;
109 struct touch_caps *emu = &impl->emu;
110 struct touch_frame *frame = &dev->frame;
111 int best_x, best_y, best_d = -1; 180 int best_x, best_y, best_d = -1;
112 int i; 181 int i;
113 182
114 for (i = 0; i < frame->nactive; i++) { 183 for (i = 0; i < frame->num_active; i++) {
115 struct touch *t = frame->active[i]; 184 const struct utouch_contact *t = frame->active[i];
116 float u = (t->x - caps->min_x) / (caps->max_x - caps->min_x); 185 float u = (t->x - s->min_x) / (s->max_x - s->min_x);
117 float v = (t->y - caps->min_y) / (caps->max_y - caps->min_y); 186 float v = (t->y - s->min_y) / (s->max_y - s->min_y);
118 int x = emu->min_x + u * (emu->max_x - emu->min_x); 187 int x = impl->emin_x + u * (impl->emax_x - impl->emin_x);
119 int y = emu->min_y + v * (emu->max_y - emu->min_y); 188 int y = impl->emin_y + v * (impl->emax_y - impl->emin_y);
120 int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y); 189 int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y);
121 if (best_d < 0 || d < best_d) { 190 if (best_d < 0 || d < best_d) {
122 best_x = x; 191 best_x = x;
@@ -181,15 +250,18 @@ static void handle_abs_events(struct grail *ge, const struct input_event *syn)
181 } 250 }
182} 251}
183 252
184static void tp_sync(struct touch_dev *dev, 253static void report_frame(struct grail *ge,
185 const struct input_event *syn) 254 const struct utouch_frame *frame,
255 const struct input_event *syn)
186{ 256{
187 struct grail *ge = dev->priv; 257
188 struct grail_impl *impl = ge->impl; 258 struct grail_impl *impl = ge->impl;
189 int head = impl->evbuf.head; 259 int head = impl->evbuf.head;
190 struct input_event iev; 260 struct input_event iev;
191 struct grail_event gev; 261 struct grail_event gev;
192 struct touch_frame *frame = &dev->frame; 262
263 ge->impl->frame = frame;
264
193 gin_frame_begin(ge, frame); 265 gin_frame_begin(ge, frame);
194 gru_recognize(ge, frame); 266 gru_recognize(ge, frame);
195 gin_frame_end(ge, frame); 267 gin_frame_end(ge, frame);
@@ -211,78 +283,42 @@ static void tp_sync(struct touch_dev *dev,
211 } 283 }
212} 284}
213 285
214void grail_filter_abs_events(struct grail *ge, int usage) 286static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev)
215{
216 struct grail_impl *x = ge->impl;
217 x->filter_abs = usage;
218}
219
220int grail_open(struct grail *ge, int fd)
221{
222 struct grail_impl *x;
223 int ret;
224 x = calloc(1, sizeof(*x));
225 if (!x)
226 return -ENOMEM;
227 ge->impl = x;
228
229 ret = touch_dev_open(&x->dev, fd);
230 if (ret)
231 goto freemem;
232 set_emulation_caps(x, fd);
233 x->dev.event = tp_event;
234 x->dev.sync = tp_sync;
235 x->dev.priv = ge;
236
237 ret = gin_init(ge);
238 if (ret)
239 goto freedev;
240
241 ret = gru_init(ge);
242 if (ret)
243 goto freegin;
244
245 return 0;
246 freegin:
247 gin_destroy(ge);
248 freedev:
249 touch_dev_close(&x->dev, fd);
250 freemem:
251 free(x);
252 ge->impl = 0;
253 return ret;
254}
255
256void grail_close(struct grail *ge, int fd)
257{ 287{
258 struct grail_impl *x = ge->impl; 288 struct grail_impl *impl = ge->impl;
259 void *status; 289 const struct utouch_frame *frame;
260 gru_destroy(ge);
261 gin_destroy(ge);
262 touch_dev_close(&x->dev, fd);
263 free(ge->impl);
264 ge->impl = 0;
265}
266 290
267int grail_idle(struct grail *ge, int fd, int ms) 291 if (ev->type == EV_SYN || ev->type == EV_ABS) {
268{ 292 frame = utouch_frame_pump_mtdev(impl->fh, ev);
269 struct grail_impl *x = ge->impl; 293 if (frame)
270 return touch_dev_idle(&x->dev, fd, ms); 294 report_frame(ge, frame, ev);
295 } else if (ev->type == EV_KEY) {
296 switch (ev->code) {
297 case BTN_TOUCH:
298 case BTN_TOOL_FINGER:
299 case BTN_TOOL_DOUBLETAP:
300 case BTN_TOOL_TRIPLETAP:
301 case BTN_TOOL_QUADTAP:
302 break;
303 default:
304 evbuf_put(&impl->evbuf, ev);
305 break;
306 }
307 } else {
308 evbuf_put(&impl->evbuf, ev);
309 }
271} 310}
272 311
273int grail_pull(struct grail *ge, int fd) 312int grail_pull(struct grail *ge, int fd)
274{ 313{
275 struct grail_impl *x = ge->impl; 314 struct grail_impl *impl = ge->impl;
276 return touch_dev_pull(&x->dev, fd); 315 struct input_event ev;
277} 316 int ret, count = 0;
278 317
279void grail_get_units(const struct grail *ge, 318 while ((ret = mtdev_get(impl->mtdev, fd, &ev, 1)) > 0) {
280 struct grail_coord *min, struct grail_coord *max) 319 grail_pump_mtdev(ge, &ev);
281{ 320 count++;
282 const struct touch_caps *caps = &ge->impl->dev.caps; 321 }
283 min->x = caps->min_x;
284 min->y = caps->min_y;
285 max->x = caps->max_x;
286 max->y = caps->max_y;
287}
288 322
323 return count > 0 ? count : ret;
324}