summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux2014-07-17 22:56:15 -0400
committerQuentin Carbonneaux2014-07-17 22:59:56 -0400
commit542e9ad357f69cb2af873f7c7ccb1d10270fa0da (patch)
treee69df1b1407b1667aa6fb147f5f34e9fd203df14
parent1318bb739eb187c1f38e861c52037ce49b9c4a87 (diff)
hacked a basic poll loop
-rw-r--r--Makefile2
-rw-r--r--evnt.c60
-rw-r--r--evnt.h21
-rw-r--r--gui.h5
-rw-r--r--main.c43
-rw-r--r--win.c5
-rw-r--r--x11.c27
7 files changed, 134 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index e7cdd45..5b33552 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ OBJDIR := obj
LDFLAGS += $$(pkg-config --libs x11 xft)
CFLAGS += -g --std=c99 -Wall -Wextra -I. $$(pkg-config --cflags x11 xft)
-SRCFILES := unicode.c x11.c buf.c edit.c win.c exec.c vicmd.w main.c
+SRCFILES := unicode.c evnt.c x11.c buf.c edit.c win.c exec.c vicmd.w main.c
OBJFILES := $(patsubst %.w, $(OBJDIR)/%.o, $(SRCFILES:%.c=$(OBJDIR)/%.o))
all: $(OBJDIR)/edit
diff --git a/evnt.c b/evnt.c
new file mode 100644
index 0000000..839532f
--- /dev/null
+++ b/evnt.c
@@ -0,0 +1,60 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/select.h>
+
+#include "evnt.h"
+
+ // mail a jb
+
+void die(char *);
+
+int exiting;
+
+static E *elist;
+static int ne;
+
+void
+ev_register(E e)
+{
+ elist = realloc(elist, (ne + 1) * sizeof(E));
+ assert(elist);
+ elist[ne] = e;
+ ne++;
+}
+
+void
+ev_loop()
+{
+ fd_set rfds, wfds;
+ int maxfd, flags;
+ E *e;
+
+ while (!exiting) {
+ maxfd = -1;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ for (e=elist; e-elist < ne; e++) {
+ if (e->flags & ERead)
+ FD_SET(e->fd, &rfds);
+ if (e->flags & EWrite)
+ FD_SET(e->fd, &wfds);
+ if (e->fd > maxfd)
+ maxfd = e->fd;
+ }
+ if (select(maxfd+1, &rfds, &wfds, 0, 0) == -1) {
+ if (errno == EINTR)
+ continue;
+ die("select error");
+ }
+ for (e=elist; e-elist < ne; e++) {
+ flags = 0;
+ if (FD_ISSET(e->fd, &rfds))
+ flags |= ERead;
+ if (FD_ISSET(e->fd, &wfds))
+ flags |= EWrite;
+ if (flags)
+ e->f(flags, e->p);
+ }
+ }
+}
diff --git a/evnt.h b/evnt.h
new file mode 100644
index 0000000..20a797a
--- /dev/null
+++ b/evnt.h
@@ -0,0 +1,21 @@
+#ifndef EVNT_H
+#define EVNT_H
+
+typedef struct e E;
+
+enum {
+ ERead = 1,
+ EWrite = 2,
+};
+
+struct e {
+ int fd;
+ int flags;
+ void (*f)(int, void *);
+ void *p;
+};
+
+void ev_register(E);
+void ev_loop(void);
+
+#endif /* ndef EVNT_H */
diff --git a/gui.h b/gui.h
index 8a787fb..4380bf4 100644
--- a/gui.h
+++ b/gui.h
@@ -90,14 +90,15 @@ enum {
#define CTRL(x) ((x) ^ 64)
struct gui {
- void (*init)(void);
+ int (*init)(void);
void (*fini)(void);
+ void (*sync)(void);
void (*getfont)(GFont *fret);
void (*drawtext)(GRect *clip, Rune *str, int len,
int x, int y, GColor color);
void (*drawrect)(GRect *clip, int x, int y, int w, int h, GColor c);
int (*textwidth)(Rune *str, int len);
- void (*nextevent)(GEvent *eret);
+ int (*nextevent)(GEvent *eret);
};
/* Available gui modules */
diff --git a/main.c b/main.c
index 0b0d174..05fef9c 100644
--- a/main.c
+++ b/main.c
@@ -7,12 +7,14 @@
#include "cmd.h"
#include "edit.h"
+#include "evnt.h"
#include "gui.h"
#include "win.h"
W *curwin;
int scrolling;
-int exiting;
+
+static struct gui *g;
void
die(char *m)
@@ -21,22 +23,14 @@ die(char *m)
exit(1);
}
-int
-main(int ac, char *av[])
+static void
+gev(int flag, void *unused)
{
- struct gui *g;
- EBuf *eb;
GEvent e;
- g = &gui_x11;
- win_init(g);
-
- eb = eb_new();
- eb_read(eb, ac > 1 ? av[1] : "dummy.txt");
- curwin = win_new(eb);
+ assert(flag == ERead && unused == 0);
- while (!exiting) {
- g->nextevent(&e);
+ while (g->nextevent(&e) != 0) {
switch (e.type) {
case GResize:
win_resize_frame(e.resize.width, e.resize.height);
@@ -58,12 +52,33 @@ main(int ac, char *av[])
default:
break;
}
+
if (curwin->cu >= curwin->l[curwin->nl])
curwin->cu = curwin->l[curwin->nl-1];
if (curwin->cu < curwin->l[0])
curwin->cu = curwin->l[0];
- win_redraw_frame();
}
+
+ win_redraw_frame();
+ g->sync();
+}
+
+int
+main(int ac, char *av[])
+{
+ int guifd;
+ EBuf *eb;
+
+ g = &gui_x11;
+ guifd = g->init();
+ ev_register((E){guifd, ERead, gev, 0});
+ win_init(g);
+
+ eb = eb_new();
+ eb_read(eb, eb->path = ac > 1 ? av[1] : "dummy.txt");
+ curwin = win_new(eb);
+
+ ev_loop();
}
#if 0
diff --git a/win.c b/win.c
index 597b1d7..abd186a 100644
--- a/win.c
+++ b/win.c
@@ -38,10 +38,7 @@ static int tabw;
void
win_init(struct gui *gui)
{
- g = gui;
-
- g->init();
- g->getfont(&font);
+ (g = gui)->getfont(&font);
/* initialize tab width */
tabw = TabWidth * g->textwidth((Rune[]){' '}, 1);
diff --git a/x11.c b/x11.c
index 4c69110..1670988 100644
--- a/x11.c
+++ b/x11.c
@@ -30,7 +30,7 @@ XftDraw *xft;
static int w, h;
static int dirty;
-static void
+static int
init()
{
XWindowAttributes wa;
@@ -78,6 +78,8 @@ init()
/* initialize back buffer and Xft drawing context */
pbuf = XCreatePixmap(d, win, Width, Height, depth);
xft = XftDrawCreate(d, pbuf, visual, cmap);
+
+ return XConnectionNumber(d);
}
static void
@@ -161,20 +163,27 @@ textwidth(Rune *str, int len)
}
static void
+sync()
+{
+ if (dirty) {
+ XCopyArea(d, pbuf, win, gc, 0, 0, w, h, 0, 0);
+ XFlush(d);
+ }
+}
+
+static int
nextevent(GEvent *gev)
{
XEvent e;
- if (dirty)
- goto expose;
+ while (XEventsQueued(d, QueuedAfterFlush)) {
- do {
XNextEvent(d, &e);
switch (e.type) {
case Expose:
- expose:
- XCopyArea(d, pbuf, win, gc, 0, 0, w, h, 0, 0);
+ dirty = 1;
+ sync();
continue;
case ConfigureNotify:
@@ -285,13 +294,15 @@ nextevent(GEvent *gev)
default:
continue;
}
- return;
- } while (1);
+ return 1;
+ }
+ return 0;
}
struct gui gui_x11 = {
.init = init,
.fini = fini,
+ .sync = sync,
.getfont = getfont,
.drawtext = drawtext,
.drawrect = drawrect,