summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac8
-rw-r--r--src/Makefile.am2
-rw-r--r--src/eventcomm.c143
-rw-r--r--test/Makefile.am2
4 files changed, 149 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac
index f8c7259..62f6ace 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,6 +121,14 @@ case "${host}" in
esac
if test "x$BUILD_EVENTCOMM" = xyes; then
AC_DEFINE(BUILD_EVENTCOMM, 1, [Optional backend eventcomm enabled])
+
+ if test "x$HAVE_XI22" = xyes; then
+ # Obtain compiler/linker options for mtdev
+ PKG_CHECK_MODULES(MTDEV, mtdev, HAVE_MTDEV="yes", HAVE_MTDEV="no")
+ fi
+ if test "x$HAVE_XI22" = xyes && test "x$HAVE_MTDEV" = xyes; then
+ AC_DEFINE(HAVE_MTDEV, 1, [MTDev available])
+ fi
fi
if test "x$BUILD_PSMCOMM" = xyes; then
AC_DEFINE(BUILD_PSMCOMM, 1, [Optional backend psmcomm enabled])
diff --git a/src/Makefile.am b/src/Makefile.am
index 5e04670..a6715e6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,6 +44,8 @@ endif
if BUILD_EVENTCOMM
@DRIVER_NAME@_drv_la_SOURCES += \
eventcomm.c eventcomm.h
+@DRIVER_NAME@_drv_la_LIBADD = \
+ $(MTDEV_LIBS)
endif
if BUILD_PSMCOMM
diff --git a/src/eventcomm.c b/src/eventcomm.c
index 00dc532..7c34bbe 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -41,6 +41,9 @@
#include "synaptics.h"
#include "synapticsstr.h"
#include <xf86.h>
+#ifdef HAVE_MTDEV
+#include <mtdev.h>
+#endif
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
@@ -62,6 +65,9 @@ struct eventcomm_proto_data
* exists for readability of the code.
*/
BOOL need_grab;
+#ifdef HAVE_MTDEV
+ int axis_map[MT_ABS_SIZE];
+#endif
};
static Bool
@@ -70,11 +76,6 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
- if (!proto_data) {
- proto_data = calloc(1, sizeof(struct eventcomm_proto_data));
- priv->proto_data = proto_data;
- }
-
if (para->grab_event_device) {
/* Try to grab the event device so that data don't leak to /dev/input/mice */
int ret;
@@ -497,6 +498,120 @@ static int EventDevOnly(const struct dirent *dir) {
return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}
+#ifdef HAVE_MTDEV
+static void
+event_query_touch(InputInfoPtr pInfo)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
+ struct eventcomm_proto_data *proto_data = priv->proto_data;
+ struct mtdev *mtdev;
+ int i;
+
+ priv->num_touches = 0;
+ priv->num_mt_axes = 0;
+
+ mtdev = mtdev_new_open(pInfo->fd);
+ if (!mtdev)
+ {
+ xf86IDrvMsg(pInfo, X_WARNING,
+ "failed to open mtdev when querying touch capabilities\n");
+ return;
+ }
+
+ for (i = 0; i < MT_ABS_SIZE; i++)
+ {
+ if (mtdev->caps.has_abs[i])
+ {
+ switch (i)
+ {
+ /* X and Y axis info is handed by synaptics already */
+ case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
+ case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
+ /* Skip tracking ID info */
+ case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
+ break;
+ default:
+ priv->num_mt_axes++;
+ break;
+ }
+ priv->has_touch = TRUE;
+ }
+ }
+
+ if (priv->has_touch)
+ {
+ int axnum;
+ static const char *labels[] =
+ {
+ AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR,
+ AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR,
+ AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR,
+ AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR,
+ AXIS_LABEL_PROP_ABS_MT_ORIENTATION,
+ AXIS_LABEL_PROP_ABS_MT_POSITION_X,
+ AXIS_LABEL_PROP_ABS_MT_POSITION_Y,
+ AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE,
+ AXIS_LABEL_PROP_ABS_MT_BLOB_ID,
+ AXIS_LABEL_PROP_ABS_MT_TRACKING_ID,
+ AXIS_LABEL_PROP_ABS_MT_PRESSURE,
+ };
+
+ if (mtdev->caps.slot.maximum > 0)
+ priv->num_touches = mtdev->caps.slot.maximum -
+ mtdev->caps.slot.minimum + 1;
+
+ priv->touch_axes = malloc(priv->num_mt_axes *
+ sizeof(SynapticsTouchAxisRec));
+ if (!priv->touch_axes)
+ {
+ priv->has_touch = FALSE;
+ goto out;
+ }
+
+ axnum = 0;
+ for (i = 0; i < MT_ABS_SIZE; i++)
+ {
+ if (mtdev->caps.has_abs[i])
+ {
+ switch (i)
+ {
+ /* X and Y axis info is handed by synaptics already, we just
+ * need to map the evdev codes to the valuator numbers */
+ case ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR:
+ proto_data->axis_map[i] = 0;
+ break;
+
+ case ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR:
+ proto_data->axis_map[i] = 1;
+ break;
+
+ /* Skip tracking ID info */
+ case ABS_MT_TRACKING_ID - ABS_MT_TOUCH_MAJOR:
+ break;
+
+ default:
+ priv->touch_axes[axnum].label = labels[i];
+ priv->touch_axes[axnum].min =
+ mtdev->caps.abs[i].minimum;
+ priv->touch_axes[axnum].max =
+ mtdev->caps.abs[i].maximum;
+ /* Kernel provides units/mm, X wants units/m */
+ priv->touch_axes[axnum].res =
+ mtdev->caps.abs[i].resolution * 1000;
+ /* Valuators 0-3 are used for X, Y, and scrolling */
+ proto_data->axis_map[i] = 4 + axnum;
+ axnum++;
+ break;
+ }
+ }
+ }
+ }
+
+out:
+ mtdev_close(mtdev);
+}
+#endif
+
/**
* Probe the open device for dimensions.
*/
@@ -505,9 +620,25 @@ EventReadDevDimensions(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
struct eventcomm_proto_data *proto_data = priv->proto_data;
+#ifdef HAVE_MTDEV
+ int i;
+#endif
+
+ proto_data = calloc(1, sizeof(struct eventcomm_proto_data));
+ priv->proto_data = proto_data;
+
+#ifdef HAVE_MTDEV
+ for (i = 0; i < MT_ABS_SIZE; i++)
+ proto_data->axis_map[i] = -1;
+#endif
if (event_query_is_touchpad(pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE))
- event_query_axis_ranges(pInfo);
+ {
+ event_query_axis_ranges(pInfo);
+#ifdef HAVE_MTDEV
+ event_query_touch(pInfo);
+#endif
+ }
event_query_model(pInfo->fd, &priv->model, &priv->id_vendor, &priv->id_product);
xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
diff --git a/test/Makefile.am b/test/Makefile.am
index 5dd8cdb..87de1ec 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -9,6 +9,8 @@ noinst_PROGRAMS = eventcomm-test
eventcomm_test_SOURCES = eventcomm-test.c\
$(top_srcdir)/src/eventcomm.c \
$(fake_syms)
+
+eventcomm_test_LDADD = $(MTDEV_LIBS)
endif
TESTS = $(noinst_PROGRAMS)