[PATCH xinput 1/1] Add experimental multitouch support from XI 2.1
Daniel Stone
daniel at fooishbar.org
Fri Dec 17 09:14:49 PST 2010
From: Chase Douglas <chase.douglas at canonical.com>
This patch adds experimental support for listening to touch streams
(TouchBegin, TouchMotion and TouchEnd) with test-xi2, as well as showing
TouchClass information with list.
Based on an initial patch by Daniel Stone.
Signed-off-by: Daniel Stone <daniel at fooishbar.org>
Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
configure.ac | 6 ++++
src/list.c | 28 ++++++++++++++++++++
src/test_xi2.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 98 insertions(+), 12 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1dc2ce2..d657a59 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,12 @@ PKG_CHECK_MODULES(XI2, [xi >= 1.2.99.2] [inputproto >= 1.9.99.15],
HAVE_XI2="no");
AM_CONDITIONAL(HAVE_XI2, [ test "$HAVE_XI2" = "yes" ])
+# XI2.1 support
+PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.99.1] [inputproto >= 2.0.99.1],
+ HAVE_XI2_1="yes"; AC_DEFINE(HAVE_XI2_1, 1, [XI2_1 available]),
+ HAVE_XI2_1="no");
+AM_CONDITIONAL(HAVE_XI2_1, [ test "$HAVE_XI2_1" = "yes" ])
+
AC_SUBST(XINPUT_CFLAGS)
AC_SUBST(XINPUT_LIBS)
AC_SUBST(HAVE_XI2)
diff --git a/src/list.c b/src/list.c
index 8633c62..8920cad 100644
--- a/src/list.c
+++ b/src/list.c
@@ -24,6 +24,9 @@
#include "xinput.h"
#include <string.h>
#include <X11/extensions/XIproto.h> /* for XI_Device***ChangedNotify */
+#ifdef HAVE_XI2_1
+#include <X11/extensions/XI2proto.h> /* for XITouch* */
+#endif
static void
print_info(Display* dpy, XDeviceInfo *info, Bool shortformat)
@@ -178,6 +181,31 @@ print_classes_xi2(Display* display, XIAnyClassInfo **classes,
XFree(name);
}
break;
+#ifdef HAVE_XI2_1
+ case XITouchClass:
+ {
+ XITouchClassInfo *t = (XITouchClassInfo *)classes[i];
+
+ printf("\t\tMultitouch capable (max %d touches):\n",
+ t->num_touches);
+ printf("\t\t Mode: %s\n",
+ t->mode == XIDirectTouch ? "direct" : "dependent");
+ }
+ break;
+ case XITouchValuatorClass:
+ {
+ XITouchValuatorClassInfo *tv =
+ (XITouchValuatorClassInfo *)classes[i];
+ char *name = tv->label ?
+ XGetAtomName(display, tv->label) : NULL;
+
+ printf("\t\tDetail for Touch Valuator %d:\n", tv->number);
+ printf("\t\t Label: %s\n", (name) ? name : "None");
+ printf("\t\t Range: %f - %f\n", tv->min, tv->max);
+ printf("\t\t Resolution: %d units/m\n", tv->resolution);
+ }
+ break;
+#endif /* HAVE_XI2_1 */
}
}
diff --git a/src/test_xi2.c b/src/test_xi2.c
index 5b56397..443bbd8 100644
--- a/src/test_xi2.c
+++ b/src/test_xi2.c
@@ -29,26 +29,41 @@
extern void print_classes_xi2(Display*, XIAnyClassInfo **classes,
int num_classes);
-static Window create_win(Display *dpy)
+static void create_win(Display *dpy, Window *win, Window *subwin)
{
- Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200,
- 200, 0, 0, WhitePixel(dpy, 0));
- Window subwindow = XCreateSimpleWindow(dpy, win, 50, 50, 50, 50, 0, 0,
- BlackPixel(dpy, 0));
-
- XMapWindow(dpy, subwindow);
- XSelectInput(dpy, win, ExposureMask);
- return win;
+ *win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200,
+ 200, 0, 0, WhitePixel(dpy, 0));
+ *subwin = XCreateSimpleWindow(dpy, *win, 50, 50, 50, 50, 0, 0,
+ BlackPixel(dpy, 0));
+ XMapWindow(dpy, *subwin);
+ XSelectInput(dpy, *win, ExposureMask);
}
static void print_deviceevent(XIDeviceEvent* event)
{
double *val;
int i;
+ static int touch_events_received = 0;
+ static int thong = 0;
printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
printf(" detail: %d\n", event->detail);
- printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : "");
+
+ switch (event->evtype)
+ {
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : "");
+ break;
+ case XI_TouchBegin:
+ case XI_TouchMotion:
+ case XI_TouchEnd:
+ printf(" flags: %s%s%s\n",
+ (event->flags & XITouchOwner) ? "owner " : "",
+ (event->flags & XITouchOwnerAccepted) ? "owner accepted " : "",
+ (event->flags & XITouchPendingFinish) ? "pending finish " : "");
+ break;
+ }
printf(" root: %.2f/%.2f\n", event->root_x, event->root_y);
printf(" event: %.2f/%.2f\n", event->event_x, event->event_y);
@@ -74,6 +89,14 @@ static void print_deviceevent(XIDeviceEvent* event)
printf(" windows: root 0x%lx event 0x%lx child 0x%lx\n",
event->root, event->event, event->child);
+
+ if (event->evtype == XI_TouchBegin)
+ touch_events_received = 0;
+ else if (event->evtype == XI_TouchMotion && event->event != event->child &&
+ (event->flags & XITouchOwner) && ++touch_events_received == 5)
+ XIAllowTouchEvents(event->display, event->sourceid, event->detail,
+ (thong ^= 1) ? XITouchOwnerAccept :
+ XITouchOwnerReject);
}
static void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event)
@@ -279,6 +302,11 @@ static const char* type_to_name(int evtype)
case XI_RawButtonPress: name = "RawButtonPress"; break;
case XI_RawButtonRelease: name = "RawButtonRelease"; break;
case XI_RawMotion: name = "RawMotion"; break;
+#ifdef HAVE_XI2_1
+ case XI_TouchBegin: name = "TouchBegin"; break;
+ case XI_TouchEnd: name = "TouchEnd"; break;
+ case XI_TouchMotion: name = "TouchMotion"; break;
+#endif
default:
name = "unknown event type"; break;
}
@@ -294,14 +322,18 @@ test_xi2(Display *display,
char *desc)
{
XIEventMask mask;
- Window win;
+ Window win, subwin;
list(display, argc, argv, name, desc);
- win = create_win(display);
+ create_win(display, &win, &subwin);
/* Select for motion events */
mask.deviceid = XIAllDevices;
+#ifdef HAVE_XI2_1
+ mask.mask_len = XIMaskLen(XI_TouchMotion);
+#else
mask.mask_len = XIMaskLen(XI_RawMotion);
+#endif
mask.mask = calloc(mask.mask_len, sizeof(char));
XISetMask(mask.mask, XI_ButtonPress);
XISetMask(mask.mask, XI_ButtonRelease);
@@ -316,9 +348,17 @@ test_xi2(Display *display,
XISetMask(mask.mask, XI_HierarchyChanged);
XISetMask(mask.mask, XI_PropertyEvent);
XISelectEvents(display, win, &mask, 1);
+#ifdef HAVE_XI2_1
+ memset(mask.mask, 0, mask.mask_len);
+ XISetMask(mask.mask, XI_TouchBegin);
+ XISetMask(mask.mask, XI_TouchMotion);
+ XISetMask(mask.mask, XI_TouchEnd);
+ XISelectEvents(display, subwin, &mask, 1);
+#endif
XMapWindow(display, win);
XSync(display, False);
+#if 0
{
XIGrabModifiers modifiers[] = {{0, 0}, {0, 0x10}, {0, 0x1}, {0, 0x11}};
int nmods = sizeof(modifiers)/sizeof(modifiers[0]);
@@ -337,6 +377,18 @@ test_xi2(Display *display,
XIUngrabButton(display, 3, 1, win, nmods - 2, &modifiers[2]);
XIUngrabKeycode(display, 3, 24 /* q */, win, nmods - 2, &modifiers[2]);
}
+#else
+ {
+ XIGrabModifiers mods = { XIAnyModifier, 0 };
+ mask.deviceid = XIAllMasterDevices;
+ memset(mask.mask, 0, mask.mask_len);
+ XISetMask(mask.mask, XI_TouchBegin);
+ XISetMask(mask.mask, XI_TouchMotion);
+ XISetMask(mask.mask, XI_TouchEnd);
+ XIGrabTouchBegin(display, XIAllMasterDevices, win, False, &mask,
+ 1, &mods);
+ }
+#endif
mask.deviceid = XIAllMasterDevices;
memset(mask.mask, 0, mask.mask_len);
--
1.7.2.3
More information about the xorg-devel
mailing list