我只是想了解在X11中如何调用事件处理程序的技巧。 所以在Linux / X11中,如果一个窗口注册ASyncMode中的事件(即PointerMotion),X11如何调用该进程的事件处理程序?
他们是否使用某种形式的中断?
令我感到困惑的是,我的流程没有任何东西可以轮询X11事件。我甚至附加了gdb并验证了在X11库可能启动的场景下没有运行的线程。因此,我必须知道这实际上是如何运作的。
溢出我!
答案 0 :(得分:1)
X11客户端使用tcp或unix套接字连接(通常为端口6000 + tcp的显示编号和'/tmp/.X11-unix/X'+域套接字的显示编号)进行通信。协议本身是双工的,您可以随时发送请求,并收到回复,错误和事件。事件和错误总是32字节长的数据包。
有关如何处理来自X服务器的传入数据的各种策略。使用xlib,在每个已知产生响应的请求之后,都会阻塞read()调用以读取那么多数据。在“闲置”期间,您需要read all events and errors from connection manually:
while(1) {
XNextEvent(d, &e);
/* draw or redraw the window */
if(e.type==Expose) {
XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
}
/* exit on key press */
if(e.type==KeyPress)
break;
// Handle Windows Close Event
if(e.type==ClientMessage)
break;
}
在此代码段XNextEvent
中,从套接字消耗32个字节的数据到e
结构,while
循环中的代码根据应用程序逻辑和事件类型以及有效负载调度它。
在其他一些库中,如node-x11(注意:我是作者)事件循环隐藏在框架async io模型后面并隐式发生。
var x11 = require('x11');
var PointerMotion = x11.eventMask.PointerMotion;
x11.createClient(function(err, display) {
var X = display.client;
var root = display.screen[0].root;
var wid = X.AllocID();
X.CreateWindow(
wid, root,
0, 0, 400, 300,
0, 0, 0, 0,
{
eventMask: PointerMotion
}
);
X.MapWindow(wid);
X.on('event', function(ev) {
if (ev.name == 'PointerMotion')
{
console.log('Mouse motion!', [ev.x, ev.y]);
}
});
X.on('error', function(e) {
console.log(e);
});
});