Package: xserver-xorg-input-tslib
Version: 0.0.5-1
Severity: normal
Tags: patch

When the variance module is enabled in ts.conf, the tslib input driver will
emit a ButtonRelease event only when the pen is pressed the next time.  This
is because the variance module caches samples and will produce two samples on
a release event, but the input driver is only prepared to receive one sample
each time there is data available in the fd.  A solution is to open the
touchscreen in non-blocking mode and read as long as samples are available.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (1, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 2.6.26.2 (SMP w/2 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=fi_FI.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
--- xf86-input-tslib-0.0.5/src/tslib.c	2008-08-19 09:48:11.000000000 +0300
+++ xf86-input-tslib-0.0.5.mod/src/tslib.c	2008-10-04 00:29:23.000000000 +0300
@@ -123,52 +123,50 @@
 	int ret;
 	int x,y;
 
-	ret = ts_read(priv->ts, &samp, 1);
+	while((ret = ts_read(priv->ts, &samp, 1)) == 1) {
+		if(samp.pressure) {
+			int tmp_x = samp.x;
+
+			switch(priv->rotate) {
+			case TSLIB_ROTATE_CW:	samp.x = samp.y;
+						samp.y = priv->width - tmp_x;
+						break;
+			case TSLIB_ROTATE_UD:	samp.x = priv->width - samp.x;
+						samp.y = priv->height - samp.y;
+						break;
+			case TSLIB_ROTATE_CCW:	samp.x = priv->height - samp.y;
+						samp.y = tmp_x;
+						break;
+			default:		break;
+			}
+
+			priv->lastx = samp.x;
+			priv->lasty = samp.y;
+			x = samp.x;
+			y = samp.y;
+
+			xf86XInputSetScreen(local, priv->screen_num,
+					samp.x,
+					samp.y);
 
-	if (ret < 0) {
-		ErrorF("ts_read failed\n");
-		return;
-	}
+			xf86PostMotionEvent (local->dev, TRUE, 0, 2,
+					x, y);
 
-//	ErrorF("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure);
-
-	if(samp.pressure) {
-		int tmp_x = samp.x;
-
-		switch(priv->rotate) {
-		case TSLIB_ROTATE_CW:	samp.x = samp.y;
-					samp.y = priv->width - tmp_x;
-					break;
-		case TSLIB_ROTATE_UD:	samp.x = priv->width - samp.x;
-					samp.y = priv->height - samp.y;
-					break;
-		case TSLIB_ROTATE_CCW:	samp.x = priv->height - samp.y;
-					samp.y = tmp_x;
-					break;
-		default:		break;
 		}
 
-		priv->lastx = samp.x;
-		priv->lasty = samp.y;
-		x = samp.x;
-		y = samp.y;
-
-		xf86XInputSetScreen(local, priv->screen_num,
-				samp.x,
-				samp.y);
-
-		xf86PostMotionEvent (local->dev, TRUE, 0, 2,
-				x, y);
+		if(!!priv->lastp != !!samp.pressure) {
+			priv->lastp = samp.pressure;
 
+			xf86PostButtonEvent(local->dev, TRUE,
+				1, !!samp.pressure, 0, 2,
+				priv->lastx,
+				priv->lasty);
+		}
 	}
 
-	if(priv->lastp != samp.pressure) {
-		priv->lastp = samp.pressure;
-
-		xf86PostButtonEvent(local->dev, TRUE,
-			1, !!samp.pressure, 0, 2,
-			priv->lastx,
-			priv->lasty);
+	if (ret < 0) {
+		ErrorF("ts_read failed\n");
+		return;
 	}
 
 }
@@ -183,7 +181,7 @@
 {
 	InputInfoPtr pInfo;
 	unsigned char map[MAXBUTTONS + 1];
-	int i;
+	int i, axiswidth, axisheight;
 	struct ts_priv *priv;
 
 	ErrorF("%s\n", __FUNCTION__);
@@ -212,17 +210,29 @@
 			return !Success;
 		}
 
+		switch(priv->rotate) {
+		case TSLIB_ROTATE_CW:
+		case TSLIB_ROTATE_CCW:
+			axiswidth = priv->height;
+			axisheight = priv->width;
+			break;
+		default:
+			axiswidth = priv->width;
+			axisheight = priv->height;
+			break;
+		}
+
 		InitValuatorAxisStruct(device, 0, 0,    	/* min val */
-					       priv->width - 1,	/* max val */
-					       priv->width,	/* resolution */
+					       axiswidth - 1,	/* max val */
+					       axiswidth,	/* resolution */
 					       0,		/* min_res */
-					       priv->width);	/* max_res */
+					       axiswidth);	/* max_res */
 
 		InitValuatorAxisStruct(device, 1, 0,    	/* min val */
-					       priv->height - 1,/* max val */
-					       priv->height,	/* resolution */
+					       axisheight - 1,	/* max val */
+					       axisheight,	/* resolution */
 					       0,		/* min_res */
-					       priv->height);	/* max_res */
+					       axisheight);	/* max_res */
 
 		if (InitProximityClassDeviceStruct (device) == FALSE) {
 			ErrorF ("Unable to allocate EVTouch touchscreen ProximityClassDeviceStruct\n");
@@ -336,7 +346,7 @@
 
 	s = xf86SetStrOption(pInfo->options, "TslibDevice", NULL);
 
-	priv->ts = ts_open(s, 0);
+	priv->ts = ts_open(s, 1);
 	if (!priv->ts) {
 		ErrorF("ts_open failed (device=%s)\n",s);
 		return NULL;

Reply via email to