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

时间:2023-01-07 12:02:59

I'm simply trying to understand the technique of how event handlers are called in X11. So in Linux/X11, if a window registers for events in ASyncMode (i.e. PointerMotion), how does X11 call the event handler for that process?

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

Are they using some form of interrupts?

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

What baffles me is that my process has nothing that is polling for X11 events. I even attached gdb and verified that there are no threads running under the scene that could've been started by X11 libs. So there must a gap in my knowledge as to how this actually works.

令我感到困惑的是,我的流程没有任何东西可以轮询X11事件。我甚至附加了gdb并验证了在X11库已经启动的场景下没有运行的线程。因此,我的知识必须存在差距才能实现。

overflow me!

1 个解决方案

#1


1  

X11 clients use tcp or unix socket connection (usually port 6000 + display number for tcp and '/tmp/.X11-unix/X' + display number for domain socket) for communication. The protocol itself is duplex, you can send requests at any time and you receive replies, errors and events. Events and errors are always 32 bytes long packets.

X11客户端使用tcp或unix套接字连接(通常为端口6000 + tcp的显示编号和'/tmp/.X11-unix/X'+域套接字的显示编号)进行通信。协议本身是双工的,您可以随时发送请求,并收到回复,错误和事件。事件和错误总是32字节长的数据包。

There are various strategies on how to process incoming data from X server. With xlib, after each request known to produce response there is blocking read() call to read that much data. During 'idle' time you are expected to read all events and errors from connection manually:

有关如何处理来自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;
   }

In this snippet XNextEvent consumes 32 bytes of data from socket into e structure, and code in while loop dispatches it depending on app logic and event type and payload.

在这个片段中,XNextEvent将32个字节的数据从socket转换为e结构,而while循环中的代码根据应用程序逻辑和事件类型以及有效负载调度它。

In some other libraries like node-x11 (note: I'm author) event loop is hidden behind framework async io model and happens implicitly.

在其他一些库中,比如node-x11(注意:我是作者),事件循环隐藏在框架异步模型之后,并且隐式发生。

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


1  

X11 clients use tcp or unix socket connection (usually port 6000 + display number for tcp and '/tmp/.X11-unix/X' + display number for domain socket) for communication. The protocol itself is duplex, you can send requests at any time and you receive replies, errors and events. Events and errors are always 32 bytes long packets.

X11客户端使用tcp或unix套接字连接(通常为端口6000 + tcp的显示编号和'/tmp/.X11-unix/X'+域套接字的显示编号)进行通信。协议本身是双工的,您可以随时发送请求,并收到回复,错误和事件。事件和错误总是32字节长的数据包。

There are various strategies on how to process incoming data from X server. With xlib, after each request known to produce response there is blocking read() call to read that much data. During 'idle' time you are expected to read all events and errors from connection manually:

有关如何处理来自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;
   }

In this snippet XNextEvent consumes 32 bytes of data from socket into e structure, and code in while loop dispatches it depending on app logic and event type and payload.

在这个片段中,XNextEvent将32个字节的数据从socket转换为e结构,而while循环中的代码根据应用程序逻辑和事件类型以及有效负载调度它。

In some other libraries like node-x11 (note: I'm author) event loop is hidden behind framework async io model and happens implicitly.

在其他一些库中,比如node-x11(注意:我是作者),事件循环隐藏在框架异步模型之后,并且隐式发生。

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