Hi,
I just finished my orientation patch for synaptics. It's not heavily
tested for the moment. If anyone could test ...
I added 4 options to the driver, quoting from the man page:
Option "Orientation" "integer"
This option can be used to change the orientation of the track‐
pad and can takes values from 0 to 3. The default value 0
implies a normal orientation, other values can be used to have
respectively an orientation set to the left, an inverted orien‐
tation, and an orientation set to the right. This may be useful
in combinaison with the orientation option of the XRandR exten‐
sion. You may notice that the values used are the same to the
values used by XRandR. Along with this option, you might be
interested to enable the DontReportSize option. Read its docu‐
mentation to know why.
Option "DontReportSize" "boolean"
This option prevent the synaptics driver from reporting the size
of the trackpad to Xorg. Xorg can use this information to
amplify the movements in one direction. For example, if your
trackpad is wider than higher, Xorg will speed up your vertical
movements. For example, moving the mouse cursor every two pixels
when synaptics told Xorg that there was a movement on one unit
along the y axis. This is particularly useful with the Orienta‐
tion option which effectively swaps the axis inside the synap‐
tics driver. At that time, Xorg no longer have relevant informa‐
tion about the size of the x and y axis and might amplifying the
movements of the wrong axis. Causing an unusable trackpad, over
sensitive horizontally and very slow vertically for example.
Option "VertSpeed" "float"
Changes the vertical speed. This is a number multiplied by the
input given by the trackpad. So a value above 1 speed up the
vertical axis, a value below 1 slows down the vertical move‐
ments. This option isn't affected by the orientation, so when
the screen is rotated using XRandR, the movements you have with
your oriented trackpad will be similar to those you have with a
non oriented trackpad and a non rotated screen.
Option "HorizSpeed" "float"
Changes the horizontal speed similarly to VertSpeed.
The patch is licenced under the MIT licence.
The next thing would be to automatically change the orientation of the
trackpad when XRandR rotates the screen.
Mildred
--
Mildred Ki'Lya
╭───────── mildred593@online.fr ──────────
│ Jabber, GoogleTalk: <[EMAIL PROTECTED]>
│ Site: <http://ki.lya.online.fr> GPG ID: 9A7D 2E2B
│ Fingerprint: 197C A7E6 645B 4299 6D37 684B 6F9D A8D6 9A7D 2E2B
diff --git a/include/synaptics.h b/include/synaptics.h
index 7e55293..77c4622 100644
--- a/include/synaptics.h
+++ b/include/synaptics.h
@@ -133,6 +133,10 @@ typedef struct _SynapticsSHM
double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */
double press_motion_max_factor; /* factor applied on speed when finger pressure is at minimum */
Bool grab_event_device; /* grab event device for exclusive use? */
+ int orientation; /* orientation of the trackpad */
+ Bool dont_report_size; /* Don't report the size of the trackpad to Xorg */
+ double horiz_speed; /* Horizontal speed for mouse movements */
+ double vert_speed; /* Vertical speed for mouse movements */
} SynapticsSHM;
/*
diff --git a/man/synaptics.man b/man/synaptics.man
index 79958e7..491a160 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -384,6 +384,47 @@ reenabled.
.
This can be achieved by switching to a text console and then switching
back to X.
+.TP
+.BI "Option \*qOrientation\*q \*q" integer \*q
+This option can be used to change the orientation of the trackpad and can
+takes values from 0 to 3. The default value 0 implies a normal orientation,
+other values can be used to have respectively an orientation set to the
+left, an inverted orientation, and an orientation set to the right.
+This may be useful in combinaison with the orientation option of the XRandR
+extension. You may notice that the values used are the same to the values
+used by XRandR.
+.
+Along with this option, you might be interested to enable the DontReportSize
+option. Read its documentation to know why.
+.
+.TP
+.BI "Option \*qDontReportSize\*q \*q" boolean \*q
+This option prevent the synaptics driver from reporting the size of the trackpad
+to Xorg. Xorg can use this information to amplify the movements in one
+direction. For example, if your trackpad is wider than higher, Xorg will speed
+up your vertical movements. For example, moving the mouse cursor every two
+pixels when synaptics told Xorg that there was a movement on one unit along the
+y axis.
+.
+This is particularly useful with the Orientation option which effectively swaps
+the axis inside the synaptics driver. At that time, Xorg no longer have relevant
+information about the size of the x and y axis and might amplifying the
+movements of the wrong axis. Causing an unusable trackpad, over sensitive
+horizontally and very slow vertically for example.
+.
+.TP
+.BI "Option \*qVertSpeed\*q \*q" float \*q
+Changes the vertical speed. This is a number multiplied by the input given by
+the trackpad. So a value above 1 speed up the vertical axis, a value below 1
+slows down the vertical movements.
+.
+This option isn't affected by the orientation, so when the screen is rotated
+using XRandR, the movements you have with your oriented trackpad will be similar
+to those you have with a non oriented trackpad and a non rotated screen.
+.
+.TP
+.BI "Option \*qHorizSpeed\*q \*q" float \*q
+Changes the horizontal speed similarly to VertSpeed.
.
.
.LP
diff --git a/src/synaptics.c b/src/synaptics.c
index df29358..7e4d4a4 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -475,6 +475,8 @@ static void set_default_parameters(LocalDevicePtr local)
pars->single_tap_timeout = xf86SetIntOption(opts, "SingleTapTimeout", 180);
pars->press_motion_min_z = xf86SetIntOption(opts, "PressureMotionMinZ", pressureMotionMinZ);
pars->press_motion_max_z = xf86SetIntOption(opts, "PressureMotionMaxZ", pressureMotionMaxZ);
+ pars->orientation = xf86SetIntOption(opts, "Orientation", 0);
+ pars->dont_report_size = xf86SetBoolOption(opts, "DontReportSize", FALSE);
pars->min_speed = synSetFloatOption(opts, "MinSpeed", 0.4);
pars->max_speed = synSetFloatOption(opts, "MaxSpeed", 0.7);
@@ -484,6 +486,8 @@ static void set_default_parameters(LocalDevicePtr local)
pars->coasting_speed = synSetFloatOption(opts, "CoastingSpeed", 0.0);
pars->press_motion_min_factor = synSetFloatOption(opts, "PressureMotionMinFactor", 1.0);
pars->press_motion_max_factor = synSetFloatOption(opts, "PressureMotionMaxFactor", 1.0);
+ pars->horiz_speed = synSetFloatOption(opts, "HorizSpeed", 1.0);
+ pars->vert_speed = synSetFloatOption(opts, "VertSpeed", 1.0);
pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE);
/* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
@@ -774,13 +778,13 @@ DeviceInit(DeviceIntPtr dev)
#endif
);
/* X valuator */
- if (priv->minx < priv->maxx)
+ if (priv->minx < priv->maxx && priv->synpara->dont_report_size == FALSE)
xf86InitValuatorAxisStruct(dev, 0, priv->minx, priv->maxx, 1, 0, 1);
else
xf86InitValuatorAxisStruct(dev, 0, 0, -1, 1, 0, 1);
xf86InitValuatorDefaults(dev, 0);
/* Y valuator */
- if (priv->miny < priv->maxy)
+ if (priv->miny < priv->maxy && priv->synpara->dont_report_size == FALSE)
xf86InitValuatorAxisStruct(dev, 1, priv->miny, priv->maxy, 1, 0, 1);
else
xf86InitValuatorAxisStruct(dev, 1, 0, -1, 1, 0, 1);
@@ -1397,6 +1401,54 @@ estimate_delta(double x0, double x1, double x2, double x3)
return x0 * 0.3 + x1 * 0.1 - x2 * 0.1 - x3 * 0.3;
}
+static void
+HandleOrientation_double(int orientation, double *dx, double *dy) {
+ double tmp;
+ switch(orientation) {
+ default:
+ case 0:
+ break;
+ case 1: /* left */
+ tmp = *dx;
+ *dx = -*dy;
+ *dy = tmp;
+ break;
+ case 2: /* inverted */
+ *dx = -*dx;
+ *dy = -*dy;
+ break;
+ case 3: /* right */
+ tmp = *dx;
+ *dx = *dy;
+ *dy = -tmp;
+ break;
+ }
+}
+
+static void
+HandleOrientation_int(int orientation, int *dx, int *dy) {
+ int tmp;
+ switch(orientation) {
+ default:
+ case 0:
+ break;
+ case 1: /* left */
+ tmp = *dx;
+ *dx = -*dy;
+ *dy = tmp;
+ break;
+ case 2: /* inverted */
+ *dx = -*dx;
+ *dy = -*dy;
+ break;
+ case 3: /* right */
+ tmp = *dx;
+ *dx = *dy;
+ *dy = -tmp;
+ break;
+ }
+}
+
static int
ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
edge_type edge, int *dxP, int *dyP)
@@ -1439,14 +1491,20 @@ ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
double dtime = (hw->millis - HIST(0).millis) / 1000.0;
if (priv->moving_state == MS_TRACKSTICK) {
- dx = (hw->x - priv->trackstick_neutral_x);
- dy = (hw->y - priv->trackstick_neutral_y);
+ dx = (hw->x - priv->trackstick_neutral_x) * para->horiz_speed;
+ dy = (hw->y - priv->trackstick_neutral_y) * para->vert_speed;
+
+ HandleOrientation_double(para->orientation, &dx, &dy);
dx = dx * dtime * para->trackstick_speed;
dy = dy * dtime * para->trackstick_speed;
} else if (moving_state == MS_TOUCHPAD_RELATIVE) {
- dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x);
- dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y);
+ dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x)
+ * para->horiz_speed;
+ dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y)
+ * para->vert_speed;
+
+ HandleOrientation_double(para->orientation, &dx, &dy);
if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always) {
int minZ = para->edge_motion_min_z;
@@ -1462,7 +1520,7 @@ ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
} else {
edge_speed = minSpd + (hw->z - minZ) * (maxSpd - minSpd) / (maxZ - minZ);
}
- if (!priv->synpara->circular_pad) {
+ if (!para->circular_pad) {
/* on rectangular pad */
if (edge & RIGHT_EDGE) {
x_edge_speed = edge_speed;
@@ -1481,6 +1539,9 @@ ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
relative_coords(priv, hw->x, hw->y, &relX, &relY);
x_edge_speed = (int)(edge_speed * relX);
y_edge_speed = (int)(edge_speed * relY);
+
+ HandleOrientation_int(para->orientation,
+ &x_edge_speed, &y_edge_speed);
}
}
}
@@ -1544,7 +1605,7 @@ struct ScrollData {
};
static void
-start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type edge,
+start_coasting(SynapticsPrivate *priv, int x, int y, edge_type edge,
Bool vertical)
{
SynapticsSHM *para = priv->synpara;
@@ -1561,7 +1622,7 @@ start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type ed
double scrolls_per_sec = dy / pkt_time / sdelta;
if (fabs(scrolls_per_sec) >= para->coasting_speed) {
priv->autoscroll_yspd = scrolls_per_sec;
- priv->autoscroll_y = (hw->y - priv->scroll_y) / (double)sdelta;
+ priv->autoscroll_y = (y - priv->scroll_y) / (double)sdelta;
}
}
} else {
@@ -1571,7 +1632,7 @@ start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type ed
double scrolls_per_sec = dx / pkt_time / sdelta;
if (fabs(scrolls_per_sec) >= para->coasting_speed) {
priv->autoscroll_xspd = scrolls_per_sec;
- priv->autoscroll_x = (hw->x - priv->scroll_x) / (double)sdelta;
+ priv->autoscroll_x = (x - priv->scroll_x) / (double)sdelta;
}
}
}
@@ -1593,6 +1654,9 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
{
SynapticsSHM *para = priv->synpara;
int delay = 1000000000;
+ int oriented_x = hw->x, oriented_y = hw->y;
+
+ HandleOrientation_int(para->orientation, &oriented_x, &oriented_y);
sd->left = sd->right = sd->up = sd->down = 0;
@@ -1633,14 +1697,14 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
(para->scroll_twofinger_vert) && (para->scroll_dist_vert != 0)) {
priv->vert_scroll_twofinger_on = TRUE;
priv->vert_scroll_edge_on = FALSE;
- priv->scroll_y = hw->y;
+ priv->scroll_y = oriented_y;
DBG(7, ErrorF("vert two-finger scroll detected\n"));
}
if (!priv->horiz_scroll_twofinger_on &&
(para->scroll_twofinger_horiz) && (para->scroll_dist_horiz != 0)) {
priv->horiz_scroll_twofinger_on = TRUE;
priv->horiz_scroll_edge_on = FALSE;
- priv->scroll_x = hw->x;
+ priv->scroll_x = oriented_x;
DBG(7, ErrorF("horiz two-finger scroll detected\n"));
}
}
@@ -1650,13 +1714,13 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
(edge & RIGHT_EDGE)) {
priv->vert_scroll_edge_on = TRUE;
- priv->scroll_y = hw->y;
+ priv->scroll_y = oriented_y;
DBG(7, ErrorF("vert edge scroll detected on right edge\n"));
}
if ((para->scroll_edge_horiz) && (para->scroll_dist_horiz != 0) &&
(edge & BOTTOM_EDGE)) {
priv->horiz_scroll_edge_on = TRUE;
- priv->scroll_x = hw->x;
+ priv->scroll_x = oriented_x;
DBG(7, ErrorF("horiz edge scroll detected on bottom edge\n"));
}
}
@@ -1706,7 +1770,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
if ((oldv || oldh) && !para->scroll_edge_corner &&
!(priv->circ_scroll_on || priv->vert_scroll_edge_on ||
priv->horiz_scroll_edge_on)) {
- start_coasting(priv, hw, edge, oldv);
+ start_coasting(priv, oriented_x, oriented_y, edge, oldv);
}
}
@@ -1721,7 +1785,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
* we're in the corner, but we were moving so slowly when we
* got here that we didn't actually start coasting. */
DBG(7, ErrorF("corner edge scroll on\n"));
- start_coasting(priv, hw, edge, TRUE);
+ start_coasting(priv, oriented_x, oriented_y, edge, TRUE);
}
} else if (para->circular_scrolling) {
priv->vert_scroll_edge_on = FALSE;
@@ -1740,7 +1804,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
* we're in the corner, but we were moving so slowly when we
* got here that we didn't actually start coasting. */
DBG(7, ErrorF("corner edge scroll on\n"));
- start_coasting(priv, hw, edge, FALSE);
+ start_coasting(priv, oriented_x, oriented_y, edge, FALSE);
}
} else if (para->circular_scrolling) {
priv->horiz_scroll_edge_on = FALSE;
@@ -1761,11 +1825,11 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
/* + = down, - = up */
int delta = para->scroll_dist_vert;
if (delta > 0) {
- while (hw->y - priv->scroll_y > delta) {
+ while (oriented_y - priv->scroll_y > delta) {
sd->down++;
priv->scroll_y += delta;
}
- while (hw->y - priv->scroll_y < -delta) {
+ while (oriented_y - priv->scroll_y < -delta) {
sd->up++;
priv->scroll_y -= delta;
}
@@ -1775,11 +1839,11 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
/* + = right, - = left */
int delta = para->scroll_dist_horiz;
if (delta > 0) {
- while (hw->x - priv->scroll_x > delta) {
+ while (oriented_x - priv->scroll_x > delta) {
sd->right++;
priv->scroll_x += delta;
}
- while (hw->x - priv->scroll_x < -delta) {
+ while (oriented_x - priv->scroll_x < -delta) {
sd->left++;
priv->scroll_x -= delta;
}
@@ -1870,6 +1934,46 @@ HandleClickWithFingers(SynapticsSHM *para, struct SynapticsHwState *hw)
}
}
+static edge_type
+HandleEdgeOrientation(int orientation, edge_type edge) {
+ int new_edge = 0;
+ if(edge & BOTTOM_EDGE) {
+ switch(orientation) {
+ default:
+ case 0: new_edge |= BOTTOM_EDGE; break;
+ case 1: new_edge |= LEFT_EDGE; break;
+ case 2: new_edge |= TOP_EDGE; break;
+ case 3: new_edge |= RIGHT_EDGE; break;
+ }
+ } else if(edge & TOP_EDGE) {
+ switch(orientation) {
+ default:
+ case 0: new_edge |= TOP_EDGE; break;
+ case 1: new_edge |= RIGHT_EDGE; break;
+ case 2: new_edge |= BOTTOM_EDGE; break;
+ case 3: new_edge |= LEFT_EDGE; break;
+ }
+ }
+ if(edge & LEFT_EDGE) {
+ switch(orientation) {
+ default:
+ case 0: new_edge |= LEFT_EDGE; break;
+ case 1: new_edge |= TOP_EDGE; break;
+ case 2: new_edge |= RIGHT_EDGE; break;
+ case 3: new_edge |= BOTTOM_EDGE; break;
+ }
+ } else if(edge & RIGHT_EDGE) {
+ switch(orientation) {
+ default:
+ case 0: new_edge |= RIGHT_EDGE; break;
+ case 1: new_edge |= BOTTOM_EDGE; break;
+ case 2: new_edge |= LEFT_EDGE; break;
+ case 3: new_edge |= TOP_EDGE; break;
+ }
+ }
+ return new_edge;
+}
+
/*
* React on changes in the hardware state. This function is called every time
@@ -1928,16 +2032,16 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
/* 3rd button emulation */
hw->middle |= HandleMidButtonEmulation(priv, hw, &delay);
- /* Fingers emulate other buttons */
- if(hw->left && hw->numFingers >= 1){
- HandleClickWithFingers(para, hw);
- }
-
/* Two finger emulation */
if (hw->z >= para->emulate_twofinger_z && hw->numFingers == 1) {
hw->numFingers = 2;
}
+ /* Fingers emulate other buttons */
+ if(hw->left && hw->numFingers >= 1){
+ HandleClickWithFingers(para, hw);
+ }
+
/* Up/Down button scrolling or middle/double click */
double_click = FALSE;
if (!para->updown_button_scrolling) {
@@ -1995,6 +2099,7 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
}
edge = edge_detection(priv, hw->x, hw->y);
+ edge = HandleEdgeOrientation(para->orientation, edge);
finger = SynapticsDetectFinger(priv, hw);
diff --git a/tools/synclient.c b/tools/synclient.c
index 2677d63..3672cb7 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -123,6 +123,10 @@ static struct Parameter params[] = {
DEFINE_PAR("PressureMotionMinFactor", press_motion_min_factor, PT_DOUBLE, 0, 10.0),
DEFINE_PAR("PressureMotionMaxFactor", press_motion_max_factor, PT_DOUBLE, 0, 10.0),
DEFINE_PAR("GrabEventDevice", grab_event_device, PT_BOOL, 0, 1),
+ DEFINE_PAR("Orientation", orientation, PT_INT, 0, 3),
+ DEFINE_PAR("DontReportSize", dont_report_size, PT_BOOL, 0, 1),
+ DEFINE_PAR("HorizSpeed", horiz_speed, PT_DOUBLE, 0, 10),
+ DEFINE_PAR("VertSpeed", vert_speed, PT_DOUBLE, 0, 10),
{ NULL, 0, 0, 0, 0 }
};
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg