[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-input-synaptics: Changes to 'ubuntu+1'



 debian/changelog                    |    9 
 debian/control                      |    5 
 debian/patches/127_multitouch.patch |  745 ++++++++++++++++++++++++++++++++++++
 debian/patches/series               |    1 
 4 files changed, 756 insertions(+), 4 deletions(-)

New commits:
commit 906dfcfdb5954360c69d2f713ff4462a4326e679
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Jan 19 16:39:39 2012 -0800

    releasing version 1.5.0+git20120101-1ubuntu1

diff --git a/debian/changelog b/debian/changelog
index f3e3b4a..bfebd76 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,11 +1,11 @@
-xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1) UNRELEASED; urgency=low
+xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1) precise; urgency=low
 
   * Add multitouch support
     - Add 127_multitouch.patch
   * Bump Build-Depends for x11proto-input-dev to 2.1.99.5
   * Remove obsolete dependencies on utouch-grail and old xserver-xorg-core
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:38:25 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:39:31 -0800
 
 xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1~nomt3) precise; urgency=low
 

commit 6638c4485fdcfed12f646992cb120355623c7531
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Jan 19 16:38:46 2012 -0800

    Remove obsolete dependencies on utouch-grail and old xserver-xorg-core

diff --git a/debian/changelog b/debian/changelog
index 46f068b..f3e3b4a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,8 +3,9 @@ xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1) UNRELEASED; urgency=lo
   * Add multitouch support
     - Add 127_multitouch.patch
   * Bump Build-Depends for x11proto-input-dev to 2.1.99.5
+  * Remove obsolete dependencies on utouch-grail and old xserver-xorg-core
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:35:19 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:38:25 -0800
 
 xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1~nomt3) precise; urgency=low
 
diff --git a/debian/control b/debian/control
index db9e29c..2355490 100644
--- a/debian/control
+++ b/debian/control
@@ -17,7 +17,6 @@ Build-Depends:
  xutils-dev (>= 1:7.5+4),
  x11proto-input-dev (>= 2.1.99.5),
  libmtdev-dev,
- libutouch-grail-dev
 Build-Conflicts:
  libxtst-dev
 Standards-Version: 3.9.2
@@ -31,8 +30,6 @@ Depends:
  ${shlibs:Depends},
  ${xinpdriver:Depends},
  ${misc:Depends},
- libutouch-grail1 (>= 1.0.19),
- xserver-xorg-core (>= 2:1.9.99.902-2ubuntu1)
 Conflicts: xorg-driver-synaptics
 Replaces: xorg-driver-synaptics
 Provides: ${xinpdriver:Provides}, xorg-driver-synaptics

commit 034f46c4aa1cbd4d3a35626bcfaf5bca4a058d6d
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Jan 19 16:37:05 2012 -0800

    Bump Build-Depends for x11proto-input-dev to 2.1.99.5

diff --git a/debian/changelog b/debian/changelog
index ab5fc0e..46f068b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,8 +2,9 @@ xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1) UNRELEASED; urgency=lo
 
   * Add multitouch support
     - Add 127_multitouch.patch
+  * Bump Build-Depends for x11proto-input-dev to 2.1.99.5
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:32:52 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:35:19 -0800
 
 xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1~nomt3) precise; urgency=low
 
diff --git a/debian/control b/debian/control
index 90a2f80..db9e29c 100644
--- a/debian/control
+++ b/debian/control
@@ -15,7 +15,7 @@ Build-Depends:
  pkg-config,
  quilt,
  xutils-dev (>= 1:7.5+4),
- x11proto-input-dev (>= 2.0.1-1ubuntu1),
+ x11proto-input-dev (>= 2.1.99.5),
  libmtdev-dev,
  libutouch-grail-dev
 Build-Conflicts:

commit b1e0f380abc08700f14b157ef74e8dae8874af1b
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Jan 19 16:33:36 2012 -0800

    Add multitouch support
    
    * Add multitouch support
      - Add 127_multitouch.patch

diff --git a/debian/changelog b/debian/changelog
index d792baf..ab5fc0e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1) UNRELEASED; urgency=low
+
+  * Add multitouch support
+    - Add 127_multitouch.patch
+
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 19 Jan 2012 16:32:52 -0800
+
 xserver-xorg-input-synaptics (1.5.0+git20120101-1ubuntu1~nomt3) precise; urgency=low
 
   * Fix default speed due to change in motion estimation
diff --git a/debian/patches/127_multitouch.patch b/debian/patches/127_multitouch.patch
new file mode 100644
index 0000000..ca19332
--- /dev/null
+++ b/debian/patches/127_multitouch.patch
@@ -0,0 +1,745 @@
+diff --git a/configure.ac b/configure.ac
+index bb95403..166a4f8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -64,6 +64,11 @@ AC_SUBST([sdkdir])
+ DRIVER_NAME=synaptics
+ AC_SUBST([DRIVER_NAME])
+ 
++PKG_CHECK_MODULES(XI22, [inputproto >= 2.1.99.3] [xorg-server >= 1.11.3], HAVE_XI22="yes", HAVE_XI22="no")
++if test "x$HAVE_XI22" = xyes; then
++    AC_DEFINE(HAVE_MULTITOUCH, 1, [XI2.2 available])
++fi
++
+ # -----------------------------------------------------------------------------
+ #			Configuration options
+ # -----------------------------------------------------------------------------
+@@ -116,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..05ff02b 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,19 +65,133 @@ struct eventcomm_proto_data
+      * exists for readability of the code.
+      */
+     BOOL need_grab;
++#ifdef HAVE_MTDEV
++    struct mtdev *mtdev;
++    int axis_map[MT_ABS_SIZE];
++    int cur_slot;
++    enum
++    {
++        SLOTSTATE_OPEN = 0,
++        SLOTSTATE_CLOSE,
++        SLOTSTATE_UPDATE,
++        SLOTSTATE_EMPTY,
++    } slot_state;
++    ValuatorMask *mt_mask;
++    ValuatorMask **last_mt_vals;
++#endif
+ };
+ 
+-static Bool
+-EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
++#ifdef HAVE_MTDEV
++static int
++num_slots(const struct eventcomm_proto_data *proto_data)
++{
++    int value = proto_data->mtdev->caps.slot.maximum -
++                proto_data->mtdev->caps.slot.minimum + 1;
++
++    /* If we don't know how many slots there are, assume at least 10 */
++    return value > 1 ? value : 10;
++}
++
++static int
++last_mt_vals_slot(const struct eventcomm_proto_data *proto_data)
++{
++    int value = proto_data->cur_slot - proto_data->mtdev->caps.slot.minimum;
++
++    return value < num_slots(proto_data) ? value : -1;
++}
++
++static void
++UninitializeTouch(InputInfoPtr pInfo)
+ {
+     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 (!proto_data->mtdev)
++        return;
++
++    valuator_mask_free(&proto_data->mt_mask);
++    if (proto_data->last_mt_vals)
++    {
++        int i;
++
++        for (i = 0; i < num_slots(proto_data); i++)
++            valuator_mask_free(&proto_data->last_mt_vals[i]);
++        free(proto_data->last_mt_vals);
++        proto_data->last_mt_vals = NULL;
++    }
++
++    mtdev_close(proto_data->mtdev);
++    proto_data->mtdev = NULL;
++}
++
++static void
++InitializeTouch(InputInfoPtr pInfo)
++{
++    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->proto_data;
++    int i;
++
++    proto_data->mtdev = mtdev_new_open(pInfo->fd);
++    if (!proto_data->mtdev)
++    {
++        xf86IDrvMsg(pInfo, X_WARNING,
++                    "failed to create mtdev instance, ignoring touch events\n");
++        return;
++    }
++
++    proto_data->cur_slot = proto_data->mtdev->caps.slot.value;
++
++    /* Axes 0-4 are for X, Y, and scrolling. num_mt_axes does not include X and
++     * Y. */
++    proto_data->mt_mask = valuator_mask_new(4 + priv->num_mt_axes);
++    if (!proto_data->mt_mask)
++    {
++        xf86IDrvMsg(pInfo, X_WARNING,
++                    "failed to create MT valuator mask, ignoring touch "
++                    "events\n");
++        UninitializeTouch(pInfo);
++        return;
++    }
++
++    proto_data->last_mt_vals = calloc(num_slots(proto_data),
++                                      sizeof(ValuatorMask *));
++    if (!proto_data->last_mt_vals)
++    {
++        xf86IDrvMsg(pInfo, X_WARNING,
++                    "failed to allocate MT last values mask array\n");
++        UninitializeTouch(pInfo);
++        return;
+     }
+ 
++    for (i = 0; i < num_slots(proto_data); i++)
++    {
++        int j;
++
++        proto_data->last_mt_vals[i] = valuator_mask_new(4 + priv->num_mt_axes);
++        if (!proto_data->last_mt_vals[i])
++        {
++            xf86IDrvMsg(pInfo, X_WARNING,
++                        "failed to allocate MT last values mask\n");
++            UninitializeTouch(pInfo);
++            return;
++        }
++
++        /* Axes 0-4 are for X, Y, and scrolling. num_mt_axes does not include X
++         * and Y. */
++        valuator_mask_set(proto_data->last_mt_vals[i], 0, 0);
++        valuator_mask_set(proto_data->last_mt_vals[i], 1, 0);
++        for (j = 4; j < priv->num_mt_axes; j++)
++            valuator_mask_set(proto_data->last_mt_vals[i], j, 0);
++    }
++}
++#endif
++
++static Bool
++EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
++{
++    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    struct eventcomm_proto_data *proto_data = (struct eventcomm_proto_data*)priv->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;
+@@ -88,9 +205,23 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
+ 
+     proto_data->need_grab = FALSE;
+ 
++#ifdef HAVE_MTDEV
++    InitializeTouch(pInfo);
++#endif
++
+     return TRUE;
+ }
+ 
++static Bool
++EventDeviceOffHook(InputInfoPtr pInfo)
++{
++#ifdef HAVE_MTDEV
++    UninitializeTouch(pInfo);
++#endif
++
++    return Success;
++}
++
+ /**
+  * Test if the device on the file descriptior is recognized as touchpad
+  * device. Required bits for touchpad recognition are:
+@@ -353,10 +484,20 @@ EventQueryHardware(InputInfoPtr pInfo)
+ static Bool
+ SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
+ {
++#ifdef HAVE_MTDEV
++    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    struct eventcomm_proto_data *proto_data = priv->proto_data;
++#endif
+     int rc = TRUE;
+     ssize_t len;
+ 
+-    len = read(pInfo->fd, ev, sizeof(*ev));
++#ifdef HAVE_MTDEV
++    if (proto_data->mtdev)
++        len = mtdev_get(proto_data->mtdev, pInfo->fd, ev, 1) *
++              sizeof(struct input_event);
++    else
++#endif
++        len = read(pInfo->fd, ev, sizeof(*ev));
+     if (len <= 0)
+     {
+         /* We use X_NONE here because it doesn't alloc */
+@@ -370,6 +511,87 @@ SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
+     return rc;
+ }
+ 
++static void
++EventProcessTouch(InputInfoPtr pInfo)
++{
++#ifdef HAVE_MTDEV
++    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    struct eventcomm_proto_data *proto_data = priv->proto_data;
++    int type;
++
++    if (proto_data->cur_slot < 0 || !priv->has_touch)
++        return;
++
++    /* If the ABS_MT_SLOT is the first event we get after EV_SYN, skip this */
++    if (proto_data->slot_state == SLOTSTATE_EMPTY)
++        return;
++
++    switch (proto_data->slot_state)
++    {
++        case SLOTSTATE_CLOSE:
++            type = XI_TouchEnd;
++            break;
++        case SLOTSTATE_OPEN:
++            type = XI_TouchBegin;
++            break;
++        default:
++            type = XI_TouchUpdate;
++            break;
++    }
++
++    xf86PostTouchEvent(pInfo->dev, proto_data->cur_slot, type, 0,
++                       proto_data->mt_mask);
++
++    proto_data->slot_state = SLOTSTATE_EMPTY;
++    valuator_mask_zero(proto_data->mt_mask);
++#endif
++}
++
++static void
++EventProcessTouchEvent(InputInfoPtr pInfo, struct CommData *comm,
++                       struct input_event *ev)
++{
++#ifdef HAVE_MTDEV
++    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    struct eventcomm_proto_data *proto_data = priv->proto_data;
++
++    if (ev->code == ABS_MT_SLOT)
++    {
++        EventProcessTouch(pInfo);
++        proto_data->cur_slot = ev->value;
++    } else
++    {
++        int slot_index = last_mt_vals_slot(proto_data);
++
++        if (proto_data->slot_state == SLOTSTATE_EMPTY)
++            proto_data->slot_state = SLOTSTATE_UPDATE;
++        if (ev->code == ABS_MT_TRACKING_ID)
++        {
++            if (ev->value >= 0)
++            {
++                proto_data->slot_state = SLOTSTATE_OPEN;
++
++                if (slot_index >= 0)
++                    valuator_mask_copy(proto_data->mt_mask,
++                                       proto_data->last_mt_vals[slot_index]);
++                else
++                    xf86IDrvMsg(pInfo, X_WARNING,
++                                "Attempted to copy values from out-of-range "
++                                "slot, touch events may be incorrect.\n");
++            } else
++                proto_data->slot_state = SLOTSTATE_CLOSE;
++        } else
++        {
++            int map = proto_data->axis_map[ev->code - ABS_MT_TOUCH_MAJOR];
++            valuator_mask_set(proto_data->mt_mask, map, ev->value);
++            if (slot_index >= 0)
++                valuator_mask_set(proto_data->last_mt_vals[slot_index], map,
++                                  ev->value);
++        }
++    }
++#endif
++}
++
+ /**
+  * Count the number of fingers based on the CommData information.
+  * The CommData struct contains the event information based on previous
+@@ -408,6 +630,7 @@ EventReadHwState(InputInfoPtr pInfo,
+ 	case EV_SYN:
+ 	    switch (ev.code) {
+ 	    case SYN_REPORT:
++		EventProcessTouch(pInfo);
+ 		hw->numFingers = count_fingers(comm);
+ 		hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
+ 		*hwRet = *hw;
+@@ -472,20 +695,23 @@ EventReadHwState(InputInfoPtr pInfo,
+ 	    }
+ 	    break;
+ 	case EV_ABS:
+-	    switch (ev.code) {
+-	    case ABS_X:
+-		hw->x = ev.value;
+-		break;
+-	    case ABS_Y:
+-		hw->y = ev.value;
+-		break;
+-	    case ABS_PRESSURE:
+-		hw->z = ev.value;
+-		break;
+-	    case ABS_TOOL_WIDTH:
+-		hw->fingerWidth = ev.value;
+-		break;
+-	    }
++	    if (ev.code < ABS_MT_SLOT) {
++		switch (ev.code) {
++		case ABS_X:
++		    hw->x = ev.value;
++		    break;
++		case ABS_Y:
++		    hw->y = ev.value;
++		    break;
++		case ABS_PRESSURE:
++		    hw->z = ev.value;
++		    break;
++		case ABS_TOOL_WIDTH:
++		    hw->fingerWidth = ev.value;
++		    break;
++		}
++	    } else
++		EventProcessTouchEvent(pInfo, comm, &ev);
+ 	    break;
+ 	}
+     }
+@@ -497,6 +723,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 +845,26 @@ 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;
++    proto_data->cur_slot = -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",
+@@ -584,7 +941,7 @@ EventAutoDevProbe(InputInfoPtr pInfo, const char *device)
+ 
+ struct SynapticsProtocolOperations event_proto_operations = {
+     EventDeviceOnHook,
+-    NULL,
++    EventDeviceOffHook,
+     EventQueryHardware,
+     EventReadHwState,
+     EventAutoDevProbe,
+diff --git a/src/synaptics.c b/src/synaptics.c
+index b1f2cf2..34915a2 100644
+--- a/src/synaptics.c
++++ b/src/synaptics.c
+@@ -937,8 +937,13 @@ DeviceClose(DeviceIntPtr dev)
+     return RetValue;
+ }
+ 
+-static void InitAxesLabels(Atom *labels, int nlabels)
++static void InitAxesLabels(Atom *labels, int nlabels,
++                           const SynapticsPrivate *priv)
+ {
++#ifdef HAVE_MULTITOUCH
++    int i;
++#endif
++
+     memset(labels, 0, nlabels * sizeof(Atom));
+     switch(nlabels)
+     {
+@@ -950,11 +955,20 @@ static void InitAxesLabels(Atom *labels, int nlabels)
+             labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
+ #endif
+         case 2:
+-            labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
++            labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+         case 1:
+-            labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
++            labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+             break;
+     }
++
++#ifdef HAVE_MULTITOUCH
++    for (i = 0; i < priv->num_mt_axes; i++)
++    {
++        SynapticsTouchAxisRec *axis = &priv->touch_axes[i];
++        int axnum = nlabels - priv->num_mt_axes + i;
++        labels[axnum] = XIGetKnownProperty(axis->label);
++    }
++#endif
+ }
+ 
+ static void InitButtonLabels(Atom *labels, int nlabels)
+@@ -993,14 +1007,25 @@ DeviceInit(DeviceIntPtr dev)
+     int min, max;
+     int num_axes = 2;
+     Atom btn_labels[SYN_MAX_BUTTONS] = { 0 };
+-    Atom axes_labels[4] = { 0 };
++    Atom *axes_labels;
+     DeviceVelocityPtr pVel;
+ 
+ #ifdef HAVE_SMOOTH_SCROLL
+     num_axes += 2;
+ #endif
+ 
+-    InitAxesLabels(axes_labels, num_axes);
++#ifdef HAVE_MULTITOUCH
++    num_axes += priv->num_mt_axes;
++#endif
++
++    axes_labels = calloc(num_axes, sizeof(Atom));
++    if (!axes_labels)
++    {
++        xf86IDrvMsg(pInfo, X_ERROR, "failed to allocate axis labels\n");
++        return !Success;
++    }
++
++    InitAxesLabels(axes_labels, num_axes, priv);
+     InitButtonLabels(btn_labels, SYN_MAX_BUTTONS);
+ 
+     DBG(3, "Synaptics DeviceInit called\n");
+@@ -1106,7 +1131,10 @@ DeviceInit(DeviceIntPtr dev)
+     priv->scroll_axis_vert = 3;
+     priv->scroll_events_mask = valuator_mask_new(MAX_VALUATORS);
+     if (!priv->scroll_events_mask)
++    {
++        free(axes_labels);
+         return !Success;
++    }
+ 
+     SetScrollValuator(dev, priv->scroll_axis_horiz, SCROLL_TYPE_HORIZONTAL,
+                       priv->synpara.scroll_dist_horiz, 0);
+@@ -1114,6 +1142,43 @@ DeviceInit(DeviceIntPtr dev)
+                       priv->synpara.scroll_dist_vert, 0);
+ #endif
+ 
++#ifdef HAVE_MULTITOUCH
++    if (priv->has_touch)
++    {
++        if (!InitTouchClassDeviceStruct(dev, priv->num_touches,
++                                        XIDependentTouch, priv->num_mt_axes))
++        {
++            xf86IDrvMsg(pInfo, X_ERROR,
++                        "failed to initialize touch class device\n");
++            priv->has_touch = 0;
++            goto no_touch;
++        }
++
++        for (i = 0; i < priv->num_mt_axes; i++)
++        {
++            SynapticsTouchAxisRec *axis = &priv->touch_axes[i];
++            int axnum = num_axes - priv->num_mt_axes + i;
++            Atom atom = axes_labels[axnum];
++
++            if (!xf86InitValuatorAxisStruct(dev, axnum, axes_labels[axnum],
++                                            axis->min, axis->max, axis->res, 0,
++                                            axis->res, Absolute))
++            {
++                xf86IDrvMsg(pInfo, X_WARNING,
++                            "failed to initialize axis %s, skipping\n",
++                            axis->label);
++                continue;
++            }
++
++            xf86InitValuatorDefaults(dev, axnum);
++        }
++    }
++
++no_touch:
++#endif
++
++    free(axes_labels);
++
+     if (!alloc_shm_data(pInfo))
+ 	return !Success;
+ 
+diff --git a/src/synapticsstr.h b/src/synapticsstr.h
+index d74ebcd..d3b8607 100644
+--- a/src/synapticsstr.h
++++ b/src/synapticsstr.h
+@@ -56,6 +56,14 @@ typedef struct _SynapticsMoveHist
+     CARD32 millis;
+ } SynapticsMoveHistRec;
+ 
++typedef struct _SynapticsTouchAxis
++{
++    const char *label;
++    int min;
++    int max;
++    int res;
++} SynapticsTouchAxisRec;
++
+ enum FingerState {              /* Note! The order matters. Compared with < operator. */
+     FS_BLOCKED = -1,
+     FS_UNTOUCHED = 0, /* this is 0 so it's the initialized value. */
+@@ -265,6 +273,13 @@ typedef struct _SynapticsPrivateRec
+     int scroll_axis_vert;               /* Vertical smooth-scrolling axis */
+     ValuatorMask *scroll_events_mask;   /* ValuatorMask for smooth-scrolling */
+ #endif
++
++#ifdef HAVE_MULTITOUCH
++    Bool has_touch;                     /* Device has multitouch capabilities */
++    int num_touches;                    /* Number of touches supported */
++    int num_mt_axes;                    /* Number of multitouch axes other than X, Y */
++    SynapticsTouchAxisRec *touch_axes;  /* Touch axis information other than X, Y */
++#endif
+ } SynapticsPrivate;
+ 
+ #endif /* _SYNAPTICSSTR_H_ */
+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)
+diff --git a/test/fake-symbols.c b/test/fake-symbols.c
+index 71c3bc5..361243c 100644
+--- a/test/fake-symbols.c
++++ b/test/fake-symbols.c
+@@ -450,3 +450,34 @@ Bool QueueWorkProc (
+ {
+     return FALSE;
+ }
++
++#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
++_X_EXPORT ValuatorMask  *valuator_mask_new(int num_valuators)
++{
++    return NULL;
++}
++
++_X_EXPORT void valuator_mask_free(ValuatorMask **mask)
++{
++}
++
++_X_EXPORT void valuator_mask_set(ValuatorMask *mask, int valuator, int data)
++{
++}
++
++_X_EXPORT void valuator_mask_zero(ValuatorMask *mask)
++{
++}
++
++_X_EXPORT void valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
++{
++}
++#endif
++
++#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16
++_X_EXPORT void xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid,
++                                  uint16_t type, uint32_t flags,
++                                  const ValuatorMask *mask)
++{
++}
++#endif
diff --git a/debian/patches/series b/debian/patches/series
index 87644a2..5793129 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,3 +17,4 @@
 124_syndaemon_events.patch
 125_option_rec_revert.patch
 126_default_speed.patch
+127_multitouch.patch


Reply to: