shithub: libacme

Download patch

ref: b168e70e99b9376220b15677d95ba3339515c6f5
parent: adf4a1f0608eaf424e39993c42ef54737d63e624
author: james palmer <foura@biobuf.link>
date: Mon Jun 7 07:33:18 EDT 2021

clean things up, use libthread to make some things easier

--- a/acme.h
+++ b/acme.h
@@ -8,37 +8,47 @@
 typedef struct AEvent AEvent;
 
 struct AWin {
-	int id;		/* acme window id */
+	int id;
 	
-	/* file descriptors */
-	int ctl;
-	int event;
-	int addr;
-	int data;
+	int ctlfd;
+	int eventfd;
+	int addrfd;
+	int datafd;
+	int bodyfd;
 	
-	void *aux;	/* user data */
+	Channel *eventc;
+	
+	void *aux;
+	
+	AWin *next;
 };
 
 struct AEvent {
-	char origin;				/* mouse, keyboard, etc. */
-	char type;					/* delete, exec, etc. */
-	int p;						/* click point */
-	int q0, q1;					/* expanded text */
-	int flags;					/* event flags */
-	int ntext;					/* how much text */
-	char text[AEventSz + 1];	/* text from the event */
+	char origin;
+	char type;
+	
+	int p;
+	int q0, q1;
+	int flags;
+	
+	int ntext;
+	char text[AEventSz + 1];
 };
 
 int		awinfsopen(AWin *, char *, int);
+
 AWin *	awincreate(void);
 void	awinclose(AWin *);
-void	awintitle(AWin *, char *, ...);
+void	awincloseall(void);
+
 void	awinctl(AWin *, char *, ...);
 void	awinclear(AWin *);
-void	awinappend(AWin *, char *, ...);
-void	awinerror(AWin *, char *,	...);
+void	awinprint(AWin *, char *, ...);
+void	awinerror(AWin *, char *, ...);
+void	awinfatal(AWin *, char *, ...);
 void	awinaddtag(AWin *, char *);
 void	awinsettag(AWin *, char *);
 
-int aeventnext(AWin *, AEvent *);
-void aeventsend(AWin *, AEvent *);
+Channel *	aeventlisten(AWin *);
+void		aeventstop(AWin *);
+void		aeventsend(AWin *, AEvent *);
--- a/event.c
+++ b/event.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <thread.h>
 #include <bio.h>
 
 #include "acme.h"
@@ -38,23 +39,21 @@
 	return len;
 }
 
-int
-aeventnext(AWin *w, AEvent *ev)
+static int
+aeventnext(Biobuf *bio, AEvent *ev)
 {
 	int flags;
-	Biobuf bio;
 	
 	flags = 0;
-	Binit(&bio, w->event, OREAD);
 	
 Again:
-	ev->origin = Bgetc(&bio);
-	ev->type = Bgetc(&bio);
-	ev->q0 = aeventgetnum(&bio);
-	ev->q1 = aeventgetnum(&bio);
-	ev->flags = aeventgetnum(&bio);
-	ev->ntext = aeventgetdata(&bio, ev);
-	if(Bgetc(&bio) != '\n') {
+	ev->origin = Bgetc(bio);
+	ev->type = Bgetc(bio);
+	ev->q0 = aeventgetnum(bio);
+	ev->q1 = aeventgetnum(bio);
+	ev->flags = aeventgetnum(bio);
+	ev->ntext = aeventgetdata(bio, ev);
+	if(Bgetc(bio) != '\n') {
 		werrstr("unterminated mesage");
 		return -1;
 	}
@@ -69,11 +68,52 @@
 	return ev->origin;
 }
 
+static void
+aeventproc(void *aux)
+{
+	AWin *w;
+	Channel *c;
+	Biobuf bio;
+	AEvent ev;
+	
+	w = aux;
+	c = w->eventc;
+	Binit(&bio, w->eventfd, OREAD);
+	
+	while(aeventnext(&bio, &ev)) {
+		if(send(c, &ev) < 0) {
+			Bterm(&bio);
+			exits(nil);
+		}
+	}
+}
+
+Channel *
+aeventlisten(AWin *w)
+{
+	if(w->eventc)
+		return w->eventc;
+		
+	w->eventc = chancreate(sizeof(AEvent), 0);
+	proccreate(aeventproc, w, 4096);
+	
+	return w->eventc;
+}
+
 void
+aeventstop(AWin *w)
+{
+	if(w->eventc) {
+		chanclose(w->eventc);
+		w->eventc = nil;
+	}
+}
+
+void
 aeventsend(AWin *w, AEvent *ev)
 {
 	if(ev->flags & 0x2)
-		fprint(w->event, "%c%c%d %d\n", ev->origin, ev->type, ev->p, ev->p);
+		fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->p, ev->p);
 	else
-		fprint(w->event, "%c%c%d %d\n", ev->origin, ev->type, ev->q0, ev->q1);
+		fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->q0, ev->q1);
 }
--- a/window.c
+++ b/window.c
@@ -1,17 +1,21 @@
 #include <u.h>
 #include <libc.h>
+#include <thread.h>
 
 #include "acme.h"
 
+static AWin *awins;
+
 int
-awinfsopen(AWin *w, char *f, int mode)
+awinfsopen(AWin *w, char *file, int mode)
 {
 	char buf[128];
 	int fd;
-	
-	snprint(buf, sizeof(buf), "/mnt/wsys/%d/%s", w->id, f);
+
+	snprint(buf, sizeof(buf), "/mnt/wsys/%d/%s", w->id, file);
 	if((fd = open(buf, mode|OCEXEC)) < 0)
-		sysfatal("open %s: %r", buf);
+		sysfatal("open %s: %r", file);
+
 	return fd;
 }
 
@@ -22,16 +26,19 @@
 	char buf[12];
 	
 	w = mallocz(sizeof(AWin), 1);
-	w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
-	if(w->ctl < 0)
+	w->ctlfd = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
+	if(w->ctlfd < 0)
 		sysfatal("open ctl: %r");
-	if(read(w->ctl, buf, sizeof(buf)) != sizeof(buf))
+	if(read(w->ctlfd, buf, sizeof(buf)) != sizeof(buf))
 		sysfatal("read ctl: %r");
 	
 	w->id = atoi(buf);
-	w->event = awinopen(w, "event", ORDWR);
-	w->addr = awinopen(w, "addr", ORDWR);
-	w->data = awinopen(w, "data", ORDWR);
+	w->eventfd = awinfsopen(w, "event", ORDWR);
+	w->addrfd = awinfsopen(w, "addr", ORDWR);
+	w->datafd = awinfsopen(w, "data", ORDWR);
+
+	w->next = awins;
+	awins = w;
 	
 	return w;
 }
@@ -39,27 +46,44 @@
 void
 awinclose(AWin *w)
 {
-	fprint(w->ctl, "delete");
+	AWin *temp;
 	
-	close(w->event);
-	close(w->addr);
-	close(w->data);
+	fprint(w->ctlfd, "delete");
+
+	close(w->eventfd);
+	close(w->addrfd);
+	close(w->datafd);
 	
-	free(w);
+	temp = awins;
+	while(temp) {
+		if(awins->next == w) {
+			temp->next = w->next;
+			free(w);
+			return;
+		}
+		
+		temp = awins->next;
+	}
 }
 
 void
-awintitle(AWin *w, char *fmt, ...)
+awincloseall(void)
 {
-	char *title;
-	va_list args;
+	AWin *temp;
 	
-	va_start(args, fmt);
-	title = vsmprint(fmt, args);
-	va_end(args);
-	
-	awinctl(w, "name %s\n", title);
-	free(title);
+	temp = awins;
+	while(temp) {
+		fprint(temp->ctlfd, "delete");
+		
+		close(temp->eventfd);
+		close(temp->addrfd);
+		close(temp->datafd);
+		
+		awins = temp->next;
+		free(temp);
+		temp = awins;
+		
+	}
 }
 
 void
@@ -68,7 +92,7 @@
 	va_list args;
 	
 	va_start(args, fmt);
-	vfprint(w->ctl, fmt, args);
+	vfprint(w->ctlfd, fmt, args);
 	va_end(args);
 }
 
@@ -75,17 +99,17 @@
 void
 awinclear(AWin *w)
 {
-	fprint(w->addr, ",");
-	fprint(w->data, "");
+	fprint(w->addrfd, ",");
+	fprint(w->datafd, "");
 }
 
 void
-awinappend(AWin *w, char *fmt, ...)
+awinprint(AWin *w, char *fmt, ...)
 {
 	int fd;
 	va_list args;
 	
-	fd = awinopen(w, "body", OWRITE);
+	fd = awinfsopen(w, "body", OWRITE);
 	
 	va_start(args, fmt);
 	vfprint(fd, fmt, args);
@@ -97,35 +121,51 @@
 void
 awinerror(AWin *w, char *fmt, ...)
 {
-	int errorfd;
+	int fd;
 	va_list args;
 	
-	errorfd = awinopen(w, "errors", OWRITE);
+	fd = awinfsopen(w, "errors", OWRITE);
 	
 	va_start(args, fmt);
-	vfprint(errorfd, fmt, args);
+	vfprint(fd, fmt, args);
 	va_end(args);
 	
-	close(errorfd);
+	close(fd);
 }
 
 void
+awinfatal(AWin *w, char *fmt, ...)
+{
+	int fd;
+	va_list args;
+	
+	fd = awinfsopen(w, "body", OWRITE);
+	
+	va_start(args, fmt);
+	vfprint(fd, fmt, args);
+	va_end(args);
+	
+	awinclose(w);
+	close(fd);
+}
+
+void
 awinaddtag(AWin *w, char *tag)
 {
-	int tagfd;
+	int fd;
 	
-	tagfd = awinopen(w, "tag", OWRITE);
-	fprint(tagfd, "%s ", tag);
-	close(tagfd);
+	fd = awinfsopen(w, "tag", OWRITE);
+	fprint(fd, "%s ", tag);
+	close(fd);
 }
 
 void
 awinsettag(AWin *w, char *tag)
 {
-	int tagfd;
+	int fd;
 	
 	awinctl(w, "cleartag");
-	tagfd = awinopen(w, "tag", OWRITE);
-	fprint(tagfd, "%s", tag);
-	close(tagfd);
+	fd = awinfsopen(w, "tag", OWRITE);
+	fprint(fd, "%s", tag);
+	close(fd);
 }