[PATCH synaptics] Support the new Lenovo X1 Carbon 3rd trackpoint buttons
Hans de Goede
hdegoede at redhat.com
Thu Jan 29 00:50:12 PST 2015
Hi,
On 29-01-15 03:00, Peter Hutterer wrote:
> This device has the trackpoint buttons wired up to the touchpad to send BTN_0,
> BTN_1 and BTN_2 for left, right, middle. This conflicts with previous
> touchpads that used those event codes for dedicated scroll buttons.
>
> Add an option HasTrackpointButtons that can be set via a xorg.conf.d
> snippets. This option is not intended as a user-set option, rather
> we expect distributions to ship some conglomerate of udev/hal rules with
> xorg.conf snippets that take effect.
>
> If the option is set, we look at the three affected buttons at the beginning
> of HandleState and send button events immediately for them. The HW state is
> reset to neutral and other processing continues. This saves us from having to
> synchronize these buttons with software buttons (also present on this device),
> tapping, etc.
>
> Since the buttons are physically different and (mentally) associated with the
> trackpoint device we also don't need to worry about having finger motion event
> correctly synced up with the button presses - it's acceptable to send the
> presses before the motion events.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Looks good.
Reviewed-by: Hans de Goede <hdegoede at redhat.com>
Regards,
Hans
> ---
> conf/50-synaptics.conf | 7 +++++++
> conf/71-synaptics.rules | 9 +++++++++
> man/synaptics.man | 14 ++++++++++++++
> src/synaptics.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> src/synapticsstr.h | 2 ++
> 5 files changed, 74 insertions(+)
> create mode 100644 conf/71-synaptics.rules
>
> diff --git a/conf/50-synaptics.conf b/conf/50-synaptics.conf
> index aa50456..5fb131e 100644
> --- a/conf/50-synaptics.conf
> +++ b/conf/50-synaptics.conf
> @@ -44,3 +44,10 @@ Section "InputClass"
> MatchDriver "synaptics"
> Option "SoftButtonAreas" "0 0 0 0 0 0 0 0"
> EndSection
> +
> +Section "InputClass"
> + Identifier "Lenovo *50 and Carbon 3rd trackpoint buttons"
> + MatchDriver "synaptics"
> + MatchTag "has_trackpoint_buttons"
> + Option "HasTrackpointButtons" "on"
> +EndSection
> diff --git a/conf/71-synaptics.rules b/conf/71-synaptics.rules
> new file mode 100644
> index 0000000..b1cec40
> --- /dev/null
> +++ b/conf/71-synaptics.rules
> @@ -0,0 +1,9 @@
> +ACTION=="remove", GOTO="touchpad_end"
> +KERNEL!="event*", GOTO="touchpad_end"
> +ENV{ID_INPUT_TOUCHPAD}=="", GOTO="touchpad_end"
> +
> +KERNELS=="serio1", \
> + ATTRS{firmware_id}=="*LEN0048*", \
> + ENV{ID_INPUT.tags}="has_trackpoint_buttons"
> +
> +LABEL="touchpad_end"
> diff --git a/man/synaptics.man b/man/synaptics.man
> index 7083b3a..65fb337 100644
> --- a/man/synaptics.man
> +++ b/man/synaptics.man
> @@ -518,6 +518,20 @@ initialized if
> .B Option \*qHasSecondarySoftButtons\*q
> is enabled and this option is set in the __xconfigfile__(__filemansuffix__).
> .
> +.TP
> +.BI "Option \*qHasTrackpointButtons\*q \*q" boolean \*q
> +This option is only available on selected devices. You should never need to
> +set this option manually, your distribution should ship
> +__xconfigfile__(__filemansuffix__) snippets to enable this option where
> +required. Devices that require this option include the Lenovo X1 Carbon 3rd
> +and the Lenovo *50 series (T450, T550, etc.).
> +If enabled, the device is considered to have the trackpoint left, middle,
> +right buttons wired to the touchpad. If set, this option disables scroll
> +buttons, i.e.
> +.B Option \*qUpDownScrolling\*q, \*qLeftRightScrolling\*q
> +and the respective repeat options for scroll buttons.
> +This options is considered a hardware property and is not exposed as
> +configurable X Input device property.
>
> .SH CONFIGURATION DETAILS
> .SS Area handling
> diff --git a/src/synaptics.c b/src/synaptics.c
> index 955b042..07b012f 100644
> --- a/src/synaptics.c
> +++ b/src/synaptics.c
> @@ -703,6 +703,12 @@ set_default_parameters(InputInfoPtr pInfo)
> pars->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", TOUCHPAD_ON);
>
> if (priv->has_scrollbuttons) {
> + priv->has_trackpoint_buttons = xf86SetBoolOption(opts, "HasTrackpointButtons", FALSE);
> + if (priv->has_trackpoint_buttons)
> + priv->has_scrollbuttons = FALSE;
> + }
> +
> + if (priv->has_scrollbuttons) {
> pars->updown_button_scrolling =
> xf86SetBoolOption(opts, "UpDownScrolling", TRUE);
> pars->leftright_button_scrolling =
> @@ -1081,6 +1087,7 @@ SynapticsReset(SynapticsPrivate * priv)
> priv->mid_emu_state = MBE_OFF;
> priv->nextRepeat = 0;
> priv->lastButtons = 0;
> + priv->lastTrackpointButtons = 0;
> priv->prev_z = 0;
> priv->prevFingers = 0;
> priv->num_active_touches = 0;
> @@ -2779,6 +2786,34 @@ handle_clickfinger(SynapticsPrivate * priv, struct SynapticsHwState *hw)
> }
> }
>
> +static void
> +handle_trackpoint_buttons(const InputInfoPtr pInfo,
> + struct SynapticsHwState *hw)
> +{
> + SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
> + unsigned int buttons, change;
> + int id;
> +
> + buttons = (hw->multi[0] ? 0x1 : 0) |
> + (hw->multi[1] ? 0x4 : 0) |
> + (hw->multi[2] ? 0x2 : 0);
> +
> + change = buttons ^ priv->lastTrackpointButtons;
> + while (change) {
> + id = ffs(change); /* number of first set bit 1..32 is returned */
> + change &= ~(1 << (id - 1));
> + xf86PostButtonEvent(pInfo->dev, FALSE, id,
> + (buttons & (1 << (id - 1))),
> + 0, 0);
> + }
> +
> + hw->multi[0] = FALSE;
> + hw->multi[1] = FALSE;
> + hw->multi[2] = FALSE;
> +
> + priv->lastTrackpointButtons = buttons;
> +}
> +
> /* 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
> @@ -3134,6 +3169,13 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> Bool using_cumulative_coords = FALSE;
> Bool ignore_motion;
>
> + /* if we have phys. trackpoint buttons wired up to the touchpad, process
> + * them first. They belong to a different device so we don't care about
> + * sending out motion events before the trackpoint buttons. This makes
> + * the code a lot easier to slot in */
> + if (priv->has_trackpoint_buttons)
> + handle_trackpoint_buttons(pInfo, hw);
> +
> /* We need both and x/y, the driver can't handle just one of the two
> * yet. But since it's possible to hit a phys button on non-clickpads
> * without ever getting motion data first, we must continue with 0/0 for
> diff --git a/src/synapticsstr.h b/src/synapticsstr.h
> index f8ab14e..91c41fc 100644
> --- a/src/synapticsstr.h
> +++ b/src/synapticsstr.h
> @@ -289,6 +289,7 @@ struct _SynapticsPrivateRec {
> int repeatButtons; /* buttons for repeat */
> int nextRepeat; /* Time when to trigger next auto repeat event */
> int lastButtons; /* last state of the buttons */
> + int lastTrackpointButtons; /* last state of the trackpoint buttons */
> int prev_z; /* previous z value, for palm detection */
> int prevFingers; /* previous numFingers, for transition detection */
> int avg_width; /* weighted average of previous fingerWidth values */
> @@ -308,6 +309,7 @@ struct _SynapticsPrivateRec {
> Bool has_pressure; /* device reports pressure */
> Bool has_width; /* device reports finger width */
> Bool has_scrollbuttons; /* device has physical scrollbuttons */
> + Bool has_trackpoint_buttons;/* device has trackpoint buttons wired to touchpad */
> Bool has_semi_mt; /* device is only semi-multitouch capable */
> Bool has_mt_palm_detect; /* device reports per finger width and pressure */
>
>
More information about the xorg-devel
mailing list