diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/gpm.c gpm-1.19.5/src/gpm.c
--- gpm-1.19.5.orig/src/gpm.c	Thu Oct  4 23:33:48 2001
+++ gpm-1.19.5/src/gpm.c	Thu Oct  4 23:33:37 2001
@@ -446,6 +446,7 @@
   else
     {
     event->dx=event->dy=0;
+    event->wdx=event->wdy=0;
 
     nEvent.modifiers = 0; /* some mice set them */
     FD_ZERO(&fdSet); FD_SET(fd,&fdSet); i=0;
@@ -488,6 +489,10 @@
         event->dx = (nEvent.x) - (event->x);
         event->dy = (nEvent.y) - (event->y);
 	}
+
+      /* propagate wheel */
+      event->wdx += nEvent.wdx;
+      event->wdy += nEvent.wdy;
 
       select(fd+1,&fdSet,(fd_set *)NULL,(fd_set *)NULL,&timeout/* zero */);
       }
diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/headers/gpm.h gpm-1.19.5/src/headers/gpm.h
--- gpm-1.19.5.orig/src/headers/gpm.h	Wed Sep 12 17:07:34 2001
+++ gpm-1.19.5/src/headers/gpm.h	Thu Oct  4 23:33:37 2001
@@ -115,6 +115,7 @@
   unsigned char buttons, modifiers;  /* try to be a multiple of 4 */
   unsigned short vc;
   short dx, dy, x, y;
+  short wdx, wdy;
   enum Gpm_Etype type;
   int clicks;
   enum Gpm_Margin margin;
diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/mice.c gpm-1.19.5/src/mice.c
--- gpm-1.19.5.orig/src/mice.c	Thu Oct  4 23:33:48 2001
+++ gpm-1.19.5/src/mice.c	Thu Oct  4 23:33:37 2001
@@ -359,16 +359,49 @@
 /* m$ 'Intellimouse' (steveb 20/7/97) */
 static int M_ms3(Gpm_Event *state,  unsigned char *data)
 {
+  state->wdx = state->wdy = 0;
+
   state->buttons= ((data[0] & 0x20) >> 3)	/* left */
 		| ((data[3] & 0x10) >> 3)	/* middle */
 		| ((data[0] & 0x10) >> 4);	/* right */
   state->dx=      (signed char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
   state->dy=      (signed char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
-  /* wheel (dz??) is (data[3] & 0x0f) */
+
+  switch (data[3] & 0x0f) {
+    case 0x0e: state->wdx = +1; break;
+    case 0x02: state->wdx = -1; break;
+    case 0x0f: state->wdy = +1; break;
+    case 0x01: state->wdy = -1; break;
+  }
 
   return 0;
 }
 
+static int R_ms3(Gpm_Event *state, int fd)
+{
+  char buf[4] = {0, 0, 0, 0};
+
+  buf[0] |= 0x40;
+
+  buf[0] |= ((state->buttons & GPM_B_LEFT) ? 0x20 : 0);
+  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;
+
+  if (state->wdy > 0)
+    buf[3] |= 0x0f;
+  else if (state->wdy < 0)
+    buf[3] |= 0x01;
+
+  return write(fd,buf,4);
+}
+
+
 /* M_brw is a variant of m$ 'Intellimouse' the middle button is different */
 static int M_brw(Gpm_Event *state,  unsigned char *data)
 {
@@ -499,6 +532,39 @@
   return 0;
 }
 
+static int M_imps2(Gpm_Event *state,  unsigned char *data)
+{
+  static int tap_active=0;     // there exist glidepoint ps2 mice
+  state->wdx = state->wdy = 0; // Clear them..
+
+  state->dx = state->dy = state->wdx = state->wdy = 0;
+
+  state->buttons= ((data[0] & 1) << 2) // left
+    | ((data[0] & 6) >> 1); // middle and right
+
+  if (data[0]==0 && opt_glidepoint_tap) // by default this is false
+    state->buttons = tap_active = opt_glidepoint_tap;
+  else if (tap_active) {
+    if (data[0]==8)
+      state->buttons = tap_active = 0;
+    else state->buttons = tap_active;
+  }
+
+  // Standard movement..
+  state->dx = (data[0] & 0x10) ? data[1] - 256 : data[1];
+  state->dy = (data[0] & 0x20) ? -(data[2] - 256) : -data[2];
+
+  // The wheels..
+  switch (data[3] & 0x0f) {
+    case 0x0e: state->wdx = +1; break;
+    case 0x02: state->wdx = -1; break;
+    case 0x0f: state->wdy = +1; break;
+    case 0x01: state->wdy = -1; break;
+  }
+
+  return 0;
+}
+
 static int M_netmouse(Gpm_Event *state,  unsigned char *data)
 {
   /* Avoid this beasts if you can.  They connect to normal PS/2 port,
@@ -2096,14 +2162,14 @@
            "", M_bare, I_pnp, CS7 | STD_FLG,
                                 {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0},
   {"imps2","Microsoft Intellimouse (ps2) - autodetect 2/3 buttons,wheel unused",
-           "", M_ps2, I_imps2, STD_FLG,
+           "", M_imps2, I_imps2, STD_FLG,
                                 {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0},
   {"exps2",   "IntelliMouse Explorer (ps2) - 3 buttons, wheel unused",
            "ExplorerPS/2", M_ps2, I_exps2, STD_FLG,
                                 {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0},
   {"ms3", "Microsoft Intellimouse (serial) - 3 buttons, wheel unused",
            "", M_ms3, I_pnp, CS7 | STD_FLG,
-                                {0xc0, 0x40, 0xc0, 0x00}, 4, 1, 0, 0, 0},
+                                {0xc0, 0x40, 0xc0, 0x00}, 4, 1, 0, 0, R_ms3},
   {"netmouse",  "Genius NetMouse (ps2) - 2 buttons and 2 buttons 'up'/'down'.", 
            "", M_netmouse, I_netmouse, CS7 | STD_FLG,
                                 {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0},
