From 5413332506b2929c30c169a3f68934252d39cfff Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 23 Jan 2026 15:29:32 +0900 Subject: [PATCH] introduce MwWidget->berserk --- include/Mw/TypeDefs.h | 2 ++ src/abstract/time.c | 5 ----- src/core.c | 3 ++- src/widget/opengl.c | 42 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index d175c2b..d6bd1da 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -104,6 +104,8 @@ struct _MwWidget { void* root_font; void* root_boldfont; + + int berserk; }; #endif diff --git a/src/abstract/time.c b/src/abstract/time.c index 7279978..1050c46 100644 --- a/src/abstract/time.c +++ b/src/abstract/time.c @@ -46,16 +46,11 @@ long MwTimeGetTick(void) { } void MwTimeSleep(int ms) { -#ifdef __NetBSD__ - usleep(ms * 100); -#else - /* i don't know why this method does not work well on netbsd */ struct timespec ts; ts.tv_sec = ms / 1000; ts.tv_nsec = (ms % 1000) * 1000000; nanosleep(&ts, NULL); -#endif } #endif diff --git a/src/core.c b/src/core.c index 9ec87b2..78d2a94 100644 --- a/src/core.c +++ b/src/core.c @@ -154,6 +154,7 @@ MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, h->destroyed = 0; h->dark_theme = 0; h->bgcolor = NULL; + h->berserk = 0; if(parent == NULL) arrput(h->tick_list, h); @@ -392,7 +393,7 @@ void MwLoop(MwWidget handle) { more = over % (wait / 2); t = (tick + wait - more) - (t2 = MwTimeGetTick()); if(t > 0) { - MwTimeSleep(t); + if(!handle->berserk) MwTimeSleep(t); tick = MwTimeGetTick(); over -= more; } else { diff --git a/src/widget/opengl.c b/src/widget/opengl.c index 0dedd7f..8738b5d 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -56,7 +56,9 @@ typedef struct waylandopengl { #endif static int create(MwWidget handle) { - void* r = NULL; + void* r = NULL; + MwWidget w = handle; + #ifdef USE_GDI if(handle->lowlevel->common.type == MwLLBackendGDI) { PIXELFORMATDESCRIPTOR pfd; @@ -210,10 +212,16 @@ static int create(MwWidget handle) { MwSetDefault(handle); + while(w->parent != NULL) w = w->parent; + + w->berserk++; + return 0; } static void destroy(MwWidget handle) { + MwWidget w = handle; + #ifdef USE_GDI if(handle->lowlevel->common.type == MwLLBackendGDI) { gdiopengl_t* o = handle->internal; @@ -241,22 +249,48 @@ static void destroy(MwWidget handle) { } #endif + while(w->parent != NULL) w = w->parent; + + w->berserk++; + free(handle->internal); } static void mwOpenGLMakeCurrentImpl(MwWidget handle) { + /* these swap interval functions belonging here actually stink! */ + #ifdef USE_GDI if(handle->lowlevel->common.type == MwLLBackendGDI) { - gdiopengl_t* o = handle->internal; + gdiopengl_t* o = handle->internal; + void (*swap_interval_ext)(int) = NULL; o->wglMakeCurrent(o->dc, o->gl); + + if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) { + swap_interval_ext(1); + } } #endif #ifdef USE_X11 if(handle->lowlevel->common.type == MwLLBackendX11) { - x11opengl_t* o = handle->internal; + x11opengl_t* o = handle->internal; + void (*swap_interval_ext)(Display*, GLXDrawable, int) = NULL; + void (*swap_interval_mesa)(unsigned int) = NULL; + void (*swap_interval_sgi)(int) = NULL; o->glXMakeCurrent(handle->lowlevel->x11.display, handle->lowlevel->x11.window, o->gl); + + if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) { + swap_interval_ext(handle->lowlevel->x11.display, handle->lowlevel->x11.window, 1); + } + + if((swap_interval_mesa = MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) { + swap_interval_mesa(1); + } + + if((swap_interval_sgi = MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) { + swap_interval_sgi(1); + } } #endif #ifdef USE_WAYLAND @@ -266,6 +300,8 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) { if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface, o->egl_context)) { printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); } + + eglSwapInterval(o->egl_display, 1); } #endif }