Commit 402cc872 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Peter Hutterer
Browse files

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's avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>

[couple of man-page additions and rewrites]
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 945acfc2
...@@ -489,6 +489,18 @@ soft button areas. Button areas may not overlap, however it is permitted for two ...@@ -489,6 +489,18 @@ soft button areas. Button areas may not overlap, however it is permitted for two
buttons to share an edge value. buttons to share an edge value.
Property: "Synaptics Soft Button Areas" 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).
For the allowed values for this option, see
.B Option \*qSoftButtonAreas\*q.
Primary and secondary soft button areas must not overlap each other. If they do,
the behavior of the driver is undefined.
No property associated, this option must be set in the
__xconfigfile__(__filemansuffix__).
.
.SH CONFIGURATION DETAILS .SH CONFIGURATION DETAILS
.SS Area handling .SS Area handling
...@@ -708,6 +720,12 @@ ClickPads provide software emulated buttons through ...@@ -708,6 +720,12 @@ ClickPads provide software emulated buttons through
These buttons enable areas on the touchpad to perform as right or middle These buttons enable areas on the touchpad to perform as right or middle
mouse button. When the user performs a click within a defined soft button mouse button. When the user performs a click within a defined soft button
area, a right or middle click is performed. area, a right or middle click is performed.
.LP
Some laptops, most notably the Lenovo T440, T540 and x240 series, provide a
pointing stick without physical buttons. On those laptops, the top of the
touchpad acts as software-emulated button area. This area can be configured
with
.B Option SecondarySoftButtonAreas.
.SH "DEVICE PROPERTIES" .SH "DEVICE PROPERTIES"
Synaptics 1.0 and higher support input device properties if the driver is Synaptics 1.0 and higher support input device properties if the driver is
......
...@@ -452,7 +452,7 @@ SynapticsIsSoftButtonAreasValid(int *values) ...@@ -452,7 +452,7 @@ SynapticsIsSoftButtonAreasValid(int *values)
} }
static void static void
set_softbutton_areas_option(InputInfoPtr pInfo) set_softbutton_areas_option(InputInfoPtr pInfo, char *option_name, int offset)
{ {
SynapticsPrivate *priv = pInfo->private; SynapticsPrivate *priv = pInfo->private;
SynapticsParameters *pars = &priv->synpara; SynapticsParameters *pars = &priv->synpara;
...@@ -467,7 +467,7 @@ set_softbutton_areas_option(InputInfoPtr pInfo) ...@@ -467,7 +467,7 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
if (!pars->clickpad) if (!pars->clickpad)
return; return;
option_string = xf86SetStrOption(pInfo->options, "SoftButtonAreas", NULL); option_string = xf86SetStrOption(pInfo->options, option_name, NULL);
if (!option_string) if (!option_string)
return; return;
...@@ -512,8 +512,8 @@ set_softbutton_areas_option(InputInfoPtr pInfo) ...@@ -512,8 +512,8 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
if (!SynapticsIsSoftButtonAreasValid(values)) if (!SynapticsIsSoftButtonAreasValid(values))
goto fail; goto fail;
memcpy(pars->softbutton_areas[0], values, 4 * sizeof(int)); memcpy(pars->softbutton_areas[offset], values, 4 * sizeof(int));
memcpy(pars->softbutton_areas[1], values + 4, 4 * sizeof(int)); memcpy(pars->softbutton_areas[offset + 1], values + 4, 4 * sizeof(int));
free(option_string); free(option_string);
...@@ -521,11 +521,23 @@ set_softbutton_areas_option(InputInfoPtr pInfo) ...@@ -521,11 +521,23 @@ set_softbutton_areas_option(InputInfoPtr pInfo)
fail: fail:
xf86IDrvMsg(pInfo, X_ERROR, xf86IDrvMsg(pInfo, X_ERROR,
"invalid SoftButtonAreas value '%s', keeping defaults\n", "invalid %s value '%s', keeping defaults\n",
option_string); option_name, option_string);
free(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 static void
set_default_parameters(InputInfoPtr pInfo) set_default_parameters(InputInfoPtr pInfo)
{ {
...@@ -739,7 +751,8 @@ set_default_parameters(InputInfoPtr pInfo) ...@@ -739,7 +751,8 @@ set_default_parameters(InputInfoPtr pInfo)
"TopEdge is bigger than BottomEdge. Fixing.\n"); "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 static double
...@@ -1501,6 +1514,18 @@ is_inside_middlebutton_area(SynapticsParameters * para, int x, int y) ...@@ -1501,6 +1514,18 @@ is_inside_middlebutton_area(SynapticsParameters * para, int x, int y)
return is_inside_button_area(para, 1, x, 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 static CARD32
timerFunc(OsTimerPtr timer, CARD32 now, pointer arg) timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
{ {
...@@ -2715,10 +2740,18 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw, ...@@ -2715,10 +2740,18 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
hw->left = 0; hw->left = 0;
hw->right = 1; 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)) { else if (is_inside_middlebutton_area(para, hw->x, hw->y)) {
hw->left = 0; hw->left = 0;
hw->middle = 1; 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) { else if (hw->left) {
hw->left = old->left; hw->left = old->left;
......
...@@ -205,7 +205,7 @@ typedef struct _SynapticsParameters { ...@@ -205,7 +205,7 @@ typedef struct _SynapticsParameters {
unsigned int resolution_horiz; /* horizontal resolution of touchpad in units/mm */ unsigned int resolution_horiz; /* horizontal resolution of touchpad in units/mm */
unsigned int resolution_vert; /* vertical 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 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 */ int hyst_x, hyst_y; /* x and y width of hysteresis box */
} SynapticsParameters; } SynapticsParameters;
......
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