diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/ChangeLog xserver-xorg-input-synaptics-1.5.99~git20120223/ChangeLog --- xserver-xorg-input-synaptics-1.5.99~git20120220/ChangeLog 2012-02-20 10:11:12.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/ChangeLog 2012-02-23 19:48:35.000000000 +0000 @@ -1,3 +1,78 @@ +commit 0a2fd560aa965ceac64c8fb047ca90006408a6f4 +Author: Chase Douglas +Date: Tue Feb 21 21:42:16 2012 +0100 + + 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 + Signed-off-by: Peter Hutterer + +commit dfc3a8ed713c2878407c6443c4d3092da3125e0c +Author: Peter Hutterer +Date: Tue Feb 21 11:32:40 2012 +1000 + + synclient: accept XA_CARDINAL as 32-bit type (#46330) + + PressureMotionMaxZ and PressureMotionMinZ were changed from float to + XA_CARDINAL in 24c44375025576dd600ccf370ba365e5d94dc22. Accept the new type. + + Fixes: + PressureMotionMinZ = format mismatch (32) + PressureMotionMaxZ = format mismatch (32) + + X.Org Bug 46330 + + Signed-off-by: Peter Hutterer + +commit c25ff549c9636ad89a81fbf364159c7f040d163b +Author: Peter Hutterer +Date: Fri Feb 17 11:49:43 2012 +1000 + + Revert "Don't store fake events in the motion history" + + 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 + + This reverts commit c8b098214b44cf0585d78c460401ea7d143769f3. + + Signed-off-by: Peter Hutterer + Reviewed-by: Chase Douglas + Acked-by: Daniel Stone + +commit 0646cdb99d708e03137afc9aabd8957f3559546a +Author: Peter Hutterer +Date: Fri Feb 17 11:46:12 2012 +1000 + + Fix build error if HAVE_MTDEV is false + + priv->has_touch is conditional on HAVE_MTDEV + + Signed-off-by: Peter Hutterer + Reviewed-by: Chase Douglas + Reviewed-by: Jeremy Huddleston + commit f9a906590e59383aef3c53faca98f0de40859f17 Author: Chase Douglas Date: Sat Feb 11 18:57:20 2012 +0100 diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/changelog xserver-xorg-input-synaptics-1.5.99~git20120223/debian/changelog --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/changelog 2012-02-23 20:03:10.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/changelog 2012-02-23 20:03:10.000000000 +0000 @@ -1,3 +1,17 @@ +xserver-xorg-input-synaptics (1.5.99~git20120223-0ubuntu1) precise; urgency=low + + * 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 + * 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 Thu, 23 Feb 2012 11:54:37 -0800 + xserver-xorg-input-synaptics (1.5.99~git20120220-0ubuntu3) precise; urgency=low * Fix crash on multitouch devices when disabled while typing (LP: #931344) diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/127_default_drag_lock.patch xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/127_default_drag_lock.patch --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/127_default_drag_lock.patch 2012-02-23 20:03:10.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/127_default_drag_lock.patch 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/129_clickpad.patch xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/129_clickpad.patch --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/129_clickpad.patch 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/129_clickpad.patch 2012-02-23 20:03:10.000000000 +0000 @@ -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, ++ ¶->clickpad); + prop_tap_fast = InitAtom(pInfo->dev, SYNAPTICS_PROP_TAP_FAST, 8, 1, ¶->fast_taps); + prop_middle_timeout = InitAtom(pInfo->dev, SYNAPTICS_PROP_MIDDLE_TIMEOUT, + 32, 1, ¶->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 -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/129_tmp_pointer_drift.patch xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/129_tmp_pointer_drift.patch --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/129_tmp_pointer_drift.patch 2012-02-23 20:03:10.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/129_tmp_pointer_drift.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -From: Peter Hutterer -To: "X.Org Devel List" -Subject: [PATCH synaptics] Revert "Don't store fake events in the motion - history" -Cc: Daniel Stone - -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 - -This reverts commit c8b098214b44cf0585d78c460401ea7d143769f3. - -Signed-off-by: Peter Hutterer ---- -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 -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/130_tmp_touch_count_fix.patch xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/130_tmp_touch_count_fix.patch --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/130_tmp_touch_count_fix.patch 2012-02-23 20:03:10.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/130_tmp_touch_count_fix.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -From 5739a101d2f96ba4a0854202017d31f2b3dfee26 Mon Sep 17 00:00:00 2001 -From: Chase Douglas -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 ---- - 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++; -+ } else if (hw->slot_state[i] == SLOTSTATE_CLOSE) -+ { -+ Bool found = FALSE; -+ int j; -+ -+ for (j = 0; j < priv->num_active_touches - 1; j++) -+ { -+ if (priv->open_slots[j] == i) -+ found = TRUE; -+ -+ if (found) -+ priv->open_slots[j] = priv->open_slots[j + 1]; -+ } -+ -+ priv->num_active_touches--; -+ } -+ } -+ -+ SynapticsResetTouchHwState(hw); -+#endif -+} -+ - static void - HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw) - { -@@ -2675,40 +2711,9 @@ HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw) - xf86PostTouchEvent(pInfo->dev, slot, XI_TouchEnd, 0, - hw->mt_mask[slot]); - } -- --out: -- /* Update the open slots and number of active touches */ -- 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++; -- } else if (hw->slot_state[i] == SLOTSTATE_CLOSE) -- { -- Bool found = FALSE; -- int j; - -- for (j = 0; j < priv->num_active_touches - 1; j++) -- { -- if (priv->open_slots[j] == i) -- found = TRUE; -- -- if (found) -- priv->open_slots[j] = priv->open_slots[j + 1]; -- } -- -- priv->num_active_touches--; -- } -- } -- -- /* We calculated the value twice, might as well double check our math */ -- if (priv->num_active_touches != new_active_touches) -- xf86IDrvMsg(pInfo, X_WARNING, -- "calculated wrong number of active touches (%d vs %d)\n", -- priv->num_active_touches, new_active_touches); -- -- SynapticsResetTouchHwState(hw); -+out: -+ UpdateTouchState(pInfo, hw); - #endif - } - -@@ -2741,7 +2746,10 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now, - - /* If touchpad is switched off, we skip the whole thing and return delay */ - if (para->touchpad_off == 1) -+ { -+ UpdateTouchState(pInfo, hw); - return delay; -+ } - - /* apply hysteresis before doing anything serious. This cancels - * out a lot of noise which might surface in strange phenomena --- -1.7.9 - diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/series xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/series --- xserver-xorg-input-synaptics-1.5.99~git20120220/debian/patches/series 2012-02-23 20:03:10.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/debian/patches/series 2012-02-23 20:03:10.000000000 +0000 @@ -17,7 +17,5 @@ 124_syndaemon_events.patch 125_option_rec_revert.patch 126_ubuntu_xi22.patch -127_default_drag_lock.patch 128_disable_three_click_action.patch -129_tmp_pointer_drift.patch -130_tmp_touch_count_fix.patch +129_clickpad.patch diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/src/eventcomm.c xserver-xorg-input-synaptics-1.5.99~git20120223/src/eventcomm.c --- xserver-xorg-input-synaptics-1.5.99~git20120220/src/eventcomm.c 2012-02-20 09:56:57.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/src/eventcomm.c 2012-02-23 19:47:54.000000000 +0000 @@ -410,6 +410,7 @@ &priv->minw, &priv->maxw, NULL, NULL); +#if HAVE_MTDEV if (priv->has_touch) { int st_minx = priv->minx; @@ -429,6 +430,7 @@ proto_data->st_to_mt_scale_y = (priv->maxy - priv->miny) / (st_maxy - st_miny); } +#endif SYSCALL(rc = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); if (rc >= 0) diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/src/synaptics.c xserver-xorg-input-synaptics-1.5.99~git20120223/src/synaptics.c --- xserver-xorg-input-synaptics-1.5.99~git20120220/src/synaptics.c 2012-02-20 09:56:57.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/src/synaptics.c 2012-02-23 19:47:54.000000000 +0000 @@ -2596,6 +2596,42 @@ 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++; + } else if (hw->slot_state[i] == SLOTSTATE_CLOSE) + { + Bool found = FALSE; + int j; + + for (j = 0; j < priv->num_active_touches - 1; j++) + { + if (priv->open_slots[j] == i) + found = TRUE; + + if (found) + priv->open_slots[j] = priv->open_slots[j + 1]; + } + + priv->num_active_touches--; + } + } + + SynapticsResetTouchHwState(hw); +#endif +} + static void HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw) { @@ -2675,40 +2711,9 @@ xf86PostTouchEvent(pInfo->dev, slot, XI_TouchEnd, 0, hw->mt_mask[slot]); } - -out: - /* Update the open slots and number of active touches */ - 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++; - } else if (hw->slot_state[i] == SLOTSTATE_CLOSE) - { - Bool found = FALSE; - int j; - - for (j = 0; j < priv->num_active_touches - 1; j++) - { - if (priv->open_slots[j] == i) - found = TRUE; - - if (found) - priv->open_slots[j] = priv->open_slots[j + 1]; - } - - priv->num_active_touches--; - } - } - /* We calculated the value twice, might as well double check our math */ - if (priv->num_active_touches != new_active_touches) - xf86IDrvMsg(pInfo, X_WARNING, - "calculated wrong number of active touches (%d vs %d)\n", - priv->num_active_touches, new_active_touches); - - SynapticsResetTouchHwState(hw); +out: + UpdateTouchState(pInfo, hw); #endif } @@ -2741,7 +2746,10 @@ /* If touchpad is switched off, we skip the whole thing and return delay */ if (para->touchpad_off == 1) + { + UpdateTouchState(pInfo, hw); return delay; + } /* apply hysteresis before doing anything serious. This cancels * out a lot of noise which might surface in strange phenomena @@ -2887,7 +2895,7 @@ 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; } diff -Nru xserver-xorg-input-synaptics-1.5.99~git20120220/tools/synclient.c xserver-xorg-input-synaptics-1.5.99~git20120223/tools/synclient.c --- xserver-xorg-input-synaptics-1.5.99~git20120220/tools/synclient.c 2012-02-20 09:56:57.000000000 +0000 +++ xserver-xorg-input-synaptics-1.5.99~git20120223/tools/synclient.c 2012-02-23 19:32:00.000000000 +0000 @@ -446,7 +446,8 @@ b[par->prop_offset] = rint(val); break; case 32: - if (format != par->prop_format || type != XA_INTEGER) { + if (format != par->prop_format || + (type != XA_INTEGER && type != XA_CARDINAL)) { fprintf(stderr, " %-23s = format mismatch (%d)\n", par->name, format); break; @@ -517,7 +518,8 @@ printf(" %-23s = %d\n", par->name, b[par->prop_offset]); break; case 32: - if (format != par->prop_format || type != XA_INTEGER) { + if (format != par->prop_format || + (type != XA_INTEGER && type != XA_CARDINAL)) { fprintf(stderr, " %-23s = format mismatch (%d)\n", par->name, format); break;