wayland: improve event loop
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoI_xD 2026-03-17 22:17:05 -07:00
commit fc7896b5ce
2 changed files with 351 additions and 355 deletions

View file

@ -1046,8 +1046,12 @@ static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland*
/* Standard Wayland event loop. */ /* Standard Wayland event loop. */
static int event_loop(MwLL handle) { static int event_loop(MwLL handle) {
struct pollfd fd; struct pollfd fd;
int timeout = 1; struct timespec timeout;
struct _MwLLWayland* wayland = &handle->wayland; struct _MwLLWayland* wayland = &handle->wayland;
int res;
timeout.tv_nsec = 1;
timeout.tv_sec = 0;
if(wayland->display == NULL) { if(wayland->display == NULL) {
return 0; return 0;
@ -1072,19 +1076,15 @@ static int event_loop(MwLL handle) {
} }
wl_display_prepare_read(handle->wayland.display); wl_display_prepare_read(handle->wayland.display);
/* Condition where no events are being sent. */ wl_display_read_events(wayland->display);
if(!poll(&fd, 1, timeout)) { if((res = wl_display_dispatch_timeout(wayland->display, &timeout)) <= 0) {
wl_display_cancel_read(wayland->display); if(res < 0) {
/* In this case, we need to commit the surface for any animations, etc. */ wl_display_cancel_read(handle->wayland.display);
}
wl_surface_commit(wayland->framebuffer.surface); wl_surface_commit(wayland->framebuffer.surface);
return 0; return 0;
} }
wl_display_read_events(wayland->display);
if(wl_display_dispatch_pending(wayland->display) < 0) {
wl_display_cancel_read(handle->wayland.display);
}
return 1; return 1;
} }
@ -1605,20 +1605,17 @@ static void MwLLFreeColorImpl(MwLLColor color) {
static int MwLLPendingImpl(MwLL handle) { static int MwLLPendingImpl(MwLL handle) {
MwBool pending = MwFALSE; MwBool pending = MwFALSE;
struct timespec timeout; struct timespec timeout;
int i;
timeout.tv_nsec = 1; timeout.tv_nsec = 1;
timeout.tv_sec = 0; timeout.tv_sec = 0;
int i;
pending = wl_display_dispatch_timeout(handle->wayland.display, &timeout); pending = wl_display_dispatch_timeout(handle->wayland.display, &timeout);
if(handle->wayland.always_render) { if(handle->wayland.always_render) {
event_loop(handle); event_loop(handle);
return 0; return 0;
} } else if(handle->wayland.force_render) {
if(handle->wayland.force_render) {
MwLLDispatch(handle, draw, NULL); MwLLDispatch(handle, draw, NULL);
// handle->wayland.force_render = 0;
// update_buffer(&handle->wayland.framebuffer);
return 1; return 1;
} }
if(handle->wayland.events_pending || handle->wayland.force_render) { if(handle->wayland.events_pending || handle->wayland.force_render) {

View file

@ -4,46 +4,46 @@
#include <Mw/Widget/OpenGL.h> #include <Mw/Widget/OpenGL.h>
#ifdef USE_GDI #ifdef USE_GDI
typedef HGLRC(WINAPI *MWwglCreateContext)(HDC); typedef HGLRC(WINAPI* MWwglCreateContext)(HDC);
typedef BOOL(WINAPI *MWwglMakeCurrent)(HDC, HGLRC); typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC);
typedef PROC(WINAPI *MWwglGetProcAddress)(LPCSTR); typedef PROC(WINAPI* MWwglGetProcAddress)(LPCSTR);
typedef BOOL(WINAPI *MWwglDeleteContext)(HGLRC); typedef BOOL(WINAPI* MWwglDeleteContext)(HGLRC);
typedef struct gdiopengl { typedef struct gdiopengl {
HDC dc; HDC dc;
HGLRC gl; HGLRC gl;
void *lib; void* lib;
MWwglCreateContext wglCreateContext; MWwglCreateContext wglCreateContext;
MWwglMakeCurrent wglMakeCurrent; MWwglMakeCurrent wglMakeCurrent;
MWwglDeleteContext wglDeleteContext; MWwglDeleteContext wglDeleteContext;
MWwglGetProcAddress wglGetProcAddress; MWwglGetProcAddress wglGetProcAddress;
} gdiopengl_t; } gdiopengl_t;
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
typedef XVisualInfo *(*MWglXChooseVisual)(Display *dpy, int screen, typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen,
int *attribList); int* attribList);
typedef GLXContext (*MWglXCreateContext)(Display *dpy, XVisualInfo *vis, typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis,
GLXContext shareList, Bool direct); GLXContext shareList, Bool direct);
typedef void (*MWglXDestroyContext)(Display *dpy, GLXContext ctx); typedef void (*MWglXDestroyContext)(Display* dpy, GLXContext ctx);
typedef Bool (*MWglXMakeCurrent)(Display *dpy, GLXDrawable drawable, typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable,
GLXContext ctx); GLXContext ctx);
typedef void (*MWglXSwapBuffers)(Display *dpy, GLXDrawable drawable); typedef void (*MWglXSwapBuffers)(Display* dpy, GLXDrawable drawable);
typedef void *(*MWglXGetProcAddress)(const GLubyte *procname); typedef void* (*MWglXGetProcAddress)(const GLubyte* procname);
typedef struct x11opengl { typedef struct x11opengl {
XVisualInfo *visual; XVisualInfo* visual;
GLXContext gl; GLXContext gl;
void *lib; void* lib;
MWglXChooseVisual glXChooseVisual; MWglXChooseVisual glXChooseVisual;
MWglXCreateContext glXCreateContext; MWglXCreateContext glXCreateContext;
MWglXDestroyContext glXDestroyContext; MWglXDestroyContext glXDestroyContext;
MWglXMakeCurrent glXMakeCurrent; MWglXMakeCurrent glXMakeCurrent;
MWglXSwapBuffers glXSwapBuffers; MWglXSwapBuffers glXSwapBuffers;
MWglXGetProcAddress glXGetProcAddress; MWglXGetProcAddress glXGetProcAddress;
} x11opengl_t; } x11opengl_t;
#endif #endif
@ -52,385 +52,384 @@ typedef struct x11opengl {
#include <wayland-egl-core.h> #include <wayland-egl-core.h>
typedef struct waylandopengl { typedef struct waylandopengl {
EGLNativeWindowType egl_window_native; EGLNativeWindowType egl_window_native;
EGLDisplay egl_display; EGLDisplay egl_display;
EGLContext egl_context; EGLContext egl_context;
EGLSurface egl_surface; EGLSurface egl_surface;
EGLConfig egl_config; EGLConfig egl_config;
} waylandopengl_t; } waylandopengl_t;
#endif #endif
static int create(MwWidget handle) { static int create(MwWidget handle) {
void *r = NULL; void* r = NULL;
MwWidget w = handle; MwWidget w = handle;
#ifdef USE_GDI #ifdef USE_GDI
if (handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int pf; int pf;
gdiopengl_t *o = r = malloc(sizeof(*o)); gdiopengl_t* o = r = malloc(sizeof(*o));
memset(&pfd, 0, sizeof(pfd)); memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd); pfd.nSize = sizeof(pfd);
pfd.nVersion = 1; pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.cDepthBits = 32; pfd.cDepthBits = 32;
pfd.cColorBits = 32; pfd.cColorBits = 32;
o->dc = GetDC(handle->lowlevel->gdi.hWnd); o->dc = GetDC(handle->lowlevel->gdi.hWnd);
pf = ChoosePixelFormat(o->dc, &pfd); pf = ChoosePixelFormat(o->dc, &pfd);
SetPixelFormat(o->dc, pf, &pfd); SetPixelFormat(o->dc, pf, &pfd);
o->lib = MwDynamicOpen("opengl32.dll"); o->lib = MwDynamicOpen("opengl32.dll");
o->wglCreateContext = o->wglCreateContext =
(MWwglCreateContext)(void *)MwDynamicSymbol(o->lib, "wglCreateContext"); (MWwglCreateContext)(void*)MwDynamicSymbol(o->lib, "wglCreateContext");
o->wglMakeCurrent = o->wglMakeCurrent =
(MWwglMakeCurrent)(void *)MwDynamicSymbol(o->lib, "wglMakeCurrent"); (MWwglMakeCurrent)(void*)MwDynamicSymbol(o->lib, "wglMakeCurrent");
o->wglDeleteContext = o->wglDeleteContext =
(MWwglDeleteContext)(void *)MwDynamicSymbol(o->lib, "wglDeleteContext"); (MWwglDeleteContext)(void*)MwDynamicSymbol(o->lib, "wglDeleteContext");
o->wglGetProcAddress = (MWwglGetProcAddress)(void *)MwDynamicSymbol( o->wglGetProcAddress = (MWwglGetProcAddress)(void*)MwDynamicSymbol(
o->lib, "wglGetProcAddress"); o->lib, "wglGetProcAddress");
o->gl = o->wglCreateContext(o->dc); o->gl = o->wglCreateContext(o->dc);
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if (handle->lowlevel->common.type == MwLLBackendX11) { if(handle->lowlevel->common.type == MwLLBackendX11) {
int attribs[5]; int attribs[5];
const char *glpath[] = {"libGL.so", "/usr/local/lib/libGL.so", const char* glpath[] = {"libGL.so", "/usr/local/lib/libGL.so",
"/usr/X11R7/lib/libGL.so", "/usr/pkg/lib/libGL.so"}; "/usr/X11R7/lib/libGL.so", "/usr/pkg/lib/libGL.so"};
int glincr = 0; int glincr = 0;
x11opengl_t *o = r = malloc(sizeof(*o)); x11opengl_t* o = r = malloc(sizeof(*o));
attribs[0] = GLX_RGBA; attribs[0] = GLX_RGBA;
attribs[1] = GLX_DOUBLEBUFFER; attribs[1] = GLX_DOUBLEBUFFER;
attribs[2] = GLX_DEPTH_SIZE; attribs[2] = GLX_DEPTH_SIZE;
attribs[3] = 24; attribs[3] = 24;
attribs[4] = None; attribs[4] = None;
while (glpath[glincr] != NULL && while(glpath[glincr] != NULL &&
(o->lib = MwDynamicOpen(glpath[glincr++])) == NULL) (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL);
;
o->glXChooseVisual = o->glXChooseVisual =
(MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual"); (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual");
o->glXCreateContext = o->glXCreateContext =
(MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext"); (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext");
o->glXDestroyContext = o->glXDestroyContext =
(MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext"); (MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext");
o->glXMakeCurrent = o->glXMakeCurrent =
(MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent"); (MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent");
o->glXSwapBuffers = o->glXSwapBuffers =
(MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers"); (MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers");
o->glXGetProcAddress = o->glXGetProcAddress =
(MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress"); (MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress");
/* XXX: fix this */ /* XXX: fix this */
o->visual = o->glXChooseVisual(handle->lowlevel->x11.display, o->visual = o->glXChooseVisual(handle->lowlevel->x11.display,
DefaultScreen(handle->lowlevel->x11.display), DefaultScreen(handle->lowlevel->x11.display),
attribs); attribs);
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL, o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL,
GL_TRUE); GL_TRUE);
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if (handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
int err; int err;
EGLint numConfigs; EGLint numConfigs;
EGLint majorVersion; EGLint majorVersion;
EGLint minorVersion; EGLint minorVersion;
EGLContext context; EGLContext context;
EGLSurface surface; EGLSurface surface;
EGLint fbAttribs[] = {EGL_SURFACE_TYPE, EGLint fbAttribs[] = {EGL_SURFACE_TYPE,
EGL_WINDOW_BIT, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, EGL_RED_SIZE,
8, 8,
EGL_GREEN_SIZE, EGL_GREEN_SIZE,
8, 8,
EGL_BLUE_SIZE, EGL_BLUE_SIZE,
8, 8,
EGL_DEPTH_SIZE, EGL_DEPTH_SIZE,
24, 24,
EGL_RENDERABLE_TYPE, EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT, EGL_OPENGL_BIT,
EGL_NONE}; EGL_NONE};
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,
1, 1,
EGL_CONTEXT_MAJOR_VERSION, EGL_CONTEXT_MAJOR_VERSION,
1, 1,
EGL_CONTEXT_MINOR_VERSION, EGL_CONTEXT_MINOR_VERSION,
1, 1,
EGL_NONE}; EGL_NONE};
EGLDisplay display; EGLDisplay display;
waylandopengl_t *o = r = malloc(sizeof(*o)); waylandopengl_t* o = r = malloc(sizeof(*o));
MwLL topmost_parent = handle->lowlevel->wayland.parent; MwLL topmost_parent = handle->lowlevel->wayland.parent;
topmost_parent->wayland.always_render = MwTRUE; topmost_parent->wayland.always_render = MwTRUE;
while (topmost_parent->wayland.parent != NULL) { while(topmost_parent->wayland.parent != NULL) {
topmost_parent = topmost_parent->wayland.parent; topmost_parent = topmost_parent->wayland.parent;
topmost_parent->wayland.always_render = MwTRUE; topmost_parent->wayland.always_render = MwTRUE;
} }
display = display =
eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display); eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display);
if (display == EGL_NO_DISPLAY) { if(display == EGL_NO_DISPLAY) {
printf("ERROR: eglGetDisplay, %0X\n", eglGetError()); printf("ERROR: eglGetDisplay, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
/* Initialize EGL */ /* Initialize EGL */
if (!eglInitialize(display, &majorVersion, &minorVersion)) { if(!eglInitialize(display, &majorVersion, &minorVersion)) {
printf("ERROR: eglInitialize, %0X\n", eglGetError()); printf("ERROR: eglInitialize, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
/* Get configs */ /* Get configs */
if ((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) ||
(numConfigs == 0)) { (numConfigs == 0)) {
printf("ERROR: eglGetConfigs, %0X\n", eglGetError()); printf("ERROR: eglGetConfigs, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
/* Choose config */ /* Choose config */
if ((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) != if((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) !=
EGL_TRUE) || EGL_TRUE) ||
(numConfigs != 1)) { (numConfigs != 1)) {
printf("ERROR: eglChooseConfig, %0X\n", eglGetError()); printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
o->egl_window_native = (EGLNativeWindowType)wl_egl_window_create( o->egl_window_native = (EGLNativeWindowType)wl_egl_window_create(
handle->lowlevel->wayland.framebuffer.surface, handle->lowlevel->wayland.framebuffer.surface,
handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh); handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh);
if (!o->egl_window_native) { if(!o->egl_window_native) {
printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n"); printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n");
return MwFALSE; return MwFALSE;
} }
/* Create a surface */ /* Create a surface */
surface = eglCreateWindowSurface(display, o->egl_config, surface = eglCreateWindowSurface(display, o->egl_config,
o->egl_window_native, NULL); o->egl_window_native, NULL);
if (surface == EGL_NO_SURFACE) { if(surface == EGL_NO_SURFACE) {
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError()); printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
eglBindAPI(EGL_OPENGL_API); eglBindAPI(EGL_OPENGL_API);
/* Create a GL context */ /* Create a GL context */
context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT, context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT,
contextAttribs); contextAttribs);
if (context == EGL_NO_CONTEXT) { if(context == EGL_NO_CONTEXT) {
printf("ERROR: eglCreateContext, %0X\n", eglGetError()); printf("ERROR: eglCreateContext, %0X\n", eglGetError());
return MwFALSE; return MwFALSE;
} }
if (!eglMakeCurrent(display, surface, surface, context)) { if(!eglMakeCurrent(display, surface, surface, context)) {
printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError()); printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError());
} }
o->egl_display = display; o->egl_display = display;
o->egl_surface = surface; o->egl_surface = surface;
o->egl_context = context; o->egl_context = context;
} }
#endif #endif
handle->internal = r; handle->internal = r;
handle->lowlevel->common.copy_buffer = 0; handle->lowlevel->common.copy_buffer = 0;
MwSetDefault(handle); MwSetDefault(handle);
while (w->parent != NULL) while(w->parent != NULL)
w = w->parent; w = w->parent;
w->berserk++; w->berserk++;
return 0; return 0;
} }
static void destroy(MwWidget handle) { static void destroy(MwWidget handle) {
MwWidget w = handle; MwWidget w = handle;
#ifdef USE_GDI #ifdef USE_GDI
if (handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
gdiopengl_t *o = handle->internal; gdiopengl_t* o = handle->internal;
o->wglMakeCurrent(NULL, NULL); o->wglMakeCurrent(NULL, NULL);
DeleteDC(o->dc); DeleteDC(o->dc);
o->wglDeleteContext(o->gl); o->wglDeleteContext(o->gl);
MwDynamicClose(o->lib); MwDynamicClose(o->lib);
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if (handle->lowlevel->common.type == MwLLBackendX11) { if(handle->lowlevel->common.type == MwLLBackendX11) {
x11opengl_t *o = handle->internal; x11opengl_t* o = handle->internal;
o->glXMakeCurrent(handle->lowlevel->x11.display, None, NULL); o->glXMakeCurrent(handle->lowlevel->x11.display, None, NULL);
o->glXDestroyContext(handle->lowlevel->x11.display, o->gl); o->glXDestroyContext(handle->lowlevel->x11.display, o->gl);
MwDynamicClose(o->lib); MwDynamicClose(o->lib);
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if (handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
/* todo */ /* todo */
} }
#endif #endif
while (w->parent != NULL) while(w->parent != NULL)
w = w->parent; w = w->parent;
w->berserk--; w->berserk--;
free(handle->internal); free(handle->internal);
} }
static void mwOpenGLMakeCurrentImpl(MwWidget handle) { static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
/* these swap interval functions belonging here actually stink! */ /* these swap interval functions belonging here actually stink! */
#ifdef USE_GDI #ifdef USE_GDI
if (handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
gdiopengl_t *o = handle->internal; gdiopengl_t* o = handle->internal;
void (*swap_interval_ext)(int) = NULL; void (*swap_interval_ext)(int) = NULL;
o->wglMakeCurrent(o->dc, o->gl); o->wglMakeCurrent(o->dc, o->gl);
if ((swap_interval_ext = if((swap_interval_ext =
MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) { MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) {
swap_interval_ext(1); swap_interval_ext(1);
} }
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if (handle->lowlevel->common.type == MwLLBackendX11) { 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_ext)(Display*, GLXDrawable, int) = NULL;
void (*swap_interval_mesa)(unsigned int) = NULL; void (*swap_interval_mesa)(unsigned int) = NULL;
void (*swap_interval_sgi)(int) = NULL; void (*swap_interval_sgi)(int) = NULL;
o->glXMakeCurrent(handle->lowlevel->x11.display, o->glXMakeCurrent(handle->lowlevel->x11.display,
handle->lowlevel->x11.window, o->gl); handle->lowlevel->x11.window, o->gl);
if ((swap_interval_ext = if((swap_interval_ext =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) { MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) {
swap_interval_ext(handle->lowlevel->x11.display, swap_interval_ext(handle->lowlevel->x11.display,
handle->lowlevel->x11.window, 1); handle->lowlevel->x11.window, 1);
} }
if ((swap_interval_mesa = if((swap_interval_mesa =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) { MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) {
swap_interval_mesa(1); swap_interval_mesa(1);
} }
if ((swap_interval_sgi = if((swap_interval_sgi =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) { MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) {
swap_interval_sgi(1); swap_interval_sgi(1);
} }
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if (handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
waylandopengl_t *o = handle->internal; waylandopengl_t* o = handle->internal;
if (!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface, if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface,
o->egl_context)) { o->egl_context)) {
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
} }
eglSwapInterval(o->egl_display, 1); eglSwapInterval(o->egl_display, 1);
} }
#endif #endif
} }
static void mwOpenGLSwapBufferImpl(MwWidget handle) { static void mwOpenGLSwapBufferImpl(MwWidget handle) {
#ifdef USE_GDI #ifdef USE_GDI
if (handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
gdiopengl_t *o = handle->internal; gdiopengl_t* o = handle->internal;
SwapBuffers(o->dc); SwapBuffers(o->dc);
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if (handle->lowlevel->common.type == MwLLBackendX11) { if(handle->lowlevel->common.type == MwLLBackendX11) {
x11opengl_t *o = handle->internal; x11opengl_t* o = handle->internal;
o->glXSwapBuffers(handle->lowlevel->x11.display, o->glXSwapBuffers(handle->lowlevel->x11.display,
handle->lowlevel->x11.window); handle->lowlevel->x11.window);
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if (handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
waylandopengl_t *o = handle->internal; waylandopengl_t* o = handle->internal;
eglSwapInterval(o->egl_display, 0); // eglSwapInterval(o->egl_display, 0);
if (!eglSwapBuffers(o->egl_display, o->egl_surface)) { if(!eglSwapBuffers(o->egl_display, o->egl_surface)) {
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError()); printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
}; };
wl_egl_window_resize((struct wl_egl_window *)o->egl_window_native, wl_egl_window_resize((struct wl_egl_window*)o->egl_window_native,
handle->lowlevel->wayland.ww, handle->lowlevel->wayland.ww,
handle->lowlevel->wayland.wh, 0, 0); handle->lowlevel->wayland.wh, 0, 0);
MwLLForceRender(handle->lowlevel); // MwLLForceRender(handle->lowlevel);
} }
#endif #endif
} }
static void *mwOpenGLGetProcAddressImpl(MwWidget handle, const char *name) { static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) {
#ifdef USE_GDI #ifdef USE_GDI
if (handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
gdiopengl_t *o = handle->internal; gdiopengl_t* o = handle->internal;
return o->wglGetProcAddress(name); return o->wglGetProcAddress(name);
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if (handle->lowlevel->common.type == MwLLBackendX11) { if(handle->lowlevel->common.type == MwLLBackendX11) {
x11opengl_t *o = handle->internal; x11opengl_t* o = handle->internal;
return o->glXGetProcAddress((const GLubyte *)name); return o->glXGetProcAddress((const GLubyte*)name);
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if (handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
return eglGetProcAddress(name); return eglGetProcAddress(name);
} }
#endif #endif
return NULL; return NULL;
} }
static void func_handler(MwWidget handle, const char *name, void *out, static void func_handler(MwWidget handle, const char* name, void* out,
va_list va) { va_list va) {
if (strcmp(name, "mwOpenGLMakeCurrent") == 0) { if(strcmp(name, "mwOpenGLMakeCurrent") == 0) {
mwOpenGLMakeCurrentImpl(handle); mwOpenGLMakeCurrentImpl(handle);
} }
if (strcmp(name, "mwOpenGLSwapBuffer") == 0) { if(strcmp(name, "mwOpenGLSwapBuffer") == 0) {
mwOpenGLSwapBufferImpl(handle); mwOpenGLSwapBufferImpl(handle);
} }
if (strcmp(name, "mwOpenGLGetProcAddress") == 0) { if(strcmp(name, "mwOpenGLGetProcAddress") == 0) {
const char *_name = va_arg(va, const char *); const char* _name = va_arg(va, const char*);
*(void **)out = mwOpenGLGetProcAddressImpl(handle, _name); *(void**)out = mwOpenGLGetProcAddressImpl(handle, _name);
} }
} }
MwClassRec MwOpenGLClassRec = {create, /* create */ MwClassRec MwOpenGLClassRec = {create, /* create */
destroy, /* destroy */ destroy, /* destroy */
NULL, /* draw */ NULL, /* draw */
NULL, /* click */ NULL, /* click */
NULL, /* parent_resize */ NULL, /* parent_resize */
NULL, /* prop_change */ NULL, /* prop_change */
NULL, /* mouse_move */ NULL, /* mouse_move */
NULL, /* mouse_up */ NULL, /* mouse_up */
NULL, /* mouse_down */ NULL, /* mouse_down */
NULL, /* key */ NULL, /* key */
func_handler, /* execute */ func_handler, /* execute */
NULL, /* tick */ NULL, /* tick */
NULL, /* resize */ NULL, /* resize */
NULL, /* children_update */ NULL, /* children_update */
NULL, /* children_prop_change */ NULL, /* children_prop_change */
NULL, /* clipboard */ NULL, /* clipboard */
NULL, NULL, NULL, NULL}; NULL, NULL, NULL, NULL};
MwClass MwOpenGLClass = &MwOpenGLClassRec; MwClass MwOpenGLClass = &MwOpenGLClassRec;
#endif #endif