diff options
| author | Quentin Carbonneaux | 2014-07-17 22:56:15 -0400 |
|---|---|---|
| committer | Quentin Carbonneaux | 2014-07-17 22:59:56 -0400 |
| commit | 542e9ad357f69cb2af873f7c7ccb1d10270fa0da (patch) | |
| tree | e69df1b1407b1667aa6fb147f5f34e9fd203df14 | |
| parent | 1318bb739eb187c1f38e861c52037ce49b9c4a87 (diff) | |
hacked a basic poll loop
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | evnt.c | 60 | ||||
| -rw-r--r-- | evnt.h | 21 | ||||
| -rw-r--r-- | gui.h | 5 | ||||
| -rw-r--r-- | main.c | 43 | ||||
| -rw-r--r-- | win.c | 5 | ||||
| -rw-r--r-- | x11.c | 27 |
7 files changed, 134 insertions, 29 deletions
@@ -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 @@ -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); + } + } +} @@ -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 */ @@ -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 */ @@ -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 @@ -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); @@ -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, |
