Code a World
Seamless Window for RDP
1. Intro
Seamless Window (无缝窗口) 用在远程桌面上非常实用。
Windows自带的远程桌面不支持无缝窗口,所以估计大家也没怎么用过,平常远程连接都是直接登录到远程机器上操作完了再返回,也没什么不方便的。但是设想一下,你实在想在Linux里用qq客户端或者无奈必须用IE浏览器,装个虚拟机或者远程登录到另外一台windows机器临时使用都可以,但是像qq这种长期使用的软件如果要不停的切换的远程机器上非常不爽,因为远程桌面大多是全屏的,不全屏也可以啊,窗口里面套窗口更不爽。这时候就可以上无缝窗口了,把远程的软件像本地软件一样显示在本地机器上,就跟在本地运行一样,就方便多了。效果图如右图:Linux的软件和Windows的软件同时供你选择,多么和谐啊。
2. Theory
和谐的只是表面现象,他们必须运行在各自的系统上才行(这里自动排除wine的情况...)。 虽然运行在各自的系统上,但是我们可以把它们显示在一起。原理也很简单,对微软的RDP协议来说,必须有服务端(远程机器),客户端(本地机器),服务端负责不停的给客户端发送远程机器的桌面显示(RDP协议传的只有一张图片,就是桌面截图),客户端向服务端发送用户的操作(鼠标、键盘操作什么的)。如果我们能让服务端除了发送整张桌面截图以外,还能把远程机器上所有打开窗口的坐标和位置信息发送过来,客户端再根据这些信息在整张图片上做裁剪就可以了~ 基于RDP的无缝窗口就实现了...
3. Software
3.1 Windows To Windows
Martin Wickett 在codeproject 上发布了一个小程序,拓展了windows自带的远程工具, 在windows与windows之间实现了无缝窗口,使用很简单,下载,在要远程的机器上安装server, 在本地安装client,然后和平常一样打开远程连接,配置一下连接选项就可以了使用了。 这个程序没什么实用价值,只是示例,还不能实用化,有源代码,有需要可以继续开发。我觉得Windows和Windows之间使用无缝窗口好像没什么必要,没想到什么应用场景。
真想在Windows对Windows上使用的,可以使用rdesktop的windows版本,原理同下面要讲的一样,但是移植rdesktop到windows要花费一番功夫,虽然已经有人做过[7],但是他移植的这个版本不包含seamlessrdp 的功能,所以还要自己修改添加。 有需要的可以自己移植看看。
3.2 Linux To Windows
Linux下的rdesktop实现了客户端的功能, windows的服务端实在Martin Wickett发布的那个服务上开发而来。rdesktop的seamless实现是由cendio [3] 实现的, 在其主页上有详细的使用说明, 这里就不多讲。
这个默认的实现每次打开一个远程的程序都会新建一个连接,像Windows Server还没问题,XP的话只能建一个远程连接, 新建一个上一个就自动断开了,很不友好,也很浪费带宽和资源,所以有人给rdesktop打了connection sharing 补丁[4],其主页也有详细的操作说明,虽然是针对是针对老版本的补丁, 经过我的测试再最新版也是能用的,只是打补丁的时候有几个地方要手动调整一下。
其中由于服务端是windows程序,cendio 又把原始的 visual studio solution 删除了,改用在MinGW交叉编译,但是由于MinGW一个已知的bug [5],无法编译。 我刚开始不知道是MinGW的问题,尝试交叉编译失败后,我又手动给改成了visual studio solution 了... 后来联系了开发作者,他把他们内部fixed的MinGW给了我, 其实只是缺少几个头文件和lib,我也自己尝试过把Windows SDK里面对应的文件直接拷贝到Linux里面,但是Windows SDK里面的头文件很多居然是大写命名的...
好了,废话不多讲, 如果你想尝试一下的话, 我已经把针对rdesktop最新版进行了升级过的patch,server端的visual studio版本,MinGW缺少的头文件和lib, 还有我预编译过的版本都上传到了我的github,你可以下载下来按照[4]或者README中的步骤进行操作。
3.3 Linux/Windows To Linux
因为Xwindow协议的Client/Server模式与Windows不一样,远程Linux机器上的X实际上是客户端,而显示的机器才是服务器,所有X协议原生支持无缝窗口。你要用Windows连接Linux,只需要在Windows上装个X server就行了,这样Linux端的程序就可以直接显示在Windows端,运行在Linux端。Linux连Linux,两边都不需要任何设置。有关Xwindow的简要概述请参考王垠这篇博客------理解 Xwindow,不再赘述。
4. Seamless window in VirtualBox
我本来是要去研究VirtualBox里面的seamless mode实现, 结果误打误撞碰上了seamlessrdp, 就花时间看了下。有关VirtualBox虚拟机里面的seamless mode模式,等研究懂了改天再写...
Reference
[1] Seamless Window 原理 http://blog.csdn.net/generalking/article/details/6163613
[2] Extending Microsoft's Terminal Services Client To Provide Seamless Windows
[4] Rdesktop Seamless Connection Sharing
[5] http://sourceforge.net/tracker
[6] 王垠---理解 Xwindow
MoSync Intro
声明:本文完全是按照自己理解所写,不对内容的正确性和准确性负责,请以MoSync的官方文档和代码为准。
MoSync 是一个开源的移动应用的跨平台开发框架。
1. Intro
当前市面上流行的主要的系统有 Android (包括API3-12), Symbian 60 (v2, v3, v5) , IOS, Win Mobile (5, 6, 6pro), Meego... 如果你想只写一套代码能在上面所有平台都能运行,现在来说只能用Java, 而且Android,Meego还是得单独维护, MoSync 就是这样的一个平台, 你只要写一个MoSync Project, 然后看到右侧的图片了么,选择你的手机型号,双击,大功告成~,你想换一个型号么,选择,双击,OK,还能批量选择生成的。使用Android的手机,它就会生成apk程序给你;使用Symbian的手机,它就会生成sis程序给你;Win Mobile? 自然是cab程序了。
如果你开发过手机应用,几乎为每个型号都维护一个版本,每个型号都有单独的补丁,看到这里你一定激动万分。
2. MoSync
MoSync 的设计很宏大,它实际上是一个引擎, 目标是接受各种语言的Project(现在只支持C/C++), 输出满足任意型号手机(现在已支持流行的大部分手机)的程序。 实现这个目标理论上只有一种可能----虚拟机。MoSync的核心其实就是个虚拟机,是一个基于寄存器的虚拟机(jvm 是基于stack 的,Android自带的davik也是基于寄存器的),有自己的指令集, 支持自己的bytecode。这个虚拟机设计的非常小巧,针对移动平台优化,不用预装在手机上,会和你的程序打包在一起, 然后你的程序在手机运行的时候,其实是先启动的这个虚拟机。速度上起码要比jvm快。
MoSync 的代价是抛弃各个平台的SDK,程序必须按照它自己的API写, 意味着你必须花时间学习它的API,不过这点代价对程序员来说应该没什么问题, 而且其官方文档和示例也很全面。它还定制了Eclipse来作为专用的IDE。
3. MoSync Building Process
MoSync定制了GCC作为其编译器,它给GCC增加了一个自己的后端(back-end) 负责把程序编译成其自己的中间语言 MoSync IL, 然后用其链接器Pipe-tool把用到的libs一起链接成二进制程序(相当于java 的 class 文件),最后根据你选的手机型号来打包,把你的程序和对应手机平台的虚拟机打包在一起,生成对应的安装包(apk, sis, cab),就可以安装到手机了。
用MoSync为Mac开发程序要多走一步程序,因为这时Packaging打包生成的不是安装包,而是一个完整的XCode Project, 你需要用XCode打开这个project, 然后就像你以前开发Mac程序一样编译,安装就行了。
由此可见,MoSync真是煞费苦心,不惜从中间语言(IL) 逆向重新生成源文件来支持Mac,封闭系统害死人啊。
4. MoSync IL
每一个虚拟机都有一套自己的中间语言,包括特定的指令集,语法等等。 一般都有两种等价形式-----汇编形式和二进制形式, 只是可读和不可读的区别。
MoSync 的汇编IL包含了详细的stabs格式的元信息(由gcc -stabs 生成), 通过这些元信息,必要的时候完全可以将这些汇编语言转换回高级语言形式,自然也可以生成源代码,上面说的Mac的方式就是这样操作的。 二进制的bytecode 去掉了这些元信息。
MoSync IL的共有128个寄存器,常用的有32个[1][2]。指令集也非常简单,没有浮点指令,所有浮点运算都转化为调用相应的函数完成。
5. MoSync Pipe-Tool
Pipe-Tool 是一个复杂的工具,包含了资源编译器, 链接器,还有代码优化的功能[3]。从汇编语言生成源代码的活也是它干的,已经实现可以从汇编语言生成C++或者Java的源代码,无论你源码原来是用什么写的,当然目前你只能用c/c++来写... 下面是从其文档上摘录的几点特别的地方:
6. MoSync Runtime Core
Runtime 是MoSync 的核心, 就是虚拟机的部分。虚拟机最基本的功能就是一行行的解释执行bytecode,或者JIT的形式将bytecode转换成目标机器native的代码,然后再执行。 这两种形式MoSync都实现了,叫VM Core 和 Recompiler Core。 官方还有一种Core叫Generated Core, 说的就是为mac支持的那种重新生成源代码的形式, 这里就不叫它Core了... 我觉的它不算Runtime的部分。
第一个问题就是要保证MoSync 这个虚拟机本身能在所有手机平台高效运行,这就没什么好办法了,只能每个手机型号维护一个版本,尽量为每个型号进行优化了(这就是牺牲一人,幸福大家的精神啊)... 不过可想而知,为JVM实现的版本,就是JVM虚拟机上再运行MoSync虚拟机,效率肯定不会高。VM Core 最终是要抛弃的,Pipe-Toole 将为只能运行Java程序的手机直接生成Java bytecode, 省得再加一层虚拟机。Recompiler core (其实就是JIT,不知为什么非得再起个名字,弄得我查了半天与JIT的区别) 目前只实现了 win mobile 5 以上 和 symbian s60 以上的版本,程序再启动时先将代码转换成目标机native的代码,这样会有一点延时启动的效果,但是转换后的代码效率就要看转换引擎了。
关于Android版本的Recompiler Core正在开发当中, 目前采用的还是VM Core。因为涉及到Android 本身应用就不是Native的形式,所以Recompiler Core实现上有些复杂, 这点可以参考[4].
7. Benchmark
目前无论官方还是第三方都找不到任何MoSync 相关的Benchmark,无法给出准确的数据说明采用MoSync的实现对效率到底有多少影响。我自己做了一个关于win mobile 5 上Native程序与MoSync Recompiler Core 之间简单的Benchmark, 方法是用Zlib对1M随机文本进行内存压缩。 首先要移植Zlib 到MoSync,其实很简单,MoSync的标准C库采用 newlib, 所以直接把代码组织成 MoSync Project, 然后编译就行了(MoSync IDE 默认的是不是采用newlib, 需要设置一下[5])。 Native版本的Win Mobile Zlib 直接从网上下载的 zilbCE。使用同样的版本1.2.3,因为我能找到的最新 zlibCE就是1.2.3了... 采用内存压缩1M 随机文本也是无奈之举, 因为用MoSync 标准C库的 fopen 实现有问题, 无法读取手机上的文件, 而手机又很老了,能跑起来的程序最大只能处理1M文本了。 不过结果还可以还是有可比性的,因为每次都是随机生成的文本, 分别取10次运行的平均结果, MoSync程序用了8000多毫秒, Native的程序只用了不到4000毫秒, 还是有点差距的。
8. Conclusion
MoSync还在开发当中,能做到现在的程度已经很不错了,为了跨平台的可靠性, 为了不让程序员们不停的进行各种版本的测试和调试,MoSync自己本身就必须做更多的手机平台测试,而且要保证一致性。
最重要的是它的用户体验非常好,你只需要维护一套代码,然后去选择手机就可以了,应该没有比这更简单的策略了吧。所以还是很值得期待的。
更多详细内容请参考官方文档。
Reference
[1] http://www.mosync.com/content/how-many-number-registers-used-mosync-il
[2] http://www.mosync.com/files/MoSync%20IL%20register%20set.pdf
[3] http://www.mosync.com/documentation/manualpages/toolchain
[4] Generally questions affect to the MoSync Build Process http://www.mosync.com/node/6690
[5] http://www.mosync.com/content/sdl-stl-standard-cc-libs
Synergy on Android
If you don't know Synergy, please go to http://synergy-foss.org to learn what is it.
Our projet is on sourceforge site: http://sourceforge.net/projects/synergyandroid/
This is the introduction for the latest deveping version, you can get the source code by
#svn co https://synergyandroid.svn.sourceforge.net/svnroot/synergyandroid/branches/pengliang synergyandroid
You can also get the trunk source tree
#svn co https://synergyandroid.svn.sourceforge.net/svnroot/synergyandroid/trunk synergyandroid
But I suggest you checkout my branch, beause running the trunk tree is a little compicated,
and my branch will be merged into trunk soon.
ps: if you found a syntax/spelling error in this article, please let me know~
Introduction
-----------------------------------------------------------------------------------------------
SynergyAndroid is a port of the synergy client to the Android platform.
See http://synergy-foss.org for detail. Currently in the planning stage.
New developers are very welcome to join in.
Pre-requirements
------------------------------------------------------------------------------------------------------
Now, we don't depend on /de/uinput module, instead with /dev/input/event0,
but still need root permission to access /dev/input/event0.
So you just need changing the permission of /dev/input/event0.
#adb shell chmod 666 /dev/input/event0
Attention: It was just tested in emulator, maybe not working on real device.
If there is only event0 file in /dev/input/ folder on your device,
and no other event* files exist, it should be work. So check it:
#adb shell ls /dev/input/
Building the project
------------------------------------------------------------------------------------------------------
SynergyAndroid use the jni to access the /dev/uinput module, so you must
compile the jni source by NDK firstly. And then you can directly build and debug the project in eclipse.
#./build_jni.sh <NDK Base>
then just build the whole project in eclipse.
Running
----------------------------------------------------------------------------------------------------
Reminder: you should build the jni source first and #adb shell chmod 666 /dev/input/event0
Then you can:
1. just run the project in eclipse or
2. install the PROJECT_PATH/bin/Synergy.apk to emulator/device.
#adb install PROJECT_PATH/bin/Synergy.apk
Problems
------------------------------------------------------------------------------------------------------
1. can't see mouse cursor on the screen.
building android custom kernel for emulator
1. Clone the android kernel source from android.git.kernel.org
#git clone git://android.git.kernel.org/kernel/common.git
2. Check out the emulator branch
#git checkout -t origin/android-goldfish-2.6.29 -b goldfish
3. Generate the kernel configuration for emulator
#make ARCH=arm goldfish_defconfig
or get a config copy from a exist emulator rom.
#adb pull /proc/config.gz
4. Edit the .config file, set the custom option, like enable uinput module
CONFIG_INPUT_UINPUT=y
5. Compile the kernel using cross toolchain (you can get prebuilt cross toolchain from android source repo or just
#git clone git://android.git.kernel.org/platform/prebuilt.git all platform cross chain are there.)
#make ARCH=arm CROSS_COMPILE=prebuilt/YOUR_PLATFORM/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
6. Now, the kernel built is in the arch/arm/boot/ folder. You can start the emulator with this kernel
#emulator -avd YOUR_AVD -kernel ANDROID_KERNEL_PATH/arch/arm/boot/zImage
Hello World
#include <stdio.h> int main() { printf("Hello World!\n"); return 0; }