shithub: fork

Download patch

ref: a361f085ba12a0c1b286b0763326a3c637ab8548
parent: f47f1ddc63b903e05df5893d2b43c5f80830596d
author: qwx <qwx@sciops.net>
date: Sat May 4 15:11:12 EDT 2024

bof: add missing changes from upstream

what the fuck

--- a/sys/src/cmd/bof/dat.h
+++ b/sys/src/cmd/bof/dat.h
@@ -173,6 +173,7 @@
 	uchar		deleted;
 	uchar		mouseopen;
 	uchar		kbdopen;
+	uchar		keyup;
 	uchar		winnameread;
 	char			*label;
 	char			*dir;
@@ -322,16 +323,10 @@
 int		gotscreen;
 int		servekbd;
 
-enum{
-	Tapon = 'b',
-	Tapoff = 'e',
-	Tapfocus = 'z',
-};
-Channel *ctltap;	/* open/close */
-Channel *resptap;	/* open/close err */
-Channel	*fromtap;	/* input from kbd tap program to window */
+Channel *opentap;	/* open fromtap or totap */
+Channel *closetap;	/* close fromtap or totap */
+Channel	*fromtap;	/* keyboard output from the tap program */
 Channel *totap;		/* our keyboard input to tap program */
-Channel *wintap;	/* tell the tapthread which Window to send to */
 
 Window	*input;
 QLock	all;			/* BUG */
--- a/sys/src/cmd/bof/rio.c
+++ b/sys/src/cmd/bof/rio.c
@@ -193,12 +193,9 @@
 	kbdchan = initkbd();
 	if(kbdchan == nil)
 		error("can't find keyboard");
-	totap = chancreate(sizeof(char*), 32);
-	fromtap = chancreate(sizeof(char*), 32);
-	wintap = chancreate(sizeof(Window*), 0);
-	ctltap = chancreate(sizeof(char*), 0);
-	resptap = chancreate(sizeof(char*), 0);
-	proccreate(keyboardtap, nil, STACK);
+	opentap = chancreate(sizeof(Channel*), 0);
+	closetap = chancreate(sizeof(Channel*), 0);
+	threadcreate(keyboardtap, nil, STACK);
 
 	wscreen = allocscreen(screen, cols[Crioback], 0);
 	if(wscreen == nil)
@@ -335,8 +332,6 @@
 		}
 	fprint(2, "rio %d: abort: %s\n", getpid(), msg);
 	abort();
-	exits(msg);
-	return 0;
 }
 
 void
@@ -349,148 +344,73 @@
 			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 *e;
-	char *watched;
-	Window *w, *cur;
-	static char keys[64];
+	Window *cur = nil;
+	Channel *c;
+	char *s;
 
+	enum { Akbd, Aopen, Aclose, Awrite, NALT };
+	Alt alts[NALT+1] = {
+		[Akbd]	{.c = kbdchan, .v = &s, .op = CHANRCV},
+		[Aopen] {.c = opentap, .v = &c, .op = CHANRCV},
+		[Aclose]{.c = closetap, .v = &c, .op = CHANRCV},
+		[Awrite]{.c = nil, .v = &s, .op = CHANNOP},
+		[NALT]	{.op = CHANEND},
+	};
+
 	threadsetname("keyboardtap");
-	enum { Awin, Actl, Afrom, Adev, Ato, Ainp, Awatch, NALT };
-	static Alt alts[NALT+1];
-	/* ctl */
-	alts[Awin].c = wintap;
-	alts[Awin].v = &w;
-	alts[Awin].op = CHANRCV;
-	alts[Actl].c = ctltap;
-	alts[Actl].v = &ctl;
-	alts[Actl].op = CHANRCV;
-	/* kbd input */
-	alts[Afrom].c = fromtap;
-	alts[Afrom].v = &s;
-	alts[Afrom].op = CHANRCV;
-	alts[Adev].c = kbdchan;
-	alts[Adev].v = &s;
-	alts[Adev].op = CHANRCV;
-	/* kbd output */
-	alts[Ato].c = totap;
-	alts[Ato].v = &s;
-	alts[Ato].op = CHANNOP;
-	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;
-	watched = nil;
-	keys[0] = 0;
-	for(;;)
+	for(;;){
 		switch(alt(alts)){
-		case Awin:
-			cur = w;
-			if(cur != nil){
-				alts[Ainp].c = cur->ck;
-				if(tapseats[OREAD] != Tapoff){	
-					if(alts[Awatch].op == CHANSND)
-						free(watched);
-					watched = smprint("%c%d", Tapfocus, cur->id);
-					alts[Awatch].op = CHANSND;
+		case Akbd:
+			if(*s == 'k' || *s == 'K')
+				shiftdown = utfrune(s+1, Kshift) != nil;
+			if(totap == nil)
+				goto Bypass;
+			if(input != nil && input != cur){	/* context change */
+				char *z = smprint("z%d", input->id);
+				if(nbsendp(totap, z) != 1){
+					free(z);
+					goto Bypass;
 				}
 			}
-			if(alts[Ainp].op != CHANNOP || alts[Ato].op != CHANNOP)
-				free(s);
-			if(cur == nil)
-				goto Reset;
-			s = smprint("K%s", keys);
-			alts[Ainp].op = CHANSND;
-			alts[Ato].op = CHANNOP;
+			cur = input;
+			if(nbsendp(totap, s) != 1)
+				goto Bypass;
 			break;
-		case Actl:
-			e = tapctlmsg(ctl);
-			sendp(resptap, e);
-			if(e != nil || *ctl != Tapoff){
-				free(ctl);
-				break;
+		case Aopen:
+			if(c == fromtap){
+				alts[Awrite].c = c;
+				alts[Awrite].op = CHANRCV;
 			}
-			free(ctl);
-			goto Reset;
-		case Afrom:
-			if(cur == nil){
+			break;
+		case Aclose:
+			if(c == fromtap){
+				fromtap = nil;
+				alts[Awrite].c = nil;
+				alts[Awrite].op = CHANNOP;
+			}
+			if(c == totap)
+				totap = nil;
+			chanfree(c);
+			break;
+		case Awrite:
+			if(input != cur){
 				free(s);
 				break;
 			}
-			alts[Afrom].op = CHANNOP;
-			alts[Adev].op = CHANNOP;
-			alts[Ato].op = CHANNOP;
-			alts[Ainp].op = CHANSND;
-			break;
-		case Adev:
-			if(s[0] == 'k' || s[0] == 'K')
-				strcpy(keys, s+1);
-			if(tapseats[OWRITE] == Tapoff && cur == nil){
+		Bypass:
+			cur = input;
+			if(cur == nil){
 				free(s);
 				break;
 			}
-			alts[Afrom].op = CHANNOP;
-			alts[Adev].op = CHANNOP;
-			if(tapseats[OWRITE] == Tapoff)
-				alts[Ainp].op = CHANSND;
-			else
-				alts[Ato].op = CHANSND;
+			sendp(cur->ck, s);
 			break;
-		case Awatch:
-			alts[Awatch].op = CHANNOP;
-			break;
-		case Ainp:
-			if(*s == 'k' || *s == 'K')
-				shiftdown = utfrune(s+1, Kshift) != nil;
-		case Ato:
-		Reset:
-			alts[Ainp].op = CHANNOP;
-			alts[Ato].op = CHANNOP;
-			alts[Afrom].op = CHANRCV;
-			alts[Adev].op = CHANRCV;
-			break;
 		}
+	}
 }
 
 int
--- a/sys/src/cmd/bof/wctl.c
+++ b/sys/src/cmd/bof/wctl.c
@@ -149,11 +149,12 @@
 	int minx, miny, dx, dy;
 
 	dx = max(Dx(screen->r) / 4, 400);
-	dy = min(Dy(screen->r) / 3, Dy(screen->r) - 1.5*Borderwidth);
+	dy = Dy(screen->r) - 1.5*Borderwidth;
 	minx = 16*i;
 	miny = 16*i;
 	i++;
 	i %= 10;
+
 	return Rect(minx, miny, minx+dx, miny+dy);
 }
 
--- a/sys/src/cmd/bof/wind.c
+++ b/sys/src/cmd/bof/wind.c
@@ -83,7 +83,6 @@
 	Channel *c;
 
 	if(input == nil){
-		sendp(wintap, w);
 		input = w;
 		return;
 	}
@@ -90,7 +89,6 @@
 	if(w == input)
 		return;
 	incref(input);
-	sendp(wintap, w);
 	c = chancreate(sizeof(Window*), 0);
 	wsendctlmesg(input, Repaint, ZR, c);
 	sendp(c, w);		/* send the new input */
@@ -1305,7 +1303,6 @@
 		return;
 	w->deleted = TRUE;
 	if(w == input){
-		sendp(wintap, nil);
 		input = nil;
 		riosetcursor(nil);
 	}
@@ -1384,11 +1381,12 @@
 			Channel *c = p;
 			input = recvp(c);
 
-			/* when we lost input, release mouse buttons */
+			/* when we lost input, release mouse and keyboard buttons */
 			if(w->mc.buttons){
 				w->mc.buttons = 0;
 				w->mouse.counter++;
 			}
+			w->keyup = w->kbdopen;
 			w->wctlready = 1;
 
 			sendp(c, w);
@@ -1559,9 +1557,9 @@
 			alts[WWread].op = CHANNOP;
 			alts[WCread].op = CHANNOP;
 		} else {
-			alts[WKbdread].op = (w->kbdopen && kbdqw != kbdqr) ?
+			alts[WKbdread].op = w->kbdopen && (kbdqw != kbdqr || w->keyup) ?
 				CHANSND : CHANNOP;
-			alts[WMouseread].op = (w->mouseopen && w->mouse.counter != w->mouse.lastcounter) ? 
+			alts[WMouseread].op = w->mouseopen && w->mouse.counter != w->mouse.lastcounter ? 
 				CHANSND : CHANNOP;
 			alts[WCwrite].op = w->scrolling || w->mouseopen || (w->qh <= w->org+w->nchars) ?
 				CHANSND : CHANNOP;
@@ -1614,6 +1612,11 @@
 				free(kbds);
 				nb += i;
 				kbdqr++;
+			}
+			if(w->keyup && nb+2 <= pair.ns){
+				w->keyup = 0;
+				memmove((char*)pair.s + nb, "K", 2);
+				nb += 2;
 			}
 			pair.ns = nb;
 			send(crm.c2, &pair);
--- a/sys/src/cmd/bof/xfid.c
+++ b/sys/src/cmd/bof/xfid.c
@@ -248,7 +248,6 @@
 {
 	Fcall t;
 	Window *w;
-	char *s;
 
 	w = x->f->w;
 	if(w != nil && w->deleted){
@@ -314,12 +313,23 @@
 		}
 		break;
 	case Qtap:
-		chanprint(ctltap, "%c%c", Tapon, x->mode);
-		s = recvp(resptap);
-		if(s == nil)
-			break;
-		filsysrespond(x->fs, x, &t, s);
-		return;
+		if((x->mode == OWRITE || x->mode == ORDWR) && fromtap != nil){
+			filsysrespond(x->fs, x, &t, Einuse);
+			return;
+		}
+		if(x->mode == OREAD || x->mode == ORDWR){
+			if(totap != nil){
+				filsysrespond(x->fs, x, &t, Einuse);
+				return;
+			}
+			totap = chancreate(sizeof(char*), 32);
+			sendp(opentap, totap);
+		}
+		if(x->mode == OWRITE || x->mode == ORDWR){
+			fromtap = chancreate(sizeof(char*), 32);
+			sendp(opentap, fromtap);
+		}
+		break;
 	case Qdot:
 		if(x->mode == ORDWR || x->mode == OWRITE){
 			filsysrespond(x->fs, x, &t, Enope);
@@ -381,8 +391,10 @@
 			w->wctlopen = FALSE;
 		break;
 	case Qtap:
-		chanprint(ctltap, "%c%c", Tapoff, x->f->mode);
-		recvp(resptap);
+		if(fromtap != nil && (x->f->mode == OWRITE || x->f->mode == ORDWR))
+			sendp(closetap, fromtap);
+		if(totap != nil && (x->f->mode == OREAD || x->f->mode == ORDWR))
+			sendp(closetap, totap);
 		break;
 	}
 	if(w)
@@ -603,8 +615,7 @@
 				fc.count = p - x->data;
 				filsysrespond(x->fs, x, &fc, "null message type");
 				return;
-			case Tapfocus:
-				/* cleanup our own pollution */
+			case 'z':	/* ignore context change */
 				break;
 			default:
 				chanprint(fromtap, "%s", p);
@@ -738,6 +749,7 @@
 		break;
 
 	case Qtap:
+		assert(totap != nil);
 		alts[Adata].c = totap;
 		alts[Adata].v = &t;
 		alts[Adata].op = CHANRCV;