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