diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index a3b5ad0..5da10ae 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -103,6 +103,7 @@ struct _MwLLWayland { MwLL parent; MwLL topmost_parent; MwBool draw_recursively; + MwBool no_viewport; GLuint fbo; unsigned int fbo_texture; diff --git a/src/backend/wayland.c b/src/backend/wayland.c index ee2770f..b87eea4 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -288,7 +288,7 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _ return proto; } -static MwBool egl_setup(MwLL self, int width, int height) { +static MwBool egl_setup(MwLL self, int x, int y, int width, int height) { int err; EGLint numConfigs; EGLint majorVersion; @@ -367,28 +367,18 @@ static MwBool egl_setup(MwLL self, int width, int height) { } } - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); + glViewport(x, y, width, height); return MwTRUE; } static void egl_resetup(MwLL handle) { int err; - - // if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) { - // printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); - // return; - // } - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, handle->wayland.ww, handle->wayland.wh, 0, -1, 1); - glViewport(0, 0, handle->wayland.ww, handle->wayland.wh); + glViewport(handle->wayland.x, handle->wayland.y, handle->wayland.ww, handle->wayland.wh); + glScissor(handle->wayland.x, handle->wayland.y, handle->wayland.ww, handle->wayland.wh); } static void recursive_draw(MwLL handle) { @@ -442,7 +432,7 @@ static void xdg_toplevel_configure(void* data, MwLLDispatch(self, resize, NULL); if(!self->wayland.egl_setup) { - self->wayland.egl_setup = egl_setup(self, width, height); + self->wayland.egl_setup = egl_setup(self, self->wayland.x, self->wayland.y, width, height); } else { wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0); egl_resetup(self); @@ -532,6 +522,7 @@ static int event_loop(MwLL handle) { if(wayland->resize_counter >= 5) { wayland->lw = wayland->ww; wayland->lh = wayland->wh; + wayland->lh = wayland->wh; wayland->resize_counter = 0; } } @@ -685,7 +676,7 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { r->wayland.configured = MwTRUE; if(!r->wayland.egl_setup) { - r->wayland.egl_setup = egl_setup(r, r->wayland.ww, r->wayland.wh); + r->wayland.egl_setup = egl_setup(r, r->wayland.x, r->wayland.y, r->wayland.ww, r->wayland.wh); egl_resetup(r); MwLLDispatch(r, draw, NULL); recursive_draw(r); @@ -733,6 +724,9 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->wayland.force_redraw = MwFALSE; r->wayland.subwidgets = NULL; r->wayland.pointer = NULL; + + r->wayland.no_viewport = MwTRUE; + if(parent == NULL) { setup_toplevel(r, x, y); } else { @@ -760,7 +754,7 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { handle->wayland.x = x; handle->wayland.y = y; if(handle->wayland.has_set_xy) { - timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); + timed_redraw_by_epoch(handle->wayland.topmost_parent, 15); recursive_draw(handle->wayland.topmost_parent); } else if(x != 0 && y != 0) { handle->wayland.has_set_xy = MwTRUE; @@ -781,7 +775,7 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh); } else { - timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); + timed_redraw_by_epoch(handle->wayland.topmost_parent, 15); recursive_draw(handle->wayland.topmost_parent); } } @@ -790,14 +784,23 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL int i, n; float maxX = 0, maxY = 0; float centerX, centerY; + float w, h; + + if(handle->wayland.parent == NULL) { + w = handle->wayland.ww; + h = handle->wayland.wh; + } else { + w = handle->wayland.parent->wayland.ww; + h = handle->wayland.parent->wayland.wh; + } glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); glBegin(GL_POLYGON); for(i = 0; i < points_count; i++) { - float x = round(handle->wayland.x) + round(points[i].x); - float y = round(handle->wayland.y) + round(points[i].y); + float x = ((float)(handle->wayland.x + points[i].x) / (w / 2)) - 1.0; + float y = 1.0 - ((float)(handle->wayland.y + points[i].y) / (h / 2)); glVertex2f(x, y); } @@ -806,15 +809,24 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; + int i; + float w, h; + + if(handle->wayland.parent == NULL) { + w = handle->wayland.ww; + h = handle->wayland.wh; + } else { + w = handle->wayland.parent->wayland.ww; + h = handle->wayland.parent->wayland.wh; + } glLineWidth(1); glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); glBegin(GL_LINES); for(i = 0; i < 2; i++) { - float x = round(handle->wayland.x) + round(points[i].x); - float y = round(handle->wayland.y) + round(points[i].y); + float x = ((float)(handle->wayland.x + points[i].x) / (w / 2)) - 1.0; + float y = 1.0 - ((float)(handle->wayland.y + points[i].y) / (h / 2)); glVertex2f(x, y); } @@ -823,6 +835,7 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { } static void MwLLBeginDrawImpl(MwLL handle) { + egl_resetup(handle); if(handle->wayland.parent == NULL) { if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) { printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); @@ -836,15 +849,6 @@ static void MwLLBeginDrawImpl(MwLL handle) { static void MwLLEndDrawImpl(MwLL handle) { int w, h; - if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { - w = handle->wayland.ww; - h = handle->wayland.wh; - } else { - MwLL parent = handle->wayland.parent; - w = parent->wayland.ww; - h = parent->wayland.wh; - } - recursive_draw(handle); // glClear(GL_COLOR_BUFFER_BIT); @@ -933,11 +937,20 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - int x, y; - glColor3f(1.0, 1.0, 1.0); + float x, y, w, h; - x = handle->wayland.x + rect->x; - y = handle->wayland.y + rect->y; + if(handle->wayland.parent == NULL) { + w = handle->wayland.ww; + h = handle->wayland.wh; + } else { + w = handle->wayland.parent->wayland.ww; + h = handle->wayland.parent->wayland.wh; + } + + x = ((float)(handle->wayland.x + rect->x) / (w / 2)) - 1.0; + y = 1.0 - ((float)(handle->wayland.y + rect->y) / (h / 2)); + + glColor3f(1.0, 1.0, 1.0); glBindTexture(GL_TEXTURE_2D, pixmap->wayland.texture); glActiveTexture(pixmap->wayland.texture); @@ -946,11 +959,11 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { glTexCoord2f(0.0f, 0); glVertex2f(x, y); glTexCoord2f(1, 0); - glVertex2f(x + rect->width, y); + glVertex2f(x + (rect->width / (w / 2)), y); glTexCoord2f(1, 1); - glVertex2f(x + rect->width, y + rect->height); + glVertex2f(x + (rect->width / (w / 2)), y - (rect->height / (h / 2))); glTexCoord2f(0.0f, 1); - glVertex2f(x, y + rect->height); + glVertex2f(x, y - (rect->height / (h / 2))); glEnd(); glFinish(); } diff --git a/src/widget/opengl.c b/src/widget/opengl.c index 05257e3..1e07ddd 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -1,6 +1,12 @@ #include #include +#ifdef USE_WAYLAND +#include +#include +#include +#endif + #ifdef USE_GDI typedef HGLRC(WINAPI* MWwglCreateContext)(HDC); typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC); @@ -89,8 +95,7 @@ static int create(MwWidget handle) { attribs[3] = 24; attribs[4] = None; - while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL) - ; + while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL); o->glXChooseVisual = (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual"); o->glXCreateContext = (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext"); @@ -104,6 +109,13 @@ static int create(MwWidget handle) { o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL, GL_TRUE); } #endif +#ifdef USE_WAYLAND + /* Wayland uses OpenGL as its backend so its already initialized */ + if(handle->lowlevel->common.type == MwLLBackendWayland) { + handle->lowlevel->wayland.no_viewport = MwTRUE; + } +#endif + handle->internal = r; handle->lowlevel->common.copy_buffer = 0; @@ -134,6 +146,10 @@ static void destroy(MwWidget handle) { MwDynamicClose(o->lib); } #endif +#ifdef USE_WAYLAND +/* Wayland uses OpenGL as its backend so its destroyed accordingly */ +#endif + free(handle->internal); } @@ -152,6 +168,10 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) { o->glXMakeCurrent(handle->lowlevel->x11.display, handle->lowlevel->x11.window, o->gl); } #endif +#ifdef USE_WAYLAND + if(handle->lowlevel->common.type == MwLLBackendWayland) { + } +#endif } static void mwOpenGLSwapBufferImpl(MwWidget handle) { @@ -169,6 +189,16 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) { o->glXSwapBuffers(handle->lowlevel->x11.display, handle->lowlevel->x11.window); } #endif +#ifdef USE_WAYLAND +#define tp handle->lowlevel->wayland.topmost_parent->wayland + if(handle->lowlevel->common.type == MwLLBackendWayland) { + if(!eglSwapBuffers( + tp.egl_display, tp.egl_surface)) { + printf("Userland error: eglSwapBuffers, %0X\n", eglGetError()); + } + } +#undef topmost_parent +#endif } static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) { @@ -185,6 +215,11 @@ static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) { return o->glXGetProcAddress((const GLubyte*)name); } +#endif +#ifdef USE_WAYLAND + if(handle->lowlevel->common.type == MwLLBackendWayland) { + return eglGetProcAddress(name); + } #endif return NULL; }