diff --git a/src/main.c b/src/main.c index 8a4835a..d51e6c3 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,13 @@ #include #include +#include + +static bool close = false; + +static void signal_handler() { + close = true; +} int main (void) { Screen screen; @@ -10,8 +17,10 @@ int main (void) { Camera camera; init_camera(&camera); + + signal(SIGINT, signal_handler); - while (poll_screen(&screen)) { + while (poll_screen(&screen) && !close) { render(&screen, &camera); update_camera(&camera, &screen); diff --git a/src/screen.c b/src/screen.c index eb2de87..5e84038 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,5 +1,4 @@ #include "screen.h" -#include #undef Screen #include @@ -7,9 +6,9 @@ #include #include #include -#include #include #include +#include #define XLIB_ILLEGAL_ACCESS #include @@ -123,16 +122,20 @@ static Swapchain create_swapchain(int width, int height, int frames, int bit_dep return swapchain; } -static void free_swapchain(Swapchain swapchain, WindowState* state) { - for (uint8_t i = 0; i < swapchain.image_count; i++) { +static void free_swapchain(Swapchain* swapchain, WindowState* state) { + pthread_mutex_lock(&state->recreate_lock); + for (uint8_t i = 0; i < swapchain->image_count; i++) { XDestroyImage(state->images[i]); // also frees pixel buffer :3 } - free(swapchain.images); + free(swapchain->images); free(state->images); + swapchain->images = NULL; XFreePixmap(dpy, state->pixel_map); XFreeGC(dpy, state->graphics_ctx); + + pthread_mutex_unlock(&state->recreate_lock); } static void recreate_swapchain(int width, int height, int bit_depth, Swapchain* swapchain, WindowState* state) { @@ -186,8 +189,13 @@ static void* swapchain_thread(void* arg) { WindowState* state = (WindowState*) screen->internal; while (1) { - pthread_mutex_lock(&state->recreate_lock); + + if (screen->swapchain.images == NULL) { + return NULL; + } + pthread_mutex_lock(&state->recreate_lock); + pthread_mutex_lock(&screen->swapchain.lock); int index = screen->swapchain.image_recent; screen->swapchain.image_front = index; @@ -294,9 +302,12 @@ bool poll_screen(struct Screen* screen) { void free_screen(struct Screen* screen) { WindowState* state = (WindowState*) screen->internal; + free_swapchain(&screen->swapchain, state); pthread_exit(&state->update_thread); + pthread_mutex_destroy(&screen->swapchain.lock); + pthread_mutex_destroy(&state->recreate_lock); + XUnmapWindow(dpy, state->window); - free_swapchain(screen->swapchain, state); XDestroyWindow(dpy, state->window); free(screen->internal);