修改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, "<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,可以下载试试看。 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值