diff options
author | Jacob Moody <moody@posixcafe.org> | 2022-09-28 02:33:23 +0000 |
---|---|---|
committer | Jacob Moody <moody@posixcafe.org> | 2022-09-28 02:33:23 +0000 |
commit | a1d252ff9b58c9c9bf3bf8765e4cf2c988ed51d4 (patch) | |
tree | 63261e6e69ead15b279d537dbc1f461577425e9e | |
parent | 03f9392b3a4583f36b8c5d961733bae00bc9417e (diff) |
rio: ensure single reader and single writer for kbdtap
Multiple readers eat each other's lunch, and it makes more
sense to limit use to one 'pipeline' then just one reader.
This also brings back the 'focus' message from kbdtap used
by ktrans to reset its line buffers when the user switches
windows. An event file was considered, but deemed harmful
to the artwork. To paraphrase an old excuse found in the code:
"rio just isn't structured for that. Apologies."
-rw-r--r-- | sys/src/cmd/ktrans/main.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/rio/dat.h | 5 | ||||
-rw-r--r-- | sys/src/cmd/rio/rio.c | 72 | ||||
-rw-r--r-- | sys/src/cmd/rio/xfid.c | 22 |
4 files changed, 77 insertions, 26 deletions
diff --git a/sys/src/cmd/ktrans/main.c b/sys/src/cmd/ktrans/main.c index f4f2a744e..6c702c1e6 100644 --- a/sys/src/cmd/ktrans/main.c +++ b/sys/src/cmd/ktrans/main.c @@ -497,7 +497,7 @@ keythread(void*) 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 @@ Drop: p++; switch(msg.code){ case 'c': case 'k': case 'K': - case 'r': + case 'z': break; default: goto Drop; diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index b9b882663..d9cb1432e 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -318,11 +318,14 @@ int servekbd; enum{ Tapon = 'b', Tapoff = 'e', + Tapfocus = 'z', }; -Channel *ctltap; /* on/off messages */ +Channel *ctltap; /* open/close */ +Channel *resptap; /* open/close err */ Channel *fromtap; /* input from kbd tap program to window */ Channel *totap; /* our keyboard input to tap program */ Channel *wintap; /* tell the tapthread which Window to send to */ + Window *input; QLock all; /* BUG */ Filsys *filsys; diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index 38153811c..daefffe93 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -199,7 +199,8 @@ threadmain(int argc, char *argv[]) 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); + resptap = chancreate(sizeof(char*), 0); proccreate(keyboardtap, nil, STACK); wscreen = allocscreen(screen, background, 0); @@ -350,17 +351,48 @@ killprocs(void) write(window[i]->notefd, "hangup", 6); } +static int tapseats[] = { [OREAD] Tapoff, [OWRITE] Tapoff }; + +char* +tapctlmsg(char *msg) +{ + int perm; + + perm = msg[1]; + switch(msg[0]){ + case Tapoff: + if(perm == ORDWR) + tapseats[OREAD] = Tapoff, tapseats[OWRITE] = Tapoff; + else + tapseats[perm] = Tapoff; + break; + case Tapon: + switch(perm){ + case ORDWR: + if(tapseats[OREAD] != Tapoff || tapseats[OWRITE] != Tapoff) + return "seat taken"; + tapseats[OREAD] = Tapon, tapseats[OWRITE] = Tapon; + break; + case OREAD: case OWRITE: + if(tapseats[perm] != Tapoff) + return "seat taken"; + tapseats[perm] = Tapon; + break; + } + break; + } + return nil; +} + void keyboardtap(void*) { char *s, *ctl; + char *watched; Window *w, *cur; - int mode; - enum { Awin, Actl, Afrom, Adev, Ato, Ainp, NALT }; - enum { Mnorm, Mtap }; - - threadsetname("keyboardtap"); + threadsetname("keyboardtap"); + enum { Awin, Actl, Afrom, Adev, Ato, Ainp, Awatch, NALT }; static Alt alts[NALT+1]; /* ctl */ alts[Awin].c = wintap; @@ -383,30 +415,31 @@ keyboardtap(void*) 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; + watched = nil; for(;;) switch(alt(alts)){ case Awin: cur = w; if(cur != nil){ alts[Ainp].c = cur->ck; - break; + if(tapseats[OREAD] == Tapoff) + break; + if(alts[Awatch].op == CHANSND) + free(watched); + watched = smprint("%c%d", Tapfocus, 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; - break; - case Tapoff: - mode = Mnorm; - break; - } + sendp(resptap, tapctlmsg(ctl)); free(ctl); break; case Afrom: @@ -420,17 +453,20 @@ keyboardtap(void*) alts[Ainp].op = CHANSND; break; case Adev: - if(mode == Mnorm && cur == nil){ + if(tapseats[OWRITE] == Tapoff && cur == nil){ free(s); break; } alts[Afrom].op = CHANNOP; alts[Adev].op = CHANNOP; - if(mode == Mnorm) + if(tapseats[OWRITE] == 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') shiftdown = utfrune(s+1, Kshift) != nil; diff --git a/sys/src/cmd/rio/xfid.c b/sys/src/cmd/rio/xfid.c index cee3c006d..7afe02353 100644 --- a/sys/src/cmd/rio/xfid.c +++ b/sys/src/cmd/rio/xfid.c @@ -247,6 +247,7 @@ xfidopen(Xfid *x) { Fcall t; Window *w; + char *s; w = x->f->w; if(w != nil && w->deleted){ @@ -312,8 +313,12 @@ xfidopen(Xfid *x) } break; case Qtap: - chanprint(ctltap, "%c", Tapon); - break; + chanprint(ctltap, "%c%c", Tapon, x->mode); + s = recvp(resptap); + if(s == nil) + break; + filsysrespond(x->fs, x, &t, s); + return; } t.qid = x->f->qid; t.iounit = messagesize-IOHDRSZ; @@ -369,7 +374,8 @@ xfidclose(Xfid *x) w->wctlopen = FALSE; break; case Qtap: - chanprint(ctltap, "%c", Tapoff); + chanprint(ctltap, "%c%c", Tapoff, x->f->mode); + recvp(resptap); break; } if(w) @@ -581,12 +587,18 @@ xfidwrite(Xfid *x) } 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 Tapfocus: + /* cleanup our own pollution */ + break; + default: + chanprint(fromtap, "%s", p); + break; } - chanprint(fromtap, "%s", p); } break; |