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,