From 36f2e466b9fa1e30bce8e30df2cb3dc1e4602f16 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 20 Feb 2014 13:13:18 -0500 Subject: [PATCH] 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 --- man/synaptics.man | 10 ++++++++++ src/synaptics.c | 47 ++++++++++++++++++++++++++++++++++++++++------- src/synapticsstr.h | 2 +- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/man/synaptics.man b/man/synaptics.man index a7889c7..c379808 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -489,6 +489,16 @@ 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 \*qSecondarySoftButtonAreas\*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 semantics as \*qSoftButtonAreas\*q. +Primary and secondary soft button areas should not overlap each other. If they do, +the behaviour is completely unpredictable. +No property associated. +. .SH CONFIGURATION DETAILS .SS Area handling 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; diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 54bc154..a60b3c0 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -205,7 +205,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 => secondary right, 3 => secondary middle button */ int hyst_x, hyst_y; /* x and y width of hysteresis box */ } SynapticsParameters; -- 1.8.5.3