RDB: fix various UTF-8 glitches.
[sgt/putty] / unicode.c
index 0684045..6938d29 100644 (file)
--- a/unicode.c
+++ b/unicode.c
@@ -40,12 +40,18 @@ void init_ucs_tables(void)
     int i, j;
     int used_dtf = 0;
     char tbuf[256];
+    int old_codepage = line_codepage;
     for (i = 0; i < 256; i++)
        tbuf[i] = i;
 
     /* Decide on the Line and Font codepages */
     line_codepage = decode_codepage(cfg.line_codepage);
 
+    if (font_codepage <= 0) { 
+       font_codepage=0; 
+       dbcs_screenfont=0; 
+    }
+
     if (cfg.vtmode == VT_OEMONLY) {
        font_codepage = 437;
        dbcs_screenfont = 0;
@@ -53,10 +59,9 @@ void init_ucs_tables(void)
            line_codepage = GetACP();
     } else if (line_codepage <= 0)
        line_codepage = font_codepage;
-    utf = (line_codepage == CP_UTF8);
 
     /* Collect screen font ucs table */
-    if (dbcs_screenfont) {
+    if (dbcs_screenfont || font_codepage == 0) {
        get_unitab(font_codepage, unitab_font, 2);
        for (i = 128; i < 256; i++)
            unitab_font[i] = (WCHAR) (ATTR_ACP + i);
@@ -74,9 +79,15 @@ void init_ucs_tables(void)
     /* Collect OEMCP ucs table */
     get_unitab(CP_OEMCP, unitab_oemcp, 1);
 
+    /* Collect CP437 ucs table for SCO acs */
+    if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
+       memcpy(unitab_scoacs, unitab_oemcp, sizeof(unitab_scoacs));
+    else
+       get_unitab(437, unitab_scoacs, 1);
+
     /* Collect line set ucs table */
     if (line_codepage == font_codepage &&
-       (dbcs_screenfont || cfg.vtmode == VT_POORMAN)) {
+       (dbcs_screenfont || cfg.vtmode == VT_POORMAN || font_codepage==0)) {
 
        /* For DBCS and POOR fonts force direct to font */
        used_dtf = 1;
@@ -143,7 +154,11 @@ void init_ucs_tables(void)
            unitab_ctrl[i] = 0xFF;
 
     /* Generate line->screen direct conversion links. */
+    if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
+       link_font(unitab_scoacs, unitab_oemcp, ATTR_OEMCP);
+
     link_font(unitab_line, unitab_font, ATTR_ACP);
+    link_font(unitab_scoacs, unitab_font, ATTR_ACP);
     link_font(unitab_xterm, unitab_font, ATTR_ACP);
 
     if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS) {
@@ -153,6 +168,8 @@ void init_ucs_tables(void)
 
     /* Last chance, if !unicode then try poorman links. */
     if (cfg.vtmode != VT_UNICODE) {
+       static char poorman_scoacs[] = 
+           "CueaaaaceeeiiiAAE**ooouuyOUc$YPsaiounNao?++**!<>###||||++||++++++--|-+||++--|-+----++++++++##||#aBTPEsyt******EN=+><++-=... n2* ";
        static char poorman_latin1[] =
            " !cL.Y|S\"Ca<--R~o+23'u|.,1o>///?AAAAAAACEEEEIIIIDNOOOOOxOUUUUYPBaaaaaaaceeeeiiiionooooo/ouuuuypy";
        static char poorman_vt100[] = "*#****o~**+++++-----++++|****L.";
@@ -167,6 +184,10 @@ void init_ucs_tables(void)
            if (!DIRECT_FONT(unitab_xterm[i]))
                unitab_xterm[i] =
                    (WCHAR) (ATTR_ACP + poorman_vt100[i - 96]);
+       for(i=128;i<256;i++) 
+           if (!DIRECT_FONT(unitab_scoacs[i]))
+               unitab_scoacs[i] = 
+                   (WCHAR) (ATTR_ACP + poorman_scoacs[i - 128]);
     }
 }
 
@@ -212,7 +233,7 @@ void luni_send(wchar_t * widebuf, int len)
 {
     static char *linebuffer = 0;
     static int linesize = 0;
-    int ratio = (utf) ? 3 : 1;
+    int ratio = (in_utf)?3:1;
     int i;
     char *p;
 
@@ -222,7 +243,7 @@ void luni_send(wchar_t * widebuf, int len)
        linesize = len * ratio * 2;
     }
 
-    if (utf) {
+    if (in_utf) {
        /* UTF is a simple algorithm */
        for (p = linebuffer, i = 0; i < len; i++) {
            wchar_t ch = widebuf[i];
@@ -628,7 +649,6 @@ int decode_codepage(char *cp_name)
     char *s, *d;
     struct cp_list_item *cpi;
     int codepage = -1;
-    char ch;
     CPINFO cpinfo;
 
     if (cp_name && *cp_name)
@@ -652,20 +672,17 @@ int decode_codepage(char *cp_name)
                    if (GetCPInfo(codepage, &cpinfo) != 0)
                        goto break_break;
                }
-               if (islower(*s))
-                   ch = toupper(*s++);
-               else
-                   ch = *s++;
-               if (ch != *d++)
+               if (tolower(*s++) != tolower(*d++))
                    break;
            }
        }
 
     if (cp_name && *cp_name) {
        d = cp_name;
-       if (strnicmp(d, "cp", 2) == 0)
+       if (tolower(d[0]) == 'c' && tolower(d[1]) == 'p')
            d += 2;
-       if (strnicmp(d, "ibm", 3) == 0)
+       if (tolower(d[0]) == 'i' && tolower(d[1]) == 'b'
+           && tolower(d[1]) == 'm')
            d += 3;
        for (s = d; *s >= '0' && *s <= '9'; s++);
        if (*s == 0 && s != d)
@@ -799,7 +816,27 @@ static struct cp_list_item cp_list[] = {
     {"VSCII", 0, 256, vscii},
     {"DEC-MCS", 0, 96, dec_mcs},
 
-/* All below here are aliases */
+    {"Win1250 (Central European)", 1250},
+    {"Win1251 (Cyrillic)", 1251},
+    {"Win1252 (Western)", 1252},
+    {"Win1253 (Greek)", 1253},
+    {"Win1254 (Turkish)", 1254},
+    {"Win1255 (Hebrew)", 1255},
+    {"Win1256 (Arabic)", 1256},
+    {"Win1257 (Baltic)", 1257},
+    {"Win1258 (Vietnamese)", 1258},
+
+    /* All below here are aliases - First the windows ones. */
+    {"Central European (Win1250)", 1250},
+    {"Cyrillic (Win1251)", 1251},
+    {"Western (Win1252)", 1252},
+    {"Greek (Win1253)", 1253},
+    {"Turkish (Win1254)", 1254},
+    {"Hebrew (Win1255)", 1255},
+    {"Arabic (Win1256)", 1256},
+    {"Baltic (Win1257)", 1257},
+    {"Vietnamese (Win1258)", 1258},
+
     {"ROMAN8", 0, 96, roman8},
     {"R8", 0, 96, roman8},