ref: b168e70e99b9376220b15677d95ba3339515c6f5
parent: adf4a1f0608eaf424e39993c42ef54737d63e624
author: james palmer <[email protected]>
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);
}