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?

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 20:14:37 -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/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 20:14:37 -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: 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 20:14:37 -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;
        }
 }

Reply via email to