Files gpm-orig/src/gpm.exe and gpm/src/gpm.exe differ
diff -urN gpm-orig/src/gpn.c gpm/src/gpn.c
--- gpm-orig/src/gpn.c	2003-11-04 15:56:50.000000000 -0500
+++ gpm/src/gpn.c	2003-11-04 16:15:02.000000000 -0500
@@ -165,8 +165,7 @@
                      break;
          case 's':   opt->sample = atoi(optarg);
                      break;
-         case 'S':   if (optarg) opt_special = optarg;
-                     else opt_special="";
+         case 'S':   opt_special = optarg ? optarg : "";
                      break;
          case 't':   mouse->type = find_protocol_by_name(optarg);
                      if (!mouse->type)
diff -urN gpm-orig/src/headers/gpmInt.h gpm/src/headers/gpmInt.h
diff -urN gpm-orig/src/mice.c gpm/src/mice.c
--- gpm-orig/src/mice.c	2003-11-04 15:56:50.000000000 -0500
+++ gpm/src/mice.c	2003-11-05 18:23:30.000000000 -0500
@@ -78,6 +78,7 @@
 
 struct micetab *micelist;
 struct repeater repeater;
+
 /*
  * Note that mman must be the first, and ms the second (I use this info
  * in mouse-test.c, as a quick and dirty hack
@@ -382,7 +383,7 @@
          while (*s && isspace(*s)) s++; /* skip spaces */
          if (!strncasecmp(name, s, len) && 
              (isspace(*(s + len)) || !isprint(*(s + len)))) {
-            break;/*found*/
+            break; /*found*/
          }
       }
    	if (s) break; /* found a synonym */
@@ -390,10 +391,9 @@
    return strlen(type->name) ? type : NULL;
 }
 
-
-/* DESCR:   allocate a new mouse and to the list of mice. initialization follows later */
-/* RETURN:  new mouse structure */
-/* COMMENT: does error handling and exiting itself */
+/* --------------------------------------------------------- */
+/* Allocates a new mouse and adds it to the list of mice. 
+   initialization follows later */
 struct micetab *add_mouse(void)
 {
    struct micetab *mouse;
@@ -407,7 +407,9 @@
    mouse->dev.fd = -1;
    mouse->dev.timeout = -1;
 
-   mouse->options.sequence = NULL;
+   mouse->type = find_protocol_by_name(DEF_TYPE);
+
+   mouse->options.sequence = transform_sequence(DEF_SEQENCE);
    mouse->options.sample = DEF_SAMPLE;
    mouse->options.delta = DEF_DELTA;
    mouse->options.accel = DEF_ACCEL;
@@ -424,23 +426,7 @@
    return mouse;
 }
 
-void delete_mouse(struct micetab *mouse)
-{
-   struct micetab *m, *prev = NULL;
-
-   for (m = micelist; m; prev = m, m = m->next) {
-      if (m == mouse) {
-         if (!prev)
-            micelist = m->next;
-         else
-            prev->next = m->next;
-         free(mouse);
-         break;
-      }
-   }
-}
-
-int init_mouse(struct micetab *mouse)
+static int open_mouse(struct mousetab *mouse)
 {
    if (!strcmp(mouse->device, "-"))
       mouse->dev.fd = 0; /* use stdin */
@@ -451,6 +437,23 @@
    /* and then reset the flag */
    fcntl(mouse->dev.fd, F_SETFL, fcntl(mouse->dev.fd, F_GETFL) & ~O_NDELAY);
 
+   return 0;
+}
+
+int setup_mouse(struct micetab *mouse, int mouse_no)
+{
+   if (!mouse->device) {
+      gpm_report(GPM_PR_ERR, "No device specified for mouse #%d", mouse_no);
+      return -1;
+   }
+
+   mouse->dev.packetlen = mouse->type->packetlen;
+   mouse->dev.volatile_proto = mouse->type->volatile_proto;
+   mouse->dev.howmany = mouse->type->howmany;
+   memcpy(mouse->dev.proto, mouse->type->proto, sizeof(mouse->type->proto));
+
+   mouse->options.absolute = mouse->type->absolute;
+
    if (mouse->type->setup) {
       if (mouse->type->setup(&mouse->dev, &mouse->options, mouse->type)) {
          gpm_report(GPM_PR_ERR, GPM_MESS_MOUSE_INIT);
@@ -458,27 +461,70 @@
          return -1;
       }
    }
+}
+
+int init_mouse(struct micetab *mouse)
+{
+   if (!strcmp(mouse->device, "-"))
+      mouse->dev.fd = 0; /* use stdin */
+   else if ((mouse->dev.fd = open(mouse->device, O_RDWR | O_NDELAY)) < 0) {
+      gpm_report(GPM_PR_ERR, GPM_MESS_OPEN, mouse->device);
+      return -1;
+   }
+   /* and then reset the flag */
+   cntl(mouse->dev.fd, F_SETFL, fcntl(mouse->dev.fd, F_GETFL) & ~O_NDELAY);
+
+   if ((mouse->dev.fd = open_mouse(mouse->device)) < 0) {
+
+      goto init_fail;
+   }
+
    /* init the device */
-   if (mouse->type->init) {
-      if (mouse->type->init(&mouse->dev, &mouse->options, mouse->type)) {
-         gpm_report(GPM_PR_ERR, GPM_MESS_MOUSE_INIT);
-         cleanup_mouse(mouse);
+   if (mouse->type->init && 
+         mouse->type->init(&mouse->dev, &mouse->options, mouse->type)) {
+      gpm_report(GPM_PR_ERR, GPM_MESS_MOUSE_INIT);
+   cleanup_mouse(mouse);
          return -1;
       }
    }
    return 0;
+
+
+   
+}
+
+void delete_mouse(struct micetab *mouse)
+{
+   struct micetab *m, *prev = NULL;
+
+   for (m = micelist; m; prev = m, m = m->next) {
+      if (m == mouse) {
+         if (!prev)
+            micelist = m->next;
+         else
+            prev->next = m->next;
+         free(mouse);
+         break;
+      }
+   }
 }
 
 void cleanup_mouse(struct micetab *mouse)
 {
    if (mouse->type->cleanup)
       mouse->type->cleanup(&mouse->dev, &mouse->options, mouse->type);
+   if (mouse->dev.fd > 0)
+      close(mouse->dev.fd);
+}
+
+void destroy_mouse(struct micetab *mouse)
+{
+   if (mouse->type->destroy)
+      mouse->type->destroy(&mouse->dev, &mouse->options, mouse->type);
    if (mouse->dev.private) {
       free(mouse->dev.private);
       mouse->dev.private = NULL;
    }
-   if (mouse->dev.fd > 0)
-      close(mouse->dev.fd);
 }
 
 struct micetab *find_mouse_by_device(char *device)
@@ -545,3 +591,27 @@
          gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, GPM_NODE_FIFO);
    }
 }
+
+char *init_button_sequence(char *in_seq)
+{
+	int i;
+   static struct {
+      char *in;
+      char *out;
+   } seq[] = {
+      { "123", "01234567" },
+      { "132", "02134657" },
+      { "213", "01452367" }, /* warning: these must be readable as integers... */
+      { "231", "02461357" },
+      { "312", "04152637" },
+      { "321", "04261537" },
+      { NULL, NULL }
+   };
+
+	for (i = 0; seq[i].in; i++)
+      if (!strcmp(seq[i].in, arg))
+         return seq[i].out;
+
+   return NULL;
+}
+
