summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorphilip <philip@FreeBSD.org>2007-03-11 20:02:26 +0000
committerphilip <philip@FreeBSD.org>2007-03-11 20:02:26 +0000
commit50b3f4c302935f38be277cc4f2b41c73be99018b (patch)
tree4fc03a1ea0f37e2a088a91780a4803632ce1d5e6 /usr.sbin
parentab3553dfb44e8eaa4aa684af4ef0c04ff425452c (diff)
downloadFreeBSD-src-50b3f4c302935f38be277cc4f2b41c73be99018b.zip
FreeBSD-src-50b3f4c302935f38be277cc4f2b41c73be99018b.tar.gz
Add dynamic acceleration to moused(8). This introduces a '-A' flag to control
the acceleration algorithm. It can be used together with the '-a' flag for regular acceleration. PR: bin/110003 Submitted by: Oliver Fromme <olli -at- lurza.secnetix.de> MFC after: 1 week
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/moused/Makefile4
-rw-r--r--usr.sbin/moused/moused.845
-rw-r--r--usr.sbin/moused/moused.c75
3 files changed, 116 insertions, 8 deletions
diff --git a/usr.sbin/moused/Makefile b/usr.sbin/moused/Makefile
index 014bf6f..a313a21 100644
--- a/usr.sbin/moused/Makefile
+++ b/usr.sbin/moused/Makefile
@@ -3,8 +3,8 @@
PROG= moused
MAN= moused.8
-DPADD= ${LIBUTIL}
-LDADD= -lutil
+DPADD= ${LIBUTIL} ${LIBM}
+LDADD= -lutil -lm
#BINMODE=4555
#PRECIOUSPROG=
diff --git a/usr.sbin/moused/moused.8 b/usr.sbin/moused/moused.8
index 4b2138d..c78086e 100644
--- a/usr.sbin/moused/moused.8
+++ b/usr.sbin/moused/moused.8
@@ -44,6 +44,7 @@
.Op Fl r Ar resolution
.Op Fl S Ar baudrate
.Op Fl VH Op Fl U Ar distance
+.Op Fl A Ar exp Ns Op , Ns Ar offset
.Op Fl a Ar X Ns Op , Ns Ar Y
.Op Fl C Ar threshold
.Op Fl m Ar N=M
@@ -213,12 +214,55 @@ mode is activated.
The default
.Ar distance
is 3 pixels.
+.It Fl A Ar exp Ns Op , Ns Ar offset
+Apply exponential (dynamic) acceleration to mouse movements:
+the faster you move the mouse, the more it will be accelerated.
+That means that small mouse movements are not accelerated,
+so they are still very accurate, while a faster movement will
+drive the pointer quickly across the screen.
+.Pp
+The
+.Ar exp
+value specifies the exponent, which is basically
+the amount of acceleration. Useful values are in the
+range 1.1 to 2.0, but it depends on your mouse hardware
+and your personal preference. A value of 1.0 means no
+exponential acceleration. A value of 2.0 means squared
+acceleration (i.e. if you move the mouse twice as fast,
+the pointer will move four times as fast on the screen).
+Values beyond 2.0 are possible but not recommended.
+A good value to start is probably 1.5.
+.Pp
+The optional
+.Ar offset
+value specifies the distance at which the acceleration
+begins. The default is 1.0, which means that the
+acceleration is applied to movements larger than one unit.
+If you specify a larger value, it takes more speed for
+the acceleration to kick in, i.e. the speed range for
+small and accurate movements is wider.
+Usually the default should be sufficient, but if you're
+not satisfied with the behaviour, try a value of 2.0.
+.Pp
+Note that the
+.Fl A
+option interacts badly with the X server's own acceleration,
+which doesn't work very well anyway. Therefore it is
+recommended to switch it off if necessary:
+.Dq xset m 1 .
.It Fl a Ar X Ns Op , Ns Ar Y
Accelerate or decelerate the mouse input.
This is a linear acceleration only.
Values less than 1.0 slow down movement, values greater than 1.0 speed it
up.
Specifying only one value sets the acceleration for both axes.
+.Pp
+You can use the
+.Fl a
+and
+.Fl A
+options at the same time to have the combined effect
+of linear and exponential acceleration.
.It Fl c
Some mice report middle button down events
as if the left and right buttons are being pressed.
@@ -758,6 +802,7 @@ option to assign the physical right button to the logical middle button:
.Sh SEE ALSO
.Xr kill 1 ,
.Xr vidcontrol 1 ,
+.Xr xset 1 ,
.Xr keyboard 4 ,
.Xr mse 4 ,
.Xr psm 4 ,
diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c
index 49f0ee7..a751774 100644
--- a/usr.sbin/moused/moused.c
+++ b/usr.sbin/moused/moused.c
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <termios.h>
#include <unistd.h>
+#include <math.h>
#define MAX_CLICKTHRESHOLD 2000 /* 2 seconds */
#define MAX_BUTTON2TIMEOUT 2000 /* 2 seconds */
@@ -99,6 +100,7 @@ __FBSDID("$FreeBSD$");
#define NoPnP 0x0010
#define VirtualScroll 0x0020
#define HVirtualScroll 0x0040
+#define ExponentialAcc 0x0080
#define ID_NONE 0
#define ID_PORT 1
@@ -394,6 +396,8 @@ static struct rodentparam {
mousemode_t mode; /* protocol information */
float accelx; /* Acceleration in the X axis */
float accely; /* Acceleration in the Y axis */
+ float expoaccel; /* Exponential acceleration */
+ float expoffset; /* Movement offset for exponential accel. */
int scrollthreshold; /* Movement distance before virtual scrolling */
} rodent = {
.flags = 0,
@@ -413,6 +417,8 @@ static struct rodentparam {
.button2timeout = DFLT_BUTTON2TIMEOUT,
.accelx = 1.0,
.accely = 1.0,
+ .expoaccel = 1.0,
+ .expoffset = 1.0,
.scrollthreshold = DFLT_SCROLLTHRESHOLD,
};
@@ -492,6 +498,7 @@ static struct drift_xy drift_previous={0,0}; /* steps in previous drift_time */
/* function prototypes */
+static void expoacc(int, int, int*, int*);
static void moused(void);
static void hup(int sig);
static void cleanup(int sig);
@@ -542,7 +549,7 @@ main(int argc, char *argv[])
for (i = 0; i < MOUSE_MAXBUTTON; ++i)
mstate[i] = &bstate[i];
- while ((c = getopt(argc, argv, "3C:DE:F:HI:PRS:T:VU:a:cdfhi:l:m:p:r:st:w:z:")) != -1)
+ while ((c = getopt(argc, argv, "3A:C:DE:F:HI:PRS:T:VU:a:cdfhi:l:m:p:r:st:w:z:")) != -1)
switch(c) {
case '3':
@@ -561,7 +568,7 @@ main(int argc, char *argv[])
case 'a':
i = sscanf(optarg, "%f,%f", &rodent.accelx, &rodent.accely);
if (i == 0) {
- warnx("invalid acceleration argument '%s'", optarg);
+ warnx("invalid linear acceleration argument '%s'", optarg);
usage();
}
@@ -570,6 +577,19 @@ main(int argc, char *argv[])
break;
+ case 'A':
+ rodent.flags |= ExponentialAcc;
+ i = sscanf(optarg, "%f,%f", &rodent.expoaccel, &rodent.expoffset);
+ if (i == 0) {
+ warnx("invalid exponential acceleration argument '%s'", optarg);
+ usage();
+ }
+
+ if (i == 1)
+ rodent.expoffset = 1.0;
+
+ break;
+
case 'c':
rodent.flags |= ChordMiddle;
break;
@@ -902,6 +922,37 @@ usbmodule(void)
return (kld_isloaded("uhub/ums") || kld_load("ums") != -1);
}
+/*
+ * Function to calculate exponential acceleration.
+ *
+ * In order to give a smoother behaviour, we record the four
+ * most recent non-zero movements and use their average value
+ * to calculate the acceleration.
+ */
+
+static void
+expoacc(int dx, int dy, int *movex, int *movey)
+{
+ static float lastlength[3] = {0.0, 0.0, 0.0};
+ float fdx, fdy, length, lbase, accel;
+
+ if (dx == 0 && dy == 0) {
+ *movex = *movey = 0;
+ return;
+ }
+ fdx = dx * rodent.accelx;
+ fdy = dy * rodent.accely;
+ length = sqrtf((fdx * fdx) + (fdy * fdy)); /* Pythagoras */
+ length = (length + lastlength[0] + lastlength[1] + lastlength[2]) / 4;
+ lbase = length / rodent.expoffset;
+ accel = powf(lbase, rodent.expoaccel) / lbase;
+ *movex = lroundf(fdx * accel);
+ *movey = lroundf(fdy * accel);
+ lastlength[2] = lastlength[1];
+ lastlength[1] = lastlength[0];
+ lastlength[0] = length; /* Insert new average, not original length! */
+}
+
static void
moused(void)
{
@@ -1161,8 +1212,14 @@ moused(void)
if (action2.flags & MOUSE_POSCHANGED) {
mouse.operation = MOUSE_MOTION_EVENT;
mouse.u.data.buttons = action2.button;
- mouse.u.data.x = action2.dx * rodent.accelx;
- mouse.u.data.y = action2.dy * rodent.accely;
+ if (rodent.flags & ExponentialAcc) {
+ expoacc(action2.dx, action2.dy,
+ &mouse.u.data.x, &mouse.u.data.y);
+ }
+ else {
+ mouse.u.data.x = action2.dx * rodent.accelx;
+ mouse.u.data.y = action2.dy * rodent.accely;
+ }
mouse.u.data.z = action2.dz;
if (debug < 2)
if (!paused)
@@ -1171,8 +1228,14 @@ moused(void)
} else {
mouse.operation = MOUSE_ACTION;
mouse.u.data.buttons = action2.button;
- mouse.u.data.x = action2.dx * rodent.accelx;
- mouse.u.data.y = action2.dy * rodent.accely;
+ if (rodent.flags & ExponentialAcc) {
+ expoacc(action2.dx, action2.dy,
+ &mouse.u.data.x, &mouse.u.data.y);
+ }
+ else {
+ mouse.u.data.x = action2.dx * rodent.accelx;
+ mouse.u.data.y = action2.dy * rodent.accely;
+ }
mouse.u.data.z = action2.dz;
if (debug < 2)
if (!paused)
OpenPOWER on IntegriCloud