#define _POSIX_C_SOURCE 200112L #include #include "xdg-shell-client-protocol.h" #include #include #include #include struct wl_display *display = NULL; struct wl_registry *registry = NULL; struct wl_compositor *compositor = NULL; struct xdg_wm_base *wm_base = NULL; struct wl_surface *surface = NULL; struct xdg_surface *xdg_surface = NULL; struct xdg_toplevel *xdg_toplevel = NULL; static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); } static const struct xdg_wm_base_listener wm_base_listener = { .ping = xdg_wm_base_ping, }; static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { xdg_surface_ack_configure(xdg_surface, serial); } static const struct xdg_surface_listener xdg_surface_listener = { .configure = xdg_surface_configure, }; static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states) { /* just exist */ } static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) { printf("close requested\n"); exit(0); } static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = xdg_toplevel_configure, .close = xdg_toplevel_close, }; static void registry_handle_global(void *data, struct wl_registry *reg, uint32_t id, const char *interface, uint32_t version) { if (strcmp(interface, wl_compositor_interface.name) == 0) { compositor = wl_registry_bind(reg, id, &wl_compositor_interface, 4); } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { wm_base = wl_registry_bind(reg, id, &xdg_wm_base_interface, 1); xdg_wm_base_add_listener(wm_base, &wm_base_listener, NULL); } } static void registry_handle_global_remove(void *data, struct wl_registry *reg, uint32_t id) { /* ignore */ } static const struct wl_registry_listener registry_listener = { .global = registry_handle_global, .global_remove = registry_handle_global_remove, }; int main(void) { display = wl_display_connect(NULL); if (!display) { fprintf(stderr, "can't connect\n"); return 1; } registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, NULL); wl_display_roundtrip(display); if (!compositor || !wm_base) { fprintf(stderr, "missing compositor or xdg_wm_base\n"); return 1; } surface = wl_compositor_create_surface(compositor); xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, surface); xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); xdg_toplevel_set_title(xdg_toplevel, "wayland window"); wl_surface_commit(surface); wl_display_roundtrip(display); printf("window open, running...\n"); while (wl_display_dispatch(display) != -1) { /* events handled by callbacks */ } wl_display_disconnect(display); return 0; }