Module Name:    src
Committed By:   nia
Date:           Tue Sep 28 06:14:28 UTC 2021

Modified Files:
        src/sys/dev/wscons: wsconsio.h wsmouse.c wsmousevar.h

Log Message:
wsmouse: add support for "precision scrolling" events and (GET|SET)PARAMS

WSCONS_EVENT_HSCROLL and WSCONS_EVENT_VSCROLL are two new wscons event
types that allow scrolling with a higher precision ("smoothness") than an
emulated scroll wheel, and are useful for touch input drivers.

WSMOUSEIO_GETPARAMS and WSMOUSEIO_SETPARAMS are two new ioctls that allow
the speed and direction of precision scrolling to be configured.

both features were originally implemented in OpenBSD.


To generate a diff of this commit:
cvs rdiff -u -r1.125 -r1.126 src/sys/dev/wscons/wsconsio.h
cvs rdiff -u -r1.69 -r1.70 src/sys/dev/wscons/wsmouse.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/wscons/wsmousevar.h

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

Modified files:

Index: src/sys/dev/wscons/wsconsio.h
diff -u src/sys/dev/wscons/wsconsio.h:1.125 src/sys/dev/wscons/wsconsio.h:1.126
--- src/sys/dev/wscons/wsconsio.h:1.125	Sat Apr 24 00:15:37 2021
+++ src/sys/dev/wscons/wsconsio.h	Tue Sep 28 06:14:27 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: wsconsio.h,v 1.125 2021/04/24 00:15:37 macallan Exp $ */
+/* $NetBSD: wsconsio.h,v 1.126 2021/09/28 06:14:27 nia Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -76,7 +76,8 @@ struct wscons_event {
 #define	WSCONS_EVENT_ASCII		13	/* key code is already ascii */
 #define	WSCONS_EVENT_MOUSE_DELTA_W	14	/* W delta amount */
 #define	WSCONS_EVENT_MOUSE_ABSOLUTE_W	15	/* W location */
-
+#define	WSCONS_EVENT_HSCROLL		16	/* X axis precision scrolling */
+#define	WSCONS_EVENT_VSCROLL		17	/* Y axis precision scrolling */
 
 /*
  * Keyboard ioctls (0 - 31)
@@ -270,6 +271,28 @@ struct wsmouse_repeat {
 #define WSMOUSEIO_SETVERSION	_IOW('W', 41, int)
 #define WSMOUSE_EVENT_VERSION	WSEVENT_VERSION
 
+enum wsmousecfg {
+	WSMOUSECFG_REVERSE_SCROLLING = 0,
+	/* Touchpad parameters */
+	WSMOUSECFG_HORIZSCROLLDIST,
+	WSMOUSECFG_VERTSCROLLDIST
+};
+
+struct wsmouse_param {
+	enum wsmousecfg key;
+	int value;
+};
+
+struct wsmouse_parameters {
+	struct wsmouse_param *params;
+	unsigned int nparams;
+};
+
+#define WSMOUSECFG_MAX		(128) /* maximum number of wsmouse_params */
+
+#define WSMOUSEIO_GETPARAMS	_IOW('W', 42, struct wsmouse_parameters)
+#define WSMOUSEIO_SETPARAMS	_IOW('W', 43, struct wsmouse_parameters)
+
 /*
  * Display ioctls (64 - 95)
  */

Index: src/sys/dev/wscons/wsmouse.c
diff -u src/sys/dev/wscons/wsmouse.c:1.69 src/sys/dev/wscons/wsmouse.c:1.70
--- src/sys/dev/wscons/wsmouse.c:1.69	Sun Dec 27 16:09:33 2020
+++ src/sys/dev/wscons/wsmouse.c	Tue Sep 28 06:14:27 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: wsmouse.c,v 1.69 2020/12/27 16:09:33 tsutsui Exp $ */
+/* $NetBSD: wsmouse.c,v 1.70 2021/09/28 06:14:27 nia Exp $ */
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -104,7 +104,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.69 2020/12/27 16:09:33 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.70 2021/09/28 06:14:27 nia Exp $");
 
 #include "wsmouse.h"
 #include "wsdisplay.h"
