diff --git a/glava.c b/glava.c index 2570593..6cc07eb 100644 --- a/glava.c +++ b/glava.c @@ -292,5 +292,12 @@ int main(int argc, char** argv) { } } + audio.terminate = 1; + int return_status; + if ((return_status = pthread_join(thread, NULL))) { + fprintf(stderr, "Failed to join with audio thread: %s\n", strerror(return_status)); + } + + free(audio.source); rd_destroy(r); } diff --git a/glfw_wcb.c b/glfw_wcb.c index 8d4f4e9..9fd931d 100644 --- a/glfw_wcb.c +++ b/glfw_wcb.c @@ -134,6 +134,8 @@ static double get_time (GLFWwindow* w) { return glfwGetT static void set_time (GLFWwindow* w, double time) { glfwSetTime(time); } static void set_swap (int i) { glfwSwapInterval(i); } static void raise (GLFWwindow* w) { glfwShowWindow(w); } +static void destroy (GLFWwindow* w) { glfwDestroyWindow(w); } +static void terminate (void) { glfwTerminate(); } static const char* get_environment(void) { return xwin_detect_wm(&wcb_glfw); } diff --git a/glx_wcb.c b/glx_wcb.c index 4600ce1..24f7ba3 100644 --- a/glx_wcb.c +++ b/glx_wcb.c @@ -160,6 +160,7 @@ Bool (*glXMakeCurrent) (Display* dpy, GLXDrawable drawable, GLXDrawable (*glXGetCurrentDrawable) (void); __GLXextFuncPtr (*glXGetProcAddressARB) (const GLubyte *); void (*glXSwapBuffers) (Display* dpy, GLXDrawable drawable); +void (*glXDestroyContext) (Display* dpy, GLXContext ctx); extern struct gl_wcb wcb_glx; @@ -222,6 +223,7 @@ static void init(void) { resolve(glXGetCurrentDrawable); resolve(glXGetProcAddressARB); resolve(glXSwapBuffers); + resolve(glXDestroyContext); intern(_MOTIF_WM_HINTS, false); intern(WM_DELETE_WINDOW, true); @@ -481,6 +483,16 @@ static double get_timert(void) { return (double) tv.tv_sec + ((double) tv.tv_nsec / 1000000000.0D); } +static void destroy(struct glxwin* w) { + glXMakeCurrent(display, None, NULL); /* release context */ + glXDestroyContext(display, w->context); + XDestroyWindow(display, w->w); +} + +static void terminate(void) { + XCloseDisplay(display); +} + static double get_time (struct glxwin* w) { return get_timert() - w->time; } static void set_time (struct glxwin* w, double time) { w->time = get_timert() - time; } static Display* get_x11_display(struct glxwin* w) { return display; } diff --git a/render.c b/render.c index bdcf793..60575bd 100644 --- a/render.c +++ b/render.c @@ -791,7 +791,8 @@ struct renderer* rd_new(const char** paths, const char* entry, context_version_major = 3, context_version_minor = 3; const char* module = force_mod; - char* xwintype = NULL, * wintitle = "GLava"; + const char* wintitle_default = "GLava"; + char* xwintype = NULL, * wintitle = (char*) wintitle_default; char** xwinstates = malloc(1); size_t xwinstates_sz = 0; bool loading_module = true, loading_smooth_pass = false, loading_presets = false;; @@ -860,6 +861,7 @@ struct renderer* rd_new(const char** paths, const char* entry, .name = "mod", .fmt = "s", .handler = RHANDLER(name, args, { if (loading_module && !force_mod) { + if (module != NULL && module != force_mod) free((char*) module); size_t len = strlen((char*) args[0]); char* str = malloc(sizeof(char) * (len + 1)); strncpy(str, (char*) args[0], len + 1); @@ -910,6 +912,7 @@ struct renderer* rd_new(const char** paths, const char* entry, }, { .name = "setsource", .fmt = "s", .handler = RHANDLER(name, args, { + if (r->audio_source_request) free(r->audio_source_request); r->audio_source_request = strdup((char*) args[0]); }) }, { .name = "setclickthrough", .fmt = "b", .handler = RHANDLER(name, args, { gl->clickthrough = *(bool*) args[0]; }) }, @@ -918,7 +921,9 @@ struct renderer* rd_new(const char** paths, const char* entry, { .name = "setforceraised", .fmt = "b", .handler = RHANDLER(name, args, { gl->force_raised = *(bool*) args[0]; }) }, { .name = "setxwintype", .fmt = "s", - .handler = RHANDLER(name, args, { xwintype = strdup((char*) args[0]); }) }, + .handler = RHANDLER(name, args, { + if (xwintype) free(xwintype); + xwintype = strdup((char*) args[0]); }) }, { .name = "setshaderversion", .fmt = "i", .handler = RHANDLER(name, args, { shader_version = *(int*) args[0]; }) }, { .name = "setswap", .fmt = "i", @@ -928,7 +933,9 @@ struct renderer* rd_new(const char** paths, const char* entry, { .name = "setprintframes", .fmt = "b", .handler = RHANDLER(name, args, { gl->print_fps = *(bool*) args[0]; }) }, { .name = "settitle", .fmt = "s", - .handler = RHANDLER(name, args, { wintitle = strdup((char*) args[0]); }) }, + .handler = RHANDLER(name, args, { + if (wintitle && wintitle != wintitle_default) free((char*) wintitle); + wintitle = strdup((char*) args[0]); }) }, { .name = "setbufsize", .fmt = "i", .handler = RHANDLER(name, args, { r->bufsize_request = *(int*) args[0]; }) }, { .name = "setbufscale", .fmt = "i", @@ -1138,9 +1145,13 @@ struct renderer* rd_new(const char** paths, const char* entry, gl->geometry[2], gl->geometry[3], gl->geometry[0], gl->geometry[1], context_version_major, context_version_minor, gl->clickthrough); if (!gl->w) abort(); + + for (size_t t = 0; t < xwinstates_sz; ++t) + free(xwinstates[t]); if (xwintype) free(xwintype); if (xwinstates) free(xwinstates); + if (wintitle && wintitle != wintitle_default) free(wintitle); glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_CLAMP); @@ -1698,7 +1709,24 @@ void* rd_get_impl_window (struct renderer* r) { return r->gl->w; } struct gl_wcb* rd_get_wcb (struct renderer* r) { return r->gl->wcb; } void rd_destroy(struct renderer* r) { - /* TODO: delete everything else, not really needed though (as the application exits after here) */ + r->gl->wcb->destroy(r->gl->w); + if (r->gl->interpolate) free(r->gl->interpolate_buf[0]); + if (r->gl->t_data) free(r->gl->t_data); + size_t t, b; + for (t = 0; t < r->gl->stages_sz; ++t) { + struct gl_sfbo* stage = &r->gl->stages[t]; + for (b = 0; b < stage->binds_sz; ++b) { + struct gl_bind* bind = &stage->binds[b]; + free(bind->transformations); + free((char*) bind->name); /* strdup */ + } + free(stage->binds); + free((char*) stage->name); /* strdup */ + } + free(r->gl->stages); + r->gl->wcb->terminate(); free(r->gl); + if (r->audio_source_request) + free(r->audio_source_request); free(r); } diff --git a/render.h b/render.h index 1b4821b..db043c2 100644 --- a/render.h +++ b/render.h @@ -35,6 +35,8 @@ struct gl_wcb { bool (*should_close) (void* ptr); void (*swap_buffers) (void* ptr); void (*raise) (void* ptr); + void (*destroy) (void* ptr); + void (*terminate) (void); void (*get_pos) (void* ptr, int* x, int* y); void (*get_fbsize) (void* ptr, int* w, int* h); void (*set_geometry) (void* ptr, int x, int y, int w, int h); @@ -68,6 +70,8 @@ struct gl_wcb { WCB_FUNC(should_close), \ WCB_FUNC(swap_buffers), \ WCB_FUNC(raise), \ + WCB_FUNC(destroy), \ + WCB_FUNC(terminate), \ WCB_FUNC(set_swap), \ WCB_FUNC(get_pos), \ WCB_FUNC(get_fbsize), \