mirror of
https://github.com/X11Libre/xf86-input-synaptics.git
synced 2026-03-24 01:34:04 +00:00
Support the new Lenovo X1 Carbon 3rd trackpoint buttons
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@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
||||
10
conf/71-synaptics.rules
Normal file
10
conf/71-synaptics.rules
Normal file
@@ -0,0 +1,10 @@
|
||||
ACTION=="remove", GOTO="touchpad_end"
|
||||
KERNEL!="event*", GOTO="touchpad_end"
|
||||
ENV{ID_INPUT_TOUCHPAD}=="", GOTO="touchpad_end"
|
||||
|
||||
# Lenovo X1 Carbon 3rd
|
||||
KERNELS=="serio1", \
|
||||
ATTRS{firmware_id}=="*LEN0048*", \
|
||||
ENV{ID_INPUT.tags}="has_trackpoint_buttons"
|
||||
|
||||
LABEL="touchpad_end"
|
||||
@@ -25,3 +25,10 @@ else
|
||||
fdidir = $(datadir)/hal/fdi/policy/20thirdparty
|
||||
dist_fdi_DATA = 11-x11-synaptics.fdi
|
||||
endif
|
||||
|
||||
if HAVE_UDEV_RULES_DIR
|
||||
udevdir=$(UDEV_RULES_DIR)
|
||||
udev_DATA = 71-synaptics.rules
|
||||
endif
|
||||
|
||||
EXTRA_DIST = 71-synaptics.rules
|
||||
|
||||
10
configure.ac
10
configure.ac
@@ -135,6 +135,16 @@ AM_CONDITIONAL([BUILD_EVENTCOMM], [test "x${BUILD_EVENTCOMM}" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_PSMCOMM], [test "x${BUILD_PSMCOMM}" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_PS2COMM], [test "x${BUILD_PS2COMM}" = "xyes"])
|
||||
|
||||
AC_ARG_WITH(udev-rules-dir,
|
||||
AS_HELP_STRING([--with-udev-rules-dir=DIR],
|
||||
[Directory where udev expects its rules files
|
||||
[[default=$libdir/udev/rules.d]]]),
|
||||
[udevdir="$withval"],
|
||||
[udevdir="$libdir/udev/rules.d"])
|
||||
UDEV_RULES_DIR=${udevdir}
|
||||
AC_SUBST(UDEV_RULES_DIR)
|
||||
AM_CONDITIONAL(HAVE_UDEV_RULES_DIR, [test "x$UDEV_RULES_DIR" != "xno"])
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Dependencies for synclient and syndaemon
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -702,6 +702,12 @@ set_default_parameters(InputInfoPtr pInfo)
|
||||
xf86SetBoolOption(opts, "HorizTwoFingerScroll", horizTwoFingerScroll);
|
||||
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);
|
||||
@@ -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;
|
||||
@@ -2782,6 +2789,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
|
||||
@@ -3137,6 +3172,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
|
||||
|
||||
@@ -290,6 +290,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 */
|
||||
@@ -309,6 +310,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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user