diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | display.c | 20 | ||||
-rw-r--r-- | display.h | 7 | ||||
-rw-r--r-- | main.c | 36 | ||||
-rw-r--r-- | runes.c | 33 | ||||
-rw-r--r-- | runes.h | 19 | ||||
-rw-r--r-- | term.c | 36 | ||||
-rw-r--r-- | term.h | 18 | ||||
-rw-r--r-- | xlib.c | 95 | ||||
-rw-r--r-- | xlib.h | 7 |
10 files changed, 167 insertions, 110 deletions
@@ -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 <cairo.h> + +#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 @@ -1,36 +0,0 @@ -#include <locale.h> -#include <stdio.h> - -#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; -} @@ -1,36 +1,21 @@ -#include <cairo.h> -#include <stdlib.h> +#include <locale.h> +#include <stdio.h> #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; } @@ -2,20 +2,17 @@ #define _RUNES_H #include <cairo.h> +#include <uv.h> -#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 @@ -0,0 +1,36 @@ +#include <cairo.h> +#include <stdlib.h> + +#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); +} @@ -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 @@ -2,8 +2,9 @@ #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> +#include <uv.h> -#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) @@ -3,17 +3,16 @@ #include <X11/Xlib.h> -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 |