shithub: riscv

Download patch

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;