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

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



 ChangeLog                                    |   75 ++
 debian/changelog                             |   14 
 debian/patches/127_default_drag_lock.patch   |   13 
 debian/patches/129_clickpad.patch            |  736 +++++++++++++++++++++++++++
 debian/patches/129_tmp_pointer_drift.patch   |   47 -
 debian/patches/130_tmp_touch_count_fix.patch |  125 ----
 debian/patches/series                        |    4 
 src/eventcomm.c                              |    2 
 src/synaptics.c                              |   76 +-
 tools/synclient.c                            |    6 
 10 files changed, 874 insertions(+), 224 deletions(-)

New commits:
commit b5a27719e97629ec339285baae655d95230da31e
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Feb 23 11:54:55 2012 -0800

    releasing version 1.5.99~git20120223-0ubuntu1

diff --git a/debian/changelog b/debian/changelog
index b677cfa..58f4697 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) UNRELEASED; urgency=low
+xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) precise; urgency=low
 
   * Update to latest code in git (0a2fd56)
     - Only includes bug fixes
@@ -10,7 +10,7 @@ xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) UNRELEASED; urgency=l
   * Add ClickPad support (LP: #932947)
     - Add 129_clickpad.patch
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:46:43 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:54:37 -0800
 
 xserver-xorg-input-synaptics (1.5.99~git20120220-0ubuntu3) precise; urgency=low
 

commit e0c5070e5ff17c10b99b4bc842b4ea8d2c56fe93
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Feb 23 11:47:20 2012 -0800

    Add ClickPad support (LP: #932947)
    
    * Add ClickPad support (LP: #932947)
      - Add 129_clickpad.patch

diff --git a/debian/changelog b/debian/changelog
index f938f00..b677cfa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,8 +7,10 @@ xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) UNRELEASED; urgency=l
     - 130_tmp_touch_count_fix.patch
   * Revert tap-and-drag locking default change (LP: #934770)
     - Drop 127_default_drag_lock.patch
+  * Add ClickPad support (LP: #932947)
+    - Add 129_clickpad.patch
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:42:57 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:46:43 -0800
 
 xserver-xorg-input-synaptics (1.5.99~git20120220-0ubuntu3) precise; urgency=low
 
diff --git a/debian/patches/129_clickpad.patch b/debian/patches/129_clickpad.patch
new file mode 100644
index 0000000..9aa048a
--- /dev/null
+++ b/debian/patches/129_clickpad.patch
@@ -0,0 +1,736 @@
+diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
+index c550cef..8c20a0c 100644
+--- a/include/synaptics-properties.h
++++ b/include/synaptics-properties.h
+@@ -49,6 +49,9 @@
+ #define SYNAPTICS_PROP_TAP_DURATIONS "Synaptics Tap Durations"
+ 
+ /* 8 bit (BOOL) */
++#define SYNAPTICS_PROP_CLICKPAD "Synaptics ClickPad"
++
++/* 8 bit (BOOL) */
+ #define SYNAPTICS_PROP_TAP_FAST "Synaptics Tap FastTap"
+ 
+ /* 32 bit */
+@@ -155,6 +158,9 @@
+ /* 32 bit, 4 values, left, right, top, bottom */
+ #define SYNAPTICS_PROP_AREA "Synaptics Area"
+ 
++/* 32 bit, 4 values, left, right, top, buttom */
++#define SYNAPTICS_PROP_SOFTBUTTON_AREAS "Synaptics Soft Button Areas"
++
+ /* 32 Bit Integer, 2 values, horizontal hysteresis, vertical hysteresis */
+ #define SYNAPTICS_PROP_NOISE_CANCELLATION "Synaptics Noise Cancellation"
+ 
+diff --git a/man/synaptics.man b/man/synaptics.man
+index b6b1dce..f50b249 100644
+--- a/man/synaptics.man
++++ b/man/synaptics.man
+@@ -143,6 +143,12 @@ Maximum time (in milliseconds) for detecting a double tap. Property:
+ The duration of the mouse click generated by tapping. Property: "Synaptics Tap
+ Durations"
+ .TP 7
++.BI "Option \*qClickPad\*q \*q" boolean \*q
++Whether the device is a click pad. A click pad device has button(s) integrated
++into the touchpad surface. The user must press downward on the touchpad in order
++to generated a button press. This property may be set automatically if a click
++pad device is detected at initialization time. Property: "Synaptics ClickPad"
++.TP 7
+ .BI "Option \*qFastTaps\*q \*q" boolean \*q
+ Makes the driver react faster to a single tap, but also makes double
+ clicks caused by double tapping slower. Property: "Synaptics Tap FastTap"
+@@ -512,6 +518,20 @@ AreaBottomEdge option to any integer value other than zero. If supported by the
+ server (version 1.9 and later), the edge may be specified in percent of
+ the total height of the touchpad. Property: "Synaptics Area"
+ .
++.TP
++.BI "Option \*qSoftButtonAreas\*q \*q" "RBL RBR RBT RBB MBL MBR MBT MBB" \*q
++Enable soft button click area support on ClickPad devices. The first four
++parameters define the area of the right button, and the second four parameters
++define the area of the middle button. The areas are defined by the left, right,
++top, and bottom edges as sequential values of the property. If any edge is set
++to 0, the edge is assumed to extend to infinity in the given direction.
++.
++When the user performs a click within the defined soft button areas, the right
++or middle click action is performed.
++.
++The use of soft button areas is disabled by setting all the values for the area
++to 0. Property: "Synaptics Soft Button Areas"
++.
+ 
+ .SH CONFIGURATION DETAILS
+ .SS Area handling
+@@ -785,6 +805,10 @@ Properties supported:
+ duration of a single click.
+ 
+ .TP 7
++.BI "Synaptics ClickPad"
++8 bit (Bool).
++
++.TP 7
+ .BI "Synaptics Tap FastTap"
+ 8 bit (BOOL).
+ 
+@@ -917,6 +941,14 @@ default.
+ 32 bit, 4 values, left, right, top, bottom. 0 disables an element.
+ 
+ .TP 7
++.BI "Synaptics Soft Button Areas"
++The Right and middle soft button areas are used to support right and middle
++click actions on a ClickPad device. Providing 0 for all values of a given button
++disables the button area.
++
++32 bit, 8 values, RBL, RBR, RBT, RBB, MBL, MBR, MBT, MBB.
++
++.TP 7
+ .BI "Synaptics Capabilities"
+ This read-only property expresses the physical capability of the touchpad,
+ most notably whether the touchpad hardware supports multi-finger tapping and
+diff --git a/src/eventcomm.c b/src/eventcomm.c
+index 6147e41..92f99a9 100644
+--- a/src/eventcomm.c
++++ b/src/eventcomm.c
+@@ -526,6 +526,18 @@ SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
+     return rc;
+ }
+ 
++static Bool
++EventTouchSlotPreviouslyOpen(SynapticsPrivate *priv, int slot)
++{
++    int i;
++
++    for (i = 0; i < priv->num_active_touches; i++)
++        if (priv->open_slots[i] == slot)
++            return TRUE;
++
++    return FALSE;
++}
++
+ static void
+ EventProcessTouchEvent(InputInfoPtr pInfo, struct SynapticsHwState *hw,
+                        struct input_event *ev)
+@@ -566,8 +578,20 @@ EventProcessTouchEvent(InputInfoPtr pInfo, struct SynapticsHwState *hw,
+             int map = proto_data->axis_map[ev->code - ABS_MT_TOUCH_MAJOR];
+             valuator_mask_set(hw->mt_mask[slot_index], map, ev->value);
+             if (slot_index >= 0)
+-                valuator_mask_set(proto_data->last_mt_vals[slot_index], map,
+-                                  ev->value);
++            {
++                ValuatorMask *mask = proto_data->last_mt_vals[slot_index];
++                int last_val = valuator_mask_get(mask, map);
++
++                if (EventTouchSlotPreviouslyOpen(priv, slot_index))
++                {
++                    if (ev->code == ABS_MT_POSITION_X)
++                        hw->cumulative_dx += ev->value - last_val;
++                    else if (ev->code == ABS_MT_POSITION_Y)
++                        hw->cumulative_dy += ev->value - last_val;
++                }
++
++                valuator_mask_set(mask, map, ev->value);
++            }
+         }
+     }
+ #endif
+@@ -609,6 +633,13 @@ EventReadHwState(InputInfoPtr pInfo,
+ 
+     SynapticsResetTouchHwState(hw);
+ 
++    /* Reset cumulative values if buttons were not previously pressed */
++    if (!hw->left && !hw->right && !hw->middle)
++    {
++        hw->cumulative_dx = hw->x;
++        hw->cumulative_dy = hw->y;
++    }
++
+     while (SynapticsReadEvent(pInfo, &ev)) {
+ 	switch (ev.type) {
+ 	case EV_SYN:
+@@ -713,6 +744,7 @@ static void
+ event_query_touch(InputInfoPtr pInfo)
+ {
+     SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
++    SynapticsParameters *para = &priv->synpara;
+     struct eventcomm_proto_data *proto_data = priv->proto_data;
+     struct mtdev *mtdev;
+     int i;
+@@ -727,7 +759,13 @@ event_query_touch(InputInfoPtr pInfo)
+     {
+         xf86IDrvMsg(pInfo, X_INFO,
+                     "ignoring touch events for semi-multitouch device\n");
+-        return;
++        priv->has_semi_mt = TRUE;
++    }
++
++    if (rc >= 0 && BitIsOn(&prop, INPUT_PROP_BUTTONPAD))
++    {
++        xf86IDrvMsg(pInfo, X_INFO, "found clickpad property\n");
++        para->clickpad = TRUE;
+     }
+ 
+     mtdev = mtdev_new_open(pInfo->fd);
+diff --git a/src/properties.c b/src/properties.c
+index 0a52801..3828229 100644
+--- a/src/properties.c
++++ b/src/properties.c
+@@ -58,6 +58,7 @@ Atom prop_finger                = 0;
+ Atom prop_tap_time              = 0;
+ Atom prop_tap_move              = 0;
+ Atom prop_tap_durations         = 0;
++Atom prop_clickpad              = 0;
+ Atom prop_tap_fast              = 0;
+ Atom prop_middle_timeout        = 0;
+ Atom prop_twofinger_pressure    = 0;
+@@ -91,6 +92,7 @@ Atom prop_gestures              = 0;
+ Atom prop_capabilities          = 0;
+ Atom prop_resolution            = 0;
+ Atom prop_area                  = 0;
++Atom prop_softbutton_areas      = 0;
+ Atom prop_noise_cancellation    = 0;
+ Atom prop_product_id            = 0;
+ Atom prop_device_node           = 0;
+@@ -189,6 +191,8 @@ InitDeviceProperties(InputInfoPtr pInfo)
+     values[2] = para->click_time;
+ 
+     prop_tap_durations = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_DURATIONS, 32, 3, values);
++    prop_clickpad = InitAtom(pInfo->dev, SYNAPTICS_PROP_CLICKPAD, 8, 1,
++                             &para->clickpad);
+     prop_tap_fast = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_FAST, 8, 1, &para->fast_taps);
+     prop_middle_timeout = InitAtom(pInfo->dev, SYNAPTICS_PROP_MIDDLE_TIMEOUT,
+                                    32, 1, &para->emulate_mid_button_time);
+@@ -297,6 +301,16 @@ InitDeviceProperties(InputInfoPtr pInfo)
+     values[3] = para->area_bottom_edge;
+     prop_area = InitAtom(pInfo->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
+ 
++    values[0] = para->softbutton_right_left_edge;
++    values[1] = para->softbutton_right_right_edge;
++    values[2] = para->softbutton_right_top_edge;
++    values[3] = para->softbutton_right_bottom_edge;
++    values[4] = para->softbutton_middle_left_edge;
++    values[5] = para->softbutton_middle_right_edge;
++    values[6] = para->softbutton_middle_top_edge;
++    values[7] = para->softbutton_middle_bottom_edge;
++    prop_softbutton_areas = InitAtom(pInfo->dev, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 8, values);
++
+     values[0] = para->hyst_x;
+     values[1] = para->hyst_y;
+     prop_noise_cancellation = InitAtom(pInfo->dev,
+@@ -392,7 +406,11 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
+         para->single_tap_timeout = timeouts[0];
+         para->tap_time_2         = timeouts[1];
+         para->click_time         = timeouts[2];
++    } else if (property == prop_clickpad) {
++        if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
++            return BadMatch;
+ 
++        para->clickpad = *(BOOL*)prop->data;
+     } else if (property == prop_tap_fast)
+     {
+         if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
+@@ -704,6 +722,25 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
+         para->area_right_edge  = area[1];
+         para->area_top_edge    = area[2];
+         para->area_bottom_edge = area[3];
++    } else if (property == prop_softbutton_areas)
++    {
++        INT32 *areas;
++
++        if (prop->size != 8 || prop->format != 32 || prop->type != XA_INTEGER)
++            return BadMatch;
++
++        areas = (INT32*)prop->data;
++        if (!SynapticsIsSoftButtonAreasValid(areas))
++            return BadValue;
++
++        para->softbutton_right_left_edge    = areas[0];
++        para->softbutton_right_right_edge   = areas[1];
++        para->softbutton_right_top_edge     = areas[2];
++        para->softbutton_right_bottom_edge  = areas[3];
++        para->softbutton_middle_left_edge   = areas[4];
++        para->softbutton_middle_right_edge  = areas[5];
++        para->softbutton_middle_top_edge    = areas[6];
++        para->softbutton_middle_bottom_edge = areas[7];
+     } else if (property == prop_noise_cancellation) {
+         INT32 *hyst;
+         if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
+diff --git a/src/synaptics.c b/src/synaptics.c
+index 4784157..139f237 100644
+--- a/src/synaptics.c
++++ b/src/synaptics.c
+@@ -410,6 +410,127 @@ static int set_percent_option(pointer options, const char* optname,
+     return result;
+ }
+ 
++Bool SynapticsIsSoftButtonAreasValid(int *values)
++{
++    Bool right_disabled = FALSE;
++    Bool middle_disabled = FALSE;
++
++    /* Check right button area */
++    if ((((values[0] != 0) && (values[1] != 0)) && (values[0] > values[1])) ||
++        (((values[2] != 0) && (values[3] != 0)) && (values[2] > values[3])))
++        return FALSE;
++
++    /* Check middle button area */
++    if ((((values[4] != 0) && (values[5] != 0)) && (values[4] > values[5])) ||
++        (((values[6] != 0) && (values[7] != 0)) && (values[6] > values[7])))
++        return FALSE;
++
++    if (values[0] == 0 && values[1] == 0 && values[2] == 0 && values[3] == 0)
++        right_disabled = TRUE;
++
++    if (values[4] == 0 && values[5] == 0 && values[6] == 0 && values[7] == 0)
++        middle_disabled = TRUE;
++
++    /* Check for overlapping button areas */
++    if (!right_disabled && !middle_disabled)
++    {
++        int right_left = values[0] ? values[0] : -INT_MAX;
++        int right_right = values[1] ? values[1] : INT_MAX;
++        int right_top = values[2] ? values[2] : -INT_MAX;
++        int right_bottom = values[3] ? values[3] : INT_MAX;
++        int middle_left = values[4] ? values[4] : -INT_MAX;
++        int middle_right = values[5] ? values[5] : INT_MAX;
++        int middle_top = values[6] ? values[6] : -INT_MAX;
++        int middle_bottom = values[7] ? values[7] : INT_MAX;
++
++        /* If areas overlap in the Y axis */
++        if ((right_bottom <= middle_bottom && right_bottom >= middle_top) ||
++            (right_top <= middle_bottom && right_top >= middle_top))
++        {
++            /* Check for identical right and left edges */
++            if (right_left == middle_left || right_right == middle_right)
++                return FALSE;
++
++            /* Check for overlapping left edges */
++            if ((right_left < middle_left && right_right >= middle_left) ||
++                (middle_left < right_left && middle_right >= right_left))
++                return FALSE;
++
++            /* Check for overlapping right edges */
++            if ((right_right > middle_right && right_left <= middle_right) ||
++                (middle_right > right_right && middle_left <= right_right))
++                return FALSE;
++        }
++
++        /* If areas overlap in the X axis */
++        if ((right_left >= middle_left && right_left <= middle_right) ||
++            (right_right >= middle_left && right_right <= middle_right))
++        {
++            /* Check for overlapping top edges */
++            if ((right_top < middle_top && right_bottom >= middle_top) ||
++                (middle_top < right_top && middle_bottom >= right_top))
++                return FALSE;
++
++            /* Check for overlapping bottom edges */
++            if ((right_bottom > middle_bottom && right_top <= middle_bottom) ||
++                (middle_bottom > right_bottom && middle_top <= right_bottom))
++                return FALSE;
++        }
++    }
++
++    return TRUE;
++}
++
++static void set_softbutton_areas_option(InputInfoPtr pInfo)
++{
++    SynapticsPrivate *priv = pInfo->private;
++    SynapticsParameters *pars = &priv->synpara;
++    int values[8];
++    char *option_string;
++    char *next_num;
++    char *end_str;
++    int i;
++
++    option_string = xf86CheckStrOption(pInfo->options, "SoftButtonAreas", NULL);
++    if (!option_string)
++        return;
++
++    next_num = option_string;
++
++    for (i = 0; i < 8 && *next_num != '\0'; i++)
++    {
++        long int value = strtol(next_num, &end_str, 0);
++        if (value > INT_MAX || value < -INT_MAX)
++            goto fail;
++
++        values[i] = value;
++
++        if (next_num != end_str)
++            next_num = end_str;
++        else
++            goto fail;
++    }
++
++    if (i < 8 || *next_num != '\0' || !SynapticsIsSoftButtonAreasValid(values))
++        goto fail;
++
++    pars->softbutton_right_left_edge = values[0];
++    pars->softbutton_right_right_edge = values[1];
++    pars->softbutton_right_top_edge = values[2];
++    pars->softbutton_right_bottom_edge = values[3];
++    pars->softbutton_middle_left_edge = values[4];
++    pars->softbutton_middle_right_edge = values[5];
++    pars->softbutton_middle_top_edge = values[6];
++    pars->softbutton_middle_bottom_edge = values[7];
++
++    return;
++
++fail:
++    xf86IDrvMsg(pInfo, X_WARNING, "invalid SoftButtonAreas value '%s'\n",
++                option_string);
++}
++                                      
++
+ static void set_default_parameters(InputInfoPtr pInfo)
+ {
+     SynapticsPrivate *priv = pInfo->private; /* read-only */
+@@ -534,6 +655,7 @@ static void set_default_parameters(InputInfoPtr pInfo)
+     pars->tap_move = xf86SetIntOption(opts, "MaxTapMove", tapMove);
+     pars->tap_time_2 = xf86SetIntOption(opts, "MaxDoubleTapTime", 180);
+     pars->click_time = xf86SetIntOption(opts, "ClickTime", 100);
++    pars->clickpad = xf86SetIntOption(opts, "ClickPad", pars->clickpad); /* Probed */
+     pars->fast_taps = xf86SetBoolOption(opts, "FastTaps", FALSE);
+     pars->emulate_mid_button_time = xf86SetIntOption(opts, "EmulateMidButtonTime", 75);
+     pars->emulate_twofinger_z = xf86SetIntOption(opts, "EmulateTwoFingerMinZ", emulateTwoFingerMinZ);
+@@ -601,6 +723,8 @@ static void set_default_parameters(InputInfoPtr pInfo)
+ 	pars->bottom_edge = tmp;
+ 	xf86IDrvMsg(pInfo, X_WARNING, "TopEdge is bigger than BottomEdge. Fixing.\n");
+     }
++
++    set_softbutton_areas_option(pInfo);
+ }
+ 
+ #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14
+@@ -1354,6 +1478,60 @@ is_inside_active_area(SynapticsPrivate *priv, int x, int y)
+     return inside_area;
+ }
+ 
++static Bool
++is_inside_rightbutton_area(SynapticsParameters *para, int x, int y)
++{
++    Bool inside_area = TRUE;
++
++    if (para->softbutton_right_left_edge == 0 &&
++        para->softbutton_right_right_edge == 0 &&
++        para->softbutton_right_top_edge == 0 &&
++        para->softbutton_right_bottom_edge == 0)
++        return FALSE;
++
++    if (para->softbutton_right_left_edge &&
++        x < para->softbutton_right_left_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_right_right_edge &&
++             x > para->softbutton_right_right_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_right_top_edge &&
++             y < para->softbutton_right_top_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_right_bottom_edge &&
++             y > para->softbutton_right_bottom_edge)
++	inside_area = FALSE;
++
++    return inside_area;
++}
++
++static Bool
++is_inside_middlebutton_area(SynapticsParameters *para, int x, int y)
++{
++    Bool inside_area = TRUE;
++
++    if (para->softbutton_middle_left_edge == 0 &&
++        para->softbutton_middle_right_edge == 0 &&
++        para->softbutton_middle_top_edge == 0 &&
++        para->softbutton_middle_bottom_edge == 0)
++        return FALSE;
++
++    if (para->softbutton_middle_left_edge &&
++        x < para->softbutton_middle_left_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_middle_right_edge &&
++             x > para->softbutton_middle_right_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_middle_top_edge &&
++             y < para->softbutton_middle_top_edge)
++	inside_area = FALSE;
++    else if (para->softbutton_middle_bottom_edge &&
++             y > para->softbutton_middle_bottom_edge)
++	inside_area = FALSE;
++
++    return inside_area;
++}
++
+ static CARD32
+ timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
+ {
+@@ -1410,6 +1588,14 @@ ReadInput(InputInfoPtr pInfo)
+     SynapticsResetTouchHwState(hw);
+ 
+     while (SynapticsGetHwState(pInfo, priv, hw)) {
++	/* Semi-mt device touch slots do not track touches. When there is a
++	 * change in the number of touches, we must disregard the temporary
++	 * motion changes. */
++	if (priv->has_semi_mt && hw->numFingers != priv->hwState->numFingers) {
++	    hw->cumulative_dx = priv->hwState->cumulative_dx;
++	    hw->cumulative_dy = priv->hwState->cumulative_dy;
++	}
++
+ 	SynapticsCopyHwState(priv->hwState, hw);
+ 	delay = HandleState(pInfo, hw, hw->millis, FALSE);
+ 	newDelay = TRUE;
+@@ -1691,7 +1877,7 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 		    Bool inside_active_area)
+ {
+     SynapticsParameters *para = &priv->synpara;
+-    Bool touch, release, is_timeout, move;
++    Bool touch, release, is_timeout, move, press;
+     int timeleft, timeout;
+     edge_type edge;
+     int delay = 1000000000;
+@@ -1705,6 +1891,7 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 	     (priv->tap_max_fingers <= ((priv->horiz_scroll_twofinger_on || priv->vert_scroll_twofinger_on)? 2 : 1)) &&
+ 	     ((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
+ 	     (abs(hw->y - priv->touch_on.y) >= para->tap_move)));
++    press = (hw->left || hw->right || hw->middle);
+ 
+     if (touch) {
+ 	priv->touch_on.x = hw->x;
+@@ -1727,6 +1914,10 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 	    SetTapState(priv, TS_1, now);
+ 	break;
+     case TS_1:
++	if (para->clickpad && press) {
++	    SetTapState(priv, TS_CLICKPAD_MOVE, now);
++	    goto restart;
++	}
+ 	if (move) {
+ 	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
+ 	    SetTapState(priv, TS_MOVE, now);
+@@ -1750,6 +1941,10 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 	}
+ 	break;
+     case TS_MOVE:
++	if (para->clickpad && press) {
++	    SetTapState(priv, TS_CLICKPAD_MOVE, now);
++	    goto restart;
++	}
+ 	if (move && priv->moving_state == MS_TRACKSTICK) {
+ 	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
+ 	}
+@@ -1804,6 +1999,10 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 	}
+ 	break;
+     case TS_DRAG:
++	if (para->clickpad && press) {
++	    SetTapState(priv, TS_CLICKPAD_MOVE, now);
++	    goto restart;
++	}
+ 	if (move)
+ 	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
+ 	if (release) {
+@@ -1832,6 +2031,23 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
+ 	    SetTapState(priv, TS_START, now);
+ 	}
+ 	break;
++    case TS_CLICKPAD_MOVE:
++	/* Disable scrolling once a button is pressed on a clickpad */
++	priv->vert_scroll_edge_on = FALSE;
++	priv->horiz_scroll_edge_on = FALSE;
++	priv->vert_scroll_twofinger_on = FALSE;
++	priv->horiz_scroll_twofinger_on = FALSE;
++
++        /* Assume one touch is only for holding the clickpad button down */
++	if (hw->numFingers > 1)
++	    hw->numFingers--;
++	SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
++	if (!press) {
++	    SetMovingState(priv, MS_FALSE, now);
++	    SetTapState(priv, TS_MOVE, now);
++	    priv->count_packet_finger = 0;
++	}
++	break;
+     }
+ 
+     timeout = GetTimeOut(priv);
+@@ -1954,9 +2170,8 @@ get_delta(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
+     int x_edge_speed = 0;
+     int y_edge_speed = 0;
+ 
+-    /* HIST is full enough: priv->count_packet_finger > 3 */
+-    *dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x);
+-    *dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y);
++    *dx = hw->x - HIST(0).x;
++    *dy = hw->y - HIST(0).y;
+ 
+     if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always)
+         get_edge_speed(priv, hw, edge, &x_edge_speed, &y_edge_speed);
+@@ -2025,7 +2240,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
+      * POLL_MS declaration. */
+     delay = MIN(delay, POLL_MS);
+ 
+-    if (priv->count_packet_finger <= 3) /* min. 3 packets, see get_delta() */
++    if (priv->count_packet_finger <= 1)
+         goto out; /* skip the lot */
+ 
+     if (priv->moving_state == MS_TRACKSTICK)
+@@ -2467,8 +2682,24 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
+     /* 3rd button emulation */
+     hw->middle |= HandleMidButtonEmulation(priv, hw, now, delay);
+ 
++    /* If this is a clickpad and the user clicks in a soft button area, press
++     * the soft button instead. */
++    if (para->clickpad && hw->left && !hw->right && !hw->middle)
++    {
++        if (is_inside_rightbutton_area(para, hw->x, hw->y))
++        {
++            hw->left = 0;
++            hw->right = 1;
++        }
++        else if (is_inside_middlebutton_area(para, hw->x, hw->y))
++        {
++            hw->left = 0;
++            hw->middle = 1;
++        }
++    }
++
+     /* Fingers emulate other buttons */
+-    if(hw->left && hw->numFingers >= 1){
++    if(!para->clickpad && hw->left && hw->numFingers >= 1){
+         handle_clickfinger(para, hw);
+     }
+ 
+@@ -2643,10 +2874,12 @@ HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw)
+     Bool restart_touches = FALSE;
+     int i;
+ 
+-    if (para->click_action[F3_CLICK1] || para->tap_action[F3_TAP])
++    if ((!para->clickpad && para->click_action[F3_CLICK1]) ||
++        para->tap_action[F3_TAP])
+         min_touches = 4;
+-    else if (para->click_action[F2_CLICK1] || para->tap_action[F2_TAP] ||
+-             para->scroll_twofinger_vert || para->scroll_twofinger_horiz)
++    else if ((!para->clickpad && para->click_action[F2_CLICK1]) ||
++             para->tap_action[F2_TAP] || para->scroll_twofinger_vert ||
++             para->scroll_twofinger_horiz)
+         min_touches = 3;
+ 
+     /* Count new number of active touches */
+@@ -2658,6 +2891,9 @@ HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw)
+             new_active_touches--;
+     }
+ 
++    if (priv->has_semi_mt)
++        goto out;
++
+     if (priv->num_active_touches < min_touches &&
+         new_active_touches < min_touches)
+     {
+@@ -2751,6 +2987,14 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
+ 	return delay;
+     }
+ 
++    /* If a physical button is pressed on a clickpad, use cumulative relative
++     * touch movements for motion */
++    if (para->clickpad && (hw->left || hw->right || hw->middle))
++    {
++        hw->x = hw->cumulative_dx;
++        hw->y = hw->cumulative_dy;
++    }
++
+     /* apply hysteresis before doing anything serious. This cancels
+      * out a lot of noise which might surface in strange phenomena
+      * like flicker in scrolling or noise motion. */
+diff --git a/src/synapticsstr.h b/src/synapticsstr.h
+index ba1eb13..baee4d9 100644
+--- a/src/synapticsstr.h
++++ b/src/synapticsstr.h
+@@ -99,7 +99,8 @@ enum TapState {
+     TS_3,			/* After second touch */
+     TS_DRAG,			/* Pointer drag enabled */
+     TS_4,			/* After release when "locked drags" enabled */
+-    TS_5			/* After touch when "locked drags" enabled */
++    TS_5,			/* After touch when "locked drags" enabled */
++    TS_CLICKPAD_MOVE,		/* After left button press on a clickpad */
+ };
+ 
+ enum TapButtonState {
+@@ -125,6 +126,7 @@ typedef struct _SynapticsParameters
+     int single_tap_timeout;		    /* timeout to recognize a single tap */
+     int tap_time_2;			    /* max. tapping time for double taps */
+     int click_time;			    /* The duration of a single click */
++    Bool clickpad;                          /* Device is a has integrated buttons */
+     Bool fast_taps;			    /* Faster reaction to single taps */
+     int emulate_mid_button_time;	    /* Max time between left and right button presses to
+ 					       emulate a middle button press. */
+@@ -178,6 +180,14 @@ typedef struct _SynapticsParameters
+     unsigned int resolution_horiz;          /* horizontal resolution of touchpad in units/mm */
+     unsigned int resolution_vert;           /* vertical resolution of touchpad in units/mm */
+     int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
++    int softbutton_right_left_edge;
++    int softbutton_right_right_edge;
++    int softbutton_right_top_edge;
++    int softbutton_right_bottom_edge;
++    int softbutton_middle_left_edge;
++    int softbutton_middle_right_edge;
++    int softbutton_middle_top_edge;
++    int softbutton_middle_bottom_edge;       /* soft button area coordinates absolute */
+     int hyst_x, hyst_y;                     /* x and y width of hysteresis box */
+ } SynapticsParameters;
+ 
+@@ -265,6 +275,7 @@ typedef struct _SynapticsPrivateRec
+     Bool has_pressure;			/* device reports pressure */
+     Bool has_width;			/* device reports finger width */
+     Bool has_scrollbuttons;		/* device has physical scrollbuttons */
++    Bool has_semi_mt;			/* device is only semi-multitouch capable */
+ 
+     enum TouchpadModel model;		/* The detected model */
+     unsigned short id_vendor;		/* vendor id */
+diff --git a/src/synproto.c b/src/synproto.c
+index 0426e8f..e945f1e 100644
+--- a/src/synproto.c
++++ b/src/synproto.c
+@@ -120,6 +120,8 @@ SynapticsCopyHwState(struct SynapticsHwState *dst,
+     dst->x = src->x;
+     dst->y = src->y;
+     dst->z = src->z;
++    dst->cumulative_dx = src->cumulative_dx;
++    dst->cumulative_dy = src->cumulative_dy;
+     dst->numFingers = src->numFingers;
+     dst->fingerWidth = src->fingerWidth;
+     dst->left = src->left;
+diff --git a/src/synproto.h b/src/synproto.h
+index 89392ac..3b9f803 100644
+--- a/src/synproto.h
++++ b/src/synproto.h
+@@ -53,6 +53,8 @@ struct SynapticsHwState {
+     int x;			/* X position of finger */
+     int y;			/* Y position of finger */
+     int z;			/* Finger pressure */
++    int cumulative_dx;		/* Cumulative delta X for clickpad dragging */
++    int cumulative_dy;		/* Cumulative delta Y for clickpad dragging */
+     int numFingers;
+     int fingerWidth;
+ 
+@@ -115,4 +117,6 @@ extern void SynapticsCopyHwState(struct SynapticsHwState *dst,
+                                  const struct SynapticsHwState *src);
+ extern void SynapticsResetTouchHwState(struct SynapticsHwState *hw);
+ 
++extern Bool SynapticsIsSoftButtonAreasValid(int *values);
++
+ #endif /* _SYNPROTO_H_ */
+diff --git a/test/fake-symbols.c b/test/fake-symbols.c
+index 7f3f0ac..65fad46 100644
+--- a/test/fake-symbols.c
++++ b/test/fake-symbols.c
+@@ -461,6 +461,11 @@ _X_EXPORT void valuator_mask_free(ValuatorMask **mask)
+ {
+ }
+ 
++_X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valuator)
++{
++    return 0;
++}
++
+ _X_EXPORT void valuator_mask_set(ValuatorMask *mask, int valuator, int data)
+ {
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 8468d55..3e900cb 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -18,3 +18,4 @@
 125_option_rec_revert.patch
 126_ubuntu_xi22.patch
 128_disable_three_click_action.patch
+129_clickpad.patch

commit 68e1c9857ffbfda13fefe4b6119e49c3ff55e0db
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Feb 23 11:44:41 2012 -0800

    Revert tap-and-drag locking default change (LP: #934770)
    
    * Revert tap-and-drag locking default change (LP: #934770)
      - Drop 127_default_drag_lock.patch

diff --git a/debian/changelog b/debian/changelog
index 998947c..f938f00 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,8 +5,10 @@ xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) UNRELEASED; urgency=l
   * Drop temporary patches that have been merged upstream:
     - 129_tmp_pointer_drift.patch
     - 130_tmp_touch_count_fix.patch
+  * Revert tap-and-drag locking default change (LP: #934770)
+    - Drop 127_default_drag_lock.patch
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:41:54 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:42:57 -0800
 
 xserver-xorg-input-synaptics (1.5.99~git20120220-0ubuntu3) precise; urgency=low
 
diff --git a/debian/patches/127_default_drag_lock.patch b/debian/patches/127_default_drag_lock.patch
deleted file mode 100644
index d1c1823..0000000
--- a/debian/patches/127_default_drag_lock.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: xserver-xorg-input-synaptics/src/synaptics.c
-===================================================================
---- xserver-xorg-input-synaptics.orig/src/synaptics.c	2012-02-13 20:28:22.178606998 -0800
-+++ xserver-xorg-input-synaptics/src/synaptics.c	2012-02-13 20:28:22.438610574 -0800
-@@ -558,7 +558,7 @@
-     }
-     pars->scroll_button_repeat = xf86SetIntOption(opts,"ScrollButtonRepeat", 100);
-     pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", 0);
--    pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", FALSE);
-+    pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", TRUE);
-     pars->locked_drag_time = xf86SetIntOption(opts, "LockedDragTimeout", 5000);
-     pars->tap_action[RT_TAP] = xf86SetIntOption(opts, "RTCornerButton", 2);
-     pars->tap_action[RB_TAP] = xf86SetIntOption(opts, "RBCornerButton", 3);
diff --git a/debian/patches/series b/debian/patches/series
index 00409ad..8468d55 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,5 +17,4 @@
 124_syndaemon_events.patch
 125_option_rec_revert.patch
 126_ubuntu_xi22.patch
-127_default_drag_lock.patch
 128_disable_three_click_action.patch

commit 7e5584cda2abd3531387c129e7373cf3fa3a9110
Author: Chase Douglas <chase.douglas@canonical.com>
Date:   Thu Feb 23 11:42:31 2012 -0800

    Drop temporary patches that have been merged upstream:
    
    * Drop temporary patches that have been merged upstream:
      - 129_tmp_pointer_drift.patch
      - 130_tmp_touch_count_fix.patch

diff --git a/debian/changelog b/debian/changelog
index 7d7c6a0..998947c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,8 +2,11 @@ xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) UNRELEASED; urgency=l
 
   * Update to latest code in git (0a2fd56)
     - Only includes bug fixes
+  * Drop temporary patches that have been merged upstream:
+    - 129_tmp_pointer_drift.patch
+    - 130_tmp_touch_count_fix.patch
 
- -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:40:08 -0800
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Thu, 23 Feb 2012 11:41:54 -0800
 
 xserver-xorg-input-synaptics (1.5.99~git20120220-0ubuntu3) precise; urgency=low
 
diff --git a/debian/patches/129_tmp_pointer_drift.patch b/debian/patches/129_tmp_pointer_drift.patch
deleted file mode 100644
index 720da4f..0000000
--- a/debian/patches/129_tmp_pointer_drift.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Peter Hutterer <peter.hutterer@who-t.net>
-To: "X.Org Devel List" <xorg-devel@lists.freedesktop.org>
-Subject: [PATCH synaptics] Revert "Don't store fake events in the motion
-	history"
-Cc: Daniel Stone <daniel@freedesktop.org>
-
-This commit introduced a regression. On some touchpads, the pointer keeps
-moving in the last direction when the finger movement stops but the finger
-is left on the touchpad.
-
-Cause appears to be get_delta() which calculates the deltas based on the
-motion history but has no control flow for the lack of fake motion events
-in the history after this commit. Thus, under some conditions, the delta is
-always non-zero as the history does not change.
-
-Reproducer attached to bug
-https://bugs.freedesktop.org/show_bug.cgi?id=45278#c11
-
-X.Org Bug 45278 <http://bugs.freedesktop.org/show_bug.cgi?id=45278>
-
-This reverts commit c8b098214b44cf0585d78c460401ea7d143769f3.
-
-Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
----
-There is probably a more extensive fix, starting with figuring out why the
-timer still fires after enough movement to adding hooks for ignoring the
-motion history if we're from a timer. This requires more time that I have
-available atm.
-
- src/synaptics.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/src/synaptics.c b/src/synaptics.c
-index 7b3f680..65b48ee 100644
---- a/src/synaptics.c
-+++ b/src/synaptics.c
-@@ -2887,7 +2887,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
-     priv->lastButtons = buttons;
- 
-     /* generate a history of the absolute positions */
--    if (inside_active_area && !from_timer)
-+    if (inside_active_area)
- 	store_history(priv, hw->x, hw->y, hw->millis);
-     return delay;
- }
--- 
-1.7.7.5
diff --git a/debian/patches/130_tmp_touch_count_fix.patch b/debian/patches/130_tmp_touch_count_fix.patch
deleted file mode 100644
index 6d33056..0000000
--- a/debian/patches/130_tmp_touch_count_fix.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 5739a101d2f96ba4a0854202017d31f2b3dfee26 Mon Sep 17 00:00:00 2001
-From: Chase Douglas <chase.douglas@canonical.com>
-Date: Tue, 21 Feb 2012 15:54:00 +0100
-Subject: [PATCH] Update touch state when device is off too
-
-If the device is turned off, usually by syndaemon to disable the
-touchpad while the typing, the touch state will not be updated with the
-latest hardware state changes. If a touch begins while the device is
-off and ends while the device is on, then the touch count will be
-decremented without any previous increment. A similar effect will occur
-if the device is on when the touch begins, but off when the touch ends.
-
-If the touch count goes negative, the index into the touch slot mask
-array will be out of bounds. This can corrupt memory and cause random
-crashes.
-
-Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
----
- src/synaptics.c |   74 ++++++++++++++++++++++++++++++------------------------
- 1 files changed, 41 insertions(+), 33 deletions(-)
-
-diff --git a/src/synaptics.c b/src/synaptics.c
-index 7b3f680..c736b6a 100644
---- a/src/synaptics.c
-+++ b/src/synaptics.c
-@@ -2596,6 +2596,42 @@ repeat_scrollbuttons(const InputInfoPtr pInfo,
-     return delay;
- }
- 
-+/* Update the open slots and number of active touches */
-+static void
-+UpdateTouchState(InputInfoPtr pInfo, struct SynapticsHwState *hw)
-+{
-+#ifdef HAVE_MULTITOUCH
-+    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
-+    int i;
-+
-+    for (i = 0; i < hw->num_mt_mask; i++)
-+    {
-+        if (hw->slot_state[i] == SLOTSTATE_OPEN)
-+        {
-+            priv->open_slots[priv->num_active_touches] = i;
-+            priv->num_active_touches++;


Reply to: