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:
parent
885bdef87b
commit
ff0e91ec45
@ -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);
|
||||
}
|
||||
}
|
||||
|
34
src/vte.c
34
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,
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user