aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2025-04-18 15:14:31 +0200
committerdec05eba <dec05eba@protonmail.com>2025-04-18 15:14:31 +0200
commit5500ce377a0a552bfa858232f7086c197d0ab458 (patch)
tree491d9666e1535c4059b4ac37836517cf8b424867 /src
parent0e12a1d216b85c8e864cc2d7d18c3d18864542c5 (diff)
Wayland rendering now works
Diffstat (limited to 'src')
-rw-r--r--src/graphics/backend/egl.c24
-rw-r--r--src/graphics/backend/glx.c17
-rw-r--r--src/graphics/backend/graphics.c16
-rw-r--r--src/graphics/font.c2
-rw-r--r--src/mgl.c14
-rw-r--r--src/window/wayland.c404
-rw-r--r--src/window/x11.c75
7 files changed, 404 insertions, 148 deletions
diff --git a/src/graphics/backend/egl.c b/src/graphics/backend/egl.c
index f92e2fc..cabbf04 100644
--- a/src/graphics/backend/egl.c
+++ b/src/graphics/backend/egl.c
@@ -32,7 +32,7 @@ static bool xvisual_match_alpha(Display *dpy, XVisualInfo *visual_info, bool alp
return (alpha && pict_format->direct.alphaMask > 0) || (!alpha && pict_format->direct.alphaMask == 0);
}
-static bool mgl_graphics_context_choose(mgl_graphics_egl *self, mgl_context *context, bool alpha) {
+static bool mgl_graphics_egl_choose_config(mgl_graphics_egl *self, mgl_context *context, bool alpha) {
self->configs = NULL;
self->ecfg = NULL;
self->visual_info = NULL;
@@ -40,13 +40,13 @@ static bool mgl_graphics_context_choose(mgl_graphics_egl *self, mgl_context *con
int32_t num_configs = 0;
context->gl.eglGetConfigs(self->display, NULL, 0, &num_configs);
if(num_configs == 0) {
- fprintf(stderr, "mgl error: no configs found\n");
+ fprintf(stderr, "mgl error: mgl_graphics_egl_choose_config: no configs found\n");
return false;
}
self->configs = (EGLConfig*)calloc(num_configs, sizeof(EGLConfig));
if(!self->configs) {
- fprintf(stderr, "mgl error: failed to allocate %d configs\n", (int)num_configs);
+ fprintf(stderr, "mgl error: mgl_graphics_egl_choose_config: failed to allocate %d configs\n", (int)num_configs);
return false;
}
@@ -54,6 +54,9 @@ static bool mgl_graphics_context_choose(mgl_graphics_egl *self, mgl_context *con
for(int i = 0; i < num_configs; i++) {
self->ecfg = self->configs[i];
+ //if(mgl_graphics_egl_get_config_attrib(self, self->ecfg, EGL_RENDERABLE_TYPE) != EGL_OPENGL_ES2_BIT)
+ // continue;
+
if(mgl_graphics_egl_get_config_attrib(self, self->ecfg, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue;
@@ -94,14 +97,13 @@ static bool mgl_graphics_context_choose(mgl_graphics_egl *self, mgl_context *con
}
}
- if(context->window_system == MGL_WINDOW_SYSTEM_X11 && !self->visual_info) {
- if(self->configs) {
- free(self->configs);
- self->configs = NULL;
- }
- self->ecfg = NULL;
+ if(!self->ecfg) {
+ fprintf(stderr, "mgl error: mgl_graphics_egl_choose_config: no appropriate glx config found\n");
+ return false;
+ }
- fprintf(stderr, "mgl error: mgl_graphics_context_choose: no appropriate visual found\n");
+ if(context->window_system == MGL_WINDOW_SYSTEM_X11 && !self->visual_info) {
+ fprintf(stderr, "mgl error: mgl_graphics_egl_choose_config: no appropriate visual found\n");
return false;
}
@@ -188,7 +190,7 @@ bool mgl_graphics_egl_init(mgl_graphics *self) {
return false;
}
- if(!mgl_graphics_context_choose(impl, context, self->alpha)) {
+ if(!mgl_graphics_egl_choose_config(impl, context, self->alpha)) {
mgl_graphics_egl_deinit(self);
return false;
}
diff --git a/src/graphics/backend/glx.c b/src/graphics/backend/glx.c
index 548b0a0..70836e3 100644
--- a/src/graphics/backend/glx.c
+++ b/src/graphics/backend/glx.c
@@ -23,7 +23,7 @@ static bool xvisual_match_alpha(Display *dpy, XVisualInfo *visual_info, bool alp
return (alpha && pict_format->direct.alphaMask > 0) || (!alpha && pict_format->direct.alphaMask == 0);
}
-static bool mgl_graphics_glx_context_choose(mgl_graphics_glx *self, mgl_context *context, bool alpha) {
+static bool mgl_graphics_glx_choose_config(mgl_graphics_glx *self, mgl_context *context, bool alpha) {
const int attr[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
@@ -58,14 +58,13 @@ static bool mgl_graphics_glx_context_choose(mgl_graphics_glx *self, mgl_context
}
}
- if(!self->visual_info) {
- if(self->fbconfigs) {
- XFree(self->fbconfigs);
- self->fbconfigs = NULL;
- }
- self->fbconfig = NULL;
+ if(!self->fbconfig) {
+ fprintf(stderr, "mgl error: mgl_graphics_glx_choose_config: no appropriate glx config found\n");
+ return false;
+ }
- fprintf(stderr, "mgl error: no appropriate visual found\n");
+ if(!self->visual_info) {
+ fprintf(stderr, "mgl error: mgl_graphics_glx_choose_config: no appropriate visual found\n");
return false;
}
@@ -129,7 +128,7 @@ bool mgl_graphics_glx_init(mgl_graphics *self) {
self->impl = impl;
mgl_context *context = mgl_get_context();
- if(!mgl_graphics_glx_context_choose(impl, context, self->alpha)) {
+ if(!mgl_graphics_glx_choose_config(impl, context, self->alpha)) {
mgl_graphics_glx_deinit(self);
return false;
}
diff --git a/src/graphics/backend/graphics.c b/src/graphics/backend/graphics.c
index 792894e..201b9e3 100644
--- a/src/graphics/backend/graphics.c
+++ b/src/graphics/backend/graphics.c
@@ -1,6 +1,7 @@
#include "../../../include/mgl/graphics/backend/graphics.h"
#include "../../../include/mgl/graphics/backend/glx.h"
#include "../../../include/mgl/graphics/backend/egl.h"
+#include "../../../include/mgl/mgl.h"
#include <string.h>
@@ -24,7 +25,20 @@ void mgl_graphics_deinit(mgl_graphics *self) {
}
bool mgl_graphics_make_context_current(mgl_graphics *self, mgl_window_handle window) {
- return self->make_context_current(self, window);
+ const bool result = self->make_context_current(self, window);
+ if(result) {
+ mgl_context *context = mgl_get_context();
+ context->gl.glEnable(GL_TEXTURE_2D);
+ context->gl.glEnable(GL_BLEND);
+ context->gl.glEnable(GL_SCISSOR_TEST);
+ context->gl.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ context->gl.glEnableClientState(GL_VERTEX_ARRAY);
+ context->gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ context->gl.glEnableClientState(GL_COLOR_ARRAY);
+ context->gl.glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ context->gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ }
+ return result;
}
void mgl_graphics_swap_buffers(mgl_graphics *self, mgl_window_handle window) {
diff --git a/src/graphics/font.c b/src/graphics/font.c
index 12235f6..671d8a1 100644
--- a/src/graphics/font.c
+++ b/src/graphics/font.c
@@ -210,7 +210,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph
/* TODO: Use stbtt_MakeGlyphBitmapSubpixelPrefilter instead for better text quality */
const size_t pixels_width = (width + GLYPH_PADDING * 2);
const size_t pixels_height = (height + GLYPH_PADDING * 2);
- const size_t pixels_size = pixels_width * pixels_height;
+ const size_t pixels_size = pixels_width * pixels_height * 2; // *2 required for opengl glTexSubImage2D
unsigned char *pixels = calloc(pixels_size, 1);
if(pixels) {
const int top_padding = GLYPH_PADDING;
diff --git a/src/mgl.c b/src/mgl.c
index d0e344f..fdf5c5b 100644
--- a/src/mgl.c
+++ b/src/mgl.c
@@ -64,13 +64,13 @@ static bool is_xwayland(Display *dpy) {
}
static int mgl_init_x11(void) {
- if(!context.connection)
- context.connection = XOpenDisplay(NULL);
-
if(!context.connection) {
- fprintf(stderr, "mgl error: mgl_init_x11: failed to connect to the X11 server\n");
- mgl_deinit();
- return -1;
+ context.connection = XOpenDisplay(NULL);
+ if(!context.connection) {
+ fprintf(stderr, "mgl error: mgl_init_x11: failed to connect to the X11 server\n");
+ mgl_deinit();
+ return -1;
+ }
}
connected_to_display_server = true;
/* If we dont call we will never get a MappingNotify until a key has been pressed */
@@ -241,7 +241,7 @@ void mgl_ping_display_server(void) {
if(!context.connection)
return;
- // TODO: Do something equivalent for wayland
+ // TODO: Do something equivalent for wayland, maybe wl_display_roundtrip and if it returns -1 then the connection to the server died
if(context.window_system == MGL_WINDOW_SYSTEM_X11) {
XNoOp(context.connection);
XFlush(context.connection);
diff --git a/src/window/wayland.c b/src/window/wayland.c
index 2671e53..20c5c7a 100644
--- a/src/window/wayland.c
+++ b/src/window/wayland.c
@@ -1,21 +1,28 @@
#include "../../../include/mgl/window/wayland.h"
#include "../../../include/mgl/mgl.h"
-#include <wayland-client.h>
-#include <wayland-egl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
+#include <wayland-client.h>
+#include <wayland-egl.h>
+#include "xdg-shell-client-protocol.h"
+
static void mgl_window_wayland_deinit(mgl_window *self);
typedef struct {
- struct wl_display *display;
struct wl_egl_window *window;
struct wl_registry *registry;
struct wl_surface *surface;
struct wl_compositor *compositor;
+ struct wl_shell *shell;
+ struct wl_shell_surface *shell_surface;
+
+ struct xdg_wm_base *xdg_wm_base;
+ struct xdg_surface *xdg_surface;
+ struct xdg_toplevel *xdg_toplevel;
mgl_graphics graphics;
} mgl_window_wayland;
@@ -24,7 +31,7 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
(void)version;
mgl_window *self = data;
mgl_window_wayland *impl = self->impl;
- if(strcmp(interface, "wl_compositor") == 0) {
+ if(strcmp(interface, wl_compositor_interface.name) == 0) {
if(impl->compositor) {
wl_compositor_destroy(impl->compositor);
impl->compositor = NULL;
@@ -52,6 +59,18 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
// .name = NULL,
// };
// wl_output_add_listener(gsr_output->output, &output_listener, gsr_output);
+ } else if(strcmp(interface, wl_shell_interface.name) == 0) {
+ if(impl->shell) {
+ wl_shell_destroy(impl->shell);
+ impl->shell = NULL;
+ }
+ impl->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
+ } else if(strcmp(interface, xdg_wm_base_interface.name) == 0) {
+ if(impl->xdg_wm_base) {
+ xdg_wm_base_destroy(impl->xdg_wm_base);
+ impl->xdg_wm_base = NULL;
+ }
+ impl->xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
}
}
@@ -67,9 +86,98 @@ static struct wl_registry_listener registry_listener = {
.global_remove = registry_remove_object,
};
-// TODO: Use title, params and existing_window
+static void shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) {
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height) {
+ mgl_window *self = data;
+ mgl_window_wayland *impl = self->impl;
+ wl_egl_window_resize(impl->window, width, height, 0, 0);
+}
+
+void shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface) {
+
+}
+
+static struct wl_shell_surface_listener shell_surface_listener = {
+ .ping = shell_surface_ping,
+ .configure = shell_surface_configure,
+ .popup_done = shell_surface_popup_done,
+};
+
+static void xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial) {
+ xdg_wm_base_pong(shell, serial);
+}
+
+static const struct xdg_wm_base_listener wm_base_listener = {
+ .ping = xdg_wm_base_ping,
+};
+
+static void xdg_surface_configure(void *data, struct xdg_surface *surface, uint32_t serial) {
+ xdg_surface_ack_configure(surface, serial);
+ // TODO:
+ //window->wait_for_configure = false;
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+ .configure = xdg_surface_configure,
+};
+
+static void xdg_toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states) {
+ mgl_window *self = data;
+ mgl_window_wayland *impl = self->impl;
+ // TODO:
+ wl_egl_window_resize(impl->window, width, height, 0, 0);
+ // struct window *window = data;
+ // uint32_t *p;
+
+ // window->fullscreen = 0;
+ // window->maximized = 0;
+ // wl_array_for_each(p, states) {
+ // uint32_t state = *p;
+ // switch (state) {
+ // case XDG_TOPLEVEL_STATE_FULLSCREEN:
+ // window->fullscreen = 1;
+ // break;
+ // case XDG_TOPLEVEL_STATE_MAXIMIZED:
+ // window->maximized = 1;
+ // break;
+ // }
+ // }
+
+ // if (width > 0 && height > 0) {
+ // if (!window->fullscreen && !window->maximized) {
+ // window->window_size.width = width;
+ // window->window_size.height = height;
+ // }
+ // window->geometry.width = width;
+ // window->geometry.height = height;
+ // } else if (!window->fullscreen && !window->maximized) {
+ // window->geometry = window->window_size;
+ // }
+
+ // if (window->native)
+ // wl_egl_window_resize(window->native,
+ // window->geometry.width,
+ // window->geometry.height, 0, 0);
+}
+
+static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) {
+ // TODO:
+ //running = 0;
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+ .configure = xdg_toplevel_configure,
+ .close = xdg_toplevel_close,
+};
+
+
+// TODO: params and existing_window
bool mgl_wayland_setup_window(mgl_window *self, const char *title, const mgl_window_create_params *params, mgl_window_handle existing_window) {
mgl_window_wayland *impl = self->impl;
+ mgl_context *context = mgl_get_context();
mgl_vec2i window_size = params ? params->size : (mgl_vec2i){ 0, 0 };
if(window_size.x <= 0 || window_size.y <= 0) {
@@ -78,73 +186,256 @@ bool mgl_wayland_setup_window(mgl_window *self, const char *title, const mgl_win
}
self->size = window_size;
- impl->display = wl_display_connect(NULL);
- if(!impl->display) {
- fprintf(stderr, "mgl error: mgl_wayland_setup_window: failed to connect to the Wayland server\n");
- return false;
- }
-
- impl->registry = wl_display_get_registry(impl->display); /* TODO: Error checking */
+ impl->registry = wl_display_get_registry(context->connection); /* TODO: Error checking */
wl_registry_add_listener(impl->registry, &registry_listener, self); /* TODO: Error checking */
/* Fetch globals */
- wl_display_roundtrip(impl->display);
+ wl_display_roundtrip(context->connection);
/* Fetch wl_output */
- //wl_display_roundtrip(impl->display);
+ //wl_display_roundtrip(context->connection);
if(!impl->compositor) {
fprintf(stderr, "mgl error: mgl_wayland_setup_window: failed to find compositor\n");
return false;
}
+ if(!impl->xdg_wm_base && !impl->shell) {
+ fprintf(stderr, "mgl error: mgl_wayland_setup_window: failed to find shell\n");
+ return false;
+ }
+
impl->surface = wl_compositor_create_surface(impl->compositor);
if(!impl->surface) {
fprintf(stderr, "mgl error: mgl_wayland_setup_window: failed to create surface\n");
return false;
}
+ if(impl->xdg_wm_base) {
+ // TODO: Error check, cleanup
+ xdg_wm_base_add_listener(impl->xdg_wm_base, &wm_base_listener, self);
+
+ impl->xdg_surface = xdg_wm_base_get_xdg_surface(impl->xdg_wm_base, impl->surface);
+ xdg_surface_add_listener(impl->xdg_surface, &xdg_surface_listener, self);
+
+ impl->xdg_toplevel = xdg_surface_get_toplevel(impl->xdg_surface);
+ xdg_toplevel_add_listener(impl->xdg_toplevel, &xdg_toplevel_listener, self);
+
+ xdg_toplevel_set_title(impl->xdg_toplevel, title);
+ } else {
+ // TODO: Error check, cleanup
+ impl->shell_surface = wl_shell_get_shell_surface(impl->shell, impl->surface);
+ wl_shell_surface_add_listener(impl->shell_surface, &shell_surface_listener, self);
+ wl_shell_surface_set_toplevel(impl->shell_surface);
+ wl_shell_surface_set_title(impl->shell_surface, title);
+ }
+
+ wl_surface_commit(impl->surface);
+
+ // TODO: Error check
+ struct wl_region *region = wl_compositor_create_region(impl->compositor);
+ wl_region_add(region, 0, 0, self->size.x, self->size.y);
+ wl_surface_set_opaque_region(impl->surface, region);
+ wl_region_destroy(region);
+
impl->window = wl_egl_window_create(impl->surface, self->size.x, self->size.y);
if(!impl->window) {
fprintf(stderr, "mgl error: mgl_wayland_setup_window: failed to create the Wayland window\n");
return false;
}
+ //mgl_window_x11_on_resize(self, self->size.x, self->size.y);
+ //mgl_window_x11_on_move(self, window_pos.x, window_pos.y);
+ mgl_view view;
+ view.position = (mgl_vec2i){ 0, 0 };
+ view.size = self->size;
+ mgl_window_set_view(self, &view);
+ mgl_window_set_scissor(self, &(mgl_scissor){ .position = { 0, 0 }, .size = self->size });
+
+ self->open = true;
+ self->focused = false;
return true;
}
+static mgl_window_handle mgl_window_wayland_get_system_handle(const mgl_window *self) {
+ const mgl_window_wayland *impl = self->impl;
+ return (mgl_window_handle)impl->window;
+}
+
+static void mgl_window_wayland_close(mgl_window *self) {
+ mgl_window_wayland *impl = self->impl;
+
+ if(impl->window) {
+ wl_egl_window_destroy(impl->window);
+ impl->window = NULL;
+ }
+
+ if(impl->surface) {
+ wl_surface_destroy(impl->surface);
+ impl->surface = NULL;
+ }
+
+ self->open = false;
+}
+
+static bool mgl_window_wayland_poll_event(mgl_window *self, mgl_event *event) {
+ mgl_context *context = mgl_get_context();
+ struct wl_display *display = context->connection;
+ const bool events_available = wl_display_dispatch_pending(display) > 0;
+ //wl_display_flush(display);
+ /* TODO: Return event here, pop from circular buffer */
+ return events_available;
+}
+
+static void mgl_window_wayland_swap_buffers(mgl_window *self) {
+ mgl_window_wayland *impl = self->impl;
+ mgl_graphics_swap_buffers(&impl->graphics, (mgl_window_handle)impl->window);
+}
+
+static void mgl_window_wayland_set_visible(mgl_window *self, bool visible) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static bool mgl_window_wayland_is_key_pressed(const mgl_window *self, mgl_key key) {
+ (void)self;
+ if(key < 0 || key >= __MGL_NUM_KEYS__)
+ return false;
+
+ fprintf(stderr, "TODO: Implement\n");
+ return false;
+}
+
+static bool mgl_window_wayland_is_mouse_button_pressed(const mgl_window *self, mgl_mouse_button button) {
+ (void)self;
+ if(button < 0 || button >= __MGL_NUM_MOUSE_BUTTONS__)
+ return false;
+
+ fprintf(stderr, "TODO: Implement\n");
+ return false;
+}
+
+static void mgl_window_wayland_set_title(mgl_window *self, const char *title) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static void mgl_window_wayland_set_cursor_visible(mgl_window *self, bool visible) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static void mgl_window_wayland_set_vsync_enabled(mgl_window *self, bool enabled) {
+ mgl_window_wayland *impl = self->impl;
+ self->vsync_enabled = enabled;
+ if(!mgl_graphics_set_swap_interval(&impl->graphics, (mgl_window_handle)impl->window, self->vsync_enabled))
+ fprintf(stderr, "mgl warning: mgl_window_wayland_set_vsync_enabled: failed to enable vsync\n");
+}
+
+static bool mgl_window_wayland_is_vsync_enabled(const mgl_window *self) {
+ return self->vsync_enabled;
+}
+
+static void mgl_window_wayland_set_fullscreen(mgl_window *self, bool fullscreen) {
+ mgl_window_wayland *impl = self->impl;
+ // TODO: The last argument is the monitor we want to fullscreen on. Use this!
+ if(impl->xdg_wm_base) {
+ if(fullscreen)
+ xdg_toplevel_set_fullscreen(impl->xdg_toplevel, NULL);
+ else
+ xdg_toplevel_unset_fullscreen(impl->xdg_toplevel);
+ } else {
+ if(fullscreen)
+ wl_shell_surface_set_fullscreen(impl->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
+ else
+ fprintf(stderr, "TODO: Implement\n");
+ }
+}
+
+static bool mgl_window_wayland_is_fullscreen(const mgl_window *self) {
+ fprintf(stderr, "TODO: Implement\n");
+ return false;
+}
+
+static void mgl_window_wayland_set_position(mgl_window *self, mgl_vec2i position) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static void mgl_window_wayland_set_size(mgl_window *self, mgl_vec2i size) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static void mgl_window_wayland_set_size_limits(mgl_window *self, mgl_vec2i minimum, mgl_vec2i maximum) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static void mgl_window_wayland_set_clipboard(mgl_window *self, const char *str, size_t size) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
+static bool mgl_window_wayland_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata, uint32_t clipboard_types) {
+ fprintf(stderr, "TODO: Implement\n");
+ return false;
+}
+
+static void mgl_window_wayland_set_key_repeat_enabled(mgl_window *self, bool enabled) {
+ self->key_repeat_enabled = enabled;
+ // TODO: Implement
+}
+
+static void mgl_window_wayland_flush(mgl_window *self) {
+ (void)self;
+ mgl_context *context = mgl_get_context();
+ struct wl_display *display = context->connection;
+ wl_display_flush(display);
+}
+
+static void* mgl_window_wayland_get_egl_display(mgl_window *self) {
+ mgl_window_wayland *impl = self->impl;
+ if(impl->graphics.graphics_api == MGL_GRAPHICS_API_EGL)
+ return mgl_graphics_get_display(&impl->graphics);
+ else
+ return NULL;
+}
+
+static void* mgl_window_wayland_get_egl_context(mgl_window *self) {
+ mgl_window_wayland *impl = self->impl;
+ if(impl->graphics.graphics_api == MGL_GRAPHICS_API_EGL)
+ return mgl_graphics_get_context(&impl->graphics);
+ else
+ return NULL;
+}
+
+static void mgl_window_wayland_for_each_active_monitor_output(mgl_window *self, mgl_active_monitor_callback callback, void *userdata) {
+ fprintf(stderr, "TODO: Implement\n");
+}
+
bool mgl_window_wayland_init(mgl_window *self, const char *title, const mgl_window_create_params *params, mgl_window_handle existing_window) {
mgl_window_wayland *impl = calloc(1, sizeof(mgl_window_wayland));
if(!impl)
return false;
- // self->get_system_handle = mgl_window_x11_get_system_handle;
- // self->close = mgl_window_x11_close;
- // self->inject_x11_event = mgl_window_x11_inject_x11_event;
- // self->poll_event = mgl_window_x11_poll_event;
- // self->swap_buffers = mgl_window_x11_swap_buffers;
- // self->set_visible = mgl_window_x11_set_visible;
- // self->is_key_pressed = mgl_window_x11_is_key_pressed;
- // self->is_mouse_button_pressed = mgl_window_x11_is_mouse_button_pressed;
- // self->set_title = mgl_window_x11_set_title;
- // self->set_cursor_visible = mgl_window_x11_set_cursor_visible;
- // self->set_vsync_enabled = mgl_window_x11_set_vsync_enabled;
- // self->is_vsync_enabled = mgl_window_x11_is_vsync_enabled;
- // self->set_fullscreen = mgl_window_x11_set_fullscreen;
- // self->is_fullscreen = mgl_window_x11_is_fullscreen;
- // self->set_position = mgl_window_x11_set_position;
- // self->set_size = mgl_window_x11_set_size;
- // self->set_size_limits = mgl_window_x11_set_size_limits;
- // self->set_clipboard = mgl_window_x11_set_clipboard;
- // self->get_clipboard = mgl_window_x11_get_clipboard;
- // self->get_clipboard_string = mgl_window_x11_get_clipboard_string;
- // self->set_key_repeat_enabled = mgl_window_x11_set_key_repeat_enabled;
- // self->flush = mgl_window_x11_flush;
- // self->get_egl_display = mgl_window_x11_get_egl_display;
- // self->get_egl_context = mgl_window_x11_get_egl_context;
- // self->for_each_active_monitor_output = mgl_window_x11_for_each_active_monitor_output;
-
+ self->get_system_handle = mgl_window_wayland_get_system_handle;
self->deinit = mgl_window_wayland_deinit;
+ self->close = mgl_window_wayland_close;
+ self->poll_event = mgl_window_wayland_poll_event;
+ self->swap_buffers = mgl_window_wayland_swap_buffers;
+ self->set_visible = mgl_window_wayland_set_visible;
+ self->is_key_pressed = mgl_window_wayland_is_key_pressed;
+ self->is_mouse_button_pressed = mgl_window_wayland_is_mouse_button_pressed;
+ self->set_title = mgl_window_wayland_set_title;
+ self->set_cursor_visible = mgl_window_wayland_set_cursor_visible;
+ self->set_vsync_enabled = mgl_window_wayland_set_vsync_enabled;
+ self->is_vsync_enabled = mgl_window_wayland_is_vsync_enabled;
+ self->set_fullscreen = mgl_window_wayland_set_fullscreen;
+ self->is_fullscreen = mgl_window_wayland_is_fullscreen;
+ self->set_position = mgl_window_wayland_set_position;
+ self->set_size = mgl_window_wayland_set_size;
+ self->set_size_limits = mgl_window_wayland_set_size_limits;
+ self->set_clipboard = mgl_window_wayland_set_clipboard;
+ self->get_clipboard = mgl_window_wayland_get_clipboard;
+ self->set_key_repeat_enabled = mgl_window_wayland_set_key_repeat_enabled;
+ self->flush = mgl_window_wayland_flush;
+ self->get_egl_display = mgl_window_wayland_get_egl_display;
+ self->get_egl_context = mgl_window_wayland_get_egl_context;
+ self->for_each_active_monitor_output = mgl_window_wayland_for_each_active_monitor_output;
self->impl = impl;
if(!mgl_wayland_setup_window(self, title, params, existing_window)) {
@@ -179,15 +470,31 @@ void mgl_window_wayland_deinit(mgl_window *self) {
return;
mgl_graphics_deinit(&impl->graphics);
+ mgl_window_wayland_close(self);
- if(impl->window) {
- wl_egl_window_destroy(impl->window);
- impl->window = NULL;
+ if(impl->xdg_toplevel) {
+ xdg_toplevel_destroy(impl->xdg_toplevel);
+ impl->xdg_toplevel = NULL;
}
- if(impl->surface) {
- wl_surface_destroy(impl->surface);
- impl->surface = NULL;
+ if(impl->xdg_surface) {
+ xdg_surface_destroy(impl->xdg_surface);
+ impl->xdg_surface = NULL;
+ }
+
+ if(impl->shell_surface) {
+ wl_shell_surface_destroy(impl->shell_surface);
+ impl->shell_surface = NULL;
+ }
+
+ if(impl->shell) {
+ wl_shell_destroy(impl->shell);
+ impl->shell = NULL;
+ }
+
+ if(impl->xdg_wm_base) {
+ xdg_wm_base_destroy(impl->xdg_wm_base);
+ impl->xdg_wm_base = NULL;
}
if(impl->compositor) {
@@ -200,11 +507,6 @@ void mgl_window_wayland_deinit(mgl_window *self) {
impl->registry = NULL;
}
- if(impl->display) {
- wl_display_disconnect(impl->display);
- impl->display = NULL;
- }
-
mgl_context *context = mgl_get_context();
if(context->current_window == self)
context->current_window = NULL;
diff --git a/src/window/x11.c b/src/window/x11.c
index 113fc1a..cf44ac2 100644
--- a/src/window/x11.c
+++ b/src/window/x11.c
@@ -4,13 +4,6 @@
#include "../../../include/mgl/system/utf8.h"
#include "../../../include/mgl/system/clock.h"
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xrender.h>
-#include <X11/extensions/Xrandr.h>
-#include <X11/XF86keysym.h>
-
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -18,6 +11,13 @@
#include <assert.h>
#include <unistd.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/XF86keysym.h>
+
static void mgl_window_x11_deinit(mgl_window *self);
/* TODO: Handle XIM better. Set XIM position to text position on screen (for text input) and reset input when selecting a new text input, etc */
@@ -34,7 +34,6 @@ typedef struct {
} x11_events_circular_buffer;
typedef struct {
- void *dpy;
Window window;
char *clipboard_string;
size_t clipboard_size;
@@ -515,16 +514,6 @@ static bool mgl_x11_setup_window(mgl_window *self, const char *title, const mgl_
self->vsync_enabled = true;
mgl_graphics_set_swap_interval(&impl->graphics, (mgl_window_handle)impl->window, self->vsync_enabled);
- context->gl.glEnable(GL_TEXTURE_2D);
- context->gl.glEnable(GL_BLEND);
- context->gl.glEnable(GL_SCISSOR_TEST);
- context->gl.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- context->gl.glEnableClientState(GL_VERTEX_ARRAY);
- context->gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- context->gl.glEnableClientState(GL_COLOR_ARRAY);
- context->gl.glPixelStorei(GL_PACK_ALIGNMENT, 1);
- context->gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
Window dummy_w;
int dummy_i;
unsigned int dummy_u;
@@ -1436,54 +1425,6 @@ static bool mgl_window_x11_get_clipboard(mgl_window *self, mgl_clipboard_callbac
return success;
}
-typedef struct {
- char **str;
- size_t *size;
-} ClipboardStringCallbackData;
-
-static bool clipboard_copy_string_callback(const unsigned char *data, size_t size, mgl_clipboard_type clipboard_type, void *userdata) {
- ClipboardStringCallbackData *callback_data = userdata;
- if(clipboard_type != MGL_CLIPBOARD_TYPE_STRING) {
- free(*callback_data->str);
- *callback_data->str = NULL;
- *callback_data->size = 0;
- return false;
- }
-
- char *new_data = realloc(*callback_data->str, *callback_data->size + size);
- if(!new_data) {
- free(*callback_data->str);
- *callback_data->str = NULL;
- *callback_data->size = 0;
- return false;
- }
-
- memcpy(new_data + *callback_data->size, data, size);
-
- *callback_data->str = new_data;
- *callback_data->size += size;
- return true;
-}
-
-static bool mgl_window_x11_get_clipboard_string(mgl_window *self, char **str, size_t *size) {
- assert(str);
- assert(size);
-
- *str = NULL;
- *size = 0;
-
- ClipboardStringCallbackData callback_data;
- callback_data.str = str;
- callback_data.size = size;
- const bool success = mgl_window_x11_get_clipboard(self, clipboard_copy_string_callback, &callback_data, MGL_CLIPBOARD_TYPE_STRING);
- if(!success) {
- free(*str);
- *str = NULL;
- *size = 0;
- }
- return success;
-}
-
static void mgl_window_x11_set_key_repeat_enabled(mgl_window *self, bool enabled) {
self->key_repeat_enabled = enabled;
}
@@ -1535,13 +1476,11 @@ bool mgl_window_x11_init(mgl_window *self, const char *title, const mgl_window_c
self->set_size_limits = mgl_window_x11_set_size_limits;
self->set_clipboard = mgl_window_x11_set_clipboard;
self->get_clipboard = mgl_window_x11_get_clipboard;
- self->get_clipboard_string = mgl_window_x11_get_clipboard_string;
self->set_key_repeat_enabled = mgl_window_x11_set_key_repeat_enabled;
self->flush = mgl_window_x11_flush;
self->get_egl_display = mgl_window_x11_get_egl_display;
self->get_egl_context = mgl_window_x11_get_egl_context;
self->for_each_active_monitor_output = mgl_window_x11_for_each_active_monitor_output;
-
self->impl = impl;
/* TODO: Use CLIPBOARD_MANAGER and SAVE_TARGETS to save clipboard in clipboard manager on exit */