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