如何调用事件处理程序(X11)

时间:2014-04-16 16:52:21

标签: linux events event-handling x11

我只是想了解在X11中如何调用事件处理程序的技巧。 所以在Linux / X11中,如果一个窗口注册ASyncMode中的事件(即PointerMotion),X11如何调用该进程的事件处理程序?

他们是否使用某种形式的中断?

令我感到困惑的是,我的流程没有任何东西可以轮询X11事件。我甚至附加了gdb并验证了在X11库可能启动的场景下没有运行的线程。因此,我必须知道这实际上是如何运作的。

溢出我!

1 个答案:

答案 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);
    });
});