Merge lp:~mtdev-team/mtview/trunk.v1.1.3 into lp:mtview
- trunk.v1.1.3
- Merge into trunk
Proposed by
Henrik Rydberg
Status: | Superseded |
---|---|
Proposed branch: | lp:~mtdev-team/mtview/trunk.v1.1.3 |
Merge into: | lp:mtview |
Diff against target: |
454 lines (+249/-87) 3 files modified
configure.ac (+10/-1) tools/Makefile.am (+8/-0) tools/mtview.c (+231/-86) |
To merge this branch: | bzr merge lp:~mtdev-team/mtview/trunk.v1.1.3 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas | Needs Fixing | ||
Review via email: mp+50587@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-02-22.
Commit message
Description of the change
v1.0.2: Reworked mtview with optional XI2.1 support and the ability to draw in multiple windows simultaneously.
v1.0.3: Adjusted api to latest version (February 2011).
To post a comment you must log in.
Revision history for this message
Henrik Rydberg (rydberg) wrote : | # |
Like this? (new branch pushed)
- 17. By Henrik Rydberg
-
Simplify XInput package test
The XI2.1 support is present in sufficiently recent xinput packages,
so simplify the testing accordingly. - 18. By Henrik Rydberg
-
Bump to version 1.1.3
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2011-01-03 18:56:34 +0000 |
3 | +++ configure.ac 2011-02-21 12:34:52 +0000 |
4 | @@ -1,7 +1,7 @@ |
5 | # Initialize Autoconf |
6 | AC_PREREQ([2.60]) |
7 | AC_INIT([Multitouch Viewer], |
8 | - [1.1.1], |
9 | + [1.1.3], |
10 | [], |
11 | [mtview]) |
12 | AC_CONFIG_SRCDIR([Makefile.am]) |
13 | @@ -27,6 +27,15 @@ |
14 | PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0]) |
15 | PKG_CHECK_MODULES([X11], [x11]) |
16 | |
17 | +AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support])) |
18 | +AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"]) |
19 | + |
20 | +AS_IF([test "x$with_xi" = "xyes"], [ |
21 | + PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.2] [inputproto >= 1.5]) |
22 | + PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.99.1] [inputproto >= 2.0.99.1]) |
23 | + AC_DEFINE([HAVE_XI], [1], [XI2.1 support]) |
24 | +]) |
25 | + |
26 | AC_CONFIG_FILES([Makefile |
27 | tools/Makefile |
28 | mtview.pc]) |
29 | |
30 | === modified file 'tools/Makefile.am' |
31 | --- tools/Makefile.am 2011-01-02 13:26:14 +0000 |
32 | +++ tools/Makefile.am 2011-02-21 12:34:52 +0000 |
33 | @@ -4,3 +4,11 @@ |
34 | |
35 | mtview_SOURCES = mtview.c |
36 | mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm |
37 | + |
38 | +if HAVE_XI |
39 | + |
40 | +AM_CFLAGS = $(XINPUT_CFLAGS) |
41 | + |
42 | +mtview_LDFLAGS += $(XINPUT_LIBS) |
43 | + |
44 | +endif |
45 | |
46 | === modified file 'tools/mtview.c' |
47 | --- tools/mtview.c 2011-01-02 13:26:14 +0000 |
48 | +++ tools/mtview.c 2011-02-21 12:34:52 +0000 |
49 | @@ -1,22 +1,29 @@ |
50 | +#include "config.h" |
51 | #include <X11/Xlib.h> |
52 | #include <stdio.h> |
53 | #include <fcntl.h> |
54 | #include <utouch/frame-mtdev.h> |
55 | +#if HAVE_XI |
56 | +#include <utouch/frame-xi2.h> |
57 | +#endif |
58 | +#include <stdlib.h> |
59 | +#include <unistd.h> |
60 | #include <string.h> |
61 | #include <math.h> |
62 | |
63 | -#define XMARG 16 |
64 | -#define YMARG 16 |
65 | #define DEF_FRAC 0.15 |
66 | #define DEF_WIDTH 0.05 |
67 | |
68 | #define DIM_TOUCH 32 |
69 | |
70 | +static int opcode; |
71 | + |
72 | struct windata { |
73 | Display *dsp; |
74 | - Window root, win; |
75 | + Window win; |
76 | GC gc; |
77 | - int screen, width, height; |
78 | + int screen; |
79 | + float off_x, off_y; |
80 | unsigned long white, black; |
81 | unsigned long color[DIM_TOUCH]; |
82 | int id[DIM_TOUCH]; |
83 | @@ -32,26 +39,28 @@ |
84 | return lrand48() & 0xffffff; |
85 | } |
86 | |
87 | -static void clear_screen(struct windata *w) |
88 | +static void clear_screen(utouch_frame_handle fh, struct windata *w) |
89 | { |
90 | + const struct utouch_surface *s = utouch_frame_get_surface(fh); |
91 | + int width = s->mapped_max_x - s->mapped_min_x; |
92 | + int height = s->mapped_max_y - s->mapped_min_y; |
93 | + |
94 | XSetForeground(w->dsp, w->gc, w->black); |
95 | - XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height); |
96 | + XFillRectangle(w->dsp, w->win, w->gc, 0, 0, width, height); |
97 | } |
98 | |
99 | static void output_touch(utouch_frame_handle fh, struct windata *w, |
100 | const struct utouch_contact *t) |
101 | { |
102 | const struct utouch_surface *s = utouch_frame_get_surface(fh); |
103 | - |
104 | - float x1 = s->min_x, y1 = s->min_y; |
105 | - float x2 = s->max_x, y2 = s->max_y; |
106 | - float dx = x2 - x1, dy = y2 - y1; |
107 | + float dx = s->mapped_max_x - s->mapped_min_x; |
108 | + float dy = s->mapped_max_y - s->mapped_min_y; |
109 | + float x = t->x - w->off_x, y = t->y - w->off_y; |
110 | float major = 0, minor = 0, angle = 0; |
111 | |
112 | if (s->use_pressure) { |
113 | - float p = DEF_FRAC / s->max_pressure; |
114 | - major = t->pressure * p * dx; |
115 | - minor = t->pressure * p * dx; |
116 | + major = DEF_FRAC * t->pressure * dy; |
117 | + minor = DEF_FRAC * t->pressure * dx; |
118 | angle = 0; |
119 | } |
120 | if (s->use_touch_major) { |
121 | @@ -68,15 +77,6 @@ |
122 | float as = fabs(sin(angle)); |
123 | float mx = max(minor * ac, major * as); |
124 | float my = max(major * ac, minor * as); |
125 | - float ux = t->x - 0.5 * mx; |
126 | - float uy = t->y - 0.5 * my; |
127 | - float vx = t->x + 0.5 * mx; |
128 | - float vy = t->y + 0.5 * my; |
129 | - |
130 | - float px = (ux - x1) / dx * w->width; |
131 | - float py = (uy - y1) / dy * w->height; |
132 | - float qx = (vx - x1) / dx * w->width; |
133 | - float qy = (vy - y1) / dy * w->height; |
134 | |
135 | if (w->id[t->slot] != t->id) { |
136 | w->id[t->slot] = t->id; |
137 | @@ -84,7 +84,9 @@ |
138 | } |
139 | |
140 | XSetForeground(w->dsp, w->gc, w->color[t->slot]); |
141 | - XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64); |
142 | + |
143 | + XFillArc(w->dsp, w->win, w->gc, x - mx / 2, y - my / 2, |
144 | + mx, my, 0, 360 * 64); |
145 | XFlush(w->dsp); |
146 | } |
147 | |
148 | @@ -98,88 +100,105 @@ |
149 | output_touch(fh, w, frame->active[i]); |
150 | } |
151 | |
152 | -static void event_loop(utouch_frame_handle fh, |
153 | - struct mtdev *dev, int fd, |
154 | - struct windata *w) |
155 | +static int init_window(struct windata *w) |
156 | +{ |
157 | + int event, err; |
158 | + int i; |
159 | + |
160 | + memset(w, 0, sizeof(w)); |
161 | + for (i = 0; i < DIM_TOUCH; i++) |
162 | + w->id[i] = -1; |
163 | + |
164 | + w->dsp = XOpenDisplay(NULL); |
165 | + if (!w->dsp) |
166 | + return -1; |
167 | + if (!XQueryExtension(w->dsp, "XInputExtension", &opcode, &event, &err)) |
168 | + return -1; |
169 | + |
170 | + w->screen = DefaultScreen(w->dsp); |
171 | + w->white = WhitePixel(w->dsp, w->screen); |
172 | + w->black = BlackPixel(w->dsp, w->screen); |
173 | + |
174 | + w->win = XCreateSimpleWindow(w->dsp, XDefaultRootWindow(w->dsp), |
175 | + 0, 0, 200, 200, 0, w->black, w->white); |
176 | + w->gc = DefaultGC(w->dsp, w->screen); |
177 | + |
178 | + XMapWindow(w->dsp, w->win); |
179 | + XFlush(w->dsp); |
180 | + |
181 | + return 0; |
182 | +} |
183 | + |
184 | +static void term_window(struct windata *w) |
185 | +{ |
186 | + XDestroyWindow(w->dsp, w->win); |
187 | + XCloseDisplay(w->dsp); |
188 | +} |
189 | + |
190 | +static void set_screen_size_mtdev(utouch_frame_handle fh, |
191 | + struct windata *w, |
192 | + XEvent *xev) |
193 | +{ |
194 | + struct utouch_surface *s = utouch_frame_get_surface(fh); |
195 | + XConfigureEvent *cev = (XConfigureEvent *)xev; |
196 | + |
197 | + s->mapped_min_x = 0; |
198 | + s->mapped_min_y = 0; |
199 | + s->mapped_max_x = DisplayWidth(w->dsp, w->screen); |
200 | + s->mapped_max_y = DisplayHeight(w->dsp, w->screen); |
201 | + s->mapped_max_pressure = 1; |
202 | + |
203 | + if (cev) { |
204 | + w->off_x = cev->x; |
205 | + w->off_y = cev->y; |
206 | + } |
207 | + |
208 | + fprintf(stderr, "map: %f %f %f %f %f %f\n", |
209 | + w->off_x, w->off_y, |
210 | + s->mapped_min_x, s->mapped_min_y, |
211 | + s->mapped_max_x, s->mapped_max_y); |
212 | +} |
213 | + |
214 | +static void run_window_mtdev(utouch_frame_handle fh, struct mtdev *dev, int fd) |
215 | { |
216 | const struct utouch_frame *frame; |
217 | struct input_event iev; |
218 | + struct windata w; |
219 | XEvent xev; |
220 | |
221 | - XSelectInput(w->dsp, w->win, |
222 | - ButtonPressMask | ButtonReleaseMask | |
223 | - ExposureMask | StructureNotifyMask); |
224 | - |
225 | - clear_screen(w); |
226 | + if (init_window(&w)) |
227 | + return; |
228 | + |
229 | + clear_screen(fh, &w); |
230 | + |
231 | + set_screen_size_mtdev(fh, &w, 0); |
232 | + XSelectInput(w.dsp, w.win, StructureNotifyMask); |
233 | + |
234 | while (1) { |
235 | while (!mtdev_idle(dev, fd, 100)) { |
236 | while (mtdev_get(dev, fd, &iev, 1) > 0) { |
237 | frame = utouch_frame_pump_mtdev(fh, &iev); |
238 | if (frame) |
239 | - report_frame(fh, frame, w); |
240 | + report_frame(fh, frame, &w); |
241 | } |
242 | } |
243 | - while (XPending(w->dsp)) { |
244 | - XNextEvent(w->dsp, &xev); |
245 | + while (XPending(w.dsp)) { |
246 | + XNextEvent(w.dsp, &xev); |
247 | + set_screen_size_mtdev(fh, &w, &xev); |
248 | } |
249 | } |
250 | -} |
251 | - |
252 | -static void run_window(utouch_frame_handle fh, struct mtdev *dev, int fd) |
253 | -{ |
254 | - struct windata w; |
255 | - int i; |
256 | - memset(&w, 0, sizeof(w)); |
257 | - for (i = 0; i < DIM_TOUCH; i++) |
258 | - w.id[i] = -1; |
259 | - |
260 | - w.dsp = XOpenDisplay(NULL); |
261 | - if (!w.dsp) |
262 | - return; |
263 | - |
264 | - w.screen = DefaultScreen(w.dsp); |
265 | - w.white = WhitePixel(w.dsp, w.screen); |
266 | - w.black = BlackPixel(w.dsp, w.screen); |
267 | - w.width = DisplayWidth(w.dsp, w.screen) - XMARG; |
268 | - w.height = DisplayHeight(w.dsp, w.screen) - YMARG; |
269 | - |
270 | - w.root = DefaultRootWindow(w.dsp); |
271 | - w.win = XCreateSimpleWindow(w.dsp, w.root, |
272 | - 0, 0, w.width, w.height, |
273 | - 0, w.black, w.white); |
274 | - |
275 | - XMapWindow(w.dsp, w.win); |
276 | - |
277 | - long eventMask = StructureNotifyMask; |
278 | - XSelectInput(w.dsp, w.win, eventMask); |
279 | - |
280 | - XEvent ev; |
281 | - do { |
282 | - XNextEvent(w.dsp, &ev); |
283 | - } while (ev.type != MapNotify); |
284 | - |
285 | - |
286 | - w.gc = XCreateGC(w.dsp, w.win, 0, NULL); |
287 | - |
288 | - event_loop(fh, dev, fd, &w); |
289 | - |
290 | - XDestroyWindow(w.dsp, w.win); |
291 | - XCloseDisplay(w.dsp); |
292 | -} |
293 | - |
294 | -int main(int argc, char *argv[]) |
295 | + |
296 | + term_window(&w); |
297 | +} |
298 | + |
299 | +static int run_mtdev(const char *name) |
300 | { |
301 | struct evemu_device *evemu; |
302 | struct mtdev *mtdev; |
303 | utouch_frame_handle fh; |
304 | int fd; |
305 | |
306 | - if (argc < 2) { |
307 | - fprintf(stderr, "Usage: %s <device>\n", argv[0]); |
308 | - return -1; |
309 | - } |
310 | - |
311 | - fd = open(argv[1], O_RDONLY | O_NONBLOCK); |
312 | + fd = open(name, O_RDONLY | O_NONBLOCK); |
313 | if (fd < 0) { |
314 | fprintf(stderr, "error: could not open device\n"); |
315 | return -1; |
316 | @@ -209,7 +228,7 @@ |
317 | return -1; |
318 | } |
319 | |
320 | - run_window(fh, mtdev, fd); |
321 | + run_window_mtdev(fh, mtdev, fd); |
322 | |
323 | utouch_frame_delete_engine(fh); |
324 | mtdev_close_delete(mtdev); |
325 | @@ -220,3 +239,129 @@ |
326 | |
327 | return 0; |
328 | } |
329 | + |
330 | +#if HAVE_XI |
331 | +static void handle_event_xi2(struct windata *w, |
332 | + utouch_frame_handle fh, |
333 | + XEvent *ev) |
334 | +{ |
335 | + XConfigureEvent *cev = (XConfigureEvent *)ev; |
336 | + XGenericEventCookie *gev = &ev->xcookie; |
337 | + const struct utouch_frame *frame; |
338 | + |
339 | + switch(ev->type) { |
340 | + case ConfigureNotify: |
341 | + if (cev->window == XDefaultRootWindow(cev->display)) { |
342 | + utouch_frame_configure_xi2(fh, cev); |
343 | + } else { |
344 | + w->off_x = cev->x; |
345 | + w->off_y = cev->y; |
346 | + } |
347 | + break; |
348 | + case GenericEvent: |
349 | + if (!XGetEventData(w->dsp, gev)) |
350 | + break; |
351 | + if (gev->type == GenericEvent && gev->extension == opcode) { |
352 | + frame = utouch_frame_pump_xi2(fh, gev->data); |
353 | + if (frame) |
354 | + report_frame(fh, frame, w); |
355 | + } |
356 | + XFreeEventData(w->dsp, gev); |
357 | + break; |
358 | + } |
359 | +} |
360 | + |
361 | +static void run_window_xi2(struct windata *w, |
362 | + utouch_frame_handle fh, |
363 | + XIDeviceInfo *dev) |
364 | +{ |
365 | + const struct utouch_frame *frame; |
366 | + XIEventMask mask; |
367 | + |
368 | + fprintf(stderr, "xi2 running\n"); |
369 | + |
370 | + XSelectInput(w->dsp, w->win, StructureNotifyMask); |
371 | + XSelectInput(w->dsp, XDefaultRootWindow(w->dsp), StructureNotifyMask); |
372 | + |
373 | + mask.deviceid = dev->deviceid; |
374 | + mask.mask_len = XIMaskLen(XI_LASTEVENT); |
375 | + mask.mask = calloc(mask.mask_len, sizeof(char)); |
376 | + |
377 | + XISetMask(mask.mask, XI_PropertyEvent); |
378 | + XISetMask(mask.mask, XI_TouchBegin); |
379 | + XISetMask(mask.mask, XI_TouchUpdate); |
380 | + XISetMask(mask.mask, XI_TouchEnd); |
381 | + XISelectEvents(w->dsp, w->win, &mask, 1); |
382 | + |
383 | + while (1) { |
384 | + XEvent ev; |
385 | + XNextEvent(w->dsp, &ev); |
386 | + handle_event_xi2(w, fh, &ev); |
387 | + } |
388 | +} |
389 | + |
390 | +static int run_xi2(int id) |
391 | +{ |
392 | + struct windata w; |
393 | + XIDeviceInfo *info, *dev; |
394 | + utouch_frame_handle fh; |
395 | + int ndevice; |
396 | + int i; |
397 | + |
398 | + if (init_window(&w)) { |
399 | + fprintf(stderr, "error: could not init window\n"); |
400 | + return -1; |
401 | + } |
402 | + |
403 | + info = XIQueryDevice(w.dsp, XIAllDevices, &ndevice); |
404 | + dev = 0; |
405 | + for (i = 0; i < ndevice; i++) |
406 | + if (info[i].deviceid == id) |
407 | + dev = &info[i]; |
408 | + if (!dev) |
409 | + return -1; |
410 | + |
411 | + if (!utouch_frame_is_supported_xi2(w.dsp, dev)) { |
412 | + fprintf(stderr, "error: unsupported device\n"); |
413 | + return -1; |
414 | + } |
415 | + |
416 | + fh = utouch_frame_new_engine(100, 32, 100); |
417 | + if (!fh || utouch_frame_init_xi2(fh, w.dsp, dev)) { |
418 | + fprintf(stderr, "error: could not init frame\n"); |
419 | + return -1; |
420 | + } |
421 | + |
422 | + run_window_xi2(&w, fh, dev); |
423 | + |
424 | + utouch_frame_delete_engine(fh); |
425 | + XIFreeDeviceInfo(info); |
426 | + term_window(&w); |
427 | + |
428 | + return 0; |
429 | +} |
430 | +#else |
431 | +static int run_xi2(int id) |
432 | +{ |
433 | + fprintf(stderr, "XI2.1 not supported\n"); |
434 | + return 0; |
435 | +} |
436 | +#endif |
437 | + |
438 | +int main(int argc, char *argv[]) |
439 | +{ |
440 | + int id, ret; |
441 | + |
442 | + if (argc < 2) { |
443 | + fprintf(stderr, "Usage: %s <device>\n", argv[0]); |
444 | + return -1; |
445 | + } |
446 | + |
447 | + id = atoi(argv[1]); |
448 | + if (id) |
449 | + ret = run_xi2(id); |
450 | + else |
451 | + ret = run_mtdev(argv[1]); |
452 | + |
453 | + return ret; |
454 | +} |
Looks fine except that configure.ac needs to be fixed up the same way as utouch-frame was fixed.