From e73e2fe95dab3e0048b24d16327adbe54326ff3f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 Sep 2011 22:33:57 -0700 Subject: Implement support for XI 2.2 Adds support for the new TouchClass for multitouch-capable servers/devices. New events: XITouchOwnershipEvent New event types handled: XITouchBegin, XITouchUpdate, XITouchEnd XIRawTouchBegin, XIRawTouchUpdate, XIRawTouchEnd New functions: XIGrabTouchBegin ... passive grabs on touches XIUngrabTouchBegin XIAllowTouchEvents ... Allow/reject touch event sequences New XIQueryDevice classes: XITouchClassInfo Requires libX11 1.5 for GetReqSized Co-authored by: Chase Douglas Signed-off-by: Peter Hutterer --- src/XExtInt.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/XIAllowEvents.c | 46 +++++++++++++++++++++++++-- src/XIPassiveGrab.c | 33 +++++++++++++++++++ src/XIint.h | 1 + 4 files changed, 167 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/XExtInt.c b/src/XExtInt.c index 29ecfa3..b12886d 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; @@ -1263,6 +1286,22 @@ copyPropertyEvent(XGenericEventCookie *cookie_in, return True; } +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 #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..ac17c01 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, XIGrabModeTouch, + 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..cc46754 100644 --- a/src/XIint.h +++ b/src/XIint.h @@ -21,6 +21,7 @@ #define XInput_2_0 7 #endif #define XInput_2_1 8 +#define XInput_2_2 9 extern XExtDisplayInfo *XInput_find_display(Display *); -- cgit v1.2.3