介绍
Wayland是linux新一代的窗口系统服务器,将来肯定会替代X Server,学习一下还是很有必要的。如果有Win32 GUI编程经验的话学习Wayland会相对容易点。Win32 GUI编程中有两个主要函数WinMain和WndProc,前者负责消息分发,后者负责具体窗口的消息处理。在Wayland中也是使用这种方式,只不过Wayland使用Listener处理消息而不是WndProc。
Listener
常用的Listener有:
wl_pointer_listener:处理鼠标消息。
wl_keyboard_listener:处理键盘消息。
frame_listener:处理窗口绘制消息。
Wayland全局对象
几乎所有的Wayland API都需要Wayland全局对象作为参数。
Wayland全局对象:
wl_display:表示与服务器的连接。
wl_registry:全局对象注册表,全局对象需要通过它获取。
wl_compositor:窗口合成器,也是服务器。
wl_shm:内存管理器,与窗口合成器共享内存用。
wl_shell:支持窗口操作功能。
wl_seat:输入设备管理器。
wl_pointer:代表鼠标设备。
wl_keyboard:代表键盘设备。
wl_registry
Wayland没有提供Get函数来获取以上全局对象,只能通过wl_registry获取全局对象。
首先创建wl_registry_listener对象:
void registry_global(LPVOID data, HREGISTRY registry, uint32_t id, const char *interface, uint32_t version)
{
if (strcmp(interface, "wl_compositor") == 0)
{
wlGetRegistry()->s_compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
}
else if (strcmp(interface, "wl_shell") == 0)
{
wlGetRegistry()->s_shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
}
else if (strcmp(interface, "wl_shm") == 0)
{
wlGetRegistry()->s_shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(wlGetRegistry()->s_shm, &shm_listenter, NULL);
}
else if (strcmp(interface, "wl_seat") == 0)
{
wlGetRegistry()->s_seat = wl_registry_bind(registry, id, &wl_seat_interface, 1);
wlGetRegistry()->s_pointer = wl_seat_get_pointer(wlGetRegistry()->s_seat);
wlGetRegistry()->s_keyboard = wl_seat_get_keyboard(wlGetRegistry()->s_seat);
}
}
static void registry_global_remove(LPVOID data, HREGISTRY registry, uint32_t name)
{
}
static struct wl_registry_listener registry_listener =
{
.global = registry_global,
.global_remove = registry_global_remove
};
int wlInit()
{
wlGetRegistry()->s_display = wl_display_connect(NULL);
HREGISTRY registry = wl_display_get_registry(wlGetRegistry()->s_display);
/* wayland的API是异步的,需要给registry设置回掉函数 */
wl_registry_add_listener(registry, ®istry_listener, NULL);
/* 处理消息 */
wl_display_roundtrip(wlGetRegistry()->s_display);
wl_display_roundtrip(wlGetRegistry()->s_display);
wl_display_get_fd(wlGetRegistry()->s_display);
/* 处理鼠标消息 */
wl_pointer_add_listener(wlGetPointer(), &pointer_listener, NULL);
wl_keyboard_add_listener(wlGetKeyboard(), &keyboard_listener, NULL);
}