Touchscreen support for ums(4)
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 - 1.1 +++ usb/hidms.c 2 Mar 2011 20:14:37 - @@ -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
Re: Touchscreen support for ums(4)
Date: Wed, 2 Mar 2011 21:23:07 +0100 (CET) From: Mark Kettenis mark.kette...@xs4all.nl 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.c31 Jul 2010 16:04:50 - 1.5 +++ bluetooth/btms.c2 Mar 2011 22:16:20 - @@ -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 - 1.33 +++ usb/ums.c 2 Mar 2011 22:16:20 - @@ -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 - 1.1 +++ usb/hidms.c 2 Mar 2011 22:16:20 - @@ -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