~chasedouglas/grail/original-touch-state

« back to all changes in this revision

Viewing changes to test/grail.c

  • Committer: Henrik Rydberg
  • Date: 2010-07-13 09:26:46 UTC
  • Revision ID: git-v1:3b837806891de6cf77d4d74d04567e7e68c82fc0
Gesture Recognition And Instantiation Library (grail)

The aim of this first commit is to get down to hard testing of concepts,
and the library currently has two test programs, touch and grail,
which can be run on commandline. Touch tests the touch interface,
and grail tests the gesture interface.

Expect thinking errors and some glitches. Other than that, the code
runs fine.

Signed-off-by: Henrik Rydberg <rydberg@bitmath.org>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 *
 
3
 * grail - Gesture Recognition And Instantiation Library
 
4
 *
 
5
 * Copyright (C) 2010 Canonical Ltd.
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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/>.
 
19
 *
 
20
 * Authors:
 
21
 *      Henrik Rydberg <rydberg@bitmath.org>
 
22
 *
 
23
 ****************************************************************************/
 
24
 
 
25
#include <grail.h>
 
26
#include <string.h>
 
27
#include <stdio.h>
 
28
#include <unistd.h>
 
29
#include <fcntl.h>
 
30
 
 
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;
 
36
};
 
37
 
 
38
static void gh_gesture(struct gesture_client *client,
 
39
                       const struct gesture_event *ev)
 
40
{
 
41
        int i;
 
42
        fprintf(stderr, "gesture %d %lld\n",
 
43
                ev->type, ev->time);
 
44
        switch (ev->type) {
 
45
        case GE_MOVE:
 
46
                fprintf(stderr, "  %d\n", ev->prop[0]);
 
47
                fprintf(stderr, "  %d\n", ev->prop[1]);
 
48
                break;
 
49
        case GE_VSCROLL:
 
50
                fprintf(stderr, "  %d\n", ev->prop[0]);
 
51
                break;
 
52
        }
 
53
}
 
54
 
 
55
static void gh_init(struct gesture_handler *gh)
 
56
{
 
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);
 
64
}
 
65
 
 
66
static void gh_handle(struct gesture_handler *gh,
 
67
                      const struct touch_frame *frame,
 
68
                      touch_time_t time)
 
69
{
 
70
        struct gesture_flag flag;
 
71
        struct gesture_event ev;
 
72
        if (frame->ntouch == 1 || frame->ntouch == 2) {
 
73
                flag.type = GE_MOVE;
 
74
                flag.time = time;
 
75
                flag.state = GS_BEGIN;
 
76
                gedev_flag(&gh->dev, &flag);
 
77
 
 
78
                ev.type = GE_MOVE;
 
79
                ev.time = time;
 
80
                ev.prop[0] =
 
81
                        frame->touch[0].prop[TP_POS_X] -
 
82
                        gh->frame.touch[0].prop[TP_POS_X];
 
83
                ev.prop[1] =
 
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);
 
88
 
 
89
                flag.time = time + 1;
 
90
                flag.state = GS_END;
 
91
                gedev_flag(&gh->dev, &flag);
 
92
        }
 
93
        if (frame->ntouch == 2) {
 
94
                flag.type = GE_VSCROLL;
 
95
                flag.time = time;
 
96
                flag.state = GS_BEGIN;
 
97
                gedev_flag(&gh->dev, &flag);
 
98
 
 
99
                ev.type = GE_VSCROLL;
 
100
                ev.time = time;
 
101
                ev.prop[0] =
 
102
                        frame->touch[0].prop[TP_POS_Y] -
 
103
                        gh->frame.touch[0].prop[TP_POS_Y];
 
104
 
 
105
                if (ev.prop[0])
 
106
                        gedev_event(&gh->dev, &ev);
 
107
 
 
108
                if (time > gh->last_scroll + 100) {
 
109
                        flag.time = time + 1;
 
110
                        flag.state = GS_END;
 
111
                        gedev_flag(&gh->dev, &flag);
 
112
                        gh->last_scroll = time;
 
113
                }
 
114
        } else {
 
115
                flag.type = GE_VSCROLL;
 
116
                flag.time = time;
 
117
                flag.state = GS_CANCEL;
 
118
                gedev_flag(&gh->dev, &flag);
 
119
        }
 
120
        gedev_sync(&gh->dev);
 
121
        gh->frame = *frame;
 
122
}
 
123
 
 
124
static void gh_destroy(struct gesture_handler *gh)
 
125
{
 
126
        gedev_detach_client(&gh->dev, &gh->client);
 
127
        client_destroy(&gh->client);
 
128
        gedev_destroy(&gh->dev);
 
129
}
 
130
 
 
131
static void tp_sync(struct touch_engine *engine, touch_time_t time)
 
132
{
 
133
        struct gesture_handler *gh = engine->priv;
 
134
        struct touch_frame *frame = &engine->frame;
 
135
        gh_handle(gh, frame, time);
 
136
}
 
137
 
 
138
static void loop_device(struct touch_dev *dev, int fd)
 
139
{
 
140
        struct gesture_handler gh;
 
141
        struct touch_engine engine;
 
142
        gh_init(&gh);
 
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);
 
148
        gh_destroy(&gh);
 
149
}
 
150
 
 
151
int main(int argc, char *argv[])
 
152
{
 
153
        struct touch_dev dev;
 
154
        int fd;
 
155
        if (argc < 2) {
 
156
                fprintf(stderr, "Usage: mtdev <device>\n");
 
157
                return -1;
 
158
        }
 
159
        fd = open(argv[1], O_RDONLY | O_NONBLOCK);
 
160
        if (fd < 0) {
 
161
                fprintf(stderr, "error: could not open device\n");
 
162
                return -1;
 
163
        }
 
164
        if (ioctl(fd, EVIOCGRAB, 1)) {
 
165
                fprintf(stderr, "error: could not grab the device\n");
 
166
                return -1;
 
167
        }
 
168
        if (touch_dev_open(&dev, fd)) {
 
169
                fprintf(stderr, "error: could not open touch device\n");
 
170
                return -1;
 
171
        }
 
172
        loop_device(&dev, fd);
 
173
        touch_dev_close(&dev, fd);
 
174
        ioctl(fd, EVIOCGRAB, 0);
 
175
        close(fd);
 
176
        return 0;
 
177
}