Hi,

On Sat, 2008-08-16 at 18:06 +0200, Sebastian Ohl wrote:
> as i told joachim, i will think about that. i cannot be so hard to
> implement the logic, but the hard part would be to get it stable(not in
> the way of code quality but in to get deterministic bias free results)
second try. now it you don't need the aux key anymore. just tap for .5
seconds in the same region (+-4px) to produce a right button click. the
main advantage is that this patch is hardware indendent, so it can be
included in any phone distro not just the openmoko ones. 

the only thing i don't like about is that there is no "visual
timeout"(on my motorola ming there is a circle drawing around my curser
while the timeout exprires). does anyone have any idea how to accomplish
that? i don't have enough expriance in xorg driver programming and the
docs are not very helpful(at least the ones i found).

Sebastian

--- xf86-input-tslib-0.0.4/src/tslib.c	2007-10-19 10:59:29.000000000 +0000
+++ xf86-input-tslib-0.0.4.b3/src/tslib.c	2008-08-16 22:42:55.000000000 +0000
@@ -50,6 +50,8 @@
 #include <mipointer.h>
 
 #include <tslib.h>
+#include <sys/time.h>
+#include <time.h>
 
 #ifdef XFree86LOADER
 #include <xf86Module.h>
@@ -57,21 +59,28 @@
 
 #define TSLIB_DEV_DEFAULT "/dev/event0"
 
-#define MAXBUTTONS 1
+#define MAXBUTTONS 2
+#define TIME23RDBUTTON 0.5
+#define MOVEMENT23RDBUTTON 4
 
 #define DEFAULT_HEIGHT		240
 #define DEFAULT_WIDTH		320
 
 enum { TSLIB_ROTATE_NONE=0, TSLIB_ROTATE_CW=270, TSLIB_ROTATE_UD=180, TSLIB_ROTATE_CCW=90 };
 
+enum button_state { BUTTON_NOT_PRESSED = 0, BUTTON_1_PRESSED = 1, BUTTON_3_CLICK = 3, BUTTON_3_CLICKED=4 };
+
 struct ts_priv {
 	XISBuffer *buffer;
 	struct tsdev *ts;
-	int lastx,lasty,lastp;
+	int lastx,lasty;
 	int screen_num;
 	int rotate;
 	int height;
 	int width;
+	enum button_state state;
+	struct timeval button_down_start;
+	int button_down_x,button_down_y;
 };
 
 static const char *DEFAULTS[] = {
@@ -118,12 +127,25 @@
 	return TRUE;
 }
 
+struct timeval TimevalDiff(struct timeval a, struct timeval b)
+{
+	struct timeval t;
+	t.tv_sec = a.tv_sec-b.tv_sec;
+	t.tv_usec = a.tv_usec - b.tv_usec;
+	if (t.tv_usec < 0) {
+		t.tv_sec--;
+		t.tv_usec += 1000000;
+	}
+	return t;
+}
+
 static void ReadInput (LocalDevicePtr local)
 {
 	struct ts_priv *priv = (struct ts_priv *) (local->private);
 	struct ts_sample samp;
 	int ret;
 	int x,y;
+	struct timeval now;
 
 	ret = ts_read(priv->ts, &samp, 1);
 
@@ -134,6 +156,9 @@
 
 //	ErrorF("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure);
 
+	gettimeofday(&now, NULL);
+	struct timeval pressureTime = TimevalDiff(now,priv->button_down_start);
+
 	if(samp.pressure) {
 		int tmp_x = samp.x;
 		
@@ -161,18 +186,78 @@
 
 		xf86PostMotionEvent (local->dev, TRUE, 0, 2,
 				x, y);
+	} 
 
+	/* button pressed state machine
+ 	 * if pressed than press button 1, start timer and remember the tab position
+	 * if pressed longer than TIME23RDBUTTON and it is not moved more than MOVEMENT23RDBUTTON release button 1 and click button 3
+	 * if still pressed do nothing until the pressure is released
+	 */
+	//ErrorF("%d\t",priv->state);
+	switch (priv->state) {
+		case BUTTON_NOT_PRESSED :
+			if (samp.pressure) {
+				priv->button_down_start = now;
+				priv->button_down_y = samp.y;
+				priv->button_down_x = samp.x;
+				priv->state = BUTTON_1_PRESSED;
+				//ErrorF("b1 down");
+				xf86PostButtonEvent(local->dev, TRUE,
+					priv->state, TRUE, 0, 2,
+					priv->lastx,
+					priv->lasty);
+			}
+			break;
+		case BUTTON_1_PRESSED :
+			if (samp.pressure) {	
+				//ErrorF("%d %d ",pressureTime.tv_sec,pressureTime.tv_usec);
+				if ((((double)pressureTime.tv_sec)+(((double)pressureTime.tv_usec)*1e-6) > TIME23RDBUTTON) &&
+				   (abs(priv->lastx-priv->button_down_x) < MOVEMENT23RDBUTTON &&
+				    abs(priv->lasty-priv->button_down_y) < MOVEMENT23RDBUTTON))
+				{
+					//ErrorF("b1 up");
+					xf86PostButtonEvent(local->dev, TRUE,
+						priv->state, FALSE, 0, 2,
+						priv->lastx,
+						priv->lasty);
+					priv->state = BUTTON_3_CLICK;
+					//ErrorF("b3 down");
+					xf86PostButtonEvent(local->dev, TRUE,
+						priv->state, TRUE, 0, 2,
+						priv->lastx,
+						priv->lasty);
+				} 
+				if (abs(priv->lastx-priv->button_down_x) > MOVEMENT23RDBUTTON ||
+				    abs(priv->lasty-priv->button_down_y) > MOVEMENT23RDBUTTON) {
+					priv->button_down_start = now;
+					priv->button_down_y = samp.y;
+					priv->button_down_x = samp.x;
+					//ErrorF("b1 state reset");
+				}
+			} else {
+				//ErrorF("b1 up");
+				xf86PostButtonEvent(local->dev, TRUE,
+					priv->state, FALSE, 0, 2,
+					priv->lastx,
+					priv->lasty);
+				priv->state = BUTTON_NOT_PRESSED;
+			}
+			break;
+		case BUTTON_3_CLICK :
+			//ErrorF("b3 up");
+			xf86PostButtonEvent(local->dev, TRUE,
+				priv->state, FALSE, 0, 2,
+				priv->lastx,
+				priv->lasty);
+			priv->state = BUTTON_3_CLICKED;
+			break;
+		case BUTTON_3_CLICKED :
+			if (!samp.pressure) {
+				//ErrorF("b3 free");
+				priv->state = BUTTON_NOT_PRESSED;
+			}
+			break;
 	}
-
-	if(priv->lastp != samp.pressure) {
-		priv->lastp = samp.pressure;
-
-		xf86PostButtonEvent(local->dev, TRUE,
-			1, !!samp.pressure, 0, 2,
-			priv->lastx,
-			priv->lasty);
-	}
-
 }
 
 /*
@@ -361,6 +446,8 @@
 
 	pInfo->fd = ts_fd(priv->ts);
 
+	priv->state = BUTTON_NOT_PRESSED;
+		
 	/* Mark the device configured */
 	pInfo->flags |= XI86_CONFIGURED;
 
_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to