mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
RDB: fix various UTF-8 glitches.
[originally from svn r1138]
This commit is contained in:
parent
26d63c3a96
commit
38b6d276d2
4
ldisc.c
4
ldisc.c
@ -28,7 +28,7 @@ static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
|
|||||||
|
|
||||||
static int plen(unsigned char c)
|
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;
|
return 1;
|
||||||
else if (c < 128)
|
else if (c < 128)
|
||||||
return 2; /* ^x for some x */
|
return 2; /* ^x for some x */
|
||||||
@ -38,7 +38,7 @@ static int plen(unsigned char c)
|
|||||||
|
|
||||||
static void pwrite(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);
|
c_write(&c, 1);
|
||||||
} else if (c < 128) {
|
} else if (c < 128) {
|
||||||
char cc[2];
|
char cc[2];
|
||||||
|
3
putty.h
3
putty.h
@ -78,7 +78,7 @@
|
|||||||
#define ATTR_DEFAULT 0x00980000UL
|
#define ATTR_DEFAULT 0x00980000UL
|
||||||
#define ATTR_DEFFG 0x00080000UL
|
#define ATTR_DEFFG 0x00080000UL
|
||||||
#define ATTR_DEFBG 0x00900000UL
|
#define ATTR_DEFBG 0x00900000UL
|
||||||
#define ERASE_CHAR (ATTR_DEFAULT | ' ')
|
#define ERASE_CHAR (ATTR_DEFAULT | ATTR_ASCII | ' ')
|
||||||
#define ATTR_MASK 0xFFFFFF00UL
|
#define ATTR_MASK 0xFFFFFF00UL
|
||||||
#define CHAR_MASK 0x000000FFUL
|
#define CHAR_MASK 0x000000FFUL
|
||||||
|
|
||||||
@ -127,6 +127,7 @@ GLOBAL WCHAR unitab_font[256];
|
|||||||
GLOBAL WCHAR unitab_xterm[256];
|
GLOBAL WCHAR unitab_xterm[256];
|
||||||
GLOBAL WCHAR unitab_oemcp[256];
|
GLOBAL WCHAR unitab_oemcp[256];
|
||||||
GLOBAL unsigned char unitab_ctrl[256];
|
GLOBAL unsigned char unitab_ctrl[256];
|
||||||
|
#define in_utf (utf || line_codepage==CP_UTF8)
|
||||||
|
|
||||||
#define LGXF_OVR 1 /* existing logfile overwrite */
|
#define LGXF_OVR 1 /* existing logfile overwrite */
|
||||||
#define LGXF_APN 0 /* existing logfile append */
|
#define LGXF_APN 0 /* existing logfile append */
|
||||||
|
65
terminal.c
65
terminal.c
@ -94,6 +94,7 @@ static int wrap, wrapnext; /* wrap flags */
|
|||||||
static int insert; /* insert-mode flag */
|
static int insert; /* insert-mode flag */
|
||||||
static int cset; /* 0 or 1: which char set */
|
static int cset; /* 0 or 1: which char set */
|
||||||
static int save_cset, save_csattr; /* saved with cursor position */
|
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 rvideo; /* global reverse video flag */
|
||||||
static int rvbell_timeout; /* for ESC[?5hESC[?5l vbell */
|
static int rvbell_timeout; /* for ESC[?5hESC[?5l vbell */
|
||||||
static int cursor_on; /* cursor enabled flag */
|
static int cursor_on; /* cursor enabled flag */
|
||||||
@ -117,7 +118,7 @@ static unsigned long cset_attr[2];
|
|||||||
/*
|
/*
|
||||||
* Saved settings on the alternate screen.
|
* 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_t, alt_b;
|
||||||
static int alt_which;
|
static int alt_which;
|
||||||
|
|
||||||
@ -279,6 +280,7 @@ static void power_on(void)
|
|||||||
alt_wnext = wrapnext = alt_ins = insert = FALSE;
|
alt_wnext = wrapnext = alt_ins = insert = FALSE;
|
||||||
alt_wrap = wrap = cfg.wrap_mode;
|
alt_wrap = wrap = cfg.wrap_mode;
|
||||||
alt_cset = cset = 0;
|
alt_cset = cset = 0;
|
||||||
|
alt_utf = utf = 0;
|
||||||
alt_sco_acs = sco_acs = 0;
|
alt_sco_acs = sco_acs = 0;
|
||||||
cset_attr[0] = cset_attr[1] = ATTR_ASCII;
|
cset_attr[0] = cset_attr[1] = ATTR_ASCII;
|
||||||
rvideo = 0;
|
rvideo = 0;
|
||||||
@ -538,6 +540,9 @@ static void swap_screen(int which)
|
|||||||
t = cset;
|
t = cset;
|
||||||
cset = alt_cset;
|
cset = alt_cset;
|
||||||
alt_cset = t;
|
alt_cset = t;
|
||||||
|
t = utf;
|
||||||
|
utf = alt_utf;
|
||||||
|
alt_utf = t;
|
||||||
t = sco_acs;
|
t = sco_acs;
|
||||||
sco_acs = alt_sco_acs;
|
sco_acs = alt_sco_acs;
|
||||||
alt_sco_acs = t;
|
alt_sco_acs = t;
|
||||||
@ -694,6 +699,7 @@ static void save_cursor(int save)
|
|||||||
savecurs = curs;
|
savecurs = curs;
|
||||||
save_attr = curr_attr;
|
save_attr = curr_attr;
|
||||||
save_cset = cset;
|
save_cset = cset;
|
||||||
|
save_utf = utf;
|
||||||
save_csattr = cset_attr[cset];
|
save_csattr = cset_attr[cset];
|
||||||
save_sco_acs = sco_acs;
|
save_sco_acs = sco_acs;
|
||||||
} else {
|
} else {
|
||||||
@ -706,11 +712,13 @@ static void save_cursor(int save)
|
|||||||
|
|
||||||
curr_attr = save_attr;
|
curr_attr = save_attr;
|
||||||
cset = save_cset;
|
cset = save_cset;
|
||||||
|
utf = save_utf;
|
||||||
cset_attr[cset] = save_csattr;
|
cset_attr[cset] = save_csattr;
|
||||||
sco_acs = save_sco_acs;
|
sco_acs = save_sco_acs;
|
||||||
fix_cpos;
|
fix_cpos;
|
||||||
if (use_bce)
|
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. */
|
/* First see about all those translations. */
|
||||||
if (termstate == TOPLEVEL) {
|
if (termstate == TOPLEVEL) {
|
||||||
if (utf)
|
if (in_utf)
|
||||||
switch (utf_state) {
|
switch (utf_state) {
|
||||||
case 0:
|
case 0:
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
/* I know; gotos are evil. This one is really bad!
|
/* UTF-8 must be stateless so we ignore iso2022. */
|
||||||
* But before you try removing it follow the path of the
|
if (unitab_ctrl[c] != 0xFF)
|
||||||
* sequence "0x5F 0xC0 0x71" with UTF and VTGraphics on.
|
c = unitab_ctrl[c];
|
||||||
*/
|
else c = ((unsigned char)c) | ATTR_ASCII;
|
||||||
/*
|
break;
|
||||||
if (cfg.no_vt_graph_with_utf8) break;
|
|
||||||
*/
|
|
||||||
goto evil_jump;
|
|
||||||
} else if ((c & 0xe0) == 0xc0) {
|
} else if ((c & 0xe0) == 0xc0) {
|
||||||
utf_size = utf_state = 1;
|
utf_size = utf_state = 1;
|
||||||
utf_char = (c & 0x1f);
|
utf_char = (c & 0x1f);
|
||||||
@ -1039,7 +1044,6 @@ void term_out(void)
|
|||||||
if (sco_acs == 2) c ^= 0x80;
|
if (sco_acs == 2) c ^= 0x80;
|
||||||
c |= ATTR_SCOACS;
|
c |= ATTR_SCOACS;
|
||||||
} else {
|
} else {
|
||||||
evil_jump:;
|
|
||||||
switch (cset_attr[cset]) {
|
switch (cset_attr[cset]) {
|
||||||
/*
|
/*
|
||||||
* Linedraw characters are different from 'ESC ( B'
|
* Linedraw characters are different from 'ESC ( B'
|
||||||
@ -1529,8 +1533,7 @@ void term_out(void)
|
|||||||
break;
|
break;
|
||||||
case ANSI('@', '%'):
|
case ANSI('@', '%'):
|
||||||
compatibility(OTHER);
|
compatibility(OTHER);
|
||||||
if (line_codepage != CP_UTF8)
|
utf = 0;
|
||||||
utf = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1850,11 +1853,9 @@ void term_out(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (use_bce)
|
if (use_bce)
|
||||||
erase_char =
|
erase_char = (' ' | ATTR_ASCII |
|
||||||
(' ' |
|
(curr_attr &
|
||||||
(curr_attr &
|
(ATTR_FGMASK | ATTR_BGMASK)));
|
||||||
(ATTR_FGMASK | ATTR_BGMASK |
|
|
||||||
ATTR_BLINK)));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 's': /* save cursor */
|
case 's': /* save cursor */
|
||||||
@ -1952,10 +1953,9 @@ void term_out(void)
|
|||||||
use_bce = (esc_args[0] <= 0);
|
use_bce = (esc_args[0] <= 0);
|
||||||
erase_char = ERASE_CHAR;
|
erase_char = ERASE_CHAR;
|
||||||
if (use_bce)
|
if (use_bce)
|
||||||
erase_char =
|
erase_char = (' ' | ATTR_ASCII |
|
||||||
(' ' |
|
(curr_attr &
|
||||||
(curr_attr &
|
(ATTR_FGMASK | ATTR_BGMASK)));
|
||||||
(ATTR_FGMASK | ATTR_BGMASK)));
|
|
||||||
break;
|
break;
|
||||||
case ANSI('E', '='):
|
case ANSI('E', '='):
|
||||||
compatibility(OTHER);
|
compatibility(OTHER);
|
||||||
@ -2347,10 +2347,9 @@ void term_out(void)
|
|||||||
vt52_bold = FALSE;
|
vt52_bold = FALSE;
|
||||||
curr_attr = ATTR_DEFAULT;
|
curr_attr = ATTR_DEFAULT;
|
||||||
if (use_bce)
|
if (use_bce)
|
||||||
erase_char = (' ' |
|
erase_char = (' ' | ATTR_ASCII |
|
||||||
(curr_attr &
|
(curr_attr &
|
||||||
(ATTR_FGMASK | ATTR_BGMASK |
|
(ATTR_FGMASK | ATTR_BGMASK)));
|
||||||
ATTR_BLINK)));
|
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
/* compatibility(VI50) */
|
/* compatibility(VI50) */
|
||||||
@ -2392,10 +2391,8 @@ void term_out(void)
|
|||||||
curr_attr |= ATTR_BOLD;
|
curr_attr |= ATTR_BOLD;
|
||||||
|
|
||||||
if (use_bce)
|
if (use_bce)
|
||||||
erase_char = (' ' |
|
erase_char = (' ' | ATTR_ASCII |
|
||||||
(curr_attr &
|
(curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
|
||||||
(ATTR_FGMASK | ATTR_BGMASK |
|
|
||||||
ATTR_BLINK)));
|
|
||||||
break;
|
break;
|
||||||
case VT52_BG:
|
case VT52_BG:
|
||||||
termstate = TOPLEVEL;
|
termstate = TOPLEVEL;
|
||||||
@ -2408,10 +2405,8 @@ void term_out(void)
|
|||||||
curr_attr |= ATTR_BLINK;
|
curr_attr |= ATTR_BLINK;
|
||||||
|
|
||||||
if (use_bce)
|
if (use_bce)
|
||||||
erase_char = (' ' |
|
erase_char = (' ' | ATTR_ASCII |
|
||||||
(curr_attr &
|
(curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
|
||||||
(ATTR_FGMASK | ATTR_BGMASK |
|
|
||||||
ATTR_BLINK)));
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default: break; /* placate gcc warning about enum use */
|
default: break; /* placate gcc warning about enum use */
|
||||||
|
15
unicode.c
15
unicode.c
@ -40,12 +40,18 @@ void init_ucs_tables(void)
|
|||||||
int i, j;
|
int i, j;
|
||||||
int used_dtf = 0;
|
int used_dtf = 0;
|
||||||
char tbuf[256];
|
char tbuf[256];
|
||||||
|
int old_codepage = line_codepage;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
tbuf[i] = i;
|
tbuf[i] = i;
|
||||||
|
|
||||||
/* Decide on the Line and Font codepages */
|
/* Decide on the Line and Font codepages */
|
||||||
line_codepage = decode_codepage(cfg.line_codepage);
|
line_codepage = decode_codepage(cfg.line_codepage);
|
||||||
|
|
||||||
|
if (font_codepage <= 0) {
|
||||||
|
font_codepage=0;
|
||||||
|
dbcs_screenfont=0;
|
||||||
|
}
|
||||||
|
|
||||||
if (cfg.vtmode == VT_OEMONLY) {
|
if (cfg.vtmode == VT_OEMONLY) {
|
||||||
font_codepage = 437;
|
font_codepage = 437;
|
||||||
dbcs_screenfont = 0;
|
dbcs_screenfont = 0;
|
||||||
@ -53,10 +59,9 @@ void init_ucs_tables(void)
|
|||||||
line_codepage = GetACP();
|
line_codepage = GetACP();
|
||||||
} else if (line_codepage <= 0)
|
} else if (line_codepage <= 0)
|
||||||
line_codepage = font_codepage;
|
line_codepage = font_codepage;
|
||||||
utf = (line_codepage == CP_UTF8);
|
|
||||||
|
|
||||||
/* Collect screen font ucs table */
|
/* Collect screen font ucs table */
|
||||||
if (dbcs_screenfont) {
|
if (dbcs_screenfont || font_codepage == 0) {
|
||||||
get_unitab(font_codepage, unitab_font, 2);
|
get_unitab(font_codepage, unitab_font, 2);
|
||||||
for (i = 128; i < 256; i++)
|
for (i = 128; i < 256; i++)
|
||||||
unitab_font[i] = (WCHAR) (ATTR_ACP + i);
|
unitab_font[i] = (WCHAR) (ATTR_ACP + i);
|
||||||
@ -82,7 +87,7 @@ void init_ucs_tables(void)
|
|||||||
|
|
||||||
/* Collect line set ucs table */
|
/* Collect line set ucs table */
|
||||||
if (line_codepage == font_codepage &&
|
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 */
|
/* For DBCS and POOR fonts force direct to font */
|
||||||
used_dtf = 1;
|
used_dtf = 1;
|
||||||
@ -228,7 +233,7 @@ void luni_send(wchar_t * widebuf, int len)
|
|||||||
{
|
{
|
||||||
static char *linebuffer = 0;
|
static char *linebuffer = 0;
|
||||||
static int linesize = 0;
|
static int linesize = 0;
|
||||||
int ratio = (utf) ? 3 : 1;
|
int ratio = (in_utf)?3:1;
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
@ -238,7 +243,7 @@ void luni_send(wchar_t * widebuf, int len)
|
|||||||
linesize = len * ratio * 2;
|
linesize = len * ratio * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utf) {
|
if (in_utf) {
|
||||||
/* UTF is a simple algorithm */
|
/* UTF is a simple algorithm */
|
||||||
for (p = linebuffer, i = 0; i < len; i++) {
|
for (p = linebuffer, i = 0; i < len; i++) {
|
||||||
wchar_t ch = widebuf[i];
|
wchar_t ch = widebuf[i];
|
||||||
|
6
window.c
6
window.c
@ -2881,7 +2881,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
#ifdef SHOW_TOASCII_RESULT
|
#ifdef SHOW_TOASCII_RESULT
|
||||||
if (r == 1 && !key_down) {
|
if (r == 1 && !key_down) {
|
||||||
if (alt_sum) {
|
if (alt_sum) {
|
||||||
if (utf || dbcs_screenfont)
|
if (in_utf || dbcs_screenfont)
|
||||||
debug((", (U+%04x)", alt_sum));
|
debug((", (U+%04x)", alt_sum));
|
||||||
else
|
else
|
||||||
debug((", LCH(%d)", alt_sum));
|
debug((", LCH(%d)", alt_sum));
|
||||||
@ -2925,7 +2925,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
|
|
||||||
if (!key_down) {
|
if (!key_down) {
|
||||||
if (alt_sum) {
|
if (alt_sum) {
|
||||||
if (utf || dbcs_screenfont) {
|
if (in_utf || dbcs_screenfont) {
|
||||||
keybuf = alt_sum;
|
keybuf = alt_sum;
|
||||||
luni_send(&keybuf, 1);
|
luni_send(&keybuf, 1);
|
||||||
} else {
|
} else {
|
||||||
@ -2952,7 +2952,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
if (!left_alt)
|
if (!left_alt)
|
||||||
keys[0] = 0;
|
keys[0] = 0;
|
||||||
/* If we will be using alt_sum fix the 256s */
|
/* 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;
|
keys[0] = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user