public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC/PATCH] Touchpads in absolute mode (synaptics) and mousedev
@ 2003-07-01  8:03 Dmitry Torokhov
  2003-07-01  9:40 ` Neil Brown
  2003-07-01 12:02 ` Felipe Alfaro Solana
  0 siblings, 2 replies; 8+ messages in thread
From: Dmitry Torokhov @ 2003-07-01  8:03 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-usb-devel

Hi,

I was trying to teach mousedev to bind to new synaptics driver. This 
may be useful for gpm and other programs that don't have native event
processing module written yet. Unfortunately absolute to relative 
conversion in mousedev only suits for tablets (digitizers) and not for
touchpads because:

- touchpads are not precise; when I take my finger off touchpad and then
  touch it again somewhere else I do not expect my cursor jump anywhere,
  I only expect cursor to move when I move my finger while pressing 
  touchpad.
- synaptics has Y axis reversed from what mousedev expects.

I tried to modify mousedev to account for differences between touchpads 
in absolute mode and digitizers in absolute mode but all my solutions 
required ugly flags - brrr... So what if we:

1. Modify mousedev so if an input device announces that it generates both
   relative and absolute events mousedev will discard all absolute axis 
   events and will rely on device supplied relative events.
2. Add absolute->relative conversion code to touchpad drivers themselves
   as drivers should know the best how to do that. If they turn out to be
   similar across different touchpads then the common module could be 
   made.

What you think?

Dmitry

diff -urN --exclude-from=/usr/src/exclude 2.5.72-vanilla/drivers/input/mouse/synaptics.c linux-2.5.72/drivers/input/mouse/synaptics.c
--- 2.5.72-vanilla/drivers/input/mouse/synaptics.c	2003-06-19 20:23:32.000000000 -0500
+++ linux-2.5.72/drivers/input/mouse/synaptics.c	2003-07-01 02:54:34.000000000 -0500
@@ -244,9 +244,9 @@
 	set_bit(BTN_FORWARD, psmouse->dev.keybit);
 	set_bit(BTN_BACK, psmouse->dev.keybit);
 
-	clear_bit(EV_REL, psmouse->dev.evbit);
-	clear_bit(REL_X, psmouse->dev.relbit);
-	clear_bit(REL_Y, psmouse->dev.relbit);
+	set_bit(EV_REL, psmouse->dev.evbit);
+	set_bit(REL_X, psmouse->dev.relbit);
+	set_bit(REL_Y, psmouse->dev.relbit);
 
 	return 0;
 
@@ -302,11 +302,14 @@
 /*
  *  called for each full received packet from the touchpad
  */
+#define fx(i)	priv->old_x[(priv->pkt_count - (i)) & 03]
+#define fy(i)	priv->old_y[(priv->pkt_count - (i)) & 03]
 static void synaptics_process_packet(struct psmouse *psmouse)
 {
 	struct input_dev *dev = &psmouse->dev;
 	struct synaptics_data *priv = psmouse->private;
 	struct synaptics_hw_state hw;
+	int dx, dy;
 
 	synaptics_parse_hw_state(priv, &hw);
 
@@ -332,6 +335,21 @@
 		}
 		if (!w_ok)
 			hw.w = 5;
+
+		if (hw.z > SYN_REL_PRESSURE_THRESHOLD) {
+			fx(0) = hw.x;
+			fy(0) = hw.y;
+			if (priv->pkt_count >= 2) {
+				dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / SYN_REL_DECEL_FACTOR;
+				dy = ((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / SYN_REL_DECEL_FACTOR;
+			      	
+				input_report_rel(dev, REL_X, dx);
+				input_report_rel(dev, REL_Y, -dy);
+			}
+			priv->pkt_count++;
+		} else {
+			priv->pkt_count = 0;
+		}
 	}
 
 	/* Post events */
diff -urN --exclude-from=/usr/src/exclude 2.5.72-vanilla/drivers/input/mouse/synaptics.h linux-2.5.72/drivers/input/mouse/synaptics.h
--- 2.5.72-vanilla/drivers/input/mouse/synaptics.h	2003-06-19 20:23:32.000000000 -0500
+++ linux-2.5.72/drivers/input/mouse/synaptics.h	2003-07-01 03:00:43.000000000 -0500
@@ -72,6 +72,9 @@
 #define SYN_ID_MINOR(i) 		(((i) >> 16) & 0xff)
 #define SYN_ID_IS_SYNAPTICS(i)		((((i) >> 8) & 0xff) == 0x47)
 
+#define SYN_REL_DECEL_FACTOR		8
+#define SYN_REL_PRESSURE_THRESHOLD	30
+
 /*
  * A structure to describe the state of the touchpad hardware (buttons and pad)
  */
@@ -100,6 +103,9 @@
 	int proto_buf_tail;
 
 	int old_w;				/* Previous w value */
+	int old_x[4];
+	int old_y[4];
+	int pkt_count;				/* number of packets with pressure above threshold */
 };
 
 #endif /* _SYNAPTICS_H */
diff -urN --exclude-from=/usr/src/exclude 2.5.72-vanilla/drivers/input/mousedev.c linux-2.5.72/drivers/input/mousedev.c
--- 2.5.72-vanilla/drivers/input/mousedev.c	2003-06-14 14:18:33.000000000 -0500
+++ linux-2.5.72/drivers/input/mousedev.c	2003-07-01 00:37:01.000000000 -0500
@@ -90,25 +90,29 @@
 					if (test_bit(BTN_TRIGGER, handle->dev->keybit))
 						break;
 					switch (code) {
-						case ABS_X:	
-							size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-							if (size != 0) {
-								list->dx += (value * xres - list->oldx) / size;
-								list->oldx += list->dx * size;
-							} else {
-								list->dx += value - list->oldx;
-								list->oldx += list->dx;
+						case ABS_X:
+							if (!test_bit(REL_X, handle->dev->relbit)) {	
+								size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
+								if (size != 0) {
+									list->dx += (value * xres - list->oldx) / size;
+									list->oldx += list->dx * size;
+								} else {
+									list->dx += value - list->oldx;
+									list->oldx += list->dx;
+								}
 							}
 							break;
 
 						case ABS_Y:
-							size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-							if (size != 0) {
-								list->dy -= (value * yres - list->oldy) / size;
-								list->oldy -= list->dy * size;
-							} else {
-								list->dy -= value - list->oldy;
-								list->oldy -= list->dy;
+							if (!test_bit(REL_Y, handle->dev->relbit)) {	
+								size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
+								if (size != 0) {
+									list->dy -= (value * yres - list->oldy) / size;
+									list->oldy -= list->dy * size;
+								} else {
+									list->dy -= value - list->oldy;
+									list->oldy -= list->dy;
+								}
 							}
 							break;
 					}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2003-07-02  6:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-07-01  8:03 [RFC/PATCH] Touchpads in absolute mode (synaptics) and mousedev Dmitry Torokhov
2003-07-01  9:40 ` Neil Brown
2003-07-01 18:29   ` Dmitry Torokhov
2003-07-01 23:43     ` Neil Brown
2003-07-02  0:57       ` Dmitry Torokhov
2003-07-02  6:59         ` Vojtech Pavlik
2003-07-01 12:02 ` Felipe Alfaro Solana
2003-07-01 18:18   ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox