~chasedouglas/grail/original-touch-state

« back to all changes in this revision

Viewing changes to src/grail-api.c

  • Committer: Henrik Rydberg
  • Date: 2011-01-02 12:08:08 UTC
  • Revision ID: rydberg@bitmath.org-20110102120808-0nzbo3fcpp91sir5
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.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <malloc.h>
31
31
#include <errno.h>
32
32
 
33
 
static void tp_event(struct touch_dev *dev,
34
 
                     const struct input_event *ev)
35
 
{
36
 
        struct grail *ge = dev->priv;
37
 
        struct grail_impl *x = ge->impl;
38
 
        if (ev->type == EV_ABS) {
39
 
                return;
40
 
        }
41
 
        if (ev->type == EV_KEY) {
42
 
                switch (ev->code) {
43
 
                case BTN_TOUCH:
44
 
                case BTN_TOOL_FINGER:
45
 
                case BTN_TOOL_DOUBLETAP:
46
 
                case BTN_TOOL_TRIPLETAP:
47
 
                case BTN_TOOL_QUADTAP:
48
 
                        return;
49
 
                }
50
 
        }
51
 
        evbuf_put(&x->evbuf, ev);
52
 
}
 
33
#define DIM_FRAMES 100
 
34
#define FRAME_RATE 100
 
35
 
 
36
void grail_filter_abs_events(struct grail *ge, int usage)
 
37
{
 
38
        struct grail_impl *x = ge->impl;
 
39
        x->filter_abs = usage;
 
40
}
 
41
 
 
42
static 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;
 
57
        }
 
58
}
 
59
 
 
60
int grail_open(struct grail *ge, int fd)
 
61
{
 
62
        struct grail_impl *x;
 
63
        int ret;
 
64
        x = calloc(1, sizeof(*x));
 
65
        if (!x)
 
66
                return -ENOMEM;
 
67
 
 
68
        x->evemu = evemu_new(0);
 
69
        if (!x->evemu) {
 
70
                ret = -ENOMEM;
 
71
                goto freemem;
 
72
        }
 
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
 
 
120
void 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;
 
131
}
 
132
 
 
133
int 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
 
 
139
void 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
53
150
 
54
151
static void evput(struct grail_impl *x, struct timeval time,
55
152
                  unsigned type, unsigned code, int value)
76
173
        impl->report_status = 0;
77
174
}
78
175
 
79
 
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
80
 
 
81
 
static 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
 
 
88
 
static 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
 
 
105
176
static void set_pointer(struct grail_impl *impl)
106
177
{
107
 
        struct touch_dev *dev = &impl->dev;
108
 
        struct touch_caps *caps = &dev->caps;
109
 
        struct touch_caps *emu = &impl->emu;
110
 
        struct touch_frame *frame = &dev->frame;
 
178
        struct utouch_surface *s = utouch_frame_get_surface(impl->fh);
 
179
        const struct utouch_frame *frame = impl->frame;
111
180
        int best_x, best_y, best_d = -1;
112
181
        int i;
113
182
 
114
 
        for (i = 0; i < frame->nactive; i++) {
115
 
                struct touch *t = frame->active[i];
116
 
                float u = (t->x - caps->min_x) / (caps->max_x - caps->min_x);
117
 
                float v = (t->y - caps->min_y) / (caps->max_y - caps->min_y);
118
 
                int x = emu->min_x + u * (emu->max_x - emu->min_x);
119
 
                int y = emu->min_y + v * (emu->max_y - emu->min_y);
 
183
        for (i = 0; i < frame->num_active; i++) {
 
184
                const struct utouch_contact *t = frame->active[i];
 
185
                float u = (t->x - s->min_x) / (s->max_x - s->min_x);
 
186
                float v = (t->y - s->min_y) / (s->max_y - s->min_y);
 
187
                int x = impl->emin_x + u * (impl->emax_x - impl->emin_x);
 
188
                int y = impl->emin_y + v * (impl->emax_y - impl->emin_y);
120
189
                int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y);
121
190
                if (best_d < 0 || d < best_d) {
122
191
                        best_x = x;
181
250
        }
182
251
}
183
252
 
184
 
static void tp_sync(struct touch_dev *dev,
185
 
                    const struct input_event *syn)
 
253
static void report_frame(struct grail *ge,
 
254
                         const struct utouch_frame *frame,
 
255
                         const struct input_event *syn)
186
256
{
187
 
        struct grail *ge = dev->priv;
 
257
 
188
258
        struct grail_impl *impl = ge->impl;
189
259
        int head = impl->evbuf.head;
190
260
        struct input_event iev;
191
261
        struct grail_event gev;
192
 
        struct touch_frame *frame = &dev->frame;
 
262
 
 
263
        ge->impl->frame = frame;
 
264
 
193
265
        gin_frame_begin(ge, frame);
194
266
        gru_recognize(ge, frame);
195
267
        gin_frame_end(ge, frame);
211
283
        }
212
284
}
213
285
 
214
 
void grail_filter_abs_events(struct grail *ge, int usage)
215
 
{
216
 
        struct grail_impl *x = ge->impl;
217
 
        x->filter_abs = usage;
218
 
}
219
 
 
220
 
int 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
 
 
256
 
void grail_close(struct grail *ge, int fd)
257
 
{
258
 
        struct grail_impl *x = ge->impl;
259
 
        void *status;
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
 
 
267
 
int grail_idle(struct grail *ge, int fd, int ms)
268
 
{
269
 
        struct grail_impl *x = ge->impl;
270
 
        return touch_dev_idle(&x->dev, fd, ms);
 
286
static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev)
 
287
{
 
288
        struct grail_impl *impl = ge->impl;
 
289
        const struct utouch_frame *frame;
 
290
 
 
291
        if (ev->type == EV_SYN || ev->type == EV_ABS) {
 
292
                frame = utouch_frame_pump_mtdev(impl->fh, ev);
 
293
                if (frame)
 
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
 
273
312
int grail_pull(struct grail *ge, int fd)
274
313
{
275
 
        struct grail_impl *x = ge->impl;
276
 
        return touch_dev_pull(&x->dev, fd);
277
 
}
278
 
 
279
 
void grail_get_units(const struct grail *ge,
280
 
                     struct grail_coord *min, struct grail_coord *max)
281
 
{
282
 
        const struct touch_caps *caps = &ge->impl->dev.caps;
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
 
 
 
314
        struct grail_impl *impl = ge->impl;
 
315
        struct input_event ev;
 
316
        int ret, count = 0;
 
317
 
 
318
        while ((ret = mtdev_get(impl->mtdev, fd, &ev, 1)) > 0) {
 
319
                grail_pump_mtdev(ge, &ev);
 
320
                count++;
 
321
        }
 
322
 
 
323
        return count > 0 ? count : ret;
 
324
}