RDB: fix various UTF-8 glitches.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 19 May 2001 15:21:05 +0000 (15:21 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 19 May 2001 15:21:05 +0000 (15:21 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@1138 cda61777-01e9-0310-a592-d414129be87e

ldisc.c
putty.h
terminal.c
unicode.c
window.c

diff --git a/ldisc.c b/ldisc.c
index 48fbe17..e1b5a38 100644 (file)
--- a/ldisc.c
+++ b/ldisc.c
@@ -28,7 +28,7 @@ static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
 
 static int plen(unsigned char c)
 {
-    if ((c >= 32 && c <= 126) || (c >= 160 && !utf))
+    if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf))
        return 1;
     else if (c < 128)
        return 2;                      /* ^x for some x */
@@ -38,7 +38,7 @@ static int plen(unsigned char c)
 
 static void pwrite(unsigned char c)
 {
-    if ((c >= 32 && c <= 126) || (c >= 160 && !utf)) {
+    if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf)) {
        c_write(&c, 1);
     } else if (c < 128) {
        char cc[2];
diff --git a/putty.h b/putty.h
index cb77ac9..3fbde4e 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -78,7 +78,7 @@
 #define ATTR_DEFAULT 0x00980000UL
 #define ATTR_DEFFG   0x00080000UL
 #define ATTR_DEFBG   0x00900000UL
-#define ERASE_CHAR   (ATTR_DEFAULT | ' ')
+#define ERASE_CHAR   (ATTR_DEFAULT | ATTR_ASCII | ' ')
 #define ATTR_MASK    0xFFFFFF00UL
 #define CHAR_MASK    0x000000FFUL
 
@@ -127,6 +127,7 @@ GLOBAL WCHAR unitab_font[256];
 GLOBAL WCHAR unitab_xterm[256];
 GLOBAL WCHAR unitab_oemcp[256];
 GLOBAL unsigned char unitab_ctrl[256];
+#define in_utf (utf || line_codepage==CP_UTF8)
 
 #define LGXF_OVR  1                   /* existing logfile overwrite */
 #define LGXF_APN  0                   /* existing logfile append */
index 391f0d2..aeadc77 100644 (file)
@@ -94,6 +94,7 @@ static int wrap, wrapnext;           /* wrap flags */
 static int insert;                    /* insert-mode flag */
 static int cset;                      /* 0 or 1: which char set */
 static int save_cset, save_csattr;     /* saved with cursor position */
+static int save_utf;                  /* saved with cursor position */
 static int rvideo;                    /* global reverse video flag */
 static int rvbell_timeout;            /* for ESC[?5hESC[?5l vbell */
 static int cursor_on;                 /* cursor enabled flag */
@@ -117,7 +118,7 @@ static unsigned long cset_attr[2];
 /*
  * Saved settings on the alternate screen.
  */
-static int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset, alt_sco_acs;
+static int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset, alt_sco_acs, alt_utf;
 static int alt_t, alt_b;
 static int alt_which;
 
@@ -279,6 +280,7 @@ static void power_on(void)
     alt_wnext = wrapnext = alt_ins = insert = FALSE;
     alt_wrap = wrap = cfg.wrap_mode;
     alt_cset = cset = 0;
+    alt_utf = utf = 0;
     alt_sco_acs = sco_acs = 0;
     cset_attr[0] = cset_attr[1] = ATTR_ASCII;
     rvideo = 0;
@@ -538,6 +540,9 @@ static void swap_screen(int which)
     t = cset;
     cset = alt_cset;
     alt_cset = t;
+    t = utf;
+    utf = alt_utf;
+    alt_utf = t;
     t = sco_acs;
     sco_acs = alt_sco_acs;
     alt_sco_acs = t;
@@ -694,6 +699,7 @@ static void save_cursor(int save)
        savecurs = curs;
        save_attr = curr_attr;
        save_cset = cset;
+       save_utf = utf;
        save_csattr = cset_attr[cset];
        save_sco_acs = sco_acs;
     } else {
@@ -706,11 +712,13 @@ static void save_cursor(int save)
 
        curr_attr = save_attr;
        cset = save_cset;
+       utf = save_utf;
        cset_attr[cset] = save_csattr;
        sco_acs = save_sco_acs;
        fix_cpos;
        if (use_bce)
-           erase_char = (' ' | (curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
+           erase_char = (' ' | ATTR_ASCII |
+                        (curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
     }
 }
 
@@ -941,18 +949,15 @@ void term_out(void)
 
        /* First see about all those translations. */
        if (termstate == TOPLEVEL) {
-           if (utf)
+           if (in_utf)
                switch (utf_state) {
                  case 0:
                    if (c < 0x80) {
-                       /* I know; gotos are evil. This one is really bad!
-                        * But before you try removing it follow the path of the
-                        * sequence "0x5F 0xC0 0x71" with UTF and VTGraphics on.
-                        */
-                       /*
-                          if (cfg.no_vt_graph_with_utf8) break;
-                        */
-                       goto evil_jump;
+                       /* UTF-8 must be stateless so we ignore iso2022. */
+                       if (unitab_ctrl[c] != 0xFF) 
+                            c = unitab_ctrl[c];
+                       else c = ((unsigned char)c) | ATTR_ASCII;
+                       break;
                    } else if ((c & 0xe0) == 0xc0) {
                        utf_size = utf_state = 1;
                        utf_char = (c & 0x1f);
@@ -1039,7 +1044,6 @@ void term_out(void)
               if (sco_acs == 2) c ^= 0x80;
               c |= ATTR_SCOACS;
            } else {
-             evil_jump:;
                switch (cset_attr[cset]) {
                    /* 
                     * Linedraw characters are different from 'ESC ( B'
@@ -1529,8 +1533,7 @@ void term_out(void)
                    break;
                  case ANSI('@', '%'):
                    compatibility(OTHER);
-                   if (line_codepage != CP_UTF8)
-                       utf = 0;
+                   utf = 0;
                    break;
                }
                break;
@@ -1850,11 +1853,9 @@ void term_out(void)
                                }
                            }
                            if (use_bce)
-                               erase_char =
-                                   (' ' |
-                                    (curr_attr &
-                                     (ATTR_FGMASK | ATTR_BGMASK |
-                                      ATTR_BLINK)));
+                               erase_char = (' ' | ATTR_ASCII |
+                                            (curr_attr & 
+                                             (ATTR_FGMASK | ATTR_BGMASK)));
                        }
                        break;
                      case 's':       /* save cursor */
@@ -1952,10 +1953,9 @@ void term_out(void)
                        use_bce = (esc_args[0] <= 0);
                        erase_char = ERASE_CHAR;
                        if (use_bce)
-                           erase_char =
-                               (' ' |
-                                (curr_attr &
-                                 (ATTR_FGMASK | ATTR_BGMASK)));
+                           erase_char = (' ' | ATTR_ASCII |
+                                        (curr_attr & 
+                                         (ATTR_FGMASK | ATTR_BGMASK)));
                        break;
                      case ANSI('E', '='):
                        compatibility(OTHER);
@@ -2347,10 +2347,9 @@ void term_out(void)
                    vt52_bold = FALSE;
                    curr_attr = ATTR_DEFAULT;
                    if (use_bce)
-                       erase_char = (' ' |
-                                     (curr_attr &
-                                      (ATTR_FGMASK | ATTR_BGMASK |
-                                       ATTR_BLINK)));
+                       erase_char = (' ' | ATTR_ASCII |
+                                    (curr_attr & 
+                                     (ATTR_FGMASK | ATTR_BGMASK)));
                    break;
                  case 'S':
                    /* compatibility(VI50) */
@@ -2392,10 +2391,8 @@ void term_out(void)
                    curr_attr |= ATTR_BOLD;
 
                if (use_bce)
-                   erase_char = (' ' |
-                                 (curr_attr &
-                                  (ATTR_FGMASK | ATTR_BGMASK |
-                                   ATTR_BLINK)));
+                   erase_char = (' ' | ATTR_ASCII |
+                                (curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
                break;
              case VT52_BG:
                termstate = TOPLEVEL;
@@ -2408,10 +2405,8 @@ void term_out(void)
                    curr_attr |= ATTR_BLINK;
 
                if (use_bce)
-                   erase_char = (' ' |
-                                 (curr_attr &
-                                  (ATTR_FGMASK | ATTR_BGMASK |
-                                   ATTR_BLINK)));
+                   erase_char = (' ' | ATTR_ASCII |
+                                (curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
                break;
 #endif
              default: break;          /* placate gcc warning about enum use */
index 4703425..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);
@@ -82,7 +87,7 @@ void init_ucs_tables(void)
 
     /* 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;
@@ -228,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;
 
@@ -238,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];
index b82ccfb..9948763 100644 (file)
--- a/window.c
+++ b/window.c
@@ -2881,7 +2881,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 #ifdef SHOW_TOASCII_RESULT
        if (r == 1 && !key_down) {
            if (alt_sum) {
-               if (utf || dbcs_screenfont)
+               if (in_utf || dbcs_screenfont)
                    debug((", (U+%04x)", alt_sum));
                else
                    debug((", LCH(%d)", alt_sum));
@@ -2925,7 +2925,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
                if (!key_down) {
                    if (alt_sum) {
-                       if (utf || dbcs_screenfont) {
+                       if (in_utf || dbcs_screenfont) {
                            keybuf = alt_sum;
                            luni_send(&keybuf, 1);
                        } else {
@@ -2952,7 +2952,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
        if (!left_alt)
            keys[0] = 0;
        /* If we will be using alt_sum fix the 256s */
-       else if (keys[0] && (utf || dbcs_screenfont))
+       else if (keys[0] && (in_utf || dbcs_screenfont))
            keys[0] = 10;
     }