#include "window.h" #include #include "events.h" #include "utils.h" #include "vec.h" #include "wlstate.h" #include "xdg-shell.h" static void wayc_surface_configure(void* data, struct xdg_surface* xdg_surface, u32 serial) { struct window_s* window = (struct window_s*)data; wayc_notnull(window); xdg_surface_ack_configure(xdg_surface, serial); wl_surface_commit(window->surface); } static void wayc_toplevel_configure(void* data, struct xdg_toplevel* xdg_toplevel, i32 width, i32 height, struct wl_array* states) { (void)xdg_toplevel; (void)states; struct window_s* window = (struct window_s*)data; wayc_notnull(window); struct eventloop_s* loop = window->loop; wayc_notnull(loop); struct event_s event = WAYC_EVENT_RESIZE(window, width, height); wayc_vec_push(&loop->events, &event); } static void wayc_toplevel_close(void* data, struct xdg_toplevel* xdg_toplevel) { (void)xdg_toplevel; struct window_s* window = (struct window_s*)data; wayc_notnull(window); struct eventloop_s* loop = window->loop; wayc_notnull(loop); struct event_s event = WAYC_EVENT_CLOSE(window); wayc_vec_push(&loop->events, &event); } static struct xdg_surface_listener WAYC_SURFACE_LISTENER = { wayc_surface_configure, }; static struct xdg_toplevel_listener WAYC_TOPLEVEL_LISTENER = { wayc_toplevel_configure, wayc_toplevel_close, nullptr, nullptr}; enum window_error_e wayc_window_init(struct window_s* window, const char* name, struct eventloop_s* loop) { wayc_notnull(window); wayc_notnull(loop); memset(window, 0, sizeof(*window)); struct wlstate_s* wlstate = &loop->state; wl_surface_t surface = wl_compositor_create_surface(wlstate->compositor); if (surface == nullptr) return WINDOW_ERROR_WL_SURFACE_CREATION; xdg_surface_t xdg_surface = xdg_wm_base_get_xdg_surface(wlstate->wm_base, surface); if (xdg_surface == nullptr) { wl_surface_destroy(surface); return WINDOW_ERROR_XDG_SURFACE_CREATION; } xdg_surface_add_listener(xdg_surface, &WAYC_SURFACE_LISTENER, window); xdg_toplevel_t xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); if (xdg_toplevel == nullptr) { xdg_surface_destroy(xdg_surface); wl_surface_destroy(surface); return WINDOW_ERROR_XDG_TOPLEVEL_CREATION; } xdg_toplevel_add_listener(xdg_toplevel, &WAYC_TOPLEVEL_LISTENER, window); xdg_toplevel_set_title(xdg_toplevel, name); wl_surface_commit(surface); window->surface = surface; window->xdg_surface = xdg_surface; window->xdg_toplevel = xdg_toplevel; window->loop = loop; wl_display_roundtrip(wlstate->display); return WINDOW_ERROR_NONE; } void wayc_window_deinit(struct window_s* window) { wayc_notnull(window); if (window->surface == nullptr || window->xdg_surface == nullptr || window->xdg_toplevel == nullptr) return; xdg_toplevel_destroy(window->xdg_toplevel); xdg_surface_destroy(window->xdg_surface); wl_surface_destroy(window->surface); window->xdg_toplevel = nullptr; window->xdg_surface = nullptr; window->surface = nullptr; } void wayc_window_redraw(struct window_s* window, struct eventloop_s* loop) { wayc_notnull(window); wayc_notnull(loop); struct event_s event = WAYC_EVENT_FRAME(window); wayc_vec_push(&loop->events, &event); }