putty在选择字体的时候,对应字体不一定下面会有gb2312的编码,
这样在复制,输入的时候就会乱码。如果碰到喜欢的字体又不能选择gb2312的字体就不好用了。我喜欢Envy Code R ,瘦瘦高高的字体 :)
方法,下载putty源码,修改实现两个功能:“汉字输入”和“剪贴板操作”。putty的代码会有选择地转换,不一定会将服务器发来的gbk码很好的发送到windows前端。
前提是服务器设置gbk编码。以freebsd为例
setenv LANG zh_CN.GBK
setenv LC_ALL zh_CN.GBK
#define SECURITY_WIN32
找到winucs.c文件,在wc_to_mb函数变量声明过后,尽量靠前,加入一句:
codepage=936;
强制让前端数据视为gbk转换为multiByte,这样就实现输入中文的功能了
找到terminal.c文件,将clipme函数修改为:
static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
{
clip_workbuf buf;
int old_top_x;
int attr;
//zeeeitch...
unsigned char mybuff[5120];
int mypos=0;
wchar_t cbuf[16], *p;
WCHAR *wbuff;//
int len;//
//zeeeitch
buf.buflen = 5120;
buf.bufpos = 0;
buf.textptr = buf.textbuf = snewn(buf.buflen, wchar_t);
buf.attrptr = buf.attrbuf = snewn(buf.buflen, int);
old_top_x = top.x; /* needed for rect==1 */
while (poslt(top, bottom)) {
int nl = FALSE;
termline *ldata = lineptr(top.y);
pos nlpos;
/*
* nlpos will point at the maximum position on this line we
* should copy up to. So we start it at the end of the
* line...
*/
nlpos.y = top.y;
nlpos.x = term->cols;
/*
* ... move it backwards if there's unused space at the end
* of the line (and also set `nl' if this is the case,
* because in normal selection mode this means we need a
* newline at the end)...
*/
if (!(ldata->lattr & LATTR_WRAPPED)) {
while (nlpos.x &&
IS_SPACE_CHR(ldata->chars[nlpos.x - 1].chr) &&
!ldata->chars[nlpos.x - 1].cc_next &&
poslt(top, nlpos))
decpos(nlpos);
if (poslt(nlpos, bottom))
nl = TRUE;
} else if (ldata->lattr & LATTR_WRAPPED2) {
/* Ignore the last char on the line in a WRAPPED2 line. */
decpos(nlpos);
}
/*
* ... and then clip it to the terminal x coordinate if
* we're doing rectangular selection. (In this case we
* still did the above, so that copying e.g. the right-hand
* column from a table doesn't fill with spaces on the
* right.)
*/
if (rect) {
if (nlpos.x > bottom.x)
nlpos.x = bottom.x;
nl = (top.y < bottom.y);
}
while (poslt(top, bottom) && poslt(top, nlpos)) {
#if 0
char cbuf[16], *p;
sprintf(cbuf, "<U+%04x>", (ldata[top.x] & 0xFFFF));
#else
//zeeeitch
//wchar_t cbuf[16], *p;
int c;
int x = top.x;
if (ldata->chars[x].chr == UCSWIDE) {
top.x++;
continue;
}
while (1) {
int uc = ldata->chars[x].chr;
attr = ldata->chars[x].attr;
switch (uc & CSET_MASK) {
case CSET_LINEDRW:
if (!term->cfg.rawcnp) {
uc = term->ucsdata->unitab_xterm[uc & 0xFF];
break;
}
case CSET_ASCII:
uc = term->ucsdata->unitab_line[uc & 0xFF];
break;
case CSET_SCOACS:
uc = term->ucsdata->unitab_scoacs[uc&0xFF];
break;
}
switch (uc & CSET_MASK) {
case CSET_ACP:
uc = term->ucsdata->unitab_font[uc & 0xFF];
break;
case CSET_OEMCP:
uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
break;
}
c = (uc & ~CSET_MASK);
#ifdef PLATFORM_IS_UTF16
if (uc > 0x10000 && uc < 0x110000) {
cbuf[0] = 0xD800 | ((uc - 0x10000) >> 10);
cbuf[1] = 0xDC00 | ((uc - 0x10000) & 0x3FF);
cbuf[2] = 0;
} else
#endif
{
cbuf[0] = uc;
cbuf[1] = 0;
}
if (DIRECT_FONT(uc)) {
if (c >= ' ' && c != 0x7F) {
char buf[4];
WCHAR wbuf[4];
int rv;
if (is_dbcs_leadbyte(term->ucsdata->font_codepage, (BYTE) c)) {
buf[0] = c;
buf[1] = (char) (0xFF & ldata->chars[top.x + 1].chr);
rv = mb_to_wc(term->ucsdata->font_codepage, 0, buf, 2, wbuf, 4);
top.x++;
} else {
buf[0] = c;
rv = mb_to_wc(term->ucsdata->font_codepage, 0, buf, 1, wbuf, 4);
}
if (rv > 0) {
memcpy(cbuf, wbuf, rv * sizeof(wchar_t));
cbuf[rv] = 0;
}
}
}
#endif
//zeeeitch,源代码不识别中文widechar,我们把所有内容搜集起来,
for (p = cbuf; *p; p++)
mybuff[mypos++] = *p;
//clip_addchar(&buf, *p, attr);
if (ldata->chars[x].cc_next)
x += ldata->chars[x].cc_next;
else
break;
}
top.x++;
}
if (nl) {
int i;
//zeeeitch我们把所有内容搜集起来,
for (i = 0; i < sel_nl_sz; i++)
mybuff[mypos++] = sel_nl[i];
//clip_addchar(&buf, sel_nl[i], 0);
}
top.y++;
top.x = rect ? old_top_x : 0;
unlineptr(ldata);
}
#if SELECTION_NUL_TERMINATED
//zeeeitch
//clip_addchar(&buf, 0, 0);
#endif
//zeeeitch....把搜集到的字符全部当作widechar,交给MultiByteToWideChar
mybuff[mypos++] = 0;
len = MultiByteToWideChar(936, 0, (LPCSTR)mybuff, -1, NULL,0);
wbuff = snewn(len+1,wchar_t);
memset(wbuff, 0, len * 2 + 2);
//得到widechar格式的wbuff
len=MultiByteToWideChar(936, 0, (LPCSTR)mybuff, -1, wbuff, len );
//再还给buf
for (p = wbuff; *p; p++)
clip_addchar(&buf, *p, 0);
clip_addchar(&buf, 0, 0);
//zeeeitch 后面代码一样
/* Finally, transfer all that to the clipboard. */
write_clip(term->frontend, buf.textbuf, buf.attrbuf, buf.bufpos, desel);
sfree(buf.textbuf);
sfree(buf.attrbuf);
}
其中注释zeeeitch的代码就是修改的地方。这样就实现了鼠标选择复制的功能。
编译后的putty.exe,可以下载试试看。