terminal: use UTF8 state machine

This adds a converter from UTF8 stream to UCS4 data so the VTE subsystem
can handle the input correctly without complicated UTF8 input.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-01-29 14:23:27 +01:00
parent 885bdef87b
commit ff0e91ec45
3 changed files with 31 additions and 12 deletions

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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);