Commit e0069c15 authored by Peter Hutterer's avatar Peter Hutterer
Browse files

Revert "Purge scrollbuttons (repeat)"

This reverts commit 0903d99a.

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
parent 48fbf44a
......@@ -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"
......@@ -732,6 +767,10 @@ FLOAT, 4 values, min, max, accel, <deprecated>
.BI "Synaptics Button Scrolling"
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"
......
......@@ -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,
&para->scroll_button_repeat);
}
prop_off =
InitAtom(pInfo->dev, SYNAPTICS_PROP_OFF, 8, 1, &para->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;
......
......@@ -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;
......@@ -2574,6 +2591,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)
......@@ -2653,6 +2710,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)
......@@ -2849,6 +2966,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
......@@ -2940,6 +3059,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
*/
......
......@@ -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 */
......
......@@ -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},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment