aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--display.c20
-rw-r--r--display.h7
-rw-r--r--main.c36
-rw-r--r--runes.c33
-rw-r--r--runes.h19
-rw-r--r--term.c36
-rw-r--r--term.h18
-rw-r--r--xlib.c95
-rw-r--r--xlib.h7
10 files changed, 167 insertions, 110 deletions
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 <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
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 <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;
-}
diff --git a/runes.c b/runes.c
index 203d01f..6ae04bc 100644
--- a/runes.c
+++ b/runes.c
@@ -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;
}
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 <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
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 <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);
+}
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 <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)
diff --git a/xlib.h b/xlib.h
index e2fcf70..809645e 100644
--- a/xlib.h
+++ b/xlib.h
@@ -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