diff --git a/hl-vt100/src/lw_terminal_vt100.c b/hl-vt100/src/lw_terminal_vt100.c index c8a182e..aea1240 100644 --- a/hl-vt100/src/lw_terminal_vt100.c +++ b/hl-vt100/src/lw_terminal_vt100.c @@ -967,8 +967,7 @@ static void HTS(struct lw_terminal *term_emul) vt100->tabulations[vt100->x] = '|'; } -static void vt100_write(struct lw_terminal *term_emul, char c) -{ +static void vt100_write_unicode(struct lw_terminal *term_emul, int c) { struct lw_terminal_vt100 *vt100; vt100 = (struct lw_terminal_vt100 *)term_emul->user_data; @@ -1022,6 +1021,47 @@ static void vt100_write(struct lw_terminal *term_emul, char c) vt100->x += 1; } +#define REPLACEMENT ('?') + +static void vt100_write(struct lw_terminal *term_emul, char c) { + struct lw_terminal_vt100 *vt100; + uint8_t uc = c; + + vt100 = (struct lw_terminal_vt100 *)term_emul->user_data; + + if (vt100->ustate == 0) { + if (uc < 0x80) { + vt100_write_unicode(term_emul, uc); + } else if((uc & 0xe0) == 0xc0) { + vt100->ustate = 1; + vt100->ubits = (uc & 0x1f); + } else if((uc & 0xf0) == 0xe0) { + vt100->ustate = 2; + vt100->ubits = (uc & 0xf); + } else if((uc & 0xf8) == 0xf0) { + vt100->ustate = 3; + vt100->ubits = (uc & 0x7); + } else { + vt100_write_unicode(term_emul, REPLACEMENT); + } + } else { + if (uc < 0x80) { + vt100_write_unicode(term_emul, REPLACEMENT); + vt100_write_unicode(term_emul, uc); + vt100->ustate = 0; + } else if ((uc & 0xc0) != 0x80) { + vt100_write_unicode(term_emul, REPLACEMENT); + vt100->ustate = 0; + } else { + vt100->ubits <<= 6; + vt100->ubits |= uc & 0x3f; + if (--vt100->ustate == 0) { + vt100_write_unicode(term_emul, vt100->ubits); + } + } + } +} + const lw_cell_t *lw_terminal_vt100_getline(struct lw_terminal_vt100 *vt100, unsigned int y) { if (y < vt100->margin_top || y > vt100->margin_bottom) return vt100->afrozen_screen + FROZEN_SCREEN_PTR(vt100, 0, y); diff --git a/hl-vt100/src/lw_terminal_vt100.h b/hl-vt100/src/lw_terminal_vt100.h index f67d007..7204055 100644 --- a/hl-vt100/src/lw_terminal_vt100.h +++ b/hl-vt100/src/lw_terminal_vt100.h @@ -84,6 +84,7 @@ struct lw_parsed_attr { struct lw_terminal_vt100 { struct lw_terminal *lw_terminal; + int ustate, ubits; unsigned int width; unsigned int height; unsigned int x;