summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2010-09-20 15:03:08 +1000
committerChase Douglas <chase.douglas@ubuntu.com>2010-10-08 22:25:33 +0200
commite080d09ea9f4908b5802510f48b8453efb608b8d (patch)
treeb48311e8f7bbf7f2c82b7f5b94b6b947f17236a3
parentccbebb111fb2084716fce67cb44b5bd8b86adbbc (diff)
Add multitouch support from Xi 2.1HEADxi2.1
Add support to libXi for all the Xi 2.1 additions to the spec: TouchClass, TouchBegin, TouchEnd and TouchMotion, as well as touch grabs. Signed-off-by: Daniel Stone <daniel@fooishbar.org>
-rw-r--r--configure.ac4
-rw-r--r--include/X11/extensions/XInput2.h108
-rw-r--r--src/XExtInt.c136
-rw-r--r--src/XIAllowEvents.c29
-rw-r--r--src/XIPassiveGrab.c21
5 files changed, 295 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 2f773f9..b5a28e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to create configure.
AC_PREREQ([2.60])
-AC_INIT(libXi, 1.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXi)
+AC_INIT(libXi, 1.4, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXi)
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
@@ -24,7 +24,7 @@ AC_PROG_LIBTOOL
AC_PROG_SED
# Checks for pkg-config packages
-PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.2.99.1] [xextproto >= 7.0.3] [xext >= 1.0.99.1] [inputproto >= 1.9.99.902])
+PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.2.99.1] [xextproto >= 7.0.3] [xext >= 1.0.99.1] [inputproto >= 2.1])
# Check for xmlto and asciidoc for man page conversion
# (only needed by people building tarballs)
diff --git a/include/X11/extensions/XInput2.h b/include/X11/extensions/XInput2.h
index e6c7b30..651b459 100644
--- a/include/X11/extensions/XInput2.h
+++ b/include/X11/extensions/XInput2.h
@@ -27,6 +27,8 @@
#ifndef _XINPUT2_H_
#define _XINPUT2_H_
+#include <stdint.h>
+
#include <X11/Xlib.h>
#include <X11/extensions/XI2.h>
#include <X11/extensions/Xge.h>
@@ -135,6 +137,35 @@ typedef struct
typedef struct
{
+ uint32_t touchid;
+ uint32_t tool;
+ double x;
+ double y;
+ double touch_major;
+ double touch_minor;
+ double tool_major;
+ double tool_minor;
+ unsigned int orientation;
+} XITouchInfo;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+ int mode;
+ double min_x;
+ double max_x;
+ double min_y;
+ double max_y;
+ double min_touch_width;
+ double max_touch_width;
+ unsigned int num_touches;
+ unsigned int max_touches;
+ XITouchInfo *touches;
+} XITouchClassInfo;
+
+typedef struct
+{
int deviceid;
char *name;
int use;
@@ -292,6 +323,55 @@ typedef struct {
int what;
} XIPropertyEvent;
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if this came from SendEvent */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_TouchBegin or XI_TouchEnd */
+ Time time;
+ int deviceid; /* id of delivery device */
+ int sourceid; /* id of originating device */
+ Window root; /* root window for delivery */
+ Window event; /* window event delivered to */
+ Window child; /* window event occured in */
+ unsigned long touchid; /* unique ID for this touch */
+ unsigned long tool; /* identifier of physical tool */
+} XITouchStateEvent;
+
+typedef XITouchStateEvent XITouchBeginEvent;
+typedef XITouchStateEvent XITouchEndEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if this came from SendEvent */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_TouchStateNotify */
+ Time time; /* time event was received */
+ int deviceid; /* id of delivery device */
+ int sourceid; /* id of originating device */
+ int mask; /* fields present in this event */
+ Window root; /* root window for delivery */
+ Window event; /* window event delivered to */
+ Window child; /* window event occured in */
+ unsigned long touchid; /* unique ID for this touch */
+ unsigned long tool; /* identifier of physical tool */
+ double root_x; /* X in screen co-ords */
+ double root_y; /* Y in screen co-ords */
+ double event_x; /* X relative to event window */
+ double event_y; /* Y relative to event window */
+ double x; /* unscaled X */
+ double y; /* unscaled Y */
+ double touch_width_major; /* major axis of contact area */
+ double touch_width_minor; /* minor axis of contact area */
+ double tool_width_major; /* major axis of proximate tool */
+ double tool_width_minor; /* minor axis of proximate tool */
+ unsigned int orientation; /* orientation of tool, in degrees */
+} XITouchMotionEvent;
+
_XFUNCPROTOBEGIN
extern Bool XIQueryPointer(
@@ -415,6 +495,14 @@ extern Status XIAllowEvents(
Time time
);
+extern Status XIAllowTouchEvents(
+ Display* display,
+ int deviceid,
+ int event_mode,
+ Time time,
+ uint32_t detail
+);
+
extern int XIGrabButton(
Display* display,
int deviceid,
@@ -466,6 +554,18 @@ extern int XIGrabFocusIn(
int num_modifiers,
XIGrabModifiers *modifiers_inout
);
+
+extern int XIGrabTouchBegin(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int grab_mode,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
extern Status XIUngrabButton(
Display* display,
int deviceid,
@@ -500,6 +600,14 @@ 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 eed6637..8dff669 100644
--- a/src/XExtInt.c
+++ b/src/XExtInt.c
@@ -146,6 +146,10 @@ static int
wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie);
static int
wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie);
+static int
+wireToTouchStateEvent(xXITouchStateEvent *in, XGenericEventCookie *cookie);
+static int
+wireToTouchMotionEvent(xXITouchMotionEvent*in, XGenericEventCookie *cookie);
static /* const */ XEvent emptyevent;
@@ -268,7 +272,8 @@ static XExtensionVersion versions[] = { {XI_Absent, 0, 0},
XI_Add_DevicePresenceNotify_Minor},
{XI_Present, XI_Add_DeviceProperties_Major,
XI_Add_DeviceProperties_Minor},
-{XI_Present, XI_2_Major, XI_2_Minor}
+{XI_Present, XI_2_Major, XI_2_Minor},
+{XI_Present, XI_2_Major, XI_2_1_Minor}
};
/***********************************************************************
@@ -985,6 +990,25 @@ XInputWireToCookie(
break;
}
return ENQUEUE_EVENT;
+ case XI_TouchBegin:
+ case XI_TouchEnd:
+ *cookie = *(XGenericEventCookie*)save;
+ if (!wireToTouchStateEvent((xXITouchStateEvent*)event, cookie))
+ {
+ printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
+ ge->evtype);
+ break;
+ }
+ return ENQUEUE_EVENT;
+ case XI_TouchMotion:
+ *cookie = *(XGenericEventCookie*)save;
+ if (!wireToTouchMotionEvent((xXITouchMotionEvent*)event, cookie))
+ {
+ printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
+ ge->evtype);
+ break;
+ }
+ return ENQUEUE_EVENT;
default:
printf("XInputWireToCookie: Unknown generic event. type %d\n", ge->evtype);
@@ -1037,6 +1061,10 @@ sizeDeviceClassType(int type, int num_elements)
case XIValuatorClass:
l = sizeof(XIValuatorClassInfo);
break;
+ case XITouchClass:
+ l = sizeof(XITouchClassInfo);
+ l += num_elements * sizeof(XITouchInfo);
+ break;
default:
printf("sizeDeviceClassType: unknown type %d\n", type);
break;
@@ -1426,6 +1454,9 @@ size_classes(xXIAnyInfo* from, int nclasses)
case XIValuatorClass:
l = sizeDeviceClassType(XIValuatorClass, 0);
break;
+ case XITouchClass:
+ l = sizeDeviceClassType(XITouchClass,
+ ((xXITouchClassInfo*)any_wire)->num_touches);
}
len += l;
@@ -1526,6 +1557,51 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int nclasses)
}
break;
+ case XITouchClass:
+ {
+ XITouchClassInfo *cls_lib;
+ xXITouchClassInfo *cls_wire;
+ XITouchInfo *tp_lib;
+ xXITouchInfo *tp_wire;
+ int j;
+
+ cls_wire = (xXITouchClassInfo*)any_wire;
+ cls_lib = next_block(&ptr_lib,
+ sizeof(XITouchClassInfo) +
+ (cls_wire->num_touches *
+ sizeof(XITouchInfo)));
+
+ cls_lib->mode = cls_wire->mode;
+ /* FIXME: fractional parts */
+ cls_lib->min_x = cls_wire->min_x.integral;
+ cls_lib->max_x = cls_wire->max_x.integral;
+ cls_lib->min_y = cls_wire->min_y.integral;
+ cls_lib->max_y = cls_wire->max_y.integral;
+ cls_lib->min_touch_width =
+ cls_wire->min_touch_width.integral;
+ cls_lib->max_touch_width =
+ cls_wire->max_touch_width.integral;
+ cls_lib->max_touches = cls_wire->max_touches;
+ cls_lib->num_touches = cls_wire->num_touches;
+ cls_lib->touches = (XITouchInfo *) &cls_lib[1];
+
+ tp_lib = cls_lib->touches;
+ tp_wire = (xXITouchInfo *) &cls_wire[1];
+ for (j = 0; j < cls_wire->num_touches; j++) {
+ tp_lib->touchid = tp_wire->touchid;
+ tp_lib->tool = tp_wire->tool;
+ tp_lib->x = tp_wire->x.integral;
+ tp_lib->y = tp_wire->y.integral;
+ tp_lib->touch_major = tp_wire->touch_major.integral;
+ tp_lib->touch_minor = tp_wire->touch_minor.integral;
+ tp_lib->tool_major = tp_wire->tool_major.integral;
+ tp_lib->tool_minor = tp_wire->tool_minor.integral;
+ tp_lib->orientation = tp_wire->orientation;
+ tp_lib++;
+ tp_wire++;
+ }
+ }
+ break;
}
len += any_wire->length * 4;
ptr_wire += any_wire->length * 4;
@@ -1711,3 +1787,61 @@ wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie)
return 1;
}
+
+static int
+wireToTouchStateEvent(xXITouchStateEvent *in, XGenericEventCookie *cookie)
+{
+ XITouchStateEvent *out = malloc(sizeof(XITouchStateEvent));
+
+ cookie->data = out;
+
+ out->type = in->type;
+ 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->root = in->root;
+ out->event = in->event;
+ out->child = in->child;
+ out->touchid = in->touchid;
+ out->tool = in->tool;
+
+ return 1;
+}
+
+static int
+wireToTouchMotionEvent(xXITouchMotionEvent *in, XGenericEventCookie *cookie)
+{
+ XITouchMotionEvent *out = malloc(sizeof(XITouchMotionEvent));
+
+ cookie->data = out;
+
+ out->type = in->type;
+ 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->mask = in->mask;
+ out->root = in->root;
+ out->event = in->event;
+ out->child = in->child;
+ out->touchid = in->touchid;
+ out->root_x = FP1616toDBL(in->root_x);
+ out->root_y = FP1616toDBL(in->root_y);
+ out->event_x = FP1616toDBL(in->event_x);
+ out->event_y = FP1616toDBL(in->event_y);
+ /* FIXME: fractional values */
+ out->x = in->x.integral;
+ out->y = in->y.integral;
+ out->touch_width_major = in->touch_width_major.integral;
+ out->touch_width_minor = in->touch_width_minor.integral;
+ out->tool_width_major = in->tool_width_major.integral;
+ out->tool_width_minor = in->tool_width_minor.integral;
+ out->orientation = in->orientation;
+
+ return 1;
+}
diff --git a/src/XIAllowEvents.c b/src/XIAllowEvents.c
index 75980a0..00229c9 100644
--- a/src/XIAllowEvents.c
+++ b/src/XIAllowEvents.c
@@ -51,3 +51,32 @@ XIAllowEvents(Display *dpy, int deviceid, int event_mode, Time time)
SyncHandle();
return Success;
}
+
+Status
+XIAllowTouchEvents(Display *dpy, int deviceid, int event_mode, Time time,
+ uint32_t touchid)
+{
+ xXIAllowEventsDetailReq *req;
+
+ XExtDisplayInfo *extinfo = XInput_find_display(dpy);
+
+ LockDisplay(dpy);
+ if (_XiCheckExtInit(dpy, XInput_2_1, extinfo) == -1)
+ return (NoSuchExtension);
+
+ /* Xlib really wants the struct and req names to be the same. */
+#define X_XIAllowEventsDetail X_XIAllowEvents
+ GetReq(XIAllowEventsDetail, req);
+#undef X_XIAllowEventsDetail
+
+ req->reqType = extinfo->codes->major_opcode;
+ req->ReqType = X_XIAllowEvents;
+ req->deviceid = deviceid;
+ req->mode = event_mode;
+ req->time = time;
+ req->detail = touchid;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return Success;
+}
diff --git a/src/XIPassiveGrab.c b/src/XIPassiveGrab.c
index 8953013..6bfea82 100644
--- a/src/XIPassiveGrab.c
+++ b/src/XIPassiveGrab.c
@@ -145,6 +145,18 @@ XIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode,
modifiers_inout);
}
+int
+XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window, int grab_mode,
+ Bool owner_events, XIEventMask *mask, int num_modifiers,
+ XIGrabModifiers *modifiers_inout)
+{
+ /* FIXME: Don't send to Xi 2.0 servers. */
+ return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0,
+ grab_window, None, grab_mode, 0,
+ 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)
@@ -208,3 +220,12 @@ 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)
+{
+ /* FIXME: Don't send to Xi 2.0 servers. */
+ return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0,
+ grab_window, num_modifiers, modifiers);
+}