diff --git a/src/terminal.c b/src/terminal.c index c712101..f18f55f 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -109,18 +109,13 @@ static void schedule_redraw(struct kmscon_terminal *term) static void pty_input(struct kmscon_pty *pty, const char *u8, size_t len, void *data) { - size_t i; struct kmscon_terminal *term = data; if (!len) { if (term->closed_cb) term->closed_cb(term, term->closed_data); } else { - /* FIXME: UTF-8. */ - for (i=0; i < len; i++) - if (u8[i] < 128) - kmscon_vte_input(term->vte, u8[i]); - + kmscon_vte_input(term->vte, u8, len); schedule_redraw(term); } } diff --git a/src/vte.c b/src/vte.c index 8249cba..0c0b162 100644 --- a/src/vte.c +++ b/src/vte.c @@ -46,11 +46,13 @@ struct kmscon_vte { struct kmscon_console *con; const char *kbd_sym; + struct kmscon_utf8_mach *mach; }; int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_symbol_table *st) { struct kmscon_vte *vte; + int ret; if (!out) return -EINVAL; @@ -65,9 +67,17 @@ int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_symbol_table *st) vte->ref = 1; vte->st = st; + ret = kmscon_utf8_mach_new(&vte->mach); + if (ret) + goto err_free; + kmscon_symbol_table_ref(vte->st); *out = vte; return 0; + +err_free: + free(vte); + return ret; } void kmscon_vte_ref(struct kmscon_vte *vte) @@ -87,6 +97,7 @@ void kmscon_vte_unref(struct kmscon_vte *vte) return; kmscon_console_unref(vte->con); + kmscon_utf8_mach_free(vte->mach); kmscon_symbol_free_u8(vte->kbd_sym); kmscon_symbol_table_unref(vte->st); free(vte); @@ -103,15 +114,28 @@ void kmscon_vte_bind(struct kmscon_vte *vte, struct kmscon_console *con) kmscon_console_ref(vte->con); } -void kmscon_vte_input(struct kmscon_vte *vte, kmscon_symbol_t ch) +void kmscon_vte_input(struct kmscon_vte *vte, const char *u8, size_t len) { + int state, i; + uint32_t ucs4; + kmscon_symbol_t sym; + if (!vte || !vte->con) return; - if (ch == '\n') - kmscon_console_newline(vte->con); - else - kmscon_console_write(vte->con, ch); + for (i = 0; i < len; ++i) { + state = kmscon_utf8_mach_feed(vte->mach, u8[i]); + if (state == KMSCON_UTF8_ACCEPT || + state == KMSCON_UTF8_REJECT) { + ucs4 = kmscon_utf8_mach_get(vte->mach); + if (ucs4 == '\n') { + kmscon_console_newline(vte->con); + } else { + sym = kmscon_symbol_make(ucs4); + kmscon_console_write(vte->con, sym); + } + } + } } int kmscon_vte_handle_keyboard(struct kmscon_vte *vte, diff --git a/src/vte.h b/src/vte.h index 44bda3b..f586869 100644 --- a/src/vte.h +++ b/src/vte.h @@ -50,7 +50,7 @@ void kmscon_vte_ref(struct kmscon_vte *vte); void kmscon_vte_unref(struct kmscon_vte *vte); void kmscon_vte_bind(struct kmscon_vte *vte, struct kmscon_console *con); -void kmscon_vte_input(struct kmscon_vte *vte, kmscon_symbol_t ch); +void kmscon_vte_input(struct kmscon_vte *vte, const char *u8, size_t len); int kmscon_vte_handle_keyboard(struct kmscon_vte *vte, const struct kmscon_input_event *ev, const char **u8, size_t *len);