summaryrefslogtreecommitdiffstats
path: root/usr.sbin/moused
diff options
context:
space:
mode:
authorphilip <philip@FreeBSD.org>2007-06-17 20:27:54 +0000
committerphilip <philip@FreeBSD.org>2007-06-17 20:27:54 +0000
commitc7a9176e2cb880ef422f7d6d68815b59b2de4537 (patch)
tree7e0f3ed59e309c6a54707c19a9d780435e37beb8 /usr.sbin/moused
parentca1ca54cb0ab727e0b19a308a6ae21e0fbe660d5 (diff)
downloadFreeBSD-src-c7a9176e2cb880ef422f7d6d68815b59b2de4537.zip
FreeBSD-src-c7a9176e2cb880ef422f7d6d68815b59b2de4537.tar.gz
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
Diffstat (limited to 'usr.sbin/moused')
-rw-r--r--usr.sbin/moused/moused.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c
index a751774..ea5062e 100644
--- a/usr.sbin/moused/moused.c
+++ b/usr.sbin/moused/moused.c
@@ -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);
@@ -923,7 +928,33 @@ usbmodule(void)
}
/*
+ * 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)
OpenPOWER on IntegriCloud