[PATCH xf86-input-synaptics] Prefer multitouch over single-touch axis ranges

Chase Douglas chase.douglas at canonical.com
Sat Feb 11 09:05:55 PST 2012


We still use single-touch data in most cases, but sometimes the
multitouch axes have higher resolution. Since we use the same XI
valuators to report ST and MT data, we must pick one axis and scale the
other to match. This change picks the MT axis ranges.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
This occurs on bcm5974 devices, i.e. Macbook trackpads.

This needs to be fixed before any clickpad patches are applied.

 src/eventcomm.c |   38 +++++++++++++++++++++++++++++++++++---
 1 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/eventcomm.c b/src/eventcomm.c
index 6ffe265..602d74c 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -70,6 +70,10 @@ struct eventcomm_proto_data
     int axis_map[MT_ABS_SIZE];
     int cur_slot;
     ValuatorMask **last_mt_vals;
+    int st_to_mt_offset_x;
+    double st_to_mt_scale_x;
+    int st_to_mt_offset_y;
+    double st_to_mt_scale_y;
 #endif
 };
 
@@ -363,6 +367,7 @@ static void
 event_query_axis_ranges(InputInfoPtr pInfo)
 {
     SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
+    struct eventcomm_proto_data *proto_data = priv->proto_data;
     unsigned long absbits[NBITS(ABS_MAX)] = {0};
     unsigned long keybits[NBITS(KEY_MAX)] = {0};
     char buf[256] = {0};
@@ -396,6 +401,30 @@ event_query_axis_ranges(InputInfoPtr pInfo)
 		      &priv->minw, &priv->maxw,
 		      NULL, NULL);
 
+    if (priv->has_touch)
+    {
+        int st_minx = priv->minx;
+        int st_maxx = priv->maxx;
+        int st_miny = priv->miny;
+        int st_maxy = priv->maxy;
+
+        event_get_abs(pInfo, pInfo->fd, ABS_MT_POSITION_X, &priv->minx,
+                      &priv->maxx, &priv->synpara.hyst_x, &priv->resx);
+        event_get_abs(pInfo, pInfo->fd, ABS_MT_POSITION_Y, &priv->miny,
+                      &priv->maxy, &priv->synpara.hyst_y, &priv->resy);
+
+        proto_data->st_to_mt_offset_x = priv->minx - st_minx;
+        proto_data->st_to_mt_scale_x =
+            (priv->maxx - priv->minx) / (st_maxx - st_minx);
+        proto_data->st_to_mt_offset_y = priv->miny - st_miny;
+        proto_data->st_to_mt_scale_y =
+            (priv->maxy - priv->miny) / (st_maxy - st_miny);
+    } else
+    {
+        proto_data->st_to_mt_scale_x = 1;
+        proto_data->st_to_mt_scale_y = 1;
+    }
+
     SYSCALL(rc = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits));
     if (rc >= 0)
     {
@@ -569,6 +598,7 @@ EventReadHwState(InputInfoPtr pInfo,
     struct SynapticsHwState *hw = comm->hwState;
     SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
     SynapticsParameters *para = &priv->synpara;
+    struct eventcomm_proto_data *proto_data = priv->proto_data;
 
     SynapticsResetTouchHwState(hw);
 
@@ -644,10 +674,12 @@ EventReadHwState(InputInfoPtr pInfo,
 	    if (ev.code < ABS_MT_SLOT) {
 		switch (ev.code) {
 		case ABS_X:
-		    hw->x = ev.value;
+		    hw->x = ev.value * proto_data->st_to_mt_scale_x +
+			proto_data->st_to_mt_offset_x;
 		    break;
 		case ABS_Y:
-		    hw->y = ev.value;
+		    hw->y = ev.value * proto_data->st_to_mt_scale_y +
+			proto_data->st_to_mt_offset_y;
 		    break;
 		case ABS_PRESSURE:
 		    hw->z = ev.value;
@@ -816,10 +848,10 @@ EventReadDevDimensions(InputInfoPtr pInfo)
 
     if (event_query_is_touchpad(pInfo->fd, (proto_data) ? proto_data->need_grab : TRUE))
     {
-        event_query_axis_ranges(pInfo);
 #ifdef HAVE_MTDEV
         event_query_touch(pInfo);
 #endif
+        event_query_axis_ranges(pInfo);
     }
     event_query_model(pInfo->fd, &priv->model, &priv->id_vendor, &priv->id_product);
 
-- 
1.7.8.3



More information about the xorg-devel mailing list