我们操作的界面是客户端,鼠标点击、窗口移动、窗口大小、键盘输入都是由客户端捕获,然后通过协议发送给服务端。这个协议Wayland由提供默认的,如果默认的满足不了需求,可以自定义协议。协议格式为XML,使用wayland-scanner程序转换为代码。
之前的文章中使用的是wayland默认的,本文我们使用wayland提供的扩展协议,stable版。
窗口部分是一样的。
我们使用新协议的对象
struct xdg_wm_base *xdg_shell;
struct xdg_surface *shell_surface;
struct xdg_toplevel *toplevel;
创建新对象
shell_surface = xdg_wm_base_get_xdg_surface(xdg_shell, surface);
if (shell_surface == NULL)
{
fprintf(stderr, "Can't create shell surface\n");
exit(1);
}else{
fprintf(stderr, "Created shell surface\n");
}
toplevel = xdg_surface_get_toplevel(shell_surface);
xdg_surface_add_listener(shell_surface,&surface_listener,NULL);
需要监听新的注册事件
static void
global_registry_handler(void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
{
if (strcmp(interface, "wl_compositor") == 0)
{
BIND_WL_REG(registry, compositor, id, &wl_compositor_interface, 1);
}else if (strcmp(interface, xdg_wm_base_interface.name) == 0){
BIND_WL_REG(registry, xdg_shell, id, &xdg_wm_base_interface, 1);
}else if (strcmp(interface, "wl_shm") == 0){
BIND_WL_REG(registry, shm, id, &wl_shm_interface, 1);
wl_shm_add_listener(shm, &shm_listener, NULL);
}
}
窗口监听和处理
static void handle_configure(void *data, struct xdg_surface *surface, uint32_t serial) {
xdg_surface_ack_configure(surface, serial);
}
static const struct xdg_surface_listener surface_listener = {
.configure = handle_configure
};
编译
协议以xml格式提供,我们在使用时要把它生成为代码。
WAYLAND_FLAGS = $(shell pkg-config wayland-client --cflags --libs)
WAYLAND_PROTOCOLS_DIR = $(shell pkg-config wayland-protocols --variable=pkgdatadir)
WAYLAND_SCANNER = $(shell pkg-config --variable=wayland_scanner wayland-scanner)
XDG_SHELL_PROTOCOL = $(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml
HEADERS=xdg-shell-client-protocol.h
SOURCES=xdg-shell-protocol.c
all: $(HEADERS) $(SOURCES)
gcc -o shell_stable shell_stable.c $(SOURCES) -I. -lwayland-client -lwayland-egl -lEGL -lGL
xdg-shell-client-protocol.h:
$(WAYLAND_SCANNER) client-header $(XDG_SHELL_PROTOCOL) xdg-shell-client-protocol.h
xdg-shell-protocol.c:
$(WAYLAND_SCANNER) private-code $(XDG_SHELL_PROTOCOL) xdg-shell-protocol.c
clean:
rm -rf shell_stable $(HEADERS) $(SOURCES)
显示效果和之前的窗口一样。
EGL版本只是替换了窗口显示部分,其他的代码一样。
完整代码在Wayland_Frashman中的10.shell_stable、10.shell_stable_EGL下。