ChangeLog | 68 +++++++++++++++ configure.ac | 2 debian/changelog | 6 + include/synaptics-properties.h | 3 man/synaptics.man | 60 ++++++++++--- src/properties.c | 65 ++++++++++++++ src/synaptics.c | 181 ++++++++++++++++++++++++++++++++++++++++- src/synapticsstr.h | 15 +++ tools/synclient.c | 8 + 9 files changed, 391 insertions(+), 17 deletions(-)
New commits: commit 12772d87eb69a1fcd305edc2684ae032f21da52e Author: Michele Cane <michele.c...@gmail.com> Date: Wed Mar 12 08:27:46 2014 +0100 Bump changelogs. diff --git a/ChangeLog b/ChangeLog index abe6647..0868026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,71 @@ +commit 8a5533aaa7e6e57bca7674de4cd25b3a18217d44 +Author: Peter Hutterer <peter.hutte...@who-t.net> +Date: Wed Mar 12 09:42:38 2014 +1000 + + synaptics 1.7.4 + + Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> + +commit c189854a688465c820d5ef5767e00b69394a1601 +Author: Keith Packard <kei...@keithp.com> +Date: Sat Feb 22 01:44:37 2014 -0800 + + Close device if DeviceOnHook fails + + Signed-off-by: Keith Packard <kei...@keithp.com> + Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> + (cherry picked from commit 22fe8bdc6668e78853768c62f4d1331114c7eca0) + +commit 503082bf17dfc4cb3d4b794ea514ac6f413c07f2 +Author: Peter Hutterer <peter.hutte...@who-t.net> +Date: Tue Feb 18 10:14:37 2014 +1000 + + man: setting scroll deltas to 0 doesn't work (#75074) + + 6d47d33 disallows a zero value for horizontal/vertical scroll deltas but the + man page wasn't updated. We've added separate toggles to enable/disable + scrolling a few years ago, setting the distance to 0 is not recommended. + + X.Org Bug 75074 <http://bugs.freedesktop.org/show_bug.cgi?id=75074> + + Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> + (cherry picked from commit 2ea76fad6545a712713de1a09965158805e83c55) + +commit 0b70c76eab57822526585bbd11a1408bd115f26b +Author: Peter Hutterer <peter.hutte...@who-t.net> +Date: Thu Feb 13 14:55:12 2014 +1000 + + Revert "Drop circular pad support" + + This reverts commit 3b02e7fd81da4b100fb9ac32378f6d50f54cf0e2. + + Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> + + Conflicts: + man/synaptics.man + src/synaptics.c + + Acked-by: Daniel Stone <dan...@fooishbar.org> + (cherry picked from commit 4f543ce1d6ae9ca11086a3009d149505590584a8) + +commit 1bd4ca3b5af6e5ee98c7d7f153fd4ee643c29e1a +Author: Peter Hutterer <peter.hutte...@who-t.net> +Date: Fri Jan 17 08:24:35 2014 +1000 + + Revert "Purge scrollbuttons (repeat)" + + This reverts commit 0903d99ada1755f11a2a5cbf89a345de896e18ec. + + Scroll buttons are still present in some modern devices, e.g. the Fujitsu + Lifebook E782 and others in the series. + + Conflicts: + include/synaptics.h + man/synaptics.man + src/synaptics.c + + (cherry picked from commit e0069c154440305ece6def92a9813a9f8004b2fb) + commit 90d93891be0dcc55d87c349ab438144ead818402 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Mon Jan 13 15:14:06 2014 +1000 diff --git a/debian/changelog b/debian/changelog index 605331d..ad3236b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +xserver-xorg-input-synaptics (1.7.4-1) UNRELEASED; urgency=medium + + * New upstream release. + + -- Michele Cane <michele.c...@gmail.com> Wed, 12 Mar 2014 08:24:48 +0100 + xserver-xorg-input-synaptics (1.7.3-1) unstable; urgency=medium [ Michele Cane ] commit 8a5533aaa7e6e57bca7674de4cd25b3a18217d44 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Wed Mar 12 09:42:38 2014 +1000 synaptics 1.7.4 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index ea5c002..c41e6da 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-input-synaptics], - [1.7.3], + [1.7.4], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-input-synaptics]) AC_CONFIG_SRCDIR([Makefile.am]) commit c189854a688465c820d5ef5767e00b69394a1601 Author: Keith Packard <kei...@keithp.com> Date: Sat Feb 22 01:44:37 2014 -0800 Close device if DeviceOnHook fails Signed-off-by: Keith Packard <kei...@keithp.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> (cherry picked from commit 22fe8bdc6668e78853768c62f4d1331114c7eca0) diff --git a/src/synaptics.c b/src/synaptics.c index 1c22873..0986e20 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -959,8 +959,10 @@ DeviceOn(DeviceIntPtr dev) } if (priv->proto_ops->DeviceOnHook && - !priv->proto_ops->DeviceOnHook(pInfo, &priv->synpara)) + !priv->proto_ops->DeviceOnHook(pInfo, &priv->synpara)) { + xf86CloseSerial(pInfo->fd); return !Success; + } priv->comm.buffer = XisbNew(pInfo->fd, INPUT_BUFFER_SIZE); if (!priv->comm.buffer) { commit 503082bf17dfc4cb3d4b794ea514ac6f413c07f2 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Feb 18 10:14:37 2014 +1000 man: setting scroll deltas to 0 doesn't work (#75074) 6d47d33 disallows a zero value for horizontal/vertical scroll deltas but the man page wasn't updated. We've added separate toggles to enable/disable scrolling a few years ago, setting the distance to 0 is not recommended. X.Org Bug 75074 <http://bugs.freedesktop.org/show_bug.cgi?id=75074> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> (cherry picked from commit 2ea76fad6545a712713de1a09965158805e83c55) diff --git a/man/synaptics.man b/man/synaptics.man index eb04eb2..7da7527 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -585,9 +585,6 @@ effect on scrolling speed. Scrolling speed is determined solely from the VertScrollDelta and HorizScrollDelta parameters. . -To disable vertical or horizontal scrolling, set VertScrollDelta or -HorizScrollDelta to zero. -. To invert the direction of vertical or horizontal scrolling, set VertScrollDelta or HorizScrollDelta to a negative value. . commit 0b70c76eab57822526585bbd11a1408bd115f26b Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Thu Feb 13 14:55:12 2014 +1000 Revert "Drop circular pad support" This reverts commit 3b02e7fd81da4b100fb9ac32378f6d50f54cf0e2. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Conflicts: man/synaptics.man src/synaptics.c Acked-by: Daniel Stone <dan...@fooishbar.org> (cherry picked from commit 4f543ce1d6ae9ca11086a3009d149505590584a8) diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h index b717880..19bd2b2 100644 --- a/include/synaptics-properties.h +++ b/include/synaptics-properties.h @@ -116,6 +116,9 @@ #define SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER "Synaptics Circular Scrolling Trigger" /* 8 bit (BOOL) */ +#define SYNAPTICS_PROP_CIRCULAR_PAD "Synaptics Circular Pad" + +/* 8 bit (BOOL) */ #define SYNAPTICS_PROP_PALM_DETECT "Synaptics Palm Detection" /* 32 bit, 2 values, width, z */ diff --git a/man/synaptics.man b/man/synaptics.man index 7652404..eb04eb2 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -351,6 +351,13 @@ l l. .TE Property: "Synaptics Circular Scrolling Trigger" .TP +.BI "Option \*qCircularPad\*q \*q" boolean \*q +. +Instead of being a rectangle, the edge is the ellipse enclosed by the +Left/Right/Top/BottomEdge parameters. +. +For circular touchpads. Property: "Synaptics Circular Pad" +.TP .BI "Option \*qPalmDetect\*q \*q" boolean \*q If palm detection should be enabled. . @@ -933,7 +940,6 @@ The following options are no longer part of the driver configuration: .TP .BI "Option \*qEdgeMotionUseAlways\*q \*q" boolean \*q .TP -.BI "Option \*qCircularPad\*q \*q" boolean \*q .SH "AUTHORS" .LP diff --git a/src/properties.c b/src/properties.c index 0041544..886d8c2 100644 --- a/src/properties.c +++ b/src/properties.c @@ -295,6 +295,9 @@ InitDeviceProperties(InputInfoPtr pInfo) prop_circscroll_trigger = InitAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER, 8, 1, ¶->circular_trigger); + prop_circpad = + InitAtom(pInfo->dev, SYNAPTICS_PROP_CIRCULAR_PAD, 8, 1, + ¶->circular_pad); prop_palm = InitAtom(pInfo->dev, SYNAPTICS_PROP_PALM_DETECT, 8, 1, ¶->palm_detect); @@ -666,6 +669,12 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, para->circular_trigger = trigger; } + else if (property == prop_circpad) { + if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER) + return BadMatch; + + para->circular_pad = *(BOOL *) prop->data; + } else if (property == prop_palm) { if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; diff --git a/src/synaptics.c b/src/synaptics.c index 493986d..1c22873 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -701,6 +701,7 @@ set_default_parameters(InputInfoPtr pInfo) pars->circular_scrolling = xf86SetBoolOption(opts, "CircularScrolling", FALSE); pars->circular_trigger = xf86SetIntOption(opts, "CircScrollTrigger", 0); + pars->circular_pad = xf86SetBoolOption(opts, "CircularPad", FALSE); pars->palm_detect = xf86SetBoolOption(opts, "PalmDetect", FALSE); pars->palm_min_width = xf86SetIntOption(opts, "PalmMinWidth", palmMinWidth); pars->palm_min_z = xf86SetIntOption(opts, "PalmMinZ", palmMinZ); @@ -1328,6 +1329,32 @@ DeviceInit(DeviceIntPtr dev) return !Success; } +/* + * Convert from absolute X/Y coordinates to a coordinate system where + * -1 corresponds to the left/upper edge and +1 corresponds to the + * right/lower edge. + */ +static void +relative_coords(SynapticsPrivate * priv, int x, int y, + double *relX, double *relY) +{ + int minX = priv->synpara.left_edge; + int maxX = priv->synpara.right_edge; + int minY = priv->synpara.top_edge; + int maxY = priv->synpara.bottom_edge; + double xCenter = (minX + maxX) / 2.0; + double yCenter = (minY + maxY) / 2.0; + + if ((maxX - xCenter > 0) && (maxY - yCenter > 0)) { + *relX = (x - xCenter) / (maxX - xCenter); + *relY = (y - yCenter) / (maxY - yCenter); + } + else { + *relX = 0; + *relY = 0; + } +} + /* return angle of point relative to center */ static double angle(SynapticsPrivate * priv, int x, int y) @@ -1352,10 +1379,38 @@ diffa(double a1, double a2) } static enum EdgeType +circular_edge_detection(SynapticsPrivate * priv, int x, int y) +{ + enum EdgeType edge = 0; + double relX, relY, relR; + + relative_coords(priv, x, y, &relX, &relY); + relR = SQR(relX) + SQR(relY); + + if (relR > 1) { + /* we are outside the ellipse enclosed by the edge parameters */ + if (relX > M_SQRT1_2) + edge |= RIGHT_EDGE; + else if (relX < -M_SQRT1_2) + edge |= LEFT_EDGE; + + if (relY < -M_SQRT1_2) + edge |= TOP_EDGE; + else if (relY > M_SQRT1_2) + edge |= BOTTOM_EDGE; + } + + return edge; +} + +static enum EdgeType edge_detection(SynapticsPrivate * priv, int x, int y) { enum EdgeType edge = NO_EDGE; + if (priv->synpara.circular_pad) + return circular_edge_detection(priv, x, y); + if (x > priv->synpara.right_edge) edge |= RIGHT_EDGE; else if (x < priv->synpara.left_edge) diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 3f66b14..54bc154 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -190,6 +190,7 @@ typedef struct _SynapticsParameters { Bool circular_scrolling; /* Enable circular scrolling */ double scroll_dist_circ; /* Scrolling angle radians */ int circular_trigger; /* Trigger area for circular scrolling */ + Bool circular_pad; /* Edge has an oval or circular shape */ Bool palm_detect; /* Enable Palm Detection */ int palm_min_width; /* Palm detection width */ int palm_min_z; /* Palm detection depth */ diff --git a/tools/synclient.c b/tools/synclient.c index f999311..ac31a66 100644 --- a/tools/synclient.c +++ b/tools/synclient.c @@ -121,6 +121,7 @@ static struct Parameter params[] = { {"CircularScrolling", PT_BOOL, 0, 1, SYNAPTICS_PROP_CIRCULAR_SCROLLING, 8, 0}, {"CircScrollDelta", PT_DOUBLE, .01, 3, SYNAPTICS_PROP_CIRCULAR_SCROLLING_DIST, 0 /* float */, 0}, {"CircScrollTrigger", PT_INT, 0, 8, SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER, 8, 0}, + {"CircularPad", PT_BOOL, 0, 1, SYNAPTICS_PROP_CIRCULAR_PAD, 8, 0}, {"PalmDetect", PT_BOOL, 0, 1, SYNAPTICS_PROP_PALM_DETECT, 8, 0}, {"PalmMinWidth", PT_INT, 0, 15, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 0}, {"PalmMinZ", PT_INT, 0, 255, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 1}, commit 1bd4ca3b5af6e5ee98c7d7f153fd4ee643c29e1a Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Fri Jan 17 08:24:35 2014 +1000 Revert "Purge scrollbuttons (repeat)" This reverts commit 0903d99ada1755f11a2a5cbf89a345de896e18ec. Scroll buttons are still present in some modern devices, e.g. the Fujitsu Lifebook E782 and others in the series. Conflicts: include/synaptics.h man/synaptics.man src/synaptics.c (cherry picked from commit e0069c154440305ece6def92a9813a9f8004b2fb) diff --git a/man/synaptics.man b/man/synaptics.man index 079a5f8..7652404 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -198,6 +198,41 @@ Default: 0.5 percent of the diagonal or (in case of evdev) the appropriate The minimum vertical HW distance required to generate motion events. See \fBHorizHysteresis\fR. .TP +.BI "Option \*qUpDownScrolling\*q \*q" boolean \*q +If on, the up/down buttons generate button 4/5 events. +. +If off, the up button generates a double click and the down button +generates a button 2 event. This option is only available for touchpads with +physical scroll buttons. +Property: "Synaptics Button Scrolling" +.TP +.BI "Option \*qLeftRightScrolling\*q \*q" boolean \*q +If on, the left/right buttons generate button 6/7 events. +. +If off, the left/right buttons both generate button 2 events. +This option is only available for touchpads with physical scroll buttons. +Property: "Synaptics Button Scrolling" +.TP +.BI "Option \*qUpDownScrollRepeat\*q \*q" boolean \*q +If on, and the up/down buttons are used for scrolling +(\fBUpDownScrolling\fR), these buttons will send auto-repeating 4/5 events, +with the delay between repeats determined by \fBScrollButtonRepeat\fR. +This option is only available for touchpads with physical scroll buttons. +Property: "Synaptics Button Scrolling Repeat" +.TP +.BI "Option \*qLeftRightScrollRepeat\*q \*q" boolean \*q +If on, and the left/right buttons are used for scrolling +(\fBLeftRightScrolling\fR), these buttons will send auto-repeating 6/7 events, +with the delay between repeats determined by \fBScrollButtonRepeat\fR. +This option is only available for touchpads with physical scroll buttons. +Property: "Synaptics Button Scrolling Repeat" +.TP +.BI "Option \*qScrollButtonRepeat\*q \*q" integer \*q +The number of milliseconds between repeats of button events 4-7 from the +up/down/left/right scroll buttons. +This option is only available for touchpads with physical scroll buttons. +Property: "Synaptics Button Scrolling Time" +.TP .BI "Option \*qEmulateMidButtonTime\*q \*q" integer \*q Maximum time (in milliseconds) for middle button emulation. Property: "Synaptics Middle Button Timeout" @@ -733,6 +768,10 @@ FLOAT, 4 values, min, max, accel, <deprecated> 8 bit (BOOL), 2 values, updown, leftright. .TP 7 +.BI "Synaptics Button Scrolling Repeat" +8 bit (BOOL), 2 values, updown, leftright. + +.TP 7 .BI "Synaptics Button Scrolling Time" 32 bit. @@ -894,16 +933,6 @@ The following options are no longer part of the driver configuration: .TP .BI "Option \*qEdgeMotionUseAlways\*q \*q" boolean \*q .TP -.BI "Option \*qUpDownScrolling\*q \*q" boolean \*q -.TP -.BI "Option \*qLeftRightScrolling\*q \*q" boolean \*q -.TP -.BI "Option \*qUpDownScrollRepeat\*q \*q" boolean \*q -.TP -.BI "Option \*qLeftRightScrollRepeat\*q \*q" boolean \*q -.TP -.BI "Option \*qScrollButtonRepeat\*q \*q" integer \*q -.TP .BI "Option \*qCircularPad\*q \*q" boolean \*q .SH "AUTHORS" diff --git a/src/properties.c b/src/properties.c index 797f1da..0041544 100644 --- a/src/properties.c +++ b/src/properties.c @@ -68,6 +68,9 @@ Atom prop_speed = 0; Atom prop_edgemotion_pressure = 0; Atom prop_edgemotion_speed = 0; Atom prop_edgemotion_always = 0; +Atom prop_buttonscroll = 0; +Atom prop_buttonscroll_repeat = 0; +Atom prop_buttonscroll_time = 0; Atom prop_off = 0; Atom prop_lockdrags = 0; Atom prop_lockdrags_time = 0; @@ -247,6 +250,22 @@ InitDeviceProperties(InputInfoPtr pInfo) fvalues[3] = 0; prop_speed = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_SPEED, 4, fvalues); + if (priv->has_scrollbuttons) { + values[0] = para->updown_button_scrolling; + values[1] = para->leftright_button_scrolling; + prop_buttonscroll = + InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 2, values); + + values[0] = para->updown_button_repeat; + values[1] = para->leftright_button_repeat; + prop_buttonscroll_repeat = + InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 2, + values); + prop_buttonscroll_time = + InitAtom(pInfo->dev, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32, 1, + ¶->scroll_button_repeat); + } + prop_off = InitAtom(pInfo->dev, SYNAPTICS_PROP_OFF, 8, 1, ¶->touchpad_off); prop_lockdrags = @@ -518,6 +537,43 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, para->max_speed = speed[1]; para->accl = speed[2]; } + else if (property == prop_buttonscroll) { + BOOL *scroll; + + if (!priv->has_scrollbuttons) + return BadMatch; + + if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) + return BadMatch; + + scroll = (BOOL *) prop->data; + para->updown_button_scrolling = scroll[0]; + para->leftright_button_scrolling = scroll[1]; + + } + else if (property == prop_buttonscroll_repeat) { + BOOL *repeat; + + if (!priv->has_scrollbuttons) + return BadMatch; + + if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) + return BadMatch; + + repeat = (BOOL *) prop->data; + para->updown_button_repeat = repeat[0]; + para->leftright_button_repeat = repeat[1]; + } + else if (property == prop_buttonscroll_time) { + if (!priv->has_scrollbuttons) + return BadMatch; + + if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) + return BadMatch; + + para->scroll_button_repeat = *(INT32 *) prop->data; + + } else if (property == prop_off) { CARD8 off; diff --git a/src/synaptics.c b/src/synaptics.c index e391a98..493986d 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -669,6 +669,20 @@ set_default_parameters(InputInfoPtr pInfo) pars->scroll_twofinger_horiz = xf86SetBoolOption(opts, "HorizTwoFingerScroll", horizTwoFingerScroll); pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", TOUCHPAD_ON); + + if (priv->has_scrollbuttons) { + pars->updown_button_scrolling = + xf86SetBoolOption(opts, "UpDownScrolling", TRUE); + pars->leftright_button_scrolling = + xf86SetBoolOption(opts, "LeftRightScrolling", TRUE); + pars->updown_button_repeat = + xf86SetBoolOption(opts, "UpDownScrollRepeat", TRUE); + pars->leftright_button_repeat = + xf86SetBoolOption(opts, "LeftRightScrollRepeat", TRUE); + } + pars->scroll_button_repeat = + xf86SetIntOption(opts, "ScrollButtonRepeat", 100); + pars->locked_drags = xf86SetBoolOption(opts, "LockedDrags", FALSE); pars->locked_drag_time = xf86SetIntOption(opts, "LockedDragTimeout", 5000); pars->tap_action[RT_TAP] = xf86SetIntOption(opts, "RTCornerButton", 0); @@ -818,6 +832,8 @@ SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) xf86ErrorFVerb(6, "port opened successfully\n"); /* initialize variables */ + priv->repeatButtons = 0; + priv->nextRepeat = 0; priv->count_packet_finger = 0; priv->tap_state = TS_START; priv->tap_button = 0; @@ -995,6 +1011,7 @@ SynapticsReset(SynapticsPrivate * priv) priv->circ_scroll_on = FALSE; priv->circ_scroll_vert = FALSE; priv->mid_emu_state = MBE_OFF; + priv->nextRepeat = 0; priv->lastButtons = 0; priv->prev_z = 0; priv->prevFingers = 0; @@ -2555,6 +2572,46 @@ handle_clickfinger(SynapticsPrivate * priv, struct SynapticsHwState *hw) } } +/* Adjust the hardware state according to the extra buttons (if the touchpad + * has any and not many touchpads do these days). These buttons are up/down + * tilt buttons and/or left/right buttons that then map into a specific + * function (or scrolling into). + */ +static Bool +adjust_state_from_scrollbuttons(const InputInfoPtr pInfo, + struct SynapticsHwState *hw) +{ + SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private); + SynapticsParameters *para = &priv->synpara; + Bool double_click = FALSE; + + if (!para->updown_button_scrolling) { + if (hw->down) { /* map down button to middle button */ + hw->middle = TRUE; + } + + if (hw->up) { /* up button generates double click */ + if (!priv->prev_up) + double_click = TRUE; + } + priv->prev_up = hw->up; + + /* reset up/down button events */ + hw->up = hw->down = FALSE; + } + + /* Left/right button scrolling, or middle clicks */ + if (!para->leftright_button_scrolling) { + if (hw->multi[2] || hw->multi[3]) + hw->middle = TRUE; + + /* reset left/right button events */ + hw->multi[2] = hw->multi[3] = FALSE; + } + + return double_click; +} + static void update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw, struct SynapticsHwState *old, CARD32 now, int *delay) @@ -2634,6 +2691,66 @@ post_scroll_events(const InputInfoPtr pInfo) xf86PostMotionEventM(pInfo->dev, FALSE, priv->scroll_events_mask); } +static inline int +repeat_scrollbuttons(const InputInfoPtr pInfo, + const struct SynapticsHwState *hw, + int buttons, CARD32 now, int delay) +{ + SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private); + SynapticsParameters *para = &priv->synpara; + int repeat_delay, timeleft; + int rep_buttons = 0; + + if (para->updown_button_repeat) + rep_buttons |= (1 << (4 - 1)) | (1 << (5 - 1)); + if (para->leftright_button_repeat) + rep_buttons |= (1 << (6 - 1)) | (1 << (7 - 1)); + + /* Handle auto repeat buttons */ + repeat_delay = clamp(para->scroll_button_repeat, SBR_MIN, SBR_MAX); + if (((hw->up || hw->down) && para->updown_button_repeat && + para->updown_button_scrolling) || + ((hw->multi[2] || hw->multi[3]) && para->leftright_button_repeat && + para->leftright_button_scrolling)) { + priv->repeatButtons = buttons & rep_buttons; + if (!priv->nextRepeat) { + priv->nextRepeat = now + repeat_delay * 2; + } + } + else { + priv->repeatButtons = 0; + priv->nextRepeat = 0; + } + + if (priv->repeatButtons) { + timeleft = TIME_DIFF(priv->nextRepeat, now); + if (timeleft > 0) + delay = MIN(delay, timeleft); + if (timeleft <= 0) { + int change, id; + + change = priv->repeatButtons; + while (change) { + id = ffs(change); + change &= ~(1 << (id - 1)); + if (id == 4) + priv->scroll.delta_y -= para->scroll_dist_vert; + else if (id == 5) + priv->scroll.delta_y += para->scroll_dist_vert; + else if (id == 6) + priv->scroll.delta_x -= para->scroll_dist_horiz; + else if (id == 7) + priv->scroll.delta_x += para->scroll_dist_horiz; + } + + priv->nextRepeat = now + repeat_delay; + delay = MIN(delay, repeat_delay); + } + } + + return delay; +} + /* Update the open slots and number of active touches */ static void UpdateTouchState(InputInfoPtr pInfo, struct SynapticsHwState *hw) @@ -2830,6 +2947,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now, /* these two just update hw->left, right, etc. */ update_hw_button_state(pInfo, hw, priv->old_hw_state, now, &delay); + if (priv->has_scrollbuttons) + double_click = adjust_state_from_scrollbuttons(pInfo, hw); /* now we know that these _coordinates_ aren't in the area. invalid are: x, y, z, numFingers, fingerWidth @@ -2921,6 +3040,9 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now, 0, 0); } + if (priv->has_scrollbuttons) + delay = repeat_scrollbuttons(pInfo, hw, buttons, now, delay); + /* Process scroll events only if coordinates are * in the Synaptics Area */ diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 3d6f756..3f66b14 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -55,6 +55,10 @@ #define SYNAPTICS_MAX_TOUCHES 10 #define SYN_MAX_BUTTONS 12 /* Max number of mouse buttons */ +/* Minimum and maximum values for scroll_button_repeat */ +#define SBR_MIN 10 +#define SBR_MAX 1000 + enum OffState { TOUCHPAD_ON = 0, TOUCHPAD_OFF = 1, @@ -168,6 +172,12 @@ typedef struct _SynapticsParameters { Bool scroll_twofinger_horiz; /* Enable/disable horizontal two-finger scrolling */ double min_speed, max_speed, accl; /* movement parameters */ + Bool updown_button_scrolling; /* Up/Down-Button scrolling or middle/double-click */ + Bool leftright_button_scrolling; /* Left/right-button scrolling, or two lots of middle button */ + Bool updown_button_repeat; /* If up/down button being used to scroll, auto-repeat? */ + Bool leftright_button_repeat; /* If left/right button being used to scroll, auto-repeat? */ + int scroll_button_repeat; /* time, in milliseconds, between scroll events being + * sent when holding down scroll buttons */ int touchpad_off; /* Switches the touchpad off * 0 : Not off * 1 : Off @@ -209,7 +219,7 @@ struct _SynapticsPrivateRec { const char *device; /* device node */ CARD32 timer_time; /* when timer last fired */ - OsTimerPtr timer; /* for tap processing, etc */ + OsTimerPtr timer; /* for up/down-button repeat, tap processing, etc */ struct CommData comm; @@ -254,6 +264,8 @@ struct _SynapticsPrivateRec { False: Generate horizontal events */ double frac_x, frac_y; /* absolute -> relative fraction */ enum MidButtonEmulation mid_emu_state; /* emulated 3rd button */ + int repeatButtons; /* buttons for repeat */ + int nextRepeat; /* Time when to trigger next auto repeat event */ int lastButtons; /* last state of the buttons */ int prev_z; /* previous z value, for palm detection */ int prevFingers; /* previous numFingers, for transition detection */ diff --git a/tools/synclient.c b/tools/synclient.c index bd7cb61..f999311 100644 --- a/tools/synclient.c +++ b/tools/synclient.c @@ -50,6 +50,8 @@ #endif #define SYN_MAX_BUTTONS 12 +#define SBR_MIN 10 +#define SBR_MAX 1000 union flong { /* Xlibs 64-bit property handling madness */ long l; @@ -98,6 +100,11 @@ static struct Parameter params[] = { {"MinSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 0}, {"MaxSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 1}, {"AccelFactor", PT_DOUBLE, 0, 1.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 2}, + {"UpDownScrolling", PT_BOOL, 0, 1, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 0}, + {"LeftRightScrolling", PT_BOOL, 0, 1, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 1}, + {"UpDownScrollRepeat", PT_BOOL, 0, 1, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 0}, + {"LeftRightScrollRepeat", PT_BOOL, 0, 1, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 1}, + {"ScrollButtonRepeat", PT_INT, SBR_MIN , SBR_MAX, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32, 0}, {"TouchpadOff", PT_INT, 0, 2, SYNAPTICS_PROP_OFF, 8, 0}, {"LockedDrags", PT_BOOL, 0, 1, SYNAPTICS_PROP_LOCKED_DRAGS, 8, 0}, {"LockedDragTimeout", PT_INT, 0, 30000, SYNAPTICS_PROP_LOCKED_DRAGS_TIMEOUT, 32, 0}, -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1wndp5-00080s...@moszumanska.debian.org