ref: ce84082205f8367c1a4676c4810d92b30ae87f49
parent: cd9cddf3dd64b01e7e54ba3a3371a8d0a5c70748
author: cinap_lenrek <[email protected]>
date: Sun Apr 3 18:54:22 EDT 2016
change /dev/kbd to return multiple messages per read
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -417,7 +417,9 @@
}
free(s);
return;
- } else if(n < 2)
+ }
+Nextmsg:
+ if(n < 2)
return;
switch(p[0]){
case 'R':
@@ -429,24 +431,16 @@
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 @@
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 @@
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 @@
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 @@
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);
}
}
}
--- a/sys/src/cmd/rio/dat.h
+++ b/sys/src/cmd/rio/dat.h
@@ -95,11 +95,6 @@
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 @@
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 */
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -1302,8 +1302,13 @@
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;
--- a/sys/src/cmd/rio/wind.c
+++ b/sys/src/cmd/rio/wind.c
@@ -41,7 +41,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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,7 +411,7 @@
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)
@@ -413,7 +418,7 @@
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){
--- a/sys/src/cmd/rio/xfid.c
+++ b/sys/src/cmd/rio/xfid.c
@@ -614,13 +614,9 @@
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 @@
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 @@
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 @@
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;
@@ -832,49 +811,6 @@
}
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);
--- a/sys/src/cmd/vnc/kbdv.c
+++ b/sys/src/cmd/vnc/kbdv.c
@@ -203,10 +203,22 @@
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;
--- a/sys/src/games/c64/c64.c
+++ b/sys/src/games/c64/c64.c
@@ -131,7 +131,7 @@
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 @@
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);
--- a/sys/src/games/doom/i_video.c
+++ b/sys/src/games/doom/i_video.c
@@ -257,8 +257,19 @@
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;
--- a/sys/src/games/gb/gb.c
+++ b/sys/src/games/gb/gb.c
@@ -218,7 +218,7 @@
void
keyproc(void *)
{
- int fd, k;
+ int fd, n, k;
static char buf[256];
char *s;
Rune r;
@@ -228,8 +228,17 @@
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;
--- a/sys/src/games/gba/gba.c
+++ b/sys/src/games/gba/gba.c
@@ -226,7 +226,7 @@
void
keyproc(void *)
{
- int fd, k;
+ int fd, n, k;
static char buf[256];
char *s;
Rune r;
@@ -235,8 +235,17 @@
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;
--- a/sys/src/games/md/md.c
+++ b/sys/src/games/md/md.c
@@ -180,7 +180,7 @@
void
keyproc(void *)
{
- int fd, k;
+ int fd, n, k;
static char buf[256];
char *s;
Rune r;
@@ -189,8 +189,17 @@
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);
--- a/sys/src/games/nes/nes.c
+++ b/sys/src/games/nes/nes.c
@@ -172,7 +172,7 @@
void
keyproc(void *)
{
- int fd, k;
+ int fd, n, k;
static char buf[256];
char *s;
Rune r;
@@ -181,8 +181,17 @@
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);
--- a/sys/src/games/snes/snes.c
+++ b/sys/src/games/snes/snes.c
@@ -116,7 +116,7 @@
void
keyproc(void *)
{
- int fd, k;
+ int fd, n, k;
static char buf[256];
char *s;
Rune r;
@@ -125,8 +125,17 @@
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;