change /dev/kbd to return multiple messages per read

This commit is contained in:
cinap_lenrek 2016-04-03 22:54:22 +02:00
parent cd9cddf3dd
commit ce84082205
13 changed files with 215 additions and 187 deletions

View file

@ -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);
}
}
}

View file

@ -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 */

View file

@ -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;

View file

@ -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];
Mousereadmesg mrm;
Kbdreadmesg krm;
Conswritemesg cwm;
Consreadmesg crm;
Consreadmesg cwrm;
Mousereadmesg mrm;
Conswritemesg cwm;
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){

View file

@ -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");

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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;