[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#155808: marked as done (xserver-xfree86: [mouse] absolute positioning patch backported from CVS HEAD)



Your message dated Mon, 12 Feb 2007 23:40:01 +0100
with message-id <45D0ECC1.3050909@ens-lyon.org>
and subject line ping timeout, closing
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: xserver-xfree86
Version: 4.2
Severity: wishlist

This is a patch I created by backporting from the current X CVS tree.
This patch adds support for the Viewsonic Viewpad touchscreen (among
others).  Without this patch, the mouse only operates in relative
positioning mode.  i.e. if you touch the screen on a button, you don't
click on that button, you click wherever the pointer was when you
touched the screen.  I've also forwarded this patch on to the upstream
author who's doing the CVS tree work.

Thanks

--- xc/programs/Xserver/hw/xfree86/input/mouse/mousePriv.h	2002/02/24 15:13:22	1.6
+++ xc/programs/Xserver/hw/xfree86/input/mouse/mousePriv.h	2002/03/18 20:50:34
@@ -19,7 +19,13 @@
 
 typedef struct {
     int state;
-} ps2PrivRec, *ps2PrivPtr;
+    int	min_x;
+    int	max_x;
+    int	min_y;
+    int	max_y;
+    int	rotate;
+    int	reporting_mode;    
+} mousePrivRec, *mousePrivPtr;
 
 /* mouse proto flags */
 #define MPF_NONE		0x00
--- xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c	2002/02/24 15:13:22	1.50
+++ xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c	2002/03/18 20:50:34
@@ -73,6 +73,7 @@
 static Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0,
 		 	     int v1, int v2, int v3, int v4, int v5, int *x,
 		 	     int *y);
+static int MouseControl(InputInfoPtr pInfo, xDeviceCtl * control);
 
 static void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
 static void MousePostEvent(InputInfoPtr pInfo, int buttons,
@@ -119,6 +120,11 @@
     OPTION_FLOW_CONTROL,
     OPTION_VTIME,
     OPTION_VMIN,
+    OPTION_MINX,
+    OPTION_MAXX,
+    OPTION_MINY,
+    OPTION_MAXY,
+    OPTION_ROTATE,
     OPTION_EMULATE_WHEEL,
     OPTION_EMU_WHEEL_BUTTON,
     OPTION_EMU_WHEEL_INERTIA,
@@ -153,6 +159,13 @@
     { OPTION_FLOW_CONTROL,	"FlowControl",	  OPTV_STRING,	{0}, FALSE },
     { OPTION_VTIME,		"VTime",	  OPTV_INTEGER,	{0}, FALSE },
     { OPTION_VMIN,		"VMin",		  OPTV_INTEGER,	{0}, FALSE },
+    /* touchscreen options */
+    { OPTION_MINX,		"MinX",		  OPTV_INTEGER,	{0}, FALSE },
+    { OPTION_MAXX,		"MaxX",		  OPTV_INTEGER,	{0}, FALSE },
+    { OPTION_MINY,		"MinY",		  OPTV_INTEGER,	{0}, FALSE },
+    { OPTION_MAXY,		"MaxY",		  OPTV_INTEGER,	{0}, FALSE },
+    { OPTION_ROTATE,		"Rotate",	  OPTV_STRING,	{0}, FALSE },
+    /* end touchscreen options */
     { OPTION_EMULATE_WHEEL,	"EmulateWheel",	  OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_EMU_WHEEL_BUTTON,	"EmulateWheelButton", OPTV_INTEGER, {0}, FALSE },
     { OPTION_EMU_WHEEL_INERTIA,	"EmulateWheelInertia", OPTV_INTEGER, {0}, FALSE },
@@ -256,7 +269,9 @@
     { "GlidePointPS/2",		MSE_XPS2,	NULL,		PROT_GLIDEPS2 },
     { "NetMousePS/2",		MSE_XPS2,	NULL,		PROT_NETPS2 },
     { "NetScrollPS/2",		MSE_XPS2,	NULL,		PROT_NETSCPS2 },
-
+    { "ScreenCoderPS/2",	MSE_XPS2,	NULL,		PROT_SCPS2 },
+    { "ScreenCoderIMPS/2",	MSE_XPS2,	NULL,		PROT_SCIMPS2 },
+    { "ScreenCoderEXPPS/2",	MSE_XPS2,	NULL,		PROT_SCEXPPS2 },
     /* Bus Mouse */
     { "BusMouse",		MSE_BUS,	NULL,		PROT_BM },
 
@@ -594,8 +609,10 @@
 static InputInfoPtr
 MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
 {
+    char *s;
     InputInfoPtr pInfo;
     MouseDevPtr pMse;
+    mousePrivPtr mPriv;
     MessageType from = X_DEFAULT;
     const char *protocol;
     MouseProtocolID protocolID;
@@ -615,7 +632,7 @@
     pInfo->read_input = MouseReadInput;
     pInfo->motion_history_proc = xf86GetMotionEvents;
     pInfo->history_size = 0;
-    pInfo->control_proc = NULL;
+    pInfo->control_proc = MouseControl;
     pInfo->close_proc = NULL;
     pInfo->switch_mode = NULL;
     pInfo->conversion_proc = MouseConvert;
@@ -710,6 +727,9 @@
 #endif
     pInfo->fd = -1;
 
+    if (!(mPriv = (pointer) xcalloc(sizeof(mousePrivRec), 1)))
+      return pInfo;
+    pMse->mousePriv = mPriv;
     pMse->CommonOptions(pInfo);
 
     pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
@@ -743,6 +763,21 @@
 	xf86ErrorF("\n");
     }
 
+    s = xf86SetStrOption(pInfo->options, "Rotate", NULL);
+    if (s) {
+	if (!xf86NameCmp(s, "CW")) {
+            mPriv->rotate = 1;
+	}else if (!xf86NameCmp(s, "CCW")) {
+            mPriv->rotate = -1;
+	}else{
+            mPriv->rotate = 0;
+        }
+    }
+    mPriv->min_x = xf86SetIntOption(pInfo->options, "MinX", 0);
+    mPriv->max_x = xf86SetIntOption(pInfo->options, "MaxX", 1023);
+    mPriv->min_y = xf86SetIntOption(pInfo->options, "MinY", 0);
+    mPriv->max_y = xf86SetIntOption(pInfo->options, "MaxY", 1023);
+
     pInfo->flags |= XI86_CONFIGURED;
     return pInfo;
 }
