Package: gpm
Version: 1.20.4-6
Severity: normal

Dear GPM maintainers,
gpm does no handle "clickpad" which are now quite common because gpm only see a
single button, so you can select, but not paste.
<http://www.synaptics.com/solutions/products/clickpad>

I wrote a preliminary patch with allow gpm to work with the clickpad
on my laptop.

It also fix a bug that make the evdev drivers unusable on 64bit platforms.

Cheers,
-- 
Bill. <[email protected]>

Imagine a large red swirl here. 
Index: gpm-1.20.4/src/mice.c
===================================================================
--- gpm-1.20.4.orig/src/mice.c  2013-08-04 15:33:23.092359180 +0200
+++ gpm-1.20.4/src/mice.c       2013-08-04 15:47:39.765153053 +0200
@@ -213,7 +213,7 @@
 /*========================================================================*/
 
 #define REALPOS_MAX 16383 /*  min 0 max=16383, but due to change.  */
-int realposx=-1, realposy=-1;
+int realposx=-1, realposy=-1, realpress=0;
 
 /*========================================================================*/
 /* 
@@ -239,22 +239,86 @@
 #ifdef HAVE_LINUX_INPUT_H
 static int M_evdev (Gpm_Event * state, unsigned char *data)
 {
-   struct input_event thisevent;
-   (void) memcpy (&thisevent, data, sizeof (struct input_event));
-   if (thisevent.type == EV_REL) {
-      if (thisevent.code == REL_X)
-         state->dx = (signed char) thisevent.value;
-      else if (thisevent.code == REL_Y)
-         state->dy = (signed char) thisevent.value;
-   } else if (thisevent.type == EV_KEY) {
+  struct input_event thisevent;
+  static int slot, lastbtn;
+  static struct tracker
+  {
+    int id, x, y;
+  } tr[2], oldtr[2];
+  (void) memcpy (&thisevent, data, sizeof (struct input_event));
+  state->dx = 0;
+  state->dy = 0;
+  switch (thisevent.type)
+  {
+  case SYN_REPORT:
+    {
+      int s;
+      for(s=0; s<=1; s++)
+        if (tr[s].id==-1)
+          tr[s].y=5000;
+      for(s=0; s<=1; s++)
+        if (tr[s].y<4000)
+        {
+          state->dx = (signed char) (tr[s].x-oldtr[s].x)/4;
+          state->dy = (signed char) (tr[s].y-oldtr[s].y)/4;
+          break;
+        }
+      oldtr[0] = tr[0]; oldtr[1] = tr[1];
+    }
+    break;
+  case EV_ABS:
+    {
+      int val = (int) thisevent.value;
+      switch (thisevent.code)
+      {
+      case ABS_MT_SLOT:
+        slot = val;
+        break;
+      case ABS_MT_TRACKING_ID:
+        tr[slot].id = val;
+        break;
+      case ABS_MT_POSITION_X:
+        tr[slot].x = val;
+        break;
+      case ABS_MT_POSITION_Y:
+        tr[slot].y = val;
+        break;
+      }
+    }
+    break;
+  case EV_KEY:
+    {
+      int val = (int) thisevent.value;
       switch(thisevent.code) {
-         case BTN_LEFT:    state->buttons ^= GPM_B_LEFT;    break;
-         case BTN_MIDDLE:  state->buttons ^= GPM_B_MIDDLE;  break;
-         case BTN_RIGHT:   state->buttons ^= GPM_B_RIGHT;   break;
-         case BTN_SIDE:    state->buttons ^= GPM_B_MIDDLE;  break;
-      }   
-   }
-   return 0;
+      case BTN_LEFT:
+        {
+          if (val)
+          {
+            int s, btn;
+            if (tr[0].id>=0 && tr[0].y>4000)
+              s = 0;
+            else if (tr[1].id>=0 && tr[1].y>4000)
+              s = 1;
+            else return 0;
+            if (tr[s].x < 2500)
+              btn = GPM_B_LEFT;
+            else if (tr[s].x < 4500)
+              btn = GPM_B_MIDDLE;
+            else
+              btn = GPM_B_RIGHT;
+            state->buttons |= btn;
+            lastbtn = btn;
+          } else
+            state->buttons &= ~lastbtn;
+        }
+        break;
+      case BTN_MIDDLE:  state->buttons ^= GPM_B_MIDDLE;  break;
+      case BTN_RIGHT:   state->buttons ^= GPM_B_RIGHT;   break;
+      case BTN_SIDE:    state->buttons ^= GPM_B_MIDDLE;  break;
+      }
+    }
+  }
+  return 0;
 }
 #endif /* HAVE_LINUX_INPUT_H */
 
@@ -2479,7 +2543,7 @@
 #ifdef HAVE_LINUX_INPUT_H
    {"evdev", "Linux Event Device",
             "", M_evdev, I_empty, STD_FLG,
-                        {0x00, 0x00, 0x00, 0x00} , 16, 16, 0, 0, NULL},
+                        {0x00, 0x00, 0x00, 0x00} , sizeof(struct input_event), 
sizeof(struct input_event), 0, 0, NULL},
 #endif /* HAVE_LINUX_INPUT_H */
    {"exps2",  "IntelliMouse Explorer (ps2) - 3 buttons (wheel is repeated).",
             "ExplorerPS/2", M_imps2, I_ps2, STD_FLG,

Reply via email to