diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-02-27 02:36:54 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-02-27 02:36:54 +0100 |
commit | 09b250f079e38883e8ad5dc47e4aa93258e0c083 (patch) | |
tree | aeddf59702169a5595d558b04fbbd53e7be0e86a /sys/src/cmd/aux | |
parent | e95f557ba57b7102693b169bbe3f93661de8bec7 (diff) |
kbdfs: read outer /dev/kbd file and use it just like /dev/kbdin
this allows running kbdfs under kbdfs :-)
going use this in new drawterm. drawterm provides the initial
/dev/kbd, but only sends rune up/down messages (keeps it simple).
the servers kbdfs reads that and exports itself the full
set of files, similar to what we do in vncs. this also
provides note processing.
Diffstat (limited to 'sys/src/cmd/aux')
-rw-r--r-- | sys/src/cmd/aux/kbdfs/kbdfs.c | 361 |
1 files changed, 207 insertions, 154 deletions
diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c index 52c1c6ffd..ffd4936de 100644 --- a/sys/src/cmd/aux/kbdfs/kbdfs.c +++ b/sys/src/cmd/aux/kbdfs/kbdfs.c @@ -89,16 +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 msinfd; -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; @@ -260,7 +264,49 @@ Rune kbtabctl[Nscan] = [0x78] 0, '', 0, '\b', 0, 0, 0, 0, }; -void reboot(void); +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 @@ -347,6 +393,83 @@ 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; + } else 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'); + /* + * handle ^X forms according to keymap and + * assign button. + */ + for(i=0; i<Nscan; i++){ + if((a->shift && 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; + + case 'c': + chartorune(&k.r, p+1); + nbsend(runechan, &k.r); + break; + + default: + if(!kbdopen) + break; + s = emalloc9p(n); + memmove(s, p, n); + if(nbsendp(kbdchan, s) <= 0) + free(s); + } +} + void setleds(Scan *scan, int leds) { @@ -378,6 +501,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* @@ -492,6 +633,8 @@ consproc(void *) memmove(buf, p, n); p = buf + n; } + + shutdown(); } static int @@ -782,6 +925,8 @@ 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) @@ -1164,29 +1309,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) @@ -1195,91 +1336,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; i<Nscan; i++){ - if((a->shift && 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; i<r->ifcall.count; i++) - kbdputsc((Scan*)f->aux, (uchar)r->ifcall.data[i]); - r->ofcall.count = i; + if(f->qid.path == Qkbin){ + for(i=0; i<n; i++) + kbdputsc((Scan*)f->aux, (uchar)p[i]); + } else { + kbdin((Scan*)f->aux, p, n); + } break; case Qkbmap: @@ -1287,6 +1359,7 @@ fswrite(Req *r) return; } + r->ofcall.count = n; respond(r, nil); } @@ -1329,50 +1402,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]; @@ -1381,7 +1411,7 @@ procopen(int pid, char *name, int mode) return eopen(buf, mode); } -void +static void elevate(void) { Dir *d, nd; @@ -1410,21 +1440,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++; @@ -1433,10 +1485,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++; @@ -1445,16 +1497,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); - msinfd = eopen("/dev/mousein", 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); @@ -1466,8 +1521,6 @@ threadmain(int argc, char** argv) 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); } |