@@ -170,6 +170,10 @@ struct wsmouse_softc {
 	int			sc_repeat_button;
 	callout_t		sc_repeat_callout;
 	unsigned int		sc_repeat_delay;
+
+	int			sc_reverse_scroll;
+	int			sc_horiz_scroll_dist;
+	int			sc_vert_scroll_dist;
 };
 
 static int  wsmouse_match(device_t, cfdata_t, void *);
@@ -177,6 +181,13 @@ static void wsmouse_attach(device_t, dev
 static int  wsmouse_detach(device_t, int);
 static int  wsmouse_activate(device_t, enum devact);
 
+static int  wsmouse_set_params(struct wsmouse_softc *,
+			       struct wsmouse_param *, size_t);
+static int  wsmouse_get_params(struct wsmouse_softc *,
+			       struct wsmouse_param *, size_t);
+static int  wsmouse_handle_params(struct wsmouse_softc *,
+				  struct wsmouse_parameters *, bool);
+
 static int  wsmouse_do_ioctl(struct wsmouse_softc *, u_long, void *,
 			     int, struct lwp *);
 
@@ -258,6 +269,9 @@ wsmouse_attach(device_t parent, device_t
 	memset(&sc->sc_repeat, 0, sizeof(sc->sc_repeat));
 	sc->sc_repeat_button = -1;
 	sc->sc_repeat_delay = 0;
+	sc->sc_reverse_scroll = 0;
+	sc->sc_horiz_scroll_dist = WSMOUSE_DEFAULT_SCROLL_DIST;
+	sc->sc_vert_scroll_dist = WSMOUSE_DEFAULT_SCROLL_DIST;
 	callout_init(&sc->sc_repeat_callout, 0);
 	callout_setfunc(&sc->sc_repeat_callout, wsmouse_repeat, sc);
 
@@ -516,6 +530,41 @@ wsmouse_input(device_t wsmousedev, u_int
 	}
 }
 
+void
+wsmouse_precision_scroll(device_t wsmousedev, int x, int y)
+{
+	struct wsmouse_softc *sc = device_private(wsmousedev);
+	struct wseventvar *evar;
+	struct wscons_event events[2];
+	int nevents = 0;
+
+	evar = sc->sc_base.me_evp;
+	if (evar == NULL)
+		return;
+
+	if (sc->sc_reverse_scroll) {
+		x = -x;
+		y = -y;
+	}
+
+	x = (x * 4096) / sc->sc_horiz_scroll_dist;
+	y = (y * 4096) / sc->sc_vert_scroll_dist;
+
+	if (x != 0) {
+		events[nevents].type = WSCONS_EVENT_HSCROLL;
+		events[nevents].value = x;
+		nevents++;
+	}
+
+	if (y != 0) {
+		events[nevents].type = WSCONS_EVENT_VSCROLL;
+		events[nevents].value = y;
+		nevents++;
+	}
+
+	(void)wsevent_inject(evar, events, nevents);
+}
+
 static void
 wsmouse_repeat(void *v)
 {
@@ -566,6 +615,88 @@ wsmouse_repeat(void *v)
 	splx(oldspl);
 }
 
+static int
+wsmouse_set_params(struct wsmouse_softc *sc,
+    struct wsmouse_param *buf, size_t nparams)
+{
+	size_t i = 0;
+
+	for (i = 0; i < nparams; ++i) {
+		switch (buf[i].key) {	
+		case WSMOUSECFG_REVERSE_SCROLLING:
+			sc->sc_reverse_scroll = (buf[i].value != 0);
+			break;
+		case WSMOUSECFG_HORIZSCROLLDIST:
+			sc->sc_horiz_scroll_dist = buf[i].value;
+			break;
+		case WSMOUSECFG_VERTSCROLLDIST:
+			sc->sc_vert_scroll_dist = buf[i].value;
+			break;
+		}
+	}
+	return 0;
+}
+
+static int
+wsmouse_get_params(struct wsmouse_softc *sc,
+    struct wsmouse_param *buf, size_t nparams)
+{
+	size_t i = 0;
+
+	for (i = 0; i < nparams; ++i) {
+		switch (buf[i].key) {	
+		case WSMOUSECFG_REVERSE_SCROLLING:
+			buf[i].value = sc->sc_reverse_scroll;
+			break;
+		case WSMOUSECFG_HORIZSCROLLDIST:
+			buf[i].value = sc->sc_horiz_scroll_dist;
+			break;
+		case WSMOUSECFG_VERTSCROLLDIST:
+			buf[i].value = sc->sc_vert_scroll_dist;
+			break;
+		}
+	}
+	return 0;
+}
+
+static int
+wsmouse_handle_params(struct wsmouse_softc *sc, struct wsmouse_parameters *upl,
+    bool set)
+{
+	size_t len;
+	struct wsmouse_param *buf;
+	int error = 0;
+
+	if (upl->params == NULL || upl->nparams > WSMOUSECFG_MAX)
+		return EINVAL;
+	if (upl->nparams == 0)
+		return 0;
+
+	len = upl->nparams * sizeof(struct wsmouse_param);
+
+	buf = kmem_alloc(len, KM_SLEEP);
+	if (buf == NULL)
+		return ENOMEM;
+	if ((error = copyin(upl->params, buf, len)) != 0)
+		goto error;
+
+	if (set) {
+		error = wsmouse_set_params(sc, buf, upl->nparams);
+		if (error != 0)
+			goto error;
+	} else {
+		error = wsmouse_get_params(sc, buf, upl->nparams);
+		if (error != 0)
+			goto error;
+		if ((error = copyout(buf, upl->params, len)) != 0)
+			goto error;
+	}
+
+error:
+	kmem_free(buf, len);
+	return error;
+}
+
 int
 wsmouseopen(dev_t dev, int flags, int mode, struct lwp *l)
 {
@@ -762,6 +893,16 @@ wsmouse_do_ioctl(struct wsmouse_softc *s
 
 	case WSMOUSEIO_SETVERSION:
 		return wsevent_setversion(sc->sc_base.me_evp, *(int *)data);
+
+	case WSMOUSEIO_GETPARAMS:
+		return wsmouse_handle_params(sc,
+		    (struct wsmouse_parameters *)data, false);
+
+	case WSMOUSEIO_SETPARAMS:
+		if ((flag & FWRITE) == 0)
+			return EACCES;
+		return wsmouse_handle_params(sc,
+		    (struct wsmouse_parameters *)data, true);
 	}
 
 	/*

Index: src/sys/dev/wscons/wsmousevar.h
diff -u src/sys/dev/wscons/wsmousevar.h:1.11 src/sys/dev/wscons/wsmousevar.h:1.12
--- src/sys/dev/wscons/wsmousevar.h:1.11	Tue May 12 14:47:55 2009
+++ src/sys/dev/wscons/wsmousevar.h	Tue Sep 28 06:14:27 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: wsmousevar.h,v 1.11 2009/05/12 14:47:55 cegger Exp $ */
+/* $NetBSD: wsmousevar.h,v 1.12 2021/09/28 06:14:27 nia Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -73,3 +73,5 @@ int	wsmousedevprint(void *, const char *
 #define WSMOUSE_INPUT_ABSOLUTE_Z	(1<<2)
 #define WSMOUSE_INPUT_ABSOLUTE_W	(1<<3)
 void	wsmouse_input(device_t, u_int, int, int, int, int, u_int);
+#define WSMOUSE_DEFAULT_SCROLL_DIST	(12)
+void	wsmouse_precision_scroll(device_t, int, int);

Reply via email to