summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-10-26 15:50:53 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-10-26 15:50:53 +1000
commitb79f36bc971f5f7ae85db99c32acc32af9fa8f00 (patch)
tree0882bbcd287e95c1b4545956de0b7ecf4596d72a
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.am4
-rw-r--r--configure.ac36
-rw-r--r--multitouch.c164
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;
+}