mirror of
https://github.com/X11Libre/xf86-input-synaptics.git
synced 2026-04-14 11:54:16 +00:00
Added support for circular touchpads. Based on a patch from
Axel G. Rossberg <Axel@Rossberg.net>.
This commit is contained in:
3
README
3
README
@@ -121,6 +121,9 @@ CircScrollTrigger Int Trigger region on the touchpad to start circular scrolling
|
||||
0=All Edges, 1=Top Edge, 2=Top Right Corner, 3=Right Edge,
|
||||
4=Bottom Right Corner, 5=Bottom Edge, 6=Bottom Left Corner,
|
||||
7=Left Edge, 8=Top Left Corner
|
||||
CircularPad Bool Instead of being a rectangle, the edge is the ellipse
|
||||
enclosed by the Left/Right/Top/BottomEdge parameters.
|
||||
For circular touchpads.
|
||||
|
||||
A tap event happens when the finger is touched and released in a time
|
||||
interval shorter than MaxTapTime, and the touch and release
|
||||
|
||||
89
synaptics.c
89
synaptics.c
@@ -103,6 +103,10 @@ typedef enum {
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_SQRT1_2
|
||||
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Forward declaration
|
||||
****************************************************************************/
|
||||
@@ -332,6 +336,7 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
||||
pars->tap_action[F3_TAP] = xf86SetIntOption(local->options, "TapButton3", 3);
|
||||
pars->circular_scrolling = xf86SetBoolOption(local->options, "CircularScrolling", FALSE);
|
||||
pars->circular_trigger = xf86SetIntOption(local->options, "CircScrollTrigger", 0);
|
||||
pars->circular_pad = xf86SetBoolOption(local->options, "CircularPad", FALSE);
|
||||
|
||||
str_par = xf86FindOptionValue(local->options, "MinSpeed");
|
||||
if ((!str_par) || (xf86sscanf(str_par, "%lf", &pars->min_speed) != 1))
|
||||
@@ -564,6 +569,30 @@ move_distance(int dx, int dy)
|
||||
return xf86sqrt((dx * dx) + (dy * dy));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from absolute X/Y coordinates to a coordinate system where
|
||||
* -1 corresponds to the left/upper edge and +1 corresponds to the
|
||||
* right/lower edge.
|
||||
*/
|
||||
static void relative_coords(SynapticsPrivate *priv, int x, int y,
|
||||
double* relX, double* relY)
|
||||
{
|
||||
int minX = priv->synpara->left_edge;
|
||||
int maxX = priv->synpara->right_edge;
|
||||
int minY = priv->synpara->top_edge;
|
||||
int maxY = priv->synpara->bottom_edge;
|
||||
double xCenter = (minX + maxX) / 2.0;
|
||||
double yCenter = (minY + maxY) / 2.0;
|
||||
|
||||
if ((maxX - xCenter > 0) && (maxY - yCenter > 0)) {
|
||||
*relX = (x - xCenter) / (maxX - xCenter);
|
||||
*relY = (y - yCenter) / (maxY - yCenter);
|
||||
} else {
|
||||
*relX = 0;
|
||||
*relY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* return angle of point relative to center */
|
||||
static double
|
||||
angle(SynapticsPrivate *priv, int x, int y)
|
||||
@@ -586,11 +615,39 @@ diffa(double a1, double a2)
|
||||
return da;
|
||||
}
|
||||
|
||||
static edge_type
|
||||
circular_edge_detection(SynapticsPrivate *priv, int x, int y)
|
||||
{
|
||||
edge_type edge = 0;
|
||||
double relX, relY, relR;
|
||||
|
||||
relative_coords(priv, x, y, &relX, &relY);
|
||||
relR = relX * relX + relY * relY;
|
||||
|
||||
if (relR > 1) {
|
||||
/* we are outside the ellipse enclosed by the edge parameters */
|
||||
if (relX > M_SQRT1_2)
|
||||
edge |= RIGHT_EDGE;
|
||||
else if (relX < -M_SQRT1_2)
|
||||
edge |= LEFT_EDGE;
|
||||
|
||||
if (relY < -M_SQRT1_2)
|
||||
edge |= TOP_EDGE;
|
||||
else if (relY > M_SQRT1_2)
|
||||
edge |= BOTTOM_EDGE;
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
static edge_type
|
||||
edge_detection(SynapticsPrivate *priv, int x, int y)
|
||||
{
|
||||
edge_type edge = 0;
|
||||
|
||||
if (priv->synpara->circular_pad)
|
||||
return circular_edge_detection(priv, x, y);
|
||||
|
||||
if (x > priv->synpara->right_edge)
|
||||
edge |= RIGHT_EDGE;
|
||||
else if (x < priv->synpara->left_edge)
|
||||
@@ -1046,6 +1103,8 @@ static long ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
|
||||
int minSpd = para->edge_motion_min_speed;
|
||||
int maxSpd = para->edge_motion_max_speed;
|
||||
int edge_speed;
|
||||
int x_edge_speed = 0;
|
||||
int y_edge_speed = 0;
|
||||
|
||||
if (hw->z <= minZ) {
|
||||
edge_speed = minSpd;
|
||||
@@ -1054,16 +1113,28 @@ static long ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
|
||||
} else {
|
||||
edge_speed = minSpd + (hw->z - minZ) * (maxSpd - minSpd) / (maxZ - minZ);
|
||||
}
|
||||
if (edge & RIGHT_EDGE) {
|
||||
dx += clamp(edge_speed - dx, 0, edge_speed);
|
||||
} else if (edge & LEFT_EDGE) {
|
||||
dx -= clamp(edge_speed + dx, 0, edge_speed);
|
||||
}
|
||||
if (edge & TOP_EDGE) {
|
||||
dy -= clamp(edge_speed + dy, 0, edge_speed);
|
||||
} else if (edge & BOTTOM_EDGE) {
|
||||
dy += clamp(edge_speed - dy, 0, edge_speed);
|
||||
if (!priv->synpara->circular_pad) {
|
||||
/* on rectangular pad */
|
||||
if (edge & RIGHT_EDGE) {
|
||||
x_edge_speed = edge_speed;
|
||||
} else if (edge & LEFT_EDGE) {
|
||||
x_edge_speed = -edge_speed;
|
||||
}
|
||||
if (edge & TOP_EDGE) {
|
||||
y_edge_speed = -edge_speed;
|
||||
} else if (edge & BOTTOM_EDGE) {
|
||||
y_edge_speed = edge_speed;
|
||||
}
|
||||
} else if (edge) {
|
||||
/* at edge of circular pad */
|
||||
double relX, relY;
|
||||
|
||||
relative_coords(priv, hw->x, hw->y, &relX, &relY);
|
||||
x_edge_speed = (int)(edge_speed * relX);
|
||||
y_edge_speed = (int)(edge_speed * relY);
|
||||
}
|
||||
dx += x_edge_speed;
|
||||
dy += y_edge_speed;
|
||||
}
|
||||
|
||||
/* speed depending on distance/packet */
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef struct _SynapticsSHM
|
||||
Bool circular_scrolling; /* Enable circular scrolling */
|
||||
double scroll_dist_circ; /* Scrolling angle radians */
|
||||
int circular_trigger; /* Trigger area for circular scrolling */
|
||||
Bool circular_pad; /* Edge has an oval or circular shape */
|
||||
} SynapticsSHM;
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,6 +100,7 @@ static struct Parameter params[] = {
|
||||
DEFINE_PAR("CircularScrolling", circular_scrolling, PT_BOOL, 0, 1),
|
||||
DEFINE_PAR("CircScrollDelta", scroll_dist_circ, PT_DOUBLE, .01, 3),
|
||||
DEFINE_PAR("CircScrollTrigger", circular_trigger, PT_INT, 0, 8),
|
||||
DEFINE_PAR("CircularPad", circular_pad, PT_BOOL, 0, 1),
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user