@@ -778,6 +813,9 @@
   {  0xf8, 0x80, 0x00, 0x00,  5,   0x00, 0xff, MPF_NONE },  /* BusMouse */
   {  0xf8, 0x80, 0x00, 0x00,  5,   0x00, 0xff, MPF_NONE },  /* Auto (dummy) */
   {  0xf8, 0x80, 0x00, 0x00,  8,   0x00, 0xff, MPF_NONE },  /* SysMouse */
+  {  0x00, 0x00, 0x00, 0x00,  3,   0x00, 0xff, MPF_NONE },  /* ScreenCoder */
+  {  0x00, 0x00, 0x00, 0x00,  4,   0x00, 0xff, MPF_NONE },  /* ScreenCoder Im */
+  {  0x00, 0x00, 0x00, 0x00,  4,   0x00, 0xff, MPF_NONE },  /* ScreenCoder Exp */
 };
 
 /*
@@ -1082,9 +1120,9 @@
     case PROT_GLIDEPS2:
     case PROT_NETPS2:		/* NetMouse, NetMouse Pro, Mie Mouse */
     case PROT_NETSCPS2:		/* NetScroll */
+    case PROT_SCPS2:
+    case PROT_SCIMPS2:
+    case PROT_SCEXPPS2:
-	if ((pMse->mousePriv = 
-	     (pointer) xcalloc(sizeof(ps2PrivRec), 1)) == 0)
-	    return FALSE;
 	initPs2(pInfo,TRUE);
 	break;
     case PROT_SYSMOUSE:
@@ -1113,6 +1148,7 @@
     int pBufP;
     int c;
     unsigned char *pBuf, u;
+    MouseProtocolID tmpProto;
 
     pMse = pInfo->private;
     pBufP = pMse->protoBufTail;
@@ -1332,7 +1368,63 @@
 	 */
 
 	dz = dw = 0;
