修改putty源代码,解决某些字体无法选择gb2312字符集问题 | 您所在的位置:网站首页 › putty源代码 › 修改putty源代码,解决某些字体无法选择gb2312字符集问题 |
putty在选择字体的时候,对应字体不一定下面会有gb2312的编码,
这样在复制,输入的时候就会乱码。如果碰到喜欢的字体又不能选择gb2312的字体就不好用了。我喜欢Envy Code R ,瘦瘦高高的字体 :) 方法,下载putty源码,修改实现两个功能:“汉字输入”和“剪贴板操作”。putty的代码会有选择地转换,不一定会将服务器发来的gbk码很好的发送到windows前端。 前提是服务器设置gbk编码。以freebsd为例 setenv LANG zh_CN.GBK setenv LC_ALL zh_CN.GBK在putty源码中找到winstuff.h,加入,让vc2005能编译通过,这是一个与编码无关的修改 #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, "", (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,可以下载试试看。
|
CopyRight 2018-2019 实验室设备网 版权所有 |