summaryrefslogtreecommitdiff
path: root/src/grail-api.c
blob: 19b66aa188d5d1dcf8ec5a89be8f8a039502fca7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "grail-inserter.h"
#include "grail-recognizer.h"
#include <grail.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <errno.h>
#include "evbuf.h"

struct grail_impl {
	struct touch_dev dev;
	struct touch_engine engine;
	struct evbuf evbuf;
};

static void tp_event(struct touch_engine *engine,
		     const struct input_event *ev)
{
	struct grail *ge = engine->priv;
	struct grail_impl *x = ge->impl;
	evbuf_put(&x->evbuf, ev);
}

static void tp_sync(struct touch_engine *engine,
		    const struct input_event *syn)
{
	struct input_event ev;
	struct grail *ge = engine->priv;
	struct grail_impl *x = ge->impl;
	struct touch_frame *frame = &engine->frame;
	grail_mask_t filtered[DIM_EV_TYPE_BYTES];
	int nevent = 0;
	gin_frame_begin(ge, frame->time);
	gru_recognize(ge, frame);
	gin_frame_end(ge, filtered);
	if (!ge->event) {
		evbuf_clear(&x->evbuf);
		return;
	}
	while (!evbuf_empty(&x->evbuf)) {
		evbuf_get(&x->evbuf, &ev);
		if (grail_get_mask(filtered, ev.type))
			continue;
		ge->event(ge, &ev);
		nevent++;
	}
	if (nevent)
		ge->event(ge, syn);
}

int grail_open(struct grail *ge, int fd)
{
	struct grail_impl *x;
	int ret;
	x = calloc(1, sizeof(*x));
	if (!x)
		return -ENOMEM;
	ret = gin_init(ge);
	if (ret)
		goto freemem;
	ret = gru_init(ge);
	if (ret)
		goto freedev;
	ret = touch_dev_open(&x->dev, fd);
	if (ret)
		goto freegru;
	touch_engine_init(&x->engine, tp_event, tp_sync, ge);
	touch_engine_attach(&x->engine, &x->dev);
	ge->impl = x;
	return 0;
 freegru:
	gru_destroy(ge);
 freedev:
	gin_destroy(ge);
 freemem:
	free(x);
	return ret;
}

void grail_close(struct grail *ge, int fd)
{
	struct grail_impl *x = ge->impl;
	touch_engine_detach(&x->engine, &x->dev);
	touch_dev_close(&x->dev, fd);
	gru_destroy(ge);
	gin_destroy(ge);
	free(ge->impl);
	ge->impl = 0;
}

int grail_idle(struct grail *ge, int fd, int ms)
{
	struct grail_impl *x = ge->impl;
	return touch_dev_idle(&x->dev, fd, ms);
}

int grail_pull(struct grail *ge, int fd)
{
	struct grail_impl *x = ge->impl;
	return touch_dev_pull(&x->dev, fd);
}