shithub: lola

Download patch

ref: 8e41616af560b69d176f9b3d4a5380e3220e8915
parent: ee60859199f151377a32b6932bde88cc6fe6007a
author: aap <[email protected]>
date: Sun Jan 29 19:52:03 EST 2023

cleanup; wctl

--- a/TODO
+++ b/TODO
@@ -1,9 +1,10 @@
 rethink resizing and repainting
-implement all Qids
-	wctl
+rethink hiding/unhiding
+file permissions
+attach names (none, new, ...)
 border resize/move
 write text
-wctl
+top/bottom/current seems to work a bit different in rio
 release keys and buttons when unfocused
 ...
 
--- a/fs.c
+++ b/fs.c
@@ -16,8 +16,8 @@
 	Qsnarf,
 	Qtext,
 	Qwdir,
-//	Qwctl,
 	Qwindow,
+	Qwctl,
 	Qtap,
 
 	NQids
@@ -47,6 +47,7 @@
 	Qcursor,	QTFILE, "cursor",
 	Qscreen,	QTFILE, "screen",
 	Qwindow,	QTFILE, "window",
+	Qwctl,	QTFILE, "wctl",
 	Qtap,	QTFILE, "kbdtap",
 };
 
@@ -169,9 +170,9 @@
 
 	w = nil;
 	if(strcmp(r->ifcall.aname, "new") == 0){
-		w = wcreate(rectaddpt(newrect(), screen->r.min));
-wsetpid(w, -1, 1);
-wsetname(w);
+// TODO: parse
+		w = wcreate(rectaddpt(newrect(), screen->r.min), FALSE, scrolling);
+		wincmd(w, 0, nil, nil);
 		flushimage(display, 1);
 		decref(w);	/* don't delete, xfid will take it */
 	}else if(id = strtol(r->ifcall.aname, &end, 10), *end == '\0'){
@@ -329,9 +330,12 @@
 		return;
 	}
 
+	/* only text can be truncated (not implemented yet) */
+	if(QFILE(r->fid->qid.path) != Qtext)
+		r->ifcall.mode &= (OREAD|OWRITE|ORDWR);		
+
 	switch(QFILE(r->fid->qid.path)){
 	case Qsnarf:
-		r->ifcall.mode &= ~OTRUNC;
 		if(r->ifcall.mode==ORDWR || r->ifcall.mode==OWRITE)
 			ntsnarf = 0;
 		break;
@@ -362,8 +366,20 @@
 		w->mouseopen = TRUE;
 		break;
 
+	case Qwctl:
+		if(r->ifcall.mode==ORDWR || r->ifcall.mode==OREAD){
+			/* can only have one reader of wctl */
+			if(w->wctlopen){
+				respond(r, Einuse);
+				return;
+			}
+			w->wctlopen = TRUE;
+			w->wctlready = TRUE;
+			wsendmsg(w, Wakeup);
+		}
+		break;
+
 	case Qtap:
-		r->ifcall.mode &= (OREAD|OWRITE|ORDWR);
 		chanprint(ctltap, "%c%c", Tapon, r->ifcall.mode);
 		respond(r, recvp(resptap));
 		return;
@@ -397,11 +413,11 @@
 	case Qconsctl:
 		if(x->rawmode){
 			x->rawmode = 0;
-			wsendmsg(w, Rawoff, ZR, nil);
+			wsendmsg(w, Rawoff);
 		}
 		if(w->holdmode > 0){
 			w->holdmode = 1;
-			wsendmsg(w, Holdoff, ZR, nil);
+			wsendmsg(w, Holdoff);
 		}
 		w->consctlopen = FALSE;
 		break;
@@ -413,7 +429,7 @@
 	case Qmouse:
 		w->mouseopen = FALSE;
 		w->resized = FALSE;
-		wsendmsg(w, Refresh, ZR, nil);
+		wsendmsg(w, Refresh);
 		break;
 
 	case Qcursor:
@@ -421,6 +437,11 @@
 		wsetcursor(w);
 		break;
 
+	case Qwctl:
+		if(fid->omode==ORDWR || fid->omode==OREAD)
+			w->wctlopen = FALSE;
+		break;
+
 	case Qtap:
 		chanprint(ctltap, "%c%c", Tapoff, fid->omode);
 		recvp(resptap);
@@ -575,6 +596,13 @@
 	case Qwindow:
 		respond(r, readimg(r, w->img));
 		return;
+	case Qwctl:
+		if(r->ifcall.count < 4*12){
+			respond(r, Etooshort);
+			return;
+		}
+		respond(r, readblocking(r, w->wctlread));
+		return;
 	case Qtap:
 		respond(r, readblocking(r, totap));
 		return;
@@ -638,25 +666,25 @@
 
 	case Qconsctl:
 		if(strncmp(data, "holdon", 6) == 0){
-			wsendmsg(w, Holdon, ZR, nil);
+			wsendmsg(w, Holdon);
 			break;
 		}
 		if(strncmp(data, "holdoff", 7) == 0){
-			wsendmsg(w, Holdoff, ZR, nil);
+			wsendmsg(w, Holdoff);
 			break;
 		}
 		if(strncmp(data, "rawon", 5) == 0){
 			if(w->holdmode){
 				w->holdmode = 1;
-				wsendmsg(w, Holdoff, ZR, nil);
+				wsendmsg(w, Holdoff);
 			}
 			if(x->rawmode++ == 0)
-				wsendmsg(w, Rawon, ZR, nil);
+				wsendmsg(w, Rawon);
 			break;
 		}
 		if(strncmp(data, "rawoff", 6) == 0){
 			if(--x->rawmode == 0)
-				wsendmsg(w, Rawoff, ZR, nil);
+				wsendmsg(w, Rawoff);
 			break;
 		}
 		respond(r, "unknown control message");
@@ -735,6 +763,15 @@
 		free(w->dir);
 		w->dir = cleanname(p);
 		break;
+
+	case Qwctl:
+		/* sucks that we have no space for '\0' */
+		p = emalloc(count+1);
+		memmove(p, data, count);
+		p[count] = '\0';
+		respond(r, writewctl(w, p));
+		free(p);
+		return;
 
 	case Qtap:
 		if(count < 2){
--- a/inc.h
+++ b/inc.h
@@ -14,7 +14,9 @@
 typedef uchar bool;
 enum {
 	FALSE = 0,
-	TRUE = 1
+	TRUE = 1,
+
+	BIG = 3
 };
 
 #define ALT(c, v, t) (Alt){ c, v, t, nil, nil, 0 }
@@ -153,7 +155,8 @@
 enum
 {
 	Closed,
-	Reshaped,
+	Resized,
+	Moved,
 	Deleted,
 	Refresh,
 	Holdon,
@@ -163,14 +166,6 @@
 	Wakeup
 };
 
-typedef struct Wctlmesg Wctlmesg;
-struct Wctlmesg
-{
-	int type;
-	Rectangle r;
-	void *p;
-};
-
 typedef struct Window Window;
 struct Window
 {
@@ -192,8 +187,10 @@
 	Text text;
 	Rectangle scrollr;
 	Rectangle textr;
-	bool scrolling;
 	int holdmode;
+	bool scrolling;
+	bool wctlready;
+	bool wctlopen;
 
 	Mousectl mc;
 	Mousequeue mq;
@@ -208,13 +205,14 @@
 	bool consctlopen;
 	bool kbdopen;
 
-	Channel *gone;		// window gone
-	Channel *ctl;		// Wctlmesg
-	/* channels to xfids */
+	Channel *gone;		/* window gone */
+	Channel *ctl;		/* Wctlmesg */
+	/* channels to xreqs */
 	Channel *conswrite;
 	Channel *consread;
 	Channel *kbdread;
 	Channel *mouseread;
+	Channel *wctlread;
 	Channel *complete;
 };
 
@@ -227,9 +225,9 @@
 
 void wdecor(Window *w);
 void wresize(Window *w, Rectangle r);
-Window *wcreate(Rectangle r);
+Window *wcreate(Rectangle r, bool hidden, bool scrolling);
 int wrelease(Window *w);
-void wsendmsg(Window *w, int type, Rectangle r, void *p);
+void wsendmsg(Window *w, int type);
 Window *wfind(int id);
 Window *wpointto(Point pt);
 void wsetcursor(Window *w);
@@ -240,8 +238,8 @@
 void wraise(Window *w);
 void wlower(Window *w);
 void wfocus(Window *w);
-void whide(Window *w);
-void wunhide(Window *w);
+int whide(Window *w);
+int wunhide(Window *w);
 void wsethold(Window *w, int hold);
 void wmovemouse(Window *w, Point pt);
 void wtype(Window *w, Rune r);
@@ -248,6 +246,9 @@
 void wsetname(Window *w);
 void wsetpid(Window *w, int pid, int dolabel);
 void winshell(void *args);
+int wincmd(Window *w, int pid, char *dir, char **argv);
+
+char *writewctl(Window *w, char *data);
 
 enum{
 	Tapon = 'b',
--- a/main.c
+++ b/main.c
@@ -151,24 +151,6 @@
 	free(sn);
 }
 
-Rectangle
-newrect(void)
-{
-	static int i = 0;
-	int minx, miny, dx, dy;
-
-//	dx = min(600, Dx(screen->r) - 2*Borderwidth);
-//	dy = min(400, Dy(screen->r) - 2*Borderwidth);
-	dx = 600;
-	dy = 400;
-	minx = 32 + 16*i;
-	miny = 32 + 16*i;
-	i++;
-	i %= 10;
-
-	return Rect(minx, miny, minx+dx, miny+dy);
-}
-
 static int overridecursor;
 static Cursor *ovcursor;
 static Cursor *normalcursor;
@@ -204,33 +186,11 @@
 new(Rectangle r)
 {
 	Window *w;
-	Channel *cpid;
-	void *args[5];
-	int pid;
 
-	w = wcreate(r);
+	w = wcreate(r, FALSE, scrolling);
 	assert(w);
-	w->scrolling = scrolling;
-	cpid = chancreate(sizeof(int), 0);
-	assert(cpid);
-
-	args[0] = w;
-	args[1] = cpid;
-	args[2] = "/bin/rc";
-	args[3] = rcargv;
-	args[4] = nil;
-	proccreate(winshell, args, mainstacksize);
-	pid = recvul(cpid);
-	chanfree(cpid);
-
-	if(pid == 0){
-		print("proc create failed\n");
+	if(wincmd(w, 0, nil, rcargv) == 0)
 		return nil;
-	}
-
-	wsetpid(w, pid, 1);
-	wsetname(w);
-
 	return w;
 }
 
@@ -481,7 +441,7 @@
 			xshow(x, x->nr);
 		break;
 	}
-	wsendmsg(w, Wakeup, ZR, nil);
+	wsendmsg(w, Wakeup);
 }
 
 void
@@ -515,7 +475,7 @@
 		break;
 	case Delete:
 		w = pick();
-		if(w) wsendmsg(w, Deleted, ZR, nil);
+		if(w) wsendmsg(w, Deleted);
 		break;
 	case Hide:
 		w = pick();
--- a/mkfile
+++ b/mkfile
@@ -5,6 +5,7 @@
 	main.$O \
 	text.$O \
 	wind.$O \
+	wctl.$O \
 	fs.$O \
 	util.$O \
 	time.$O
--- a/text.c
+++ b/text.c
@@ -262,7 +262,6 @@
  */
 
 static Image *scrtmp;
-enum { BIG = 3 };
 
 static Image*
 scrtemps(void)
@@ -924,7 +923,7 @@
 	if(fd < 0)
 		return 0;
 	m = emalloc(sizeof(Plumbmsg));
-	m->src = estrdup("rio");
+	m->src = estrdup("lola");		/* TODO: argument? */
 	m->dst = nil;
 	m->wdir = estrdup(dir);
 	m->type = estrdup("text");
--- a/wind.c
+++ b/wind.c
@@ -81,12 +81,17 @@
 static void
 wsetsize(Window *w, Rectangle r)
 {
+	Rectangle hr;
+
 	if(w->img)
 		freeimage(w->img);
-	w->img = allocwindow(wscreen, r, Refbackup, DNofill);
+	if(w->hidden){
+		hr = rectaddpt(r, subpt(screen->r.max, r.min));
+		w->img = allocwindow(wscreen, hr, Refbackup, DNofill);
+		originwindow(w->img, r.min, hr.min);
+	}else
+		w->img = allocwindow(wscreen, r, Refbackup, DNofill);
 	wcalcrects(w);
-// might be worth a try!
-//replclipr(w->img,0,w->contrect);
 	draw(w->img, w->img->r, colors[BACK], nil, ZP);
 	xinit(&w->text, w->textr, w->scrollr, font, w->img, colors);
 	wdecor(w);
@@ -95,7 +100,7 @@
 static int id = 1;
 
 Window*
-wcreate(Rectangle r)
+wcreate(Rectangle r, bool hidden, bool scrolling)
 {
 	Window *w;
 
@@ -105,6 +110,8 @@
 	w->notefd = -1;
 	w->label = estrdup("<unnamed>");
 	w->dir = estrdup(startdir);
+	w->hidden = hidden;
+	w->scrolling = scrolling;
 	wsetsize(w, r);
 	wlistpushfront(w);
 	// TMP - make dynamic
@@ -115,14 +122,17 @@
 
 	w->gone = chancreate(sizeof(int), 0);
 	w->kbd = chancreate(sizeof(char*), 16);
-	w->ctl = chancreate(sizeof(Wctlmesg), 0);
+	w->ctl = chancreate(sizeof(int), 0);
 	w->conswrite = chancreate(sizeof(Channel**), 0);
 	w->consread = chancreate(sizeof(Channel**), 0);
 	w->kbdread = chancreate(sizeof(Channel**), 0);
 	w->mouseread = chancreate(sizeof(Channel**), 0);
+	w->wctlread = chancreate(sizeof(Channel**), 0);
 	w->complete = chancreate(sizeof(Completion*), 0);
 	threadcreate(winthread, w, mainstacksize);
 
+	wsetname(w);
+
 	return w;
 }
 
@@ -141,6 +151,7 @@
 	chanclose(w->consread);
 	chanclose(w->kbdread);
 	chanclose(w->mouseread);
+	chanclose(w->wctlread);
 	chanclose(w->complete);
 	free(w->label);
 	free(w);
@@ -165,8 +176,8 @@
 		}
 
 	if(w->img){
-// rio does this, useful?
-//		originwindow(w->img, w->img->r.min, screen->r.max);
+		/* rio does this, not sure if useful */
+		originwindow(w->img, w->img->r.min, screen->r.max);
 		freeimage(w->img);
 	}
 	w->img = nil;
@@ -184,19 +195,14 @@
 	if(i < 0)
 		panic("negative ref count");
 	wclose(w);
-	wsendmsg(w, Closed, ZR, nil);
+	wsendmsg(w, Closed);
 	return 1;
 }
 
 void
-wsendmsg(Window *w, int type, Rectangle r, void *p)
+wsendmsg(Window *w, int type)
 {
-	Wctlmesg cm;
-
-	cm.type = type;
-	cm.r = r;
-	cm.p = p;
-	send(w->ctl, &cm);
+	sendul(w->ctl, type);
 }
 
 Window*
@@ -249,17 +255,29 @@
 	w->label = estrdup(label);
 }
 
+/* restore window order after reshaping has disturbed it */
 void
+worder(void)
+{
+	Window *w;
+	for(w = bottomwin; w; w = w->higher)
+		if(!w->hidden)
+			topwindow(w->img);
+}
+
+void
 wresize(Window *w, Rectangle r)
 {
-// TODO: maybe call wsetsize from Reshaped handler?
 	wsetsize(w, r);
-	wsendmsg(w, Reshaped, w->img->r, nil);
+	if(w != topwin && !w->hidden)
+		worder();
+	wsendmsg(w, Resized);
 }
 
 void
 wmove(Window *w, Point pos)
 {
+	Point delta;
 	/* BUG: originwindow causes the old window rect to be drawn onto the new one
 	 * with backing store of allocscreen
 	 * happens in _freeimage1(*winp); in libdraw/init.c:gengetwindow
@@ -268,17 +286,15 @@
 	 * We don't care if we're handling resizing ourselves though */
 
 	if(w->mouseopen){
-		Point delta = subpt(pos, w->img->r.min);
+		delta = subpt(pos, w->img->r.min);
 		wresize(w, rectaddpt(w->img->r, delta));
 	}else{
-		originwindow(w->img, pos, pos);
+		originwindow(w->img, pos, w->hidden ? screen->r.max : pos);
+		if(w != topwin && !w->hidden)
+			worder();
 		wcalcrects(w);
 		xsetrects(&w->text, w->textr, w->scrollr);
-
-// TODO: Reshaped changes winname, don't want that
-		w->resized = TRUE;
-		w->mc.buttons = 0;	/* avoid re-triggering clicks on resize */
-		w->mq.counter++;	/* cause mouse to be re-read */
+		wsendmsg(w, Moved);
 	}
 }
 
@@ -332,35 +348,49 @@
 	prev = focused;
 	focused = w;
 	sendp(wintap, w);
-	if(prev)
+	/* TODO a bit ugly the repitition,
+	 * but this might not stay anyways */
+	if(prev){
+		prev->wctlready = TRUE;
 		wrepaint(prev);
-	if(focused)
+		wsendmsg(prev, Wakeup);
+	}
+	if(focused){
+		focused->wctlready = TRUE;
 		wrepaint(focused);
+		wsendmsg(focused, Wakeup);
+	}
 }
 
-void
+int
 whide(Window *w)
 {
 	if(w->hidden)
-		return;
+		return -1;
 	incref(w);
 	if(w == focused)
 		wfocus(nil);
 	w->hidden = TRUE;
+	w->wctlready = TRUE;
 	originwindow(w->img, w->img->r.min, screen->r.max);
+	wsendmsg(w, Wakeup);
 	wrelease(w);
+	return 1;
 }
 
-void
+int
 wunhide(Window *w)
 {
 	if(!w->hidden)
-		return;
+		return -1;
 	incref(w);
 	w->hidden = FALSE;
+	w->wctlready = TRUE;
 	originwindow(w->img, w->img->r.min, w->img->r.min);
+	wraise(w);
 	wfocus(w);
 	wrelease(w);
+	return 1;
 }
 
 void
@@ -652,15 +682,12 @@
 }
 
 int
-winctl(Window *w, int type, Rectangle r, void *p)
+winctl(Window *w, int type)
 {
 	Text *x;
 	int i;
 
 	x = &w->text;
-/* TODO: this is kinda dumb right now. do we *really* need args? */
-(void)p;
-(void)r;
 	switch(type){
 	case Closed:
 		wfree(w);
@@ -672,10 +699,11 @@
 		wclose(w);
 		break;
 
-	case Reshaped:
-/* TODO: all the resizing code is shit */
+	case Resized:
 		wsetname(w);
+	case Moved:
 		w->resized = TRUE;
+		w->wctlready = TRUE;
 		w->mc.buttons = 0;	/* avoid re-triggering clicks on resize */
 		w->mq.counter++;	/* cause mouse to be re-read */
 		wdecor(w);
@@ -724,8 +752,9 @@
 	Text *x;
 	Rune r, *rp;
 	char *s;
-	Wctlmesg cm;
-	enum { AKbd, AMouse, ACtl, AConsWrite, AConsRead, AKbdRead, AMouseRead, AComplete, Agone, NALT };
+	int cm;
+	enum { AKbd, AMouse, ACtl, AConsWrite, AConsRead,
+		AKbdRead, AMouseRead, AWctlRead, AComplete, Agone, NALT };
 	Alt alts[NALT+1];
 	Channel *fsc;
 	Stringpair pair;
@@ -749,6 +778,7 @@
 	alts[AConsRead] = ALT(w->consread, &fsc, CHANSND);
 	alts[AKbdRead] = ALT(w->kbdread, &fsc, CHANSND);
 	alts[AMouseRead] = ALT(w->mouseread, &fsc, CHANSND);
+	alts[AWctlRead] = ALT(w->wctlread, &fsc, CHANSND);
 	alts[AComplete] = ALT(w->complete, &comp, CHANRCV);
 	alts[Agone] = ALT(w->gone, nil, CHANNOP);
 	alts[NALT].op = CHANEND;
@@ -760,6 +790,7 @@
 			alts[AConsRead].op = CHANNOP;
 			alts[AKbdRead].op = CHANNOP;
 			alts[AMouseRead].op = CHANNOP;
+			alts[AWctlRead].op = CHANNOP;
 		}else{
 			nr = xninput(x);
 			if(!w->holdmode && (nr >= 0 || cnv.n > 0 || x->rawmode && x->nraw > 0))
@@ -778,6 +809,7 @@
 				alts[AMouseRead].op = CHANSND;
 			else
 				alts[AMouseRead].op = CHANNOP;
+			alts[AWctlRead].op = w->wctlready ? CHANSND : CHANNOP;
 		}
 
 		switch(alt(alts)){
@@ -887,8 +919,18 @@
 			send(fsc, &pair);
 			break;
 
+		case AWctlRead:
+			w->wctlready = FALSE;
+			recv(fsc, &pair);
+			pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %11s %11s ",
+				w->img->r.min.x, w->img->r.min.y, w->img->r.max.x, w->img->r.max.y,
+				w == focused ? "current" : "notcurrent",
+				w->hidden ? "hidden" : "visible");
+			send(fsc, &pair);
+			break;
+
 		case ACtl:
-			if(winctl(w, cm.type, cm.r, cm.p)){
+			if(winctl(w, cm)){
 				free(cnv.buf);
 				return;
 			}
@@ -933,7 +975,7 @@
 		w->name[n+1] = 0;
 	}
 	w->name[0] = 0;
-	fprint(2, "rio: setname failed: %s\n", err);
+	fprint(2, "lola: setname failed: %s\n", err);
 }
 
 void
@@ -999,4 +1041,36 @@
 		procexec(pidc, cmd, argv);
 		_exits("exec failed");
 	}
+}
+
+int
+wincmd(Window *w, int pid, char *dir, char **argv)
+{
+	Channel *cpid;
+	void *args[5];
+
+	if(argv){
+		cpid = chancreate(sizeof(int), 0);
+		assert(cpid);
+		args[0] = w;
+		args[1] = cpid;
+		args[2] = "/bin/rc";
+		args[3] = argv;
+		args[4] = dir;
+		proccreate(winshell, args, mainstacksize);
+		pid = recvul(cpid);
+		chanfree(cpid);
+		if(pid == 0){
+			wsendmsg(w, Deleted);
+			return 0;
+		}
+	}
+
+	wsetpid(w, pid, 1);
+	if(dir){
+		free(w->dir);
+		w->dir = estrdup(dir);
+	}
+
+	return pid;
 }