diff options
author | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2024-02-07 22:49:00 +0100 |
---|---|---|
committer | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2024-02-07 22:49:00 +0100 |
commit | 35a70d71f62e41d78d68247075ce174f2b6d997a (patch) | |
tree | c9af8d8c44256abfc100c396182fd27f1f4c7263 /src/window.c |
inital commit -- THE CUBES SPIN
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
Diffstat (limited to 'src/window.c')
-rw-r--r-- | src/window.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/window.c b/src/window.c new file mode 100644 index 0000000..63aefec --- /dev/null +++ b/src/window.c @@ -0,0 +1,148 @@ +#include "render/window.h" + +#include <stdlib.h> +#include <string.h> + +static void global(void *data, struct wl_registry *reg, + uint32_t name, const char *interface, uint32_t version) { + struct window *win = data; + if (strcmp(wl_compositor_interface.name, interface) == 0) { + win->comp = wl_registry_bind(reg, name, &wl_compositor_interface, version); + } else if (strcmp(xdg_wm_base_interface.name, interface) == 0) { + win->xdg_base = wl_registry_bind(reg, name, &xdg_wm_base_interface, version); + } else if (strcmp(zxdg_decoration_manager_v1_interface.name, interface) == 0) { + win->deco_manager = wl_registry_bind(reg, name, + &zxdg_decoration_manager_v1_interface, version); + } +} + +static void global_remove(void *data, struct wl_registry *reg, uint32_t name) {} + +static struct wl_registry_listener reg_list = { + .global = global, + .global_remove = global_remove +}; + +static void ping(void *data, struct xdg_wm_base *base, uint32_t serial) { + xdg_wm_base_pong(base, serial); +} + +static struct xdg_wm_base_listener xdg_list = { + .ping = ping +}; + +void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { + xdg_surface_ack_configure(xdg_surface, serial); +} + +static struct xdg_surface_listener xdg_surface_list = { + .configure = xdg_surface_configure, +}; + +void toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, + int32_t width, int32_t height, struct wl_array *states) { + struct window *win = data; + win->resize = true; + win->width = width != 0 ? width : 1920; + win->height = height != 0 ? height : 1080; +} + +void toplevel_close(void *data, struct xdg_toplevel *toplevel) { + struct window *win = data; + win->should_close = true; +} + +static struct xdg_toplevel_listener toplevel_listener = { + .configure = toplevel_configure, + .close = toplevel_close, +}; + +struct window *window_init(const char *title) { + struct window *win = calloc(1, sizeof(*win)); + + win->title = title; + win->should_close = false; + + win->dpy = wl_display_connect(NULL); + if (!win->dpy) + goto err; + + win->reg = wl_display_get_registry(win->dpy); + if (!win->reg) + goto err; + + wl_registry_add_listener(win->reg, ®_list, win); + wl_display_roundtrip(win->dpy); + + if (!win->comp || !win->dpy || !win->deco_manager || !win->xdg_base) + goto err; + + xdg_wm_base_add_listener(win->xdg_base, &xdg_list, win); + + win->surface = wl_compositor_create_surface(win->comp); + if (!win->surface) + goto err; + + win->xdg_surface = xdg_wm_base_get_xdg_surface(win->xdg_base, win->surface); + xdg_surface_add_listener(win->xdg_surface, &xdg_surface_list, win); + + win->xdg_toplevel = xdg_surface_get_toplevel(win->xdg_surface); + xdg_toplevel_set_title(win->xdg_toplevel, title); + xdg_toplevel_set_min_size(win->xdg_toplevel, 640, 480); + xdg_toplevel_add_listener(win->xdg_toplevel, &toplevel_listener, win); + + win->deco = zxdg_decoration_manager_v1_get_toplevel_decoration(win->deco_manager, win->xdg_toplevel); + zxdg_toplevel_decoration_v1_set_mode(win->deco, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + + wl_surface_commit(win->surface); + while (!win->resize) + wl_display_roundtrip(win->dpy); + win->resize = false; + + return win; + +err: + window_destroy(win); + return NULL; +} + +void window_destroy(struct window *win) { + if (!win) + return; + + if (win->deco) + zxdg_toplevel_decoration_v1_destroy(win->deco); + if (win->deco_manager) + zxdg_decoration_manager_v1_destroy(win->deco_manager); + if (win->xdg_toplevel) + xdg_toplevel_destroy(win->xdg_toplevel); + if (win->xdg_surface) + xdg_surface_destroy(win->xdg_surface); + if (win->xdg_base) + xdg_wm_base_destroy(win->xdg_base); + if (win->comp) + wl_compositor_destroy(win->comp); + if (win->reg) + wl_registry_destroy(win->reg); + if (win->dpy) + wl_display_disconnect(win->dpy); + free(win); +} + +VkSurfaceKHR window_create_vk_surface(VkInstance instance, struct window *win) { + if (!win) + return VK_NULL_HANDLE; + + VkWaylandSurfaceCreateInfoKHR create_info = { + .sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, + .display = win->dpy, + .surface = win->surface + }; + + VkSurfaceKHR surface; + VkResult res = vkCreateWaylandSurfaceKHR(instance, &create_info, NULL, &surface); + if (res != VK_SUCCESS) + return VK_NULL_HANDLE; + + return surface; +} |