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
=== modified file 'configure.ac'
--- configure.ac 2011-01-03 18:56:34 +0000
+++ configure.ac 2011-02-21 12:34:52 +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,15 @@
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.2] [inputproto >= 1.5])
35 PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.99.1] [inputproto >= 2.0.99.1])
36 AC_DEFINE([HAVE_XI], [1], [XI2.1 support])
37])
38
30AC_CONFIG_FILES([Makefile39AC_CONFIG_FILES([Makefile
31 tools/Makefile40 tools/Makefile
32 mtview.pc])41 mtview.pc])
3342
=== modified file 'tools/Makefile.am'
--- tools/Makefile.am 2011-01-02 13:26:14 +0000
+++ tools/Makefile.am 2011-02-21 12:34:52 +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-21 12:34:52 +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: