diff options
-rw-r--r-- | main.c | 47 | ||||
-rw-r--r-- | runes.c | 10 | ||||
-rw-r--r-- | runes.h | 2 | ||||
-rw-r--r-- | xlib.c | 43 | ||||
-rw-r--r-- | xlib.h | 2 |
5 files changed, 66 insertions, 38 deletions
@@ -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); @@ -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); @@ -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 @@ -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); @@ -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 |