From 5862e59b63a0757894f2cadeb81ee379308a41aa Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 17 Oct 2025 03:47:54 +0000 Subject: [PATCH] safety git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@393 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/gldemos/glutlayer.c | 4 +++- include/Mw/Core.h | 6 +++--- include/Mw/TypeDefs.h | 2 ++ src/backend/x11.c | 5 +++-- src/core.c | 27 ++++++++++++++++++--------- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/examples/gldemos/glutlayer.c b/examples/gldemos/glutlayer.c index ee8efce..78733b0 100644 --- a/examples/gldemos/glutlayer.c +++ b/examples/gldemos/glutlayer.c @@ -58,7 +58,9 @@ int main() { reshape(400, 400); MwAddUserHandler(window, MwNresizeHandler, resize, NULL); - MwAddUserHandler(window, MwNtickHandler, tick, NULL); + MwAddUserHandler(opengl, MwNtickHandler, tick, NULL); + + MwAddTickList(opengl); MwAddUserHandler(opengl, MwNkeyHandler, key_pressed, NULL); diff --git a/include/Mw/Core.h b/include/Mw/Core.h index a0d48d4..c1bcc7b 100644 --- a/include/Mw/Core.h +++ b/include/Mw/Core.h @@ -16,7 +16,7 @@ * %param y Handler name */ #define MwDispatch(x, y) \ - if(x->widget_class != NULL && x->widget_class->y != NULL) x->widget_class->y(x) + if(!x->destroyed && x->widget_class != NULL && x->widget_class->y != NULL) x->widget_class->y(x) /*! * %warning Used internally @@ -26,7 +26,7 @@ * %return `0` for success, otherwise failed */ #define MwDispatch2(x, y) \ - ((x->widget_class != NULL && x->widget_class->y != NULL) ? x->widget_class->y(x) : 0) + ((!x->destroyed && x->widget_class != NULL && x->widget_class->y != NULL) ? x->widget_class->y(x) : 0) /*! * %warning Used internally @@ -36,7 +36,7 @@ * %param z Argument */ #define MwDispatch3(x, y, z) \ - if(x->widget_class != NULL && x->widget_class->y != NULL) x->widget_class->y(x, z) + if(!x->destroyed && x->widget_class != NULL && x->widget_class->y != NULL) x->widget_class->y(x, z) #define MwWaitMS 10 diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index be51a45..6a63897 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -106,6 +106,8 @@ struct _MwWidget { MwWidget* destroy_queue; MwWidget* tick_list; + + int destroyed; }; #endif diff --git a/src/backend/x11.c b/src/backend/x11.c index 560c661..2fe7401 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -132,14 +132,15 @@ MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { void MwLLDestroy(MwLL handle) { MwLLDestroyCommon(handle); - XDestroyIC(handle->xic); - XCloseIM(handle->xim); + if(handle->xic) XDestroyIC(handle->xic); + if(handle->xim) XCloseIM(handle->xim); destroy_pixmap(handle); XFree(handle->visual); XFreeGC(handle->display, handle->gc); XUnmapWindow(handle->display, handle->window); XDestroyWindow(handle->display, handle->window); + XFlush(handle->display); free(handle); } diff --git a/src/core.c b/src/core.c index 065dbac..d5c1b21 100644 --- a/src/core.c +++ b/src/core.c @@ -113,6 +113,7 @@ MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, h->prop_event = 1; h->draw_inject = NULL; h->tick_list = NULL; + h->destroyed = 0; if(parent == NULL) arrput(h->tick_list, h); @@ -211,17 +212,11 @@ void MwDestroyWidget(MwWidget handle) { if(handle->parent != NULL) { arrput(handle->parent->destroy_queue, handle); } + handle->destroyed = 1; } -void MwStep(MwWidget handle) { +static void clean_destroy_queue(MwWidget handle) { int i, j; - if(setjmp(handle->before_step)) return; - for(i = 0; i < arrlen(handle->children); i++) MwStep(handle->children[i]); - - handle->prop_event = 0; - if(handle->lowlevel != NULL) MwLLNextEvent(handle->lowlevel); - handle->prop_event = 1; - for(i = 0; i < arrlen(handle->destroy_queue); i++) { MwWidget w = handle->destroy_queue[i]; @@ -238,12 +233,24 @@ void MwStep(MwWidget handle) { arrfree(handle->destroy_queue); } +void MwStep(MwWidget handle) { + int i; + if(setjmp(handle->before_step)) return; + for(i = 0; i < arrlen(handle->children); i++) MwStep(handle->children[i]); + + handle->prop_event = 0; + if(handle->lowlevel != NULL && MwLLPending(handle->lowlevel)) MwLLNextEvent(handle->lowlevel); + handle->prop_event = 1; + + clean_destroy_queue(handle); +} + int MwPending(MwWidget handle) { int i; for(i = 0; i < arrlen(handle->children); i++) { if(MwPending(handle->children[i])) return 1; } - return MwLLPending(handle->lowlevel); + return (arrlen(handle->destroy_queue) > 0 ? 1 : 0) || MwLLPending(handle->lowlevel); } void MwLoop(MwWidget handle) { @@ -255,6 +262,7 @@ void MwLoop(MwWidget handle) { for(i = 0; i < arrlen(handle->tick_list); i++) { MwDispatchUserHandler(handle->tick_list[i], MwNtickHandler, NULL); } + tick = MwWaitMS - (MwLLGetTick() - tick); if(tick > 0) MwLLSleep(tick); tick = MwLLGetTick(); @@ -394,6 +402,7 @@ void MwSetDefault(MwWidget handle) { void MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data) { int ind = shgeti(handle->handler, key); if(ind == -1) return; + if(handle->destroyed) return; handle->handler[ind].value(handle, handle->handler[ind].user_data, handler_data); }