-	switch (pMse->protocolID) {
+       /* The ScreenCoder operates in two modes.  In the first
+          mode, it injects relative motion packets along with
+          packets from an external pointer device.  The format of
+          packets from both sources is identical.  In the second
+          mode, the injected packets represent absolute position.
+          In that case, the external pointer device packets are
+          guaranteed (by reformatting) to have bit 3 of byte 0 set.
+          This block looks for, and processes absolute position
+          packets, while passing relative motion packets along
+          for processing as PS/2, IMPS/2 or EXPPS/2 packets, i.e.,
+	  this block of code picks off the absolute position
+          packets from the data stream. [RAB-2002/04/25] */
+       tmpProto = pMse->protocolID;
+       switch (tmpProto) {
+       case PROT_SCPS2:
+           if (pBuf[0] & 0x08){
+               /* it belongs to the external pointer */
+               tmpProto = PROT_PS2;
+               break;
+           }
+       case PROT_SCIMPS2:
+           if (pBuf[0] & 0x08){
+               /* it belongs to the external pointer */
+               tmpProto = PROT_IMPS2;
+               break;
+           }
+       case PROT_SCEXPPS2:
+           if (pBuf[0] & 0x08){
+               /* it belongs to the external pointer */
+               tmpProto = PROT_EXPPS2;
+               break;
+           }
+       /* fall through to common code which deals with
+       * absolute positioning information: common to
+       * PROT_SCPS2, PROT_SCIMPS2, and PROT_SCEXPPS2 */
+           if ((pBuf[0] & 0x03) == 0x03){
+               buttons = 0;
+           }else if ((pBuf[0] & 0x03) == 0x00){
+               buttons = 0x04;
+           }else{
+               buttons = 0;
+               ErrorF("fell out of sync !!!");
+           }
+           dx = ((pBuf[0] & 0x30)<<4) + pBuf[1];
+           dy = ((pBuf[0] & 0xC0)<<2) + pBuf[2];
+           /* dz is ignored in absolute mode */
+            /* this flags dx and dy as absolute position */
+           buttons |= MSE_ABSOLUTE_POSN;
+           tmpProto = PROT_SKIP;
+           break;
+       default:
+           break;
+       }
+
+       switch (tmpProto) {
+       case PROT_SKIP:
+         break;
 	case PROT_LOGIMAN:	/* MouseMan / TrackMan   [CHRIS-211092] */
 	case PROT_MS:		/* Microsoft */
 	    if (pMse->chordMiddle)
@@ -1559,6 +1651,24 @@
     pMse->threshold = ctrl->threshold;
 }
 
+static int
+MouseControl(InputInfoPtr pInfo, xDeviceCtl * control)
+{
+    MouseDevPtr pMse;
+    mousePrivPtr mPriv;
+    xDeviceTSCalibrationCtl *c;
+
+        pMse = pInfo->private;
+	mPriv = (mousePrivPtr)pMse->mousePriv;
+        c = (xDeviceTSCalibrationCtl *) control;
+
+	mPriv->min_x = c->min_x;
+	mPriv->max_x = c->max_x;
+	mPriv->min_y = c->min_y;
+	mPriv->max_y = c->max_y;
+	return (Success);
+} /* [RAB - 2002/04/25] */
+
 /*
  ***************************************************************************
  *
@@ -1989,8 +2099,13 @@
 	buttons &= ~pMse->wheelButtonMask;
     }
 
-    if (dx || dy)
-	xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+    if (buttons & MSE_ABSOLUTE_POSN){ /* [RAB - 2002/04/25] */
+       xf86PostMotionEvent(pInfo->dev, 1, 0, 2, dx, dy);
+       buttons &= ~MSE_ABSOLUTE_POSN;
+    }else{
+       if (dx || dy)
+           xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+    }
 
     if (truebuttons != pMse->lastButtons) {
 
@@ -2040,10 +2155,12 @@
 MousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw)
 {
     MouseDevPtr pMse;
+    mousePrivPtr mPriv;
     int zbutton = 0;
 
 
     pMse = pInfo->private;
+    mPriv = (mousePrivPtr)pMse->mousePriv;
 
     /* Map the Z axis movement. */
     /* XXX Could this go in the conversion_proc? */
@@ -2077,12 +2194,43 @@
 	dz = 0;
 	break;
     }
