summaryrefslogtreecommitdiff
path: root/src/synaptics.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-02-20 13:13:18 -0500
committerPeter Hutterer <peter.hutterer@who-t.net>2014-02-21 11:29:33 +1000
commit402cc872570b58b8420e7973d0706f3b2a2aaf91 (patch)
tree7a2fda16d0275177d23a72033cea5820e344daf5 /src/synaptics.c
parent945acfc261707be78cbc5438c22b061e20076004 (diff)
Add secondary (top) software buttons area
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.tissoires@redhat.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> [couple of man-page additions and rewrites] Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/synaptics.c')
-rw-r--r--src/synaptics.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/synaptics.c b/src/synaptics.c
index 1666045..5fd5edc 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -452,7 +452,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;
@@ -467,7 +467,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;
@@ -512,8 +512,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);
@@ -521,12 +521,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_primary_softbutton_areas_option(InputInfoPtr pInfo)
+{
+ set_softbutton_areas_option(pInfo, "SoftButtonAreas", 0);
+}
+
+static void
+set_secondary_softbutton_areas_option(InputInfoPtr pInfo)
+{
+ set_softbutton_areas_option(pInfo, "SecondarySoftButtonAreas", 2);
+}
+
+static void
set_default_parameters(InputInfoPtr pInfo)
{
SynapticsPrivate *priv = pInfo->private; /* read-only */
@@ -739,7 +751,8 @@ set_default_parameters(InputInfoPtr pInfo)
"TopEdge is bigger than BottomEdge. Fixing.\n");
}
- set_softbutton_areas_option(pInfo);
+ set_primary_softbutton_areas_option(pInfo);
+ set_secondary_softbutton_areas_option(pInfo);
}
static double
@@ -1501,6 +1514,18 @@ is_inside_middlebutton_area(SynapticsParameters * para, int x, int y)
return is_inside_button_area(para, 1, x, y);
}
+static Bool
+is_inside_sec_rightbutton_area(SynapticsParameters * para, int x, int y)
+{
+ return is_inside_button_area(para, 2, x, y);
+}
+
+static Bool
+is_inside_sec_middlebutton_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)
{
@@ -2715,10 +2740,18 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
hw->left = 0;
hw->right = 1;
}
+ else if (is_inside_sec_rightbutton_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_sec_middlebutton_area(para, hw->x, hw->y)) {
+ hw->left = 0;
+ hw->middle = 1;
+ }
}
else if (hw->left) {
hw->left = old->left;