Add CJK Width option to PuTTY. This is a HACK for lagency CJK terminal software that assume box drawing characters is width 2. Index: config.c =================================================================== --- config.c (revision 5396) +++ config.c (working copy) @@ -999,6 +999,9 @@ ctrl_checkbox(s, "Enable blinking text", 'n', HELPCTX(terminal_blink), dlg_stdcheckbox_handler, I(offsetof(Config,blinktext))); + ctrl_checkbox(s, "Set width of CJK ambiguous characters to 2", 'J', + HELPCTX(terminal_cjk_width), + dlg_stdcheckbox_handler, I(offsetof(Config,cjk_width))); ctrl_editbox(s, "Answerback to ^E:", 's', 100, HELPCTX(terminal_answerback), dlg_stdeditbox_handler, I(offsetof(Config,answerback)), Index: windows/winhelp.h =================================================================== --- windows/winhelp.h (revision 5396) +++ windows/winhelp.h (working copy) @@ -41,6 +41,7 @@ #define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr" #define WINHELP_CTX_terminal_bce "terminal.bce" #define WINHELP_CTX_terminal_blink "terminal.blink" +#define WINHELP_CTX_terminal_cjk_width "terminal.cjk_width" #define WINHELP_CTX_terminal_answerback "terminal.answerback" #define WINHELP_CTX_terminal_localecho "terminal.localecho" #define WINHELP_CTX_terminal_localedit "terminal.localedit" Index: doc/config.but =================================================================== --- doc/config.but (revision 5396) +++ doc/config.but (working copy) @@ -397,6 +397,17 @@ mid-session using \q{Change Settings}, it will take effect immediately. +\S{config-blink} \q{Set width of CJK ambiguous characters to 2} + +\cfg{winhelp-topic}{terminal.cjk_width} + +When this is on, characters with East Asian Ambiguous (A) category +in UTR 11 have a column width of 2. Othrwise, they have a column +width of 1. + +This is useful for some legacy CJK text terminal-based programs (like +BBS) assuming box drawings and others to have a column width of 2. + \S{config-answerback} \q{Answerback to ^E} \cfg{winhelp-topic}{terminal.answerback} Index: settings.c =================================================================== --- settings.c (revision 5396) +++ settings.c (working copy) @@ -350,6 +350,7 @@ write_setting_i(sesskey, "LockSize", cfg->resize_action); write_setting_i(sesskey, "BCE", cfg->bce); write_setting_i(sesskey, "BlinkText", cfg->blinktext); + write_setting_i(sesskey, "CJKWidth", cfg->cjk_width); write_setting_i(sesskey, "X11Forward", cfg->x11_forward); write_setting_s(sesskey, "X11Display", cfg->x11_display); write_setting_i(sesskey, "X11AuthType", cfg->x11_auth); @@ -576,6 +577,7 @@ gppi(sesskey, "WindowBorder", 1, &cfg->window_border); gppi(sesskey, "CurType", 0, &cfg->cursor_type); gppi(sesskey, "BlinkCur", 0, &cfg->blink_cur); + gppi(sesskey, "CJKWidth", 0, &cfg->cjk_width); /* pedantic compiler tells me I can't use &cfg->beep as an int * :-) */ gppi(sesskey, "Beep", 1, &cfg->beep); gppi(sesskey, "BeepInd", 0, &cfg->beep_ind); Index: terminal.c =================================================================== --- terminal.c (revision 5396) +++ terminal.c (working copy) @@ -1179,6 +1179,9 @@ term->app_keypad_keys = term->cfg.app_keypad; term->use_bce = term->cfg.bce; term->blink_is_real = term->cfg.blinktext; + my_wcwidth = &wcwidth; + if (term->cjk_width = term->cfg.cjk_width) + my_wcwidth = &wcwidth_cjk; term->erase_char = term->basic_erase_char; term->alt_which = 0; term_print_finish(term); @@ -1290,13 +1293,14 @@ * default one. The full list is: Auto wrap mode, DEC Origin * Mode, BCE, blinking text, character classes. */ - int reset_wrap, reset_decom, reset_bce, reset_tblink, reset_charclass; + int reset_wrap, reset_decom, reset_bce, reset_tblink, reset_cjk_width, reset_charclass; int i; reset_wrap = (term->cfg.wrap_mode != cfg->wrap_mode); reset_decom = (term->cfg.dec_om != cfg->dec_om); reset_bce = (term->cfg.bce != cfg->bce); reset_tblink = (term->cfg.blinktext != cfg->blinktext); + reset_cjk_width = (term->cfg.cjk_width != cfg->cjk_width); reset_charclass = 0; for (i = 0; i < lenof(term->cfg.wordness); i++) if (term->cfg.wordness[i] != cfg->wordness[i]) @@ -1331,6 +1335,11 @@ if (reset_tblink) { term->blink_is_real = term->cfg.blinktext; } + if (reset_cjk_width) { + my_wcwidth = &wcwidth; + if (term->cjk_width = term->cfg.cjk_width) + my_wcwidth = &wcwidth_cjk; + } if (reset_charclass) for (i = 0; i < 256; i++) term->wordness[i] = term->cfg.wordness[i]; @@ -2830,7 +2839,7 @@ if (DIRECT_CHAR(c)) width = 1; if (!width) - width = wcwidth((wchar_t) c); + width = my_wcwidth((wchar_t) c); if (term->wrapnext && term->wrap && width > 0) { cline->lattr |= LATTR_WRAPPED; Index: terminal.h =================================================================== --- terminal.h (revision 5396) +++ terminal.h (working copy) @@ -121,6 +121,7 @@ int cblinker; /* When blinking is the cursor on ? */ int tblinker; /* When the blinking text is on */ int blink_is_real; /* Actually blink blinking text */ + int cjk_width; /* Enable CJK Width ? */ int term_echoing; /* Does terminal want local echo? */ int term_editing; /* Does terminal want local edit? */ int sco_acs, save_sco_acs; /* CSI 10,11,12m -> OEM charset */ Index: wcwidth.c =================================================================== --- wcwidth.c (revision 5396) +++ wcwidth.c (working copy) @@ -146,7 +146,6 @@ return width; } -#if 0 /* RDB: we don't need the cjk version */ /* * The following function is the same as wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as @@ -155,7 +154,7 @@ * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ -static int wcwidth_cjk(wchar_t ucs) +int wcwidth_cjk(wchar_t ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ @@ -233,4 +232,3 @@ return width; } -#endif Index: putty.h =================================================================== --- putty.h (revision 5396) +++ putty.h (working copy) @@ -483,6 +483,7 @@ int resize_action; int bce; int blinktext; + int cjk_width; int win_name_always; int width, height; FontSpec font; @@ -858,8 +859,11 @@ /* * Exports from wcwidth.c */ +int (*my_wcwidth)(wchar_t ucs); int wcwidth(wchar_t ucs); int wcswidth(const wchar_t *pwcs, size_t n); +int wcwidth_cjk(wchar_t ucs); +int wcswidth_cjk(const wchar_t *pwcs, size_t n); /* * Exports from mscrypto.c