[Gpm] repeat and accel

Andrew Pimlott andrew@pimlott.ne.mediaone.net
Tue, 25 Sep 2001 17:15:56 -0400


On Mon, Mar 19, 2001 at 05:43:48PM +0100, Alessandro Rubini wrote:
> Who is going to fix it?

I dropped the ball on this one because I am lame, but I'm officially tired
of running a patched gpm, so it's time to submit what I did.  Having a
maintainer is some incentive. :-)

The problem, to recall, is that sometimes the repeater functions are asked
to repeat more bits of dx and dy motion than the protocol can represent.
The result is erratic mouse movement (in the application using /dev/gpmdata)
when you move the mouse sufficiently fast.  The discussion on this was in
February or March (in case there is no archive, I can send it).

I noticed that this is not such a problem with stock gpm, because the only
repeaters are msc and summa.  summa is presumably only meant for people with
tablets, and msc seems (?!) to have 9 bits of delta, which is enough to hide
the problem in most cases.  However, in Debian, sun and ms3 are both
repeated and use 8 bits of delta, which shows the problem better.

There are two issues involved: 1) different protocols support a different
number of bits of dx; and 2) the "-d accel" feature can cause the repeated
dx to be bigger than the original dx.  One proposal was to ignore
acceleration when repeating.  This is consistent with ignoring "-r
responsiveness" (aka opt_scale), which is done currently.  However, this
would not solve issue 1; also, since the gpm default value for acceleration
is 2, pretty much everyone who uses the repeater would notice his mouse slow
down in applications that use the repeater.  So, I decided that the best
thing to do would be to limit the values repeated to the range supported by
the protocol, and leave the acceleration alone.

Patch against gpm-1.19.5 is below.  Feel free to change for style, but I
would like to keep the capping factored out so I can apply it to the
repeaters in Debian gpm.  I don't really know what's up with msc, but I went
by Alessandro's comment in the last discussion.

Andrew

--- mice.c.orig Tue Sep 25 17:48:30 2001
+++ mice.c      Tue Sep 25 17:48:32 2001
@@ -203,6 +203,21 @@
 int realposx=-1, realposy=-1;
 
 /*========================================================================*/
+/* 
+ * When repeating, it is important not to try to repeat more bits of dx and
+ * dy than the protocol can handle.  Otherwise, you may end up repeating the
+ * low bits of a large value, which causes erratic motion.
+ */
+
+static int limit_delta(int delta, int min, int max)
+{
+    return
+        delta > max ? max :
+        delta < min ? min
+                    : delta;
+}
+
+/*========================================================================*/
 /*
  * Ok, here we are: first, provide the functions; initialization is later.
  * The return value is the number of unprocessed bytes
@@ -423,10 +438,13 @@
 static int R_msc(Gpm_Event *state, int fd)
 {
   signed char buffer[5];
+  int dx, dy;
 
   /* sluggish... */
   buffer[0]=(state->buttons ^ 0x07) | 0x80;
+  dx = limit_delta(state->dx, -256, 254);
   buffer[3] =  state->dx - (buffer[1] = state->dx/2); /* Markus */
+  dy = limit_delta(state->dy, -256, 254);
   buffer[4] = -state->dy - (buffer[2] = -state->dy/2);
   return write(fd,buffer,5);