X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/e93ed4323c03b94653cda6ba5881c0081c3d905f..e359e9c01acdf5aad21780e27e538cfd8d597aac:/ldisc.c diff --git a/ldisc.c b/ldisc.c index 91af0aca..d57e6d17 100644 --- a/ldisc.c +++ b/ldisc.c @@ -23,7 +23,7 @@ static void c_write(Ldisc ldisc, char *buf, int len) { - from_backend(ldisc->term, 0, buf, len); + from_backend(ldisc->frontend, 0, buf, len); } static int plen(Ldisc ldisc, unsigned char c) @@ -32,13 +32,20 @@ static int plen(Ldisc ldisc, unsigned char c) return 1; else if (c < 128) return 2; /* ^x for some x */ + else if (in_utf(ldisc->term) && c >= 0xC0) + return 1; /* UTF-8 introducer character + * (FIXME: combining / wide chars) */ + else if (in_utf(ldisc->term) && c >= 0x80 && c < 0xC0) + return 0; /* UTF-8 followup character */ else - return 4; /* for hex XY */ + return 4; /* hex representation */ } static void pwrite(Ldisc ldisc, unsigned char c) { - if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term))) { + if ((c >= 32 && c <= 126) || + (!in_utf(ldisc->term) && c >= 0xA0) || + (in_utf(ldisc->term) && c >= 0x80)) { c_write(ldisc, (char *)&c, 1); } else if (c < 128) { char cc[2]; @@ -52,6 +59,14 @@ static void pwrite(Ldisc ldisc, unsigned char c) } } +static int char_start(Ldisc ldisc, unsigned char c) +{ + if (in_utf(ldisc->term)) + return (c < 0x80 || c >= 0xC0); + else + return 1; +} + static void bsb(Ldisc ldisc, int n) { while (n--) @@ -65,7 +80,7 @@ void *ldisc_create(Config *mycfg, Terminal *term, Backend *back, void *backhandle, void *frontend) { - Ldisc ldisc = smalloc(sizeof(*ldisc)); + Ldisc ldisc = snew(struct ldisc_tag); ldisc->buf = NULL; ldisc->buflen = 0; @@ -137,7 +152,9 @@ void ldisc_send(void *handle, char *buf, int len, int interactive) c += KCTRL('@'); switch (ldisc->quotenext ? ' ' : c) { /* - * ^h/^?: delete one char and output one BSB + * ^h/^?: delete, and output BSBs, to return to + * last character boundary (in UTF-8 mode this may + * be more than one byte) * ^w: delete, and output BSBs, to return to last * space/nonspace boundary * ^u: delete, and output BSBs, to return to BOL @@ -153,9 +170,11 @@ void ldisc_send(void *handle, char *buf, int len, int interactive) case KCTRL('H'): case KCTRL('?'): /* backspace/delete */ if (ldisc->buflen > 0) { - if (ECHOING) - bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1])); - ldisc->buflen--; + do { + if (ECHOING) + bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1])); + ldisc->buflen--; + } while (!char_start(ldisc, ldisc->buf[ldisc->buflen])); } break; case CTRL('W'): /* delete word */ @@ -261,7 +280,7 @@ void ldisc_send(void *handle, char *buf, int len, int interactive) default_case: if (ldisc->buflen >= ldisc->bufsiz) { ldisc->bufsiz = ldisc->buflen + 256; - ldisc->buf = srealloc(ldisc->buf, ldisc->bufsiz); + ldisc->buf = sresize(ldisc->buf, ldisc->bufsiz, char); } ldisc->buf[ldisc->buflen++] = c; if (ECHOING)