diff 86e3e0791c239bbaaece242cf78fa56794b58a72 uncommitted --- a/sys/src/cmd/nusb/kb/hid.h +++ b/sys/src/cmd/nusb/kb/hid.h @@ -24,7 +24,8 @@ Reportproto = 1, /* protocols for SET_REPORT request */ - Reportout = 0x0200, + Reportout = 0x0200, + Reportfeature = 0x0300, }; /* --- a/sys/src/cmd/nusb/kb/kb.c +++ b/sys/src/cmd/nusb/kb/kb.c @@ -68,6 +68,8 @@ int y; int z; + int pr; /* stylus pressure */ + int b; int m; @@ -657,6 +659,12 @@ s->abs |= 4; s->z = v; break; + case 0x0D0030: /* Tip Pressure */ + if((f & (Fabs|Frel)) == Fabs){ + v = ((vlong)(v - g[LogiMin]) << 31) / (g[LogiMax] - g[LogiMin]); + s->pr = v; + } + break; } s->valid = 1; } @@ -687,13 +695,17 @@ return nil; } +enum { + PrThreshold = (int)(((vlong)1<<31)/20), /* 5% of max int */ +}; + static void readerproc(void* a) { char err[ERRMAX], mbuf[80]; ushort lastk[Nkey], uks[Nkey], dks[Nkey], nuks, ndks; - int i, c, bpress, lastb, nlastk, stopped; - int abs, x, y, z, b; + int i, c, bpress, lastb, nlastk, stopped, prbias; + int abs, x, y, z, b, pr; Hidreport p; Hidslot lasts[nelem(p.s)], *s, *l; Hiddev *f = a; @@ -704,6 +716,7 @@ memset(&p, 0, sizeof(p)); memset(lasts, 0, sizeof(lasts)); lastb = nlastk = 0; + prbias = -1; for(;;){ if(f->ep == nil) @@ -789,8 +802,10 @@ } /* handle mouse/touchpad */ - if(p.ns == 0) + if(p.ns == 0){ + prbias = -1; /* reset pressure baseline */ continue; + } /* combine all the slots */ bpress = abs = x = y = z = b = 0; @@ -829,6 +844,15 @@ b |= 4; bpress |= s->m; + /* stylus pressure */ + pr = s->pr; + if(prbias < 0 || pr < prbias) + prbias = pr; + bpress |= 1; + if(pr - prbias > PrThreshold){ + b |= 1; + } + /* X/Y are absolute? */ if((s->abs & 3) == 3){ /* ignore absolute position when nothing changed */ @@ -928,6 +952,59 @@ } static void +wacommte450(Hiddev *f) +{ + static uchar descr[] = { + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x01, /* Usage (Digitizer), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x02, /* Report ID (2), */ + 0x09, 0x20, /* Usage (Stylus), */ + 0xA0, /* Collection (Physical), */ + 0x75, 0x04, /* Report Size (4), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x14, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x09, 0x32, /* Usage (In Range), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x03, /* Report Size (3), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0xA4, /* Push, */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x65, 0x13, /* Unit (Inch), */ + 0x55, 0xFD, /* Unit Exponent (-3), */ + 0x75, 0x10, /* Report Size (16), */ + 0x95, 0x01, /* Report Count (1), */ + 0x09, 0x30, /* Usage (X), */ + 0x26, 0xA8, 0x39, /* Logical Maximum, */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x31, /* Usage (Y), */ + 0x26, 0x09, 0x24, /* Logical Maximum, */ + 0x81, 0x02, /* Input (Variable), */ + 0xB4, /* Pop, */ + 0x09, 0x30, /* Usage (Tip Pressure), */ + 0x75, 0x10, /* Report Size (16), */ + 0x26, 0xFF, 0x01, /* Logical Maximum, */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0xC0 /* End Collection */ + }; + static uchar req[] = { 0x02, 0x02 }; + Dev *d = f->dev; + + /* switch to mode 2 */ + if(usbcmd(d, Rh2d|Rclass|Riface, Setreport, Reportfeature|0x02, 0, req, sizeof(req)) < 0) + hdfatal(f, "failed to initialize wacom mte-450"); + + /* override report descriptor */ + memmove(f->rep, descr, f->nrep = sizeof(descr)); +} + +static void quirks(Hiddev *f) { Dev *d; @@ -956,6 +1033,11 @@ f->rep[13] = 8; f->rep[21] = 8; f->rep[31] = 0; + return; + } + + if(d->usb->vid == 0x056a && d->usb->did == 0x0065){ + wacommte450(f); return; } }