X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/d4413bd2bbee00fa4a058e6c3a58c11d5596cd3d..HEAD:/unix/uxucs.c diff --git a/unix/uxucs.c b/unix/uxucs.c index f3d6a89a..5d3d5af0 100644 --- a/unix/uxucs.c +++ b/unix/uxucs.c @@ -21,14 +21,14 @@ int is_dbcs_leadbyte(int codepage, char byte) return 0; /* we don't do DBCS */ } -int mb_to_wc(int codepage, int flags, char *mbstr, int mblen, +int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen, wchar_t *wcstr, int wclen) { if (codepage == DEFAULT_CODEPAGE) { int n = 0; - mbstate_t state = { 0 }; + mbstate_t state; - setlocale(LC_CTYPE, ""); + memset(&state, 0, sizeof state); while (mblen > 0) { size_t i = mbrtowc(wcstr+n, mbstr, (size_t)mblen, &state); @@ -39,8 +39,6 @@ int mb_to_wc(int codepage, int flags, char *mbstr, int mblen, mblen -= i; } - setlocale(LC_CTYPE, "C"); - return n; } else if (codepage == CS_NONE) { int n = 0; @@ -58,7 +56,7 @@ int mb_to_wc(int codepage, int flags, char *mbstr, int mblen, NULL, NULL, 0); } -int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, +int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen, char *mbstr, int mblen, char *defchr, int *defused, struct unicode_data *ucsdata) { @@ -68,10 +66,10 @@ int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, if (codepage == DEFAULT_CODEPAGE) { char output[MB_LEN_MAX]; - mbstate_t state = { 0 }; + mbstate_t state; int n = 0; - setlocale(LC_CTYPE, ""); + memset(&state, 0, sizeof state); while (wclen > 0) { int i = wcrtomb(output, wcstr[0], &state); @@ -83,8 +81,6 @@ int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, wclen--; } - setlocale(LC_CTYPE, "C"); - return n; } else if (codepage == CS_NONE) { int n = 0; @@ -106,8 +102,8 @@ int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen, /* * Return value is TRUE if pterm is to run in direct-to-font mode. */ -int init_ucs(struct unicode_data *ucsdata, - char *linecharset, int font_charset) +int init_ucs(struct unicode_data *ucsdata, char *linecharset, + int utf8_override, int font_charset, int vtmode) { int i, ret = 0; @@ -120,10 +116,27 @@ int init_ucs(struct unicode_data *ucsdata, ucsdata->font_codepage = -1; /* - * line_codepage should be decoded from the specification in - * cfg. + * If utf8_override is set and the POSIX locale settings + * dictate a UTF-8 character set, then just go straight for + * UTF-8. + */ + ucsdata->line_codepage = CS_NONE; + if (utf8_override) { + const char *s; + if (((s = getenv("LC_ALL")) && *s) || + ((s = getenv("LC_CTYPE")) && *s) || + ((s = getenv("LANG")) && *s)) { + if (strstr(s, "UTF-8")) + ucsdata->line_codepage = CS_UTF8; + } + } + + /* + * Failing that, line_codepage should be decoded from the + * specification in conf. */ - ucsdata->line_codepage = decode_codepage(linecharset); + if (ucsdata->line_codepage == CS_NONE) + ucsdata->line_codepage = decode_codepage(linecharset); /* * If line_codepage is _still_ CS_NONE, we assume we're using @@ -143,7 +156,8 @@ int init_ucs(struct unicode_data *ucsdata, * in the line codepage into Unicode. */ for (i = 0; i < 256; i++) { - char c[1], *p; + char c[1]; + const char *p; wchar_t wc[1]; int len; c[0] = i; @@ -176,8 +190,18 @@ int init_ucs(struct unicode_data *ucsdata, 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020 }; + static const wchar_t unitab_xterm_poorman[32] = + L"*#****o~**+++++-----++++|****L. "; + + const wchar_t *ptr; + + if (vtmode == VT_POORMAN) + ptr = unitab_xterm_poorman; + else + ptr = unitab_xterm_std; + if (i >= 0x5F && i < 0x7F) - ucsdata->unitab_xterm[i] = unitab_xterm_std[i & 0x1F]; + ucsdata->unitab_xterm[i] = ptr[i & 0x1F]; else ucsdata->unitab_xterm[i] = ucsdata->unitab_line[i]; } @@ -187,7 +211,8 @@ int init_ucs(struct unicode_data *ucsdata, * simply CP437. */ for (i = 0; i < 256; i++) { - char c[1], *p; + char c[1]; + const char *p; wchar_t wc[1]; int len; c[0] = i; @@ -228,17 +253,19 @@ const char *cp_name(int codepage) const char *cp_enumerate(int index) { int charset; - if (index == 0) - return "Use font encoding"; - charset = charset_localenc_nth(index-1); - if (charset == CS_NONE) + charset = charset_localenc_nth(index); + if (charset == CS_NONE) { + /* "Use font encoding" comes after all the named charsets */ + if (charset_localenc_nth(index-1) != CS_NONE) + return "Use font encoding"; return NULL; + } return charset_to_localenc(charset); } int decode_codepage(char *cp_name) { - if (!*cp_name) - return CS_NONE; /* use font encoding */ + if (!cp_name || !*cp_name) + return CS_UTF8; return charset_from_localenc(cp_name); }