diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-02-15 18:56:17 +0100 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-02-15 18:56:17 +0100 |
| commit | 91c364d87b88a89dc991f9effbf4d537ca19192a (patch) | |
| tree | a7d6489764e23aeb415d46576227010f855a70c4 | |
| parent | 0129cd863ad87b8090f150611be58ac9e6e9bfda (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.ac | 9 | ||||
| -rw-r--r-- | tools/Makefile.am | 8 | ||||
| -rw-r--r-- | tools/mtview.c | 117 |
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]) | |||
| 27 | PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0]) | 27 | PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.0]) |
| 28 | PKG_CHECK_MODULES([X11], [x11]) | 28 | PKG_CHECK_MODULES([X11], [x11]) |
| 29 | 29 | ||
| 30 | AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support])) | ||
| 31 | AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"]) | ||
| 32 | |||
| 33 | AS_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 | |||
| 30 | AC_CONFIG_FILES([Makefile | 39 | AC_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 | ||
| 5 | mtview_SOURCES = mtview.c | 5 | mtview_SOURCES = mtview.c |
| 6 | mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm | 6 | mtview_LDFLAGS = -lX11 -lutouch-frame -lutouch-evemu -lmtdev -lm |
| 7 | |||
| 8 | if HAVE_XI | ||
| 9 | |||
| 10 | AM_CFLAGS = $(XINPUT_CFLAGS) | ||
| 11 | |||
| 12 | mtview_LDFLAGS += $(XINPUT_LIBS) | ||
| 13 | |||
| 14 | endif | ||
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 | ||
| 244 | static 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 | |||
| 274 | static 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 | |||
| 303 | static 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 | ||
| 344 | static int run_xi2(int id) | ||
| 345 | { | ||
| 346 | fprintf(stderr, "XI2.1 not supported\n"); | ||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | #endif | ||
| 350 | |||
| 239 | int main(int argc, char *argv[]) | 351 | int 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 | } |
