Main

May 20, 2009

X Window 的 Resize 处理

程序员在陌生领域工作时,都想寻求范例。看起来,我们都很依赖 Meme Machine 。

可惜的是, X Window 领域的直接针对 XLib 编程的范例太少。偶尔碰到点问题都让人很痛苦。只有反复研究文档了。

我的程序在处理 Resize 消息时老是不正确,仔细阅读文档后,发现是以前理解有问题。

起先,我为窗口消息注册了 ResizeRedirectMask ,然后在消息循环中就可以得到一个 ResizeRequest 消息。然后,我处理这个消息,但结果总是不对。

今天研究了一下,发现 ResizeRedirectMask 会导致 no further processing is performed 。也就是说,通知你 resize 请求后,X 系统就不管你了。至于还差什么事情要做(比如改变客户区大小),我也不知道该怎么做才完全正确。(如果在 Windows 里,应该是调用 DefaultWindowProc )

不过解决方法其实也很简单,不用注册 ResizeRedirectMask ,而注册 StructureNotifyMask 。在窗口改变的时候, X 会发一个 ConfigureNotify 。因为这个只是 Notify ,所以 X 会把所有它应该做的事情做的周全。

March 25, 2009

libstdc++ 卸载问题

今天,同事花了一下午时间,终于查到了 周末我碰到的问题 的根本原因。

是因为,GLU 是用 C++ 实现的,而导致 libstdc++.so 会跟随它卸载,而 libstdc++.so 本身有一个 bug ,导致程序崩溃。

当然,显露这个 bug 还有一个前提,我的程序是纯 C 写的,完全没有用到 libstdc++ 。

有兴趣的同学可以查看这个帖子:http://unix.derkeiler.com/pdf/Mailing-Lists/FreeBSD/stable/2006-05/msg00719.pdf

March 22, 2009

Freebsd 下 glx 的一点问题

最近特别忙,经常连续工作超过 10 小时。所以情绪也有点不稳定,有的应该在半小时处理完的问题,会拖上几个小时。比如昨天就碰到一个。

由于底层代码由我一个人做了大规模重构(在不改变中间层的基础上做的),大约修改了一万多行代码,上百个 C 文件,其中重写了数千行。这样的变动实在太大,以至于出了罕见的问题后,很让人头痛。新的代码在 Windows 和 Ubuntu 上都一切正常,惟独在 Freebsd 上,程序退出的时候会引起一个 core dump 。

我对 gdb 调试器的高阶运用显然经验不足,加上这几年写代码也不怎么调试。(IMHO ,与其增加调试能力,不如提高设计能力和编写高质量代码的能力;让 bug 不容易出现,或是把 bug 限制在很小的范围,比解决 bug 更重要)在尝试过初步的调试后,我还是使用大脑做静态分析。确定问题出在 so 文件的显式关闭 (主动调用 dlclose)的环节。

March 28, 2008

X 下的鼠标滚轮消息的处理

今天午休的时候,抽了几分钟解决我们的游戏 client engine 在 X Window 下无法处理鼠标滚轮事件的问题。

可能这年头直接写代码处理 XEvent 的程序员不多,我 google 了一下,没有找到详细的文档。不过我想这不会是大问题,没有资料就直接看 .h 文件好了。

打开 Xlib.h 通读了一遍,发现没有什么 event 结构是跟滚轮有关的。又绕回自己的程序试了一下,原来,X 下没有特别为鼠标滚轮做单独的消息。(Windows 下则有对应的 WM_MOUSEWHEEL

取而代之的是,鼠标的前滚和后滚被映射到了鼠标的第 4 和第 5 个按键的事件上了。(这个其实可以在 X 的配置文件里配置,相关资料很容易 google 到。)那么,支持鼠标滚轮事件的处理,只需要在 ButtonPress 做处理即可。

January 15, 2008

随便写写

最近把 Asimov 的《基地》系列中,正传三本看完了。算是补课也好,没有辜负我专门去邮购这些书。买书真是件奢侈的事儿,以前是因为书贵,现在是因为时间和精力。

初翻此书,没有我当年期待的那么好。在那个没有网络的年代,读到这些科幻名著是件很难的事情。Asimov 也被神化了,这里面老爸对此亦有贡献。在我还刚认识几个字,是本书就想拿来读的年龄段,他就向我兴致勃勃的介绍 Verne ,Asimov 。弄的我小时候以为这两个就是世界上最伟大的作家。

不过,把这几本读完后,也不算太糟糕。或许有些翻译质量的不适应,故事还是高潮迭起的。毕竟是数十年前的科幻了,幻想中的科学总有那么一点怪怪的。当我在第一本中看到“电算板”时,心里只有一个念头,这不就是笔记本电脑么?功能好象还抵不上我现在用的 palm 手机 :)

抛开想象中的落伍科技之外(YY 方面自然比不过如今流行的玄幻小说),情节方面的构思还是颇为引人入胜的。即使许多情节的设计以今天的眼光看来不算新鲜。但我们应该考虑到这么多年来,总有新的作者不断仿效加工,才使得我们有了审美疲劳。

总之,向没看过的此书的科幻迷推荐一下。

July 17, 2007

X Window 编程的两个小问题

X Window 其实比 Widnows 要好理解的多,设计的也更为合理一些。但是无奈,资料太少、中文的就更少了。搜来搜去就那么几篇,书也没看见几本 :( 所以在 X 下做开发,对于我,比在 Windows 下麻烦了许多。

最近一段时间遇到了许多问题,解决了两个,记录在这里:

截获窗口关闭的消息

Windows 下很简单,WM_CLOSE 消息是也。btw, 一般人也不会理会这个消息大多数情况其实是由 explorer 转发过来的,而不是 GUI 系统直接发进你的窗口 。在你的窗口进程陷入死循环,无法处理窗口消息时,标题栏上的关闭叉叉按纽依然可以工作。

X Window 下,我想当然的从文档中找到一个叫作 DestroyNotiify 的消息,但是写到消息循环中怎么都触发不了。在 X 下,用鼠标点击窗口右上那个叉叉,得到的反应和 Windows 下点了死掉的窗口的关闭一样。会弹出一个对话框,OK 后强行杀掉。

后来才知道:应该先用 XInternAtom 拿到一个叫做 WM_DELETE_WINDOW 的 atom ,用 XSetWMProtocols 设置到窗口上。然后在消息循环中 case ClientMessage 方可查询到这个 atom ,从而得之窗口将被关掉的消息。

X Window 下的键盘自动连发跟 Windows 下行为不一致

当你按住一个键,X Window 和 Windows 都会模拟出一串的连续键击。但 X 下的行为跟 Windows 不同的是:X 会自动生成 key up 的消息 (X 下叫作 KeyRelease )。

在 Windows 下,你只会在真正松开键时得到唯一次 WM_KEYUP 。而在 X 下你会得到一系列的 KeyPress / KeyRelease 对,严格的按照一个 KeyPress 消息、接一个 KeyRelease 消息的来。大多数情况下,X 的处理更为合理。但是对于游戏就有点麻烦,我们无法简单的知道用户是否一直按着一个键不放。