From 758acbc65fe52f8ac364e61c5d2d2b73083b1fe6 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 5 Apr 2014 20:22:25 -0400 Subject: use libuv to process events --- Makefile | 6 ++-- display.c | 20 ++++++++++++++ display.h | 7 +++++ main.c | 36 ------------------------ runes.c | 33 ++++++---------------- runes.h | 19 ++++++------- term.c | 36 ++++++++++++++++++++++++ term.h | 18 ++++++++++++ xlib.c | 95 ++++++++++++++++++++++++++++++++++++++++++--------------------- xlib.h | 7 ++--- 10 files changed, 167 insertions(+), 110 deletions(-) create mode 100644 display.c create mode 100644 display.h delete mode 100644 main.c create mode 100644 term.c create mode 100644 term.h diff --git a/Makefile b/Makefile index c385821..2ab83c0 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,15 @@ OUT = runes -OBJ = runes.o xlib.o main.o +OBJ = runes.o display.o xlib.o term.o CFLAGS ?= -g LDFLAGS ?= -g build: $(OUT) $(OUT): $(OBJ) - $(CC) $(shell pkg-config --libs cairo-xlib) $(LDFLAGS) -o $@ $^ + $(CC) $(shell pkg-config --libs cairo-xlib libuv) $(LDFLAGS) -o $@ $^ %.o: %.c - $(CC) $(shell pkg-config --cflags cairo-xlib) $(CFLAGS) -c -o $@ $^ + $(CC) $(shell pkg-config --cflags cairo-xlib libuv) $(CFLAGS) -c -o $@ $^ clean: rm -f $(OUT) $(OBJ) diff --git a/display.c b/display.c new file mode 100644 index 0000000..81e348b --- /dev/null +++ b/display.c @@ -0,0 +1,20 @@ +#include + +#include "runes.h" + +void runes_display_init(RunesTerm *t) +{ + cairo_select_font_face(t->cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(t->cr, 14.0); + cairo_set_source_rgb(t->cr, 0.0, 0.0, 1.0); + cairo_move_to(t->cr, 0.0, 14.0); +} + +void runes_display_glyph(RunesTerm *t, char *buf, size_t len) +{ + if (len) { + buf[len] = '\0'; + cairo_show_text(t->cr, buf); + cairo_surface_flush(t->surface); + } +} diff --git a/display.h b/display.h new file mode 100644 index 0000000..5651ccb --- /dev/null +++ b/display.h @@ -0,0 +1,7 @@ +#ifndef _RUNES_DISPLAY_H +#define _RUNES_DISPLAY_H + +void runes_display_init(RunesTerm *t); +void runes_display_glyph(RunesTerm *t, char *buf, size_t len); + +#endif diff --git a/main.c b/main.c deleted file mode 100644 index 6c7c123..0000000 --- a/main.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include - -#include "runes.h" - -int main (int argc, char *argv[]) -{ - RunesTerm *t; - - setlocale(LC_ALL, ""); - - t = runes_term_create(); - - cairo_select_font_face(t->cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size(t->cr, 14.0); - cairo_set_source_rgb(t->cr, 0.0, 0.0, 1.0); - cairo_move_to(t->cr, 0.0, 14.0); - - runes_prepare_input(t); - - for (;;) { - char *buf; - size_t len; - - runes_read_key(t, &buf, &len); - if (len) { - buf[len] = '\0'; - cairo_show_text(t->cr, buf); - cairo_surface_flush(t->surface); - } - } - - runes_term_destroy(t); - - return 0; -} diff --git a/runes.c b/runes.c index 203d01f..6ae04bc 100644 --- a/runes.c +++ b/runes.c @@ -1,36 +1,21 @@ -#include -#include +#include +#include #include "runes.h" -RunesTerm *runes_term_create() +int main (int argc, char *argv[]) { RunesTerm *t; - t = malloc(sizeof(RunesTerm)); + setlocale(LC_ALL, ""); - t->w = runes_window_create(); - t->surface = runes_surface_create(t->w); - t->cr = cairo_create(t->surface); + t = runes_term_create(); - return t; -} + runes_display_init(t); -void runes_prepare_input(RunesTerm *t) -{ - runes_window_prepare_input(t->w); -} + uv_run(t->loop, UV_RUN_DEFAULT); -void runes_read_key(RunesTerm *t, char **buf, size_t *len) -{ - runes_window_read_key(t->w, buf, len); -} - -void runes_term_destroy(RunesTerm *t) -{ - cairo_destroy(t->cr); - cairo_surface_destroy(t->surface); - runes_window_destroy(t->w); + runes_term_destroy(t); - free(t); + return 0; } diff --git a/runes.h b/runes.h index 86b0f03..36a905a 100644 --- a/runes.h +++ b/runes.h @@ -2,20 +2,17 @@ #define _RUNES_H #include +#include -#include "xlib.h" +struct runes_term; +struct runes_window; -typedef struct { - RunesWindow *w; - /* RunesBuffer *buf; */ +typedef struct runes_term RunesTerm; +typedef struct runes_window RunesWindow; - cairo_surface_t *surface; - cairo_t *cr; -} RunesTerm; +#include "term.h" +#include "display.h" -RunesTerm *runes_term_create(); -void runes_prepare_input(RunesTerm *t); -void runes_read_key(RunesTerm *t, char **buf, size_t *len); -void runes_term_destroy(RunesTerm *t); +#include "xlib.h" #endif diff --git a/term.c b/term.c new file mode 100644 index 0000000..d3345d9 --- /dev/null +++ b/term.c @@ -0,0 +1,36 @@ +#include +#include + +#include "runes.h" + +RunesTerm *runes_term_create() +{ + RunesTerm *t; + + t = malloc(sizeof(RunesTerm)); + + t->w = runes_window_create(); + t->surface = runes_surface_create(t->w); + t->cr = cairo_create(t->surface); + t->loop = runes_loop_create(t); + + return t; +} + +uv_loop_t *runes_loop_create(RunesTerm *t) +{ + uv_loop_t *loop; + + loop = uv_default_loop(); + runes_loop_init(t, loop); + return loop; +} + +void runes_term_destroy(RunesTerm *t) +{ + cairo_destroy(t->cr); + cairo_surface_destroy(t->surface); + runes_window_destroy(t->w); + + free(t); +} diff --git a/term.h b/term.h new file mode 100644 index 0000000..52d5836 --- /dev/null +++ b/term.h @@ -0,0 +1,18 @@ +#ifndef _RUNES_TERM_H +#define _RUNES_TERM_H + +struct runes_term { + RunesWindow *w; + /* RunesBuffer *buf; */ + + cairo_surface_t *surface; + cairo_t *cr; + + uv_loop_t *loop; +}; + +RunesTerm *runes_term_create(); +uv_loop_t *runes_loop_create(RunesTerm *t); +void runes_term_destroy(RunesTerm *t); + +#endif diff --git a/xlib.c b/xlib.c index 1aa7717..94d267b 100644 --- a/xlib.c +++ b/xlib.c @@ -2,8 +2,9 @@ #include #include #include +#include -#include "xlib.h" +#include "runes.h" RunesWindow *runes_window_create() { @@ -61,47 +62,77 @@ cairo_surface_t *runes_surface_create(RunesWindow *w) return cairo_xlib_surface_create(w->dpy, w->w, vis, attrs.width, attrs.height); } -void runes_window_prepare_input(RunesWindow *w) +struct loop_data { + uv_work_t req; + XEvent e; + RunesTerm *t; +}; + +static void runes_get_next_event(uv_work_t *req) { - unsigned long mask; + struct loop_data *data; - XGetICValues(w->ic, XNFilterEvents, &mask, NULL); - XSelectInput(w->dpy, w->w, mask|KeyPressMask); - XSetICFocus(w->ic); + data = (struct loop_data *)req->data; + XNextEvent(data->t->w->dpy, &data->e); } -void runes_window_read_key(RunesWindow *w, char **outbuf, size_t *outlen) +static void runes_process_event(uv_work_t *req, int status) { - static char *buf = NULL; - static size_t len = 8; - XEvent e; - Status s; - KeySym sym; - size_t chars; + struct loop_data *data; + XEvent *e; + RunesWindow *w; - if (!buf) { - buf = malloc(len); + data = ((struct loop_data *)req->data); + e = &data->e; + w = data->t->w; + + if (!XFilterEvent(e, None)) { + switch (e->type) { + case KeyPress: { + char *buf = NULL; + size_t len = 8; + KeySym sym; + Status s; + size_t chars; + + buf = malloc(len); + + for (;;) { + chars = Xutf8LookupString(w->ic, &e->xkey, buf, len - 1, &sym, &s); + if (s == XBufferOverflow) { + len = chars + 1; + buf = realloc(buf, len); + continue; + } + break; + } + + runes_display_glyph(data->t, buf, chars); + free(buf); + break; + } + default: + break; + } } - XNextEvent(w->dpy, &e); - if (XFilterEvent(&e, None) || e.type != KeyPress) { - *outlen = 0; - *outbuf = buf; - return; - } + uv_queue_work(req->loop, req, runes_get_next_event, runes_process_event); +} - for (;;) { - chars = Xutf8LookupString(w->ic, &e.xkey, buf, len - 1, &sym, &s); - if (s == XBufferOverflow) { - len = chars + 1; - buf = realloc(buf, len); - continue; - } - break; - } +void runes_loop_init(RunesTerm *t, uv_loop_t *loop) +{ + unsigned long mask; + void *data; + + XGetICValues(t->w->ic, XNFilterEvents, &mask, NULL); + XSelectInput(t->w->dpy, t->w->w, mask|KeyPressMask); + XSetICFocus(t->w->ic); + + data = malloc(sizeof(struct loop_data)); + ((struct loop_data *)data)->req.data = data; + ((struct loop_data *)data)->t = t; - *outlen = chars; - *outbuf = buf; + uv_queue_work(loop, data, runes_get_next_event, runes_process_event); } void runes_window_destroy(RunesWindow *w) diff --git a/xlib.h b/xlib.h index e2fcf70..809645e 100644 --- a/xlib.h +++ b/xlib.h @@ -3,17 +3,16 @@ #include -typedef struct { +struct runes_window { Display *dpy; Window w; GC gc; XIC ic; -} RunesWindow; +}; RunesWindow *runes_window_create(); cairo_surface_t *runes_surface_create(RunesWindow *w); -void runes_window_prepare_input(RunesWindow *w); -void runes_window_read_key(RunesWindow *w, char **buf, size_t *len); +void runes_loop_init(RunesTerm *t, uv_loop_t *loop); void runes_window_destroy(RunesWindow *w); #endif -- cgit v1.2.3-54-g00ecf