X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2Fcmd%2Faux%2Fkbdfs%2Fkbdfs.c;h=c4dd3362a9ad30c5d3dd7e335c708e120f96297f;hb=4ed396d438554c2dea8521b0e5a7ee51826d4125;hp=7373ef1b08caf4178d48950c150db4b8d7ceeb96;hpb=663aff7fb2394784e4d5565f57f84a43d69115b9;p=plan9front.git diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c index 7373ef1b0..c4dd3362a 100644 --- a/sys/src/cmd/aux/kbdfs/kbdfs.c +++ b/sys/src/cmd/aux/kbdfs/kbdfs.c @@ -89,15 +89,20 @@ char Ewalk[] = "walk in non directory"; char Ephase[] = "the front fell off"; char Eintr[] = "interrupted"; -int scanfd; -int ledsfd; -int consfd; -int mctlfd; -int notefd; +int kbdifd = -1; +int scanfd = -1; +int ledsfd = -1; +int consfd = -1; +int mctlfd = -1; +int msinfd = -1; +int notefd = -1; +int killfd = -1; int kbdopen; int consctlopen; int quiet = 0; +char *sname = nil; +char *mntpt = "/dev"; int debug; @@ -113,6 +118,7 @@ Channel *runechan; /* chan(Rune) */ Channel *conschan; /* chan(char*) */ Channel *kbdchan; /* chan(char*) */ +Channel *intchan; /* chan(int) */ /* * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard. @@ -155,7 +161,7 @@ Rune kbtabshift[Nscan] = [0x60] 0, 0, 0, 0, 0, 0, 0, 0, [0x68] 0, 0, 0, 0, 0, 0, 0, 0, [0x70] 0, 0, 0, 0, 0, 0, 0, 0, -[0x78] 0, Kup, 0, Kup, 0, 0, 0, 0, +[0x78] 0, Kdown, 0, Kup, 0, 0, 0, 0, }; Rune kbtabesc1[Nscan] = @@ -178,6 +184,46 @@ Rune kbtabesc1[Nscan] = [0x78] 0, Kup, 0, 0, 0, 0, 0, 0, }; +Rune kbtabshiftesc1[Nscan] = +{ +[0x00] 0, 0, 0, 0, 0, 0, 0, 0, +[0x08] 0, 0, 0, 0, 0, 0, 0, 0, +[0x10] 0, 0, 0, 0, 0, 0, 0, 0, +[0x18] 0, 0, 0, 0, 0, 0, 0, 0, +[0x20] 0, 0, 0, 0, 0, 0, 0, 0, +[0x28] 0, 0, 0, 0, 0, 0, 0, 0, +[0x30] 0, 0, 0, 0, 0, 0, 0, 0, +[0x38] 0, 0, 0, 0, 0, 0, 0, 0, +[0x40] 0, 0, 0, 0, 0, 0, 0, 0, +[0x48] Kup, 0, 0, 0, 0, 0, 0, 0, +[0x50] 0, 0, 0, 0, 0, 0, 0, 0, +[0x58] 0, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kup, 0, 0, 0, 0, 0, 0, +}; + +Rune kbtabctrlesc1[Nscan] = +{ +[0x00] 0, 0, 0, 0, 0, 0, 0, 0, +[0x08] 0, 0, 0, 0, 0, 0, 0, 0, +[0x10] 0, 0, 0, 0, 0, 0, 0, 0, +[0x18] 0, 0, 0, 0, 0, 0, 0, 0, +[0x20] 0, 0, 0, 0, 0, 0, 0, 0, +[0x28] 0, 0, 0, 0, 0, 0, 0, 0, +[0x30] 0, 0, 0, 0, 0, 0, 0, 0, +[0x38] 0, 0, 0, 0, 0, 0, 0, 0, +[0x40] 0, 0, 0, 0, 0, 0, 0, 0, +[0x48] Kup, 0, 0, 0, 0, 0, 0, 0, +[0x50] 0, 0, 0, 0, 0, 0, 0, 0, +[0x58] 0, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, Kup, 0, 0, 0, 0, 0, 0, +}; + Rune kbtabaltgr[Nscan] = { [0x00] 0, 0, 0, 0, 0, 0, 0, 0, @@ -218,7 +264,69 @@ Rune kbtabctl[Nscan] = [0x78] 0, '', 0, '\b', 0, 0, 0, 0, }; -void reboot(void); +Rune kbtabshiftaltgr[Nscan] = +{ +[0x00] 0, 0, 0, 0, 0, 0, 0, 0, +[0x08] 0, 0, 0, 0, 0, 0, 0, 0, +[0x10] 0, 0, 0, 0, 0, 0, 0, 0, +[0x18] 0, 0, 0, 0, 0, 0, 0, 0, +[0x20] 0, 0, 0, 0, 0, 0, 0, 0, +[0x28] 0, 0, 0, 0, 0, 0, 0, 0, +[0x30] 0, 0, 0, 0, 0, 0, 0, 0, +[0x38] 0, 0, 0, 0, 0, 0, 0, 0, +[0x40] 0, 0, 0, 0, 0, 0, 0, 0, +[0x48] 0, 0, 0, 0, 0, 0, 0, 0, +[0x50] 0, 0, 0, 0, 0, 0, 0, 0, +[0x58] 0, 0, 0, 0, 0, 0, 0, 0, +[0x60] 0, 0, 0, 0, 0, 0, 0, 0, +[0x68] 0, 0, 0, 0, 0, 0, 0, 0, +[0x70] 0, 0, 0, 0, 0, 0, 0, 0, +[0x78] 0, 0, 0, 0, 0, 0, 0, 0, +}; + +char* +dev(char *file) +{ + static char *buf = nil; + free(buf); + buf = smprint("%s/%s", mntpt, file); + return buf; +} + +int +eopen(char *name, int mode) +{ + int fd; + + fd = open(name, mode); + if(fd < 0 && !quiet) + fprint(2, "%s: warning: can't open %s: %r\n", argv0, name); + return fd; +} + +void +reboot(void) +{ + int fd; + + if(debug) + return; + + if((fd = eopen(dev("reboot"), OWRITE)) < 0) + return; + fprint(fd, "reboot\n"); + close(fd); +} + +void +shutdown(void) +{ + if(notefd >= 0) + write(notefd, "hangup", 6); + if(killfd >= 0) + write(killfd, "hangup", 6); + threadexitsall(nil); +} /* * Scan code processing @@ -249,8 +357,18 @@ kbdputsc(Scan *scan, int c) if(c >= Nscan) return; - if(scan->esc1) + /* qemu workarround: emulate e0 for numpad */ + if(c != 0 && strchr("GHIKMOPQRS", c) != nil) + scan->esc1 |= !scan->num; + + if(scan->esc1 && scan->ctl && kbtabctrlesc1[c] != 0) + key.r = kbtabctrlesc1[c]; + else if(scan->esc1 && scan->shift && kbtabshiftesc1[c] != 0) + key.r = kbtabshiftesc1[c]; + else if(scan->esc1) key.r = kbtabesc1[c]; + else if(scan->shift && scan->altgr && kbtabshiftaltgr[c] != 0) + key.r = kbtabshiftaltgr[c]; else if(scan->shift) key.r = kbtabshift[c]; else if(scan->altgr) @@ -297,6 +415,81 @@ kbdputsc(Scan *scan, int c) scan->esc1 = 0; } +static void +kbdin(Scan *a, char *p, int n) +{ + char *s; + Key k; + int i; + + if(n > 0 && p[n-1] != 0){ + /* + * old format as used by bitsy keyboard: + * just a string of characters, no keyup + * information. + */ + s = emalloc9p(n+1); + memmove(s, p, n); + s[n] = 0; + p = s; + while(*p){ + p += chartorune(&k.r, p); + if(k.r) + send(rawchan, &k.r); + } + free(s); + return; + } +Nextmsg: + if(n < 2) + return; + switch(p[0]){ + case 'R': + case 'r': + /* rune up/down */ + chartorune(&k.r, p+1); + if(k.r == 0) + break; + k.b = k.r; + k.down = (p[0] == 'r'); + /* + * assign button according to keymap. + */ + for(i=0; ishift && kbtabshift[i] == k.r) || (kbtab[i] == k.r)){ + if(kbtab[i]) + k.b = kbtab[i]; + break; + } + } + send(keychan, &k); + if(k.r == Kshift) + a->shift = k.down; + else if(k.r == Kaltgr) + a->altgr = k.down; + else if(k.r == Kctl) + a->ctl = k.down; + break; + + case 'c': + chartorune(&k.r, p+1); + nbsend(runechan, &k.r); + break; + + default: + if(!kbdopen) + break; + i = strlen(p)+1; + s = emalloc9p(i); + memmove(s, p, i); + if(nbsendp(kbdchan, s) <= 0) + free(s); + } + i = strlen(p)+1; + n -= i, p += i; + goto Nextmsg; +} + void setleds(Scan *scan, int leds) { @@ -328,6 +521,24 @@ scanproc(void *) kbdputsc(&scan, buf[i]); setleds(&scan, (scan.num<<1) | (scan.caps<<2)); } + + shutdown(); +} + +void +kbdiproc(void *) +{ + char buf[1024]; + Scan scan; + int n; + + threadsetname("kbdiproc"); + + memset(&scan, 0, sizeof scan); + while((n = read(kbdifd, buf, sizeof buf)) > 0) + kbdin(&scan, buf, n); + + shutdown(); } char* @@ -353,13 +564,24 @@ keyproc(void *) { Rune rb[Nscan+1]; Key key; - int i, nb; + int i, nb, mouseb; char *s; threadsetname("keyproc"); nb = 0; + mouseb = 0; while(recv(keychan, &key) > 0){ + if(msinfd >= 0 && key.r >= Kmouse+1 && key.r <= Kmouse+5){ + i = 1<<(key.r-(Kmouse+1)); + if(key.down) + mouseb |= i; + else + mouseb &= ~i; + fprint(msinfd, "m%11d %11d %11d", 0, 0, mouseb); + continue; /* ignored when mapped to mouse button */ + } + rb[0] = 0; for(i=0; i= '0' && rr <= '9') - r |= (rr - '0'); + r = (r << 4) | (rr - '0'); else if(rr >= 'a' && rr <= 'f') - r |= 10 + (rr - 'a'); + r = (r << 4) | (10 + (rr - 'a')); else if(rr >= 'A' && rr <= 'F') - r |= 10 + (rr - 'A'); + r = (r << 4) | (10 + (rr - 'A')); else break; - } - if(i == 4 && r) + } while(--i > 0); + if((i == 0 || rr == ';') && r != 0 && r <= Runemax) goto Forward; } else { if(nextrune(rawchan, &rr)) @@ -543,6 +767,21 @@ Forward: } } +/* + * Need to do this in a separate proc because if process we're interrupting + * is dying and trying to print tombstone, kernel is blocked holding p->debug lock. + */ +void +intrproc(void *) +{ + threadsetname("intrproc"); + + for(;;){ + if(recv(intchan, nil) > 0) + write(notefd, "interrupt", 9); + } +} + /* * Cook lines for cons */ @@ -565,9 +804,8 @@ lineproc(void *aux) recv(cook, &r); switch(r){ case Kdel: - if(notefd < 0) + if(nbsend(intchan, ¬efd) <= 0) continue; - write(notefd, "interrupt", 9); /* no break */ case '\0': /* flush */ nr = 0; @@ -613,10 +851,11 @@ reqproc(void *aux) Channel **ac; Req *r, *q, **qq; char *s, *p, *e; - int n; + int n, m; threadsetname("reqproc"); + e = nil; s = nil; p = nil; @@ -634,7 +873,7 @@ reqproc(void *aux) a[AEND].op = CHANEND; for(;;){ - a[ASTR].op = s ? CHANNOP : CHANRCV; + a[ASTR].op = s != nil ? CHANNOP : CHANRCV; switch(alt(a)){ case AREQ: @@ -665,27 +904,38 @@ reqproc(void *aux) p = s; } - while(s && q){ + while(s != nil && q != nil){ r = q; if((q = q->aux) == nil) qq = &q; - - e = s + strlen(s); - if(p == s && r->fid->qid.path == Qkbd) - e++; /* send terminating \0 if its kbd file */ + r->ofcall.count = 0; + if(s == p){ + More: + e = s + strlen(s); + if(r->fid->qid.path == Qkbd) + e++; /* send terminating \0 if its kbd file */ + } n = e - p; - if(n > r->ifcall.count) - n = r->ifcall.count; - - r->ofcall.count = n; - memmove(r->ofcall.data, p, n); - respond(r, nil); - + m = r->ifcall.count - r->ofcall.count; + if(n > m){ + if(r->ofcall.count > 0){ + respond(r, nil); + continue; + } + n = m; + } + memmove((char*)r->ofcall.data + r->ofcall.count, p, n); + r->ofcall.count += n; p += n; if(p >= e){ free(s); - s = nil; + s = nbrecvp(a[ASTR].c); + if(s != nil){ + p = s; + goto More; + } } + respond(r, nil); } } } @@ -707,10 +957,14 @@ ctlproc(void *) threadsetname("ctlproc"); + if(kbdifd >= 0) + proccreate(kbdiproc, nil, STACK); /* kbdifd -> kbdin() */ if(scanfd >= 0) proccreate(scanproc, nil, STACK); /* scanfd -> keychan */ if(consfd >= 0) proccreate(consproc, nil, STACK); /* consfd -> runechan */ + if(notefd >= 0) + proccreate(intrproc, nil, STACK); /* intchan -> notefd */ threadcreate(keyproc, nil, STACK); /* keychan -> rawchan, kbdchan */ threadcreate(runeproc, nil, STACK); /* rawchan -> runechan */ @@ -779,22 +1033,19 @@ ctlproc(void *) Rune* kbmapent(int t, int sc) { - if(sc < 0 || sc >= Nscan) - return nil; - switch(t){ - default: - return nil; - case 0: - return &kbtab[sc]; - case 1: - return &kbtabshift[sc]; - case 2: - return &kbtabesc1[sc]; - case 3: - return &kbtabaltgr[sc]; - case 4: - return &kbtabctl[sc]; - } + static Rune *tabs[] = { + /* 0 */ kbtab, + /* 1 */ kbtabshift, + /* 2 */ kbtabesc1, + /* 3 */ kbtabaltgr, + /* 4 */ kbtabctl, + /* 5 */ kbtabctrlesc1, + /* 6 */ kbtabshiftesc1, + /* 7 */ kbtabshiftaltgr, + }; + if(t >= 0 && t < nelem(tabs) && sc >= 0 && sc < Nscan) + return &tabs[t][sc]; + return nil; } void @@ -881,7 +1132,7 @@ kbmapwrite(Req *req) else goto Badarg; }else if(*lp == 'M' && ('1' <= lp[1] && lp[1] <= '5')) - r = 0xF900+lp[1]-'0'; + r = Kmouse+lp[1]-'0'; else if(*lp>='0' && *lp<='9') /* includes 0x... */ r = strtoul(lp, &lp, 0); else @@ -1083,29 +1334,25 @@ static void fswrite(Req *r) { Fid *f; - Scan *a; - char *p, *s; + char *p; int n, i; - Key k; f = r->fid; + p = r->ifcall.data; + n = r->ifcall.count; switch((ulong)f->qid.path){ default: respond(r, Ephase); return; case Qcons: - n = r->ifcall.count; - if(write(1, r->ifcall.data, n) != n){ + if(write(1, p, n) != n){ responderror(r); return; } - r->ofcall.count = n; break; case Qconsctl: - p = r->ifcall.data; - n = r->ifcall.count; if(n >= 5 && memcmp(p, "rawon", 5) == 0) sendul(ctlchan, Rawon); else if(n >= 6 && memcmp(p, "rawoff", 6) == 0) @@ -1114,91 +1361,22 @@ fswrite(Req *r) respond(r, Ebadarg); return; } - r->ofcall.count = n; break; + case Qkbin: case Qkbdin: - p = r->ifcall.data; - n = r->ifcall.count; - r->ofcall.count = n; if(n == 0) break; - if(p[n-1] != 0){ - /* - * old format as used by bitsy keyboard: - * just a string of characters, no keyup - * information. - */ - s = emalloc9p(n+1); - memmove(s, p, n); - s[n] = 0; - p = s; - while(*p){ - p += chartorune(&k.r, p); - if(k.r) - send(rawchan, &k.r); - } - free(s); - break; - } - switch(p[0]){ - case 'R': - case 'r': - /* rune up/down */ - chartorune(&k.r, p+1); - if(k.r == 0) - break; - k.b = k.r; - k.down = (p[0] == 'r'); - if(f->aux == nil){ - f->aux = emalloc9p(sizeof(Scan)); - memset(f->aux, 0, sizeof(Scan)); - } - a = f->aux; - /* - * handle ^X forms according to keymap and - * assign button. - */ - for(i=0; ishift && kbtabshift[i] == k.r) || (kbtab[i] == k.r)){ - if(kbtab[i]) - k.b = kbtab[i]; - if(a->shift) - k.r = kbtabshift[i]; - else if(a->altgr) - k.r = kbtabaltgr[i]; - else if(a->ctl) - k.r = kbtabctl[i]; - break; - } - } - if(k.b) - send(keychan, &k); - if(k.r == Kshift) - a->shift = k.down; - else if(k.r == Kaltgr) - a->altgr = k.down; - else if(k.r == Kctl) - a->ctl = k.down; - break; - default: - if(!kbdopen) - break; - s = emalloc9p(n); - memmove(s, p, n); - if(nbsendp(kbdchan, s) <= 0) - free(s); - } - break; - - case Qkbin: if(f->aux == nil){ f->aux = emalloc9p(sizeof(Scan)); memset(f->aux, 0, sizeof(Scan)); } - for(i=0; iifcall.count; i++) - kbdputsc((Scan*)f->aux, (uchar)r->ifcall.data[i]); - r->ofcall.count = i; + if(f->qid.path == Qkbin){ + for(i=0; iaux, (uchar)p[i]); + } else { + kbdin((Scan*)f->aux, p, n); + } break; case Qkbmap: @@ -1206,6 +1384,7 @@ fswrite(Req *r) return; } + r->ofcall.count = n; respond(r, nil); } @@ -1248,50 +1427,7 @@ fsdestroyfid(Fid *f) } } -static void -fsend(Srv*) -{ - threadexitsall(nil); -} - -Srv fs = { - .attach= fsattach, - .walk1= fswalk1, - .open= fsopen, - .read= fsread, - .write= fswrite, - .stat= fsstat, - .flush= fsflush, - .destroyfid= fsdestroyfid, - .end= fsend, -}; - -int -eopen(char *name, int mode) -{ - int fd; - - fd = open(name, mode); - if(fd < 0 && !quiet) - fprint(2, "%s: warning: can't open %s: %r\n", argv0, name); - return fd; -} - -void -reboot(void) -{ - int fd; - - if(debug) - return; - - if((fd = eopen("/dev/reboot", OWRITE)) < 0) - return; - fprint(fd, "reboot\n"); - close(fd); -} - -int +static int procopen(int pid, char *name, int mode) { char buf[128]; @@ -1300,7 +1436,7 @@ procopen(int pid, char *name, int mode) return eopen(buf, mode); } -void +static void elevate(void) { Dir *d, nd; @@ -1329,21 +1465,43 @@ elevate(void) close(fd); } +static void +fsstart(Srv*) +{ + killfd = procopen(getpid(), "notepg", OWRITE); + elevate(); + proccreate(ctlproc, nil, STACK); +} + +static void +fsend(Srv*) +{ + shutdown(); +} + +Srv fs = { + .start= fsstart, + .attach= fsattach, + .walk1= fswalk1, + .open= fsopen, + .read= fsread, + .write= fswrite, + .stat= fsstat, + .flush= fsflush, + .destroyfid= fsdestroyfid, + .end= fsend, +}; + void usage(void) { - fprint(2, "usage: %s [ -qdD ] [ -s srv ] [ -m mntpnt ] [ file ]\n", argv0); + fprint(2, "usage: %s [ -qdD ] [ -s sname ] [ -m mntpnt ] [ file ]\n", argv0); exits("usage"); } void threadmain(int argc, char** argv) { - char *mtpt = "/dev"; - char *srv = nil; - - consfd = -1; - ARGBEGIN{ case 'd': debug++; @@ -1352,10 +1510,10 @@ threadmain(int argc, char** argv) chatty9p++; break; case 's': - srv = EARGF(usage()); + sname = EARGF(usage()); break; case 'm': - mtpt = EARGF(usage()); + mntpt = EARGF(usage()); break; case 'q': quiet++; @@ -1364,15 +1522,19 @@ threadmain(int argc, char** argv) usage(); }ARGEND - notefd = procopen(getpid(), "notepg", OWRITE); - - scanfd = eopen("/dev/scancode", OREAD); - ledsfd = eopen("/dev/leds", OWRITE); - mctlfd = eopen("/dev/mousectl", OWRITE); - if(*argv) consfd = eopen(*argv, OREAD); + kbdifd = open(dev("kbd"), OREAD); + if(kbdifd < 0){ + scanfd = eopen(dev("scancode"), OREAD); + ledsfd = eopen(dev("leds"), OWRITE); + mctlfd = eopen(dev("mousectl"), OWRITE); + msinfd = eopen(dev("mousein"), OWRITE); + } + + notefd = procopen(getpid(), "notepg", OWRITE); + consreqchan = chancreate(sizeof(Req*), 0); kbdreqchan = chancreate(sizeof(Req*), 0); @@ -1382,8 +1544,8 @@ threadmain(int argc, char** argv) runechan = chancreate(sizeof(Rune), 32); conschan = chancreate(sizeof(char*), 16); kbdchan = chancreate(sizeof(char*), 16); + intchan = chancreate(sizeof(int), 0); - elevate(); - procrfork(ctlproc, nil, STACK, RFNAMEG|RFNOTEG); - threadpostmountsrv(&fs, srv, mtpt, MBEFORE); + threadpostmountsrv(&fs, sname, mntpt, MBEFORE); + threadexits(0); }