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

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
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.

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 :

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 :

Like this? (new branch pushed)

lp:~mtdev-team/mtview/trunk.v1.1.3 updated
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+}

Subscribers

People subscribed via source and target branches

to all changes: