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
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170895
@ -398,6 +398,8 @@ static struct rodentparam {
|
|||||||
float accely; /* Acceleration in the Y axis */
|
float accely; /* Acceleration in the Y axis */
|
||||||
float expoaccel; /* Exponential acceleration */
|
float expoaccel; /* Exponential acceleration */
|
||||||
float expoffset; /* Movement offset for exponential accel. */
|
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 */
|
int scrollthreshold; /* Movement distance before virtual scrolling */
|
||||||
} rodent = {
|
} rodent = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
@ -419,6 +421,8 @@ static struct rodentparam {
|
|||||||
.accely = 1.0,
|
.accely = 1.0,
|
||||||
.expoaccel = 1.0,
|
.expoaccel = 1.0,
|
||||||
.expoffset = 1.0,
|
.expoffset = 1.0,
|
||||||
|
.remainx = 0.0,
|
||||||
|
.remainy = 0.0,
|
||||||
.scrollthreshold = DFLT_SCROLLTHRESHOLD,
|
.scrollthreshold = DFLT_SCROLLTHRESHOLD,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -498,6 +502,7 @@ static struct drift_xy drift_previous={0,0}; /* steps in previous drift_time */
|
|||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
|
|
||||||
|
static void linacc(int, int, int*, int*);
|
||||||
static void expoacc(int, int, int*, int*);
|
static void expoacc(int, int, int*, int*);
|
||||||
static void moused(void);
|
static void moused(void);
|
||||||
static void hup(int sig);
|
static void hup(int sig);
|
||||||
@ -922,8 +927,34 @@ usbmodule(void)
|
|||||||
return (kld_isloaded("uhub/ums") || kld_load("ums") != -1);
|
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.
|
* Function to calculate exponential acceleration.
|
||||||
|
* (Also includes linear acceleration if enabled.)
|
||||||
*
|
*
|
||||||
* In order to give a smoother behaviour, we record the four
|
* In order to give a smoother behaviour, we record the four
|
||||||
* most recent non-zero movements and use their average value
|
* 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;
|
length = (length + lastlength[0] + lastlength[1] + lastlength[2]) / 4;
|
||||||
lbase = length / rodent.expoffset;
|
lbase = length / rodent.expoffset;
|
||||||
accel = powf(lbase, rodent.expoaccel) / lbase;
|
accel = powf(lbase, rodent.expoaccel) / lbase;
|
||||||
*movex = lroundf(fdx * accel);
|
fdx = fdx * accel + rodent.remainx;
|
||||||
*movey = lroundf(fdy * accel);
|
fdy = fdy * accel + rodent.remainy;
|
||||||
|
*movex = lroundf(fdx);
|
||||||
|
*movey = lroundf(fdy);
|
||||||
|
rodent.remainx = fdx - *movex;
|
||||||
|
rodent.remainy = fdy - *movey;
|
||||||
lastlength[2] = lastlength[1];
|
lastlength[2] = lastlength[1];
|
||||||
lastlength[1] = lastlength[0];
|
lastlength[1] = lastlength[0];
|
||||||
lastlength[0] = length; /* Insert new average, not original length! */
|
lastlength[0] = length; /* Insert new average, not original length! */
|
||||||
@ -1217,8 +1252,8 @@ moused(void)
|
|||||||
&mouse.u.data.x, &mouse.u.data.y);
|
&mouse.u.data.x, &mouse.u.data.y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mouse.u.data.x = action2.dx * rodent.accelx;
|
linacc(action2.dx, action2.dy,
|
||||||
mouse.u.data.y = action2.dy * rodent.accely;
|
&mouse.u.data.x, &mouse.u.data.y);
|
||||||
}
|
}
|
||||||
mouse.u.data.z = action2.dz;
|
mouse.u.data.z = action2.dz;
|
||||||
if (debug < 2)
|
if (debug < 2)
|
||||||
@ -1233,8 +1268,8 @@ moused(void)
|
|||||||
&mouse.u.data.x, &mouse.u.data.y);
|
&mouse.u.data.x, &mouse.u.data.y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mouse.u.data.x = action2.dx * rodent.accelx;
|
linacc(action2.dx, action2.dy,
|
||||||
mouse.u.data.y = action2.dy * rodent.accely;
|
&mouse.u.data.x, &mouse.u.data.y);
|
||||||
}
|
}
|
||||||
mouse.u.data.z = action2.dz;
|
mouse.u.data.z = action2.dz;
|
||||||
if (debug < 2)
|
if (debug < 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user