diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-10-26 15:50:53 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-10-26 15:50:53 +1000 |
commit | b79f36bc971f5f7ae85db99c32acc32af9fa8f00 (patch) | |
tree | 0882bbcd287e95c1b4545956de0b7ecf4596d72a |
Add basic multitouch testing program.
This doesn't do anything but print events so far.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 36 | ||||
-rw-r--r-- | multitouch.c | 164 |
3 files changed, 204 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..05655a6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +bin_PROGRAMS = multitouch + +multitouch_LDADD = $(XINPUT_LIBS) +multitouch_CFLAGS = $(XINPUT_CFLAGS) diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3f419d7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,36 @@ +# Copyright © 2011 Red Hat, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +# Initialize Autoconf +AC_PREREQ([2.60]) +AC_INIT([multitouch], [0.0.1], [], []) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +AC_PROG_CC +# Obtain compiler/linker options for dependencies +PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.5.99.1] [inputproto >= 2.1.99.1]) + +AC_OUTPUT([Makefile]) diff --git a/multitouch.c b/multitouch.c new file mode 100644 index 0000000..86ed48c --- /dev/null +++ b/multitouch.c @@ -0,0 +1,164 @@ +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <signal.h> + +#include <X11/Xlib.h> +#include <X11/extensions/XInput.h> +#include <X11/extensions/XInput2.h> + +struct multitouch { + Display *dpy; + int screen; + Window root; + Window win; +}; + +static int error(const char *fmt, ...) +{ + va_list args; + fprintf(stderr, "E: "); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + return EXIT_FAILURE; +} + +static void msg(const char *fmt, ...) +{ + va_list args; + printf("M: "); + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +static int running = 1; +static void sighandler(int signal) +{ + running = 0; + error("signal received, shutting down\n"); +} + +static Window init_window(struct multitouch *mt) +{ + Window win; + XEvent event; + XIEventMask evmask; + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + + win = XCreateSimpleWindow(mt->dpy, mt->root, 0, 0, 800, 600, + 0, 0, WhitePixel(mt->dpy, mt->screen)); + XMapWindow(mt->dpy, win); + XMaskEvent(mt->dpy, ExposureMask, &event); + + evmask.mask = mask; + evmask.mask_len = sizeof(mask); + memset(mask, 0, sizeof(mask)); + evmask.deviceid = XIAllMasterDevices; + + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + + XISelectEvents(mt->dpy, win, &evmask, 1); + + XFlush(mt->dpy); + + return win; +} + +static int init_x11(struct multitouch *mt) +{ + Display *dpy; + int major = 2, minor = 2; + + dpy = XOpenDisplay(NULL); + if (!dpy) + return error("Invalid DISPLAY.\n"); + + if (XIQueryVersion(dpy, &major, &minor) != Success || + major * 10 + minor < 22) + return error("Need XI 2.2\n"); + + + mt->dpy = dpy; + mt->screen = DefaultScreen(dpy); + mt->root = DefaultRootWindow(dpy); + + mt->win = init_window(mt); + if (!mt->win) + return error("Failed to create window.\n"); + + return EXIT_SUCCESS; +} + +static void teardown(struct multitouch *mt) +{ + if (mt->win) + XUnmapWindow(mt->dpy, mt->win); + XCloseDisplay(mt->dpy); +} + +static void print_event(struct multitouch *mt, XIDeviceEvent* event) +{ + const char *type; + switch(event->evtype) + { + case XI_TouchBegin: type = "TouchBegin"; break; + case XI_TouchUpdate: type = "TouchUpdate"; break; + case XI_TouchEnd: type = "TouchEnd"; break; + } + msg("Event: %s\n", type); +} + + +static int main_loop(struct multitouch *mt) +{ + int xi_opcode, xi_error, xi_event; + + XQueryExtension(mt->dpy, INAME, &xi_opcode, &xi_event, &xi_error); + + while (running) + { + XEvent ev; + XGenericEventCookie *cookie = &ev.xcookie; + XNextEvent(mt->dpy, &ev); + if (XGetEventData(mt->dpy, cookie) && + cookie->type == GenericEvent && + cookie->extension == xi_opcode) + { + print_event(mt, cookie->data); + } + + XFreeEventData(mt->dpy, cookie); + } + + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) +{ + int rc; + struct multitouch mt = { 0 }; + + rc = init_x11(&mt); + if (rc != EXIT_SUCCESS) + return rc; + + signal(SIGINT, sighandler); + + main_loop(&mt); + + teardown(&mt); + + return EXIT_SUCCESS; +} |