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

Reply via email to