Merge lp:~oif-team/frame/trunk.v1.0.2 into lp:frame
- trunk.v1.0.2
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~oif-team/frame/trunk.v1.0.2 |
Merge into: | lp:frame |
Diff against target: |
1217 lines (+836/-87) 15 files modified
.gitignore (+1/-0) configure.ac (+9/-1) include/utouch/frame-mtdev.h (+8/-0) include/utouch/frame-xi2.h (+49/-0) include/utouch/frame.h (+61/-6) src/Makefile.am (+9/-1) src/frame-impl.h (+2/-1) src/frame-mtdev.c (+14/-10) src/frame-xi2.c (+304/-0) src/frame.c (+80/-7) tools/Makefile.am (+13/-1) tools/common-defs.h (+85/-0) tools/utouch-frame-test-mtdev.c (+2/-60) tools/utouch-frame-test-xi2.c (+177/-0) tools/utouch-frame-test-xi2.txt (+22/-0) |
To merge this branch: | bzr merge lp:~oif-team/frame/trunk.v1.0.2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Needs Fixing | ||
Stephen M. Webb (community) | Approve | ||
Review via email: mp+50582@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-02-22.
Commit message
Description of the change
New version, fixing Chase's comment and adding yet more functionality.
Chase Douglas (chasedouglas) wrote : | # |
1. Velocity compensation for unchanged touches seems to work fine for mtdev, but works terribly for xi 2.1. I think this is due to the X timestamps being poorly correlated to evdev/device timing. We need to disable velocity compensation in the xi 2.1 branch for now. I think we should look into adding device timestamps as a valuator in xi.
2. I've changed the version number of libXi for our multitouch changes. There could be a 1.4.2 released between now and when the upstream libXI has xi 2.1 support, so I downgraded the version to 1.4.1.99.1. This change is not in the ppa, but will be in the ubuntu version of the package. Thus, the configure.ac check should be updated for it.
3. A minor nitpick :). configure.ac is checking for the x11 package twice. You can get rid of the following line:
PKG_CHECK_
Henrik Rydberg (rydberg) wrote : | # |
Here is a patch for position filter inhibit for xi, please test :-)
diff --git a/src/frame-xi2.c b/src/frame-xi2.c
index 7fc38fd..98a43bd 100644
--- a/src/frame-xi2.c
+++ b/src/frame-xi2.c
@@ -288,6 +288,8 @@ utouch_
Event *ev)
for (i = 0; i < nbit; i++)
if (XIMaskIsSet(mask, i))
handle_
+ /* no velocity adjustments without device time stamps */
+ slot->vx = slot->vy = 0;
if (ev->evtype == XI_TouchEnd)
utouch_
return utouch_
Henrik Rydberg (rydberg) wrote : | # |
> Inconsistent #ifdef'ing around ABS_MT_DISTANCE: sometimes #if 0, sometimes
> #ifdef ABS_MT_DISTANCE.
>
> You might want to fix that before committing.
>
> Other than that, I find no obvious problems.
This is obviously not right, but placed here because of a missing variable in xserver-
Henrik Rydberg (rydberg) wrote : | # |
I think all comments are now addressed. Pushed a new version of v1.0.2.
- 15. By Henrik Rydberg
-
Simplify XInput package test
The XI2.1 support is present in sufficiently recent xinput packages,
so simplify the testing accordingly. - 16. By Henrik Rydberg
-
Fix ABS_MT_DISTANCE compilation conditional
The ABS_MT_DISTANCE is new, and the corresponding entry in
xserver-properties. h is even newer. Make compilation conditional on
the existence of those two defines. - 17. By Henrik Rydberg
-
Disable time-dependent filtering for current XI2.1
Velocity-adjusted positioning and Kalman filters depend on accurate
time stamps on events. Until we have device event times, disable this
functionality for XI2.1 - 18. By Henrik Rydberg
-
Bump to version 1.0.2
Unmerged revisions
Preview Diff
1 | === modified file '.gitignore' |
2 | --- .gitignore 2010-12-30 19:23:24 +0000 |
3 | +++ .gitignore 2011-02-21 12:19:53 +0000 |
4 | @@ -79,3 +79,4 @@ |
5 | .bzr |
6 | patches |
7 | tools/utouch-frame-test-mtdev |
8 | +tools/utouch-frame-test-xi2 |
9 | |
10 | === modified file 'configure.ac' |
11 | --- configure.ac 2011-02-03 16:07:34 +0000 |
12 | +++ configure.ac 2011-02-21 12:19:53 +0000 |
13 | @@ -1,7 +1,7 @@ |
14 | # Initialize Autoconf |
15 | AC_PREREQ([2.60]) |
16 | AC_INIT([Touch Frame Library], |
17 | - [1.0.0], |
18 | + [1.0.2], |
19 | [], |
20 | [utouch-frame]) |
21 | AC_CONFIG_SRCDIR([Makefile.am]) |
22 | @@ -25,6 +25,14 @@ |
23 | PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1]) |
24 | PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0]) |
25 | |
26 | +AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support])) |
27 | +AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"]) |
28 | + |
29 | +AS_IF([test "x$with_xi" = "xyes"], [ |
30 | + PKG_CHECK_MODULES([X11], [x11]) |
31 | + PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.4.99.1] [inputproto >= 2.0.99.1]) |
32 | +]) |
33 | + |
34 | AC_CHECK_PROG([ASCIIDOC], [a2x], [a2x]) |
35 | AM_CONDITIONAL([HAVE_DOCTOOLS], [test "x$ASCIIDOC" != "x"]) |
36 | AS_IF([test "x$ASCIIDOC" = "x"], |
37 | |
38 | === modified file 'include/utouch/frame-mtdev.h' |
39 | --- include/utouch/frame-mtdev.h 2010-12-30 19:23:24 +0000 |
40 | +++ include/utouch/frame-mtdev.h 2011-02-21 12:19:53 +0000 |
41 | @@ -22,6 +22,10 @@ |
42 | #ifndef _UTOUCH_FRAME_MTDEV_H |
43 | #define _UTOUCH_FRAME_MTDEV_H |
44 | |
45 | +#ifdef __cplusplus |
46 | +extern "C" { |
47 | +#endif |
48 | + |
49 | #define MTDEV_NO_LEGACY_API |
50 | |
51 | #include <utouch/frame.h> |
52 | @@ -36,4 +40,8 @@ |
53 | const struct utouch_frame * |
54 | utouch_frame_pump_mtdev(utouch_frame_handle fh, const struct input_event *ev); |
55 | |
56 | +#ifdef __cplusplus |
57 | +} |
58 | +#endif |
59 | + |
60 | #endif |
61 | |
62 | === added file 'include/utouch/frame-xi2.h' |
63 | --- include/utouch/frame-xi2.h 1970-01-01 00:00:00 +0000 |
64 | +++ include/utouch/frame-xi2.h 2011-02-21 12:19:53 +0000 |
65 | @@ -0,0 +1,49 @@ |
66 | +/***************************************************************************** |
67 | + * |
68 | + * utouch-frame - Touch Frame Library |
69 | + * |
70 | + * Copyright (C) 2010-2011 Canonical Ltd. |
71 | + * |
72 | + * This program is free software: you can redistribute it and/or modify it |
73 | + * under the terms of the GNU General Public License as published by the |
74 | + * Free Software Foundation, either version 3 of the License, or (at your |
75 | + * option) any later version. |
76 | + * |
77 | + * This program is distributed in the hope that it will be useful, but |
78 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
79 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
80 | + * General Public License for more details. |
81 | + * |
82 | + * You should have received a copy of the GNU General Public License along |
83 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
84 | + * |
85 | + ****************************************************************************/ |
86 | + |
87 | +#ifndef _UTOUCH_FRAME_XI2_H |
88 | +#define _UTOUCH_FRAME_XI2_H |
89 | + |
90 | +#ifdef __cplusplus |
91 | +extern "C" { |
92 | +#endif |
93 | + |
94 | +#define MTDEV_NO_LEGACY_API |
95 | + |
96 | +#include <utouch/frame.h> |
97 | +#include <X11/extensions/XInput2.h> |
98 | + |
99 | +int utouch_frame_is_supported_xi2(Display *dpy, const XIDeviceInfo *dev); |
100 | + |
101 | +int utouch_frame_init_xi2(utouch_frame_handle fh, |
102 | + Display *dpy, const XIDeviceInfo *dev); |
103 | + |
104 | +int utouch_frame_configure_xi2(utouch_frame_handle fh, |
105 | + const XConfigureEvent *ev); |
106 | + |
107 | +const struct utouch_frame * |
108 | +utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev); |
109 | + |
110 | +#ifdef __cplusplus |
111 | +} |
112 | +#endif |
113 | + |
114 | +#endif |
115 | |
116 | === modified file 'include/utouch/frame.h' |
117 | --- include/utouch/frame.h 2010-12-30 19:23:24 +0000 |
118 | +++ include/utouch/frame.h 2011-02-21 12:19:53 +0000 |
119 | @@ -22,9 +22,13 @@ |
120 | #ifndef _UTOUCH_FRAME_H |
121 | #define _UTOUCH_FRAME_H |
122 | |
123 | +#ifdef __cplusplus |
124 | +extern "C" { |
125 | +#endif |
126 | + |
127 | #include <stdint.h> |
128 | |
129 | -#define UTOUCH_FRAME_VERSION 0x00001000 |
130 | +#define UTOUCH_FRAME_VERSION 0x00001010 |
131 | |
132 | /** |
133 | * struct utouch_surface - device surface details |
134 | @@ -42,11 +46,23 @@ |
135 | * @phys_width: physical width in millimeters (mm) |
136 | * @phys_height: physical height in millimeters (mm) |
137 | * @phys_pressure: maximal physical pressure (N/cm^2) |
138 | - * @min_x: minimum horizontal coordinate value |
139 | - * @min_y: minimum vertical coordinate value |
140 | - * @max_x: maximum horizontal coordinate value |
141 | - * @max_y: maximum vertical coordinate value |
142 | - * @max_pressure: maximum pressure coordinate value |
143 | + * @min_x: minimum horizontal device coordinate |
144 | + * @min_y: minimum vertical device coordinate |
145 | + * @max_x: maximum horizontal device coordinate |
146 | + * @max_y: maximum vertical device coordinate |
147 | + * @max_pressure: maximum pressure device coordinate |
148 | + * @max_orient: maximum orientation device coordinate |
149 | + * @mapped_min_x: minimum horizontal mapped coordinate |
150 | + * @mapped_min_y: minimum vertical mapped coordinate |
151 | + * @mapped_max_x: maximum horizontal mapped coordinate |
152 | + * @mapped_max_y: maximum vertical mapped coordinate |
153 | + * @mapped_max_pressure: maximum pressure mapped coordinate |
154 | + * |
155 | + * The mutable contact given by utouch_frame_get_current_slot() should |
156 | + * be set in device coordinates. The contact data is subsequently |
157 | + * transformed to mapped (e.g., screen) coordinates in |
158 | + * utouch_frame_sync(). To a frame user, all data will appear in |
159 | + * mapped coordinates. |
160 | * |
161 | * Device properties and touch surface details. Later versions of this |
162 | * struct may grow in size, but will remain binary compatible with |
163 | @@ -72,6 +88,12 @@ |
164 | float max_x; |
165 | float max_y; |
166 | float max_pressure; |
167 | + float max_orient; |
168 | + float mapped_min_x; |
169 | + float mapped_min_y; |
170 | + float mapped_max_x; |
171 | + float mapped_max_y; |
172 | + float mapped_max_pressure; |
173 | }; |
174 | |
175 | #define UTOUCH_TOOL_FINGER 0 |
176 | @@ -93,6 +115,8 @@ |
177 | * @orientation: direction of ellipse (left: -Pi/2, up: 0, right: Pi/2) |
178 | * @pressure: pressure of contact (pressure units) |
179 | * @distance: distance of contact (surface units) |
180 | + * @vx: horizontal velocity coordinate (units / millisecond) |
181 | + * @vy: vertical velocity coordinate (units / millisecond) |
182 | * |
183 | * Surface contact details. Later versions of this struct may grow in |
184 | * size, but will remain binary compatible with older versions. |
185 | @@ -116,6 +140,8 @@ |
186 | float orientation; |
187 | float pressure; |
188 | float distance; |
189 | + float vx; |
190 | + float vy; |
191 | }; |
192 | |
193 | /* time in milliseconds */ |
194 | @@ -163,6 +189,20 @@ |
195 | */ |
196 | unsigned int utouch_frame_get_version(void); |
197 | |
198 | +/** |
199 | + * utouch_frame_get_num_frames - get number of supported frames |
200 | + * |
201 | + * Returns the number of frames supported by this engine. |
202 | + */ |
203 | +unsigned int utouch_frame_get_num_frames(utouch_frame_handle fh); |
204 | + |
205 | +/** |
206 | + * utouch_frame_get_num_slots - get number of supported slots |
207 | + * |
208 | + * Returns the number of simultaneous contacts supported by this engine. |
209 | + */ |
210 | +unsigned int utouch_frame_get_num_slots(utouch_frame_handle fh); |
211 | + |
212 | utouch_frame_handle utouch_frame_new_engine_raw(unsigned int num_frames, |
213 | unsigned int num_slots, |
214 | unsigned int frame_rate, |
215 | @@ -228,6 +268,17 @@ |
216 | int utouch_frame_set_current_slot(utouch_frame_handle fh, int slot); |
217 | |
218 | /** |
219 | + * utouch_frame_set_current_id - set the current slot by touch id |
220 | + * @fh: the frame engine in use |
221 | + * @id: the touch id |
222 | + * |
223 | + * Sets the slot currently being modified, by touch id. If the id is |
224 | + * not currently in use (does not have an active slot), a new slot is |
225 | + * assigned. Returns zero if successful, negative error otherwise. |
226 | + */ |
227 | +int utouch_frame_set_current_id(utouch_frame_handle fh, int id); |
228 | + |
229 | +/** |
230 | * utouch_frame_sync - synchronize and return new frame |
231 | * @fh: the frame engine in use |
232 | * @time: the frame synchronization time (ms) |
233 | @@ -247,4 +298,8 @@ |
234 | const struct utouch_frame *utouch_frame_sync(utouch_frame_handle fh, |
235 | utouch_frame_time_t time); |
236 | |
237 | +#ifdef __cplusplus |
238 | +} |
239 | +#endif |
240 | + |
241 | #endif |
242 | |
243 | === modified file 'src/Makefile.am' |
244 | --- src/Makefile.am 2010-12-30 19:23:24 +0000 |
245 | +++ src/Makefile.am 2011-02-21 12:19:53 +0000 |
246 | @@ -3,7 +3,7 @@ |
247 | libutouch_frame_la_LDFLAGS = \ |
248 | -version-info @LIB_VERSION@ \ |
249 | -lm \ |
250 | - $(EVEMU_LIBS) |
251 | + $(EVEMU_LIBS) \ |
252 | $(MTDEV_LIBS) |
253 | |
254 | libutouch_frame_la_SOURCES = \ |
255 | @@ -19,3 +19,11 @@ |
256 | libutouch_frameinclude_HEADERS = \ |
257 | $(top_srcdir)/include/utouch/frame.h \ |
258 | $(top_srcdir)/include/utouch/frame-mtdev.h |
259 | + |
260 | +if HAVE_XI |
261 | + |
262 | +libutouch_frame_la_LDFLAGS += $(XINPUT_LIBS) $(X11_LIBS) |
263 | +libutouch_frame_la_SOURCES += frame-xi2.c |
264 | +libutouch_frameinclude_HEADERS += $(top_srcdir)/include/utouch/frame-xi2.h |
265 | + |
266 | +endif |
267 | |
268 | === modified file 'src/frame-impl.h' |
269 | --- src/frame-impl.h 2011-02-03 16:12:20 +0000 |
270 | +++ src/frame-impl.h 2011-02-21 12:19:53 +0000 |
271 | @@ -30,10 +30,11 @@ |
272 | int hold_ms; |
273 | int frame; |
274 | int slot; |
275 | - float max_orient; |
276 | struct utouch_surface *surface; |
277 | struct utouch_frame **frames; |
278 | struct utouch_frame *next; |
279 | + int *evmap; |
280 | + float map[9]; |
281 | }; |
282 | |
283 | #endif |
284 | |
285 | === modified file 'src/frame-mtdev.c' |
286 | --- src/frame-mtdev.c 2011-02-08 18:24:27 +0000 |
287 | +++ src/frame-mtdev.c 2011-02-21 12:19:53 +0000 |
288 | @@ -104,12 +104,12 @@ |
289 | } |
290 | |
291 | s->max_pressure = evemu_get_abs_maximum(dev, ABS_MT_PRESSURE); |
292 | - if (s->use_pressure && s->max_pressure == 0) |
293 | + if (s->max_pressure == 0) |
294 | s->max_pressure = 256; |
295 | |
296 | - fh->max_orient = evemu_get_abs_maximum(dev, ABS_MT_ORIENTATION); |
297 | - if (s->use_orientation && fh->max_orient == 0) |
298 | - fh->max_orient = 1; |
299 | + s->max_orient = evemu_get_abs_maximum(dev, ABS_MT_ORIENTATION); |
300 | + if (s->max_orient == 0) |
301 | + s->max_orient = 1; |
302 | |
303 | tmp = evemu_get_abs_resolution(dev, ABS_MT_POSITION_X); |
304 | if (tmp > 0) |
305 | @@ -133,14 +133,16 @@ |
306 | else |
307 | s->phys_pressure = 10; |
308 | |
309 | + /* defaults expected by initial frame version */ |
310 | + s->mapped_min_x = s->min_x; |
311 | + s->mapped_min_y = s->min_y; |
312 | + s->mapped_max_x = s->max_x; |
313 | + s->mapped_max_y = s->max_y; |
314 | + s->mapped_max_pressure = s->max_pressure; |
315 | + |
316 | return 0; |
317 | } |
318 | |
319 | -static float touch_angle(utouch_frame_handle fh, int orient) |
320 | -{ |
321 | - return orient / fh->max_orient * M_PI_2; |
322 | -} |
323 | - |
324 | static int handle_abs_event(utouch_frame_handle fh, |
325 | const struct input_event *ev) |
326 | { |
327 | @@ -152,9 +154,11 @@ |
328 | return 1; |
329 | case ABS_MT_POSITION_X: |
330 | t->x = ev->value; |
331 | + t->vx = 0; |
332 | return 1; |
333 | case ABS_MT_POSITION_Y: |
334 | t->y = ev->value; |
335 | + t->vy = 0; |
336 | return 1; |
337 | case ABS_MT_TOUCH_MAJOR: |
338 | t->touch_major = ev->value; |
339 | @@ -169,7 +173,7 @@ |
340 | t->width_minor = ev->value; |
341 | return 1; |
342 | case ABS_MT_ORIENTATION: |
343 | - t->orientation = touch_angle(fh, ev->value); |
344 | + t->orientation = ev->value; |
345 | return 1; |
346 | case ABS_MT_PRESSURE: |
347 | t->pressure = ev->value; |
348 | |
349 | === added file 'src/frame-xi2.c' |
350 | --- src/frame-xi2.c 1970-01-01 00:00:00 +0000 |
351 | +++ src/frame-xi2.c 2011-02-21 12:19:53 +0000 |
352 | @@ -0,0 +1,304 @@ |
353 | +/***************************************************************************** |
354 | + * |
355 | + * utouch-frame - Touch Frame Library |
356 | + * |
357 | + * Copyright (C) 2010 Canonical Ltd. |
358 | + * |
359 | + * This program is free software: you can redistribute it and/or modify it |
360 | + * under the terms of the GNU General Public License as published by the |
361 | + * Free Software Foundation, either version 3 of the License, or (at your |
362 | + * option) any later version. |
363 | + * |
364 | + * This program is distributed in the hope that it will be useful, but |
365 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
366 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
367 | + * General Public License for more details. |
368 | + * |
369 | + * You should have received a copy of the GNU General Public License along |
370 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
371 | + * |
372 | + ****************************************************************************/ |
373 | +#include <utouch/frame-xi2.h> |
374 | +#include <xorg/xserver-properties.h> |
375 | +#include <linux/input.h> |
376 | +#include "frame-impl.h" |
377 | +#include <stdlib.h> |
378 | +#include <stdio.h> |
379 | +#include <errno.h> |
380 | +#include <math.h> |
381 | +#include <string.h> |
382 | +#include <X11/Xlib.h> |
383 | + |
384 | +static Atom transform_atom; |
385 | + |
386 | +#define set_field(fh, name, number, field) \ |
387 | + if (!strcmp(name, AXIS_LABEL_PROP_##field) && \ |
388 | + (fh->evmap[number] = field)) |
389 | + |
390 | +int utouch_frame_is_supported_xi2(Display *dpy, const XIDeviceInfo *dev) |
391 | +{ |
392 | + |
393 | + int i; |
394 | + |
395 | + for (i = 0; i < dev->num_classes; i++) |
396 | + if (dev->classes[i]->type == XITouchClass) |
397 | + return 1; |
398 | + |
399 | + return 0; |
400 | +} |
401 | + |
402 | +static void init_properties(utouch_frame_handle fh, |
403 | + Display *dpy, const XIDeviceInfo *dev) |
404 | +{ |
405 | + struct utouch_surface *s = fh->surface; |
406 | + XITouchClassInfo *v; |
407 | + int i; |
408 | + |
409 | + for (i = 0; i < dev->num_classes; i++) { |
410 | + v = (void *)dev->classes[i]; |
411 | + if (v->type != XITouchClass) |
412 | + continue; |
413 | + switch(v->mode) { |
414 | + case XIDependentTouch: |
415 | + s->needs_pointer = 1; |
416 | + break; |
417 | + case XIDirectTouch: |
418 | + s->is_direct = 1; |
419 | + break; |
420 | + default: |
421 | + fprintf(stderr, "unknown mode\n"); |
422 | + break; |
423 | + } |
424 | + } |
425 | + |
426 | + if (transform_atom == None) |
427 | + transform_atom = XInternAtom(dpy, XI_PROP_TRANSFORM, True); |
428 | + |
429 | + fh->map[0] = fh->map[4] = fh->map[8] = 1; |
430 | +} |
431 | + |
432 | +static void update_transform(utouch_frame_handle fh, Display *dpy, int devid) |
433 | +{ |
434 | + unsigned long nitem, nbyte; |
435 | + unsigned char *data; |
436 | + int format; |
437 | + Atom type; |
438 | + |
439 | + if (transform_atom == None) |
440 | + return; |
441 | + |
442 | + XIGetProperty(dpy, devid, transform_atom, 0, 9, False, |
443 | + AnyPropertyType, &type, &format, &nitem, &nbyte, &data); |
444 | + |
445 | + if (format == 32 && nitem == 9 && nbyte == 0) |
446 | + memcpy(fh->map, data, sizeof(fh->map)); |
447 | + else |
448 | + fprintf(stderr, "Invalid transform matrix\n"); |
449 | + |
450 | + XFree(data); |
451 | +} |
452 | + |
453 | +static void update_screen(utouch_frame_handle fh, Display *dpy) |
454 | +{ |
455 | + struct utouch_surface *s = fh->surface; |
456 | + XWindowAttributes attrs; |
457 | + float x1, y1, x2, y2; |
458 | + |
459 | + XGetWindowAttributes(dpy, XDefaultRootWindow(dpy), &attrs); |
460 | + |
461 | + x1 = 0; |
462 | + y1 = 0; |
463 | + x2 = attrs.width; |
464 | + y2 = attrs.height; |
465 | + |
466 | + s->mapped_min_x = fh->map[0] * x1 + fh->map[1] * y1 + fh->map[2]; |
467 | + s->mapped_min_y = fh->map[3] * x1 + fh->map[4] * y1 + fh->map[5]; |
468 | + s->mapped_max_x = fh->map[0] * x2 + fh->map[1] * y2 + fh->map[2]; |
469 | + s->mapped_max_y = fh->map[3] * x2 + fh->map[4] * y2 + fh->map[5]; |
470 | + s->mapped_max_pressure = 1; |
471 | + |
472 | + fprintf(stderr, "frame map: %f %f %f %f %f\n", |
473 | + s->mapped_min_x, s->mapped_min_y, |
474 | + s->mapped_max_x, s->mapped_max_y, s->mapped_max_pressure); |
475 | +} |
476 | + |
477 | +static void init_valuators(utouch_frame_handle fh, |
478 | + Display *dpy, const XIDeviceInfo *dev) |
479 | +{ |
480 | + struct utouch_surface *s = fh->surface; |
481 | + XITouchValuatorClassInfo *v; |
482 | + char *name; |
483 | + int i; |
484 | + |
485 | + s->phys_width = 100; |
486 | + s->phys_height = 65; |
487 | + s->phys_pressure = 10; |
488 | + s->max_x = 1024; |
489 | + s->max_y = 768; |
490 | + s->max_pressure = 256; |
491 | + s->max_orient = 1; |
492 | + |
493 | + for (i = 0; i < dev->num_classes; i++) { |
494 | + v = (void *)dev->classes[i]; |
495 | + if (v->type != XITouchValuatorClass) |
496 | + continue; |
497 | + name = XGetAtomName(dpy, v->label); |
498 | + set_field(fh, name, v->number, ABS_MT_POSITION_X) { |
499 | + s->min_x = v->min; |
500 | + s->max_x = v->max; |
501 | + if (v->resolution > 0) |
502 | + s->phys_width = (v->max - v->min) / |
503 | + v->resolution; |
504 | + } |
505 | + set_field(fh, name, v->number, ABS_MT_POSITION_Y) { |
506 | + s->min_y = v->min; |
507 | + s->max_y = v->max; |
508 | + if (v->resolution > 0) |
509 | + s->phys_height = (v->max - v->min) / |
510 | + v->resolution; |
511 | + } |
512 | + set_field(fh, name, v->number, ABS_MT_TOUCH_MAJOR) { |
513 | + s->use_touch_major = 1; |
514 | + } |
515 | + set_field(fh, name, v->number, ABS_MT_TOUCH_MINOR) { |
516 | + s->use_touch_minor = 1; |
517 | + } |
518 | + set_field(fh, name, v->number, ABS_MT_WIDTH_MAJOR) { |
519 | + s->use_width_major = 1; |
520 | + } |
521 | + set_field(fh, name, v->number, ABS_MT_WIDTH_MINOR) { |
522 | + s->use_width_minor = 1; |
523 | + } |
524 | + set_field(fh, name, v->number, ABS_MT_ORIENTATION) { |
525 | + s->use_orientation = 1; |
526 | + s->max_orient = v->max > 0 ? v->max : 1; |
527 | + } |
528 | + set_field(fh, name, v->number, ABS_MT_PRESSURE) { |
529 | + s->use_pressure = 1; |
530 | + s->max_pressure = v->max > 0 ? v->max : 256; |
531 | + if (v->resolution > 0) |
532 | + s->phys_pressure = v->max / v->resolution; |
533 | + } |
534 | +#if 0 |
535 | + set_field(fh, name, v->number, ABS_MT_DISTANCE) { |
536 | + s->use_distance = 1; |
537 | + } |
538 | +#endif |
539 | + XFree(name); |
540 | + } |
541 | +} |
542 | + |
543 | +int utouch_frame_init_xi2(utouch_frame_handle fh, |
544 | + Display *dpy, const XIDeviceInfo *dev) |
545 | +{ |
546 | + int event; |
547 | + int err; |
548 | + |
549 | + free(fh->evmap); |
550 | + fh->evmap =calloc(dev->num_classes, sizeof(int)); |
551 | + if (!fh->evmap) |
552 | + return -ENOMEM; |
553 | + |
554 | + if (!utouch_frame_is_supported_xi2(dpy, dev)) |
555 | + return -ENODEV; |
556 | + |
557 | + init_properties(fh, dpy, dev); |
558 | + init_valuators(fh, dpy, dev); |
559 | + update_transform(fh, dpy, dev->deviceid); |
560 | + update_screen(fh, dpy); |
561 | + |
562 | + return 0; |
563 | +} |
564 | + |
565 | +static int handle_event(utouch_frame_handle fh, |
566 | + struct utouch_contact *slot, |
567 | + int ix, float value) |
568 | +{ |
569 | + switch (fh->evmap[ix]) { |
570 | + case ABS_MT_POSITION_X: |
571 | + slot->x = value; |
572 | + slot->vx = 0; |
573 | + return 1; |
574 | + case ABS_MT_POSITION_Y: |
575 | + slot->y = value; |
576 | + slot->vy = 0; |
577 | + return 1; |
578 | + case ABS_MT_TOUCH_MAJOR: |
579 | + slot->touch_major = value; |
580 | + return 1; |
581 | + case ABS_MT_TOUCH_MINOR: |
582 | + slot->touch_minor = value; |
583 | + return 1; |
584 | + case ABS_MT_WIDTH_MAJOR: |
585 | + slot->width_major = value; |
586 | + return 1; |
587 | + case ABS_MT_WIDTH_MINOR: |
588 | + slot->width_minor = value; |
589 | + return 1; |
590 | + case ABS_MT_ORIENTATION: |
591 | + slot->orientation = value; |
592 | + return 1; |
593 | + case ABS_MT_PRESSURE: |
594 | + slot->pressure = value; |
595 | + return 1; |
596 | +#ifdef ABS_MT_DISTANCE |
597 | + case ABS_MT_DISTANCE: |
598 | + slot->distance = value; |
599 | + return 1; |
600 | +#endif |
601 | + case ABS_MT_TOOL_TYPE: |
602 | + slot->tool_type = value; |
603 | + return 1; |
604 | + default: |
605 | + fprintf(stderr, "did not get that one: %d\n", ix); |
606 | + return 0; |
607 | + } |
608 | +} |
609 | + |
610 | +int utouch_frame_configure_xi2(utouch_frame_handle fh, |
611 | + const XConfigureEvent *ev) |
612 | +{ |
613 | + if (ev->display) |
614 | + update_screen(fh, ev->display); |
615 | + return 1; |
616 | +} |
617 | + |
618 | +const struct utouch_frame * |
619 | +utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev) |
620 | +{ |
621 | + const XIPropertyEvent *prop_ev; |
622 | + const double *value; |
623 | + const unsigned char *mask; |
624 | + struct utouch_contact *slot; |
625 | + int touchid, nbyte, nbit, num, i; |
626 | + |
627 | + switch (ev->evtype) { |
628 | + case XI_TouchBegin: |
629 | + case XI_TouchUpdate: |
630 | + case XI_TouchEnd: |
631 | + value = ev->valuators.values; |
632 | + mask = ev->valuators.mask; |
633 | + touchid = ev->detail; |
634 | + nbyte = ev->valuators.mask_len; |
635 | + nbit = nbyte << 3; |
636 | + |
637 | + utouch_frame_set_current_id(fh, touchid); |
638 | + slot = utouch_frame_get_current_slot(fh); |
639 | + num = 0; |
640 | + for (i = 0; i < nbit; i++) |
641 | + if (XIMaskIsSet(mask, i)) |
642 | + handle_event(fh, slot, i, value[num++]); |
643 | + if (ev->evtype == XI_TouchEnd) |
644 | + utouch_frame_get_current_slot(fh)->id = -1; |
645 | + return utouch_frame_sync(fh, ev->time); |
646 | + case XI_PropertyEvent: |
647 | + prop_ev = (XIPropertyEvent *)ev; |
648 | + if (prop_ev->property == transform_atom && ev->display) { |
649 | + update_transform(fh, ev->display, ev->deviceid); |
650 | + update_screen(fh, ev->display); |
651 | + } |
652 | + break; |
653 | + } |
654 | + |
655 | + return 0; |
656 | +} |
657 | |
658 | === modified file 'src/frame.c' |
659 | --- src/frame.c 2010-12-30 19:23:24 +0000 |
660 | +++ src/frame.c 2011-02-21 12:19:53 +0000 |
661 | @@ -33,6 +33,16 @@ |
662 | return UTOUCH_FRAME_VERSION; |
663 | } |
664 | |
665 | +unsigned int utouch_frame_get_num_frames(utouch_frame_handle fh) |
666 | +{ |
667 | + return fh->num_frames; |
668 | +} |
669 | + |
670 | +unsigned int utouch_frame_get_num_slots(utouch_frame_handle fh) |
671 | +{ |
672 | + return fh->num_slots; |
673 | +} |
674 | + |
675 | static void destroy_slots(struct utouch_contact **slots, int nslot) |
676 | { |
677 | int i; |
678 | @@ -181,6 +191,7 @@ |
679 | |
680 | void utouch_frame_delete_engine(utouch_frame_handle fh) |
681 | { |
682 | + free(fh->evmap); |
683 | destroy_frame(fh->next, fh->num_slots); |
684 | destroy_frames(fh->frames, fh->num_frames, fh->num_slots); |
685 | free(fh->surface); |
686 | @@ -205,11 +216,53 @@ |
687 | return 0; |
688 | } |
689 | |
690 | -static void copy_contact(utouch_frame_handle fh, |
691 | - struct utouch_contact *a, |
692 | - const struct utouch_contact *b) |
693 | -{ |
694 | +int utouch_frame_set_current_id(utouch_frame_handle fh, int id) |
695 | +{ |
696 | + struct utouch_contact *t; |
697 | + int i; |
698 | + |
699 | + for (i = 0; i < fh->num_slots; i++) { |
700 | + t = fh->next->slots[i]; |
701 | + if (t->id == id) |
702 | + return utouch_frame_set_current_slot(fh, i); |
703 | + } |
704 | + for (i = 0; i < fh->num_slots; i++) { |
705 | + t = fh->next->slots[i]; |
706 | + if (t->id < 0) { |
707 | + t->id = id; |
708 | + return utouch_frame_set_current_slot(fh, i); |
709 | + } |
710 | + } |
711 | + return -ENOMEM; |
712 | +} |
713 | + |
714 | +static void transform_slot(struct utouch_contact *slot, |
715 | + const struct utouch_surface *s) |
716 | +{ |
717 | + float fx = (s->mapped_max_x - s->mapped_min_x) / (s->max_x - s->min_x); |
718 | + float fy = (s->mapped_max_y - s->mapped_min_y) / (s->max_y - s->min_y); |
719 | + /* assume clipped view for asymmetrical scaling */ |
720 | + float f = MAX(fx, fy); |
721 | + |
722 | + slot->x = fx * (slot->x - s->min_x) + s->mapped_min_x; |
723 | + slot->y = fy * (slot->y - s->min_y) + s->mapped_min_y; |
724 | + slot->touch_major *= f; |
725 | + slot->touch_minor *= f; |
726 | + slot->width_major *= f; |
727 | + slot->width_minor *= f; |
728 | + slot->orientation *= M_PI_2 / s->max_orient; |
729 | + slot->pressure *= s->mapped_max_pressure / s->max_pressure; |
730 | + slot->distance *= f; |
731 | +} |
732 | + |
733 | +static void set_contact(utouch_frame_handle fh, |
734 | + struct utouch_contact *a, |
735 | + struct utouch_contact *b, |
736 | + utouch_frame_time_t dt) |
737 | +{ |
738 | + static const float D = 0.333; |
739 | struct utouch_surface *s = fh->surface; |
740 | + const struct utouch_contact *ap = a->prev; |
741 | |
742 | a->active = b->id != -1; |
743 | a->id = b->id; |
744 | @@ -225,6 +278,23 @@ |
745 | a->orientation = b->orientation; |
746 | a->pressure = b->pressure; |
747 | a->distance = b->distance; |
748 | + |
749 | + transform_slot(a, s); |
750 | + |
751 | + if (a->active && ap->active && a->id == ap->id) { |
752 | + a->x += b->vx * dt; |
753 | + a->y += b->vy * dt; |
754 | + if (dt > 0) { |
755 | + a->vx = (1 - D) * ap->vx + D * (a->x - ap->x) / dt; |
756 | + a->vy = (1 - D) * ap->vy + D * (a->y - ap->y) / dt; |
757 | + } |
758 | + } else { |
759 | + a->vx = 0; |
760 | + a->vy = 0; |
761 | + } |
762 | + |
763 | + b->vx = a->vx; |
764 | + b->vy = a->vy; |
765 | } |
766 | |
767 | static int detect_addrem(const struct utouch_contact *a, |
768 | @@ -261,14 +331,18 @@ |
769 | const struct utouch_frame *prev = frame->prev; |
770 | struct utouch_frame *next = fh->next; |
771 | int naddrem = 0, nmod = 0; |
772 | + utouch_frame_time_t dt; |
773 | int i; |
774 | |
775 | + frame->time = time ? time : get_time_ms(); |
776 | frame->num_active = 0; |
777 | + dt = frame->time - prev->time; |
778 | + |
779 | for (i = 0; i < fh->num_slots; i++) { |
780 | struct utouch_contact *p = frame->slots[i]; |
781 | - const struct utouch_contact *q = next->slots[i]; |
782 | + struct utouch_contact *q = next->slots[i]; |
783 | |
784 | - copy_contact(fh, p, q); |
785 | + set_contact(fh, p, q, dt); |
786 | if (p->active) |
787 | frame->active[frame->num_active++] = p; |
788 | |
789 | @@ -278,7 +352,6 @@ |
790 | if (naddrem + nmod == 0) |
791 | return 0; |
792 | |
793 | - frame->time = time ? time : get_time_ms(); |
794 | if (naddrem == 0 && frame->time < prev->time + fh->hold_ms) |
795 | return 0; |
796 | |
797 | |
798 | === modified file 'tools/Makefile.am' |
799 | --- tools/Makefile.am 2011-02-03 16:07:34 +0000 |
800 | +++ tools/Makefile.am 2011-02-21 12:19:53 +0000 |
801 | @@ -2,10 +2,22 @@ |
802 | |
803 | INCLUDES=-I$(top_srcdir)/include/ |
804 | |
805 | -utouch_frame_test_mtdev_SOURCES = utouch-frame-test-mtdev.c |
806 | +utouch_frame_test_mtdev_SOURCES = common-defs.h utouch-frame-test-mtdev.c |
807 | utouch_frame_test_mtdev_LDFLAGS = -L$(top_builddir)/src/.libs/ \ |
808 | -lutouch-frame -lutouch-evemu -lmtdev -lm |
809 | |
810 | +if HAVE_XI |
811 | + |
812 | +AM_CFLAGS = $(XINPUT_CFLAGS) |
813 | + |
814 | +bin_PROGRAMS += utouch-frame-test-xi2 |
815 | + |
816 | +utouch_frame_test_xi2_SOURCES = common-defs.h utouch-frame-test-xi2.c |
817 | +utouch_frame_test_xi2_LDFLAGS = $(XINPUT_LIBS) $(X11_LIBS) \ |
818 | + -L$(top_builddir)/src/.libs/ -lutouch-frame |
819 | + |
820 | +endif |
821 | + |
822 | if HAVE_DOCTOOLS |
823 | dist_man_MANS = utouch-frame-test-mtdev.1 |
824 | |
825 | |
826 | === added file 'tools/common-defs.h' |
827 | --- tools/common-defs.h 1970-01-01 00:00:00 +0000 |
828 | +++ tools/common-defs.h 2011-02-21 12:19:53 +0000 |
829 | @@ -0,0 +1,85 @@ |
830 | +/***************************************************************************** |
831 | + * |
832 | + * utouch-frame - Touch Frame Library |
833 | + * |
834 | + * Copyright (C) 2010-2011 Canonical Ltd. |
835 | + * |
836 | + * This program is free software: you can redistribute it and/or modify it |
837 | + * under the terms of the GNU General Public License as published by the |
838 | + * Free Software Foundation, either version 3 of the License, or (at your |
839 | + * option) any later version. |
840 | + * |
841 | + * This program is distributed in the hope that it will be useful, but |
842 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
843 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
844 | + * General Public License for more details. |
845 | + * |
846 | + * You should have received a copy of the GNU General Public License along |
847 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
848 | + * |
849 | + * Authors: |
850 | + * Henrik Rydberg <rydberg@bitmath.org> |
851 | + * |
852 | + ****************************************************************************/ |
853 | + |
854 | +static void report_device_caps(utouch_frame_handle fh) |
855 | +{ |
856 | + const struct utouch_surface *s = utouch_frame_get_surface(fh); |
857 | + |
858 | + fprintf(stderr, "device props:\n"); |
859 | + if (s->needs_pointer) |
860 | + fprintf(stderr, "\tpointer\n"); |
861 | + if (s->is_direct) |
862 | + fprintf(stderr, "\tdirect\n"); |
863 | + if (s->is_buttonpad) |
864 | + fprintf(stderr, "\tbuttonpad\n"); |
865 | + if (s->is_semi_mt) |
866 | + fprintf(stderr, "\tsemi_mt\n"); |
867 | + fprintf(stderr, "device mt events:\n"); |
868 | + if (s->use_touch_major) |
869 | + fprintf(stderr, "\ttouch_major\n"); |
870 | + if (s->use_touch_minor) |
871 | + fprintf(stderr, "\ttouch_minor\n"); |
872 | + if (s->use_width_major) |
873 | + fprintf(stderr, "\twidth_major\n"); |
874 | + if (s->use_width_minor) |
875 | + fprintf(stderr, "\twidth_minor\n"); |
876 | + if (s->use_orientation) |
877 | + fprintf(stderr, "\torientation\n"); |
878 | + if (s->use_pressure) |
879 | + fprintf(stderr, "\tpressure\n"); |
880 | + if (s->use_distance) |
881 | + fprintf(stderr, "\tdistance\n"); |
882 | +} |
883 | + |
884 | +static void report_frame(const struct utouch_frame *frame) |
885 | +{ |
886 | + int i; |
887 | + |
888 | + for (i = 0; i < frame->num_active; i++) { |
889 | + const struct utouch_contact *t = frame->active[i]; |
890 | + |
891 | + fprintf(stderr, "touch %d\n", i); |
892 | + fprintf(stderr, " slot: %d\n", t->slot); |
893 | + fprintf(stderr, " id: %d\n", t->id); |
894 | + fprintf(stderr, " tool_type: %d\n", t->tool_type); |
895 | + fprintf(stderr, " x: %f\n", t->x); |
896 | + fprintf(stderr, " y: %f\n", t->y); |
897 | + fprintf(stderr, " touch_major: %f\n", t->touch_major); |
898 | + fprintf(stderr, " touch_minor: %f\n", t->touch_minor); |
899 | + fprintf(stderr, " width_major: %f\n", t->width_major); |
900 | + fprintf(stderr, " width_minor: %f\n", t->width_minor); |
901 | + fprintf(stderr, " angle: %f\n", t->orientation); |
902 | + fprintf(stderr, " pressure: %f\n", t->pressure); |
903 | + fprintf(stderr, " distance: %f\n", t->distance); |
904 | + fprintf(stderr, " vx: %f\n", t->vx); |
905 | + fprintf(stderr, " vy: %f\n", t->vy); |
906 | + } |
907 | + |
908 | + fprintf(stderr, "sync %d %ld %d %d %d\n", |
909 | + frame->num_active, |
910 | + frame->time, |
911 | + frame->sequence_id, |
912 | + frame->revision, |
913 | + frame->slot_revision); |
914 | +} |
915 | |
916 | === modified file 'tools/utouch-frame-test-mtdev.c' |
917 | --- tools/utouch-frame-test-mtdev.c 2011-02-08 18:28:09 +0000 |
918 | +++ tools/utouch-frame-test-mtdev.c 2011-02-21 12:19:53 +0000 |
919 | @@ -30,6 +30,7 @@ |
920 | #include <stdio.h> |
921 | #include <unistd.h> |
922 | #include <fcntl.h> |
923 | +#include "common-defs.h" |
924 | |
925 | struct frame_test { |
926 | struct evemu_device *evemu; |
927 | @@ -69,36 +70,6 @@ |
928 | memset(test, 0, sizeof(*test)); |
929 | } |
930 | |
931 | -static void report_frame(const struct utouch_frame *frame) |
932 | -{ |
933 | - int i; |
934 | - |
935 | - for (i = 0; i < frame->num_active; i++) { |
936 | - const struct utouch_contact *t = frame->active[i]; |
937 | - |
938 | - fprintf(stderr, "touch %d\n", i); |
939 | - fprintf(stderr, " slot: %d\n", t->slot); |
940 | - fprintf(stderr, " id: %d\n", t->id); |
941 | - fprintf(stderr, " tool_type: %d\n", t->tool_type); |
942 | - fprintf(stderr, " x: %f\n", t->x); |
943 | - fprintf(stderr, " y: %f\n", t->y); |
944 | - fprintf(stderr, " touch_major: %f\n", t->touch_major); |
945 | - fprintf(stderr, " touch_minor: %f\n", t->touch_minor); |
946 | - fprintf(stderr, " width_major: %f\n", t->width_major); |
947 | - fprintf(stderr, " width_minor: %f\n", t->width_minor); |
948 | - fprintf(stderr, " angle: %f\n", t->orientation); |
949 | - fprintf(stderr, " pressure: %f\n", t->pressure); |
950 | - fprintf(stderr, " distance: %f\n", t->distance); |
951 | - } |
952 | - |
953 | - fprintf(stderr, "sync %d %ld %d %d %d\n", |
954 | - frame->num_active, |
955 | - frame->time, |
956 | - frame->sequence_id, |
957 | - frame->revision, |
958 | - frame->slot_revision); |
959 | -} |
960 | - |
961 | static void loop_device(struct frame_test *test, int fd) |
962 | { |
963 | const struct utouch_frame *frame; |
964 | @@ -113,35 +84,6 @@ |
965 | } |
966 | } |
967 | |
968 | -static void report_device_caps(struct frame_test *test) |
969 | -{ |
970 | - struct utouch_surface *s = utouch_frame_get_surface(test->fh); |
971 | - fprintf(stderr, "device props:\n"); |
972 | - if (s->needs_pointer) |
973 | - fprintf(stderr, "\tpointer\n"); |
974 | - if (s->is_direct) |
975 | - fprintf(stderr, "\tdirect\n"); |
976 | - if (s->is_buttonpad) |
977 | - fprintf(stderr, "\tbuttonpad\n"); |
978 | - if (s->is_semi_mt) |
979 | - fprintf(stderr, "\tsemi_mt\n"); |
980 | - fprintf(stderr, "device mt events:\n"); |
981 | - if (s->use_touch_major) |
982 | - fprintf(stderr, "\ttouch_major\n"); |
983 | - if (s->use_touch_minor) |
984 | - fprintf(stderr, "\ttouch_minor\n"); |
985 | - if (s->use_width_major) |
986 | - fprintf(stderr, "\twidth_major\n"); |
987 | - if (s->use_width_minor) |
988 | - fprintf(stderr, "\twidth_minor\n"); |
989 | - if (s->use_orientation) |
990 | - fprintf(stderr, "\torientation\n"); |
991 | - if (s->use_pressure) |
992 | - fprintf(stderr, "\tpressure\n"); |
993 | - if (s->use_distance) |
994 | - fprintf(stderr, "\tdistance\n"); |
995 | -} |
996 | - |
997 | int main(int argc, char *argv[]) |
998 | { |
999 | struct frame_test test; |
1000 | @@ -182,7 +124,7 @@ |
1001 | return -1; |
1002 | } |
1003 | |
1004 | - report_device_caps(&test); |
1005 | + report_device_caps(test.fh); |
1006 | |
1007 | loop_device(&test, fd); |
1008 | |
1009 | |
1010 | === added file 'tools/utouch-frame-test-xi2.c' |
1011 | --- tools/utouch-frame-test-xi2.c 1970-01-01 00:00:00 +0000 |
1012 | +++ tools/utouch-frame-test-xi2.c 2011-02-21 12:19:53 +0000 |
1013 | @@ -0,0 +1,177 @@ |
1014 | +/***************************************************************************** |
1015 | + * |
1016 | + * utouch-frame - Touch Frame Library |
1017 | + * |
1018 | + * Copyright (C) 2010-2011 Canonical Ltd. |
1019 | + * |
1020 | + * This program is free software: you can redistribute it and/or modify it |
1021 | + * under the terms of the GNU General Public License as published by the |
1022 | + * Free Software Foundation, either version 3 of the License, or (at your |
1023 | + * option) any later version. |
1024 | + * |
1025 | + * This program is distributed in the hope that it will be useful, but |
1026 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
1027 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1028 | + * General Public License for more details. |
1029 | + * |
1030 | + * You should have received a copy of the GNU General Public License along |
1031 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1032 | + * |
1033 | + * Authors: |
1034 | + * Henrik Rydberg <rydberg@bitmath.org> |
1035 | + * |
1036 | + ****************************************************************************/ |
1037 | + |
1038 | +#define MTDEV_NO_LEGACY_API |
1039 | + |
1040 | +#include <utouch/frame-xi2.h> |
1041 | +#include <string.h> |
1042 | +#include <stdio.h> |
1043 | +#include <unistd.h> |
1044 | +#include <fcntl.h> |
1045 | +#include <stdlib.h> |
1046 | +#include "common-defs.h" |
1047 | + |
1048 | +static int opcode; |
1049 | + |
1050 | +struct frame_test { |
1051 | + Display *display; |
1052 | + Window root, win; |
1053 | + XIDeviceInfo *info, *dev; |
1054 | + utouch_frame_handle fh; |
1055 | +}; |
1056 | + |
1057 | +static int init_xi2(struct frame_test *test, int id) |
1058 | +{ |
1059 | + Display *dpy; |
1060 | + int ndevices, i; |
1061 | + int event, error; |
1062 | + |
1063 | + dpy = XOpenDisplay(NULL); |
1064 | + if (!dpy) |
1065 | + return -1; |
1066 | + |
1067 | + if (!XQueryExtension(dpy, "XInputExtension", &opcode, &event, &error)) |
1068 | + return -1; |
1069 | + |
1070 | + test->display = dpy; |
1071 | + test->info = XIQueryDevice(dpy, XIAllDevices, &ndevices); |
1072 | + test->dev = 0; |
1073 | + for (i = 0; i < ndevices; i++) |
1074 | + if (test->info[i].deviceid == id) |
1075 | + test->dev = &test->info[i]; |
1076 | + if (!test->dev) |
1077 | + return -1; |
1078 | + |
1079 | + test->root = DefaultRootWindow(dpy); |
1080 | + test->win = XCreateSimpleWindow(dpy, test->root, |
1081 | + 0, 0, 400, 400, 0, |
1082 | + BlackPixel(dpy, 0), |
1083 | + WhitePixel(dpy, 0)); |
1084 | + |
1085 | + XMapWindow(test->display, test->win); |
1086 | + XFlush(test->display); |
1087 | + |
1088 | + return 0; |
1089 | +} |
1090 | + |
1091 | +static int init_frame(struct frame_test *test) |
1092 | +{ |
1093 | + test->fh = utouch_frame_new_engine(100, 32, 100); |
1094 | + if (!test->fh) |
1095 | + return -1; |
1096 | + return utouch_frame_init_xi2(test->fh, test->display, test->dev); |
1097 | +} |
1098 | + |
1099 | +static void destroy_all(struct frame_test *test) |
1100 | +{ |
1101 | + utouch_frame_delete_engine(test->fh); |
1102 | + XIFreeDeviceInfo(test->info); |
1103 | + XDestroyWindow(test->display, test->win); |
1104 | + XCloseDisplay(test->display); |
1105 | + memset(test, 0, sizeof(*test)); |
1106 | +} |
1107 | + |
1108 | +static void handle_event(struct frame_test *test, XEvent *ev) |
1109 | +{ |
1110 | + XGenericEventCookie *gev = &ev->xcookie; |
1111 | + const struct utouch_frame *frame; |
1112 | + XConfigureEvent *cev; |
1113 | + XIDeviceEvent *dev; |
1114 | + |
1115 | + switch(ev->type) { |
1116 | + case ConfigureNotify: |
1117 | + cev = (XConfigureEvent *)ev; |
1118 | + if (cev->window == XDefaultRootWindow(cev->display)) |
1119 | + utouch_frame_configure_xi2(test->fh, cev); |
1120 | + break; |
1121 | + case GenericEvent: |
1122 | + if (!XGetEventData(test->display, gev)) |
1123 | + break; |
1124 | + dev = gev->data; |
1125 | + /* null for some requests, quite odd */ |
1126 | + dev->display = ev->xany.display; |
1127 | + if (gev->type == GenericEvent && gev->extension == opcode) { |
1128 | + frame = utouch_frame_pump_xi2(test->fh, dev); |
1129 | + if (frame) |
1130 | + report_frame(frame); |
1131 | + } |
1132 | + XFreeEventData(test->display, gev); |
1133 | + break; |
1134 | + } |
1135 | +} |
1136 | + |
1137 | +static void loop_device(struct frame_test *test) |
1138 | +{ |
1139 | + XIEventMask mask; |
1140 | + |
1141 | + mask.deviceid = XIAllDevices; |
1142 | + mask.mask_len = XIMaskLen(XI_LASTEVENT); |
1143 | + mask.mask = calloc(mask.mask_len, sizeof(char)); |
1144 | + |
1145 | + XISetMask(mask.mask, XI_TouchBegin); |
1146 | + XISetMask(mask.mask, XI_TouchUpdate); |
1147 | + XISetMask(mask.mask, XI_TouchEnd); |
1148 | + XISetMask(mask.mask, XI_PropertyEvent); |
1149 | + XISelectEvents(test->display, test->win, &mask, 1); |
1150 | + |
1151 | + XSelectInput(test->display, test->root, StructureNotifyMask); |
1152 | + |
1153 | + while (1) { |
1154 | + XEvent ev; |
1155 | + XNextEvent(test->display, &ev); |
1156 | + handle_event(test, &ev); |
1157 | + } |
1158 | +} |
1159 | + |
1160 | +int main(int argc, char *argv[]) |
1161 | +{ |
1162 | + struct frame_test test; |
1163 | + int id; |
1164 | + |
1165 | + if (argc < 2) { |
1166 | + fprintf(stderr, "Usage: %s <xinput_device_number>\n", argv[0]); |
1167 | + return -1; |
1168 | + } |
1169 | + id = atoi(argv[1]); |
1170 | + |
1171 | + if (init_xi2(&test, id)) { |
1172 | + fprintf(stderr, "error: could not describe device\n"); |
1173 | + return -1; |
1174 | + } |
1175 | + if (!utouch_frame_is_supported_xi2(test.display, test.dev)) { |
1176 | + fprintf(stderr, "error: unsupported device\n"); |
1177 | + return -1; |
1178 | + } |
1179 | + if (init_frame(&test)) { |
1180 | + fprintf(stderr, "error: could not init frame\n"); |
1181 | + return -1; |
1182 | + } |
1183 | + |
1184 | + report_device_caps(test.fh); |
1185 | + |
1186 | + loop_device(&test); |
1187 | + |
1188 | + destroy_all(&test); |
1189 | + return 0; |
1190 | +} |
1191 | |
1192 | === added file 'tools/utouch-frame-test-xi2.txt' |
1193 | --- tools/utouch-frame-test-xi2.txt 1970-01-01 00:00:00 +0000 |
1194 | +++ tools/utouch-frame-test-xi2.txt 2011-02-21 12:19:53 +0000 |
1195 | @@ -0,0 +1,22 @@ |
1196 | +UTOUCH-FRAME-TEST-XI2(1) |
1197 | +========================== |
1198 | + |
1199 | +NAME |
1200 | +---- |
1201 | + |
1202 | + utouch-frame-test-xi2 - report frame events from an xinput device |
1203 | + |
1204 | +SYNOPSIS |
1205 | +-------- |
1206 | + |
1207 | + utouch-frame-test-xi2 xinput-device-number |
1208 | + |
1209 | +DESCRIPTION |
1210 | +----------- |
1211 | + |
1212 | +A test tool used to analyse the capabilities and act as a test driver for the |
1213 | +uTouch touch frame library. |
1214 | + |
1215 | +AUTHOR |
1216 | +------ |
1217 | +utouch-frame-test-xi2 was written by Henrik Rydberg <rydberg@euromail.se> |
Inconsistent #ifdef'ing around ABS_MT_DISTANCE: sometimes #if 0, sometimes #ifdef ABS_MT_DISTANCE.
You might want to fix that before committing.
Other than that, I find no obvious problems.