eventcomm: Initialize touch device and axes

Use mtdev to ensure touches are tracked and of evdev MT protocol type
B.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Chase Douglas
2012-01-19 13:05:48 -08:00
committed by Peter Hutterer
parent 56d32619b9
commit b1b9745979
4 changed files with 149 additions and 6 deletions

View File

@@ -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])

View File

@@ -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

View File

@@ -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",

View File

@@ -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)