#include "wlstate.h" #include "utils.h" #include "xdg-shell.h" #include #include #include #define WAYC_VERSION 1 static void wayc_xdg_wm_base_pong(void *data, struct xdg_wm_base *wm_base, u32 serial) { (void)data; xdg_wm_base_pong(wm_base, serial); } static struct xdg_wm_base_listener WAYC_XDG_WM_BASE_LISTENER = { wayc_xdg_wm_base_pong, }; static void wayc_registry_add(void *data, struct wl_registry *registry, u32 name, const char *interface, u32 version) { (void)version; wayc_notnull(data); wayc_notnull(registry); wayc_notnull(interface); struct wlstate_s *state = (struct wlstate_s *)data; if (!strcmp(interface, wl_compositor_interface.name)) { wl_compositor_t compositor = (wl_compositor_t)wl_registry_bind( registry, name, &wl_compositor_interface, WAYC_VERSION); wayc_notnull(compositor); state->compositor = compositor; } if (!strcmp(interface, xdg_wm_base_interface.name)) { xdg_wm_base_t wm_base = (xdg_wm_base_t)wl_registry_bind( registry, name, &xdg_wm_base_interface, WAYC_VERSION); wayc_notnull(wm_base); state->wm_base = wm_base; xdg_wm_base_add_listener(wm_base, &WAYC_XDG_WM_BASE_LISTENER, state); } } static void wayc_registry_remove(void *data, struct wl_registry *registry, u32 name) { wayc_notnull(data); wayc_notnull(registry); wayc_panic("Registry global removed: name=%u", name); } static struct wl_registry_listener WAYC_REGISTRY_LISTENER = { wayc_registry_add, wayc_registry_remove, }; bool wayc_wlstate_init(struct wlstate_s *state) { wayc_notnull(state); memset(state, 0, sizeof(*state)); wl_display_t display = wl_display_connect(NULL); if (display == NULL) return false; i32 eventfd = wl_display_get_fd(display); if (eventfd == -1) { wl_display_disconnect(display); return false; } wl_registry_t registry = wl_display_get_registry(display); if (registry == NULL) { wl_display_disconnect(display); return false; } wl_registry_add_listener(registry, &WAYC_REGISTRY_LISTENER, state); wl_display_roundtrip(display); state->display = display; state->registry = registry; state->eventfd = eventfd; return true; } void wayc_wlstate_deinit(struct wlstate_s *state) { wayc_notnull(state); if (state->display == nullptr) return; wl_display_disconnect(state->display); state->display = nullptr; state->registry = nullptr; state->compositor = nullptr; state->wm_base = nullptr; state->eventfd = -1; } void wayc_wlstate_update(struct wlstate_s *state) { wayc_notnull(state); struct pollfd pfd = { state->eventfd, POLLIN, 0, }; i32 rc = poll(&pfd, 1, 0); if (rc == -1) wayc_panic("Failed to poll Wayland eventfd"); if (!(pfd.revents & POLLIN)) return; rc = wl_display_dispatch(state->display); if (rc == -1) wayc_panic("Failed to dispatch Wayland events"); }