diff options
author | Mikhail Burakov <mburakov@mailbox.org> | 2023-04-02 12:09:20 +0200 |
---|---|---|
committer | Mikhail Burakov <mburakov@mailbox.org> | 2023-04-07 13:47:39 +0200 |
commit | eecbacdc1ab1b29fee71f3a689e01cabe12b3730 (patch) | |
tree | 0b6c924678a31ed2f46061f7767a99bb40b57737 | |
parent | 972e03b4a09b790d9ed9c8102cc897a75c9bb751 (diff) |
Major rewrite of window to support input events
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | main.c | 22 | ||||
-rw-r--r-- | window.c | 513 | ||||
-rw-r--r-- | window.h | 10 |
4 files changed, 365 insertions, 182 deletions
@@ -2,4 +2,6 @@ .clang-format compile_commands.json compile_flags.txt +linux-dmabuf-unstable-v1.h receiver +xdg-shell.h @@ -31,11 +31,31 @@ static volatile sig_atomic_t g_signal; static void OnSignal(int status) { g_signal = status; } +static void OnWindowClose(void* user) { + (void)user; + g_signal = SIGINT; +} + +static void OnWindowKey(void* user, unsigned key, bool pressed) { + // TODO +} + +static void WindowDtor(struct Window** window) { + if (!*window) return; + WindowDestroy(*window); + *window = NULL; +} + int main(int argc, char* argv[]) { (void)argc; (void)argv; - struct AUTO(Window)* window = WindowCreate(); + static const struct WindowEventHandlers window_event_handlers = { + .OnClose = OnWindowClose, + .OnKey = OnWindowKey, + }; + struct Window __attribute__((cleanup(WindowDtor)))* window = + WindowCreate(&window_event_handlers, NULL); if (!window) { LOG("Failed to create window"); return EXIT_FAILURE; @@ -18,7 +18,6 @@ #include "window.h" #include <errno.h> -#include <signal.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -30,108 +29,236 @@ #include "util.h" #include "xdg-shell.h" +// TODO(mburakov): This would look like shit until Wayland guys finally fix +// https://gitlab.freedesktop.org/wayland/wayland/-/issues/160 + struct Window { + const struct WindowEventHandlers* event_handlers; + void* user; + struct wl_display* wl_display; struct wl_surface* wl_surface; + struct wl_pointer* wl_pointer; + struct wl_keyboard* wl_keyboard; struct xdg_wm_base* xdg_wm_base; struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1; + struct xdg_surface* xdg_surface; struct xdg_toplevel* xdg_toplevel; struct wl_buffer** wl_buffers; }; -static void wl_registryDestroy(struct wl_registry** wl_registry) { - if (!wl_registry || !*wl_registry) return; - wl_registry_destroy(*wl_registry); - *wl_registry = NULL; -} - -static void wl_compositorDestroy(struct wl_compositor** wl_compositor) { - if (!wl_compositor || !*wl_compositor) return; - wl_compositor_destroy(*wl_compositor); - *wl_compositor = NULL; -} - -static void xdg_wm_baseDestroy(struct xdg_wm_base** xdg_wm_base) { - if (!xdg_wm_base || !*xdg_wm_base) return; - xdg_wm_base_destroy(*xdg_wm_base); - *xdg_wm_base = NULL; -} - -static void zwp_linux_buffer_params_v1Destroy( - struct zwp_linux_buffer_params_v1** zwp_linux_buffer_params_v1) { - if (!zwp_linux_buffer_params_v1 || !*zwp_linux_buffer_params_v1) return; - zwp_linux_buffer_params_v1_destroy(*zwp_linux_buffer_params_v1); - *zwp_linux_buffer_params_v1 = NULL; -} - -static void wl_bufferDestroy(struct wl_buffer** wl_buffer) { - if (!wl_buffer || !*wl_buffer) return; - wl_buffer_destroy(*wl_buffer); - *wl_buffer = NULL; -} - -static void OnWmBasePing(void* data, struct xdg_wm_base* xdg_wm_base, - uint32_t serial) { - (void)data; - xdg_wm_base_pong(xdg_wm_base, serial); -} - -static void OnRegistryGlobal(void* data, struct wl_registry* registry, - uint32_t name, const char* interface, - uint32_t version) { +static void OnWlRegistryGlobal(void* data, struct wl_registry* wl_registry, + uint32_t name, const char* interface, + uint32_t version) { struct Window* window = data; if (!strcmp(interface, wl_compositor_interface.name)) { - struct AUTO(wl_compositor)* compositor = - wl_registry_bind(registry, name, &wl_compositor_interface, version); + struct wl_compositor* compositor = + wl_registry_bind(wl_registry, name, &wl_compositor_interface, version); if (!compositor) { - LOG("Failed to bind wayland compositor (%s)", strerror(errno)); + LOG("Failed to bind wl_compositor (%s)", strerror(errno)); return; } window->wl_surface = wl_compositor_create_surface(compositor); - if (!window->wl_surface) { - LOG("Failed to create wayland surface (%s)", strerror(errno)); + if (!window->wl_surface) + LOG("Failed to create wl_surface (%s)", strerror(errno)); + wl_compositor_destroy(compositor); + + } else if (!strcmp(interface, wl_seat_interface.name)) { + struct wl_seat* wl_seat = + wl_registry_bind(wl_registry, name, &wl_seat_interface, version); + if (!wl_seat) { + LOG("Failed to bind wl_seat (%s)", strerror(errno)); return; } + window->wl_pointer = wl_seat_get_pointer(wl_seat); + if (!window->wl_pointer) + LOG("Failed to get wl_pointer (%s)", strerror(errno)); + window->wl_keyboard = wl_seat_get_keyboard(wl_seat); + if (!window->wl_keyboard) + LOG("Failed to get wl_keyboard (%s)", strerror(errno)); + wl_seat_destroy(wl_seat); + } else if (!strcmp(interface, xdg_wm_base_interface.name)) { - struct AUTO(xdg_wm_base)* xdg_wm_base = - wl_registry_bind(registry, name, &xdg_wm_base_interface, version); - if (!xdg_wm_base) { - LOG("Failed to bind wayland xdg_wm_base (%s)", strerror(errno)); - return; - } - static const struct xdg_wm_base_listener wm_base_listener = { - .ping = OnWmBasePing, - }; - if (xdg_wm_base_add_listener(xdg_wm_base, &wm_base_listener, NULL)) { - LOG("Failed to add wayland wm base listener (%s)", strerror(errno)); - return; - } - window->xdg_wm_base = RELEASE(xdg_wm_base); + window->xdg_wm_base = + wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, version); + if (!window->xdg_wm_base) + LOG("Failed to bind xdg_wm_base (%s)", strerror(errno)); + } else if (!strcmp(interface, zwp_linux_dmabuf_v1_interface.name)) { window->zwp_linux_dmabuf_v1 = wl_registry_bind( - registry, name, &zwp_linux_dmabuf_v1_interface, version); + wl_registry, name, &zwp_linux_dmabuf_v1_interface, version); if (!window->zwp_linux_dmabuf_v1) - LOG("Failed to bind wayland zwp_linux_dmabuf_v1 (%s)", strerror(errno)); + LOG("Failed to bind zwp_linux_dmabuf_v1 (%s)", strerror(errno)); } } -static void OnRegistryGlobalRemove(void* data, struct wl_registry* registry, - uint32_t name) { +static void OnWlRegistryGlobalRemove(void* data, struct wl_registry* registry, + uint32_t name) { (void)data; (void)registry; (void)name; } -static void OnSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, - uint32_t serial) { +static void OnWlPointerEnter(void* data, struct wl_pointer* wl_pointer, + uint32_t serial, struct wl_surface* surface, + wl_fixed_t surface_x, wl_fixed_t surface_y) { + (void)data; + (void)wl_pointer; + (void)serial; + (void)surface; + (void)surface_x; + (void)surface_y; +} + +static void OnWlPointerLeave(void* data, struct wl_pointer* wl_pointer, + uint32_t serial, struct wl_surface* surface) { + (void)data; + (void)wl_pointer; + (void)serial; + (void)surface; +} + +static void OnWlPointerMotion(void* data, struct wl_pointer* wl_pointer, + uint32_t time, wl_fixed_t surface_x, + wl_fixed_t surface_y) { + (void)data; + (void)wl_pointer; + (void)time; + (void)surface_x; + (void)surface_y; +} + +static void OnWlPointerButton(void* data, struct wl_pointer* wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, + uint32_t state) { + (void)data; + (void)wl_pointer; + (void)serial; + (void)time; + (void)button; + (void)state; +} + +static void OnWlPointerAxis(void* data, struct wl_pointer* wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) { + (void)data; + (void)wl_pointer; + (void)time; + (void)axis; + (void)value; +} + +static void OnWlPointerFrame(void* data, struct wl_pointer* wl_pointer) { + (void)data; + (void)wl_pointer; +} + +static void OnWlPointerAxisSource(void* data, struct wl_pointer* wl_pointer, + uint32_t axis_source) { + (void)data; + (void)wl_pointer; + (void)axis_source; +} + +static void OnWlPointerAxisStop(void* data, struct wl_pointer* wl_pointer, + uint32_t time, uint32_t axis) { + (void)data; + (void)wl_pointer; + (void)time; + (void)axis; +} + +static void OnWlPointerAxisDiscrete(void* data, struct wl_pointer* wl_pointer, + uint32_t axis, int32_t discrete) { + (void)data; + (void)wl_pointer; + (void)axis; + (void)discrete; +} + +static void OnWlPointerAxisValue120(void* data, struct wl_pointer* wl_pointer, + uint32_t axis, int32_t value120) { + (void)data; + (void)wl_pointer; + (void)axis; + (void)value120; +} + +static void OnWlKeyboardKeymap(void* data, struct wl_keyboard* wl_keyboard, + uint32_t format, int32_t fd, uint32_t size) { + (void)data; + (void)wl_keyboard; + (void)format; + (void)fd; + (void)size; +} + +static void OnWlKeyboardEnter(void* data, struct wl_keyboard* wl_keyboard, + uint32_t serial, struct wl_surface* surface, + struct wl_array* keys) { + (void)data; + (void)wl_keyboard; + (void)serial; + (void)surface; + (void)keys; +} + +static void OnWlKeyboardLeave(void* data, struct wl_keyboard* wl_keyboard, + uint32_t serial, struct wl_surface* surface) { + (void)data; + (void)wl_keyboard; + (void)serial; + (void)surface; +} + +static void OnWlKeyboardKey(void* data, struct wl_keyboard* wl_keyboard, + uint32_t serial, uint32_t time, uint32_t key, + uint32_t state) { + (void)wl_keyboard; + (void)serial; + (void)time; + struct Window* window = data; + window->event_handlers->OnKey(window->user, key, !!state); +} + +static void OnWlKeyboardModifiers(void* data, struct wl_keyboard* wl_keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { + (void)data; + (void)wl_keyboard; + (void)serial; + (void)mods_depressed; + (void)mods_latched; + (void)mods_locked; + (void)group; +} + +static void OnWlKeyboardRepeatInfo(void* data, struct wl_keyboard* wl_keyboard, + int32_t rate, int32_t delay) { + (void)data; + (void)wl_keyboard; + (void)rate; + (void)delay; +} + +static void OnXdgWmBasePing(void* data, struct xdg_wm_base* xdg_wm_base, + uint32_t serial) { + (void)data; + xdg_wm_base_pong(xdg_wm_base, serial); +} + +static void OnXdgSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, + uint32_t serial) { (void)data; xdg_surface_ack_configure(xdg_surface, serial); } -static void OnToplevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, - int32_t width, int32_t height, - struct wl_array* states) { +static void OnXdgToplevelConfigure(void* data, + struct xdg_toplevel* xdg_toplevel, + int32_t width, int32_t height, + struct wl_array* states) { (void)data; (void)xdg_toplevel; (void)width; @@ -139,180 +266,209 @@ static void OnToplevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, (void)states; } -static void OnToplevelClose(void* data, struct xdg_toplevel* xdg_toplevel) { - (void)data; +static void OnXdgToplevelClose(void* data, struct xdg_toplevel* xdg_toplevel) { (void)xdg_toplevel; - raise(SIGINT); + struct Window* window = data; + window->event_handlers->OnClose(window->user); } -static void OnToplevelConfigureBounds(void* data, - struct xdg_toplevel* xdg_toplevel, - int32_t width, int32_t height) { +static void OnXdgToplevelConfigureBounds(void* data, + struct xdg_toplevel* xdg_toplevel, + int32_t width, int32_t height) { (void)data; (void)xdg_toplevel; (void)width; (void)height; } -static void OnToplevelWmCapabilities(void* data, - struct xdg_toplevel* xdg_toplevel, - struct wl_array* capabilities) { +static void OnXdgToplevelWmCapabilities(void* data, + struct xdg_toplevel* xdg_toplevel, + struct wl_array* capabilities) { (void)data; (void)xdg_toplevel; (void)capabilities; } - -struct Window* WindowCreate(void) { - struct AUTO(Window)* window = calloc(1, sizeof(struct Window)); +struct Window* WindowCreate(const struct WindowEventHandlers* event_handlers, + void* user) { + struct Window* window = malloc(sizeof(struct Window)); if (!window) { LOG("Failed to allocate window (%s)", strerror(errno)); return NULL; } + *window = (struct Window){ + .event_handlers = event_handlers, + .user = user, + }; window->wl_display = wl_display_connect(NULL); if (!window->wl_display) { - LOG("Failed to connect wayland display (%s)", strerror(errno)); - return NULL; + LOG("Failed to connect wl_display (%s)", strerror(errno)); + goto rollback_window; } - struct AUTO(wl_registry)* wl_registry = - wl_display_get_registry(window->wl_display); + struct wl_registry* wl_registry = wl_display_get_registry(window->wl_display); if (!wl_registry) { - LOG("Failed to get wayland registry (%s)", strerror(errno)); - return NULL; + LOG("Failed to get wl_registry (%s)", strerror(errno)); + goto rollback_wl_display; } static const struct wl_registry_listener wl_registry_listener = { - .global = OnRegistryGlobal, - .global_remove = OnRegistryGlobalRemove, + .global = OnWlRegistryGlobal, + .global_remove = OnWlRegistryGlobalRemove, }; if (wl_registry_add_listener(wl_registry, &wl_registry_listener, window)) { - LOG("Failed to set wayland registry listener (%s)", strerror(errno)); - return NULL; + LOG("Failed to add wl_registry listener (%s)", strerror(errno)); + goto rollback_wl_registry; } if (wl_display_roundtrip(window->wl_display) == -1) { - LOG("Failed to roundtrip wayland display (%s)", strerror(errno)); - return NULL; + LOG("Failed to roundtrip wl_display (%s)", strerror(errno)); + goto rollback_wl_registry; } - - if (!window->wl_surface || !window->xdg_wm_base || - !window->zwp_linux_dmabuf_v1) { + if (!window->wl_surface || !window->wl_pointer || !window->wl_keyboard || + !window->xdg_wm_base || !window->zwp_linux_dmabuf_v1) { LOG("Some wayland objects are missing"); - return NULL; + goto rollback_globals; + } + + static const struct wl_pointer_listener wl_pointer_listener = { + .enter = OnWlPointerEnter, + .leave = OnWlPointerLeave, + .motion = OnWlPointerMotion, + .button = OnWlPointerButton, + .axis = OnWlPointerAxis, + .frame = OnWlPointerFrame, + .axis_source = OnWlPointerAxisSource, + .axis_stop = OnWlPointerAxisStop, + .axis_discrete = OnWlPointerAxisDiscrete, + .axis_value120 = OnWlPointerAxisValue120, + }; + if (wl_pointer_add_listener(window->wl_pointer, &wl_pointer_listener, + window)) { + LOG("Failed to add wl_pointer listener (%s)", strerror(errno)); + goto rollback_globals; + } + static const struct wl_keyboard_listener wl_keyboard_listener = { + .keymap = OnWlKeyboardKeymap, + .enter = OnWlKeyboardEnter, + .leave = OnWlKeyboardLeave, + .key = OnWlKeyboardKey, + .modifiers = OnWlKeyboardModifiers, + .repeat_info = OnWlKeyboardRepeatInfo, + }; + if (wl_keyboard_add_listener(window->wl_keyboard, &wl_keyboard_listener, + window)) { + LOG("Failed to add wl_keyboard listener (%s)", strerror(errno)); + goto rollback_globals; + } + static const struct xdg_wm_base_listener xdg_wm_base_listener = { + .ping = OnXdgWmBasePing, + }; + if (xdg_wm_base_add_listener(window->xdg_wm_base, &xdg_wm_base_listener, + NULL)) { + LOG("Failed to add xdg_wm_base listener (%s)", strerror(errno)); + goto rollback_globals; } + window->xdg_surface = xdg_wm_base_get_xdg_surface(window->xdg_wm_base, window->wl_surface); if (!window->xdg_surface) { - LOG("Failed to get wayland surface (%s)", strerror(errno)); - return NULL; + LOG("Failed to get xdg_surface (%s)", strerror(errno)); + goto rollback_globals; } static const struct xdg_surface_listener xdg_surface_listener = { - .configure = OnSurfaceConfigure, + .configure = OnXdgSurfaceConfigure, }; if (xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, NULL)) { - LOG("Failed to add wayland surface listener (%s)", strerror(errno)); - return NULL; + LOG("Failed to add xdg_surface listener (%s)", strerror(errno)); + goto rollback_xdg_surface; } + window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface); if (!window->xdg_toplevel) { - LOG("Failed to get wayland toplevel (%s)", strerror(errno)); - return NULL; + LOG("Failed to get xdg_toplevel (%s)", strerror(errno)); + goto rollback_xdg_surface; } static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = OnToplevelConfigure, - .close = OnToplevelClose, - .configure_bounds = OnToplevelConfigureBounds, - .wm_capabilities = OnToplevelWmCapabilities, + .configure = OnXdgToplevelConfigure, + .close = OnXdgToplevelClose, + .configure_bounds = OnXdgToplevelConfigureBounds, + .wm_capabilities = OnXdgToplevelWmCapabilities, }; if (xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, - NULL)) { - LOG("Failed to add wayland toplevel listener (%s)", strerror(errno)); - return NULL; + window)) { + LOG("Failed to add xdg_toplevel listener (%s)", strerror(errno)); + goto rollback_xdg_toplevel; } xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL); wl_surface_commit(window->wl_surface); - return RELEASE(window); + if (wl_display_roundtrip(window->wl_display) == -1) { + LOG("Failed to roundtrip wl_display (%s)", strerror(errno)); + goto rollback_xdg_toplevel; + } + wl_registry_destroy(wl_registry); + return window; + +rollback_xdg_toplevel: + xdg_toplevel_destroy(window->xdg_toplevel); +rollback_xdg_surface: + xdg_surface_destroy(window->xdg_surface); +rollback_globals: + if (window->zwp_linux_dmabuf_v1) + zwp_linux_dmabuf_v1_destroy(window->zwp_linux_dmabuf_v1); + if (window->xdg_wm_base) xdg_wm_base_destroy(window->xdg_wm_base); + if (window->wl_keyboard) wl_keyboard_release(window->wl_keyboard); + if (window->wl_pointer) wl_pointer_release(window->wl_pointer); + if (window->wl_surface) wl_surface_destroy(window->wl_surface); +rollback_wl_registry: + wl_registry_destroy(wl_registry); +rollback_wl_display: + wl_display_disconnect(window->wl_display); +rollback_window: + free(window); + return NULL; } int WindowGetEventsFd(const struct Window* window) { int events_fd = wl_display_get_fd(window->wl_display); - if (events_fd == -1) - LOG("Failed to get wayland display fd (%s)", strerror(errno)); + if (events_fd == -1) LOG("Failed to get wl_display fd (%s)", strerror(errno)); return events_fd; } bool WindowProcessEvents(const struct Window* window) { - if (wl_display_dispatch(window->wl_display) == -1) { - LOG("Failed to dispatch wayland display (%s)", strerror(errno)); - return false; - } - return true; -} - -static void OnZwpLinuxBufferParamsCreated( - void* data, struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, - struct wl_buffer* buffer) { - (void)zwp_linux_buffer_params_v1; - struct wl_buffer** wl_buffer = data; - *wl_buffer = buffer; -} - -static void OnZwpLinuxBufferParamsFailed( - void* data, struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1) { - (void)data; - (void)zwp_linux_buffer_params_v1; + bool result = wl_display_dispatch(window->wl_display) != -1; + if (!result) LOG("Failed to dispatch wl_display (%s)", strerror(errno)); + return result; } static void DestroyBuffers(struct Window* window) { if (!window->wl_buffers) return; for (size_t i = 0; window->wl_buffers[i]; i++) wl_buffer_destroy(window->wl_buffers[i]); - free(RELEASE(window->wl_buffers)); + free(window->wl_buffers); + window->wl_buffers = NULL; } static struct wl_buffer* CreateBuffer(struct Window* window, const struct Frame* frame) { - struct AUTO(zwp_linux_buffer_params_v1)* zwp_linux_buffer_params_v1 = + struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1 = zwp_linux_dmabuf_v1_create_params(window->zwp_linux_dmabuf_v1); if (!zwp_linux_buffer_params_v1) { - LOG("Failed to create wayland dmabuf params (%s)", strerror(errno)); + LOG("Failed to create zwp_linux_buffer_params_v1 (%s)", strerror(errno)); return NULL; } - - struct AUTO(wl_buffer)* wl_buffer = NULL; - static const struct zwp_linux_buffer_params_v1_listener - zwp_linux_buffer_params_v1_listener = { - .created = OnZwpLinuxBufferParamsCreated, - .failed = OnZwpLinuxBufferParamsFailed, - }; - if (zwp_linux_buffer_params_v1_add_listener( - zwp_linux_buffer_params_v1, &zwp_linux_buffer_params_v1_listener, - &wl_buffer)) { - LOG("Failed to add buffer wayland dmabuf params listener (%s)", - strerror(errno)); - return NULL; - } - - for (size_t i = 0; i < frame->nplanes; i++) { + for (uint32_t i = 0; i < frame->nplanes; i++) { zwp_linux_buffer_params_v1_add( - zwp_linux_buffer_params_v1, frame->planes[i].dmabuf_fd, (uint32_t)i, + zwp_linux_buffer_params_v1, frame->planes[i].dmabuf_fd, i, frame->planes[i].offset, frame->planes[i].pitch, frame->planes[i].modifier >> 32, frame->planes[i].modifier & UINT32_MAX); } - zwp_linux_buffer_params_v1_create(zwp_linux_buffer_params_v1, - (int)frame->width, (int)frame->height, - frame->fourcc, 0); - if (wl_display_roundtrip(window->wl_display) == -1) { - LOG("Failed to roundtrip wayland display (%s)", strerror(errno)); - return NULL; - } - if (!wl_buffer) { - LOG("Failed to create wl_buffer"); - return NULL; - } - - return RELEASE(wl_buffer); + struct wl_buffer* wl_buffer = zwp_linux_buffer_params_v1_create_immed( + zwp_linux_buffer_params_v1, (int)frame->width, (int)frame->height, + frame->fourcc, 0); + zwp_linux_buffer_params_v1_destroy(zwp_linux_buffer_params_v1); + if (!wl_buffer) LOG("Failed to create wl_buffer (%s)", strerror(errno)); + return wl_buffer; } bool WindowAssignFrames(struct Window* window, size_t nframes, @@ -339,20 +495,19 @@ bool WindowShowFrame(struct Window* window, size_t index) { wl_surface_damage(window->wl_surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(window->wl_surface); bool result = wl_display_roundtrip(window->wl_display) != -1; - if (!result) LOG("Failed to roundtrip wayland display (%s)", strerror(errno)); + if (!result) LOG("Failed to roundtrip wl_display (%s)", strerror(errno)); return result; } -void WindowDestroy(struct Window** window) { - if (!window || !*window) return; - DestroyBuffers(*window); - if ((*window)->xdg_toplevel) xdg_toplevel_destroy((*window)->xdg_toplevel); - if ((*window)->xdg_surface) xdg_surface_destroy((*window)->xdg_surface); - if ((*window)->zwp_linux_dmabuf_v1) - zwp_linux_dmabuf_v1_destroy((*window)->zwp_linux_dmabuf_v1); - if ((*window)->xdg_wm_base) xdg_wm_base_destroy((*window)->xdg_wm_base); - if ((*window)->wl_surface) wl_surface_destroy((*window)->wl_surface); - if ((*window)->wl_display) wl_display_disconnect((*window)->wl_display); - free(*window); - *window = NULL; +void WindowDestroy(struct Window* window) { + DestroyBuffers(window); + xdg_toplevel_destroy(window->xdg_toplevel); + xdg_surface_destroy(window->xdg_surface); + zwp_linux_dmabuf_v1_destroy(window->zwp_linux_dmabuf_v1); + xdg_wm_base_destroy(window->xdg_wm_base); + wl_keyboard_release(window->wl_keyboard); + wl_pointer_release(window->wl_pointer); + wl_surface_destroy(window->wl_surface); + wl_display_disconnect(window->wl_display); + free(window); } @@ -24,12 +24,18 @@ struct Window; struct Frame; -struct Window* WindowCreate(void); +struct WindowEventHandlers { + void (*OnClose)(void* user); + void (*OnKey)(void* user, unsigned key, bool pressed); +}; + +struct Window* WindowCreate( + const struct WindowEventHandlers* window_event_handlers, void* user); int WindowGetEventsFd(const struct Window* window); bool WindowProcessEvents(const struct Window* window); bool WindowAssignFrames(struct Window* window, size_t nframes, const struct Frame* frames); bool WindowShowFrame(struct Window* window, size_t index); -void WindowDestroy(struct Window** window); +void WindowDestroy(struct Window* window); #endif // RECEIVER_WINDOW_H_ |