summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--configure.ac9
-rw-r--r--include/utouch/frame-xi2.h49
-rw-r--r--src/Makefile.am8
-rw-r--r--src/frame-impl.h2
-rw-r--r--src/frame-xi2.c302
-rw-r--r--src/frame.c1
-rw-r--r--tools/Makefile.am12
-rw-r--r--tools/utouch-frame-test-xi2.c238
-rw-r--r--tools/utouch-frame-test-xi2.txt22
10 files changed, 644 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index cf601fa..75c2197 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,3 +79,4 @@ core
79.bzr 79.bzr
80patches 80patches
81tools/utouch-frame-test-mtdev 81tools/utouch-frame-test-mtdev
82tools/utouch-frame-test-xi2
diff --git a/configure.ac b/configure.ac
index 980a044..12b275e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,15 @@ AC_PROG_INSTALL
25PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1]) 25PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1])
26PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0]) 26PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0])
27 27
28AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support]))
29AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"])
30
31AS_IF([test "x$with_xi" = "xyes"], [
32 PKG_CHECK_MODULES([X11], [x11])
33 PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.2] [inputproto >= 1.5])
34 PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.99.1] [inputproto >= 2.0.99.1])
35])
36
28AC_CHECK_PROG([ASCIIDOC], [a2x], [a2x]) 37AC_CHECK_PROG([ASCIIDOC], [a2x], [a2x])
29AM_CONDITIONAL([HAVE_DOCTOOLS], [test "x$ASCIIDOC" != "x"]) 38AM_CONDITIONAL([HAVE_DOCTOOLS], [test "x$ASCIIDOC" != "x"])
30AS_IF([test "x$ASCIIDOC" = "x"], 39AS_IF([test "x$ASCIIDOC" = "x"],
diff --git a/include/utouch/frame-xi2.h b/include/utouch/frame-xi2.h
new file mode 100644
index 0000000..5849c40
--- /dev/null
+++ b/include/utouch/frame-xi2.h
@@ -0,0 +1,49 @@
1/*****************************************************************************
2 *
3 * utouch-frame - Touch Frame Library
4 *
5 * Copyright (C) 2010-2011 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 ****************************************************************************/
21
22#ifndef _UTOUCH_FRAME_XI2_H
23#define _UTOUCH_FRAME_XI2_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#define MTDEV_NO_LEGACY_API
30
31#include <utouch/frame.h>
32#include <X11/extensions/XInput2.h>
33
34int utouch_frame_is_supported_xi2(Display *dpy, const XIDeviceInfo *dev);
35
36int utouch_frame_init_xi2(utouch_frame_handle fh,
37 Display *dpy, const XIDeviceInfo *dev);
38
39int utouch_frame_configure_xi2(utouch_frame_handle fh,
40 const XConfigureEvent *ev);
41
42const struct utouch_frame *
43utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev);
44
45#ifdef __cplusplus
46}
47#endif
48
49#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index a6f98f9..c3fd3b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,3 +19,11 @@ libutouch_frameincludedir = $(includedir)/utouch
19libutouch_frameinclude_HEADERS = \ 19libutouch_frameinclude_HEADERS = \
20 $(top_srcdir)/include/utouch/frame.h \ 20 $(top_srcdir)/include/utouch/frame.h \
21 $(top_srcdir)/include/utouch/frame-mtdev.h 21 $(top_srcdir)/include/utouch/frame-mtdev.h
22
23if HAVE_XI
24
25libutouch_frame_la_LDFLAGS += $(XINPUT_LIBS) $(X11_LIBS)
26libutouch_frame_la_SOURCES += frame-xi2.c
27libutouch_frameinclude_HEADERS += $(top_srcdir)/include/utouch/frame-xi2.h
28
29endif
diff --git a/src/frame-impl.h b/src/frame-impl.h
index 38affe7..b072de9 100644
--- a/src/frame-impl.h
+++ b/src/frame-impl.h
@@ -33,6 +33,8 @@ struct utouch_frame_engine {
33 struct utouch_surface *surface; 33 struct utouch_surface *surface;
34 struct utouch_frame **frames; 34 struct utouch_frame **frames;
35 struct utouch_frame *next; 35 struct utouch_frame *next;
36 int *evmap;
37 float map[9];
36}; 38};
37 39
38#endif 40#endif
diff --git a/src/frame-xi2.c b/src/frame-xi2.c
new file mode 100644
index 0000000..a78d9bf
--- /dev/null
+++ b/src/frame-xi2.c
@@ -0,0 +1,302 @@
1/*****************************************************************************
2 *
3 * utouch-frame - Touch Frame 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 ****************************************************************************/
21#include <utouch/frame-xi2.h>
22#include <xorg/xserver-properties.h>
23#include <linux/input.h>
24#include "frame-impl.h"
25#include <stdlib.h>
26#include <stdio.h>
27#include <errno.h>
28#include <math.h>
29#include <string.h>
30#include <X11/Xlib.h>
31
32static Atom transform_atom;
33
34#define set_field(fh, name, number, field) \
35 if (!strcmp(name, AXIS_LABEL_PROP_##field) && \
36 (fh->evmap[number] = field))
37
38int utouch_frame_is_supported_xi2(Display *dpy, const XIDeviceInfo *dev)
39{
40
41 int i;
42
43 for (i = 0; i < dev->num_classes; i++)
44 if (dev->classes[i]->type == XITouchClass)
45 return 1;
46
47 return 0;
48}
49
50static void init_properties(utouch_frame_handle fh,
51 Display *dpy, const XIDeviceInfo *dev)
52{
53 struct utouch_surface *s = fh->surface;
54 XITouchClassInfo *v;
55 int i;
56
57 for (i = 0; i < dev->num_classes; i++) {
58 v = (void *)dev->classes[i];
59 if (v->type != XITouchClass)
60 continue;
61 switch(v->mode) {
62 case XIDependentTouch:
63 s->needs_pointer = 1;
64 break;
65 case XIDirectTouch:
66 s->is_direct = 1;
67 break;
68 default:
69 fprintf(stderr, "unknown mode\n");
70 break;
71 }
72 }
73
74 if (transform_atom == None)
75 transform_atom = XInternAtom(dpy, XI_PROP_TRANSFORM, True);
76
77 fh->map[0] = fh->map[4] = fh->map[8] = 1;
78}
79
80static void update_transform(utouch_frame_handle fh, Display *dpy, int devid)
81{
82 unsigned long nitem, nbyte;
83 unsigned char *data;
84 int format;
85 Atom type;
86
87 if (transform_atom == None)
88 return;
89
90 XIGetProperty(dpy, devid, transform_atom, 0, 9, False,
91 AnyPropertyType, &type, &format, &nitem, &nbyte, &data);
92
93 if (format == 32 && nitem == 9 && nbyte == 0)
94 memcpy(fh->map, data, sizeof(fh->map));
95 else
96 fprintf(stderr, "Invalid transform matrix\n");
97
98 XFree(data);
99}
100
101static void update_screen(utouch_frame_handle fh, Display *dpy)
102{
103 struct utouch_surface *s = fh->surface;
104 XWindowAttributes attrs;
105 float x1, y1, x2, y2;
106
107 XGetWindowAttributes(dpy, XDefaultRootWindow(dpy), &attrs);
108
109 x1 = 0;
110 y1 = 0;
111 x2 = attrs.width;
112 y2 = attrs.height;
113
114 s->mapped_min_x = fh->map[0] * x1 + fh->map[1] * y1 + fh->map[2];
115 s->mapped_min_y = fh->map[3] * x1 + fh->map[4] * y1 + fh->map[5];
116 s->mapped_max_x = fh->map[0] * x2 + fh->map[1] * y2 + fh->map[2];
117 s->mapped_max_y = fh->map[3] * x2 + fh->map[4] * y2 + fh->map[5];
118 s->mapped_max_pressure = 1;
119
120 fprintf(stderr, "frame map: %f %f %f %f %f\n",
121 s->mapped_min_x, s->mapped_min_y,
122 s->mapped_max_x, s->mapped_max_y, s->mapped_max_pressure);
123}
124
125static void init_valuators(utouch_frame_handle fh,
126 Display *dpy, const XIDeviceInfo *dev)
127{
128 struct utouch_surface *s = fh->surface;
129 XITouchValuatorClassInfo *v;
130 char *name;
131 int i;
132
133 s->phys_width = 100;
134 s->phys_height = 65;
135 s->phys_pressure = 10;
136 s->max_x = 1024;
137 s->max_y = 768;
138 s->max_pressure = 256;
139 s->max_orient = 1;
140
141 for (i = 0; i < dev->num_classes; i++) {
142 v = (void *)dev->classes[i];
143 if (v->type != XITouchValuatorClass)
144 continue;
145 name = XGetAtomName(dpy, v->label);
146 set_field(fh, name, v->number, ABS_MT_POSITION_X) {
147 s->min_x = v->min;
148 s->max_x = v->max;
149 if (v->resolution > 0)
150 s->phys_width = (v->max - v->min) /
151 v->resolution;
152 }
153 set_field(fh, name, v->number, ABS_MT_POSITION_Y) {
154 s->min_y = v->min;
155 s->max_y = v->max;
156 if (v->resolution > 0)
157 s->phys_height = (v->max - v->min) /
158 v->resolution;
159 }
160 set_field(fh, name, v->number, ABS_MT_TOUCH_MAJOR) {
161 s->use_touch_major = 1;
162 }
163 set_field(fh, name, v->number, ABS_MT_TOUCH_MINOR) {
164 s->use_touch_minor = 1;
165 }
166 set_field(fh, name, v->number, ABS_MT_WIDTH_MAJOR) {
167 s->use_width_major = 1;
168 }
169 set_field(fh, name, v->number, ABS_MT_WIDTH_MINOR) {
170 s->use_width_minor = 1;
171 }
172 set_field(fh, name, v->number, ABS_MT_ORIENTATION) {
173 s->use_orientation = 1;
174 s->max_orient = v->max > 0 ? v->max : 1;
175 }
176 set_field(fh, name, v->number, ABS_MT_PRESSURE) {
177 s->use_pressure = 1;
178 s->max_pressure = v->max > 0 ? v->max : 256;
179 if (v->resolution > 0)
180 s->phys_pressure = v->max / v->resolution;
181 }
182#if 0
183 set_field(fh, name, v->number, ABS_MT_DISTANCE) {
184 s->use_distance = 1;
185 }
186#endif
187 XFree(name);
188 }
189}
190
191int utouch_frame_init_xi2(utouch_frame_handle fh,
192 Display *dpy, const XIDeviceInfo *dev)
193{
194 int event;
195 int err;
196
197 free(fh->evmap);
198 fh->evmap =calloc(dev->num_classes, sizeof(int));
199 if (!fh->evmap)
200 return -ENOMEM;
201
202 if (!utouch_frame_is_supported_xi2(dpy, dev))
203 return -ENODEV;
204
205 init_properties(fh, dpy, dev);
206 init_valuators(fh, dpy, dev);
207 update_transform(fh, dpy, dev->deviceid);
208 update_screen(fh, dpy);
209
210 return 0;
211}
212
213static int handle_event(utouch_frame_handle fh,
214 struct utouch_contact *slot,
215 int ix, float value)
216{
217 switch (fh->evmap[ix]) {
218 case ABS_MT_POSITION_X:
219 slot->x = value;
220 return 1;
221 case ABS_MT_POSITION_Y:
222 slot->y = value;
223 return 1;
224 case ABS_MT_TOUCH_MAJOR:
225 slot->touch_major = value;
226 return 1;
227 case ABS_MT_TOUCH_MINOR:
228 slot->touch_minor = value;
229 return 1;
230 case ABS_MT_WIDTH_MAJOR:
231 slot->width_major = value;
232 return 1;
233 case ABS_MT_WIDTH_MINOR:
234 slot->width_minor = value;
235 return 1;
236 case ABS_MT_ORIENTATION:
237 slot->orientation = value;
238 return 1;
239 case ABS_MT_PRESSURE:
240 slot->pressure = value;
241 return 1;
242#ifdef ABS_MT_DISTANCE
243 case ABS_MT_DISTANCE:
244 slot->distance = value;
245 return 1;
246#endif
247 case ABS_MT_TOOL_TYPE:
248 slot->tool_type = value;
249 return 1;
250 default:
251 fprintf(stderr, "did not get that one: %d\n", ix);
252 return 0;
253 }
254}
255
256int utouch_frame_configure_xi2(utouch_frame_handle fh,
257 const XConfigureEvent *ev)
258{
259 if (ev->display)
260 update_screen(fh, ev->display);
261 return 1;
262}
263
264const struct utouch_frame *
265utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev)
266{
267 const XIPropertyEvent *prop_ev;
268 const double *value;
269 const unsigned char *mask;
270 struct utouch_contact *slot;
271 int touchid, nbyte, nbit, num, i;
272
273 switch (ev->evtype) {
274 case XI_TouchBegin:
275 case XI_TouchMotion:
276 case XI_TouchEnd:
277 value = ev->valuators.values;
278 mask = ev->valuators.mask;
279 touchid = ev->detail;
280 nbyte = ev->valuators.mask_len;
281 nbit = nbyte << 3;
282
283 utouch_frame_set_current_id(fh, touchid);
284 slot = utouch_frame_get_current_slot(fh);
285 num = 0;
286 for (i = 0; i < nbit; i++)
287 if (XIMaskIsSet(mask, i))
288 handle_event(fh, slot, i, value[num++]);
289 if (ev->evtype == XI_TouchEnd)
290 utouch_frame_get_current_slot(fh)->id = -1;
291 return utouch_frame_sync(fh, ev->time);
292 case XI_PropertyEvent:
293 prop_ev = (XIPropertyEvent *)ev;
294 if (prop_ev->property == transform_atom && ev->display) {
295 update_transform(fh, ev->display, ev->deviceid);
296 update_screen(fh, ev->display);
297 }
298 break;
299 }
300
301 return 0;
302}
diff --git a/src/frame.c b/src/frame.c
index 061b170..32bd2cd 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -181,6 +181,7 @@ out:
181 181
182void utouch_frame_delete_engine(utouch_frame_handle fh) 182void utouch_frame_delete_engine(utouch_frame_handle fh)
183{ 183{
184 free(fh->evmap);
184 destroy_frame(fh->next, fh->num_slots); 185 destroy_frame(fh->next, fh->num_slots);
185 destroy_frames(fh->frames, fh->num_frames, fh->num_slots); 186 destroy_frames(fh->frames, fh->num_frames, fh->num_slots);
186 free(fh->surface); 187 free(fh->surface);
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 91e99ce..3b612cc 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -6,6 +6,18 @@ utouch_frame_test_mtdev_SOURCES = utouch-frame-test-mtdev.c
6utouch_frame_test_mtdev_LDFLAGS = -L$(top_builddir)/src/.libs/ \ 6utouch_frame_test_mtdev_LDFLAGS = -L$(top_builddir)/src/.libs/ \
7 -lutouch-frame -lutouch-evemu -lmtdev -lm 7 -lutouch-frame -lutouch-evemu -lmtdev -lm
8 8
9if HAVE_XI
10
11AM_CFLAGS = $(XINPUT_CFLAGS)
12
13bin_PROGRAMS += utouch-frame-test-xi2
14
15utouch_frame_test_xi2_SOURCES = utouch-frame-test-xi2.c
16utouch_frame_test_xi2_LDFLAGS = $(XINPUT_LIBS) $(X11_LIBS) \
17 -L$(top_builddir)/src/.libs/ -lutouch-frame
18
19endif
20
9if HAVE_DOCTOOLS 21if HAVE_DOCTOOLS
10dist_man_MANS = utouch-frame-test-mtdev.1 22dist_man_MANS = utouch-frame-test-mtdev.1
11 23
diff --git a/tools/utouch-frame-test-xi2.c b/tools/utouch-frame-test-xi2.c
new file mode 100644
index 0000000..df68c1a
--- /dev/null
+++ b/tools/utouch-frame-test-xi2.c
@@ -0,0 +1,238 @@
1/*****************************************************************************
2 *
3 * utouch-frame - Touch Frame Library
4 *
5 * Copyright (C) 2010-2011 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#define MTDEV_NO_LEGACY_API
26
27#include <utouch/frame-xi2.h>
28#include <string.h>
29#include <stdio.h>
30#include <unistd.h>
31#include <fcntl.h>
32#include <stdlib.h>
33
34static int opcode;
35
36struct frame_test {
37 Display *display;
38 Window root, win;
39 XIDeviceInfo *info, *dev;
40 utouch_frame_handle fh;
41};
42
43static int init_xi2(struct frame_test *test, int id)
44{
45 Display *dpy;
46 int ndevices, i;
47 int event, error;
48
49 dpy = XOpenDisplay(NULL);
50 if (!dpy)
51 return -1;
52
53 if (!XQueryExtension(dpy, "XInputExtension", &opcode, &event, &error))
54 return -1;
55
56 test->display = dpy;
57 test->info = XIQueryDevice(dpy, XIAllDevices, &ndevices);
58 test->dev = 0;
59 for (i = 0; i < ndevices; i++)
60 if (test->info[i].deviceid == id)
61 test->dev = &test->info[i];
62 if (!test->dev)
63 return -1;
64
65 test->root = DefaultRootWindow(dpy);
66 test->win = XCreateSimpleWindow(dpy, test->root,
67 0, 0, 400, 400, 0,
68 BlackPixel(dpy, 0),
69 WhitePixel(dpy, 0));
70
71 XMapWindow(test->display, test->win);
72 XFlush(test->display);
73
74 return 0;
75}
76
77static int init_frame(struct frame_test *test)
78{
79 test->fh = utouch_frame_new_engine(100, 32, 100);
80 if (!test->fh)
81 return -1;
82 return utouch_frame_init_xi2(test->fh, test->display, test->dev);
83}
84
85static void destroy_all(struct frame_test *test)
86{
87 utouch_frame_delete_engine(test->fh);
88 XIFreeDeviceInfo(test->info);
89 XDestroyWindow(test->display, test->win);
90 XCloseDisplay(test->display);
91 memset(test, 0, sizeof(*test));
92}
93
94static void report_device_caps(struct frame_test *test)
95{
96 struct utouch_surface *s = utouch_frame_get_surface(test->fh);
97 fprintf(stderr, "device props:\n");
98 if (s->needs_pointer)
99 fprintf(stderr, "\tpointer\n");
100 if (s->is_direct)
101 fprintf(stderr, "\tdirect\n");
102 if (s->is_buttonpad)
103 fprintf(stderr, "\tbuttonpad\n");
104 if (s->is_semi_mt)
105 fprintf(stderr, "\tsemi_mt\n");
106 fprintf(stderr, "device mt events:\n");
107 if (s->use_touch_major)
108 fprintf(stderr, "\ttouch_major\n");
109 if (s->use_touch_minor)
110 fprintf(stderr, "\ttouch_minor\n");
111 if (s->use_width_major)
112 fprintf(stderr, "\twidth_major\n");
113 if (s->use_width_minor)
114 fprintf(stderr, "\twidth_minor\n");
115 if (s->use_orientation)
116 fprintf(stderr, "\torientation\n");
117 if (s->use_pressure)
118 fprintf(stderr, "\tpressure\n");
119 if (s->use_distance)
120 fprintf(stderr, "\tdistance\n");
121}
122
123static void report_frame(const struct utouch_frame *frame,
124 const XIDeviceEvent *ev)
125{
126 int i;
127
128 for (i = 0; i < frame->num_active; i++) {
129 const struct utouch_contact *t = frame->active[i];
130
131 fprintf(stderr, "touch %d\n", i);
132 fprintf(stderr, " slot: %d\n", t->slot);
133 fprintf(stderr, " id: %d\n", t->id);
134 fprintf(stderr, " tool_type: %d\n", t->tool_type);
135 fprintf(stderr, " x: %f\n", t->x);
136 fprintf(stderr, " y: %f\n", t->y);
137 fprintf(stderr, " touch_major: %f\n", t->touch_major);
138 fprintf(stderr, " touch_minor: %f\n", t->touch_minor);
139 fprintf(stderr, " width_major: %f\n", t->width_major);
140 fprintf(stderr, " width_minor: %f\n", t->width_minor);
141 fprintf(stderr, " angle: %f\n", t->orientation);
142 fprintf(stderr, " pressure: %f\n", t->pressure);
143 fprintf(stderr, " distance: %f\n", t->distance);
144 }
145
146 fprintf(stderr, "sync %d %ld %d %d %d %f %f\n",
147 frame->num_active,
148 frame->time,
149 frame->sequence_id,
150 frame->revision,
151 frame->slot_revision,
152 ev->root_x,
153 ev->root_y);
154}
155
156static void handle_event(struct frame_test *test, XEvent *ev)
157{
158 XGenericEventCookie *gev = &ev->xcookie;
159 const struct utouch_frame *frame;
160 XConfigureEvent *cev;
161 XIDeviceEvent *dev;
162
163 switch(ev->type) {
164 case ConfigureNotify:
165 cev = (XConfigureEvent *)ev;
166 if (cev->window == XDefaultRootWindow(cev->display))
167 utouch_frame_configure_xi2(test->fh, cev);
168 break;
169 case GenericEvent:
170 if (!XGetEventData(test->display, gev))
171 break;
172 dev = gev->data;
173 /* null for some requests, quite odd */
174 dev->display = ev->xany.display;
175 if (gev->type == GenericEvent && gev->extension == opcode) {
176 frame = utouch_frame_pump_xi2(test->fh, dev);
177 if (frame)
178 report_frame(frame, dev);
179 }
180 XFreeEventData(test->display, gev);
181 break;
182 }
183}
184
185static void loop_device(struct frame_test *test)
186{
187 XIEventMask mask;
188
189 mask.deviceid = XIAllDevices;
190 mask.mask_len = XIMaskLen(XI_TouchMotion);
191 mask.mask = calloc(mask.mask_len, sizeof(char));
192
193 XISetMask(mask.mask, XI_TouchBegin);
194 XISetMask(mask.mask, XI_TouchMotion);
195 XISetMask(mask.mask, XI_TouchEnd);
196 XISetMask(mask.mask, XI_PropertyEvent);
197 XISelectEvents(test->display, test->win, &mask, 1);
198
199 XSelectInput(test->display, test->root, StructureNotifyMask);
200
201 while (1) {
202 XEvent ev;
203 XNextEvent(test->display, &ev);
204 handle_event(test, &ev);
205 }
206}
207
208int main(int argc, char *argv[])
209{
210 struct frame_test test;
211 int id;
212
213 if (argc < 2) {
214 fprintf(stderr, "Usage: %s <xinput_device_number>\n", argv[0]);
215 return -1;
216 }
217 id = atoi(argv[1]);
218
219 if (init_xi2(&test, id)) {
220 fprintf(stderr, "error: could not describe device\n");
221 return -1;
222 }
223 if (!utouch_frame_is_supported_xi2(test.display, test.dev)) {
224 fprintf(stderr, "error: unsupported device\n");
225 return -1;
226 }
227 if (init_frame(&test)) {
228 fprintf(stderr, "error: could not init frame\n");
229 return -1;
230 }
231
232 report_device_caps(&test);
233
234 loop_device(&test);
235
236 destroy_all(&test);
237 return 0;
238}
diff --git a/tools/utouch-frame-test-xi2.txt b/tools/utouch-frame-test-xi2.txt
new file mode 100644
index 0000000..9f79167
--- /dev/null
+++ b/tools/utouch-frame-test-xi2.txt
@@ -0,0 +1,22 @@
1UTOUCH-FRAME-TEST-XI2(1)
2==========================
3
4NAME
5----
6
7 utouch-frame-test-xi2 - report frame events from an xinput device
8
9SYNOPSIS
10--------
11
12 utouch-frame-test-xi2 xinput-device-number
13
14DESCRIPTION
15-----------
16
17A test tool used to analyse the capabilities and act as a test driver for the
18uTouch touch frame library.
19
20AUTHOR
21------
22utouch-frame-test-xi2 was written by Henrik Rydberg <rydberg@euromail.se>