summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Burakov <mburakov@mailbox.org>2023-04-02 12:09:20 +0200
committerMikhail Burakov <mburakov@mailbox.org>2023-04-07 13:47:39 +0200
commiteecbacdc1ab1b29fee71f3a689e01cabe12b3730 (patch)
tree0b6c924678a31ed2f46061f7767a99bb40b57737
parent972e03b4a09b790d9ed9c8102cc897a75c9bb751 (diff)
Major rewrite of window to support input events
-rw-r--r--.gitignore2
-rw-r--r--main.c22
-rw-r--r--window.c513
-rw-r--r--window.h10
4 files changed, 365 insertions, 182 deletions
diff --git a/.gitignore b/.gitignore
index 4e2021d..2ca1a3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@
.clang-format
compile_commands.json
compile_flags.txt
+linux-dmabuf-unstable-v1.h
receiver
+xdg-shell.h
diff --git a/main.c b/main.c
index 2a5e7ff..c650ea2 100644
--- a/main.c
+++ b/main.c
@@ -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;
diff --git a/window.c b/window.c
index 4c89c18..232d261 100644
--- a/window.c
+++ b/window.c
@@ -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);
}
diff --git a/window.h b/window.h
index 80562f3..a0f6b0d 100644
--- a/window.h
+++ b/window.h
@@ -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_