summaryrefslogtreecommitdiff
path: root/src/grail-api.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/grail-api.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/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}