Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/wscons wsmouse: add support for "precision scrolling...
details: https://anonhg.NetBSD.org/src/rev/8885ca9482ba
branches: trunk
changeset: 1023848:8885ca9482ba
user: nia <nia%NetBSD.org@localhost>
date: Tue Sep 28 06:14:27 2021 +0000
description:
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.
diffstat:
sys/dev/wscons/wsconsio.h | 27 +++++++-
sys/dev/wscons/wsmouse.c | 145 +++++++++++++++++++++++++++++++++++++++++++-
sys/dev/wscons/wsmousevar.h | 4 +-
3 files changed, 171 insertions(+), 5 deletions(-)
diffs (264 lines):
diff -r 41e292aa6210 -r 8885ca9482ba sys/dev/wscons/wsconsio.h
--- a/sys/dev/wscons/wsconsio.h Mon Sep 27 20:09:55 2021 +0000
+++ b/sys/dev/wscons/wsconsio.h Tue Sep 28 06:14:27 2021 +0000
@@ -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 @@
#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 @@
#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)
*/
diff -r 41e292aa6210 -r 8885ca9482ba sys/dev/wscons/wsmouse.c
--- a/sys/dev/wscons/wsmouse.c Mon Sep 27 20:09:55 2021 +0000
+++ b/sys/dev/wscons/wsmouse.c Tue Sep 28 06:14:27 2021 +0000
@@ -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 @@
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 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 @@
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 @@
}
}
+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 @@
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 @@
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);
}
/*
diff -r 41e292aa6210 -r 8885ca9482ba sys/dev/wscons/wsmousevar.h
--- a/sys/dev/wscons/wsmousevar.h Mon Sep 27 20:09:55 2021 +0000
+++ b/sys/dev/wscons/wsmousevar.h Tue Sep 28 06:14:27 2021 +0000
@@ -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 @@
#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);
Home |
Main Index |
Thread Index |
Old Index