aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.c47
-rw-r--r--runes.c10
-rw-r--r--runes.h2
-rw-r--r--xlib.c43
-rw-r--r--xlib.h2
5 files changed, 66 insertions, 38 deletions
diff --git a/main.c b/main.c
index 282c1b7..6c7c123 100644
--- a/main.c
+++ b/main.c
@@ -6,7 +6,6 @@
int main (int argc, char *argv[])
{
RunesTerm *t;
- unsigned long mask;
setlocale(LC_ALL, "");
@@ -17,46 +16,18 @@ int main (int argc, char *argv[])
cairo_set_source_rgb(t->cr, 0.0, 0.0, 1.0);
cairo_move_to(t->cr, 0.0, 14.0);
- XGetICValues(t->w->ic, XNFilterEvents, &mask, NULL);
- XSelectInput(t->w->dpy, t->w->w, mask|KeyPressMask);
- XSetICFocus(t->w->ic);
+ runes_prepare_input(t);
for (;;) {
- XEvent e;
- char buf[10];
-
- XNextEvent(t->w->dpy, &e);
- if (XFilterEvent(&e, None)) {
- continue;
- }
- if (e.type == KeyPress) {
- Status s;
- KeySym sym;
- int chars;
-
- chars = Xutf8LookupString(t->w->ic, &e.xkey, buf, 9, &sym, &s);
- buf[chars] = '\0';
- switch (s) {
- case XLookupKeySym:
- fprintf(stderr, "keysym: %d\n", sym);
- break;
- case XLookupBoth:
- case XLookupChars:
- fprintf(stderr, "chars: %10s\n", buf);
- break;
- case XLookupNone:
- fprintf(stderr, "none\n");
- break;
- default:
- fprintf(stderr, "???\n");
- break;
- }
- }
- else {
- continue;
+ 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);
}
- cairo_show_text(t->cr, buf);
- cairo_surface_flush(t->surface);
}
runes_term_destroy(t);
diff --git a/runes.c b/runes.c
index 10103e9..203d01f 100644
--- a/runes.c
+++ b/runes.c
@@ -16,6 +16,16 @@ RunesTerm *runes_term_create()
return t;
}
+void runes_prepare_input(RunesTerm *t)
+{
+ runes_window_prepare_input(t->w);
+}
+
+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);
diff --git a/runes.h b/runes.h
index 424b792..86b0f03 100644
--- a/runes.h
+++ b/runes.h
@@ -14,6 +14,8 @@ typedef struct {
} RunesTerm;
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);
#endif
diff --git a/xlib.c b/xlib.c
index 6578ca7..4d8d039 100644
--- a/xlib.c
+++ b/xlib.c
@@ -59,6 +59,49 @@ cairo_surface_t *runes_surface_create(RunesWindow *w)
return cairo_xlib_surface_create(w->dpy, w->w, vis, 240, 80);
}
+void runes_window_prepare_input(RunesWindow *w)
+{
+ unsigned long mask;
+
+ XGetICValues(w->ic, XNFilterEvents, &mask, NULL);
+ XSelectInput(w->dpy, w->w, mask|KeyPressMask);
+ XSetICFocus(w->ic);
+}
+
+void runes_window_read_key(RunesWindow *w, char **outbuf, size_t *outlen)
+{
+ static char *buf = NULL;
+ static size_t len = 8;
+ XEvent e;
+ Status s;
+ KeySym sym;
+ size_t chars;
+
+ if (!buf) {
+ buf = malloc(len);
+ }
+
+ XNextEvent(w->dpy, &e);
+ if (XFilterEvent(&e, None) || e.type != KeyPress) {
+ *outlen = 0;
+ *outbuf = buf;
+ return;
+ }
+
+ for (;;) {
+ chars = Xutf8LookupString(w->ic, &e.xkey, buf, len - 1, &sym, &s);
+ if (s == XBufferOverflow) {
+ len = chars + 1;
+ buf = realloc(buf, len);
+ continue;
+ }
+ break;
+ }
+
+ *outlen = chars;
+ *outbuf = buf;
+}
+
void runes_window_destroy(RunesWindow *w)
{
XDestroyWindow(w->dpy, w->w);
diff --git a/xlib.h b/xlib.h
index 9847faa..e2fcf70 100644
--- a/xlib.h
+++ b/xlib.h
@@ -12,6 +12,8 @@ typedef struct {
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_window_destroy(RunesWindow *w);
#endif