-    dx = pMse->invX * dx;
-    dy = pMse->invY * dy;
-    if (pMse->flipXY) {
-	int tmp = dx;
-	dx = dy;
-	dy = tmp;
+    if (buttons & MSE_ABSOLUTE_POSN){ /* [RAB - 2002/04/25] */
+      int scaled_x,scaled_y;
+	/*******************************************
+	The use of mPriv->rotate allows absolute positioning
+	to be rotated here, but defers rotation of relative
+	positioning to the screen driver (since that seems to
+	be where it's done in at least the SiS driver).
+
+	Note: The xf86ScaleAxis function could have been used here,
+	but we can fold inversion and the flip operation into our
+	logic better without using this function.
+	*******************************************/
+	#define SCALE 10000
+        scaled_x = (SCALE * (dx - mPriv->min_x)) / mPriv->max_x;
+        scaled_y = (SCALE * (dy - mPriv->min_y)) / mPriv->max_y;
+	if (pMse->invX < 0 || mPriv->rotate == 1){
+            scaled_x = SCALE - scaled_x;
+        }
+	if (pMse->invY < 0 || mPriv->rotate == -1){
+            scaled_y = SCALE - scaled_y;
+        }
+	if (pMse->flipXY || mPriv->rotate ) {
+	    dx = scaled_y * screenInfo.screens[0]->width / SCALE;
+	    dy = scaled_x * screenInfo.screens[0]->height / SCALE;
+	}else{
+	    dx = scaled_x * screenInfo.screens[0]->width / SCALE;
+	    dy = scaled_y * screenInfo.screens[0]->height / SCALE;
+	}
+    }else{
+	dx = pMse->invX * dx;
+	dy = pMse->invY * dy;
+
+	if (pMse->flipXY) {
+	    int tmp = dx;
+	    dx = dy;
+	    dy = tmp;
+	}
     }
     MouseDoPostEvent(pInfo, buttons, dx, dy);
 
@@ -2151,6 +2299,40 @@
 	}
 	break;
 
+    case PROT_SCIMPS2:         /* ScreenCoder Intellimouse PS/2 */
+       {
+           /* "255" says "don't write, just read and discard" !!! */
+           static unsigned char seq[] = { 243, 200, 243, 100, 243, 80, 242,
+                                         243, 80, 243, 60, 243, 100,
+                                        242, 255, 243, 100 };
+
+           param = seq;
+           paramlen = sizeof(seq);
+       }
+       break;
+    case PROT_SCEXPPS2:                /* ScreenCoder Explorer PS/2 */
+       {
+           /* "255" says "don't write, just read and discard" !!! */
+           static unsigned char seq[] = { 243, 200, 243, 100, 243, 80,
+                                        243, 200, 243, 200, 243, 80, 242,
+                                         243, 80, 243, 60, 243, 100,
+                                        242, 255, 243, 100 };
+
+           param = seq;
+           paramlen = sizeof(seq);
+       }
+       break;
+    case PROT_SCPS2:           /* ScreenCoder PS/2 */
+       {
+           /* "255" says "don't write, just read and discard" !!! */
+           static unsigned char seq[] = { 243, 80, 243, 60, 243, 100,
+                                        242, 255, 243, 100 };
+
+           param = seq;
+           paramlen = sizeof(seq);
+       }
+       break;
+
     case PROT_THINKPS2:		/* ThinkingMouse */
 	{
 	    static unsigned char seq[] = { 243, 10, 232,  0, 243, 20, 243, 60,
@@ -2162,14 +2344,23 @@
     }
 
     if (paramlen > 0) {
-#ifdef EXTMOUSEDEBUG
+/* The introduction of the "255" escape value, neccessary to initialize
+ * the ScreenCoder, makes it mandatory to use this block.  [RAB - 2002/04/25]
+ */
+#if 1
+        int i;
 	for (i = 0; i < paramlen; ++i) {
-	    if (xf86WriteSerial(pInfo->fd, &param[i], 1) != 1)
+            /* "255" says "don't write, just read and discard" !!!*/
+            if (param[i] != 255){
+              if (xf86WriteSerial(pInfo->fd, &param[i], 1) != 1)
 		ErrorF("SetupMouse: Write to mouse failed (%s)\n",
 		       strerror(errno));
+            }
 	    usleep(30000);
 	    xf86ReadSerial(pInfo->fd, &c, 1);
+#ifdef EXTMOUSEDEBUG
 	    ErrorF("SetupMouse: got %02x\n", c);
+#endif
 	}
 #else
 	if (xf86WriteSerial(pInfo->fd, param, paramlen) != paramlen)
@@ -2179,7 +2370,7 @@
  	xf86FlushInput(pInfo->fd);
     }
 
-    ((ps2PrivPtr)(pMse->mousePriv))->state = 0;
+    ((mousePrivPtr)(pMse->mousePriv))->state = 0;
     if (osInfo->SetPS2Res) {
 	osInfo->SetPS2Res(pInfo, pMse->protocol, pMse->sampleRate,
 			  pMse->resolution);
@@ -2231,19 +2422,19 @@
 ps2mouseReset(InputInfoPtr pInfo, unsigned char val) 
 {
     MouseDevPtr pMse = pInfo->private;
-    ps2PrivPtr ps2priv = (ps2PrivPtr)pMse->mousePriv;
+    mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv;
 #ifdef EXTMOUSEDEBUG
-    ErrorF("Ps/2 Mouse State: %i, 0x%x\n",ps2priv->state,val);
+    ErrorF("Ps/2 Mouse State: %i, 0x%x\n",mPriv->state,val);
 #endif
-    switch (ps2priv->state) {
+    switch (mPriv->state) {
 	case 0:
 	    if (val == 0xaa) 
-		ps2priv->state = 1;
+		mPriv->state = 1;
 	    else 
-		ps2priv->state = 0;
+		mPriv->state = 0;
 		return FALSE;
 	case 1:
-	    ps2priv->state = 0;
+	    mPriv->state = 0;
 	    if (val == 0x00) {
 		xf86MsgVerb(X_INFO,3,
 			    "Got reinsert event: reinitializing PS/2 mouse\n");
--- xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h	2002/02/24 15:14:55	1.10
+++ xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h	2002/03/18 17:23:36
@@ -32,6 +32,10 @@
     PROT_BM,
     PROT_AUTO,
     PROT_SYSMOUSE,
+    PROT_SCPS2,
+    PROT_SCIMPS2,
+    PROT_SCEXPPS2,
+    PROT_SKIP,
     PROT_NUMPROTOS	/* This must always be last. */
 } MouseProtocolID;
 
--- xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h	2002/02/24 17:22:17	1.16
+++ xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h	2002/02/24 17:23:56
@@ -165,5 +165,6 @@
 
 #define MSE_MAXBUTTONS	12
 #define MSE_DFLTBUTTONS	 3
+#define MSE_ABSOLUTE_POSN (1<<MSE_MAXBUTTONS)
 
 #endif /* _XF86OSMOUSE_H_ */
--- xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml	2002/03/18 19:46:55	1.11
+++ xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml	2002/03/18 19:33:26
@@ -913,6 +913,51 @@
 	Option	"Protocol"	"Auto"
 </verb>
 
+<sect1>Semtech ScreenCoder(PS/2) <p>
+The Semtech Screencoder provides a single packet stream from a resistive
+touchscreen and an "external" pointing device (which could be built into
+a laptop or tablet).  By default, it appears as a PS/2 mouse to the system,
+but it will send Intellimouse PS/2 or Explorer PS/2 packets after the
+appropriate "knocking" sequences have been sent by the system.
+
+Since the Screencoder acts as a controller to the pointing device, it
+independently determines the highest level supported by the pointing
+device.  It will then reformat the pointing device packets as needed.
+
+By default the touchscreen acts as a relative motion pointer, i.e.,
+it looks like mouse motion with button 1 pressed, so it doesn't
+matter where you initially touch the screen, only the direction
+your touch while in contact with the screen matters.
+
+To use the ScreenCoder in this mode, enter:
+<verb>
+	Option	"Protocol"	"PS/2"
+</verb>
+<verb>
+	Option	"Protocol"	"IMPS/2"
+</verb>
+or
+<verb>
+	Option	"Protocol"	"ExplorerPS/2"
+</verb>
+
+The ScreenCoder can also encode touchscreen positioning in absolute
+form.  This is useful for pressing on-screen buttons, etc.  In this
+mode, two packet formats appear in the data stream, with a status bit
+to distinguish one from the other.
+
+To use the ScreenCoder in this mode, enter:
+<verb>
+	Option	"Protocol"	"ScreenCoderPS/2"
+</verb>
+<verb>
+	Option	"Protocol"	"ScreenCoderIMPS/2"
+</verb>
+or
+<verb>
+	Option	"Protocol"	"ScreenCoderEXPPS/2"
+</verb>
+
 <sect>Configuration Examples <p>
 
 This section shows some example <tt>InputDevice</tt> section for 


-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG=1C58 8B2C FB5E 3F64 EA5C  64AE 78FE E5FE F0CB A0AD


--- End Message ---
--- Begin Message ---
I am closing this bug since the submitter did not reply to the ping I
send a couple weeks ago. If anybody ever reproduces this problem, feel
free to reopen.

Brice


--- End Message ---

Reply to: