From: Chase Douglas <[email protected]> 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 <[email protected]> Signed-off-by: Chase Douglas <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
