wayland resize
This commit is contained in:
parent
39f44a56e3
commit
d4d4835fd1
2 changed files with 207 additions and 85 deletions
|
|
@ -41,6 +41,7 @@ struct _MwLLWaylandTopLevel {
|
||||||
struct xdg_toplevel* xdg_top_level;
|
struct xdg_toplevel* xdg_top_level;
|
||||||
struct xdg_toplevel_listener xdg_toplevel_listener;
|
struct xdg_toplevel_listener xdg_toplevel_listener;
|
||||||
struct xdg_surface_listener xdg_surface_listener;
|
struct xdg_surface_listener xdg_surface_listener;
|
||||||
|
struct wl_surface_listener surface_listener;
|
||||||
|
|
||||||
struct xkb_context* xkb_context;
|
struct xkb_context* xkb_context;
|
||||||
|
|
||||||
|
|
@ -81,7 +82,8 @@ struct _MwLLWayland {
|
||||||
|
|
||||||
MwBool configured;
|
MwBool configured;
|
||||||
MwBool force_redraw;
|
MwBool force_redraw;
|
||||||
MwBool do_clear;
|
MwBool egl_setup;
|
||||||
|
MwBool egl_do_resetup;
|
||||||
MwU32 x, y, ww, wh;
|
MwU32 x, y, ww, wh;
|
||||||
int z_index;
|
int z_index;
|
||||||
|
|
||||||
|
|
@ -89,15 +91,12 @@ struct _MwLLWayland {
|
||||||
|
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
unsigned int fbo_texture;
|
unsigned int fbo_texture;
|
||||||
unsigned int rbo;
|
|
||||||
|
|
||||||
MwBool egl_setup;
|
|
||||||
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;
|
||||||
GLuint vertex_buffer;
|
EGLConfig egl_config;
|
||||||
GLuint vertex_array;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLWaylandColor {
|
struct _MwLLWaylandColor {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,12 @@ PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
||||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||||
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus;
|
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus;
|
||||||
|
|
||||||
|
EGLint contextAttribs[] = {
|
||||||
|
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||||
|
EGL_CONTEXT_MAJOR_VERSION, 1,
|
||||||
|
EGL_CONTEXT_MINOR_VERSION, 1,
|
||||||
|
EGL_NONE};
|
||||||
|
|
||||||
#define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name)
|
#define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name)
|
||||||
|
|
||||||
static void new_protocol(void* data, struct wl_registry* registry,
|
static void new_protocol(void* data, struct wl_registry* registry,
|
||||||
|
|
@ -52,6 +58,19 @@ static void protocol_removed(void* data,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void surface_enter(void* data,
|
||||||
|
struct wl_surface* wl_surface,
|
||||||
|
struct wl_output* output) {
|
||||||
|
MwLL self = data;
|
||||||
|
|
||||||
|
printf("yhdhfgh\n");
|
||||||
|
};
|
||||||
|
static void surface_leave(void* data,
|
||||||
|
struct wl_surface* wl_surface,
|
||||||
|
struct wl_output* output) {
|
||||||
|
printf("yhdhfgh\n");
|
||||||
|
};
|
||||||
|
|
||||||
static void wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {};
|
static void wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {};
|
||||||
static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
||||||
MwU32 capabilities) {};
|
MwU32 capabilities) {};
|
||||||
|
|
@ -64,13 +83,6 @@ void xdg_wm_base_ping(void* data,
|
||||||
xdg_wm_base_pong(xdg_wm_base, serial);
|
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||||
};
|
};
|
||||||
|
|
||||||
static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
|
||||||
wayland->shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// static void buffer_setup(struct _MwLLWayland* wayland) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
static wayland_protocol_t* wl_seat_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
static wayland_protocol_t* wl_seat_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
||||||
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
||||||
proto->listener = malloc(sizeof(struct wl_seat_listener));
|
proto->listener = malloc(sizeof(struct wl_seat_listener));
|
||||||
|
|
@ -143,7 +155,6 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
EGLint minorVersion;
|
EGLint minorVersion;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
EGLConfig config;
|
|
||||||
EGLint fbAttribs[] =
|
EGLint fbAttribs[] =
|
||||||
{
|
{
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
|
@ -153,11 +164,6 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
EGL_BLUE_SIZE, 8,
|
EGL_BLUE_SIZE, 8,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||||
EGL_NONE};
|
EGL_NONE};
|
||||||
EGLint contextAttribs[] = {
|
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
|
||||||
EGL_CONTEXT_MAJOR_VERSION, 1,
|
|
||||||
EGL_CONTEXT_MINOR_VERSION, 1,
|
|
||||||
EGL_NONE};
|
|
||||||
|
|
||||||
EGLDisplay display = eglGetDisplay(self->wayland.display);
|
EGLDisplay display = eglGetDisplay(self->wayland.display);
|
||||||
if(display == EGL_NO_DISPLAY) {
|
if(display == EGL_NO_DISPLAY) {
|
||||||
|
|
@ -178,7 +184,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose config
|
// Choose config
|
||||||
if((eglChooseConfig(display, fbAttribs, &config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
if((eglChooseConfig(display, fbAttribs, &self->wayland.egl_config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
||||||
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
||||||
return MwFALSE;
|
return MwFALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +197,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a surface
|
// Create a surface
|
||||||
surface = eglCreateWindowSurface(display, config, self->wayland.egl_window_native, NULL);
|
surface = eglCreateWindowSurface(display, self->wayland.egl_config, self->wayland.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;
|
||||||
|
|
@ -200,7 +206,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
eglBindAPI(EGL_OPENGL_API);
|
eglBindAPI(EGL_OPENGL_API);
|
||||||
|
|
||||||
// Create a GL context
|
// Create a GL context
|
||||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
context = eglCreateContext(display, self->wayland.egl_config, EGL_NO_CONTEXT, 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;
|
||||||
|
|
@ -226,24 +232,15 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
glGenRenderbuffers(1, &self->wayland.rbo);
|
|
||||||
// glBindRenderbuffer(GL_RENDERBUFFER, self->wayland.rbo));
|
|
||||||
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 768, 1024);
|
|
||||||
// glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
||||||
|
|
||||||
glGenFramebuffers(1, &self->wayland.fbo);
|
glGenFramebuffers(1, &self->wayland.fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, self->wayland.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, self->wayland.fbo);
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->wayland.fbo_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->wayland.fbo_texture, 0);
|
||||||
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self->wayland.rbo);
|
|
||||||
|
|
||||||
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
printf("Error binding framebuffer: %0X\n", err);
|
printf("Error binding framebuffer: %0X\n", err);
|
||||||
return MwFALSE;
|
return MwFALSE;
|
||||||
|
|
@ -263,6 +260,66 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
||||||
return MwTRUE;
|
return MwTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void egl_resetup(MwLL handle) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if(!handle->wayland.egl_do_resetup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!eglMakeCurrent(handle->wayland.egl_display, 0, 0, handle->wayland.egl_context)) {
|
||||||
|
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!eglDestroySurface(handle->wayland.egl_display, handle->wayland.egl_surface)) {
|
||||||
|
printf("ERROR: eglDestroySurface, %0X\n", eglGetError());
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
handle->wayland.egl_surface = eglCreateWindowSurface(handle->wayland.egl_display, handle->wayland.egl_config, handle->wayland.egl_window_native, NULL);
|
||||||
|
if(handle->wayland.egl_surface == EGL_NO_SURFACE) {
|
||||||
|
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteTextures(1, &handle->wayland.fbo_texture);
|
||||||
|
glGenTextures(1, &handle->wayland.fbo_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
||||||
|
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, handle->wayland.ww, handle->wayland.wh, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &handle->wayland.fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, handle->wayland.fbo);
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||||
|
|
||||||
|
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
printf("Error binding framebuffer: %0X\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, handle->wayland.ww, handle->wayland.wh, 0, -1, 1);
|
||||||
|
glViewport(0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||||
|
|
||||||
|
handle->wayland.egl_do_resetup = MwFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_configure(void* data,
|
static void xdg_toplevel_configure(void* data,
|
||||||
struct xdg_toplevel* xdg_toplevel,
|
struct xdg_toplevel* xdg_toplevel,
|
||||||
MwI32 width, MwI32 height,
|
MwI32 width, MwI32 height,
|
||||||
|
|
@ -284,26 +341,12 @@ static void xdg_toplevel_configure(void* data,
|
||||||
if(!self->wayland.egl_setup) {
|
if(!self->wayland.egl_setup) {
|
||||||
self->wayland.egl_setup = egl_setup(self, width, height);
|
self->wayland.egl_setup = egl_setup(self, width, height);
|
||||||
MwLLForceRender(self);
|
MwLLForceRender(self);
|
||||||
} else {
|
|
||||||
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0, width, height, 0, -1, 1);
|
|
||||||
self->wayland.do_clear = MwTRUE;
|
|
||||||
|
|
||||||
// glDeleteTextures(1, &self->wayland.fbo_texture);
|
|
||||||
// glGenTextures(1, &self->wayland.fbo_texture);
|
|
||||||
// glBindTexture(GL_TEXTURE_2D, self->wayland.fbo_texture);
|
|
||||||
|
|
||||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
|
||||||
|
|
||||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
||||||
|
self->wayland.egl_do_resetup = MwTRUE;
|
||||||
|
egl_resetup(self);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -416,7 +459,6 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
||||||
wayland->wl_protocol_setup_map = NULL;
|
wayland->wl_protocol_setup_map = NULL;
|
||||||
wayland->wl_protocol_map = NULL;
|
wayland->wl_protocol_map = NULL;
|
||||||
|
|
||||||
WL_INTERFACE(wl_shm);
|
|
||||||
WL_INTERFACE(wl_compositor);
|
WL_INTERFACE(wl_compositor);
|
||||||
WL_INTERFACE(wl_subcompositor);
|
WL_INTERFACE(wl_subcompositor);
|
||||||
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
|
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
|
||||||
|
|
@ -429,8 +471,9 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
||||||
|
|
||||||
#undef WL_INTERFACE
|
#undef WL_INTERFACE
|
||||||
|
|
||||||
static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
static void setup_toplevel(MwLL r, int x, int y) {
|
||||||
int i;
|
int i;
|
||||||
|
struct wl_region* region;
|
||||||
|
|
||||||
r->wayland.type = MWLL_WAYLAND_TOPLEVEL;
|
r->wayland.type = MWLL_WAYLAND_TOPLEVEL;
|
||||||
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
|
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
|
||||||
|
|
@ -484,20 +527,29 @@ static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
||||||
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
||||||
|
|
||||||
// setup mandatory listeners
|
// setup mandatory listeners
|
||||||
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
||||||
|
|
||||||
|
r->wayland.toplevel->surface_listener.enter = surface_enter;
|
||||||
|
r->wayland.toplevel->surface_listener.leave = surface_leave;
|
||||||
|
|
||||||
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
||||||
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
||||||
|
|
||||||
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
||||||
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
||||||
r);
|
r);
|
||||||
|
wl_surface_add_listener(r->wayland.surface, &r->wayland.toplevel->surface_listener, r);
|
||||||
|
|
||||||
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko Wayland App");
|
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko Wayland App");
|
||||||
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
||||||
|
|
||||||
// Perform the initial commit and wait for the first configure event
|
// Perform the initial commit and wait for the first configure event
|
||||||
|
region = wl_compositor_create_region(r->wayland.compositor);
|
||||||
|
wl_region_add(region, 0, 0, r->wayland.ww, r->wayland.wh);
|
||||||
|
wl_surface_set_opaque_region(r->wayland.surface, region);
|
||||||
wl_surface_commit(r->wayland.surface);
|
wl_surface_commit(r->wayland.surface);
|
||||||
event_loop(&r->wayland);
|
event_loop(&r->wayland);
|
||||||
|
wl_region_destroy(region);
|
||||||
|
|
||||||
printf("%p\n", shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name));
|
printf("%p\n", shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name));
|
||||||
|
|
||||||
|
|
@ -516,21 +568,33 @@ static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
||||||
|
|
||||||
// buffer_setup(&r->wayland);
|
// buffer_setup(&r->wayland);
|
||||||
|
|
||||||
wl_surface_commit(r->wayland.surface);
|
|
||||||
|
|
||||||
// glGenBuffers(1, &vertex_buffer);
|
// glGenBuffers(1, &vertex_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int height) {
|
static void setup_subsurface(MwLL parent, MwLL r, int x, int y) {
|
||||||
struct wl_compositor* compositor = parent->wayland.compositor;
|
struct wl_compositor* compositor = parent->wayland.compositor;
|
||||||
struct wl_subcompositor* subcompositor = parent->wayland.subcompositor;
|
struct wl_subcompositor* subcompositor = parent->wayland.subcompositor;
|
||||||
struct wl_surface* parent_surface = parent->wayland.surface;
|
struct wl_surface* parent_surface = parent->wayland.surface;
|
||||||
|
MwLL topmost_parent = parent;
|
||||||
|
struct wl_region* region;
|
||||||
|
|
||||||
|
while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||||
|
topmost_parent = topmost_parent->wayland.parent;
|
||||||
|
}
|
||||||
|
|
||||||
r->wayland.type = MWLL_WAYLAND_SUBSURFACE;
|
r->wayland.type = MWLL_WAYLAND_SUBSURFACE;
|
||||||
|
|
||||||
r->wayland.display = parent->wayland.display;
|
r->wayland.display = parent->wayland.display;
|
||||||
|
|
||||||
r->wayland.surface = wl_compositor_create_surface(compositor);
|
r->wayland.surface = wl_compositor_create_surface(compositor);
|
||||||
|
wl_surface_add_listener(r->wayland.surface, &topmost_parent->wayland.toplevel->surface_listener, r);
|
||||||
|
|
||||||
|
region = wl_compositor_create_region(compositor);
|
||||||
|
wl_region_add(region, 0, 0, r->wayland.ww, r->wayland.wh);
|
||||||
|
wl_surface_set_opaque_region(r->wayland.surface, region);
|
||||||
|
wl_surface_commit(r->wayland.surface);
|
||||||
|
event_loop(&r->wayland);
|
||||||
|
wl_region_destroy(region);
|
||||||
|
|
||||||
r->wayland.subsurface = wl_subcompositor_get_subsurface(subcompositor, r->wayland.surface, parent_surface);
|
r->wayland.subsurface = wl_subcompositor_get_subsurface(subcompositor, r->wayland.surface, parent_surface);
|
||||||
|
|
||||||
|
|
@ -540,8 +604,8 @@ static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int h
|
||||||
|
|
||||||
setup_callbacks(&r->wayland);
|
setup_callbacks(&r->wayland);
|
||||||
|
|
||||||
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
|
r->wayland.registry = wl_display_get_registry(topmost_parent->wayland.display);
|
||||||
r->wayland.display = parent->wayland.display;
|
r->wayland.display = topmost_parent->wayland.display;
|
||||||
|
|
||||||
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
||||||
if(wl_display_roundtrip(r->wayland.display) == -1) {
|
if(wl_display_roundtrip(r->wayland.display) == -1) {
|
||||||
|
|
@ -554,13 +618,24 @@ static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int h
|
||||||
|
|
||||||
r->wayland.configured = MwTRUE;
|
r->wayland.configured = MwTRUE;
|
||||||
|
|
||||||
r->wayland.egl_context = parent->wayland.egl_context;
|
r->wayland.egl_context = topmost_parent->wayland.egl_context;
|
||||||
r->wayland.egl_display = parent->wayland.egl_display;
|
r->wayland.egl_display = topmost_parent->wayland.egl_display;
|
||||||
r->wayland.egl_surface = parent->wayland.egl_surface;
|
r->wayland.egl_surface = topmost_parent->wayland.egl_surface;
|
||||||
r->wayland.fbo = parent->wayland.fbo;
|
r->wayland.fbo = topmost_parent->wayland.fbo;
|
||||||
r->wayland.fbo_texture = parent->wayland.fbo_texture;
|
r->wayland.fbo_texture = topmost_parent->wayland.fbo_texture;
|
||||||
r->wayland.rbo = parent->wayland.rbo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void framebuffer_action_begin(MwLL handle) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, handle->wayland.fbo);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void framebuffer_action_end(MwLL handle) {
|
||||||
|
glFinish();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||||
MwLL r;
|
MwLL r;
|
||||||
r = malloc(sizeof(*r));
|
r = malloc(sizeof(*r));
|
||||||
|
|
@ -576,13 +651,12 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||||
r->wayland.parent = parent;
|
r->wayland.parent = parent;
|
||||||
|
|
||||||
r->wayland.force_redraw = MwFALSE;
|
r->wayland.force_redraw = MwFALSE;
|
||||||
r->wayland.do_clear = MwFALSE;
|
|
||||||
r->common.success = MwTRUE;
|
r->common.success = MwTRUE;
|
||||||
|
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
setup_toplevel(r, x, y, width, height);
|
setup_toplevel(r, x, y);
|
||||||
} else {
|
} else {
|
||||||
setup_subsurface(parent, r, x, y, width, height);
|
setup_subsurface(parent, r, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -611,6 +685,10 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||||
|
/* Prevent an integer underflow when the w/h is too low */
|
||||||
|
if(w < 10 || h < 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handle->wayland.ww = w;
|
handle->wayland.ww = w;
|
||||||
handle->wayland.wh = h;
|
handle->wayland.wh = h;
|
||||||
|
|
||||||
|
|
@ -621,29 +699,74 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||||
int i;
|
int i, n;
|
||||||
|
float maxX = 0, maxY = 0;
|
||||||
|
float centerX, centerY;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
if(points_count > 3) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, handle->wayland.fbo);
|
/* To avoid having to do a real triangulation algorithim:
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
1.) loop through the points once to determine the bounds of the polygon
|
||||||
|
2.) calculate the center of the polygon
|
||||||
|
|
||||||
if(points_count == 3) {
|
*/
|
||||||
glBegin(GL_TRIANGLES);
|
for(i = 0; i < points_count; i++) {
|
||||||
} else if(points_count == 4) {
|
float x = round(handle->wayland.x) + round(points[i].x);
|
||||||
glBegin(GL_QUADS);
|
float y = round(handle->wayland.y) + round(points[i].y);
|
||||||
} else {
|
if(x >= maxX) {
|
||||||
glBegin(GL_QUAD_STRIP);
|
maxX = x;
|
||||||
|
}
|
||||||
|
if(y >= maxY) {
|
||||||
|
maxY = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
centerX = (handle->wayland.x + maxX / 2);
|
||||||
|
centerY = (handle->wayland.y + maxY / 2);
|
||||||
|
|
||||||
|
/* Efficient? No. But at the end of the day it's still not that many polygons, and if a computer can't handle 12 polygons over 6 then it should not be using Wayland anyways */
|
||||||
|
|
||||||
|
framebuffer_action_begin(handle);
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
for(i = 0; i < points_count; i++) {
|
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);
|
||||||
|
|
||||||
glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0);
|
glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0);
|
||||||
glVertex2f(
|
|
||||||
ceil(handle->wayland.x) + ceil(points[i].x),
|
/* If we have a polygon that's covering the whole screen, we want to do glClear
|
||||||
ceil(handle->wayland.y) + ceil(points[i].y));
|
*/
|
||||||
|
if(x == 0 && y == 0) {
|
||||||
|
/*
|
||||||
|
We determine this by checking if all of the points are at the edge of the screen (and if there's more then 6 points).
|
||||||
|
Not a pretty solution, but unless the user does something weird like draw a triangle over itself twice, I'm pretty sure this is effective.
|
||||||
|
*/
|
||||||
|
if(points_count >= 6) {
|
||||||
|
MwBool doClear = MwTRUE;
|
||||||
|
for(n = 0; n < points_count; n++) {
|
||||||
|
if((points[n].x >= (handle->wayland.ww) - 1 || points[n].x <= 1) && (points[n].y >= (handle->wayland.wh) - 1 || points[n].y <= 1)) {
|
||||||
|
} else {
|
||||||
|
doClear = MwFALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(doClear) {
|
||||||
|
glEnd();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glClearColor(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1);
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glVertex2f(x, y);
|
||||||
|
if(points_count > 3) {
|
||||||
|
glVertex2f(maxX, maxY);
|
||||||
|
glVertex2f(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
glFinish();
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
framebuffer_action_end(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
||||||
|
|
@ -663,8 +786,8 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
// glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glClearColor(0, 0, 0, 1);
|
// glClearColor(0, 0, 0, 1);
|
||||||
|
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue