Module Name:    xsrc
Committed By:   nia
Date:           Fri Oct  8 23:30:17 UTC 2021

Modified Files:
        xsrc/external/mit/xf86-input-ws/dist/src: ws.c ws.h

Log Message:
xf86-input-ws: Port auto-calibration bits from xf86-input-mouse.

Needed for absolute input devices where pointer coordinates do not
match the display size.

Tested by jmcneill.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 xsrc/external/mit/xf86-input-ws/dist/src/ws.c
cvs rdiff -u -r1.4 -r1.5 xsrc/external/mit/xf86-input-ws/dist/src/ws.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/xf86-input-ws/dist/src/ws.c
diff -u xsrc/external/mit/xf86-input-ws/dist/src/ws.c:1.13 xsrc/external/mit/xf86-input-ws/dist/src/ws.c:1.14
--- xsrc/external/mit/xf86-input-ws/dist/src/ws.c:1.13	Fri Oct  1 07:14:37 2021
+++ xsrc/external/mit/xf86-input-ws/dist/src/ws.c	Fri Oct  8 23:30:17 2021
@@ -219,6 +219,10 @@ wsPreInit12(InputDriverPtr drv, InputInf
 		buttons_from = X_CONFIG;
 	}
 
+	priv->autoCalibrate = xf86SetBoolOption(pInfo->options, "AutoCalibrate", TRUE);
+	xf86Msg(X_CONFIG, "%s: auto calibration %sabled\n",
+	    pInfo->name, priv->autoCalibrate ? "en" : "dis"); 
+
 	priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0);
 	xf86Msg(X_CONFIG, "%s associated screen: %d\n",
 	    pInfo->name, priv->screen_no);
@@ -602,6 +606,45 @@ wsDeviceOff(DeviceIntPtr pWS)
 }
 
 static void
+wsAutoCalibrate(InputInfoPtr pInfo)
+{
+	WSDevicePtr priv;
+	int width, height;
+	struct wsmouse_calibcoords cal;
+
+	priv = pInfo->private;
+	width = screenInfo.screens[priv->screen_no]->width;
+	height = screenInfo.screens[priv->screen_no]->height;
+
+	if (width != priv->lastScreenWidth ||
+	    height != priv->lastScreenHeight) {
+		if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &cal) == 0 &&
+		    cal.minx != cal.maxy && cal.miny != cal.maxy) {
+
+			xf86Msg(X_INFO, "%s: auto-calibrating abs pointer for %dx%d screen\n",
+			    pInfo->name, width, height);
+
+			priv->min_x = cal.minx;
+			priv->min_y = cal.miny;
+			priv->max_x = cal.maxx;
+			priv->max_y = cal.maxy;
+
+			priv->translateAbs =
+			    cal.samplelen == WSMOUSE_CALIBCOORDS_RESET;
+		}
+		priv->lastScreenWidth = width;
+		priv->lastScreenHeight = height;
+	}
+}
+
+static int
+wsTranslate(InputInfoPtr pInfo, int scrRange,
+    int rawMin, int rawMax, int rawVal)
+{
+	return ((rawVal - rawMin) * scrRange) / (rawMax - rawMin);
+}
+
+static void
 wsReadInput(InputInfoPtr pInfo)
 {
 	WSDevicePtr priv;
@@ -613,6 +656,9 @@ wsReadInput(InputInfoPtr pInfo)
 
 	priv = pInfo->private;
 
+	if (priv->autoCalibrate)
+		wsAutoCalibrate(pInfo);
+
 	XisbBlockDuration(priv->buffer, -1);
 	pBuf = (unsigned char *)eventList;
 	n = 0;
@@ -658,12 +704,19 @@ wsReadInput(InputInfoPtr pInfo)
 			if (event->value == 4095) 
 				break;
 			ax = event->value;
+			if (priv->translateAbs)
+				ax = wsTranslate(pInfo,
+				    priv->lastScreenWidth,
+				    priv->min_x, priv->max_x, ax);
 			if (priv->inv_x)
 				ax = priv->max_x - ax + priv->min_x;
 			break;
 		case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
 			DBG(4, ErrorF("Absolute Y %d\n", event->value));
 			ay = event->value;
+			if (priv->translateAbs)
+				ay = wsTranslate(pInfo, priv->lastScreenWidth,
+				    priv->min_y, priv->max_y, ay);
 			if (priv->inv_y)
 				ay = priv->max_y - ay + priv->min_y;
 			break;

Index: xsrc/external/mit/xf86-input-ws/dist/src/ws.h
diff -u xsrc/external/mit/xf86-input-ws/dist/src/ws.h:1.4 xsrc/external/mit/xf86-input-ws/dist/src/ws.h:1.5
--- xsrc/external/mit/xf86-input-ws/dist/src/ws.h:1.4	Tue Sep 28 06:17:15 2021
+++ xsrc/external/mit/xf86-input-ws/dist/src/ws.h	Fri Oct  8 23:30:17 2021
@@ -47,6 +47,9 @@ typedef struct WSDevice {
 	int screen_no;
 	int num, den, threshold; /* relative accel params */
 	pointer buffer;
+	int autoCalibrate;
+	int translateAbs;
+	int lastScreenWidth, lastScreenHeight;
 	int negativeZ, positiveZ; /* mappings for Z axis */
 	int negativeW, positiveW; /* mappings for W axis */
 	struct wsmouse_calibcoords coords; /* mirror of the kernel values */

Reply via email to