From 21d2b241875c072a8700e838ae0da677a7b9d428 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 14 Jan 2003 18:28:23 +0000 Subject: [PATCH] Deglobalise the Unicode module. Despite all my grand plans, I've 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 | 4 +- putty.h | 26 +++++----- terminal.c | 55 +++++++++++---------- terminal.h | 4 +- unicode.c | 157 +++++++++++++++++++++++++++++++---------------------------- unix/pterm.c | 17 ++++--- unix/unix.h | 4 +- unix/uxucs.c | 45 +++++++++-------- window.c | 46 ++++++++--------- winstuff.h | 2 +- 10 files changed, 193 insertions(+), 167 deletions(-) diff --git a/ldiscucs.c b/ldiscucs.c index 2e19adcc..2160266c 100644 --- a/ldiscucs.c +++ b/ldiscucs.c @@ -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 db37db24..12944ed0 100644 --- 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); diff --git a/terminal.c b/terminal.c index ba5e14e8..9ad33d61 100644 --- a/terminal.c +++ b/terminal.c @@ -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) diff --git a/terminal.h b/terminal.h index 72c8f877..daadd708 100644 --- a/terminal.h +++ b/terminal.h @@ -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 diff --git a/unicode.c b/unicode.c index 3c25c6ea..fdfa08db 100644 --- 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) diff --git a/unix/pterm.c b/unix/pterm.c index 69538f7c..c2071955 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -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); diff --git a/unix/unix.h b/unix/unix.h index a1b155a6..65f374d4 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -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. diff --git a/unix/uxucs.c b/unix/uxucs.c index 5b211498..8731239f 100644 --- a/unix/uxucs.c +++ b/unix/uxucs.c @@ -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; diff --git a/window.c b/window.c index 77f45984..aac6ac6a 100644 --- 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= ' ' && (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; } diff --git a/winstuff.h b/winstuff.h index 9516675a..ed12ba56 100644 --- a/winstuff.h +++ b/winstuff.h @@ -201,6 +201,6 @@ void EnableSizeTip(int bEnable); /* * Exports from unicode.c. */ -void init_ucs(Config *); +void init_ucs(Config *, struct unicode_data *); #endif -- 2.11.0