4.2 Wayland book Incorporating an event loop
Incorporating an event loop
libwayland provides its own event loop implementation for Wayland servers to take advantage of, but the maintainers have acknowledged this as a design overstep. For clients, there is no such equivalent. However, the Wayland server event loop is useful enough, even if it’s out-of-scope.
libwayland 实现了自己的 event loop, 并将它提供给 Wayland server 使用。而对于 client, 则没有提供这样的机制。虽然开发维护者也认为这在架构的整体设计上是越界的。但是, Wayland server 的 event loop 真的很有用~
Wayland server event loop
Each wl_display
created by libwayland-server has a corresponding
wl_event_loop
, which you may obtain a reference to with
wl_display_get_event_loop
. If you’re writing a new Wayland compositor, you
will likely want to use this as your only event loop. You can add file
descriptors to it with wl_event_loop_add_fd
, and timers with
wl_event_loop_add_timer
. It also handles signals via
wl_event_loop_add_signal
, which can be pretty convenient.
libwayland-server 创建的每个 wl_display
都有一个对应的 wl_event_loop
,你可以使用
wl_display_get_event_loop
获得对 loop 的引用。 如果你正在编写一个新的 Wayland compositor,
可以通过这个接口获得唯一的 event loop。 (有了 loop 以后)可以使用 wl_event_loop_add_fd
为 loop 增加对(对应的)fd 的监听,使用 wl_event_loop_add_timer
添加定时器。甚至可以通过
wl_event_loop_add_signal
添加需要处理的信号,总之,非常方便。
With the event loop configured to your liking to monitor all of the events your
compositor has to respond to, you can process events and dispatch Wayland
clients all at once by calling wl_display_run
, which will process the event
loop and block until the display terminates (via wl_display_terminate
). Most
Wayland compositors which were built from the ground-up with Wayland in mind (as
opposed to being ported from X11) use this approach.
你可以随心所欲的配置自己的 event-loop,监听自己的 compositor 必须响应的所有 event。
可以通过调用 wl_display_run
一次性完成处理 event,派发消息至 Wayland client。
run 函数会一直不知疲倦的循环工作,直至死亡(wl_display_terminate
)。大多数从头开始构建的
Wayland compositor(而不是从 X11 移植)都是使用这种方法实现的(消息处理循环机制)。
However, it’s also possible to take the wheel and incorporate the Wayland
display into your own event loop. wl_display
uses the event loop internally
for processing clients, and you can choose to either monitor the Wayland event
loop on your own, dispatching it as necessary, or you can disregard it
entirely and manually process client updates. If you wish to allow the Wayland
event loop to look after itself and treat it as subservient to your own event
loop, you can use wl_event_loop_get_fd
to obtain a poll-able file
descriptor, then call wl_event_loop_dispatch
to process events when activity
occurs on that file descriptor. You will also need to call
wl_display_flush_clients
when you have data which needs writing to clients.
当然,也是可以将 Wayland display 和循环放到你自己的 event loop里面。wl_display
在内部使用
event loop 来处理 client 的 request,你可以选择自己监控 Wayland event loop,必要时调度它;或者完全忽视它,
自己手动处理 client 的 request 完成更新。如果你希望 Wayland event loop 自行处理相关任务,并将他变为你自己
event loop 中的一部分,可以使用 wl_event_loop_get_fd
来获取一个(基于 Wayland event loop) poll-able 的 fd,
之后此 fd 发生活动时,调用 wl_event_loop_dispatch
处理事件。当需要将数据写入 client 时,还需要调用 wl_display_flush_clients
。
Wayland client event loop
libwayland-client, on the other hand, does not have its own event loop. However, since there is only generally one file descriptor, it’s easier to manage without. If Wayland events are the only sort which your program expects, then this simple loop will suffice:
另一边,libwayland-client 没有自己的 event loop。然而,由于通常只有一个 fd(也就是和 sever 交互的 socket), 不使用 event loop 明显更容易管理。如果Wayland 的 event 事件是 client 所期望的唯一消息来源,那么调用如下的简单的循环就足够了:
while (wl_display_dispatch(display) != -1) {
/* This space deliberately left blank */
}
However, if you have a more sophisticated application, you can build your own
event loop in any manner you please, and obtain the Wayland display’s file
descriptor with wl_display_get_fd
. Upon POLLIN
events, call
wl_display_dispatch
to process incoming events. To flush outgoing requests,
call wl_display_flush
.
但是,如果你有更复杂的应用程序,你完全可以按照自己喜欢的任何方式构建自己的 event loop,
并使用 wl_display_get_fd
获取 Wayland display 的 fd。在 POLLIN 事件上,调用 wl_display_dispatch
来处理传入的 event。要刷新传出去的 request,请调用 wl_display_flush
。
Almost there!
At this point you have all of the context you need to set up a Wayland display and process events and requests. The only remaining step is to allocate objects to chat about with the other side of your connection. For this, we use the registry. At the end of the next chapter, we will have our first useful Wayland client!
就目前为止,你已拥有设置 Wayland display 和处理 event 和 request 所需的所有环境相关的方法函数。 剩下的唯一步骤是分配 object 以与另一边进行连接,交互。我们使用 registry 实现上述需求。 在下一章的结尾,我们将拥有第一个可用的 Wayland 客户端!
原文链接:https://wayland-book.com/