修改putty源代码,解决字体无gb2312问题

来源:互联网 发布:先知电子狗升级软件 编辑:程序博客网 时间:2024/05/29 19:20

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, "<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,交给MultiByteToWideCharmybuff[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 );//再还给buffor (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,可以下载试试看。 



原创粉丝点击