summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-02-15 18:56:17 +0100
committerHenrik Rydberg <rydberg@euromail.se>2011-02-15 18:56:17 +0100
commit91c364d87b88a89dc991f9effbf4d537ca19192a (patch)
treea7d6489764e23aeb415d46576227010f855a70c4
parent0129cd863ad87b8090f150611be58ac9e6e9bfda (diff)
Optional XI2.1 support
This patch adds XI2.1 support to mtview. Several instances of the the program can be open simultaneously, each one being a window into the device, which is mapped onto the whole screen. On a touchscreen, paiting can occur simultaneously in each window. The device mapping is automatically modified in multi-head setups, and xinput set-prop can be used to map the device to a portion of the screen. Thanks to Chase Douglas for fixing this. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r--configure.ac9
-rw-r--r--tools/Makefile.am8
-rw-r--r--tools/mtview.c117
3 files changed, 133 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 5e177c7..8e107ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,6 +27,15 @@ PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0])
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])
29 29
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([Makefile 39AC_CONFIG_FILES([Makefile
31 tools/Makefile 40 tools/Makefile
32 mtview.pc]) 41 mtview.pc])
diff --git a/tools/Makefile.am b/tools/Makefile.am
index f33b5e5..8e9f90a 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -4,3 +4,11 @@ INCLUDES=-I$(top_srcdir)/include/
4 4
5mtview_SOURCES = mtview.c 5mtview_SOURCES = mtview.c
6mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm 6mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm
7
8if HAVE_XI
9
10AM_CFLAGS = $(XINPUT_CFLAGS)
11
12mtview_LDFLAGS += $(XINPUT_LIBS)
13
14endif
diff --git a/tools/mtview.c b/tools/mtview.c
index 7d6fdc6..1096070 100644
--- a/tools/mtview.c
+++ b/tools/mtview.c
@@ -1,7 +1,11 @@
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
5#include <stdlib.h> 9#include <stdlib.h>
6#include <unistd.h> 10#include <unistd.h>
7#include <string.h> 11#include <string.h>
@@ -236,6 +240,114 @@ static int run_mtdev(const char *name)
236 return 0; 240 return 0;
237} 241}
238 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_TouchMotion);
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_TouchMotion);
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
239int main(int argc, char *argv[]) 351int main(int argc, char *argv[])
240{ 352{
241 int id, ret; 353 int id, ret;
@@ -246,7 +358,10 @@ int main(int argc, char *argv[])
246 } 358 }
247 359
248 id = atoi(argv[1]); 360 id = atoi(argv[1]);
249 ret = run_mtdev(argv[1]); 361 if (id)
362 ret = run_xi2(id);
363 else
364 ret = run_mtdev(argv[1]);
250 365
251 return ret; 366 return ret;
252} 367}