上一篇文章里介绍的linux下vnc使用剪贴板的方法可能比较复杂,也不见得很有效。比如对于//uxxxx这类的字符串,就无能为力。下面再介绍另外一种方法。相对来说比较简单,通常也更加有效。
我们知道,rfb协议里剪贴板的格式是:
typedef struct _rfbClientCutTextMsg {
CARD8 type; /* always rfbClientCutText */
CARD8 pad1;
CARD16 pad2;
CARD32 length;
/* followed by char text[length] */
} rfbClientCutTextMsg;
typedef struct _rfbServerCutTextMsg {
CARD8 type; /* always rfbServerCutText */
CARD8 pad1;
CARD16 pad2;
CARD32 length;
/* followed by char text[length] */
} rfbServerCutTextMsg;
如果text里面的内容不是ascii,而是中文,那问题就解决了。对于rfbClientCutTextMsg消息,text里面放入中文应该没问题。对于rfbServerCutTextMsg消息,由于前面已经介绍过,发的只能是ascii内容。我的做法是不要使用cutbuffer了,转而使用selections。这里介绍一个工具xsel,使用它就以设置和获取服务器剪贴板的内容。
第一,在服务器中去掉传送和设置cutbuffer的功能。我使用的是tightvnc代码,主要修改的地方是在xserever/hw/vnc/init.c中的rfbRootPropertyChange函数,在这里去提服务器传送cutbuffer的功能。然后在rfbserver.c中去掉设置cutbuffer的代码。
第二,在rfbserver.c中,当收到rfbClientCutText消息时,使用echo str |xsel -ib,设置clipboard的内容。
第三,当剪贴板内容有变化时,使用xsel -ob,拿到内容,然后发送到客户端。
大体上就这三步,怎样在vnc服务器中知道剪贴板的数据有变化呢?我的做法是使用autocutsel,当clipboard里的内容有变化,就设置 cutbuffer的内容,一旦cutbuffer有变化,就在调用到rfbRootPropertyChange函数。我们就可以在里面使用xsel -ob获取剪贴板的内容了。
通过以上的改造,现在我的vnc系统中已经可以正常使用剪贴板了。ascii字符、多字节字符都可以。当然了,只限字符串。