diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-04-03 22:54:22 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-04-03 22:54:22 +0200 |
commit | ce84082205f8367c1a4676c4810d92b30ae87f49 (patch) | |
tree | 1f33dee7fb1674e0c18dcafb5cb56b7ee92aa395 | |
parent | cd9cddf3dd64b01e7e54ba3a3371a8d0a5c70748 (diff) |
change /dev/kbd to return multiple messages per read
-rw-r--r-- | sys/src/cmd/aux/kbdfs/kbdfs.c | 66 | ||||
-rw-r--r-- | sys/src/cmd/rio/dat.h | 7 | ||||
-rw-r--r-- | sys/src/cmd/rio/rio.c | 9 | ||||
-rw-r--r-- | sys/src/cmd/rio/wind.c | 49 | ||||
-rw-r--r-- | sys/src/cmd/rio/xfid.c | 148 | ||||
-rw-r--r-- | sys/src/cmd/vnc/kbdv.c | 16 | ||||
-rw-r--r-- | sys/src/games/c64/c64.c | 15 | ||||
-rw-r--r-- | sys/src/games/doom/i_video.c | 15 | ||||
-rw-r--r-- | sys/src/games/gb/gb.c | 15 | ||||
-rw-r--r-- | sys/src/games/gba/gba.c | 15 | ||||
-rw-r--r-- | sys/src/games/md/md.c | 15 | ||||
-rw-r--r-- | sys/src/games/nes/nes.c | 15 | ||||
-rw-r--r-- | sys/src/games/snes/snes.c | 15 |
13 files changed, 214 insertions, 186 deletions
diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c index 71c694db0..17716afbc 100644 --- a/sys/src/cmd/aux/kbdfs/kbdfs.c +++ b/sys/src/cmd/aux/kbdfs/kbdfs.c @@ -417,7 +417,9 @@ kbdin(Scan *a, char *p, int n) } free(s); return; - } else if(n < 2) + } +Nextmsg: + if(n < 2) return; switch(p[0]){ case 'R': @@ -429,24 +431,16 @@ kbdin(Scan *a, char *p, int n) k.b = k.r; k.down = (p[0] == 'r'); /* - * handle ^X forms according to keymap and - * assign button. + * assign button according to keymap. */ 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); + send(keychan, &k); if(k.r == Kshift) a->shift = k.down; else if(k.r == Kaltgr) @@ -463,11 +457,15 @@ kbdin(Scan *a, char *p, int n) default: if(!kbdopen) break; - s = emalloc9p(n); - memmove(s, p, n); + 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 @@ -831,10 +829,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; @@ -852,7 +851,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: @@ -883,27 +882,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); } } } diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index 73f03eaf7..5d8891162 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -95,11 +95,6 @@ struct Mousereadmesg Channel *cm; /* chan(Mouse) */ }; -struct Kbdreadmesg -{ - Channel *ck; /* chan(char*) */ -}; - struct Stringpair /* rune and nrune or byte and nbyte */ { void *s; @@ -137,7 +132,7 @@ struct Window Channel *consread; /* chan(Consreadmesg) */ Channel *mouseread; /* chan(Mousereadmesg) */ Channel *wctlread; /* chan(Consreadmesg) */ - Channel *kbdread; /* chan(Kbdreadmesg) */ + Channel *kbdread; /* chan(Consreadmesg) */ Channel *complete; /* chan(Completion*) */ Channel *gone; /* chan(char*) */ uint nr; /* number of runes in window */ diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index 0c1564f53..4a887ab20 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -1302,8 +1302,13 @@ kbdproc(void *arg) servekbd = 1; /* read kbd state */ - while((n = read(kfd, buf, sizeof(buf))) > 0) - chanprint(c, "%.*s", n, buf); + while((n = read(kfd, buf, sizeof(buf)-1)) > 0){ + e = buf+n; + e[-1] = 0; + e[0] = 0; + for(p = buf; p < e; p += strlen(p)+1) + chanprint(c, "%s", p); + } } else { /* read single characters */ p = buf; diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c index 53365576f..e833422d4 100644 --- a/sys/src/cmd/rio/wind.c +++ b/sys/src/cmd/rio/wind.c @@ -41,7 +41,7 @@ wmk(Image *i, Mousectl *mc, Channel *ck, Channel *cctl, int scrolling) w->cursorp = nil; w->conswrite = chancreate(sizeof(Conswritemesg), 0); w->consread = chancreate(sizeof(Consreadmesg), 0); - w->kbdread = chancreate(sizeof(Kbdreadmesg), 0); + w->kbdread = chancreate(sizeof(Consreadmesg), 0); w->mouseread = chancreate(sizeof(Mousereadmesg), 0); w->wctlread = chancreate(sizeof(Consreadmesg), 0); w->complete = chancreate(sizeof(Completion*), 0); @@ -167,11 +167,9 @@ winctl(void *arg) Mousestate *mp, m; enum { WKbd, WKbdread, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, WComplete, Wgone, NWALT }; Alt alts[NWALT+1]; + Consreadmesg crm; Mousereadmesg mrm; - Kbdreadmesg krm; Conswritemesg cwm; - Consreadmesg crm; - Consreadmesg cwrm; Stringpair pair; Wctlmesg wcm; Completion *cr; @@ -182,18 +180,15 @@ winctl(void *arg) threadsetname("winctl-id%d", w->id); mrm.cm = chancreate(sizeof(Mouse), 0); - krm.ck = chancreate(sizeof(char*), 0); - cwm.cw = chancreate(sizeof(Stringpair), 0); crm.c1 = chancreate(sizeof(Stringpair), 0); crm.c2 = chancreate(sizeof(Stringpair), 0); - cwrm.c1 = chancreate(sizeof(Stringpair), 0); - cwrm.c2 = chancreate(sizeof(Stringpair), 0); + cwm.cw = chancreate(sizeof(Stringpair), 0); alts[WKbd].c = w->ck; alts[WKbd].v = &kbds; alts[WKbd].op = CHANRCV; alts[WKbdread].c = w->kbdread; - alts[WKbdread].v = &krm; + alts[WKbdread].v = &crm; alts[WKbdread].op = CHANSND; alts[WMouse].c = w->mc.c; alts[WMouse].v = &w->mc.Mouse; @@ -211,7 +206,7 @@ winctl(void *arg) alts[WCread].v = &crm; alts[WCread].op = CHANSND; alts[WWread].c = w->wctlread; - alts[WWread].v = &cwrm; + alts[WWread].v = &crm; alts[WWread].op = CHANSND; alts[WComplete].c = w->complete; alts[WComplete].v = &cr; @@ -279,14 +274,27 @@ winctl(void *arg) break; case WKbdread: - i = (kbdqr+1) % nelem(kbdq); - if(kbdqr != kbdqw) - kbdqr = i; - if(kbdq[i]){ - sendp(krm.ck, kbdq[i]); + recv(crm.c1, &pair); + nb = pair.ns; + pair.ns = 0; + t = pair.s; + while(kbdqr != kbdqw){ + int m; + + i = (kbdqr+1) % nelem(kbdq); + if(kbdq[i] == nil) + break; + m = strlen(kbdq[i])+1; + nb -= m; + if(nb < 0) + break; + memmove(t, kbdq[i], m); + t += m, pair.ns += m; + free(kbdq[i]); kbdq[i] = nil; - }else - sendp(krm.ck, strdup("K")); + kbdqr = i; + } + send(crm.c2, &pair); continue; case WMouse: @@ -329,10 +337,7 @@ winctl(void *arg) chanfree(crm.c1); chanfree(crm.c2); chanfree(mrm.cm); - chanfree(krm.ck); chanfree(cwm.cw); - chanfree(cwrm.c1); - chanfree(cwrm.c2); threadexits(nil); } continue; @@ -406,14 +411,14 @@ winctl(void *arg) continue; case WWread: w->wctlready = 0; - recv(cwrm.c1, &pair); + recv(crm.c1, &pair); s = Dx(w->screenr) > 0 ? "visible" : "hidden"; t = "notcurrent"; if(w == input) t = "current"; pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %s %s ", w->i->r.min.x, w->i->r.min.y, w->i->r.max.x, w->i->r.max.y, t, s); - send(cwrm.c2, &pair); + send(crm.c2, &pair); continue; case WComplete: if(w->i!=nil){ diff --git a/sys/src/cmd/rio/xfid.c b/sys/src/cmd/rio/xfid.c index a213bcffb..879dc01d5 100644 --- a/sys/src/cmd/rio/xfid.c +++ b/sys/src/cmd/rio/xfid.c @@ -614,13 +614,9 @@ xfidread(Xfid *x) Channel *c1, *c2; /* chan (tuple(char*, int)) */ Consreadmesg crm; Mousereadmesg mrm; - Consreadmesg cwrm; - Kbdreadmesg krm; Stringpair pair; - enum { CRdata, CRgone, CRflush, NCR }; - enum { MRdata, MRgone, MRflush, NMR }; - enum { WCRdata, WCRgone, WCRflush, NWCR }; - Alt alts[NCR+1]; + enum { Adata, Agone, Aflush, Aend }; + Alt alts[Aend+1]; w = x->f->w; if(w->deleted){ @@ -631,29 +627,42 @@ xfidread(Xfid *x) off = x->offset; cnt = x->count; switch(qid){ + case Qwctl: + if(cnt < 4*12){ + filsysrespond(x->fs, x, &fc, Etooshort); + break; + } + alts[Adata].c = w->wctlread; + goto Consmesg; + + case Qkbd: + alts[Adata].c = w->kbdread; + goto Consmesg; + case Qcons: - alts[CRdata].c = w->consread; - alts[CRdata].v = &crm; - alts[CRdata].op = CHANRCV; - alts[CRgone].c = w->gone; - alts[CRgone].v = nil; - alts[CRgone].op = CHANRCV; - alts[CRflush].c = x->flushc; - alts[CRflush].v = nil; - alts[CRflush].op = CHANRCV; - alts[NCR].op = CHANEND; + alts[Adata].c = w->consread; + + Consmesg: + alts[Adata].v = &crm; + alts[Adata].op = CHANRCV; + alts[Agone].c = w->gone; + alts[Agone].v = nil; + alts[Agone].op = CHANRCV; + alts[Aflush].c = x->flushc; + alts[Aflush].v = nil; + alts[Aflush].op = CHANRCV; + alts[Aend].op = CHANEND; switch(alt(alts)){ - case CRdata: + case Adata: break; - case CRgone: + case Agone: filsysrespond(x->fs, x, &fc, Edeleted); return; - case CRflush: + case Aflush: filsyscancel(x); return; } - c1 = crm.c1; c2 = crm.c2; t = malloc(cnt+UTFmax+1); /* room to unpack partial rune plus */ @@ -679,24 +688,24 @@ xfidread(Xfid *x) break; case Qmouse: - alts[MRdata].c = w->mouseread; - alts[MRdata].v = &mrm; - alts[MRdata].op = CHANRCV; - alts[MRgone].c = w->gone; - alts[MRgone].v = nil; - alts[MRgone].op = CHANRCV; - alts[MRflush].c = x->flushc; - alts[MRflush].v = nil; - alts[MRflush].op = CHANRCV; - alts[NMR].op = CHANEND; + alts[Adata].c = w->mouseread; + alts[Adata].v = &mrm; + alts[Adata].op = CHANRCV; + alts[Agone].c = w->gone; + alts[Agone].v = nil; + alts[Agone].op = CHANRCV; + alts[Aflush].c = x->flushc; + alts[Aflush].v = nil; + alts[Aflush].op = CHANRCV; + alts[Aend].op = CHANEND; switch(alt(alts)){ - case MRdata: + case Adata: break; - case MRgone: + case Agone: filsysrespond(x->fs, x, &fc, Edeleted); return; - case MRflush: + case Aflush: filsyscancel(x); return; } @@ -712,36 +721,6 @@ xfidread(Xfid *x) filsysrespond(x->fs, x, &fc, nil); break; - case Qkbd: - alts[MRdata].c = w->kbdread; - alts[MRdata].v = &krm; - alts[MRdata].op = CHANRCV; - alts[MRgone].c = w->gone; - alts[MRgone].v = nil; - alts[MRgone].op = CHANRCV; - alts[MRflush].c = x->flushc; - alts[MRflush].v = nil; - alts[MRflush].op = CHANRCV; - alts[NMR].op = CHANEND; - - switch(alt(alts)){ - case MRdata: - break; - case MRgone: - filsysrespond(x->fs, x, &fc, Edeleted); - return; - case MRflush: - filsyscancel(x); - return; - } - - t = recvp(krm.ck); - fc.data = t; - fc.count = strlen(t)+1; - filsysrespond(x->fs, x, &fc, nil); - free(t); - break; - case Qcursor: filsysrespond(x->fs, x, &fc, "cursor read not implemented"); break; @@ -833,49 +812,6 @@ xfidread(Xfid *x) free(t); return; - case Qwctl: /* read returns rectangle, hangs if not resized */ - if(cnt < 4*12){ - filsysrespond(x->fs, x, &fc, Etooshort); - break; - } - - alts[WCRdata].c = w->wctlread; - alts[WCRdata].v = &cwrm; - alts[WCRdata].op = CHANRCV; - alts[WCRgone].c = w->gone; - alts[WCRgone].v = nil; - alts[WCRgone].op = CHANRCV; - alts[WCRflush].c = x->flushc; - alts[WCRflush].v = nil; - alts[WCRflush].op = CHANRCV; - alts[NWCR].op = CHANEND; - - switch(alt(alts)){ - case WCRdata: - break; - case WCRgone: - filsysrespond(x->fs, x, &fc, Edeleted); - return; - case WCRflush: - filsyscancel(x); - return; - } - - c1 = cwrm.c1; - c2 = cwrm.c2; - t = malloc(cnt+1); /* be sure to have room for NUL */ - pair.s = t; - pair.ns = cnt+1; - send(c1, &pair); - recv(c2, &pair); - fc.data = pair.s; - if(pair.ns > cnt) - pair.ns = cnt; - fc.count = pair.ns; - filsysrespond(x->fs, x, &fc, nil); - free(t); - break; - default: fprint(2, "unknown qid %d in read\n", qid); snprint(buf, sizeof(buf), "unknown qid in read"); diff --git a/sys/src/cmd/vnc/kbdv.c b/sys/src/cmd/vnc/kbdv.c index 5dd4e1eae..967843b0c 100644 --- a/sys/src/cmd/vnc/kbdv.c +++ b/sys/src/cmd/vnc/kbdv.c @@ -203,10 +203,22 @@ readkbd(Vnc *v) readcons(v); return; } + buf2[0] = 0; buf2[1] = 0; - while((n = read(fd, buf, sizeof(buf))) > 0){ - buf[n-1] = 0; + buf[0] = 0; + for(;;){ + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + break; + buf[n-1] = 0; + buf[n] = 0; + } switch(buf[0]){ case 'k': s = buf+1; diff --git a/sys/src/games/c64/c64.c b/sys/src/games/c64/c64.c index 1bb7cad4a..054851813 100644 --- a/sys/src/games/c64/c64.c +++ b/sys/src/games/c64/c64.c @@ -131,7 +131,7 @@ loadtape(char *name) static void keyproc(void *) { - int fd, i, setnmi; + int fd, i, n, setnmi; u16int j; u64int k; static Rune keymap[64] = { @@ -152,8 +152,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, Kend)){ close(fd); diff --git a/sys/src/games/doom/i_video.c b/sys/src/games/doom/i_video.c index 5ce432edf..941d7e676 100644 --- a/sys/src/games/doom/i_video.c +++ b/sys/src/games/doom/i_video.c @@ -257,8 +257,19 @@ kbdproc(void) buf2[0] = 0; buf2[1] = 0; - while((n = read(kfd, buf, sizeof(buf))) > 0){ - buf[n-1] = 0; + buf[0] = 0; + for(;;){ + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(kfd, buf, sizeof(buf)-1); + if(n <= 0) + break; + buf[n-1] = 0; + buf[n] = 0; + } e.data1 = -1; e.data2 = -1; diff --git a/sys/src/games/gb/gb.c b/sys/src/games/gb/gb.c index e8bcdb459..79930ec63 100644 --- a/sys/src/games/gb/gb.c +++ b/sys/src/games/gb/gb.c @@ -218,7 +218,7 @@ screeninit(void) void keyproc(void *) { - int fd, k; + int fd, n, k; static char buf[256]; char *s; Rune r; @@ -228,8 +228,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, KF|5)) savereq = 1; diff --git a/sys/src/games/gba/gba.c b/sys/src/games/gba/gba.c index cebd1a830..50300af0b 100644 --- a/sys/src/games/gba/gba.c +++ b/sys/src/games/gba/gba.c @@ -226,7 +226,7 @@ screeninit(void) void keyproc(void *) { - int fd, k; + int fd, n, k; static char buf[256]; char *s; Rune r; @@ -235,8 +235,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, KF|5)) savereq = 1; diff --git a/sys/src/games/md/md.c b/sys/src/games/md/md.c index 27e292274..f8ffcc52c 100644 --- a/sys/src/games/md/md.c +++ b/sys/src/games/md/md.c @@ -180,7 +180,7 @@ screenproc(void *) void keyproc(void *) { - int fd, k; + int fd, n, k; static char buf[256]; char *s; Rune r; @@ -189,8 +189,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, Kdel)){ close(fd); diff --git a/sys/src/games/nes/nes.c b/sys/src/games/nes/nes.c index 78c25adb3..aa9c4fa2a 100644 --- a/sys/src/games/nes/nes.c +++ b/sys/src/games/nes/nes.c @@ -172,7 +172,7 @@ joyproc(void *) void keyproc(void *) { - int fd, k; + int fd, n, k; static char buf[256]; char *s; Rune r; @@ -181,8 +181,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, Kdel)){ close(fd); diff --git a/sys/src/games/snes/snes.c b/sys/src/games/snes/snes.c index a2b9266e9..863247fef 100644 --- a/sys/src/games/snes/snes.c +++ b/sys/src/games/snes/snes.c @@ -116,7 +116,7 @@ loadbat(char *file) void keyproc(void *) { - int fd, k; + int fd, n, k; static char buf[256]; char *s; Rune r; @@ -125,8 +125,17 @@ keyproc(void *) if(fd < 0) sysfatal("open: %r"); for(;;){ - if(read(fd, buf, sizeof(buf) - 1) <= 0) - sysfatal("read /dev/kbd: %r"); + if(buf[0] != 0){ + n = strlen(buf)+1; + memmove(buf, buf+n, sizeof(buf)-n); + } + if(buf[0] == 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n <= 0) + sysfatal("read /dev/kbd: %r"); + buf[n-1] = 0; + buf[n] = 0; + } if(buf[0] == 'c'){ if(utfrune(buf, KF|5)) savereq = 1; |