NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/46394 wsmouse button remapping
The following reply was made to PR kern/46394; it has been noted by GNATS.
From: Nat Sloss <nathanialsloss%yahoo.com.au@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/46394 wsmouse button remapping
Date: Sun, 15 Sep 2013 16:55:41 +1000
Hi I have a new set of patches for wsmouse button remapping.
These implement wsconsctl button remapping commands.
Usage:
wsconsctl -f /dev/wsmouse0 -m -w buttonmap=1,0
To reverse buttons for left handed people.
wsconctl -d /dev/wsmouse0 -m -w buttonmap=0,0,0
To make all buttons a left click.
wsconsctl -d /dev/wsmouse0 -m -w buttonmap=0,-1,-1
To disable right and middle buttons.
Index: sys/dev/wscons/wsconsio.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsconsio.h,v
retrieving revision 1.108
diff -u -r1.108 wsconsio.h
--- sys/dev/wscons/wsconsio.h 29 Apr 2013 13:39:47 -0000 1.108
+++ sys/dev/wscons/wsconsio.h 15 Sep 2013 07:11:51 -0000
@@ -268,6 +268,10 @@
#define WSMOUSEIO_SETVERSION _IOW('W', 41, int)
#define WSMOUSE_EVENT_VERSION WSEVENT_VERSION
+#define NBUTTONS (int)(sizeof(u_int) * 8)
+#define WSMOUSEIO_GETMAPBUTTONS _IOR('W', 43, int[NBUTTONS])
+#define WSMOUSEIO_SETMAPBUTTONS _IOW('W', 44, int[NBUTTONS])
+
/*
* Display ioctls (64 - 95)
*/
Index: sys/dev/wscons/wsmouse.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.64
diff -u -r1.64 wsmouse.c
--- sys/dev/wscons/wsmouse.c 11 Sep 2011 22:28:21 -0000 1.64
+++ sys/dev/wscons/wsmouse.c 15 Sep 2013 07:13:39 -0000
@@ -162,6 +162,8 @@
int sc_z; /* absolute-z */
int sc_w; /* absolute-w */
+ int sc_buttonMap[NBUTTONS]; /* button mappings */
+
int sc_refcnt;
u_char sc_dying; /* device is being detached */
@@ -192,6 +194,7 @@
wsmouse_match, wsmouse_attach, wsmouse_detach, wsmouse_activate);
static void wsmouse_repeat(void *v);
+static int buttonRemap(struct wsmouse_softc *, int);
extern struct cfdriver wsmouse_cd;
@@ -237,6 +240,7 @@
{
struct wsmouse_softc *sc = device_private(self);
struct wsmousedev_attach_args *ap = aux;
+ int i;
#if NWSMUX > 0
int mux, error;
#endif
@@ -272,6 +276,11 @@
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
+
+ /* Initialize button mappings 1:1 */
+ for (i = 0; i < NBUTTONS; i++)
+ sc->sc_buttonMap[i] = i;
+
}
int
@@ -339,6 +348,23 @@
return (0);
}
+static int
+buttonRemap(struct wsmouse_softc *sc, int buttons)
+{
+ int buttonState, mappedButtons, i;
+
+ buttonState = buttons;
+ mappedButtons = 0;
+
+ for (i = 0; i < NBUTTONS; i++) {
+ if ((buttonState & 1) && (sc->sc_buttonMap[i] >= 0))
+ mappedButtons |= 1 << sc->sc_buttonMap[i];
+ buttonState >>= 1;
+ }
+
+ return mappedButtons;
+}
+
void
wsmouse_input(device_t wsmousedev, u_int btns /* 0 is up */,
int x, int y, int z, int w, u_int flags)
@@ -369,7 +395,7 @@
sc->sc_base.me_parent, evar));
#endif
- sc->sc_mb = btns;
+ sc->sc_mb = buttonRemap(sc, btns);
if (!(flags & WSMOUSE_INPUT_ABSOLUTE_X))
sc->sc_dx += x;
if (!(flags & WSMOUSE_INPUT_ABSOLUTE_Y))
@@ -687,8 +713,9 @@
wsmouse_do_ioctl(struct wsmouse_softc *sc, u_long cmd, void *data,
int flag, struct lwp *l)
{
- int error;
+ int error, i;
struct wsmouse_repeat *wr;
+ int tmpButtonMap[NBUTTONS];
if (sc->sc_dying)
return (EIO);
@@ -751,6 +778,25 @@
return 0;
+ case WSMOUSEIO_GETMAPBUTTONS:
+ memcpy(data, &sc->sc_buttonMap, sizeof(sc->sc_buttonMap));
+ return 0;
+
+ case WSMOUSEIO_SETMAPBUTTONS:
+ if ((flag & FWRITE) == 0)
+ return EACCES;
+
+ /* Verify button mappings. */
+ memcpy(&tmpButtonMap, data, sizeof(tmpButtonMap));
+ for (i = 0; i < NBUTTONS; i++) {
+ if (tmpButtonMap[i] < -1 || tmpButtonMap[i] >= NBUTTONS)
+ return EINVAL;
+
+ }
+
+ memcpy(&sc->sc_buttonMap, data, sizeof(sc->sc_buttonMap));
+ return 0;
+
case WSMOUSEIO_SETVERSION:
return wsevent_setversion(sc->sc_base.me_evp, *(int *)data);
}
Index: sbin/wsconsctl/mouse.c
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/mouse.c,v
retrieving revision 1.10
diff -u -r1.10 mouse.c
--- sbin/wsconsctl/mouse.c 24 Dec 2012 01:29:20 -0000 1.10
+++ sbin/wsconsctl/mouse.c 15 Sep 2013 07:13:58 -0000
@@ -47,6 +47,7 @@
static int samplerate;
static struct wsmouse_calibcoords calibration;
static char *calibration_samples;
+static char *buttonMapString;
static struct wsmouse_repeat repeat;
static void mouse_get_calibration(int);
@@ -55,6 +56,9 @@
static void mouse_get_repeat(int);
static void mouse_put_repeat(int);
+static void mouse_get_button_map(int);
+static void mouse_put_button_map(int);
+
struct field mouse_field_tab[] = {
{ "resolution", &resolution, FMT_UINT, FLG_WRONLY },
{ "samplerate", &samplerate, FMT_UINT, FLG_WRONLY },
@@ -77,6 +81,8 @@
FMT_UINT, FLG_MODIFY },
{ "repeat.delay.minimum", &repeat.wr_delay_minimum,
FMT_UINT, FLG_MODIFY },
+ { "buttonmap", &buttonMapString,
+ FMT_STRING, FLG_MODIFY },
};
int mouse_field_tab_len = sizeof(mouse_field_tab)/
@@ -102,6 +108,9 @@
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_GET ||
field_by_value(&repeat.wr_delay_minimum)->flags & FLG_GET)
mouse_get_repeat(fd);
+
+ if (field_by_value(&buttonMapString)->flags & FLG_GET)
+ mouse_get_button_map(fd);
}
static void
@@ -157,6 +166,34 @@
}
static void
+mouse_get_button_map(int fd)
+{
+ int tmp[NBUTTONS];
+ char *tmpButtonMapString;
+ char buf[5];
+ int i;
+
+ tmpButtonMapString = malloc((4 * NBUTTONS) + 1);
+
+ if (tmpButtonMapString == NULL)
+ err(EXIT_FAILURE, "could not list button mappings");
+ tmpButtonMapString[0] = '\0';
+
+ if (ioctl(fd, WSMOUSEIO_GETMAPBUTTONS, &tmp) < 0) {
+ return;
+ }
+
+ for (i = 0; i < NBUTTONS; i++) {
+ if ( i == NBUTTONS - 1)
+ snprintf(buf, sizeof(buf), "%d", tmp[i]);
+ else
+ snprintf(buf, sizeof(buf), "%d,", tmp[i]);
+ strcat(tmpButtonMapString, buf);
+ }
+ buttonMapString = tmpButtonMapString;
+}
+
+static void
mouse_get_repeat(int fd)
{
struct wsmouse_repeat tmp;
@@ -205,6 +242,9 @@
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET ||
field_by_value(&repeat.wr_delay_minimum)->flags & FLG_SET)
mouse_put_repeat(fd);
+
+ if (field_by_value(&buttonMapString)->flags & FLG_SET)
+ mouse_put_button_map(fd);
}
static void
@@ -272,6 +312,41 @@
}
static void
+mouse_put_button_map(int fd)
+{
+ int tmp[NBUTTONS];
+ int i;
+ const char *p;
+ char *q;
+
+ for (i = 0; i < NBUTTONS; i++)
+ tmp[i] = i;
+
+ if (field_by_value(&buttonMapString)->flags & FLG_SET) {
+ p = buttonMapString;
+ for (i = 0; p[0] != '\0' && i < NBUTTONS; i++) {
+ tmp[i] = strtol(p, &q, 0);
+ if (*q != ',') {
+ p = q;
+ break;
+ }
+ p = q + 1;
+ }
+ if (p[0] != '\0')
+ errx(EXIT_FAILURE, "%s: invalid button mappings",
+ buttonMapString);
+ }
+
+ /* Set new values for button mappings. */
+ if (ioctl(fd, WSMOUSEIO_SETMAPBUTTONS, &tmp) < 0)
+ err(EXIT_FAILURE, "WSMOUSEIO_SETMAPBUTTONS");
+
+ /* Now print what changed. */
+ if (field_by_value(&buttonMapString)->flags & FLG_SET)
+ pr_field(field_by_value(&buttonMapString), " -> ");
+}
+
+static void
mouse_put_repeat(int fd)
{
struct wsmouse_repeat tmp;
Regards,
Nat.
Home |
Main Index |
Thread Index |
Old Index