Touchscreen support for ums(4)

2011-03-02 Thread Mark Kettenis
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)

2011-03-02 Thread Mark Kettenis
 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