The repeaters have the bug that sometimes dx and dy are bigger than
the repeater protocol can represent. I posted a fix for this on the
gpm mailing list that I expect will be in the next release of gpm.
Since Debian has some repeaters that aren't in the standard gpm, I
am sending a patch that applies to the Debian version. This applies
on top of the patch I sent in bug 113535.
Andrew
--- mice.c.R_ms3 Tue Sep 25 16:00:06 2001
+++ mice.c Tue Sep 25 17:39:45 2001
@@ -210,6 +210,21 @@ static int option_modem_lines(int fd, in
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
@@ -387,6 +402,7 @@ static int M_ms3(Gpm_Event *state, unsi
static int R_ms3(Gpm_Event *state, int fd)
{
char buf[4] = {0, 0, 0, 0};
+ int dx, dy;
buf[0] |= 0x40;
@@ -394,11 +410,13 @@ static int R_ms3(Gpm_Event *state, int f
buf[3] |= ((state->buttons & GPM_B_MIDDLE) ? 0x10 : 0);
buf[0] |= ((state->buttons & GPM_B_RIGHT) ? 0x10 : 0);
- buf[1] = state->dx & ~0xC0;
- buf[0] |= (state->dx & 0xC0) >> 6;
-
- buf[2] = state->dy & ~0xC0;
- buf[0] |= (state->dy & 0xC0) >> 4;
+ dx = limit_delta(state->dx, -128, 127);
+ buf[1] = dx & ~0xC0;
+ buf[0] |= (dx & 0xC0) >> 6;
+
+ dy = limit_delta(state->dy, -128, 127);
+ buf[2] = dy & ~0xC0;
+ buf[0] |= (dy & 0xC0) >> 4;
if (state->wdy > 0)
buf[3] |= 0x0f;
@@ -453,8 +471,8 @@ static int R_sun(Gpm_Event *state, int f
signed char buffer[3];
buffer[0]= (state->buttons ^ 0x07) | 0x80;
- buffer[1]= state->dx;
- buffer[2]= -(state->dy);
+ buffer[1]= limit_delta(state->dx, -128, 127);
+ buffer[2]= -(limit_delta(state->dy, -128, 127));
return write(fd,buffer,3);
}
@@ -472,11 +490,14 @@ static int M_msc(Gpm_Event *state, unsi
static int R_msc(Gpm_Event *state, int fd)
{
signed char buffer[5];
+ int dx, dy;
/* sluggish... */
buffer[0]=(state->buttons ^ 0x07) | 0x80;
- buffer[3] = state->dx - (buffer[1] = state->dx/2); /* Markus */
- buffer[4] = -state->dy - (buffer[2] = -state->dy/2);
+ dx = limit_delta(state->dx, -256, 254);
+ buffer[3] = dx - (buffer[1] = dx/2); /* Markus */
+ dy = limit_delta(state->dy, -256, 254);
+ buffer[4] = -dy - (buffer[2] = -dy/2);
return write(fd,buffer,5);
}