diff bed7f3f1a31946d417822613d01094ace514c73f uncommitted --- a//sys/src/cmd/ktrans/main.c +++ b//sys/src/cmd/ktrans/main.c @@ -497,7 +497,7 @@ threadsetname("keytrans"); while(recv(input, &m) != -1){ - if(m.code == 'r'){ + if(m.code == 'z'){ emitutf(dictch, " ", 1); resetstr(&line, nil); continue; @@ -609,7 +609,7 @@ p++; switch(msg.code){ case 'c': case 'k': case 'K': - case 'r': + case 'z': break; default: goto Drop; @@ -684,6 +684,8 @@ default: usage(); } + if(write(kbdout, "z", 2) < 2) + sysfatal("failed to enable focus watch: %r"); memset(backspace, '\b', sizeof backspace-1); backspace[sizeof backspace-1] = '\0'; --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -318,6 +318,7 @@ enum{ Tapon = 'b', Tapoff = 'e', + Tapwatch = 'z', }; Channel *ctltap; /* on/off messages */ Channel *fromtap; /* input from kbd tap program to window */ --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -199,7 +199,7 @@ totap = chancreate(sizeof(char*), 32); fromtap = chancreate(sizeof(char*), 32); wintap = chancreate(sizeof(Window*), 0); - ctltap = chancreate(sizeof(Window*), 0); + ctltap = chancreate(sizeof(char*), 0); proccreate(keyboardtap, nil, STACK); wscreen = allocscreen(screen, background, 0); @@ -354,13 +354,13 @@ keyboardtap(void*) { char *s, *ctl; + char *watched; Window *w, *cur; - int mode; - enum { Awin, Actl, Afrom, Adev, Ato, Ainp, NALT }; - enum { Mnorm, Mtap }; + int mode, perm; + int seats[] = { [OREAD] 0, [OWRITE] 0 }; - threadsetname("keyboardtap"); - + threadsetname("keyboardtap"); + enum { Awin, Actl, Afrom, Adev, Ato, Ainp, Awatch, NALT }; static Alt alts[NALT+1]; /* ctl */ alts[Awin].c = wintap; @@ -383,10 +383,14 @@ alts[Ainp].c = nil; alts[Ainp].v = &s; alts[Ainp].op = CHANNOP; + alts[Awatch].c = totap; + alts[Awatch].v = &watched; + alts[Awatch].op = CHANNOP; alts[NALT].op = CHANEND; cur = nil; - mode = Mnorm; + mode = Tapoff; + watched = nil; for(;;) switch(alt(alts)){ case Awin: @@ -393,21 +397,49 @@ cur = w; if(cur != nil){ alts[Ainp].c = cur->ck; - break; + if(mode != Tapwatch) + break; + if(alts[Awatch].op == CHANSND) + free(watched); + watched = smprint("z%d", cur->id); + alts[Awatch].op = CHANSND; } if(alts[Ainp].op != CHANNOP || alts[Ato].op != CHANNOP) free(s); goto Reset; case Actl: - switch(*ctl){ - case Tapon: - mode = Mtap; + mode = ctl[0]; + if(mode == Tapwatch){ + free(ctl); break; - case Tapoff: - mode = Mnorm; - break; } + perm = ctl[1]; free(ctl); + if(mode == Tapoff){ + if(perm == ORDWR) + memset(seats, 0, sizeof seats); + else + seats[perm] = 0; + break; + } + switch(perm){ + case ORDWR: + if(seats[OREAD] != 0 || seats[OWRITE] != 0) + sendp(ctltap, "seat taken"); + else { + seats[OREAD] = 1, seats[OWRITE] = 1; + sendp(ctltap, nil); + } + break; + case OREAD: case OWRITE: + if(seats[perm] != 0) + sendp(ctltap, "seat taken"); + else { + seats[perm] = 1; + sendp(ctltap, nil); + } + break; + } break; case Afrom: if(cur == nil){ @@ -420,16 +452,19 @@ alts[Ainp].op = CHANSND; break; case Adev: - if(mode == Mnorm && cur == nil){ + if(mode == Tapoff && cur == nil){ free(s); break; } alts[Afrom].op = CHANNOP; alts[Adev].op = CHANNOP; - if(mode == Mnorm) + if(mode == Tapoff) alts[Ainp].op = CHANSND; else alts[Ato].op = CHANSND; + break; + case Awatch: + alts[Awatch].op = CHANNOP; break; case Ainp: if(*s == 'k' || *s == 'K') --- a/sys/src/cmd/rio/xfid.c +++ b/sys/src/cmd/rio/xfid.c @@ -247,6 +247,7 @@ { Fcall t; Window *w; + char *s; w = x->f->w; if(w != nil && w->deleted){ @@ -312,8 +313,12 @@ } break; case Qtap: - chanprint(ctltap, "%c", Tapon); - break; + chanprint(ctltap, "%c%c", Tapon, x->mode); + s = recvp(ctltap); + if(s == nil) + break; + filsysrespond(x->fs, x, &t, s); + return; } t.qid = x->f->qid; t.iounit = messagesize-IOHDRSZ; @@ -369,7 +374,7 @@ w->wctlopen = FALSE; break; case Qtap: - chanprint(ctltap, "%c", Tapoff); + chanprint(ctltap, "%c%c", Tapoff, x->f->mode); break; } if(w) @@ -581,12 +586,18 @@ } e = x->data + cnt; for(p = x->data; p < e; p += strlen(p)+1){ - if(*p == '\0'){ + switch(*p){ + case '\0': fc.count = p - x->data; filsysrespond(x->fs, x, &fc, "null message type"); return; + case Tapwatch: + chanprint(ctltap, "%s", p); + break; + default: + chanprint(fromtap, "%s", p); + break; } - chanprint(fromtap, "%s", p); } break;