diff --git a/arena.h b/arena.h new file mode 100644 index 0000000..f9fd13e --- /dev/null +++ b/arena.h @@ -0,0 +1,47 @@ +#ifndef ARENA_H +#define ARENA_H + +typedef enum { + ARENA_ZERO = 1 << 0, + ARENA_SOFTFAIL = 1 << 1, +} arena_flags_t; + +// More or less taken from https://nullprogram.com/blog/2023/09/27/ +typedef struct { + uint8_t *begin; + uint8_t *end; +} arena_t; + +arena_t arena_create(ptrdiff_t capacity) +{ + arena_t a = {0}; + a.begin = malloc(capacity); + a.end = a.begin ? a.begin + capacity : 0; + return a; +} + + +void *arena_alloc(arena_t *a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, arena_flags_t flags) +{ + ptrdiff_t padding = -(uintptr_t)a->begin & (align - 1); + ptrdiff_t available = a->end - a->begin - padding; + if (available < 0 || count > available/size) + { + // TODO: Decide what to do on oom + if (flags & ARENA_SOFTFAIL) + return 0; + else + abort(); + } + void *p = a->begin + padding; + a->begin += padding + count*size; + return flags & ARENA_ZERO ? p : memset(p, 0, count*size); +} + +#define arena_reserve(arena, type, count, flags) (type *)arena_alloc(arena, sizeof(type), _Alignof(type), count, flags) + +#define KB 1024 +#define MB 1024*KB +#define GB 1024*MB + +#endif diff --git a/input.h b/input.h index 39ec62a..4242dd6 100644 --- a/input.h +++ b/input.h @@ -45,7 +45,7 @@ typedef enum { } mouse_keysym_t; #define IME_STR_MAX 200 // TODO: check if this limit is sensible -#define KEYBOARD_KEY_TOTAL +#define KEYBOARD_KEY_TOTAL 256 typedef struct { uint8_t keyboard_state; // mostly used to check if we are using the IME diff --git a/wayland.c b/wayland.c index a86066e..1b3004b 100644 --- a/wayland.c +++ b/wayland.c @@ -20,6 +20,7 @@ #include "zwp-text-input-unstable-v3-protocol.h" // common headers for platform layer and application layer #include "input.h" +#include "arena.h" struct wl_compositor *compositor = NULL; struct wl_registry *registry = NULL; @@ -48,6 +49,7 @@ struct xkb_keymap *xkb_keymap = NULL; EGLBoolean errcode = 0; bool running = true; input_t user_input = {}; +arena_t main_arena = {}; char *egl_s(int code) { @@ -192,7 +194,7 @@ void keymap_callback(void *data, struct wl_keyboard *kb, uint format, int fd, ui xkb_keymap = xkb_keymap_new_from_string(xkb_context, mem, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(mem, size); close(fd); - + if (!(xkb_state = xkb_state_new(xkb_keymap))) fprintf(stderr, "Could not initialize XKB state machine\n"); } @@ -205,9 +207,9 @@ void enter_callback(void *data, struct wl_keyboard* kb, uint serial, struct wl_s // NOTE: wl_array is a dynamic array as specified in wayland-util.h int32_t *pos = arr->data; // wl_keyboard is giving us all the currenly pressed keys anyways - for (int i = 0; i < KEYBOARD_KEY_TOTAL) + for (int i = 0; i < KEYBOARD_KEY_TOTAL; ++i) user_input.keys[i] = KEY_STATE_UNPRESSED; - + wl_array_for_each(pos, arr) { xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, (*pos) + 8); // TODO: Decide if we should also set KEY_STATE_HELD @@ -351,6 +353,11 @@ void pointer_axis_relative_direction_callback(void *data, struct wl_pointer *poi int main() { fprintf(stdout, "Starting platform layer...\n"); + main_arena = arena_create(1*GB); + if (!main_arena.begin) + fprintf(stderr, "Could not reserve memory for main arena!\n"); + + struct wl_display *display = wl_display_connect(NULL); if (!display) { @@ -387,11 +394,11 @@ int main() .configure = xdg_toplevel_configure, .close = xdg_toplevel_close }; - + const struct xdg_wm_base_listener xdg_wm_base_listener = { .ping = wayland_ping }; - + if (xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL)) fprintf(stderr, "Could not set XDG toplevel listener\n"); if (xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, NULL)) @@ -403,7 +410,7 @@ int main() } if (!(wl_pointer = wl_seat_get_pointer(wl_seat))) fprintf(stderr, "Could not get WL pointer\n"); - + if (!zwp_text_input_manager_v3) fprintf(stderr, "Could not get ZWP text input manager\n"); else if (!(zwp_text_input_v3 = zwp_text_input_manager_v3_get_text_input(zwp_text_input_manager_v3, wl_seat))) @@ -417,7 +424,7 @@ int main() .delete_surrounding_text = zwp_text_input_v3_delete_surrounding_text_callback, .done = zwp_text_input_v3_done_callback }; - + if (zwp_text_input_v3_add_listener(zwp_text_input_v3, &zwp_text_input_v3_listener, NULL)) fprintf(stderr, "Could not add ZWP text input callback\n"); @@ -440,7 +447,7 @@ int main() }; if (wl_keyboard_add_listener(wl_keyboard, &wl_keyboard_listener, NULL)) fprintf(stderr, "Could not set XKB keyboard listener\n"); - + /* NOTE: Apparently wl_pointer added 'axis_value120' with v8 and 'axis_relative_direction' events with v9. Failing to provide callbacks for them crashes the client in runtime */ const struct wl_pointer_listener wl_pointer_listener = { @@ -478,7 +485,8 @@ int main() if (errcode != EGL_TRUE) fprintf(stderr, "ERR %s: Could not retrieve EGL config number\n", egl_s(errcode)); - EGLConfig *configs = calloc(config_count, sizeof(EGLConfig)); + //EGLConfig *configs = calloc(config_count, sizeof(EGLConfig)); + EGLConfig *configs = arena_reserve(&main_arena, EGLConfig, config_count, ARENA_ZERO); EGLint attr_list[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT,