From: Benjamin Tissoires <benjamin.tissoi...@redhat.com>

New generation of laptops with trackstick do not have physical buttons
associated with the trackstick, but instead rely on software buttons at
the top of the clickpad.
Adding a secondary software button area for this purpose.
As we're likely detecting the devices that need it based on udev tags
and MatchTag configuration items, this area doesn't need to be exposed
through properties. So static configuration is fine.

Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com>
Reviewed-by: Hans de Goede <hdego...@redhat.com>
Signed-off-by: Hans de Goede <hdego...@redhat.com>
---
 man/synaptics.man  |  8 ++++++++
 src/synaptics.c    | 47 ++++++++++++++++++++++++++++++++++++++++-------
 src/synapticsstr.h |  2 +-
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/man/synaptics.man b/man/synaptics.man
index 8e7d27e..f2d178f 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -490,6 +490,14 @@ soft button areas. Button areas may not overlap, however 
it is permitted for two
 buttons to share an edge value.
 Property: "Synaptics Soft Button Areas"
 .
+.TP
+.BI "Option \*qTopSoftButtonAreas\*q \*q" "RBL RBR RBT RBB MBL MBR MBT MBB" \*q
+This option is only available on ClickPad devices.
+Enable secondary soft button click area support on ClickPad devices (usually on
+top of the device).
+Same semantic than \*qSoftButtonAreas\*q.
+No property associated.
+.
 
 .SH CONFIGURATION DETAILS
 .SS Area handling
diff --git a/src/synaptics.c b/src/synaptics.c
index 34de488..ac18c40 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -460,7 +460,7 @@ SynapticsIsSoftButtonAreasValid(int *values)
 }
 
 static void
-set_softbutton_areas_option(InputInfoPtr pInfo)
+set_softbutton_areas_option(InputInfoPtr pInfo, char *option_name, int offset)
 {
     SynapticsPrivate *priv = pInfo->private;
     SynapticsParameters *pars = &priv->synpara;
@@ -475,7 +475,7 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
     if (!pars->clickpad)
         return;
 
-    option_string = xf86SetStrOption(pInfo->options, "SoftButtonAreas", NULL);
+    option_string = xf86SetStrOption(pInfo->options, option_name, NULL);
     if (!option_string)
         return;
 
@@ -520,8 +520,8 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
     if (!SynapticsIsSoftButtonAreasValid(values))
         goto fail;
 
-    memcpy(pars->softbutton_areas[0], values, 4 * sizeof(int));
-    memcpy(pars->softbutton_areas[1], values + 4, 4 * sizeof(int));
+    memcpy(pars->softbutton_areas[offset], values, 4 * sizeof(int));
+    memcpy(pars->softbutton_areas[offset + 1], values + 4, 4 * sizeof(int));
 
     free(option_string);
 
@@ -529,12 +529,24 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
 
  fail:
     xf86IDrvMsg(pInfo, X_ERROR,
-                "invalid SoftButtonAreas value '%s', keeping defaults\n",
-                option_string);
+                "invalid %s value '%s', keeping defaults\n",
+                option_name, option_string);
     free(option_string);
 }
 
 static void
+set_bottomsoftbutton_areas_option(InputInfoPtr pInfo)
+{
+       set_softbutton_areas_option(pInfo, "SoftButtonAreas", 0);
+}
+
+static void
+set_topsoftbutton_areas_option(InputInfoPtr pInfo)
+{
+       set_softbutton_areas_option(pInfo, "TopSoftButtonAreas", 2);
+}
+
+static void
 set_default_parameters(InputInfoPtr pInfo)
 {
     SynapticsPrivate *priv = pInfo->private;    /* read-only */
@@ -747,7 +759,8 @@ set_default_parameters(InputInfoPtr pInfo)
                     "TopEdge is bigger than BottomEdge. Fixing.\n");
     }
 
-    set_softbutton_areas_option(pInfo);
+    set_bottomsoftbutton_areas_option(pInfo);
+    set_topsoftbutton_areas_option(pInfo);
 }
 
 static double
@@ -1517,6 +1530,18 @@ is_inside_middlebutton_area(SynapticsParameters * para, 
int x, int y)
     return is_inside_button_area(para, 1, x, y);
 }
 
+static Bool
+is_inside_toprightbutton_area(SynapticsParameters * para, int x, int y)
+{
+    return is_inside_button_area(para, 2, x, y);
+}
+
+static Bool
+is_inside_topmiddlebutton_area(SynapticsParameters * para, int x, int y)
+{
+    return is_inside_button_area(para, 3, x, y);
+}
+
 static CARD32
 timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
 {
@@ -2734,10 +2759,18 @@ update_hw_button_state(const InputInfoPtr pInfo, struct 
SynapticsHwState *hw,
                     hw->left = 0;
                     hw->right = 1;
                 }
+                else if (is_inside_toprightbutton_area(para, hw->x, hw->y)) {
+                    hw->left = 0;
+                    hw->right = 1;
+                }
                 else if (is_inside_middlebutton_area(para, hw->x, hw->y)) {
                     hw->left = 0;
                     hw->middle = 1;
                 }
+                else if (is_inside_topmiddlebutton_area(para, hw->x, hw->y)) {
+                    hw->left = 0;
+                    hw->middle = 1;
+                }
         }
         else if (hw->left) {
             hw->left = old->left;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 8e1efc5..59935b2 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -207,7 +207,7 @@ typedef struct _SynapticsParameters {
     unsigned int resolution_horiz;      /* horizontal resolution of touchpad 
in units/mm */
     unsigned int resolution_vert;       /* vertical resolution of touchpad in 
units/mm */
     int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge;      
 /* area coordinates absolute */
-    int softbutton_areas[2][4]; /* soft button area coordinates, 0 => right, 1 
=> middle button */
+    int softbutton_areas[4][4]; /* soft button area coordinates, 0 => right, 1 
=> middle , 2 => top right, 3 => top middle button */
     int hyst_x, hyst_y;         /* x and y width of hysteresis box */
 } SynapticsParameters;
 
-- 
1.9.0

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to