[PATCH synaptics 12/12] Make scrollbuttons processing and property conditional on their existence.

Peter Hutterer peter.hutterer at who-t.net
Thu May 6 21:42:04 PDT 2010


There are not a lot of touchpads that have extra physical scroll buttons
anymore. For those that don't have them, don't initalize the properties and
conditionalize some of the code (moved into its own functions).

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 man/synaptics.man  |   15 ++++++--
 src/eventcomm.c    |   10 +++++
 src/properties.c   |   29 +++++++++++----
 src/synaptics.c    |  100 ++++++++++++++++++++++++++++++---------------------
 src/synapticsstr.h |    1 +
 5 files changed, 102 insertions(+), 53 deletions(-)

diff --git a/man/synaptics.man b/man/synaptics.man
index 59fbaac..9075c81 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -223,29 +223,36 @@ Motion Factor"
 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. Property: "Synaptics Button Scrolling"
+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. Property:
-"Synaptics Button Scrolling"
+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. Property: "Synaptics Button Scrolling Time"
+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:
diff --git a/src/eventcomm.c b/src/eventcomm.c
index 6595fb4..9f37673 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -251,6 +251,16 @@ event_query_axis_ranges(LocalDevicePtr local)
 	   strcat(buf, " double");
 	if ((priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0)))
 	   strcat(buf, " triple");
+
+	if ((TEST_BIT(BTN_0, keybits) != 0) ||
+	    (TEST_BIT(BTN_1, keybits) != 0) ||
+	    (TEST_BIT(BTN_2, keybits) != 0) ||
+	    (TEST_BIT(BTN_3, keybits) != 0))
+	{
+	    priv->has_scrollbuttons = 1;
+	    strcat(buf, " scroll-buttons");
+	}
+
 	xf86Msg(X_PROBED, "%s: buttons:%s\n", local->name, buf);
     }
 }
diff --git a/src/properties.c b/src/properties.c
index 4366034..1134f7c 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -208,14 +208,18 @@ InitDeviceProperties(LocalDevicePtr local)
     prop_edgemotion_speed = InitAtom(local->dev, SYNAPTICS_PROP_EDGEMOTION_SPEED, 32, 2, values);
     prop_edgemotion_always = InitAtom(local->dev, SYNAPTICS_PROP_EDGEMOTION, 8, 1, &para->edge_motion_use_always);
 
-    values[0] = para->updown_button_scrolling;
-    values[1] = para->leftright_button_scrolling;
-    prop_buttonscroll = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 2, values);
-
-    values[0] = para->updown_button_repeat;
-    values[1] = para->leftright_button_repeat;
-    prop_buttonscroll_repeat = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 2, values);
-    prop_buttonscroll_time = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32, 1, &para->scroll_button_repeat);
+    if (priv->has_scrollbuttons)
+    {
+        values[0] = para->updown_button_scrolling;
+        values[1] = para->leftright_button_scrolling;
+        prop_buttonscroll = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING, 8, 2, values);
+
+        values[0] = para->updown_button_repeat;
+        values[1] = para->leftright_button_repeat;
+        prop_buttonscroll_repeat = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING_REPEAT, 8, 2, values);
+        prop_buttonscroll_time = InitAtom(local->dev, SYNAPTICS_PROP_BUTTONSCROLLING_TIME, 32, 1, &para->scroll_button_repeat);
+    }
+
     prop_off = InitAtom(local->dev, SYNAPTICS_PROP_OFF, 8, 1, &para->touchpad_off);
     prop_guestmouse = InitAtom(local->dev, SYNAPTICS_PROP_GUESTMOUSE, 8, 1, &para->guestmouse_off);
     prop_lockdrags = InitAtom(local->dev, SYNAPTICS_PROP_LOCKED_DRAGS, 8, 1, &para->locked_drags);
@@ -454,6 +458,9 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
     {
         BOOL *scroll;
 
+        if (!priv->has_scrollbuttons)
+            return BadMatch;
+
         if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
             return BadMatch;
 
@@ -465,6 +472,9 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
     {
         BOOL *repeat;
 
+        if (!priv->has_scrollbuttons)
+            return BadMatch;
+
         if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
             return BadMatch;
 
@@ -473,6 +483,9 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
         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;
 
diff --git a/src/synaptics.c b/src/synaptics.c
index 88c5237..172a778 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -492,10 +492,12 @@ static void set_default_parameters(LocalDevicePtr local)
     pars->edge_motion_min_speed = xf86SetIntOption(opts, "EdgeMotionMinSpeed", edgeMotionMinSpeed);
     pars->edge_motion_max_speed = xf86SetIntOption(opts, "EdgeMotionMaxSpeed", edgeMotionMaxSpeed);
     pars->edge_motion_use_always = xf86SetBoolOption(opts, "EdgeMotionUseAlways", FALSE);
-    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);
+    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->touchpad_off = xf86SetIntOption(opts, "TouchpadOff", 0);
     pars->guestmouse_off = xf86SetBoolOption(opts, "GuestMouseOff", FALSE);
@@ -2179,6 +2181,53 @@ post_scroll_events(const LocalDevicePtr local, struct ScrollData scroll)
         post_button_click(local, 7);
 }
 
+static inline int
+repeat_scrollbuttons(const LocalDevicePtr local,
+                     const struct SynapticsHwState *hw,
+		     int buttons, int delay)
+{
+    SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+    SynapticsParameters *para = &priv->synpara;
+    int repeat_delay, timeleft;
+    int rep_buttons = ((para->updown_button_repeat ? 0x18 : 0) |
+			(para->leftright_button_repeat ? 0x60 : 0));
+
+    /* 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 = hw->millis + repeat_delay * 2;
+	}
+    } else {
+	priv->repeatButtons = 0;
+	priv->nextRepeat = 0;
+    }
+
+    if (priv->repeatButtons) {
+	timeleft = TIME_DIFF(priv->nextRepeat, hw->millis);
+	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));
+		post_button_click(local, id);
+	    }
+
+	    priv->nextRepeat = hw->millis + repeat_delay;
+	    delay = MIN(delay, repeat_delay);
+	}
+    }
+
+    return delay;
+}
+
 /*
  * React on changes in the hardware state. This function is called every time
  * the hardware state changes. The return value is used to specify how many
@@ -2191,11 +2240,11 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
     SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
     SynapticsParameters *para = &priv->synpara;
     int finger;
-    int dx, dy, buttons, rep_buttons, id;
+    int dx, dy, buttons, id;
     edge_type edge = NO_EDGE;
     int change;
     struct ScrollData scroll;
-    int double_click, repeat_delay;
+    int double_click = FALSE;
     int delay = 1000000000;
     int timeleft;
     Bool inside_active_area;
@@ -2208,7 +2257,8 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
 
     update_hw_button_state(local, hw, &delay);
 
-    double_click = adjust_state_from_scrollbuttons(local, hw);
+    if (priv->has_scrollbuttons)
+	double_click = adjust_state_from_scrollbuttons(local, hw);
 
     edge = edge_detection(priv, hw->x, hw->y);
     inside_active_area = is_inside_active_area(priv, hw->x, hw->y);
@@ -2234,8 +2284,6 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
     timeleft = ComputeDeltas(priv, hw, edge, &dx, &dy);
     delay = MIN(delay, timeleft);
 
-    rep_buttons = ((para->updown_button_repeat ? 0x18 : 0) |
-		   (para->leftright_button_repeat ? 0x60 : 0));
 
     buttons = ((hw->left     ? 0x01 : 0) |
 	       (hw->middle   ? 0x02 : 0) |
@@ -2297,38 +2345,8 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
 	post_button_click(local, 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 = hw->millis + repeat_delay * 2;
-	}
-    } else {
-	priv->repeatButtons = 0;
-	priv->nextRepeat = 0;
-    }
-
-    if (priv->repeatButtons) {
-	timeleft = TIME_DIFF(priv->nextRepeat, hw->millis);
-	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));
-		post_button_click(local, id);
-	    }
-
-	    priv->nextRepeat = hw->millis + repeat_delay;
-	    delay = MIN(delay, repeat_delay);
-	}
-    }
+    if (priv->has_scrollbuttons)
+	delay = repeat_scrollbuttons(local, hw, buttons, delay);
 
     /* Save old values of some state variables */
     priv->finger_state = finger;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index bd19c79..d123257 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -232,6 +232,7 @@ typedef struct _SynapticsPrivateRec
     Bool has_double;			/* double click detected for this device */
     Bool has_triple;			/* triple click detected for this device */
     Bool has_pressure;			/* device reports pressure */
+    Bool has_scrollbuttons;		/* device has physical scrollbuttons */
 
     enum TouchpadModel model;          /* The detected model */
 } SynapticsPrivate;
-- 
1.6.6.1



More information about the xorg-devel mailing list