2 * USB Human Interaction Device: keyboard and mouse.
4 * If there's no usb keyboard, it tries to setup the mouse, if any.
5 * It should be started at boot time.
7 * Mouse events are converted to the format of mouse(3)
9 * Keyboard keycodes are translated to scan codes and sent to kbdfs(8)
32 typedef struct KDev KDev;
35 Dev* dev; /* usb device*/
36 Dev* ep; /* endpoint to get events */
37 int infd; /* used to send events to kernel */
38 Channel *repeatc; /* only for keyboard */
40 /* report descriptor */
46 * Map for the logitech bluetooth mouse with 8 buttons and wheels.
48 * { 0x01, 0x01 }, // left
49 * { 0x04, 0x02 }, // middle
50 * { 0x02, 0x04 }, // right
51 * { 0x40, 0x08 }, // up
52 * { 0x80, 0x10 }, // down
53 * { 0x10, 0x08 }, // side up
54 * { 0x08, 0x10 }, // side down
55 * { 0x20, 0x02 }, // page
56 * besides wheel and regular up/down report the 4th byte as 1/-1
60 * key code to scan code; for the page table used by
61 * the logitech bluetooth keyboard.
63 static char sctab[256] =
65 [0x00] 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20,
66 [0x08] 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26,
67 [0x10] 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14,
68 [0x18] 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x2, 0x3,
69 [0x20] 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
70 [0x28] 0x1c, 0x1, 0xe, 0xf, 0x39, 0xc, 0xd, 0x1a,
71 [0x30] 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34,
72 [0x38] 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
73 [0x40] 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x63, 0x46,
74 [0x48] 0x77, 0x52, 0x47, 0x49, 0x53, 0x4f, 0x51, 0x4d,
75 [0x50] 0x4b, 0x50, 0x48, 0x45, 0x35, 0x37, 0x4a, 0x4e,
76 [0x58] 0x1c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47,
77 [0x60] 0x48, 0x49, 0x52, 0x53, 0x56, 0x7f, 0x74, 0x75,
78 [0x68] 0x55, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
79 [0x70] 0x78, 0x79, 0x7a, 0x7b, 0x0, 0x0, 0x0, 0x0,
80 [0x78] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71,
81 [0x80] 0x73, 0x72, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0,
82 [0x88] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
83 [0x90] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
84 [0x98] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
85 [0xa0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
86 [0xa8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
87 [0xb0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
88 [0xb8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
89 [0xc0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
90 [0xc8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
91 [0xd0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
92 [0xd8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
93 [0xe0] 0x1d, 0x2a, 0x38, 0x7d, 0x61, 0x36, 0x64, 0x7e,
94 [0xe8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x72, 0x71,
95 [0xf0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
96 [0xf8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
99 static uchar ptrbootrep[] = {
100 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01,
101 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
102 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
103 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
104 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38,
105 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03,
106 0x81, 0x06, 0xc0, 0x09, 0x3c, 0x15, 0x00, 0x25,
107 0x01, 0x75, 0x01, 0x95, 0x01, 0xb1, 0x22, 0x95,
108 0x07, 0xb1, 0x01, 0xc0,
114 signext(int v, int bits)
118 s = sizeof(v)*8 - bits;
125 getbits(uchar *p, uchar *e, int bits, int off)
150 UsgCnt = Delim+1, /* fake */
156 repparse1(uchar *d, uchar *e, int g[], int l[], int c,
157 void (*f)(int t, int v, int g[], int l[], int c, void *a), void *a)
170 v = d[-4] | d[-3]<<8 | d[-2]<<16 | d[-1]<<24;
175 v = d[-2] | d[-1]<<8;
184 case 0: /* main item*/
187 memset(l, 0, Nl*sizeof(l[0]));
188 d = repparse1(d, e, g, l, v, f, a);
195 if(l[UsgCnt] == 0 && l[UsagMin] != 0 && l[UsagMin] < l[UsagMax])
196 for(i=l[UsagMin]; i<=l[UsagMax] && l[UsgCnt] < Nu; i++)
197 l[Nl + l[UsgCnt]++] = i;
198 for(i=0; i<g[RepCnt]; i++){
200 l[Usage] = l[Nl + i];
201 (*f)(t, v, g, l, c, a);
205 memset(l, 0, Nl*sizeof(l[0]));
207 case 1: /* global item */
210 memmove(w, g, sizeof(w));
211 d = repparse1(d, e, w, l, c, f, a);
219 else if(t != RepSize && t != RepCnt){
220 v = signext(v, (z == 3) ? 32 : 8*z);
225 case 2: /* local item */
230 } else if(t < Delim){
231 if(z != 3 && (t == Usage || t == UsagMin || t == UsagMax))
232 v = (v & 0xFFFF) | (g[UsagPg] << 16);
234 if(t == Usage && l[UsgCnt] < Nu)
235 l[Nl + l[UsgCnt]++] = v;
238 case 3: /* long item */
248 * parse the report descriptor and call f for every (Input, Output
249 * and Feature) main item as often as it would appear in the report
253 repparse(uchar *d, uchar *e,
254 void (*f)(int t, int v, int g[], int l[], int c, void *a), void *a)
258 memset(l, 0, sizeof(l));
259 memset(g, 0, sizeof(g));
260 repparse1(d, e, g, l, 0, f, a);
264 setproto(KDev *f, int eid)
269 id = f->dev->usb->ep[eid]->iface->id;
270 if(f->dev->usb->ep[eid]->iface->csp == PtrCSP){
271 f->nrep = usbcmd(f->dev, Rd2h|Rstd|Riface, Rgetdesc, Dreport<<8, id,
272 f->rep, sizeof(f->rep));
277 fprint(2, "report descriptor:");
278 for(i = 0; i < f->nrep; i++){
281 fprint(2, "%#2.2ux ", f->rep[i]);
287 f->nrep = sizeof(ptrbootrep);
288 memmove(f->rep, ptrbootrep, f->nrep);
291 return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, id, nil, 0);
295 setleds(KDev* f, int, uchar leds)
297 return usbcmd(f->dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, &leds, 1);
301 * Try to recover from a babble error. A port reset is the only way out.
302 * BUG: we should be careful not to reset a bundle with several devices.
309 close(f->dev->dfd); /* it's for usbd now */
310 devctl(f->dev, "reset");
311 for(i = 0; i < 10; i++){
313 if(opendevdata(f->dev, ORDWR) >= 0){
314 setproto(f, f->ep->id);
317 /* else usbd still working... */
334 kbfatal(KDev *kd, char *sts)
337 fprint(2, "%s: fatal: %s\n", argv0, sts);
339 fprint(2, "%s: exiting\n", argv0);
340 if(kd->repeatc != nil)
341 sendul(kd->repeatc, Diemsg);
347 kbprocname(KDev *kd, char *name)
350 snprint(buf, sizeof(buf), "%s %s", name, kd->ep->dir);
360 snprint(fn, sizeof(fn), "/proc/%d/ctl", getpid());
361 fd = open(fn, OWRITE);
364 fprint(fd, "pri 13");
368 typedef struct Ptr Ptr;
387 ptrparse(int t, int f, int g[], int l[], int, void *a)
395 if(p->p[0] != g[RepId]){
400 p->o = 8; /* skip report id byte */
402 v = getbits(p->p, p->e, g[RepSize], p->o);
404 v = signext(v, g[RepSize]);
405 if((f & (Fvar|Farray)) == Fvar && v >= g[LogiMin] && v <= g[LogiMax]){
407 * we use logical units below, but need the
408 * sign to be correct for mouse deltas.
409 * so if physical unit is signed but logical
410 * is unsigned, convert to signed but in logical
413 if((f & (Fabs|Frel)) == Frel
414 && g[PhysMin] < 0 && g[PhysMax] > 0
415 && g[LogiMin] >= 0 && g[LogiMin] < g[LogiMax])
416 v -= (g[PhysMax] * (g[LogiMax] - g[LogiMin])) / (g[PhysMax] - g[PhysMin]);
433 if((f & (Fabs|Frel)) == Fabs){
434 p->x = (v - p->absx);
442 if((f & (Fabs|Frel)) == Fabs){
443 p->y = (v - p->absy);
451 if((f & (Fabs|Frel)) == Fabs){
452 p->z = (v - p->absz);
460 p->b |= (p->z > 0) ? 8 : 16;
476 kbprocname(f, "ptr");
479 memset(&p, 0, sizeof(p));
485 if(f->ep->maxpkt < 1 || f->ep->maxpkt > sizeof(p.p))
486 kbfatal(f, "ptr: weird mouse maxpkt");
488 memset(p.p, 0, sizeof(p.p));
489 c = read(f->ep->dfd, p.p, f->ep->maxpkt);
492 rerrstr(err, sizeof(err));
494 strcpy(err, "zero read");
496 fprint(2, "%s: ptr: %s: read: %s\n", argv0, f->ep->dir, err);
497 if(strstr(err, "babble") != 0)
507 repparse(f->rep, f->rep+f->nrep, ptrparse, &p);
509 seprint(mbuf, mbuf+sizeof(mbuf), "m%11d %11d %11d", p.x, p.y, p.b);
510 if(write(f->infd, mbuf, strlen(mbuf)) < 0)
511 kbfatal(f, "mousein i/o");
516 putscan(int fd, uchar esc, uchar sc)
518 uchar s[2] = {SCesc1, 0};
528 putmod(int fd, uchar mods, uchar omods, uchar mask, uchar esc, uchar sc)
533 if((mods&mask) && !(omods&mask)){
538 if(!(mods&mask) && (omods&mask)){
553 threadsetname("sleepproc");
554 while((ms = recvul(c)) > 0)
560 repeatproc(void* arg)
563 Channel *repeatc, *sleepc;
569 repeatc = f->repeatc;
571 threadsetname("repeatproc");
573 sleepc = chancreate(sizeof(ulong), 0);
575 proccreate(sleepproc, sleepc, Stack);
582 a[1].op = sleepc!=nil ? CHANSND : CHANNOP;
599 putscan(kbdinfd, esc1, sc);
611 sendul(f->repeatc, Awakemsg);
615 startrepeat(KDev *f, uchar esc1, uchar sc)
620 c = SCesc1 << 8 | (sc & 0xff);
623 sendul(f->repeatc, c);
626 #define hasesc1(sc) (((sc) > 0x47) || ((sc) == 0x38))
629 * This routine diffs the state with the last known state
630 * and invents the scan codes that would have been sent
631 * by a non-usb keyboard in that case. This also requires supplying
632 * the extra esc1 byte as well as keyup flags.
633 * The aim is to allow future addition of other keycode pages
634 * for other keyboards.
637 putkeys(KDev *f, uchar buf[], uchar obuf[], int n, uchar dk)
644 putmod(fd, buf[0], obuf[0], Mctrl, 0, SCctrl);
645 putmod(fd, buf[0], obuf[0], (1<<Mlshift), 0, SClshift);
646 putmod(fd, buf[0], obuf[0], (1<<Mrshift), 0, SCrshift);
647 putmod(fd, buf[0], obuf[0], Mcompose, 0, SCcompose);
648 putmod(fd, buf[0], obuf[0], Maltgr, 1, SCcompose);
650 /* Report key downs */
651 for(i = 2; i < n; i++){
652 for(j = 2; j < n; j++)
653 if(buf[i] == obuf[j])
655 if(j == n && buf[i] != 0){
657 putscan(fd, hasesc1(dk), dk);
658 startrepeat(f, hasesc1(dk), dk);
664 for(i = 2; i < n; i++){
665 for(j = 2; j < n; j++)
666 if(obuf[i] == buf[j])
668 if(j == n && obuf[i] != 0){
670 putscan(fd, hasesc1(uk), uk|Keyup);
673 if(uk && (dk == 0 || dk == uk)){
681 kbdbusy(uchar* buf, int n)
685 for(i = 1; i < n; i++)
686 if(buf[i] == 0 || buf[i] != buf[0])
694 uchar dk, buf[64], lbuf[64];
699 kbprocname(f, "kbd");
701 f->repeatc = chancreate(sizeof(ulong), 0);
702 if(f->repeatc == nil)
703 kbfatal(f, "chancreate failed");
704 proccreate(repeatproc, f, Stack);
706 setleds(f, f->ep->id, 0);
709 memset(lbuf, 0, sizeof lbuf);
714 if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf)
715 kbfatal(f, "kbd: weird maxpkt");
716 memset(buf, 0, sizeof buf);
717 c = read(f->ep->dfd, buf, f->ep->maxpkt);
720 rerrstr(err, sizeof(err));
722 strcpy(err, "zero read");
724 fprint(2, "%s: kbd: %s: read: %s\n", argv0, f->ep->dir, err);
725 if(strstr(err, "babble") != 0)
734 if(kbdbusy(buf + 2, c - 2))
736 if(usbdebug > 2 || debug > 1){
737 fprint(2, "kbd mod %x: ", buf[0]);
738 for(i = 2; i < c; i++)
739 fprint(2, "kc %x ", buf[i]);
742 dk = putkeys(f, buf, lbuf, f->ep->maxpkt, dk);
743 memmove(lbuf, buf, c);
748 kbstart(Dev *d, Ep *ep, char *infile, void (*f)(void*))
752 kd = emallocz(sizeof(KDev), 1);
753 kd->infd = open(infile, OWRITE);
755 fprint(2, "%s: %s: open: %r\n", argv0, d->dir);
760 if(setproto(kd, ep->id) < 0){
761 fprint(2, "%s: %s: setproto: %r\n", argv0, d->dir);
764 kd->ep = openep(kd->dev, ep->id);
766 fprint(2, "%s: %s: openep %d: %r\n", argv0, d->dir, ep->id);
769 if(opendevdata(kd->ep, OREAD) < 0){
770 fprint(2, "%s: %s: opendevdata: %r\n", argv0, kd->ep->dir);
773 procrfork(f, kd, Stack, RFNOTEG);
782 fprint(2, "usage: %s [-d] [-a n] devid\n", argv0);
783 threadexits("usage");
787 threadmain(int argc, char* argv[])
805 d = getdev(atoi(*argv));
807 sysfatal("getdev: %r");
809 for(i = 0; i < nelem(ud->ep); i++){
810 if((ep = ud->ep[i]) == nil)
812 if(ep->type == Eintr && ep->dir == Ein && ep->iface->csp == KbdCSP)
813 kbstart(d, ep, "/dev/kbin", kbdwork);
814 if(ep->type == Eintr && ep->dir == Ein && ep->iface->csp == PtrCSP)
815 kbstart(d, ep, "/dev/mousein", ptrwork);