1
/*****************************************************************************
3
* grail - Gesture Recognition And Instantiation Library
5
* Copyright (C) 2010 Canonical Ltd.
7
* This program is free software: you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation, either version 3 of the License, or (at your
10
* option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
21
* Henrik Rydberg <rydberg@bitmath.org>
23
****************************************************************************/
31
struct gesture_handler {
32
struct touch_frame frame;
33
struct gesture_client client;
34
struct gesture_dev dev;
35
touch_time_t last_scroll;
38
static void gh_gesture(struct gesture_client *client,
39
const struct gesture_event *ev)
42
fprintf(stderr, "gesture %d %lld\n",
46
fprintf(stderr, " %d\n", ev->prop[0]);
47
fprintf(stderr, " %d\n", ev->prop[1]);
50
fprintf(stderr, " %d\n", ev->prop[0]);
55
static void gh_init(struct gesture_handler *gh)
57
memset(gh, 0, sizeof(*gh));
58
gedev_init(&gh->dev, 0);
59
client_init(&gh->client, gh);
60
gh->client.gesture = gh_gesture;
61
gh->client.priority[GE_MOVE] = 1;
62
gh->client.priority[GE_VSCROLL] = 2;
63
gedev_attach_client(&gh->dev, &gh->client);
66
static void gh_handle(struct gesture_handler *gh,
67
const struct touch_frame *frame,
70
struct gesture_flag flag;
71
struct gesture_event ev;
72
if (frame->ntouch == 1 || frame->ntouch == 2) {
75
flag.state = GS_BEGIN;
76
gedev_flag(&gh->dev, &flag);
81
frame->touch[0].prop[TP_POS_X] -
82
gh->frame.touch[0].prop[TP_POS_X];
84
frame->touch[0].prop[TP_POS_Y] -
85
gh->frame.touch[0].prop[TP_POS_Y];
86
if (ev.prop[0] || ev.prop[1])
87
gedev_event(&gh->dev, &ev);
91
gedev_flag(&gh->dev, &flag);
93
if (frame->ntouch == 2) {
94
flag.type = GE_VSCROLL;
96
flag.state = GS_BEGIN;
97
gedev_flag(&gh->dev, &flag);
102
frame->touch[0].prop[TP_POS_Y] -
103
gh->frame.touch[0].prop[TP_POS_Y];
106
gedev_event(&gh->dev, &ev);
108
if (time > gh->last_scroll + 100) {
109
flag.time = time + 1;
111
gedev_flag(&gh->dev, &flag);
112
gh->last_scroll = time;
115
flag.type = GE_VSCROLL;
117
flag.state = GS_CANCEL;
118
gedev_flag(&gh->dev, &flag);
120
gedev_sync(&gh->dev);
124
static void gh_destroy(struct gesture_handler *gh)
126
gedev_detach_client(&gh->dev, &gh->client);
127
client_destroy(&gh->client);
128
gedev_destroy(&gh->dev);
131
static void tp_sync(struct touch_engine *engine, touch_time_t time)
133
struct gesture_handler *gh = engine->priv;
134
struct touch_frame *frame = &engine->frame;
135
gh_handle(gh, frame, time);
138
static void loop_device(struct touch_dev *dev, int fd)
140
struct gesture_handler gh;
141
struct touch_engine engine;
143
touch_engine_init(&engine, tp_sync, &gh);
144
touch_engine_attach(&engine, dev);
145
while (!touch_dev_idle(dev, fd, 5000))
146
touch_dev_pull(dev, fd);
147
touch_engine_detach(&engine, dev);
151
int main(int argc, char *argv[])
153
struct touch_dev dev;
156
fprintf(stderr, "Usage: mtdev <device>\n");
159
fd = open(argv[1], O_RDONLY | O_NONBLOCK);
161
fprintf(stderr, "error: could not open device\n");
164
if (ioctl(fd, EVIOCGRAB, 1)) {
165
fprintf(stderr, "error: could not grab the device\n");
168
if (touch_dev_open(&dev, fd)) {
169
fprintf(stderr, "error: could not open touch device\n");
172
loop_device(&dev, fd);
173
touch_dev_close(&dev, fd);
174
ioctl(fd, EVIOCGRAB, 0);