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
=== modified file 'configure.ac'
--- configure.ac 2011-01-03 18:56:34 +0000
+++ configure.ac 2011-02-22 16:17:18 +0000
@@ -1,7 +1,7 @@
1# Initialize Autoconf1# Initialize Autoconf
2AC_PREREQ([2.60])2AC_PREREQ([2.60])
3AC_INIT([Multitouch Viewer],3AC_INIT([Multitouch Viewer],
4 [1.1.1],4 [1.1.3],
5 [],5 [],
6 [mtview])6 [mtview])
7AC_CONFIG_SRCDIR([Makefile.am])7AC_CONFIG_SRCDIR([Makefile.am])
@@ -27,6 +27,14 @@
27PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0])27PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0])
28PKG_CHECK_MODULES([X11], [x11])28PKG_CHECK_MODULES([X11], [x11])
2929
30AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support]))
31AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"])
32
33AS_IF([test "x$with_xi" = "xyes"], [
34 PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.4.1.99.1] [inputproto >= 2.0.99.1])
35 AC_DEFINE([HAVE_XI], [1], [XI2.1 support])
36])
37
30AC_CONFIG_FILES([Makefile38AC_CONFIG_FILES([Makefile
31 tools/Makefile39 tools/Makefile
32 mtview.pc])40 mtview.pc])
3341
=== modified file 'tools/Makefile.am'
--- tools/Makefile.am 2011-01-02 13:26:14 +0000
+++ tools/Makefile.am 2011-02-22 16:17:18 +0000
@@ -4,3 +4,11 @@
44
5mtview_SOURCES = mtview.c5mtview_SOURCES = mtview.c
6mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm6mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm
7
8if HAVE_XI
9
10AM_CFLAGS = $(XINPUT_CFLAGS)
11
12mtview_LDFLAGS += $(XINPUT_LIBS)
13
14endif
715
=== modified file 'tools/mtview.c'
--- tools/mtview.c 2011-01-02 13:26:14 +0000
+++ tools/mtview.c 2011-02-22 16:17:18 +0000
@@ -1,22 +1,29 @@
1#include "config.h"
1#include <X11/Xlib.h>2#include <X11/Xlib.h>
2#include <stdio.h>3#include <stdio.h>
3#include <fcntl.h>4#include <fcntl.h>
4#include <utouch/frame-mtdev.h>5#include <utouch/frame-mtdev.h>
6#if HAVE_XI
7#include <utouch/frame-xi2.h>
8#endif
9#include <stdlib.h>
10#include <unistd.h>
5#include <string.h>11#include <string.h>
6#include <math.h>12#include <math.h>
713
8#define XMARG 16
9#define YMARG 16
10#define DEF_FRAC 0.1514#define DEF_FRAC 0.15
11#define DEF_WIDTH 0.0515#define DEF_WIDTH 0.05
1216
13#define DIM_TOUCH 3217#define DIM_TOUCH 32
1418
19static int opcode;
20
15struct windata {21struct windata {
16 Display *dsp;22 Display *dsp;
17 Window root, win;23 Window win;
18 GC gc;24 GC gc;
19 int screen, width, height;25 int screen;
26 float off_x, off_y;
20 unsigned long white, black;27 unsigned long white, black;
21 unsigned long color[DIM_TOUCH];28 unsigned long color[DIM_TOUCH];
22 int id[DIM_TOUCH];29 int id[DIM_TOUCH];
@@ -32,26 +39,28 @@
32 return lrand48() & 0xffffff;39 return lrand48() & 0xffffff;
33}40}
3441
35static void clear_screen(struct windata *w)42static void clear_screen(utouch_frame_handle fh, struct windata *w)
36{43{
44 const struct utouch_surface *s = utouch_frame_get_surface(fh);
45 int width = s->mapped_max_x - s->mapped_min_x;
46 int height = s->mapped_max_y - s->mapped_min_y;
47
37 XSetForeground(w->dsp, w->gc, w->black);48 XSetForeground(w->dsp, w->gc, w->black);
38 XFillRectangle(w->dsp, w->win, w->gc, 0, 0, w->width, w->height);49 XFillRectangle(w->dsp, w->win, w->gc, 0, 0, width, height);
39}50}
4051
41static void output_touch(utouch_frame_handle fh, struct windata *w,52static void output_touch(utouch_frame_handle fh, struct windata *w,
42 const struct utouch_contact *t)53 const struct utouch_contact *t)
43{54{
44 const struct utouch_surface *s = utouch_frame_get_surface(fh);55 const struct utouch_surface *s = utouch_frame_get_surface(fh);
4556 float dx = s->mapped_max_x - s->mapped_min_x;
46 float x1 = s->min_x, y1 = s->min_y;57 float dy = s->mapped_max_y - s->mapped_min_y;
47 float x2 = s->max_x, y2 = s->max_y;58 float x = t->x - w->off_x, y = t->y - w->off_y;
48 float dx = x2 - x1, dy = y2 - y1;
49 float major = 0, minor = 0, angle = 0;59 float major = 0, minor = 0, angle = 0;
5060
51 if (s->use_pressure) {61 if (s->use_pressure) {
52 float p = DEF_FRAC / s->max_pressure;62 major = DEF_FRAC * t->pressure * dy;
53 major = t->pressure * p * dx;63 minor = DEF_FRAC * t->pressure * dx;
54 minor = t->pressure * p * dx;
55 angle = 0;64 angle = 0;
56 }65 }
57 if (s->use_touch_major) {66 if (s->use_touch_major) {
@@ -68,15 +77,6 @@
68 float as = fabs(sin(angle));77 float as = fabs(sin(angle));
69 float mx = max(minor * ac, major * as);78 float mx = max(minor * ac, major * as);
70 float my = max(major * ac, minor * as);79 float my = max(major * ac, minor * as);
71 float ux = t->x - 0.5 * mx;
72 float uy = t->y - 0.5 * my;
73 float vx = t->x + 0.5 * mx;
74 float vy = t->y + 0.5 * my;
75
76 float px = (ux - x1) / dx * w->width;
77 float py = (uy - y1) / dy * w->height;
78 float qx = (vx - x1) / dx * w->width;
79 float qy = (vy - y1) / dy * w->height;
8080
81 if (w->id[t->slot] != t->id) {81 if (w->id[t->slot] != t->id) {
82 w->id[t->slot] = t->id;82 w->id[t->slot] = t->id;
@@ -84,7 +84,9 @@
84 }84 }
8585
86 XSetForeground(w->dsp, w->gc, w->color[t->slot]);86 XSetForeground(w->dsp, w->gc, w->color[t->slot]);
87 XFillArc(w->dsp, w->win, w->gc, px, py, qx - px, qy - py, 0, 360 * 64);87
88 XFillArc(w->dsp, w->win, w->gc, x - mx / 2, y - my / 2,
89 mx, my, 0, 360 * 64);
88 XFlush(w->dsp);90 XFlush(w->dsp);
89}91}
9092
@@ -98,88 +100,105 @@
98 output_touch(fh, w, frame->active[i]);100 output_touch(fh, w, frame->active[i]);
99}101}
100102
101static void event_loop(utouch_frame_handle fh,103static int init_window(struct windata *w)
102 struct mtdev *dev, int fd,104{
103 struct windata *w)105 int event, err;
106 int i;
107
108 memset(w, 0, sizeof(w));
109 for (i = 0; i < DIM_TOUCH; i++)
110 w->id[i] = -1;
111
112 w->dsp = XOpenDisplay(NULL);
113 if (!w->dsp)
114 return -1;
115 if (!XQueryExtension(w->dsp, "XInputExtension", &opcode, &event, &err))
116 return -1;
117
118 w->screen = DefaultScreen(w->dsp);
119 w->white = WhitePixel(w->dsp, w->screen);
120 w->black = BlackPixel(w->dsp, w->screen);
121
122 w->win = XCreateSimpleWindow(w->dsp, XDefaultRootWindow(w->dsp),
123 0, 0, 200, 200, 0, w->black, w->white);
124 w->gc = DefaultGC(w->dsp, w->screen);
125
126 XMapWindow(w->dsp, w->win);
127 XFlush(w->dsp);
128
129 return 0;
130}
131
132static void term_window(struct windata *w)
133{
134 XDestroyWindow(w->dsp, w->win);
135 XCloseDisplay(w->dsp);
136}
137
138static void set_screen_size_mtdev(utouch_frame_handle fh,
139 struct windata *w,
140 XEvent *xev)
141{
142 struct utouch_surface *s = utouch_frame_get_surface(fh);
143 XConfigureEvent *cev = (XConfigureEvent *)xev;
144
145 s->mapped_min_x = 0;
146 s->mapped_min_y = 0;
147 s->mapped_max_x = DisplayWidth(w->dsp, w->screen);
148 s->mapped_max_y = DisplayHeight(w->dsp, w->screen);
149 s->mapped_max_pressure = 1;
150
151 if (cev) {
152 w->off_x = cev->x;
153 w->off_y = cev->y;
154 }
155
156 fprintf(stderr, "map: %f %f %f %f %f %f\n",
157 w->off_x, w->off_y,
158 s->mapped_min_x, s->mapped_min_y,
159 s->mapped_max_x, s->mapped_max_y);
160}
161
162static void run_window_mtdev(utouch_frame_handle fh, struct mtdev *dev, int fd)
104{163{
105 const struct utouch_frame *frame;164 const struct utouch_frame *frame;
106 struct input_event iev;165 struct input_event iev;
166 struct windata w;
107 XEvent xev;167 XEvent xev;
108168
109 XSelectInput(w->dsp, w->win,169 if (init_window(&w))
110 ButtonPressMask | ButtonReleaseMask |170 return;
111 ExposureMask | StructureNotifyMask);171
112172 clear_screen(fh, &w);
113 clear_screen(w);173
174 set_screen_size_mtdev(fh, &w, 0);
175 XSelectInput(w.dsp, w.win, StructureNotifyMask);
176
114 while (1) {177 while (1) {
115 while (!mtdev_idle(dev, fd, 100)) {178 while (!mtdev_idle(dev, fd, 100)) {
116 while (mtdev_get(dev, fd, &iev, 1) > 0) {179 while (mtdev_get(dev, fd, &iev, 1) > 0) {
117 frame = utouch_frame_pump_mtdev(fh, &iev);180 frame = utouch_frame_pump_mtdev(fh, &iev);
118 if (frame)181 if (frame)
119 report_frame(fh, frame, w);182 report_frame(fh, frame, &w);
120 }183 }
121 }184 }
122 while (XPending(w->dsp)) {185 while (XPending(w.dsp)) {
123 XNextEvent(w->dsp, &xev);186 XNextEvent(w.dsp, &xev);
187 set_screen_size_mtdev(fh, &w, &xev);
124 }188 }
125 }189 }
126}190
127191 term_window(&w);
128static void run_window(utouch_frame_handle fh, struct mtdev *dev, int fd)192}
129{193
130 struct windata w;194static int run_mtdev(const char *name)
131 int i;
132 memset(&w, 0, sizeof(w));
133 for (i = 0; i < DIM_TOUCH; i++)
134 w.id[i] = -1;
135
136 w.dsp = XOpenDisplay(NULL);
137 if (!w.dsp)
138 return;
139
140 w.screen = DefaultScreen(w.dsp);
141 w.white = WhitePixel(w.dsp, w.screen);
142 w.black = BlackPixel(w.dsp, w.screen);
143 w.width = DisplayWidth(w.dsp, w.screen) - XMARG;
144 w.height = DisplayHeight(w.dsp, w.screen) - YMARG;
145
146 w.root = DefaultRootWindow(w.dsp);
147 w.win = XCreateSimpleWindow(w.dsp, w.root,
148 0, 0, w.width, w.height,
149 0, w.black, w.white);
150
151 XMapWindow(w.dsp, w.win);
152
153 long eventMask = StructureNotifyMask;
154 XSelectInput(w.dsp, w.win, eventMask);
155
156 XEvent ev;
157 do {
158 XNextEvent(w.dsp, &ev);
159 } while (ev.type != MapNotify);
160
161
162 w.gc = XCreateGC(w.dsp, w.win, 0, NULL);
163
164 event_loop(fh, dev, fd, &w);
165
166 XDestroyWindow(w.dsp, w.win);
167 XCloseDisplay(w.dsp);
168}
169
170int main(int argc, char *argv[])
171{195{
172 struct evemu_device *evemu;196 struct evemu_device *evemu;
173 struct mtdev *mtdev;197 struct mtdev *mtdev;
174 utouch_frame_handle fh;198 utouch_frame_handle fh;
175 int fd;199 int fd;
176200
177 if (argc < 2) {201 fd = open(name, O_RDONLY | O_NONBLOCK);
178 fprintf(stderr, "Usage: %s <device>\n", argv[0]);
179 return -1;
180 }
181
182 fd = open(argv[1], O_RDONLY | O_NONBLOCK);
183 if (fd < 0) {202 if (fd < 0) {
184 fprintf(stderr, "error: could not open device\n");203 fprintf(stderr, "error: could not open device\n");
185 return -1;204 return -1;
@@ -209,7 +228,7 @@
209 return -1;228 return -1;
210 }229 }
211230
212 run_window(fh, mtdev, fd);231 run_window_mtdev(fh, mtdev, fd);
213232
214 utouch_frame_delete_engine(fh);233 utouch_frame_delete_engine(fh);
215 mtdev_close_delete(mtdev);234 mtdev_close_delete(mtdev);
@@ -220,3 +239,129 @@
220239
221 return 0;240 return 0;
222}241}
242
243#if HAVE_XI
244static void handle_event_xi2(struct windata *w,
245 utouch_frame_handle fh,
246 XEvent *ev)
247{
248 XConfigureEvent *cev = (XConfigureEvent *)ev;
249 XGenericEventCookie *gev = &ev->xcookie;
250 const struct utouch_frame *frame;
251
252 switch(ev->type) {
253 case ConfigureNotify:
254 if (cev->window == XDefaultRootWindow(cev->display)) {
255 utouch_frame_configure_xi2(fh, cev);
256 } else {
257 w->off_x = cev->x;
258 w->off_y = cev->y;
259 }
260 break;
261 case GenericEvent:
262 if (!XGetEventData(w->dsp, gev))
263 break;
264 if (gev->type == GenericEvent && gev->extension == opcode) {
265 frame = utouch_frame_pump_xi2(fh, gev->data);
266 if (frame)
267 report_frame(fh, frame, w);
268 }
269 XFreeEventData(w->dsp, gev);
270 break;
271 }
272}
273
274static void run_window_xi2(struct windata *w,
275 utouch_frame_handle fh,
276 XIDeviceInfo *dev)
277{
278 const struct utouch_frame *frame;
279 XIEventMask mask;
280
281 fprintf(stderr, "xi2 running\n");
282
283 XSelectInput(w->dsp, w->win, StructureNotifyMask);
284 XSelectInput(w->dsp, XDefaultRootWindow(w->dsp), StructureNotifyMask);
285
286 mask.deviceid = dev->deviceid;
287 mask.mask_len = XIMaskLen(XI_LASTEVENT);
288 mask.mask = calloc(mask.mask_len, sizeof(char));
289
290 XISetMask(mask.mask, XI_PropertyEvent);
291 XISetMask(mask.mask, XI_TouchBegin);
292 XISetMask(mask.mask, XI_TouchUpdate);
293 XISetMask(mask.mask, XI_TouchEnd);
294 XISelectEvents(w->dsp, w->win, &mask, 1);
295
296 while (1) {
297 XEvent ev;
298 XNextEvent(w->dsp, &ev);
299 handle_event_xi2(w, fh, &ev);
300 }
301}
302
303static int run_xi2(int id)
304{
305 struct windata w;
306 XIDeviceInfo *info, *dev;
307 utouch_frame_handle fh;
308 int ndevice;
309 int i;
310
311 if (init_window(&w)) {
312 fprintf(stderr, "error: could not init window\n");
313 return -1;
314 }
315
316 info = XIQueryDevice(w.dsp, XIAllDevices, &ndevice);
317 dev = 0;
318 for (i = 0; i < ndevice; i++)
319 if (info[i].deviceid == id)
320 dev = &info[i];
321 if (!dev)
322 return -1;
323
324 if (!utouch_frame_is_supported_xi2(w.dsp, dev)) {
325 fprintf(stderr, "error: unsupported device\n");
326 return -1;
327 }
328
329 fh = utouch_frame_new_engine(100, 32, 100);
330 if (!fh || utouch_frame_init_xi2(fh, w.dsp, dev)) {
331 fprintf(stderr, "error: could not init frame\n");
332 return -1;
333 }
334
335 run_window_xi2(&w, fh, dev);
336
337 utouch_frame_delete_engine(fh);
338 XIFreeDeviceInfo(info);
339 term_window(&w);
340
341 return 0;
342}
343#else
344static int run_xi2(int id)
345{
346 fprintf(stderr, "XI2.1 not supported\n");
347 return 0;
348}
349#endif
350
351int main(int argc, char *argv[])
352{
353 int id, ret;
354
355 if (argc < 2) {
356 fprintf(stderr, "Usage: %s <device>\n", argv[0]);
357 return -1;
358 }
359
360 id = atoi(argv[1]);
361 if (id)
362 ret = run_xi2(id);
363 else
364 ret = run_mtdev(argv[1]);
365
366 return ret;
367}

Subscribers

People subscribed via source and target branches

to all changes: