diff options
author | philip <philip@FreeBSD.org> | 2007-03-11 20:02:26 +0000 |
---|---|---|
committer | philip <philip@FreeBSD.org> | 2007-03-11 20:02:26 +0000 |
commit | 50b3f4c302935f38be277cc4f2b41c73be99018b (patch) | |
tree | 4fc03a1ea0f37e2a088a91780a4803632ce1d5e6 /usr.sbin/moused | |
parent | ab3553dfb44e8eaa4aa684af4ef0c04ff425452c (diff) | |
download | FreeBSD-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/moused')
-rw-r--r-- | usr.sbin/moused/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/moused/moused.8 | 45 | ||||
-rw-r--r-- | usr.sbin/moused/moused.c | 75 |
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) |