Merge lp:~mtdev-team/mtview/trunk.v1.1.3 into lp:mtview

Proposed by Henrik Rydberg
Status: Merged
Merged at revision: 18
Proposed branch: lp:~mtdev-team/mtview/trunk.v1.1.3
Merge into: lp:mtview
Diff against target: 453 lines (+248/-87)
3 files modified
configure.ac (+9/-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
Reviewer Review Type Date Requested Status
Chase Douglas Approve
Review via email: mp+50774@code.launchpad.net

This proposal supersedes a proposal from 2011-02-21.

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
Chase Douglas (chasedouglas) wrote : Posted in a previous version of this proposal

Looks fine except that configure.ac needs to be fixed up the same way as utouch-frame was fixed.

review: Needs Fixing
Revision history for this message
Henrik Rydberg (rydberg) wrote : Posted in a previous version of this proposal

Like this? (new branch pushed)

Revision history for this message
Henrik Rydberg (rydberg) wrote :

I am going ahead and merging this since the problem is trivially fixed.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

To finish off, yes, this looks good :). I forgot about a dentist appointment, so I had to run!

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: