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

3

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

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

令我困惑的是,我的进程没有任何东西正在轮询X11事件。 我甚至附加了gdb并验证了在场景下没有运行由X11库启动的线程。所以我对这实际上是如何工作存在一些知识上的空缺。

向我倾述吧!

1个回答

3
X11客户端使用tcp或unix套接字连接(通常是tcp的端口6000+显示器号码,域套接字的'/tmp/.X11-unix/X'+显示器号码)进行通信。协议本身是双工的,您可以随时发送请求并接收回复、错误和事件。事件和错误始终是32字节长的数据包。
有各种处理来自X服务器的传入数据的策略。使用xlib,在已知会产生响应的每个请求之后,都会调用阻塞read()函数来读取相应数量的数据。在“空闲”时间,您需要手动读取 来自连接的所有事件和错误
   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(注意:我是作者),事件循环被隐藏在框架异步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);
    });
});

1
谢谢Andrey,那么你的意思是说没有疯狂的机制将程序执行转移到事件处理程序吗?也就是说,我的应用程序(即XtMainLoop)必须有一些轮询X11事件的东西? - rbhkamal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接