diff options
Diffstat (limited to 'src/synaptics.c')
-rw-r--r-- | src/synaptics.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/synaptics.c b/src/synaptics.c index e6a90f2..0f0b5b9 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; @@ -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 |