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
This commit is contained in:
parent
1267d00111
commit
86b3ea3634
@ -3,8 +3,8 @@
|
||||
PROG= moused
|
||||
MAN= moused.8
|
||||
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
DPADD= ${LIBUTIL} ${LIBM}
|
||||
LDADD= -lutil -lm
|
||||
|
||||
#BINMODE=4555
|
||||
#PRECIOUSPROG=
|
||||
|
@ -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 ,
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user