ThinkPad570でスクロールマウスもどき #2

id:ha-tan:20050523の続き。スクロールマウスもどき機能のON/OFFをsysctlで制御できるようにした。環境は、NetBSD-2.0.2。しかし、これまた見よう見真似のコピペコードだ。

--- dev/pckbport/pms.c	8 May 2005 12:42:41 -0000	1.1.1.1
+++ dev/pckbport/pms.c	27 May 2005 17:31:28 -0000	1.6
@@ -32,6 +32,7 @@
 #include <sys/ioctl.h>
 #include <sys/kernel.h>
 #include <sys/kthread.h>
+#include <sys/sysctl.h>
 
 #include <machine/bus.h>
 
@@ -49,6 +50,8 @@
 #define DPRINTF(x)
 #endif
 
+int pms_tp_scroll; /* enable thinkpad scroll? XXX sysctl */
+
 enum pms_type { PMS_UNKNOWN, PMS_STANDARD, PMS_SCROLL3, PMS_SCROLL5 };
 
 struct pms_protocol {
@@ -85,6 +88,7 @@
 
 	struct device *sc_wsmousedev;
 	struct proc *sc_event_thread;
+	int dz;
 };
 
 int pmsprobe(struct device *, struct cfdata *, void *);
@@ -250,6 +254,7 @@
 
 	sc->inputstate = 0;
 	sc->buttons = 0;
+	sc->dz = 0;
 
 	pckbport_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 1);
 
@@ -606,6 +611,23 @@
 			dy = -127;
 		
 		sc->inputstate = 0;
+
+		if (pms_tp_scroll) {
+		    if (newbuttons & 0x02) {
+				sc->dz += dy;
+				if (sc->dz < -10 || sc->dz > 10) {
+					dz = -sc->dz;
+					if (dz >= 128)
+						dz = 127;	/* XXX need? */
+					if (dz <= -128)
+						dz = -127;	/* XXX need? */
+					sc->dz = 0;
+				}
+				dx = dy = 0;
+		    }
+		    newbuttons &= ~0x02;
+		}
+		
 		changed = (sc->buttons ^ newbuttons);
 		sc->buttons = newbuttons;
 
@@ -640,3 +662,41 @@
 		return;
 	}
 }
+
+SYSCTL_SETUP(sysctl_pms, "sysctl pms subtree setup")
+{
+	int rc, pms_root_num;
+	struct sysctlnode *node;
+	
+	if ((rc = sysctl_createv(
+			 clog, 0, NULL, NULL,
+			 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
+			 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
+		goto err;
+	}
+	
+	if ((rc = sysctl_createv(
+			 clog, 0, NULL, &node,
+			 CTLFLAG_PERMANENT, CTLTYPE_NODE, "pms",
+			 SYSCTL_DESCR("PS/2 mouse interface controls"),
+			 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
+		goto err;
+	}
+
+	pms_root_num = node->sysctl_num;
+	
+	if ((rc = sysctl_createv(
+			 clog, 0, NULL, &node, 
+			 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+			 CTLTYPE_INT, "tp_scroll",
+			 SYSCTL_DESCR("ThinkPad scroll hack"),
+			 NULL, 0, &pms_tp_scroll, 0,
+			 CTL_HW, pms_root_num, CTL_CREATE, CTL_EOL)) != 0) {
+		goto err;
+	}
+
+	return;
+	
+  err:
+	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
+}

実行例: ONにする場合

$ sudo sysctl -w hw.pms.tp_scroll=1
hw.pms.tp_scroll: 0 -> 1

実行例: OFFにする場合

$ sudo sysctl -w hw.pms.tp_scroll=0
hw.pms.tp_scroll: 1 -> 0

BUGS。相変らずPS/2マウスが複数挿さっている場合を考えてない。