Fix a (very) longstanding bug in moused(8) affecting high-resolution rodents
when linear acceleration (-a) was enabled with a <1 value to slow them down. Previously, rounding errors would eat small movements so the mouse had to be moved a certain distance to get any movement at all. We now calculate the rounding errors and take them into account when reporting movement. PR: bin/113749 Submitted by: Oliver Fromme <olli -at- secnetix.de> MFC after: 3 days
This commit is contained in:
parent
75298de2a0
commit
d933824786
@ -398,6 +398,8 @@ static struct rodentparam {
|
||||
float accely; /* Acceleration in the Y axis */
|
||||
float expoaccel; /* Exponential acceleration */
|
||||
float expoffset; /* Movement offset for exponential accel. */
|
||||
float remainx; /* Remainder on X and Y axis, respectively... */
|
||||
float remainy; /* ... to compensate for rounding errors. */
|
||||
int scrollthreshold; /* Movement distance before virtual scrolling */
|
||||
} rodent = {
|
||||
.flags = 0,
|
||||
@ -419,6 +421,8 @@ static struct rodentparam {
|
||||
.accely = 1.0,
|
||||
.expoaccel = 1.0,
|
||||
.expoffset = 1.0,
|
||||
.remainx = 0.0,
|
||||
.remainy = 0.0,
|
||||
.scrollthreshold = DFLT_SCROLLTHRESHOLD,
|
||||
};
|
||||
|
||||
@ -498,6 +502,7 @@ static struct drift_xy drift_previous={0,0}; /* steps in previous drift_time */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
static void linacc(int, int, int*, int*);
|
||||
static void expoacc(int, int, int*, int*);
|
||||
static void moused(void);
|
||||
static void hup(int sig);
|
||||
@ -922,8 +927,34 @@ usbmodule(void)
|
||||
return (kld_isloaded("uhub/ums") || kld_load("ums") != -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to calculate linear acceleration.
|
||||
*
|
||||
* If there are any rounding errors, the remainder
|
||||
* is stored in the remainx and remainy variables
|
||||
* and taken into account upon the next movement.
|
||||
*/
|
||||
|
||||
static void
|
||||
linacc(int dx, int dy, int *movex, int *movey)
|
||||
{
|
||||
float fdx, fdy;
|
||||
|
||||
if (dx == 0 && dy == 0) {
|
||||
*movex = *movey = 0;
|
||||
return;
|
||||
}
|
||||
fdx = dx * rodent.accelx + rodent.remainx;
|
||||
fdy = dy * rodent.accely + rodent.remainy;
|
||||
*movex = lround(fdx);
|
||||
*movey = lround(fdy);
|
||||
rodent.remainx = fdx - *movex;
|
||||
rodent.remainy = fdy - *movey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to calculate exponential acceleration.
|
||||
* (Also includes linear acceleration if enabled.)
|
||||
*
|
||||
* In order to give a smoother behaviour, we record the four
|
||||
* most recent non-zero movements and use their average value
|
||||
@ -946,8 +977,12 @@ expoacc(int dx, int dy, int *movex, int *movey)
|
||||
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);
|
||||
fdx = fdx * accel + rodent.remainx;
|
||||
fdy = fdy * accel + rodent.remainy;
|
||||
*movex = lroundf(fdx);
|
||||
*movey = lroundf(fdy);
|
||||
rodent.remainx = fdx - *movex;
|
||||
rodent.remainy = fdy - *movey;
|
||||
lastlength[2] = lastlength[1];
|
||||
lastlength[1] = lastlength[0];
|
||||
lastlength[0] = length; /* Insert new average, not original length! */
|
||||
@ -1217,8 +1252,8 @@ moused(void)
|
||||
&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;
|
||||
linacc(action2.dx, action2.dy,
|
||||
&mouse.u.data.x, &mouse.u.data.y);
|
||||
}
|
||||
mouse.u.data.z = action2.dz;
|
||||
if (debug < 2)
|
||||
@ -1233,8 +1268,8 @@ moused(void)
|
||||
&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;
|
||||
linacc(action2.dx, action2.dy,
|
||||
&mouse.u.data.x, &mouse.u.data.y);
|
||||
}
|
||||
mouse.u.data.z = action2.dz;
|
||||
if (debug < 2)
|
||||
|
Loading…
Reference in New Issue
Block a user