Deglobalise the Unicode module. Despite all my grand plans, I've
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 14 Jan 2003 18:28:23 +0000 (18:28 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 14 Jan 2003 18:28:23 +0000 (18:28 +0000)
just done this the very simple way - bundle all the globals into a
data structure and pass pointers around. One particularly ugly wart
is that wc_to_mb now takes a pointer to this structure as an
argument (optional, may be NULL, and unused in any Unicode layer
that's even marginally less of a mess than the Windows one). I do
need to do this properly at some point, but for now this should just
about be adequate. As usual, the Mac port has not been updated.

git-svn-id: svn://svn.tartarus.org/sgt/putty@2592 cda61777-01e9-0310-a592-d414129be87e

ldiscucs.c
putty.h
terminal.c
terminal.h
unicode.c
unix/pterm.c
unix/unix.h
unix/uxucs.c
window.c
winstuff.h

index 2e19adc..2160266 100644 (file)
@@ -66,8 +66,8 @@ void luni_send(void *handle, wchar_t * widebuf, int len, int interactive)
        }
     } else {
        int rv;
-       rv = wc_to_mb(line_codepage, 0, widebuf, len,
-                     linebuffer, linesize, NULL, NULL);
+       rv = wc_to_mb(ldisc->term->ucsdata->line_codepage, 0, widebuf, len,
+                     linebuffer, linesize, NULL, NULL, ldisc->term->ucsdata);
        if (rv >= 0)
            p = linebuffer + rv;
        else
diff --git a/putty.h b/putty.h
index db37db2..12944ed 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -108,15 +108,18 @@ struct sesslist {
     char *buffer;                     /* so memory can be freed later */
 };
 
-GLOBAL int dbcs_screenfont;
-GLOBAL int font_codepage;
-GLOBAL int line_codepage;
-GLOBAL wchar_t unitab_scoacs[256];
-GLOBAL wchar_t unitab_line[256];
-GLOBAL wchar_t unitab_font[256];
-GLOBAL wchar_t unitab_xterm[256];
-GLOBAL wchar_t unitab_oemcp[256];
-GLOBAL unsigned char unitab_ctrl[256];
+struct unicode_data {
+    char **uni_tbl;
+    int dbcs_screenfont;
+    int font_codepage;
+    int line_codepage;
+    wchar_t unitab_scoacs[256];
+    wchar_t unitab_line[256];
+    wchar_t unitab_font[256];
+    wchar_t unitab_xterm[256];
+    wchar_t unitab_oemcp[256];
+    unsigned char unitab_ctrl[256];
+};
 
 #define LGXF_OVR  1                   /* existing logfile overwrite */
 #define LGXF_APN  0                   /* existing logfile append */
@@ -497,7 +500,7 @@ int platform_default_i(char *name, int def);
  * Exports from terminal.c.
  */
 
-Terminal *term_init(Config *, void *);
+Terminal *term_init(Config *, struct unicode_data *, void *);
 void term_size(Terminal *, int, int, int);
 void term_out(Terminal *);
 void term_paint(Terminal *, Context, int, int, int, int, int);
@@ -616,7 +619,8 @@ int is_dbcs_leadbyte(int codepage, char byte);
 int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
             wchar_t *wcstr, int wclen);
 int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
-            char *mbstr, int mblen, char *defchr, int *defused);
+            char *mbstr, int mblen, char *defchr, int *defused,
+            struct unicode_data *ucsdata);
 wchar_t xlat_uskbd2cyrllic(int ch);
 int check_compose(int first, int second);
 int decode_codepage(char *cp_name);
index ba5e14e..9ad33d6 100644 (file)
@@ -337,7 +337,8 @@ void term_clrsb(Terminal *term)
 /*
  * Initialise the terminal.
  */
-Terminal *term_init(Config *mycfg, void *frontend)
+Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata,
+                   void *frontend)
 {
     Terminal *term;
 
@@ -347,6 +348,7 @@ Terminal *term_init(Config *mycfg, void *frontend)
      */
     term = smalloc(sizeof(Terminal));
     term->frontend = frontend;
+    term->ucsdata = ucsdata;
     term->cfg = *mycfg;                       /* STRUCTURE COPY */
     term->logctx = NULL;
     term->compatibility_level = TM_PUTTY;
@@ -1274,8 +1276,8 @@ void term_out(Terminal *term)
                  case 0:
                    if (c < 0x80) {
                        /* UTF-8 must be stateless so we ignore iso2022. */
-                       if (unitab_ctrl[c] != 0xFF) 
-                            c = unitab_ctrl[c];
+                       if (term->ucsdata->unitab_ctrl[c] != 0xFF) 
+                            c = term->ucsdata->unitab_ctrl[c];
                        else c = ((unsigned char)c) | ATTR_ASCII;
                        break;
                    } else if ((c & 0xe0) == 0xc0) {
@@ -1372,8 +1374,8 @@ void term_out(Terminal *term)
                     * the same encoding.
                     */
                  case ATTR_LINEDRW:
-                   if (unitab_ctrl[c] != 0xFF)
-                       c = unitab_ctrl[c];
+                   if (term->ucsdata->unitab_ctrl[c] != 0xFF)
+                       c = term->ucsdata->unitab_ctrl[c];
                    else
                        c = ((unsigned char) c) | ATTR_LINEDRW;
                    break;
@@ -1385,8 +1387,8 @@ void term_out(Terminal *term)
                        break;
                    }
                  /*FALLTHROUGH*/ case ATTR_ASCII:
-                   if (unitab_ctrl[c] != 0xFF)
-                       c = unitab_ctrl[c];
+                   if (term->ucsdata->unitab_ctrl[c] != 0xFF)
+                       c = term->ucsdata->unitab_ctrl[c];
                    else
                        c = ((unsigned char) c) | ATTR_ASCII;
                    break;
@@ -3115,13 +3117,13 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
            tattr = (*d & (ATTR_MASK ^ CSET_MASK));
            switch (tchar & CSET_MASK) {
              case ATTR_ASCII:
-               tchar = unitab_line[tchar & 0xFF];
+               tchar = term->ucsdata->unitab_line[tchar & 0xFF];
                break;
              case ATTR_LINEDRW:
-               tchar = unitab_xterm[tchar & 0xFF];
+               tchar = term->ucsdata->unitab_xterm[tchar & 0xFF];
                break;
              case ATTR_SCOACS:  
-               tchar = unitab_scoacs[tchar&0xFF]; 
+               tchar = term->ucsdata->unitab_scoacs[tchar&0xFF]; 
                break;
            }
            tattr |= (tchar & CSET_MASK);
@@ -3179,7 +3181,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
            if ((attr & CSET_MASK) == 0x2300 && tchar >= 0xBA
                && tchar <= 0xBD) break_run = TRUE;
 
-           if (!dbcs_screenfont && !dirty_line) {
+           if (!term->ucsdata->dbcs_screenfont && !dirty_line) {
                if ((tchar | tattr) == term->disptext[idx])
                    break_run = TRUE;
                else if (!dirty_run && ccount == 1)
@@ -3194,7 +3196,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
                start = j;
                ccount = 0;
                attr = tattr;
-               if (dbcs_screenfont)
+               if (term->ucsdata->dbcs_screenfont)
                    last_run_dirty = dirty_run;
                dirty_run = dirty_line;
            }
@@ -3414,22 +3416,22 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect)
            switch (uc & CSET_MASK) {
              case ATTR_LINEDRW:
                if (!term->cfg.rawcnp) {
-                   uc = unitab_xterm[uc & 0xFF];
+                   uc = term->ucsdata->unitab_xterm[uc & 0xFF];
                    break;
                }
              case ATTR_ASCII:
-               uc = unitab_line[uc & 0xFF];
+               uc = term->ucsdata->unitab_line[uc & 0xFF];
                break;
              case ATTR_SCOACS:  
-               uc = unitab_scoacs[uc&0xFF]; 
+               uc = term->ucsdata->unitab_scoacs[uc&0xFF]; 
                break;
            }
            switch (uc & CSET_MASK) {
              case ATTR_ACP:
-               uc = unitab_font[uc & 0xFF];
+               uc = term->ucsdata->unitab_font[uc & 0xFF];
                break;
              case ATTR_OEMCP:
-               uc = unitab_oemcp[uc & 0xFF];
+               uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
                break;
            }
 
@@ -3443,14 +3445,14 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect)
                    char buf[4];
                    WCHAR wbuf[4];
                    int rv;
-                   if (is_dbcs_leadbyte(font_codepage, (BYTE) c)) {
+                   if (is_dbcs_leadbyte(term->ucsdata->font_codepage, (BYTE) c)) {
                        buf[0] = c;
                        buf[1] = (char) (0xFF & ldata[top.x + 1]);
-                       rv = mb_to_wc(font_codepage, 0, buf, 2, wbuf, 4);
+                       rv = mb_to_wc(term->ucsdata->font_codepage, 0, buf, 2, wbuf, 4);
                        top.x++;
                    } else {
                        buf[0] = c;
-                       rv = mb_to_wc(font_codepage, 0, buf, 1, wbuf, 4);
+                       rv = mb_to_wc(term->ucsdata->font_codepage, 0, buf, 1, wbuf, 4);
                    }
 
                    if (rv > 0) {
@@ -3580,28 +3582,29 @@ static int wordtype(Terminal *term, int uc)
 
     switch (uc & CSET_MASK) {
       case ATTR_LINEDRW:
-       uc = unitab_xterm[uc & 0xFF];
+       uc = term->ucsdata->unitab_xterm[uc & 0xFF];
        break;
       case ATTR_ASCII:
-       uc = unitab_line[uc & 0xFF];
+       uc = term->ucsdata->unitab_line[uc & 0xFF];
        break;
       case ATTR_SCOACS:  
-       uc = unitab_scoacs[uc&0xFF]; 
+       uc = term->ucsdata->unitab_scoacs[uc&0xFF]; 
        break;
     }
     switch (uc & CSET_MASK) {
       case ATTR_ACP:
-       uc = unitab_font[uc & 0xFF];
+       uc = term->ucsdata->unitab_font[uc & 0xFF];
        break;
       case ATTR_OEMCP:
-       uc = unitab_oemcp[uc & 0xFF];
+       uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
        break;
     }
 
     /* For DBCS font's I can't do anything usefull. Even this will sometimes
      * fail as there's such a thing as a double width space. :-(
      */
-    if (dbcs_screenfont && font_codepage == line_codepage)
+    if (term->ucsdata->dbcs_screenfont &&
+       term->ucsdata->font_codepage == term->ucsdata->line_codepage)
        return (uc != ' ');
 
     if (uc < 0x80)
index 72c8f87..daadd70 100644 (file)
@@ -171,6 +171,8 @@ struct terminal_tag {
 
     void *logctx;
 
+    struct unicode_data *ucsdata;
+
     /*
      * We maintain a full _copy_ of a Config structure here, not
      * merely a pointer to it. That way, when we're passed a new
@@ -181,6 +183,6 @@ struct terminal_tag {
     Config cfg;
 };
 
-#define in_utf(term) ((term)->utf || line_codepage==CP_UTF8)
+#define in_utf(term) ((term)->utf || (term)->ucsdata->line_codepage==CP_UTF8)
 
 #endif
index 3c25c6e..fdfa08d 100644 (file)
--- a/unicode.c
+++ b/unicode.c
@@ -16,8 +16,6 @@
  * the xterm one has the four scanlines that have no unicode 2.0
  * equivalents mapped to their unicode 3.0 locations.
  */
-static char **uni_tbl;
-
 static const WCHAR unitab_xterm_std[32] = {
     0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
     0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
@@ -416,7 +414,7 @@ static const struct cp_list_item cp_list[] = {
 
 static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr);
 
-void init_ucs(Config *cfg)
+void init_ucs(Config *cfg, struct unicode_data *ucsdata)
 {
     int i, j;
     int used_dtf = 0;
@@ -426,132 +424,138 @@ void init_ucs(Config *cfg)
        tbuf[i] = i;
 
     /* Decide on the Line and Font codepages */
-    line_codepage = decode_codepage(cfg->line_codepage);
+    ucsdata->line_codepage = decode_codepage(cfg->line_codepage);
 
-    if (font_codepage <= 0) { 
-       font_codepage=0; 
-       dbcs_screenfont=0; 
+    if (ucsdata->font_codepage <= 0) { 
+       ucsdata->font_codepage=0; 
+       ucsdata->dbcs_screenfont=0; 
     }
 
     if (cfg->vtmode == VT_OEMONLY) {
-       font_codepage = 437;
-       dbcs_screenfont = 0;
-       if (line_codepage <= 0)
-           line_codepage = GetACP();
-    } else if (line_codepage <= 0)
-       line_codepage = font_codepage;
+       ucsdata->font_codepage = 437;
+       ucsdata->dbcs_screenfont = 0;
+       if (ucsdata->line_codepage <= 0)
+           ucsdata->line_codepage = GetACP();
+    } else if (ucsdata->line_codepage <= 0)
+       ucsdata->line_codepage = ucsdata->font_codepage;
 
     /* Collect screen font ucs table */
-    if (dbcs_screenfont || font_codepage == 0) {
-       get_unitab(font_codepage, unitab_font, 2);
+    if (ucsdata->dbcs_screenfont || ucsdata->font_codepage == 0) {
+       get_unitab(ucsdata->font_codepage, ucsdata->unitab_font, 2);
        for (i = 128; i < 256; i++)
-           unitab_font[i] = (WCHAR) (ATTR_ACP + i);
+           ucsdata->unitab_font[i] = (WCHAR) (ATTR_ACP + i);
     } else {
-       get_unitab(font_codepage, unitab_font, 1);
+       get_unitab(ucsdata->font_codepage, ucsdata->unitab_font, 1);
 
        /* CP437 fonts are often broken ... */
-       if (font_codepage == 437)
-           unitab_font[0] = unitab_font[255] = 0xFFFF;
+       if (ucsdata->font_codepage == 437)
+           ucsdata->unitab_font[0] = ucsdata->unitab_font[255] = 0xFFFF;
     }
     if (cfg->vtmode == VT_XWINDOWS)
-       memcpy(unitab_font + 1, unitab_xterm_std,
+       memcpy(ucsdata->unitab_font + 1, unitab_xterm_std,
               sizeof(unitab_xterm_std));
 
     /* Collect OEMCP ucs table */
-    get_unitab(CP_OEMCP, unitab_oemcp, 1);
+    get_unitab(CP_OEMCP, ucsdata->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));
+       memcpy(ucsdata->unitab_scoacs, ucsdata->unitab_oemcp,
+              sizeof(ucsdata->unitab_scoacs));
     else
-       get_unitab(437, unitab_scoacs, 1);
+       get_unitab(437, ucsdata->unitab_scoacs, 1);
 
     /* Collect line set ucs table */
-    if (line_codepage == font_codepage &&
-       (dbcs_screenfont || cfg->vtmode == VT_POORMAN || font_codepage==0)) {
+    if (ucsdata->line_codepage == ucsdata->font_codepage &&
+       (ucsdata->dbcs_screenfont ||
+        cfg->vtmode == VT_POORMAN || ucsdata->font_codepage==0)) {
 
        /* For DBCS and POOR fonts force direct to font */
        used_dtf = 1;
        for (i = 0; i < 32; i++)
-           unitab_line[i] = (WCHAR) i;
+           ucsdata->unitab_line[i] = (WCHAR) i;
        for (i = 32; i < 256; i++)
-           unitab_line[i] = (WCHAR) (ATTR_ACP + i);
-       unitab_line[127] = (WCHAR) 127;
+           ucsdata->unitab_line[i] = (WCHAR) (ATTR_ACP + i);
+       ucsdata->unitab_line[127] = (WCHAR) 127;
     } else {
-       get_unitab(line_codepage, unitab_line, 0);
+       get_unitab(ucsdata->line_codepage, ucsdata->unitab_line, 0);
     }
 
 #if 0
     debug(
-         ("Line cp%d, Font cp%d%s\n", line_codepage, font_codepage,
-          dbcs_screenfont ? " DBCS" : ""));
+         ("Line cp%d, Font cp%d%s\n", ucsdata->line_codepage,
+          ucsdata->font_codepage, ucsdata->dbcs_screenfont ? " DBCS" : ""));
 
     for (i = 0; i < 256; i += 16) {
        for (j = 0; j < 16; j++) {
-           debug(("%04x%s", unitab_line[i + j], j == 15 ? "" : ","));
+           debug(("%04x%s", ucsdata->unitab_line[i + j], j == 15 ? "" : ","));
        }
        debug(("\n"));
     }
 #endif
 
     /* VT100 graphics - NB: Broken for non-ascii CP's */
-    memcpy(unitab_xterm, unitab_line, sizeof(unitab_xterm));
-    memcpy(unitab_xterm + '`', unitab_xterm_std, sizeof(unitab_xterm_std));
-    unitab_xterm['_'] = ' ';
+    memcpy(ucsdata->unitab_xterm, ucsdata->unitab_line,
+          sizeof(ucsdata->unitab_xterm));
+    memcpy(ucsdata->unitab_xterm + '`', unitab_xterm_std,
+          sizeof(unitab_xterm_std));
+    ucsdata->unitab_xterm['_'] = ' ';
 
     /* Generate UCS ->line page table. */
-    if (uni_tbl) {
+    if (ucsdata->uni_tbl) {
        for (i = 0; i < 256; i++)
-           if (uni_tbl[i])
-               sfree(uni_tbl[i]);
-       sfree(uni_tbl);
-       uni_tbl = 0;
+           if (ucsdata->uni_tbl[i])
+               sfree(ucsdata->uni_tbl[i]);
+       sfree(ucsdata->uni_tbl);
+       ucsdata->uni_tbl = 0;
     }
     if (!used_dtf) {
        for (i = 0; i < 256; i++) {
-           if (DIRECT_CHAR(unitab_line[i]))
+           if (DIRECT_CHAR(ucsdata->unitab_line[i]))
                continue;
-           if (DIRECT_FONT(unitab_line[i]))
+           if (DIRECT_FONT(ucsdata->unitab_line[i]))
                continue;
-           if (!uni_tbl) {
-               uni_tbl = smalloc(256 * sizeof(char *));
-               memset(uni_tbl, 0, 256 * sizeof(char *));
+           if (!ucsdata->uni_tbl) {
+               ucsdata->uni_tbl = smalloc(256 * sizeof(char *));
+               memset(ucsdata->uni_tbl, 0, 256 * sizeof(char *));
            }
-           j = ((unitab_line[i] >> 8) & 0xFF);
-           if (!uni_tbl[j]) {
-               uni_tbl[j] = smalloc(256 * sizeof(char));
-               memset(uni_tbl[j], 0, 256 * sizeof(char));
+           j = ((ucsdata->unitab_line[i] >> 8) & 0xFF);
+           if (!ucsdata->uni_tbl[j]) {
+               ucsdata->uni_tbl[j] = smalloc(256 * sizeof(char));
+               memset(ucsdata->uni_tbl[j], 0, 256 * sizeof(char));
            }
-           uni_tbl[j][unitab_line[i] & 0xFF] = i;
+           ucsdata->uni_tbl[j][ucsdata->unitab_line[i] & 0xFF] = i;
        }
     }
 
     /* Find the line control characters. */
     for (i = 0; i < 256; i++)
-       if (unitab_line[i] < ' '
-           || (unitab_line[i] >= 0x7F && unitab_line[i] < 0xA0))
-           unitab_ctrl[i] = i;
+       if (ucsdata->unitab_line[i] < ' '
+           || (ucsdata->unitab_line[i] >= 0x7F && 
+               ucsdata->unitab_line[i] < 0xA0))
+           ucsdata->unitab_ctrl[i] = i;
        else
-           unitab_ctrl[i] = 0xFF;
+           ucsdata->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(ucsdata->unitab_scoacs, ucsdata->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);
+    link_font(ucsdata->unitab_line, ucsdata->unitab_font, ATTR_ACP);
+    link_font(ucsdata->unitab_scoacs, ucsdata->unitab_font, ATTR_ACP);
+    link_font(ucsdata->unitab_xterm, ucsdata->unitab_font, ATTR_ACP);
 
     if (cfg->vtmode == VT_OEMANSI || cfg->vtmode == VT_XWINDOWS) {
-       link_font(unitab_line, unitab_oemcp, ATTR_OEMCP);
-       link_font(unitab_xterm, unitab_oemcp, ATTR_OEMCP);
+       link_font(ucsdata->unitab_line, ucsdata->unitab_oemcp, ATTR_OEMCP);
+       link_font(ucsdata->unitab_xterm, ucsdata->unitab_oemcp, ATTR_OEMCP);
     }
 
-    if (dbcs_screenfont && font_codepage != line_codepage) {
+    if (ucsdata->dbcs_screenfont &&
+       ucsdata->font_codepage != ucsdata->line_codepage) {
        /* F***ing Microsoft fonts, Japanese and Korean codepage fonts
         * have a currency symbol at 0x5C but their unicode value is 
         * still given as U+005C not the correct U+00A5. */
-       unitab_line['\\'] = ATTR_OEMCP + '\\';
+       ucsdata->unitab_line['\\'] = ATTR_OEMCP + '\\';
     }
 
     /* Last chance, if !unicode then try poorman links. */
@@ -563,18 +567,20 @@ void init_ucs(Config *cfg)
        static char poorman_vt100[] = "*#****o~**+++++-----++++|****L.";
 
        for (i = 160; i < 256; i++)
-           if (!DIRECT_FONT(unitab_line[i]) &&
-               unitab_line[i] >= 160 && unitab_line[i] < 256)
-               unitab_line[i] = (WCHAR) (ATTR_ACP
-                                         + poorman_latin1[unitab_line[i] -
-                                                          160]);
+           if (!DIRECT_FONT(ucsdata->unitab_line[i]) &&
+               ucsdata->unitab_line[i] >= 160 &&
+               ucsdata->unitab_line[i] < 256) {
+               ucsdata->unitab_line[i] =
+                   (WCHAR) (ATTR_ACP +
+                            poorman_latin1[ucsdata->unitab_line[i] - 160]);
+           }
        for (i = 96; i < 127; i++)
-           if (!DIRECT_FONT(unitab_xterm[i]))
-               unitab_xterm[i] =
-                   (WCHAR) (ATTR_ACP + poorman_vt100[i - 96]);
+           if (!DIRECT_FONT(ucsdata->unitab_xterm[i]))
+               ucsdata->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] = 
+           if (!DIRECT_FONT(ucsdata->unitab_scoacs[i]))
+               ucsdata->unitab_scoacs[i] = 
                    (WCHAR) (ATTR_ACP + poorman_scoacs[i - 128]);
     }
 }
@@ -1172,11 +1178,12 @@ void get_unitab(int codepage, wchar_t * unitab, int ftype)
 }
 
 int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
-            char *mbstr, int mblen, char *defchr, int *defused)
+            char *mbstr, int mblen, char *defchr, int *defused,
+            struct unicode_data *ucsdata)
 {
     char *p;
     int i;
-    if (codepage == line_codepage && uni_tbl) {
+    if (ucsdata && codepage == ucsdata->line_codepage && ucsdata->uni_tbl) {
        /* Do this by array lookup if we can. */
        if (wclen < 0) {
            for (wclen = 0; wcstr[wclen++] ;);   /* will include the NUL */
@@ -1185,7 +1192,7 @@ int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
            wchar_t ch = wcstr[i];
            int by;
            char *p1;
-           if (uni_tbl && (p1 = uni_tbl[(ch >> 8) & 0xFF])
+           if (ucsdata->uni_tbl && (p1 = ucsdata->uni_tbl[(ch >> 8) & 0xFF])
                && (by = p1[ch & 0xFF]))
                *p++ = by;
            else if (ch < 0x80)
index 69538f7..c207195 100644 (file)
@@ -67,6 +67,7 @@ struct gui_data {
     void *backhandle;
     Terminal *term;
     void *logctx;
+    struct unicode_data ucsdata;
     Config cfg;
 };
 
@@ -1283,9 +1284,10 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
 
     inst->pasteout_data = smalloc(len*6);
     inst->pasteout_data_len = len*6;
-    inst->pasteout_data_len = wc_to_mb(line_codepage, 0, data, len,
-                                      inst->pasteout_data,
-                                      inst->pasteout_data_len, NULL, NULL);
+    inst->pasteout_data_len = wc_to_mb(inst->ucsdata.line_codepage, 0,
+                                      data, len, inst->pasteout_data,
+                                      inst->pasteout_data_len,
+                                      NULL, NULL, NULL);
     if (inst->pasteout_data_len == 0) {
        sfree(inst->pasteout_data);
        inst->pasteout_data = NULL;
@@ -1396,7 +1398,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
     inst->pastein_data_len = seldata->length;
     inst->pastein_data_len =
        mb_to_wc((seldata->type == inst->utf8_string_atom ?
-                 CS_UTF8 : line_codepage),
+                 CS_UTF8 : inst->ucsdata.line_codepage),
                 0, seldata->data, seldata->length,
                 inst->pastein_data, inst->pastein_data_len);
 
@@ -1646,7 +1648,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
        } else {
            gcs = smalloc(sizeof(GdkWChar) * (len+1));
            wc_to_mb(inst->fontinfo[fontid].charset, 0,
-                    wcs, len, gcs, len, ".", NULL);
+                    wcs, len, gcs, len, ".", NULL, NULL);
            gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc,
                          x*inst->font_width+inst->cfg.window_border,
                          y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,
@@ -2315,7 +2317,8 @@ int main(int argc, char **argv)
     inst->compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE);
     inst->utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE);
 
-    inst->direct_to_font = init_ucs(inst->cfg.line_codepage, font_charset);
+    inst->direct_to_font = init_ucs(&inst->ucsdata,
+                                   inst->cfg.line_codepage, font_charset);
 
     inst->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
@@ -2415,7 +2418,7 @@ int main(int argc, char **argv)
     inst->currcursor = inst->textcursor;
     show_mouseptr(inst, 1);
 
-    inst->term = term_init(&inst->cfg, inst);
+    inst->term = term_init(&inst->cfg, &inst->ucsdata, inst);
     inst->logctx = log_init(inst, &inst->cfg);
     term_provide_logctx(inst->term, inst->logctx);
 
index a1b155a..65f374d 100644 (file)
@@ -69,7 +69,9 @@ void (*putty_signal(int sig, void (*func)(int)))(int);
 /*
  * Exports from unicode.c.
  */
-int init_ucs(char *line_codepage, int font_charset);
+struct unicode_data;
+int init_ucs(struct unicode_data *ucsdata,
+            char *line_codepage, int font_charset);
 
 /*
  * Spare function exported directly from uxnet.c.
index 5b21149..8731239 100644 (file)
@@ -58,7 +58,8 @@ int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
 }
 
 int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
-            char *mbstr, int mblen, char *defchr, int *defused)
+            char *mbstr, int mblen, char *defchr, int *defused,
+            struct unicode_data *ucsdata)
 {
     /* FIXME: we should remove the defused param completely... */
     if (defused)
@@ -104,7 +105,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(char *linecharset, int font_charset)
+int init_ucs(struct unicode_data *ucsdata, 
+            char *linecharset, int font_charset)
 {
     int i, ret = 0;
 
@@ -114,15 +116,15 @@ int init_ucs(char *linecharset, int font_charset)
      * support at all. So we set this to something which will never
      * be used.
      */
-    font_codepage = -1;
+    ucsdata->font_codepage = -1;
 
     /*
      * line_codepage should be decoded from the specification in
      * cfg.
      */
-    line_codepage = charset_from_mimeenc(linecharset);
-    if (line_codepage == CS_NONE)
-       line_codepage = charset_from_xenc(linecharset);
+    ucsdata->line_codepage = charset_from_mimeenc(linecharset);
+    if (ucsdata->line_codepage == CS_NONE)
+       ucsdata->line_codepage = charset_from_xenc(linecharset);
 
     /*
      * If line_codepage is _still_ CS_NONE, we assume we're using
@@ -131,10 +133,10 @@ int init_ucs(char *linecharset, int font_charset)
      * font we were given had an incomprehensible charset - then we
      * fall back to using the D800 page.
      */
-    if (line_codepage == CS_NONE)
-       line_codepage = font_charset;
+    if (ucsdata->line_codepage == CS_NONE)
+       ucsdata->line_codepage = font_charset;
 
-    if (line_codepage == CS_NONE)
+    if (ucsdata->line_codepage == CS_NONE)
        ret = 1;
 
     /*
@@ -148,13 +150,14 @@ int init_ucs(char *linecharset, int font_charset)
        c[0] = i;
        p = c;
        len = 1;
-       if (line_codepage == CS_NONE)
-           unitab_line[i] = 0xD800 | i;
-       else if (1 == charset_to_unicode(&p, &len, wc, 1, line_codepage,
+       if (ucsdata->line_codepage == CS_NONE)
+           ucsdata->unitab_line[i] = 0xD800 | i;
+       else if (1 == charset_to_unicode(&p, &len, wc, 1,
+                                        ucsdata->line_codepage,
                                         NULL, L"", 0))
-           unitab_line[i] = wc[0];
+           ucsdata->unitab_line[i] = wc[0];
        else
-           unitab_line[i] = 0xFFFD;
+           ucsdata->unitab_line[i] = 0xFFFD;
     }
 
     /*
@@ -175,9 +178,9 @@ int init_ucs(char *linecharset, int font_charset)
            0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
        };
        if (i >= 0x5F && i < 0x7F)
-           unitab_xterm[i] = unitab_xterm_std[i & 0x1F];
+           ucsdata->unitab_xterm[i] = unitab_xterm_std[i & 0x1F];
        else
-           unitab_xterm[i] = unitab_line[i];
+           ucsdata->unitab_xterm[i] = ucsdata->unitab_line[i];
     }
 
     /*
@@ -192,9 +195,9 @@ int init_ucs(char *linecharset, int font_charset)
        p = c;
        len = 1;
        if (1 == charset_to_unicode(&p, &len, wc, 1, CS_CP437, NULL, L"", 0))
-           unitab_scoacs[i] = wc[0];
+           ucsdata->unitab_scoacs[i] = wc[0];
        else
-           unitab_scoacs[i] = 0xFFFD;
+           ucsdata->unitab_scoacs[i] = 0xFFFD;
     }
 
     /*
@@ -205,12 +208,12 @@ int init_ucs(char *linecharset, int font_charset)
      * used in this way will be IBM or MS code pages anyway.)
      */
     for (i = 0; i < 256; i++) {
-       int lineval = unitab_line[i];
+       int lineval = ucsdata->unitab_line[i];
        if (lineval < ' ' || (lineval >= 0x7F && lineval < 0xA0) ||
            (lineval >= 0xD800 && lineval < 0xD820) || (lineval == 0xD87F))
-           unitab_ctrl[i] = i;
+           ucsdata->unitab_ctrl[i] = i;
        else
-           unitab_ctrl[i] = 0xFF;
+           ucsdata->unitab_ctrl[i] = 0xFF;
     }
 
     return ret;
index 77f4598..aac6ac6 100644 (file)
--- a/window.c
+++ b/window.c
@@ -120,6 +120,7 @@ static void *ldisc;
 static Backend *back;
 static void *backhandle;
 
+static struct unicode_data ucsdata;
 static int session_closed;
 
 Config cfg;                           /* exported to windlg.c */
@@ -508,7 +509,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
     hwnd = NULL;
 
-    term = term_init(&cfg, NULL);
+    memset(&ucsdata, 0, sizeof(ucsdata));
+
+    term = term_init(&cfg, &ucsdata, NULL);
     logctx = log_init(NULL, &cfg);
     term_provide_logctx(term, logctx);
 
@@ -1112,16 +1115,15 @@ static void init_fonts(int pick_width, int pick_height)
 
        /* !!! Yes the next line is right */
        if (cset == OEM_CHARSET)
-           font_codepage = GetOEMCP();
+           ucsdata.font_codepage = GetOEMCP();
        else
-           if (TranslateCharsetInfo
-               ((DWORD *) cset, &info, TCI_SRCCHARSET)) font_codepage =
-               info.ciACP;
+           if (TranslateCharsetInfo ((DWORD *) cset, &info, TCI_SRCCHARSET))
+               ucsdata.font_codepage = info.ciACP;
        else
-           font_codepage = -1;
+           ucsdata.font_codepage = -1;
 
-       GetCPInfo(font_codepage, &cpinfo);
-       dbcs_screenfont = (cpinfo.MaxCharSize > 1);
+       GetCPInfo(ucsdata.font_codepage, &cpinfo);
+       ucsdata.dbcs_screenfont = (cpinfo.MaxCharSize > 1);
     }
 
     f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE);
@@ -1209,7 +1211,7 @@ static void init_fonts(int pick_width, int pick_height)
     }
     fontflag[0] = fontflag[1] = fontflag[2] = 1;
 
-    init_ucs(&cfg);
+    init_ucs(&cfg, &ucsdata);
 }
 
 static void another_font(int fontno)
@@ -2760,8 +2762,8 @@ void do_text(Context ctx, int x, int y, char *text, int len,
            if (lattr == LATTR_TOP || lattr == LATTR_BOT)
                text_adjust *= 2;
            attr &= ~CSET_MASK;
-           text[0] = (char) (unitab_xterm['q'] & CHAR_MASK);
-           attr |= (unitab_xterm['q'] & CSET_MASK);
+           text[0] = (char) (ucsdata.unitab_xterm['q'] & CHAR_MASK);
+           attr |= (ucsdata.unitab_xterm['q'] & CSET_MASK);
            if (attr & ATTR_UNDER) {
                attr &= ~ATTR_UNDER;
                force_manual_underline = 1;
@@ -2822,7 +2824,7 @@ void do_text(Context ctx, int x, int y, char *text, int len,
        line_box.right = font_width*term->cols+offset_width;
 
     /* We're using a private area for direct to font. (512 chars.) */
-    if (dbcs_screenfont && (attr & CSET_MASK) == ATTR_ACP) {
+    if (ucsdata.dbcs_screenfont && (attr & CSET_MASK) == ATTR_ACP) {
        /* Ho Hum, dbcs fonts are a PITA! */
        /* To display on W9x I have to convert to UCS */
        static wchar_t *uni_buf = 0;
@@ -2835,15 +2837,15 @@ void do_text(Context ctx, int x, int y, char *text, int len,
 
        for(nlen = mptr = 0; mptr<len; mptr++) {
            uni_buf[nlen] = 0xFFFD;
-           if (IsDBCSLeadByteEx(font_codepage, (BYTE) text[mptr])) {
+           if (IsDBCSLeadByteEx(ucsdata.font_codepage, (BYTE) text[mptr])) {
                IpDx[nlen] += char_width;
-               MultiByteToWideChar(font_codepage, MB_USEGLYPHCHARS,
+               MultiByteToWideChar(ucsdata.font_codepage, MB_USEGLYPHCHARS,
                                   text+mptr, 2, uni_buf+nlen, 1);
                mptr++;
            }
            else
            {
-               MultiByteToWideChar(font_codepage, MB_USEGLYPHCHARS,
+               MultiByteToWideChar(ucsdata.font_codepage, MB_USEGLYPHCHARS,
                                   text+mptr, 1, uni_buf+nlen, 1);
            }
            nlen++;
@@ -3012,17 +3014,17 @@ int char_width(Context ctx, int uc) {
 
     switch (uc & CSET_MASK) {
       case ATTR_ASCII:
-       uc = unitab_line[uc & 0xFF];
+       uc = ucsdata.unitab_line[uc & 0xFF];
        break;
       case ATTR_LINEDRW:
-       uc = unitab_xterm[uc & 0xFF];
+       uc = ucsdata.unitab_xterm[uc & 0xFF];
        break;
       case ATTR_SCOACS:
-       uc = unitab_scoacs[uc & 0xFF];
+       uc = ucsdata.unitab_scoacs[uc & 0xFF];
        break;
     }
     if (DIRECT_FONT(uc)) {
-       if (dbcs_screenfont) return 1;
+       if (ucsdata.dbcs_screenfont) return 1;
 
        /* Speedup, I know of no font where ascii is the wrong width */
        if ((uc&CHAR_MASK) >= ' ' && (uc&CHAR_MASK)<= '~') 
@@ -3767,7 +3769,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 #ifdef SHOW_TOASCII_RESULT
        if (r == 1 && !key_down) {
            if (alt_sum) {
-               if (in_utf(term) || dbcs_screenfont)
+               if (in_utf(term) || ucsdata.dbcs_screenfont)
                    debug((", (U+%04x)", alt_sum));
                else
                    debug((", LCH(%d)", alt_sum));
@@ -3820,7 +3822,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
                if (!key_down) {
                    if (alt_sum) {
-                       if (in_utf(term) || dbcs_screenfont) {
+                       if (in_utf(term) || ucsdata.dbcs_screenfont) {
                            keybuf = alt_sum;
                            term_seen_key_event(term);
                            luni_send(ldisc, &keybuf, 1, 1);
@@ -3870,7 +3872,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] && (in_utf(term) || dbcs_screenfont))
+       else if (keys[0] && (in_utf(term) || ucsdata.dbcs_screenfont))
            keys[0] = 10;
     }
 
index 9516675..ed12ba5 100644 (file)
@@ -201,6 +201,6 @@ void EnableSizeTip(int bEnable);
 /*
  * Exports from unicode.c.
  */
-void init_ucs(Config *);
+void init_ucs(Config *, struct unicode_data *);
 
 #endif