diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-09-14 22:33:57 -0700 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-11 15:35:36 +1000 |
commit | d8658c18e2acb31160094a32f99ab4dcbff37726 (patch) | |
tree | 83dd958ab65d5a41091ed7ac47fe992a3e9956d9 | |
parent | 015bbd7df2dce225e74e9a0cd671188927333ebb (diff) |
Implement support for XI 2.2multitouch
Adds support for the new TouchClass for multitouch-capable servers/devices.
Since the protocol (and thus the API) is not stable, this requires
--enable-unstable-protocol at configure time (same as the inputproto)
New events:
XITouchOwnershipEvent
New functions:
XIGrabTouchBegin ... passive grabs on touches
XIUngrabTouchBegin
XIAllowTouchEvents ... Allow/reject touch event sequences
New XIQueryDevice classes:
XITouchClassInfo
Requires libX11 1.5 for GetReqSized
Currently missing man pages.
Co-authored by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | include/X11/extensions/XInput2.h | 51 | ||||
-rw-r--r-- | src/XExtInt.c | 91 | ||||
-rw-r--r-- | src/XIAllowEvents.c | 46 | ||||
-rw-r--r-- | src/XIPassiveGrab.c | 33 | ||||
-rw-r--r-- | src/XIint.h | 2 |
6 files changed, 233 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac index c6565a8..4793c8c 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ XORG_WITH_ASCIIDOC(8.4.5) XORG_CHECK_MALLOC_ZERO # Obtain compiler/linker options for depedencies -PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.2.99.1] [xextproto >= 7.0.3] [xext >= 1.0.99.1] [inputproto >= 2.0.99.1]) +PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.4.99.1] [xextproto >= 7.0.3] [xext >= 1.0.99.1] [inputproto >= 2.1.99.2]) # Check for xmlto and asciidoc for man page conversion # (only needed by people building tarballs) @@ -48,6 +48,19 @@ AM_CONDITIONAL([INSTALL_MANPAGES], [test -f "$srcdir/man/XAllowDeviceEvents.man" || \ test $have_doctools = yes]) +# inputproto is still unstable and requires the defines below. Make sure the +# user specifies --unstable-protocol too +AC_ARG_ENABLE(unstable-protocol, + AS_HELP_STRING([--enable-unstable-protocol], + [Enables compilation of yet-to-be-finalised protocol (default: disabled)]), + [UNSTABLE_PROTO=$enableval], + [UNSTABLE_PROTO=no]) +if test "x$UNSTABLE_PROTO" = xyes; then + AC_DEFINE(XINPUT2_1_USE_UNSTABLE_PROTOCOL, 1, [Use XI 2.1 unstable protocol]) + AC_DEFINE(XINPUT2_2_USE_UNSTABLE_PROTOCOL, 1, [Use XI 2.1 unstable protocol]) +fi # no else branch, the compiler will complain for us + + AC_CONFIG_FILES([Makefile src/Makefile man/Makefile diff --git a/include/X11/extensions/XInput2.h b/include/X11/extensions/XInput2.h index 910b25f..26de695 100644 --- a/include/X11/extensions/XInput2.h +++ b/include/X11/extensions/XInput2.h @@ -146,6 +146,14 @@ typedef struct typedef struct { + int type; + int sourceid; + int mode; + int num_touches; +} XITouchClassInfo; + +typedef struct +{ int deviceid; char *name; int use; @@ -303,6 +311,23 @@ typedef struct { int what; } XIPropertyEvent; +typedef struct { + int type; /* GenericEvent */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* XI extension offset */ + int evtype; + Time time; + int deviceid; + int sourceid; + unsigned int touchid; + Window root; + Window event; + Window child; + int flags; +} XITouchOwnershipEvent; + _XFUNCPROTOBEGIN extern Bool XIQueryPointer( @@ -426,6 +451,14 @@ extern Status XIAllowEvents( Time time ); +extern Status XIAllowTouchEvents( + Display* display, + int deviceid, + unsigned int touchid, + Window grab_window, + int event_mode +); + extern int XIGrabButton( Display* display, int deviceid, @@ -477,6 +510,17 @@ extern int XIGrabFocusIn( int num_modifiers, XIGrabModifiers *modifiers_inout ); + +extern int XIGrabTouchBegin( + Display* display, + int deviceid, + Window grab_window, + int owner_events, + XIEventMask *mask, + int num_modifiers, + XIGrabModifiers *modifiers_inout +); + extern Status XIUngrabButton( Display* display, int deviceid, @@ -511,6 +555,13 @@ extern Status XIUngrabFocusIn( XIGrabModifiers *modifiers ); +extern Status XIUngrabTouchBegin( + Display* display, + int deviceid, + Window grab_window, + int num_modifiers, + XIGrabModifiers *modifiers +); extern Atom *XIListProperties( Display* display, diff --git a/src/XExtInt.c b/src/XExtInt.c index fb5f5c4..9196172 100644 --- a/src/XExtInt.c +++ b/src/XExtInt.c @@ -150,6 +150,9 @@ static int wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie); static int wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie); +static int +wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in, + XGenericEventCookie *cookie); static /* const */ XEvent emptyevent; @@ -275,7 +278,8 @@ static XExtensionVersion versions[] = { {XI_Absent, 0, 0}, {XI_Present, XI_Add_DeviceProperties_Major, XI_Add_DeviceProperties_Minor}, {XI_Present, 2, 0}, -{XI_Present, 2, 1} +{XI_Present, 2, 1}, +{XI_Present, 2, 2} }; /*********************************************************************** @@ -928,6 +932,9 @@ XInputWireToCookie( case XI_ButtonRelease: case XI_KeyPress: case XI_KeyRelease: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: *cookie = *(XGenericEventCookie*)save; if (!wireToDeviceEvent((xXIDeviceEvent*)event, cookie)) { @@ -954,12 +961,25 @@ XInputWireToCookie( break; } return ENQUEUE_EVENT; + case XI_TouchOwnership: + *cookie = *(XGenericEventCookie*)save; + if (!wireToTouchOwnershipEvent((xXITouchOwnershipEvent*)event, + cookie)) + { + printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", + ge->evtype); + break; + } + return ENQUEUE_EVENT; case XI_RawKeyPress: case XI_RawKeyRelease: case XI_RawButtonPress: case XI_RawButtonRelease: case XI_RawMotion: + case XI_RawTouchBegin: + case XI_RawTouchUpdate: + case XI_RawTouchEnd: *cookie = *(XGenericEventCookie*)save; if (!wireToRawEvent((xXIRawEvent*)event, cookie)) { @@ -1046,6 +1066,9 @@ sizeDeviceClassType(int type, int num_elements) case XIScrollClass: l = sizeof(XIScrollClassInfo); break; + case XITouchClass: + l = sizeof(XITouchClassInfo); + break; default: printf("sizeDeviceClassType: unknown type %d\n", type); break; @@ -1264,6 +1287,22 @@ copyPropertyEvent(XGenericEventCookie *cookie_in, } static Bool +copyTouchOwnershipEvent(XGenericEventCookie *cookie_in, + XGenericEventCookie *cookie_out) +{ + XITouchOwnershipEvent *in, *out; + + in = cookie_in->data; + + out = cookie_out->data = malloc(sizeof(XITouchOwnershipEvent)); + if (!out) + return False; + + *out = *in; + return True; +} + +static Bool copyRawEvent(XGenericEventCookie *cookie_in, XGenericEventCookie *cookie_out) { @@ -1322,6 +1361,9 @@ XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out case XI_ButtonRelease: case XI_KeyPress: case XI_KeyRelease: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: ret = copyDeviceEvent(in, out); break; case XI_DeviceChanged: @@ -1339,6 +1381,9 @@ XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out case XI_PropertyEvent: ret = copyPropertyEvent(in, out); break; + case XI_TouchOwnership: + ret = copyTouchOwnershipEvent(in, out); + break; case XI_RawKeyPress: case XI_RawKeyRelease: case XI_RawButtonPress: @@ -1455,6 +1500,9 @@ size_classes(xXIAnyInfo* from, int nclasses) case XIScrollClass: l = sizeDeviceClassType(XIScrollClass, 0); break; + case XITouchClass: + l = sizeDeviceClassType(XITouchClass, 0); + break; } len += l; @@ -1586,6 +1634,22 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) to->classes[cls_idx++] = any_lib; } break; + case XITouchClass: + { + XITouchClassInfo *cls_lib; + xXITouchInfo *cls_wire; + + cls_wire = (xXITouchInfo*)any_wire; + cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo)); + + cls_lib->type = cls_wire->type; + cls_lib->sourceid = cls_wire->sourceid; + cls_lib->mode = cls_wire->mode; + cls_lib->num_touches = cls_wire->num_touches; + + to->classes[cls_idx++] = any_lib; + } + break; } len += any_wire->length * 4; ptr_wire += any_wire->length * 4; @@ -1780,3 +1844,28 @@ wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie) return 1; } + +static int +wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in, + XGenericEventCookie *cookie) +{ + XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent)); + + cookie->data = out; + + out->type = in->type; + out->display = cookie->display; + out->extension = in->extension; + out->evtype = in->evtype; + out->send_event = ((in->type & 0x80) != 0); + out->time = in->time; + out->deviceid = in->deviceid; + out->sourceid = in->sourceid; + out->touchid = in->touchid; + out->root = in->root; + out->event = in->event; + out->child = in->child; + out->flags = in->flags; + + return 1; +} diff --git a/src/XIAllowEvents.c b/src/XIAllowEvents.c index d4da6d0..d987549 100644 --- a/src/XIAllowEvents.c +++ b/src/XIAllowEvents.c @@ -33,9 +33,12 @@ #include <X11/extensions/extutil.h> #include "XIint.h" -Status -XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time) +static Status +_XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time, + unsigned int touchid, Window grab_window) { + Bool have_XI22 = True; + int req_len = sz_xXIAllowEventsReq; /* in bytes */ xXIAllowEventsReq *req; XExtDisplayInfo *extinfo = XInput_find_display(dpy); @@ -44,14 +47,51 @@ XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time) if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) return (NoSuchExtension); - GetReq(XIAllowEvents, req); + /* 2.2's XIAllowEvents is 8 bytes longer than 2.0 */ + if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) { + req_len -= 8; + have_XI22 = False; + } + + GetReqSized(XIAllowEvents, req_len, req); + req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIAllowEvents; req->deviceid = deviceid; req->mode = event_mode; req->time = time; + if (have_XI22) { + req->touchid = touchid; + req->grab_window = grab_window; + } + UnlockDisplay(dpy); SyncHandle(); return Success; } + +Status +XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time) +{ + return _XIAllowEvents(dpy, deviceid, event_mode, time, 0, None); +} + +Status +XIAllowTouchEvents(Display *dpy, int deviceid, unsigned int touchid, + Window grab_window, int event_mode) +{ + int status; + XExtDisplayInfo *extinfo = XInput_find_display(dpy); + + LockDisplay(dpy); + if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) + return (NoSuchExtension); + + status = _XIAllowEvents(dpy, deviceid, event_mode, CurrentTime, touchid, grab_window); + + UnlockDisplay(dpy); + SyncHandle(); + + return status; +} diff --git a/src/XIPassiveGrab.c b/src/XIPassiveGrab.c index 7625521..f8eafed 100644 --- a/src/XIPassiveGrab.c +++ b/src/XIPassiveGrab.c @@ -148,6 +148,25 @@ XIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode, modifiers_inout); } +int +XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window, + Bool owner_events, XIEventMask *mask, + int num_modifiers, XIGrabModifiers *modifiers_inout) +{ + XExtDisplayInfo *extinfo = XInput_find_display(dpy); + + LockDisplay(dpy); + if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) + return -1; + + /* FIXME: allow selection of GrabMode for paired devices? */ + return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0, + grab_window, None, GrabModeAsync, + GrabModeAsync, owner_events, mask, + num_modifiers, modifiers_inout); +} + + static int _XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail, Window grab_window, int num_modifiers, XIGrabModifiers *modifiers) @@ -211,3 +230,17 @@ XIUngrabFocusIn(Display* display, int deviceid, Window grab_window, return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0, grab_window, num_modifiers, modifiers); } + +int +XIUngrabTouchBegin(Display* display, int deviceid, Window grab_window, + int num_modifiers, XIGrabModifiers *modifiers) +{ + XExtDisplayInfo *extinfo = XInput_find_display(display); + + LockDisplay(display); + if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1) + return -1; + + return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0, + grab_window, num_modifiers, modifiers); +} diff --git a/src/XIint.h b/src/XIint.h index 41d99b3..e746374 100644 --- a/src/XIint.h +++ b/src/XIint.h @@ -19,6 +19,8 @@ #define XInput_Add_DevicePresenceNotify 5 #define XInput_Add_DeviceProperties 6 #define XInput_2_0 7 +#define XInput_2_1 8 +#define XInput_2_2 9 #endif #define XInput_2_1 8 |