> Date: Wed, 2 Mar 2011 21:23:07 +0100 (CET)
> From: Mark Kettenis <[email protected]>
> 
> This diff adds touchscreen support to ums(4).  This works great for
> newer Gunze USB touchscreens in "WHQL" mode.  That means that it is
> Microsoft approved, so it should be some sort of standard way to hook
> these things up.  Rather than hardcoding the calibration for the
> device I have (like uts(4) seems to) I make it default to raw mode.
> At least for the device that I have that isn't too far off.
> 
> ok?

Alexandr Shadchin pointed out I forgot to include hidmsvar.h in the diff.

Index: bluetooth/btms.c
===================================================================
RCS file: /cvs/src/sys/dev/bluetooth/btms.c,v
retrieving revision 1.5
diff -u -p -r1.5 btms.c
--- bluetooth/btms.c    31 Jul 2010 16:04:50 -0000      1.5
+++ bluetooth/btms.c    2 Mar 2011 22:16:20 -0000
@@ -170,13 +170,18 @@ btms_wsmouse_ioctl(void *self, u_long cm
 {
        struct btms_softc *sc = (struct btms_softc *)self;
        struct hidms *ms = &sc->sc_ms;
+       int rc;
+
+       rc = hidms_ioctl(ms, cmd, data, flag, p);
+       if (rc != -1)
+               return rc;
 
        switch (cmd) {
        case WSMOUSEIO_GTYPE:
                *(u_int *)data = WSMOUSE_TYPE_BLUETOOTH;
                return 0;
        default:
-               return hidms_ioctl(ms, cmd, data, flag, p);
+               return -1;
        }
 }
 
Index: usb/ums.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.33
diff -u -p -r1.33 ums.c
--- usb/ums.c   2 Aug 2010 23:17:34 -0000       1.33
+++ usb/ums.c   2 Mar 2011 22:16:20 -0000
@@ -227,15 +227,18 @@ ums_ioctl(void *v, u_long cmd, caddr_t d
        struct hidms *ms = &sc->sc_ms;
        int rc;
 
+       rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
+       if (rc != -1)
+               return rc;
+       rc = hidms_ioctl(ms, cmd, data, flag, p);
+       if (rc != -1)
+               return rc;
+
        switch (cmd) {
        case WSMOUSEIO_GTYPE:
                *(u_int *)data = WSMOUSE_TYPE_USB;
                return 0;
        default:
-               rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
-               if (rc != -1)
-                       return rc;
-               else
-                       return hidms_ioctl(ms, cmd, data, flag, p);
+               return -1;
        }
 }
Index: usb/hidms.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/hidms.c,v
retrieving revision 1.1
diff -u -p -r1.1 hidms.c
--- usb/hidms.c 31 Jul 2010 16:04:50 -0000      1.1
+++ usb/hidms.c 2 Mar 2011 22:16:20 -0000
@@ -63,7 +63,8 @@ int   hidmsdebug = 0;
 
 #define HIDMS_BUT(i)   ((i) == 1 || (i) == 2 ? 3 - (i) : i)
 
-#define NOTMOUSE(f)    (((f) & (HIO_CONST | HIO_RELATIVE)) != HIO_RELATIVE)
+#define MOUSE_FLAGS_MASK       (HIO_CONST | HIO_RELATIVE)
+#define NOTMOUSE(f)            (((f) & MOUSE_FLAGS_MASK) != HIO_RELATIVE)
 
 int
 hidms_setup(struct device *self, struct hidms *ms, uint32_t quirks,
@@ -73,6 +74,7 @@ hidms_setup(struct device *self, struct 
        int i, wheel, twheel;
 
        ms->sc_device = self;
+       ms->sc_rawmode = 1;
 
        if (quirks & UQ_MS_REVZ)
                ms->sc_flags |= HIDMS_REVZ;
@@ -86,7 +88,13 @@ hidms_setup(struct device *self, struct 
                printf("\n%s: mouse has no X report\n", self->dv_xname);
                return ENXIO;
        }
-       if (NOTMOUSE(flags)) {
+       switch(flags & MOUSE_FLAGS_MASK) {
+       case 0:
+               ms->sc_flags |= HIDMS_ABSX;
+               break;
+       case HIO_RELATIVE:
+               break;
+       default:
                printf("\n%s: X report 0x%04x not supported\n",
                    self->dv_xname, flags);
                return ENXIO;
@@ -97,7 +105,13 @@ hidms_setup(struct device *self, struct 
                printf("\n%s: mouse has no Y report\n", self->dv_xname);
                return ENXIO;
        }
-       if (NOTMOUSE(flags)) {
+       switch(flags & MOUSE_FLAGS_MASK) {
+       case 0:
+               ms->sc_flags |= HIDMS_ABSY;
+               break;
+       case HIO_RELATIVE:
+               break;
+       default:
                printf("\n%s: Y report 0x%04x not supported\n",
                    self->dv_xname, flags);
                return ENXIO;
@@ -225,7 +239,7 @@ hidms_attach(struct hidms *ms, const str
        printf("\n");
 
 #ifdef HIDMS_DEBUG
-       DPRINTF(("hidms_attach: sc=%p\n", sc));
+       DPRINTF(("hidms_attach: ms=%p\n", ms));
        DPRINTF(("hidms_attach: X\t%d/%d\n",
             ms->sc_loc_x.pos, ms->sc_loc_x.size));
        DPRINTF(("hidms_attach: Y\t%d/%d\n",
@@ -252,7 +266,7 @@ hidms_detach(struct hidms *ms, int flags
 {
        int rv = 0;
 
-       DPRINTF(("hidms_detach: sc=%p flags=%d\n", sc, flags));
+       DPRINTF(("hidms_detach: ms=%p flags=%d\n", ms, flags));
 
        /* No need to do reference counting of hidms, wsmouse has all the goo */
        if (ms->sc_wsmousedev != NULL)
@@ -266,6 +280,7 @@ hidms_input(struct hidms *ms, uint8_t *d
 {
        int dx, dy, dz, dw;
        u_int32_t buttons = 0;
+       int flags;
        int i, s;
 
        DPRINTFN(5,("hidms_input: len=%d\n", len));
@@ -292,16 +307,40 @@ hidms_input(struct hidms *ms, uint8_t *d
                        return;
        }
 
+       flags = WSMOUSE_INPUT_DELTA;
+       if (ms->sc_flags & HIDMS_ABSX)
+               flags |= WSMOUSE_INPUT_ABSOLUTE_X;
+       if (ms->sc_flags & HIDMS_ABSY)
+               flags |= WSMOUSE_INPUT_ABSOLUTE_Y;
+
        dx =  hid_get_data(data, &ms->sc_loc_x);
        dy = -hid_get_data(data, &ms->sc_loc_y);
        dz =  hid_get_data(data, &ms->sc_loc_z);
        dw =  hid_get_data(data, &ms->sc_loc_w);
 
+       if (ms->sc_flags & HIDMS_ABSY)
+               dy = -dy;
        if (ms->sc_flags & HIDMS_REVZ)
                dz = -dz;
        if (ms->sc_flags & HIDMS_REVW)
                dw = -dw;
 
+       if (ms->sc_tsscale.swapxy && !ms->sc_rawmode) {
+               int tmp = dx;
+               dx = dy;
+               dy = tmp;
+       }
+
+       if (!ms->sc_rawmode &&
+           (ms->sc_tsscale.maxx - ms->sc_tsscale.minx) != 0 &&
+           (ms->sc_tsscale.maxy - ms->sc_tsscale.miny) != 0) {
+               /* Scale down to the screen resolution. */
+               dx = ((dx - ms->sc_tsscale.minx) * ms->sc_tsscale.resx) /
+                   (ms->sc_tsscale.maxx - ms->sc_tsscale.minx);
+               dy = ((dy - ms->sc_tsscale.miny) * ms->sc_tsscale.resy) /
+                   (ms->sc_tsscale.maxy - ms->sc_tsscale.miny);
+       }
+
        for (i = 0; i < ms->sc_num_buttons; i++)
                if (hid_get_data(data, &ms->sc_loc_btn[i]))
                        buttons |= (1 << HIDMS_BUT(i));
@@ -314,7 +353,7 @@ hidms_input(struct hidms *ms, uint8_t *d
                if (ms->sc_wsmousedev != NULL) {
                        s = spltty();
                        wsmouse_input(ms->sc_wsmousedev, buttons,
-                           dx, dy, dz, dw, WSMOUSE_INPUT_DELTA);
+                           dx, dy, dz, dw, flags);
                        splx(s);
                }
        }
@@ -335,7 +374,47 @@ int
 hidms_ioctl(struct hidms *ms, u_long cmd, caddr_t data, int flag,
     struct proc *p)
 {
+       struct wsmouse_calibcoords *wsmc = (struct wsmouse_calibcoords *)data;
+
        switch (cmd) {
+       case WSMOUSEIO_SCALIBCOORDS:
+               if (!(wsmc->minx >= 0 && wsmc->maxx >= 0 &&
+                   wsmc->miny >= 0 && wsmc->maxy >= 0 &&
+                   wsmc->resx >= 0 && wsmc->resy >= 0 &&
+                   wsmc->minx < 32768 && wsmc->maxx < 32768 &&
+                   wsmc->miny < 32768 && wsmc->maxy < 32768 &&
+                   (wsmc->maxx - wsmc->minx) != 0 &&
+                   (wsmc->maxy - wsmc->miny) != 0 &&
+                   wsmc->resx < 32768 && wsmc->resy < 32768 &&
+                   wsmc->swapxy >= 0 && wsmc->swapxy <= 1 &&
+                   wsmc->samplelen >= 0 && wsmc->samplelen <= 1))
+                       return (EINVAL);
+
+               ms->sc_tsscale.minx = wsmc->minx;
+               ms->sc_tsscale.maxx = wsmc->maxx;
+               ms->sc_tsscale.miny = wsmc->miny;
+               ms->sc_tsscale.maxy = wsmc->maxy;
+               ms->sc_tsscale.swapxy = wsmc->swapxy;
+               ms->sc_tsscale.resx = wsmc->resx;
+               ms->sc_tsscale.resy = wsmc->resy;
+               ms->sc_rawmode = wsmc->samplelen;
+               return 0;
+       case WSMOUSEIO_GCALIBCOORDS:
+               wsmc->minx = ms->sc_tsscale.minx;
+               wsmc->maxx = ms->sc_tsscale.maxx;
+               wsmc->miny = ms->sc_tsscale.miny;
+               wsmc->maxy = ms->sc_tsscale.maxy;
+               wsmc->swapxy = ms->sc_tsscale.swapxy;
+               wsmc->resx = ms->sc_tsscale.resx;
+               wsmc->resy = ms->sc_tsscale.resy;
+               wsmc->samplelen = ms->sc_rawmode;
+               return 0;
+       case WSMOUSEIO_GTYPE:
+               if (ms->sc_flags & HIDMS_ABSX && ms->sc_flags & HIDMS_ABSY) {
+                       *(u_int *)data = WSMOUSE_TYPE_TPANEL;
+                       return 0;
+               }
+               /* FALLTHROUGH */
        default:
                return -1;
        }
Index: usb/hidmsvar.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/hidmsvar.h,v
retrieving revision 1.1
diff -u -p -r1.1 hidmsvar.h
--- usb/hidmsvar.h      31 Jul 2010 16:04:50 -0000      1.1
+++ usb/hidmsvar.h      2 Mar 2011 22:16:20 -0000
@@ -33,6 +33,13 @@
 
 #define MAX_BUTTONS    31      /* must not exceed size of sc_buttons */
 
+struct tsscale {
+       int     minx, maxx;
+       int     miny, maxy;
+       int     swapxy;
+       int     resx, resy;
+};
+
 struct hidms {
        int             sc_enabled;
        int             sc_flags;       /* device configuration */
@@ -42,6 +49,8 @@ struct hidms {
 #define HIDMS_W                        0x08    /* W direction available */
 #define HIDMS_REVW             0x10    /* W-axis is reversed */
 #define HIDMS_LEADINGBYTE      0x20    /* Unknown leading byte */
+#define HIDMS_ABSX             0x40    /* X-axis is absolute */
+#define HIDMS_ABSY             0x80    /* Y-axis is absolute */
 
        int             sc_num_buttons;
        u_int32_t       sc_buttons;     /* mouse button status */
@@ -55,6 +64,9 @@ struct hidms {
        struct hid_location sc_loc_z;
        struct hid_location sc_loc_w;
        struct hid_location sc_loc_btn[MAX_BUTTONS];
+
+       struct tsscale  sc_tsscale;
+       int             sc_rawmode;
 };
 
 void   hidms_attach(struct hidms *, const struct wsmouse_accessops *);

Reply via email to