debian/changelog | 10 + debian/patches/119_active_area_touches.patch | 102 ++++++++++++ debian/patches/120_active_touches_num_fingers.patch | 68 ++++++++ debian/patches/121_semi-mt_num_fingers.patch | 158 ++++++++++++++++++++ debian/patches/series | 3 5 files changed, 341 insertions(+)
New commits: commit 7fd7105a8c7c8c64e22379aba0052461115f1a36 Author: Chase Douglas <[email protected]> Date: Tue Mar 29 13:57:08 2011 -0400 Fix handling for SemiMultitouch trackpads with integrated buttons (LP: #736523) * Fix handling for SemiMultitouch trackpads with integrated buttons (LP: #736523) - Added 119_active_area_touches.patch - Added 120_active_touches_num_fingers.patch - Added 121_semi-mt_num_fingers.patch diff --git a/debian/changelog b/debian/changelog index a8fd761..dbaf197 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +xserver-xorg-input-synaptics (1.3.99+git20110116.0e27ce3a-0ubuntu9) UNRELEASED; urgency=low + + * Fix handling for SemiMultitouch trackpads with integrated buttons + (LP: #736523) + - Added 119_active_area_touches.patch + - Added 120_active_touches_num_fingers.patch + - Added 121_semi-mt_num_fingers.patch + + -- Chase Douglas <[email protected]> Tue, 29 Mar 2011 13:53:00 -0400 + xserver-xorg-input-synaptics (1.3.99+git20110116.0e27ce3a-0ubuntu8) natty; urgency=low * Disable SemiMultitouch devices, we don't support them yet (LP: #723905) diff --git a/debian/patches/119_active_area_touches.patch b/debian/patches/119_active_area_touches.patch new file mode 100644 index 0000000..5b39b51 --- /dev/null +++ b/debian/patches/119_active_area_touches.patch @@ -0,0 +1,102 @@ +From 5c209f9bbb3a786b247ecbc613b7f27435dd3033 Mon Sep 17 00:00:00 2001 +From: Chase Douglas <[email protected]> +Date: Tue, 29 Mar 2011 10:17:27 -0400 +Subject: [PATCH 1/3] Don't process touches outside active area + +Signed-off-by: Chase Douglas <[email protected]> +--- + src/eventcomm.c | 28 ++++++++++++++++++++++++---- + src/synaptics.c | 2 +- + src/synproto.h | 2 ++ + 3 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/src/eventcomm.c b/src/eventcomm.c +index 10c9668..bb22f55 100644 +--- a/src/eventcomm.c ++++ b/src/eventcomm.c +@@ -447,7 +447,10 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + + if (!priv->has_touch || ecpriv->cur_slot < 0 || + ecpriv->mt_slot_map[ecpriv->cur_slot] == (uint32_t)-1) ++ { ++ valuator_mask_zero(ecpriv->touch_mask); + return; ++ } + + if (ecpriv->close_slot) + { +@@ -459,10 +462,27 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + } + else + { +- uint16_t type = ecpriv->new_touch ? XI_TouchBegin : XI_TouchUpdate; ++ if (ecpriv->new_touch) ++ { ++ int x_axis = ecpriv->mt_axis_map[ABS_MT_POSITION_X - ABS_MT_TOUCH_MAJOR]; ++ int y_axis = ecpriv->mt_axis_map[ABS_MT_POSITION_Y - ABS_MT_TOUCH_MAJOR]; ++ int x = valuator_mask_get(ecpriv->touch_mask, x_axis); ++ int y = valuator_mask_get(ecpriv->touch_mask, y_axis); ++ ++ if (is_inside_active_area(priv, x, y)) ++ xf86PostTouchEvent(pInfo->dev, ++ ecpriv->mt_slot_map[ecpriv->cur_slot], ++ XI_TouchBegin, 0, ecpriv->touch_mask); ++ else ++ ecpriv->mt_slot_map[ecpriv->cur_slot] = -1; ++ } ++ else ++ { ++ xf86PostTouchEvent(pInfo->dev, ++ ecpriv->mt_slot_map[ecpriv->cur_slot], ++ XI_TouchUpdate, 0, ecpriv->touch_mask); ++ } + +- xf86PostTouchEvent(pInfo->dev, ecpriv->mt_slot_map[ecpriv->cur_slot], +- type, 0, ecpriv->touch_mask); + ecpriv->new_touch = FALSE; + } + +@@ -620,7 +640,7 @@ EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, + ecpriv->cur_vals); + } + } +- else ++ else if (ecpriv->mt_slot_map[ecpriv->cur_slot] != (uint32_t)-1) + ecpriv->close_slot = TRUE; + break; + case ABS_MT_TOUCH_MAJOR: +diff --git a/src/synaptics.c b/src/synaptics.c +index ce06216..f4e440a 100644 +--- a/src/synaptics.c ++++ b/src/synaptics.c +@@ -1188,7 +1188,7 @@ edge_detection(SynapticsPrivate *priv, int x, int y) + * priv->synpara.area_{left|right|top|bottom}_edge are + * all set to zero), the function returns TRUE. + */ +-static Bool ++Bool + is_inside_active_area(SynapticsPrivate *priv, int x, int y) + { + Bool inside_area = TRUE; +diff --git a/src/synproto.h b/src/synproto.h +index 4f93d61..1702f2a 100644 +--- a/src/synproto.h ++++ b/src/synproto.h +@@ -81,6 +81,7 @@ enum SynapticsProtocol { + struct _SynapticsParameters; + struct SynapticsHwInfo; + struct CommData; ++struct _SynapticsPrivateRec; + + struct SynapticsProtocolOperations { + int (*DevicePreInitHook)(InputDriverPtr drv, InputInfoPtr pInfo, int flags); +@@ -107,5 +108,6 @@ extern struct SynapticsProtocolOperations alps_proto_operations; + + extern int HandleState(InputInfoPtr, struct SynapticsHwState*); + extern CARD32 timerFunc(OsTimerPtr timer, CARD32 now, pointer arg); ++extern Bool is_inside_active_area(struct _SynapticsPrivateRec *priv, int x, int y); + + #endif /* _SYNPROTO_H_ */ +-- +1.7.4.1 + diff --git a/debian/patches/120_active_touches_num_fingers.patch b/debian/patches/120_active_touches_num_fingers.patch new file mode 100644 index 0000000..163a27b --- /dev/null +++ b/debian/patches/120_active_touches_num_fingers.patch @@ -0,0 +1,68 @@ +From 3a87e4530d065a114024a602fa76a4b94d905801 Mon Sep 17 00:00:00 2001 +From: Chase Douglas <[email protected]> +Date: Tue, 29 Mar 2011 10:28:52 -0400 +Subject: [PATCH 2/3] Use the number of active touches instead of BTN_*TAP + +The kernel doesn't know about inactive areas of the touchpad, so it +doesn't filter out inactive touches when counting the number of fingers +for events like BTN_DOUBLETAP. + +When touch data is provided, use the current active touch count instead. + +Signed-off-by: Chase Douglas <[email protected]> +--- + src/eventcomm.c | 8 +++++++- + src/eventcomm.h | 1 + + 2 files changed, 8 insertions(+), 1 deletions(-) + +diff --git a/src/eventcomm.c b/src/eventcomm.c +index bb22f55..d3fc943 100644 +--- a/src/eventcomm.c ++++ b/src/eventcomm.c +@@ -459,6 +459,7 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + XI_TouchEnd, 0, ecpriv->touch_mask); + ecpriv->mt_slot_map[ecpriv->cur_slot] = -1; + ecpriv->close_slot = FALSE; ++ ecpriv->active_touches--; + } + else + { +@@ -470,9 +471,12 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + int y = valuator_mask_get(ecpriv->touch_mask, y_axis); + + if (is_inside_active_area(priv, x, y)) ++ { + xf86PostTouchEvent(pInfo->dev, + ecpriv->mt_slot_map[ecpriv->cur_slot], + XI_TouchBegin, 0, ecpriv->touch_mask); ++ ecpriv->active_touches++; ++ } + else + ecpriv->mt_slot_map[ecpriv->cur_slot] = -1; + } +@@ -531,7 +535,9 @@ EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, + case EV_SYN: + switch (ev->code) { + case SYN_REPORT: +- if (comm->oneFinger) ++ if (priv->has_touch) ++ hw->numFingers = ecpriv->active_touches; ++ else if (comm->oneFinger) + hw->numFingers = 1; + else if (comm->twoFingers) + hw->numFingers = 2; +diff --git a/src/eventcomm.h b/src/eventcomm.h +index c6ef87c..d9c9ebb 100644 +--- a/src/eventcomm.h ++++ b/src/eventcomm.h +@@ -58,6 +58,7 @@ typedef struct { + int num_touches; + struct mtdev *mtdev; + struct grail *grail; ++ int active_touches; + } EventcommPrivate; + + extern Bool EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, +-- +1.7.4.1 + diff --git a/debian/patches/121_semi-mt_num_fingers.patch b/debian/patches/121_semi-mt_num_fingers.patch new file mode 100644 index 0000000..4ec14a4 --- /dev/null +++ b/debian/patches/121_semi-mt_num_fingers.patch @@ -0,0 +1,158 @@ +From 07af5bb64e1dae33ef463b71957564111aa532ab Mon Sep 17 00:00:00 2001 +From: Chase Douglas <[email protected]> +Date: Tue, 29 Mar 2011 12:11:28 -0400 +Subject: [PATCH 3/3] Add fixes for semi-multitouch devices with integrated buttons + +Some machines, such as early Dell Mini series, have synaptics trackpads +that provide semi-multitouch data and have integrated left and right +buttons at the bottom of the trackpad. Special care must be taken to +ensure these trackpads function correctly, otherwise a button press with +one finger and a drag with another finger may end up sending a two +finger scroll event. + +This patch implements the following: + +1. When the first or second touch begins on a semi-mt device, the touch + bounding box must be entirely in the trackpad active area or else the + active touch count is not incremented. +2. The maximum active touch count is 2 for a semi-mt device, but more + fingers may be reported through BTN_*TAP events. If the active touch + count is 2, use the BTN_*TAP events for determining the number of + fingers on the touchpad. Otherwise, use the active touch count. + +Signed-off-by: Chase Douglas <[email protected]> +--- + src/eventcomm.c | 59 +++++++++++++++++++++++++++++++++++++++++-------------- + src/eventcomm.h | 5 ++++ + 2 files changed, 49 insertions(+), 15 deletions(-) + +diff --git a/src/eventcomm.c b/src/eventcomm.c +index d3fc943..b247934 100644 +--- a/src/eventcomm.c ++++ b/src/eventcomm.c +@@ -406,11 +406,6 @@ event_query_axis_ranges(InputInfoPtr pInfo) + xf86Msg(X_PROBED, "%s: buttons:%s\n", pInfo->name, buf); + } + +- /* We don't support SemiMultitouch devices yet. */ +- SYSCALL(rc = ioctl(pInfo->fd, EVIOCGPROP(sizeof(prop)), &prop)); +- if (rc >= 0 && (prop & INPUT_PROP_SEMI_MT)) +- return; +- + for (i = ABS_MT_TOUCH_MAJOR; i <= ABS_MT_PRESSURE; i++) { + if (!BitIsOn(ecpriv->absbits, i)) + continue; +@@ -424,6 +419,16 @@ event_query_axis_ranges(InputInfoPtr pInfo) + ecpriv->mt_axis_map[i - ABS_MT_TOUCH_MAJOR] = ecpriv->num_mt_axes++; + priv->has_touch = TRUE; + } ++ ++ if (priv->has_touch) { ++ /* We don't support SemiMultitouch devices yet. */ ++ SYSCALL(rc = ioctl(pInfo->fd, EVIOCGPROP(sizeof(prop)), &prop)); ++ if (rc >= 0 && (prop & INPUT_PROP_SEMI_MT)) ++ ecpriv->semi_mt = TRUE; ++ else ++ ecpriv->semi_mt = FALSE; ++ } ++ + } + + static Bool +@@ -453,10 +458,11 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + } + + if (ecpriv->close_slot) +- { +- xf86PostTouchEvent(pInfo->dev, +- ecpriv->mt_slot_map[ecpriv->cur_slot], +- XI_TouchEnd, 0, ecpriv->touch_mask); ++ { ++ if (!ecpriv->semi_mt) ++ xf86PostTouchEvent(pInfo->dev, ++ ecpriv->mt_slot_map[ecpriv->cur_slot], ++ XI_TouchEnd, 0, ecpriv->touch_mask); + ecpriv->mt_slot_map[ecpriv->cur_slot] = -1; + ecpriv->close_slot = FALSE; + ecpriv->active_touches--; +@@ -470,17 +476,22 @@ ProcessTouch(InputInfoPtr pInfo, SynapticsPrivate *priv) + int x = valuator_mask_get(ecpriv->touch_mask, x_axis); + int y = valuator_mask_get(ecpriv->touch_mask, y_axis); + +- if (is_inside_active_area(priv, x, y)) ++ if ((!ecpriv->semi_mt && is_inside_active_area(priv, x, y)) || ++ (ecpriv->semi_mt && ++ (is_inside_active_area(priv, ecpriv->min_x, ecpriv->min_y) && ++ (ecpriv->active_touches == 0 || ++ is_inside_active_area(priv, ecpriv->max_x, ecpriv->max_y))))) + { +- xf86PostTouchEvent(pInfo->dev, +- ecpriv->mt_slot_map[ecpriv->cur_slot], +- XI_TouchBegin, 0, ecpriv->touch_mask); ++ if (!ecpriv->semi_mt) ++ xf86PostTouchEvent(pInfo->dev, ++ ecpriv->mt_slot_map[ecpriv->cur_slot], ++ XI_TouchBegin, 0, ecpriv->touch_mask); + ecpriv->active_touches++; + } + else + ecpriv->mt_slot_map[ecpriv->cur_slot] = -1; + } +- else ++ else if (!ecpriv->semi_mt) + { + xf86PostTouchEvent(pInfo->dev, + ecpriv->mt_slot_map[ecpriv->cur_slot], +@@ -535,7 +546,7 @@ EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, + case EV_SYN: + switch (ev->code) { + case SYN_REPORT: +- if (priv->has_touch) ++ if (priv->has_touch && ecpriv->active_touches < 2) + hw->numFingers = ecpriv->active_touches; + else if (comm->oneFinger) + hw->numFingers = 1; +@@ -667,6 +678,24 @@ EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, + valuator_mask_set(ecpriv->cur_vals, + ecpriv->mt_axis_map[ev->code - ABS_MT_TOUCH_MAJOR], + ev->value); ++ ++ if (ecpriv->semi_mt) ++ { ++ if (ev->code == ABS_MT_POSITION_X) ++ { ++ if (ecpriv->cur_slot == 0) ++ ecpriv->min_x = ev->value; ++ else ++ ecpriv->max_x = ev->value; ++ } ++ else if (ev->code == ABS_MT_POSITION_Y) ++ { ++ if (ecpriv->cur_slot == 0) ++ ecpriv->min_y = ev->value; ++ else ++ ecpriv->max_y = ev->value; ++ } ++ } + } + break; + } +diff --git a/src/eventcomm.h b/src/eventcomm.h +index d9c9ebb..4ac36a8 100644 +--- a/src/eventcomm.h ++++ b/src/eventcomm.h +@@ -59,6 +59,11 @@ typedef struct { + struct mtdev *mtdev; + struct grail *grail; + int active_touches; ++ Bool semi_mt; ++ int min_x; ++ int max_x; ++ int min_y; ++ int max_y; + } EventcommPrivate; + + extern Bool EventProcessEvent(InputInfoPtr pInfo, struct CommData *comm, +-- +1.7.4.1 + diff --git a/debian/patches/series b/debian/patches/series index 3499ca7..e9cc8ea 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -10,3 +10,6 @@ 116_xi2_1.patch 117_gestures.patch 118_quell_error_msg.patch +119_active_area_touches.patch +120_active_touches_num_fingers.patch +121_semi-mt_num_fingers.patch -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

