1
/*****************************************************************************
3
* grail - Gesture Recognition And Instantiation Library
5
* Copyright (C) 2010 Canonical Ltd.
6
* Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org>
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.
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.
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/>.
21
****************************************************************************/
23
#include <grail-touch.h>
28
/* see mtdev-mapping.h */
29
#define MTDEV_TOUCH_MINOR 1
31
#define SET_PROP(name, value) \
32
if (t->name != value) { \
37
static void finish_touch(struct touch_dev *dev, struct touch_frame *frame)
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);
45
grail_mask_set(frame->touches, dev->slot);
50
grail_mask_clear(frame->touches, dev->slot);
56
static void finish_legacy(struct touch_dev *dev, struct touch_frame *frame)
60
for (i = 0; i < frame->nactive; i++) {
61
struct touch *t = &frame->touch[i];
64
t->id = trkid++ & 0xffff;
68
SET_PROP(x, frame->touch[0].x);
69
SET_PROP(y, frame->touch[0].y);
70
SET_PROP(pressure, frame->touch[0].pressure);
72
grail_mask_set(frame->touches, i);
74
for (i = frame->nactive; i < DIM_TOUCH; i++) {
75
struct touch *t = &frame->touch[i];
81
grail_mask_clear(frame->touches, i);
85
static void finish_packet(struct touch_dev *dev,
86
const struct input_event *syn)
88
static const touch_time_t ms = 1000;
89
struct touch_frame *frame = &dev->frame;
91
if (dev->mtdev.caps.has_mtdata)
92
finish_touch(dev, frame);
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;
106
static int handle_abs_event(struct touch_dev *dev,
107
const struct input_event *ev)
109
struct touch_frame *frame = &dev->frame;
110
struct touch *t = &frame->touch[dev->slot];
113
if (dev->mtdev.caps.has_mtdata)
115
SET_PROP(x, ev->value);
118
if (dev->mtdev.caps.has_mtdata)
120
SET_PROP(y, ev->value);
123
if (dev->mtdev.caps.has_mtdata)
125
SET_PROP(pressure, ev->value);
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];
135
case ABS_MT_POSITION_X:
136
SET_PROP(x, ev->value);
138
case ABS_MT_POSITION_Y:
139
SET_PROP(y, ev->value);
141
case ABS_MT_TOUCH_MAJOR:
142
SET_PROP(touch_major, ev->value);
144
case ABS_MT_TOUCH_MINOR:
145
SET_PROP(touch_minor, ev->value);
147
case ABS_MT_WIDTH_MAJOR:
148
SET_PROP(width_major, ev->value);
150
case ABS_MT_WIDTH_MINOR:
151
SET_PROP(width_minor, ev->value);
153
case ABS_MT_ORIENTATION:
154
SET_PROP(orientation, ev->value);
156
case ABS_MT_PRESSURE:
157
SET_PROP(pressure, ev->value);
159
case ABS_MT_TOOL_TYPE:
160
SET_PROP(tool_type, ev->value);
162
case ABS_MT_TRACKING_ID:
163
if (t->id != ev->value) {
164
if (t->id != MT_ID_NULL) {
166
finish_touch(dev, frame);
168
if (ev->value != MT_ID_NULL)
178
static int handle_key_event(struct touch_dev *dev,
179
const struct input_event *ev)
181
struct touch_frame *frame = &dev->frame;
182
if (dev->mtdev.caps.has_mtdata)
186
if (ev->value && !frame->nactive)
188
else if (!ev->value && frame->nactive)
191
case BTN_TOOL_FINGER:
195
case BTN_TOOL_DOUBLETAP:
199
case BTN_TOOL_TRIPLETAP:
203
case BTN_TOOL_QUADTAP:
212
int touch_dev_open(struct touch_dev *dev, int fd)
214
struct touch_frame *frame = &dev->frame;
216
memset(dev, 0, sizeof(*dev));
217
for (i = 0; i < DIM_TOUCH; i++) {
218
struct touch *t = &frame->touch[i];
222
ret = mtdev_open(&dev->mtdev, fd);
223
if (!ret && !touch_caps_is_supported(dev, fd))
227
touch_caps_init(dev);
233
int touch_dev_idle(struct touch_dev *dev, int fd, int ms)
235
return mtdev_idle(&dev->mtdev, fd, ms);
238
int touch_dev_pull(struct touch_dev *dev, int fd)
240
struct input_event ev;
241
int ret, count = 0, consumed;
242
while ((ret = mtdev_get(&dev->mtdev, fd, &ev, 1)) > 0) {
244
if (ev.type == EV_SYN) {
245
if (ev.code == SYN_REPORT)
246
finish_packet(dev, &ev);
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);
253
if (!consumed && dev->event)
254
dev->event(dev, &ev);
257
return count > 0 ? count : ret;
260
void touch_dev_close(struct touch_dev *dev, int fd)
262
mtdev_close(&dev->mtdev);
263
memset(dev, 0, sizeof(*dev));