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 的处理更为合理。但是对于游戏就有点麻烦,我们无法简单的知道用户是否一直按着一个键不放。
这个问题我很早就遇到了,记得当初不知道 google 了些什么关键词就找到了相关资料。大约记得 X 协议中是可以关闭 X 的自动重复的。今天想把这部分代码补上,又怎么也 google 不到了 :( (该死的 google.cn 就是不给我记录搜索历史!)
最后终于还是从文档中翻出来了:
我们可以用 XAutoRepeatOn / XAutoRepeatOff 开关 autorepeat 的设置。但是简单调用这 API 似乎并不是一个好的方案。因为这个设置居然是影响全局的,甚至在窗口关闭程序退出后,设置都不会还原。
还好在 man XAutoRepeatOff 的时候看到了相关的另一个 api: XQueryKeymap :) 。用这个就够了,它可以查询键盘的真实状态。我们只用在消息循环中响应 KeyRelease 的时候,调用 XQueryKeymap 检查一下对应的按键是否真的被按下就 OK 了。
ps. 有没有 X Window 编程的高手啊,一个人搞这些东西总是很郁闷。
Comments
Posted by: 幻の上帝 | (17) December 26, 2014 09:13 AM
Posted by: komac | (16) June 27, 2008 08:11 PM
Posted by: wolke | (15) August 29, 2007 02:51 PM
Posted by: phoolimin | (14) July 24, 2007 05:30 PM
Posted by: Cloud | (13) July 23, 2007 09:11 PM
Posted by: phoolimin | (12) July 23, 2007 08:24 PM
Posted by: 热血江湖私服 | (11) July 21, 2007 07:09 PM
Posted by: Cloud | (10) July 20, 2007 05:11 PM
Posted by: lokki | (9) July 20, 2007 04:51 PM
Posted by: ywchen2000 | (8) July 20, 2007 12:01 PM
Posted by: pencilend | (7) July 19, 2007 04:33 AM
Posted by: yayv | (6) July 18, 2007 09:57 AM
Posted by: Felix Wong | (5) July 17, 2007 10:41 PM
Posted by: liaoliao | (4) July 17, 2007 12:33 PM
Posted by: Nick | (3) July 17, 2007 12:11 PM
Posted by: ywchen2000 | (2) July 17, 2007 10:34 AM
Posted by: sheep | (1) July 17, 2007 10:29 AM