Sync with rev 1.63 of NetBSD's ums.c:

If a mouse has both a wheel and a Z direction we report both.
     XXX Due to tradition the wheel is reported as the Z direction (and the Z
     direction as W).
     Now Apple's Mighty Mouse is fully supported, except the X11 mouse driver
     doesn't know what to do with the new coordinate.

MFC after:   3 months

Approved by:   njl (mentor), imp
This commit is contained in:
Rui Paulo 2007-12-26 14:31:16 +00:00
parent 9f58348801
commit 12b98c52dd

View File

@ -96,7 +96,7 @@ struct ums_softc {
u_char *sc_ibuf;
u_int8_t sc_iid;
int sc_isize;
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t;
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t, sc_loc_w;
struct hid_location *sc_loc_btn;
struct callout callout_handle; /* for spurious button ups */
@ -108,6 +108,7 @@ struct ums_softc {
#define UMS_Z 0x01 /* z direction available */
#define UMS_SPUR_BUT_UP 0x02 /* spurious button up events */
#define UMS_T 0x04 /* aa direction available (tilt) */
#define UMS_REVZ 0x08 /* Z-axis is reversed */
int nbuttons;
#define MAX_BUTTONS 31 /* chosen because sc_buttons is int */
@ -220,7 +221,7 @@ ums_attach(device_t self)
void *desc;
usbd_status err;
u_int32_t flags;
int i;
int i, wheel;
struct hid_location loc_btn;
sc->sc_disconnected = 1;
@ -276,14 +277,44 @@ ums_attach(device_t self)
return ENXIO;
}
/* try to guess the Z activator: first check Z, then WHEEL */
if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
hid_input, &sc->sc_loc_z, &flags) ||
hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
hid_input, &sc->sc_loc_z, &flags) ||
hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
hid_input, &sc->sc_loc_z, &flags)) {
/* Try the wheel first as the Z activator since it's tradition. */
wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
HUG_WHEEL),
hid_input, &sc->sc_loc_z, &flags);
if (wheel) {
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
printf("\n%s: Wheel report 0x%04x not supported\n",
device_get_nameunit(sc->sc_dev), flags);
sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
} else {
sc->flags |= UMS_Z;
if (usbd_get_quirks(uaa->device)->uq_flags &
UQ_MS_REVZ) {
/* Some wheels need the Z axis reversed. */
sc->flags |= UMS_REVZ;
}
}
/*
* We might have both a wheel and Z direction, if so put
* put the Z on the W coordinate.
*/
if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
HUG_Z),
hid_input, &sc->sc_loc_w, &flags)) {
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
printf("\n%s: Z report 0x%04x not supported\n",
device_get_nameunit(sc->sc_dev), flags);
sc->sc_loc_w.size = 0; /* Bad Z, ignore */
}
}
} else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
HUG_Z),
hid_input, &sc->sc_loc_z, &flags)) {
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
printf("\n%s: Z report 0x%04x not supported\n",
device_get_nameunit(sc->sc_dev), flags);
sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
} else {
sc->flags |= UMS_Z;
@ -449,7 +480,7 @@ ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
struct ums_softc *sc = addr;
u_char *ibuf;
int dx, dy, dz, dt;
int dx, dy, dz, dw, dt;
int buttons = 0;
int i;
@ -507,6 +538,9 @@ ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
dx = hid_get_data(ibuf, &sc->sc_loc_x);
dy = -hid_get_data(ibuf, &sc->sc_loc_y);
dz = -hid_get_data(ibuf, &sc->sc_loc_z);
dw = hid_get_data(ibuf, &sc->sc_loc_w);
if (sc->flags & UMS_REVZ)
dz = -dz;
if (sc->flags & UMS_T)
dt = -hid_get_data(ibuf, &sc->sc_loc_t);
else
@ -515,16 +549,17 @@ ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
buttons |= (1 << UMS_BUT(i));
if (dx || dy || dz || dt || (sc->flags & UMS_Z)
if (dx || dy || dz || dt || dw || (sc->flags & UMS_Z)
|| buttons != sc->status.button) {
DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d t:%d buttons:0x%x\n",
dx, dy, dz, dt, buttons));
DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d w:%d t:%d buttons:0x%x\n",
dx, dy, dz, dw, dt, buttons));
sc->status.button = buttons;
sc->status.dx += dx;
sc->status.dy += dy;
sc->status.dz += dz;
/* sc->status.dt += dt;*/ /* no way to export this yet */
/* sc->status.dt += dt; */ /* no way to export this yet */
/* sc->status.dw += dw; */ /* idem */
/* Discard data in case of full buffer */
if (sc->qcount == sizeof(sc->qbuf)) {