summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL4
-rw-r--r--configure.ac4
-rw-r--r--include/grail-touch.h85
-rw-r--r--src/Makefile.am7
-rw-r--r--src/gebuf.h4
-rw-r--r--src/gestures-drag.c6
-rw-r--r--src/gestures-pinch.c6
-rw-r--r--src/gestures-rotate.c6
-rw-r--r--src/gestures-tapping.c4
-rw-r--r--src/grail-api.c280
-rw-r--r--src/grail-event.c33
-rw-r--r--src/grail-gestures.c38
-rw-r--r--src/grail-gestures.h16
-rw-r--r--src/grail-impl.h17
-rw-r--r--src/grail-inserter.c31
-rw-r--r--src/grail-inserter.h17
-rw-r--r--src/grail-recognizer.c3
-rw-r--r--src/grail-recognizer.h3
-rw-r--r--src/touch-caps.c117
-rw-r--r--src/touch-dev.c264
-rw-r--r--tools/Makefile.am2
21 files changed, 259 insertions, 688 deletions
diff --git a/INSTALL b/INSTALL
index caaad65..629f0b8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
1grail - Gesture Recognition And Instantiation Library 1grail - Gesture Recognition And Instantiation Library
2 2
3To build, you need to have the autoconf, libtool and mtdev-dev packages 3To build, you need to have the autoconf, libtool, mtdev-dev,
4installed. Then, do 4libutouch-evemu-dev and libutouch-frame packages installed. Then, do
5 5
6 ./autogen.sh 6 ./autogen.sh
7 ./configure 7 ./configure
diff --git a/configure.ac b/configure.ac
index 0f75818..ceb9258 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,9 @@ AC_PROG_LIBTOOL
22AC_PROG_CC 22AC_PROG_CC
23AC_PROG_INSTALL 23AC_PROG_INSTALL
24 24
25PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.0]) 25PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1])
26PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0])
27PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0])
26 28
27AC_CONFIG_FILES([Makefile 29AC_CONFIG_FILES([Makefile
28 src/Makefile 30 src/Makefile
diff --git a/include/grail-touch.h b/include/grail-touch.h
deleted file mode 100644
index 9c63c80..0000000
--- a/include/grail-touch.h
+++ /dev/null
@@ -1,85 +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#ifndef _GRAIL_TOUCH_H
24#define _GRAIL_TOUCH_H
25
26#include <grail-bits.h>
27#include <mtdev.h>
28
29#define DIM_TOUCH 32
30#define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3)
31
32typedef __u64 touch_time_t;
33
34struct touch {
35 int active;
36 int slot;
37 int id;
38 int tool_type;
39 int x, y;
40 int touch_major;
41 int touch_minor;
42 int width_major;
43 int width_minor;
44 int orientation;
45 int pressure;
46};
47
48struct touch_frame {
49 int nactive;
50 int ncreate, nmodify, ndestroy;
51 touch_time_t time;
52 grail_mask_t touches[DIM_TOUCH_BYTES];
53 struct touch *active[DIM_TOUCH];
54 struct touch touch[DIM_TOUCH];
55};
56
57struct touch_caps {
58 float min_x, max_x;
59 float min_y, max_y;
60 float min_orient, max_orient;
61 float min_press, max_press;
62};
63
64struct touch_dev {
65 void (*event)(struct touch_dev *dev, const struct input_event *ev);
66 void (*sync)(struct touch_dev *dev, const struct input_event *syn);
67 void *priv;
68 struct mtdev mtdev;
69 struct touch_frame frame;
70 struct touch_caps caps;
71 int slot;
72 int state;
73};
74
75int touch_caps_is_supported(struct touch_dev *dev, int fd);
76void touch_caps_init(struct touch_dev *dev);
77float touch_angle(const struct touch_dev *dev, int orientation);
78float touch_pressure(const struct touch_dev *dev, int pressure);
79
80int touch_dev_open(struct touch_dev *dev, int fd);
81int touch_dev_idle(struct touch_dev *dev, int fd, int ms);
82int touch_dev_pull(struct touch_dev *dev, int fd);
83void touch_dev_close(struct touch_dev *dev, int fd);
84
85#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index dd2af2b..bb1c4c5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,14 +3,14 @@ lib_LTLIBRARIES = libutouch-grail.la
3libutouch_grail_la_LDFLAGS = \ 3libutouch_grail_la_LDFLAGS = \
4 -version-info @LIB_VERSION@ \ 4 -version-info @LIB_VERSION@ \
5 -lm \ 5 -lm \
6 $(MTDEV_LIBS) 6 $(MTDEV_LIBS) \
7 $(EVEMU_LIBS) \
8 $(FRAME_LIBS)
7 9
8libutouch_grail_la_SOURCES = \ 10libutouch_grail_la_SOURCES = \
9 evbuf.h \ 11 evbuf.h \
10 gebuf.h \ 12 gebuf.h \
11 grailbuf.h \ 13 grailbuf.h \
12 touch-dev.c \
13 touch-caps.c \
14 grail-bits.c \ 14 grail-bits.c \
15 grail-inserter.c \ 15 grail-inserter.c \
16 grail-inserter.h \ 16 grail-inserter.h \
@@ -34,5 +34,4 @@ libutouch_grailincludedir = $(includedir)
34libutouch_grailinclude_HEADERS = \ 34libutouch_grailinclude_HEADERS = \
35 $(top_srcdir)/include/grail-bits.h \ 35 $(top_srcdir)/include/grail-bits.h \
36 $(top_srcdir)/include/grail-types.h \ 36 $(top_srcdir)/include/grail-types.h \
37 $(top_srcdir)/include/grail-touch.h \
38 $(top_srcdir)/include/grail.h 37 $(top_srcdir)/include/grail.h
diff --git a/src/gebuf.h b/src/gebuf.h
index 460e134..0cd9219 100644
--- a/src/gebuf.h
+++ b/src/gebuf.h
@@ -23,7 +23,7 @@
23#ifndef _GRAIL_GESTURE_BUFFER_H 23#ifndef _GRAIL_GESTURE_BUFFER_H
24#define _GRAIL_GESTURE_BUFFER_H 24#define _GRAIL_GESTURE_BUFFER_H
25 25
26#include <grail.h> 26#include "grail-impl.h"
27 27
28#define DIM_GESTURE_EVENTS 512 28#define DIM_GESTURE_EVENTS 512
29 29
@@ -31,7 +31,7 @@ struct gesture_event {
31 int status; 31 int status;
32 int ntouch; 32 int ntouch;
33 int nprop; 33 int nprop;
34 touch_time_t time; 34 utouch_frame_time_t time;
35 struct grail_coord pos; 35 struct grail_coord pos;
36 grail_prop_t prop[DIM_GRAIL_PROP]; 36 grail_prop_t prop[DIM_GRAIL_PROP];
37}; 37};
diff --git a/src/gestures-drag.c b/src/gestures-drag.c
index 2ced765..05272da 100644
--- a/src/gestures-drag.c
+++ b/src/gestures-drag.c
@@ -35,7 +35,7 @@ static const int getype[DIM_TOUCH + 1] = {
35 35
36static void set_props(const struct gesture_inserter *gin, 36static void set_props(const struct gesture_inserter *gin,
37 struct combo_model *s, const struct move_model *m, 37 struct combo_model *s, const struct move_model *m,
38 const struct touch_frame *frame) 38 const struct utouch_frame *frame)
39{ 39{
40 if (m->single) { 40 if (m->single) {
41 s->prop[GRAIL_PROP_DRAG_DX] = 41 s->prop[GRAIL_PROP_DRAG_DX] =
@@ -59,7 +59,7 @@ static void set_props(const struct gesture_inserter *gin,
59static const int fm_mask = 0x03; 59static const int fm_mask = 0x03;
60 60
61int gru_drag(struct grail *ge, 61int gru_drag(struct grail *ge,
62 const struct touch_frame *frame) 62 const struct utouch_frame *frame)
63{ 63{
64 struct gesture_recognizer *gru = ge->gru; 64 struct gesture_recognizer *gru = ge->gru;
65 struct combo_model *state = &gru->drag; 65 struct combo_model *state = &gru->drag;
@@ -89,7 +89,7 @@ int gru_drag(struct grail *ge,
89} 89}
90 90
91int gru_windrag(struct grail *ge, 91int gru_windrag(struct grail *ge,
92 const struct touch_frame *frame) 92 const struct utouch_frame *frame)
93{ 93{
94 struct gesture_recognizer *gru = ge->gru; 94 struct gesture_recognizer *gru = ge->gru;
95 struct combo_model *state = &gru->windrag; 95 struct combo_model *state = &gru->windrag;
diff --git a/src/gestures-pinch.c b/src/gestures-pinch.c
index 45f1cb3..fa8a626 100644
--- a/src/gestures-pinch.c
+++ b/src/gestures-pinch.c
@@ -38,7 +38,7 @@ static const int fm_mask = 0x04;
38static void set_props(const struct gesture_inserter *gin, 38static void set_props(const struct gesture_inserter *gin,
39 struct combo_model *s, 39 struct combo_model *s,
40 const struct move_model *m, 40 const struct move_model *m,
41 const struct touch_frame *frame) 41 const struct utouch_frame *frame)
42{ 42{
43 s->prop[GRAIL_PROP_PINCH_DR] = gin->scale_r * m->fm[FM_R].action_delta; 43 s->prop[GRAIL_PROP_PINCH_DR] = gin->scale_r * m->fm[FM_R].action_delta;
44 s->prop[GRAIL_PROP_PINCH_VR] = gin->scale_r * m->fm[FM_R].velocity; 44 s->prop[GRAIL_PROP_PINCH_VR] = gin->scale_r * m->fm[FM_R].velocity;
@@ -48,7 +48,7 @@ static void set_props(const struct gesture_inserter *gin,
48} 48}
49 49
50int gru_pinch(struct grail *ge, 50int gru_pinch(struct grail *ge,
51 const struct touch_frame *frame) 51 const struct utouch_frame *frame)
52{ 52{
53 struct gesture_recognizer *gru = ge->gru; 53 struct gesture_recognizer *gru = ge->gru;
54 struct combo_model *state = &gru->pinch; 54 struct combo_model *state = &gru->pinch;
@@ -79,7 +79,7 @@ int gru_pinch(struct grail *ge,
79} 79}
80 80
81int gru_winpinch(struct grail *ge, 81int gru_winpinch(struct grail *ge,
82 const struct touch_frame *frame) 82 const struct utouch_frame *frame)
83{ 83{
84 struct gesture_recognizer *gru = ge->gru; 84 struct gesture_recognizer *gru = ge->gru;
85 struct combo_model *state = &gru->winpinch; 85 struct combo_model *state = &gru->winpinch;
diff --git a/src/gestures-rotate.c b/src/gestures-rotate.c
index 8985257..fde0db8 100644
--- a/src/gestures-rotate.c
+++ b/src/gestures-rotate.c
@@ -37,7 +37,7 @@ static const int fm_mask = 0x08;
37 37
38static void set_props(const struct gesture_inserter *gin, 38static void set_props(const struct gesture_inserter *gin,
39 struct combo_model *s, const struct move_model *m, 39 struct combo_model *s, const struct move_model *m,
40 const struct touch_frame *frame) 40 const struct utouch_frame *frame)
41{ 41{
42 s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta; 42 s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta;
43 s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity; 43 s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity;
@@ -47,7 +47,7 @@ static void set_props(const struct gesture_inserter *gin,
47} 47}
48 48
49int gru_rotate(struct grail *ge, 49int gru_rotate(struct grail *ge,
50 const struct touch_frame *frame) 50 const struct utouch_frame *frame)
51{ 51{
52 struct gesture_recognizer *gru = ge->gru; 52 struct gesture_recognizer *gru = ge->gru;
53 struct combo_model *state = &gru->rotate; 53 struct combo_model *state = &gru->rotate;
@@ -78,7 +78,7 @@ int gru_rotate(struct grail *ge,
78} 78}
79 79
80int gru_winrotate(struct grail *ge, 80int gru_winrotate(struct grail *ge,
81 const struct touch_frame *frame) 81 const struct utouch_frame *frame)
82{ 82{
83 struct gesture_recognizer *gru = ge->gru; 83 struct gesture_recognizer *gru = ge->gru;
84 struct combo_model *state = &gru->winrotate; 84 struct combo_model *state = &gru->winrotate;
diff --git a/src/gestures-tapping.c b/src/gestures-tapping.c
index aa8e6d6..6d71642 100644
--- a/src/gestures-tapping.c
+++ b/src/gestures-tapping.c
@@ -30,7 +30,7 @@ static const int fm_mask = 0x07;
30 30
31static void set_props(const struct gesture_inserter *gin, 31static void set_props(const struct gesture_inserter *gin,
32 struct tapping_model *s, const struct move_model *m, 32 struct tapping_model *s, const struct move_model *m,
33 const struct touch_frame *frame) 33 const struct utouch_frame *frame)
34{ 34{
35 s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start; 35 s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start;
36 s->prop[GRAIL_PROP_TAP_X] = gin_prop_x(gin, m->fm[FM_X].value); 36 s->prop[GRAIL_PROP_TAP_X] = gin_prop_x(gin, m->fm[FM_X].value);
@@ -40,7 +40,7 @@ static void set_props(const struct gesture_inserter *gin,
40} 40}
41 41
42int gru_tapping(struct grail *ge, 42int gru_tapping(struct grail *ge,
43 const struct touch_frame *frame) 43 const struct utouch_frame *frame)
44{ 44{
45 struct gesture_recognizer *gru = ge->gru; 45 struct gesture_recognizer *gru = ge->gru;
46 struct tapping_model *state = &gru->tapping; 46 struct tapping_model *state = &gru->tapping;
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}
diff --git a/src/grail-event.c b/src/grail-event.c
index 23fdbb3..9c0e437 100644
--- a/src/grail-event.c
+++ b/src/grail-event.c
@@ -28,17 +28,17 @@
28#include <math.h> 28#include <math.h>
29 29
30static void compute_bbox(struct grail_coord *min, struct grail_coord *max, 30static void compute_bbox(struct grail_coord *min, struct grail_coord *max,
31 const struct touch_frame *frame) 31 const struct utouch_frame *frame)
32{ 32{
33 float x, y; 33 float x, y;
34 int i; 34 int i;
35 if (frame->nactive < 1) 35 if (frame->num_active < 1)
36 return; 36 return;
37 x = frame->active[0]->x; 37 x = frame->active[0]->x;
38 y = frame->active[0]->y; 38 y = frame->active[0]->y;
39 min->x = max->x = x; 39 min->x = max->x = x;
40 min->y = max->y = y; 40 min->y = max->y = y;
41 for (i = 1; i < frame->nactive; i++) { 41 for (i = 1; i < frame->num_active; i++) {
42 x = frame->active[i]->x; 42 x = frame->active[i]->x;
43 y = frame->active[i]->y; 43 y = frame->active[i]->y;
44 if (x < min->x) 44 if (x < min->x)
@@ -53,10 +53,10 @@ static void compute_bbox(struct grail_coord *min, struct grail_coord *max,
53} 53}
54 54
55int gin_add_contact_props(const struct gesture_inserter *gin, 55int gin_add_contact_props(const struct gesture_inserter *gin,
56 grail_prop_t *prop, const struct touch_frame *frame) 56 grail_prop_t *prop, const struct utouch_frame *frame)
57{ 57{
58 struct grail_coord min, max; 58 struct grail_coord min, max;
59 int i, n = 0, ntouch = frame->nactive; 59 int i, n = 0, ntouch = frame->num_active;
60 if (!ntouch) 60 if (!ntouch)
61 return n; 61 return n;
62 if (ntouch > 5) 62 if (ntouch > 5)
@@ -67,7 +67,7 @@ int gin_add_contact_props(const struct gesture_inserter *gin,
67 prop[n++] = gin_prop_x(gin, max.x); 67 prop[n++] = gin_prop_x(gin, max.x);
68 prop[n++] = gin_prop_y(gin, max.y); 68 prop[n++] = gin_prop_y(gin, max.y);
69 for (i = 0; i < ntouch; i++) { 69 for (i = 0; i < ntouch; i++) {
70 const struct touch *ct = frame->active[i]; 70 const struct utouch_contact *ct = frame->active[i];
71 prop[n++] = ct->id; 71 prop[n++] = ct->id;
72 prop[n++] = gin_prop_x(gin, ct->x); 72 prop[n++] = gin_prop_x(gin, ct->x);
73 prop[n++] = gin_prop_y(gin, ct->y); 73 prop[n++] = gin_prop_y(gin, ct->y);
@@ -79,15 +79,15 @@ int gin_get_clients(struct grail *ge,
79 struct grail_client_info *info, int maxinfo, 79 struct grail_client_info *info, int maxinfo,
80 const grail_mask_t* types, int btypes, 80 const grail_mask_t* types, int btypes,
81 const grail_mask_t* span, int bspan, 81 const grail_mask_t* span, int bspan,
82 const struct touch_frame *frame) 82 const struct utouch_frame *frame)
83{ 83{
84 struct grail_coord pos[DIM_TOUCH]; 84 struct grail_coord pos[DIM_TOUCH];
85 int i, npos = 0; 85 int i, npos = 0;
86 if (!ge->get_clients) 86 if (!ge->get_clients)
87 return 0; 87 return 0;
88 grail_mask_foreach(i, span, bspan) { 88 grail_mask_foreach(i, span, bspan) {
89 pos[npos].x = gin_prop_x(ge->gin, frame->touch[i].x); 89 pos[npos].x = gin_prop_x(ge->gin, frame->slots[i]->x);
90 pos[npos].y = gin_prop_y(ge->gin, frame->touch[i].y); 90 pos[npos].y = gin_prop_y(ge->gin, frame->slots[i]->y);
91 npos++; 91 npos++;
92 } 92 }
93 return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes); 93 return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes);
@@ -95,7 +95,7 @@ int gin_get_clients(struct grail *ge,
95 95
96void gin_send_event(struct grail *ge, struct slot_state *s, 96void gin_send_event(struct grail *ge, struct slot_state *s,
97 const struct gesture_event *ev, 97 const struct gesture_event *ev,
98 const struct touch_frame *frame) 98 const struct utouch_frame *frame)
99{ 99{
100 struct grail_impl *impl = ge->impl; 100 struct grail_impl *impl = ge->impl;
101 const struct gesture_inserter *gin = ge->gin; 101 const struct gesture_inserter *gin = ge->gin;
@@ -121,15 +121,14 @@ void gin_send_event(struct grail *ge, struct slot_state *s,
121int grail_get_contacts(const struct grail *ge, 121int grail_get_contacts(const struct grail *ge,
122 struct grail_contact *touch, int max_touch) 122 struct grail_contact *touch, int max_touch)
123{ 123{
124 const struct touch_dev *dev = &ge->impl->dev;
125 const struct gesture_inserter *gin = ge->gin; 124 const struct gesture_inserter *gin = ge->gin;
126 const struct touch_frame *frame = &dev->frame; 125 const struct utouch_frame *frame = ge->impl->frame;
127 int i; 126 int i;
128 if (frame->nactive < max_touch) 127 if (frame->num_active < max_touch)
129 max_touch = frame->nactive; 128 max_touch = frame->num_active;
130 for (i = 0; i < max_touch; i++) { 129 for (i = 0; i < max_touch; i++) {
131 struct grail_contact *t = &touch[i]; 130 struct grail_contact *t = &touch[i];
132 const struct touch *ct = frame->active[i]; 131 const struct utouch_contact *ct = frame->active[i];
133 t->id = ct->id; 132 t->id = ct->id;
134 t->tool_type = ct->tool_type; 133 t->tool_type = ct->tool_type;
135 t->pos.x = gin_prop_x(gin, ct->x); 134 t->pos.x = gin_prop_x(gin, ct->x);
@@ -138,8 +137,8 @@ int grail_get_contacts(const struct grail *ge,
138 t->touch_minor = gin->scale_r * ct->touch_minor; 137 t->touch_minor = gin->scale_r * ct->touch_minor;
139 t->width_major = gin->scale_r * ct->width_major; 138 t->width_major = gin->scale_r * ct->width_major;
140 t->width_minor = gin->scale_r * ct->width_minor; 139 t->width_minor = gin->scale_r * ct->width_minor;
141 t->angle = touch_angle(dev, ct->orientation); 140 t->angle = ct->orientation;
142 t->pressure = touch_pressure(dev, ct->pressure); 141 t->pressure = ct->pressure;
143 } 142 }
144 return max_touch; 143 return max_touch;
145} 144}
diff --git a/src/grail-gestures.c b/src/grail-gestures.c
index ed937a4..035a199 100644
--- a/src/grail-gestures.c
+++ b/src/grail-gestures.c
@@ -31,15 +31,15 @@ static const grail_time_t SAMPLE_MS = 10;
31static const float EPS = 1e-3; 31static const float EPS = 1e-3;
32 32
33static void compute_position(float *x, float *y, 33static void compute_position(float *x, float *y,
34 const struct touch_frame *frame) 34 const struct utouch_frame *frame)
35{ 35{
36 int i, n = frame->nactive; 36 int i, n = frame->num_active;
37 *x = 0; 37 *x = 0;
38 *y = 0; 38 *y = 0;
39 if (n < 1) 39 if (n < 1)
40 return; 40 return;
41 for (i = 0; i < n; i++) { 41 for (i = 0; i < n; i++) {
42 const struct touch *t = frame->active[i]; 42 const struct utouch_contact *t = frame->active[i];
43 *x += t->x; 43 *x += t->x;
44 *y += t->y; 44 *y += t->y;
45 } 45 }
@@ -48,14 +48,14 @@ static void compute_position(float *x, float *y,
48} 48}
49 49
50static float compute_radius(float x, float y, 50static float compute_radius(float x, float y,
51 const struct touch_frame *frame) 51 const struct utouch_frame *frame)
52{ 52{
53 int i, n = frame->nactive; 53 int i, n = frame->num_active;
54 float r = 0, r2 = 0; 54 float r = 0, r2 = 0;
55 if (n < 2) 55 if (n < 2)
56 return r; 56 return r;
57 for (i = 0; i < n; i++) { 57 for (i = 0; i < n; i++) {
58 const struct touch *t = frame->active[i]; 58 const struct utouch_contact *t = frame->active[i];
59 float dx = t->x - x; 59 float dx = t->x - x;
60 float dy = t->y - y; 60 float dy = t->y - y;
61 r2 += dx * dx + dy * dy; 61 r2 += dx * dx + dy * dy;
@@ -66,16 +66,15 @@ static float compute_radius(float x, float y,
66} 66}
67 67
68static float compute_rotation(float x, float y, float r, 68static float compute_rotation(float x, float y, float r,
69 const struct touch_frame *prev, 69 const struct utouch_frame *frame)
70 const struct touch_frame *frame)
71{ 70{
72 int i, n = frame->nactive; 71 int i, n = frame->num_active;
73 float da = 0, darc2 = 0; 72 float da = 0, darc2 = 0;
74 if (n < 2) 73 if (n < 2)
75 return da; 74 return da;
76 for (i = 0; i < n; i++) { 75 for (i = 0; i < n; i++) {
77 const struct touch *t = frame->active[i]; 76 const struct utouch_contact *t = frame->active[i];
78 const struct touch *ot = &prev->touch[t->slot]; 77 const struct utouch_contact *ot = t->prev;
79 float dx = t->x - x; 78 float dx = t->x - x;
80 float dy = t->y - y; 79 float dy = t->y - y;
81 float mx = t->x - ot->x; 80 float mx = t->x - ot->x;
@@ -142,13 +141,13 @@ static void move_update(struct move_model *m, int i, float x, grail_time_t t)
142 141
143void gru_init_motion(struct grail *ge) 142void gru_init_motion(struct grail *ge)
144{ 143{
145 struct touch_caps *caps = &ge->impl->dev.caps; 144 struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
146 struct gesture_recognizer *gru = ge->gru; 145 struct gesture_recognizer *gru = ge->gru;
147 struct move_model *m = &gru->move; 146 struct move_model *m = &gru->move;
148 float D[DIM_FM]; 147 float D[DIM_FM];
149 int i; 148 int i;
150 D[FM_X] = caps->max_x - caps->min_x; 149 D[FM_X] = s->max_x - s->min_x;
151 D[FM_Y] = caps->max_y - caps->min_y; 150 D[FM_Y] = s->max_y - s->min_y;
152 D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]); 151 D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]);
153 D[FM_A] = 2 * M_PI; 152 D[FM_A] = 2 * M_PI;
154 for (i = 0; i < DIM_FM; i++) { 153 for (i = 0; i < DIM_FM; i++) {
@@ -159,14 +158,15 @@ void gru_init_motion(struct grail *ge)
159} 158}
160 159
161void gru_motion(struct grail *ge, 160void gru_motion(struct grail *ge,
162 const struct touch_frame *frame) 161 const struct utouch_frame *frame)
163{ 162{
164 struct gesture_recognizer *gru = ge->gru; 163 struct gesture_recognizer *gru = ge->gru;
165 struct move_model *m = &gru->move; 164 struct move_model *m = &gru->move;
166 grail_time_t t = frame->time; 165 grail_time_t t = frame->time;
167 float x, y, r, a; 166 float x, y, r, a;
167
168 compute_position(&x, &y, frame); 168 compute_position(&x, &y, frame);
169 if (frame->ncreate || frame->ndestroy) { 169 if (frame->prev->revision != frame->revision) {
170 r = compute_radius(x, y, frame); 170 r = compute_radius(x, y, frame);
171 a = 0; 171 a = 0;
172 move_reset(m, FM_X, x, t); 172 move_reset(m, FM_X, x, t);
@@ -175,7 +175,7 @@ void gru_motion(struct grail *ge,
175 move_reset(m, FM_A, a, t); 175 move_reset(m, FM_A, a, t);
176 m->single = 0; 176 m->single = 0;
177 m->multi = 0; 177 m->multi = 0;
178 } else if (frame->nactive < 2) { 178 } else if (frame->num_active < 2) {
179 r = 0; 179 r = 0;
180 a = 0; 180 a = 0;
181 move_update(m, FM_X, x, t); 181 move_update(m, FM_X, x, t);
@@ -190,7 +190,7 @@ void gru_motion(struct grail *ge,
190 r = compute_radius(x, y, frame); 190 r = compute_radius(x, y, frame);
191 r = move_filter(&m->fm[FM_R], r); 191 r = move_filter(&m->fm[FM_R], r);
192 a = m->fm[FM_A].value; 192 a = m->fm[FM_A].value;
193 a += compute_rotation(x, y, r, &gru->frame, frame); 193 a += compute_rotation(x, y, r, frame);
194 a = move_filter(&m->fm[FM_A], a); 194 a = move_filter(&m->fm[FM_A], a);
195 move_update(m, FM_X, x, t); 195 move_update(m, FM_X, x, t);
196 move_update(m, FM_Y, y, t); 196 move_update(m, FM_Y, y, t);
@@ -199,7 +199,7 @@ void gru_motion(struct grail *ge,
199 m->single = 0; 199 m->single = 0;
200 m->multi = 1; 200 m->multi = 1;
201 } 201 }
202 m->ntouch = frame->nactive; 202 m->ntouch = frame->num_active;
203 m->time = t; 203 m->time = t;
204} 204}
205 205
diff --git a/src/grail-gestures.h b/src/grail-gestures.h
index 27108e9..69dd7e4 100644
--- a/src/grail-gestures.h
+++ b/src/grail-gestures.h
@@ -61,7 +61,7 @@ struct move_model {
61 61
62void gru_init_motion(struct grail *ge); 62void gru_init_motion(struct grail *ge);
63void gru_motion(struct grail *ge, 63void gru_motion(struct grail *ge,
64 const struct touch_frame *frame); 64 const struct utouch_frame *frame);
65void gru_event(struct grail *ge, int gid, 65void gru_event(struct grail *ge, int gid,
66 const struct move_model *move, 66 const struct move_model *move,
67 const grail_prop_t *prop, int nprop); 67 const grail_prop_t *prop, int nprop);
@@ -77,11 +77,11 @@ struct combo_model {
77}; 77};
78 78
79int gru_drag(struct grail *ge, 79int gru_drag(struct grail *ge,
80 const struct touch_frame *frame); 80 const struct utouch_frame *frame);
81int gru_pinch(struct grail *ge, 81int gru_pinch(struct grail *ge,
82 const struct touch_frame *frame); 82 const struct utouch_frame *frame);
83int gru_rotate(struct grail *ge, 83int gru_rotate(struct grail *ge,
84 const struct touch_frame *frame); 84 const struct utouch_frame *frame);
85 85
86static inline int out_of_bounds(const struct combo_model *s, 86static inline int out_of_bounds(const struct combo_model *s,
87 const struct move_model *m) 87 const struct move_model *m)
@@ -90,11 +90,11 @@ static inline int out_of_bounds(const struct combo_model *s,
90} 90}
91 91
92int gru_windrag(struct grail *ge, 92int gru_windrag(struct grail *ge,
93 const struct touch_frame *frame); 93 const struct utouch_frame *frame);
94int gru_winpinch(struct grail *ge, 94int gru_winpinch(struct grail *ge,
95 const struct touch_frame *frame); 95 const struct utouch_frame *frame);
96int gru_winrotate(struct grail *ge, 96int gru_winrotate(struct grail *ge,
97 const struct touch_frame *frame); 97 const struct utouch_frame *frame);
98 98
99struct tapping_model { 99struct tapping_model {
100 grail_time_t start, end; 100 grail_time_t start, end;
@@ -105,7 +105,7 @@ struct tapping_model {
105}; 105};
106 106
107int gru_tapping(struct grail *ge, 107int gru_tapping(struct grail *ge,
108 const struct touch_frame *frame); 108 const struct utouch_frame *frame);
109 109
110#endif 110#endif
111 111
diff --git a/src/grail-impl.h b/src/grail-impl.h
index 2859186..dcbaedd 100644
--- a/src/grail-impl.h
+++ b/src/grail-impl.h
@@ -23,15 +23,26 @@
23#ifndef _GRAIL_IMPL_H 23#ifndef _GRAIL_IMPL_H
24#define _GRAIL_IMPL_H 24#define _GRAIL_IMPL_H
25 25
26#include <grail-touch.h> 26#define MTDEV_NO_LEGACY_API
27#define GRAIL_NO_LEGACY_API
28
29#include <grail.h>
30#include <utouch/frame-mtdev.h>
27#include "evbuf.h" 31#include "evbuf.h"
28#include "grailbuf.h" 32#include "grailbuf.h"
29 33
34#define DIM_TOUCH 32
35#define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3)
36
30struct grail_impl { 37struct grail_impl {
31 struct touch_dev dev; 38 struct evemu_device *evemu;
32 struct touch_caps emu; 39 struct mtdev *mtdev;
40 utouch_frame_handle fh;
41 const struct utouch_frame *frame;
33 struct evbuf evbuf; 42 struct evbuf evbuf;
34 struct grailbuf gbuf; 43 struct grailbuf gbuf;
44 float emin_x, emin_y;
45 float emax_x, emax_y;
35 int filter_abs; 46 int filter_abs;
36 int pointer_status; 47 int pointer_status;
37 int pointer_x, pointer_y; 48 int pointer_x, pointer_y;
diff --git a/src/grail-inserter.c b/src/grail-inserter.c
index 847995a..6f9a034 100644
--- a/src/grail-inserter.c
+++ b/src/grail-inserter.c
@@ -40,7 +40,7 @@ static int find_gslot(const struct gesture_inserter *gin, int gid)
40 40
41// todo: spanning tree for multi-user case 41// todo: spanning tree for multi-user case
42static void setup_new_gestures(struct grail *ge, 42static void setup_new_gestures(struct grail *ge,
43 const struct touch_frame *frame) 43 const struct utouch_frame *frame)
44{ 44{
45 struct gesture_inserter *gin = ge->gin; 45 struct gesture_inserter *gin = ge->gin;
46 grail_mask_t types[DIM_GRAIL_TYPE_BYTES]; 46 grail_mask_t types[DIM_GRAIL_TYPE_BYTES];
@@ -100,14 +100,14 @@ void gin_destroy(struct grail *ge)
100 ge->gin = NULL; 100 ge->gin = NULL;
101} 101}
102 102
103void gin_frame_begin(struct grail *ge, const struct touch_frame *frame) 103void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame)
104{ 104{
105 struct gesture_inserter *gin = ge->gin; 105 struct gesture_inserter *gin = ge->gin;
106 memset(gin->types, 0, sizeof(gin->types)); 106 memset(gin->types, 0, sizeof(gin->types));
107 gin->time = frame->time; 107 gin->time = frame->time;
108} 108}
109 109
110void gin_frame_end(struct grail *ge, const struct touch_frame *frame) 110void gin_frame_end(struct grail *ge, const struct utouch_frame *frame)
111{ 111{
112 struct gesture_inserter *gin = ge->gin; 112 struct gesture_inserter *gin = ge->gin;
113 int i, hold = 0, discard = 0; 113 int i, hold = 0, discard = 0;
@@ -151,11 +151,12 @@ void gin_frame_end(struct grail *ge, const struct touch_frame *frame)
151 } 151 }
152} 152}
153 153
154int gin_gid_begin_select(struct grail *ge, int type, int priority, 154int gin_gid_begin(struct grail *ge, int type, int priority,
155 const grail_mask_t *span, int nspan) 155 const struct utouch_frame *frame)
156{ 156{
157 struct gesture_inserter *gin = ge->gin; 157 struct gesture_inserter *gin = ge->gin;
158 struct slot_state *s; 158 struct slot_state *s;
159 int slot;
159 int i = grail_mask_get_first(gin->unused, sizeof(gin->unused)); 160 int i = grail_mask_get_first(gin->unused, sizeof(gin->unused));
160 if (i < 0) 161 if (i < 0)
161 return -1; 162 return -1;
@@ -165,7 +166,8 @@ int gin_gid_begin_select(struct grail *ge, int type, int priority,
165 s->id = gin->gestureid++ & MAX_GESTURE_ID; 166 s->id = gin->gestureid++ & MAX_GESTURE_ID;
166 s->status = GRAIL_STATUS_BEGIN; 167 s->status = GRAIL_STATUS_BEGIN;
167 s->nclient = 0; 168 s->nclient = 0;
168 memcpy(s->span, span, nspan); 169 for (slot = 0; slot < DIM_TOUCH; slot++)
170 grail_mask_modify(s->span, slot, frame->slots[slot]->active);
169 gebuf_clear(&s->buf); 171 gebuf_clear(&s->buf);
170 grail_mask_clear(gin->unused, i); 172 grail_mask_clear(gin->unused, i);
171 grail_mask_set(gin->fresh, i); 173 grail_mask_set(gin->fresh, i);
@@ -173,13 +175,6 @@ int gin_gid_begin_select(struct grail *ge, int type, int priority,
173 return s->id; 175 return s->id;
174} 176}
175 177
176int gin_gid_begin(struct grail *ge, int type, int priority,
177 const struct touch_frame *frame)
178{
179 return gin_gid_begin_select(ge, type, priority,
180 frame->touches, sizeof(frame->touches));
181}
182
183void gin_gid_discard(struct grail *ge, int gid) 178void gin_gid_discard(struct grail *ge, int gid)
184{ 179{
185 struct gesture_inserter *gin = ge->gin; 180 struct gesture_inserter *gin = ge->gin;
@@ -248,18 +243,18 @@ void grail_set_bbox(struct grail *ge,
248 const struct grail_coord *tmin, 243 const struct grail_coord *tmin,
249 const struct grail_coord *tmax) 244 const struct grail_coord *tmax)
250{ 245{
251 struct touch_caps *caps = &ge->impl->dev.caps; 246 struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
252 struct gesture_inserter *gin = ge->gin; 247 struct gesture_inserter *gin = ge->gin;
253 double tx, ty, dx, dy, sx, sy; 248 double tx, ty, dx, dy, sx, sy;
254 tx = tmax->x - tmin->x; 249 tx = tmax->x - tmin->x;
255 ty = tmax->y - tmin->y; 250 ty = tmax->y - tmin->y;
256 dx = caps->max_x - caps->min_x; 251 dx = s->max_x - s->min_x;
257 dy = caps->max_y - caps->min_y; 252 dy = s->max_y - s->min_y;
258 sx = tx / dx; 253 sx = tx / dx;
259 sy = ty / dy; 254 sy = ty / dy;
260 gin->scale_x = sx; 255 gin->scale_x = sx;
261 gin->scale_y = sy; 256 gin->scale_y = sy;
262 gin->scale_r = sqrt((tx * tx + ty * ty) / (dx * dx + dy * dy)); 257 gin->scale_r = sqrt((tx * tx + ty * ty) / (dx * dx + dy * dy));
263 gin->trans_x = tmin->x - caps->min_x * sx; 258 gin->trans_x = tmin->x - s->min_x * sx;
264 gin->trans_y = tmin->y - caps->min_y * sy; 259 gin->trans_y = tmin->y - s->min_y * sy;
265} 260}
diff --git a/src/grail-inserter.h b/src/grail-inserter.h
index 9baecb7..3b8cd77 100644
--- a/src/grail-inserter.h
+++ b/src/grail-inserter.h
@@ -23,8 +23,7 @@
23#ifndef _GRAIL_INSERTER_H 23#ifndef _GRAIL_INSERTER_H
24#define _GRAIL_INSERTER_H 24#define _GRAIL_INSERTER_H
25 25
26#include <grail-touch.h> 26#include "grail-impl.h"
27#include <grail.h>
28#include "gebuf.h" 27#include "gebuf.h"
29 28
30#define DIM_EV_TYPE EV_CNT 29#define DIM_EV_TYPE EV_CNT
@@ -69,27 +68,25 @@ static inline float gin_prop_y(const struct gesture_inserter *gin, float y)
69} 68}
70 69
71int gin_add_contact_props(const struct gesture_inserter *gin, 70int gin_add_contact_props(const struct gesture_inserter *gin,
72 grail_prop_t *prop, const struct touch_frame *frame); 71 grail_prop_t *prop, const struct utouch_frame *frame);
73 72
74int gin_get_clients(struct grail *ge, 73int gin_get_clients(struct grail *ge,
75 struct grail_client_info *info, int maxinfo, 74 struct grail_client_info *info, int maxinfo,
76 const grail_mask_t* types, int btypes, 75 const grail_mask_t* types, int btypes,
77 const grail_mask_t* span, int bspan, 76 const grail_mask_t* span, int bspan,
78 const struct touch_frame *frame); 77 const struct utouch_frame *frame);
79void gin_send_event(struct grail *ge, struct slot_state *s, 78void gin_send_event(struct grail *ge, struct slot_state *s,
80 const struct gesture_event *ev, 79 const struct gesture_event *ev,
81 const struct touch_frame *frame); 80 const struct utouch_frame *frame);
82 81
83int gin_init(struct grail *ge); 82int gin_init(struct grail *ge);
84void gin_destroy(struct grail *ge); 83void gin_destroy(struct grail *ge);
85 84
86void gin_frame_begin(struct grail *ge, const struct touch_frame *frame); 85void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame);
87void gin_frame_end(struct grail *ge, const struct touch_frame *frame); 86void gin_frame_end(struct grail *ge, const struct utouch_frame *frame);
88 87
89int gin_gid_begin_select(struct grail *ge, int type, int priority,
90 const grail_mask_t *span, int nspan);
91int gin_gid_begin(struct grail *ge, int type, int priority, 88int gin_gid_begin(struct grail *ge, int type, int priority,
92 const struct touch_frame *frame); 89 const struct utouch_frame *frame);
93void gin_gid_discard(struct grail *ge, int gid); 90void gin_gid_discard(struct grail *ge, int gid);
94 91
95void gin_gid_event(struct grail *ge, int gid, 92void gin_gid_event(struct grail *ge, int gid,
diff --git a/src/grail-recognizer.c b/src/grail-recognizer.c
index 932f28a..fb0ae85 100644
--- a/src/grail-recognizer.c
+++ b/src/grail-recognizer.c
@@ -42,7 +42,7 @@ void gru_destroy(struct grail *ge)
42 ge->gru = NULL; 42 ge->gru = NULL;
43} 43}
44 44
45void gru_recognize(struct grail *ge, const struct touch_frame *frame) 45void gru_recognize(struct grail *ge, const struct utouch_frame *frame)
46{ 46{
47 if (!ge->gin || !ge->gru) 47 if (!ge->gin || !ge->gru)
48 return; 48 return;
@@ -54,5 +54,4 @@ void gru_recognize(struct grail *ge, const struct touch_frame *frame)
54 gru_winpinch(ge, frame); 54 gru_winpinch(ge, frame);
55 gru_winrotate(ge, frame); 55 gru_winrotate(ge, frame);
56 gru_tapping(ge, frame); 56 gru_tapping(ge, frame);
57 ge->gru->frame = *frame;
58} 57}
diff --git a/src/grail-recognizer.h b/src/grail-recognizer.h
index 1a9edd1..56e5b8d 100644
--- a/src/grail-recognizer.h
+++ b/src/grail-recognizer.h
@@ -26,7 +26,6 @@
26#include "grail-gestures.h" 26#include "grail-gestures.h"
27 27
28struct gesture_recognizer { 28struct gesture_recognizer {
29 struct touch_frame frame;
30 struct move_model move; 29 struct move_model move;
31 struct combo_model drag; 30 struct combo_model drag;
32 struct combo_model pinch; 31 struct combo_model pinch;
@@ -38,7 +37,7 @@ struct gesture_recognizer {
38}; 37};
39 38
40int gru_init(struct grail *ge); 39int gru_init(struct grail *ge);
41void gru_recognize(struct grail *ge, const struct touch_frame *frame); 40void gru_recognize(struct grail *ge, const struct utouch_frame *frame);
42void gru_destroy(struct grail *ge); 41void gru_destroy(struct grail *ge);
43 42
44#endif 43#endif
diff --git a/src/touch-caps.c b/src/touch-caps.c
deleted file mode 100644
index f99b0d7..0000000
--- a/src/touch-caps.c
+++ /dev/null
@@ -1,117 +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 <errno.h>
25#include <math.h>
26
27/* see mtdev-mapping.h */
28#define MTDEV_POSITION_X 5
29#define MTDEV_POSITION_Y 6
30#define MTDEV_ORIENTATION 4
31#define MTDEV_PRESSURE 10
32
33#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
34
35static const int bits_per_long = 8 * sizeof(long);
36
37static inline int nlongs(int nbit)
38{
39 return (nbit + bits_per_long - 1) / bits_per_long;
40}
41
42static inline int getbit(const unsigned long *map, int key)
43{
44 return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01;
45}
46
47int touch_caps_is_supported(struct touch_dev *dev, int fd)
48{
49 unsigned long keybits[nlongs(KEY_MAX)];
50 unsigned long absbits[nlongs(ABS_MAX)];
51 unsigned long relbits[nlongs(REL_CNT)];
52 int rc;
53
54 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
55 if (rc < 0)
56 return 0;
57 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
58 if (rc < 0)
59 return 0;
60 SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbits)), relbits));
61 if (rc < 0)
62 return 0;
63
64 /* only support pure absolute devices at this time */
65 if (getbit(relbits, REL_X) || getbit(relbits, REL_Y))
66 return 0;
67
68 if (dev->mtdev.caps.has_mtdata)
69 return 1;
70
71 return getbit(absbits, ABS_X) &&
72 getbit(absbits, ABS_Y) &&
73 getbit(keybits, BTN_TOUCH) &&
74 getbit(keybits, BTN_TOOL_DOUBLETAP);
75}
76
77void touch_caps_init(struct touch_dev *dev)
78{
79 const struct mtdev_caps *mt = &dev->mtdev.caps;
80 struct touch_caps *caps = &dev->caps;
81 caps->min_x = mt->abs[MTDEV_POSITION_X].minimum;
82 caps->max_x = mt->abs[MTDEV_POSITION_X].maximum;
83 caps->min_y = mt->abs[MTDEV_POSITION_Y].minimum;
84 caps->max_y = mt->abs[MTDEV_POSITION_Y].maximum;
85 caps->min_orient = mt->abs[MTDEV_ORIENTATION].minimum;
86 caps->max_orient = mt->abs[MTDEV_ORIENTATION].maximum;
87 caps->min_press = mt->abs[MTDEV_PRESSURE].minimum;
88 caps->max_press = mt->abs[MTDEV_PRESSURE].maximum;
89 if (caps->min_x == caps->max_x) {
90 caps->min_x = 0;
91 caps->max_x = 1024;
92 }
93 if (caps->min_y == caps->max_y) {
94 caps->min_y = 0;
95 caps->max_y = 768;
96 }
97 if (caps->min_orient == caps->max_orient)
98 caps->max_orient = 1;
99 if (caps->min_orient + caps->max_orient != 0)
100 caps->min_orient = -caps->max_orient;
101 if (caps->min_press == caps->max_press) {
102 caps->min_press = 0;
103 caps->max_press = 256;
104 }
105}
106
107float touch_angle(const struct touch_dev *dev, int orient)
108{
109 const struct touch_caps *caps = &dev->caps;
110 return orient / caps->max_orient * M_PI_2;
111}
112
113float touch_pressure(const struct touch_dev *dev, int press)
114{
115 const struct touch_caps *caps = &dev->caps;
116 return (press - caps->min_press) / (caps->max_press - caps->min_press);
117}
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}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ae6866c..303f70d 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -4,4 +4,4 @@ INCLUDES=-I$(top_srcdir)/include/
4 4
5grail_gesture_SOURCES = grail-gesture.c 5grail_gesture_SOURCES = grail-gesture.c
6grail_gesture_LDFLAGS = -L$(top_builddir)/src/.libs/ \ 6grail_gesture_LDFLAGS = -L$(top_builddir)/src/.libs/ \
7 -lutouch-grail -lmtdev -lm 7 -lutouch-grail -lutouch-frame -lutouch-evemu -lmtdev -lm