From 38f61a24fcdf5a78cbabc9184f55ded3b496f1d4 Mon Sep 17 00:00:00 2001
From: PoroCYon <pcy@national.shitposting.agency>
Date: Sun, 26 May 2019 00:38:24 +0200
Subject: 'port' libui GL stuff to Linux

Only implemented the functions needed by melonDS, and only tested using
a very recent mesa+libglvnd+nouveau. Will most likely bork using
proprietary nvidia or old(er) drivers (see gl.c)
---
 src/libui_sdl/libui/unix/CMakeLists.txt |  1 +
 src/libui_sdl/libui/unix/area.c         | 41 ++++++++++++++++++++++++++++
 src/libui_sdl/libui/unix/gl.c           | 47 +++++++++++++++++++++++++++++++++
 src/libui_sdl/libui/unix/uipriv_unix.h  |  6 ++++-
 src/libui_sdl/libui/unix/window.c       | 18 +++++++++++++
 5 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 src/libui_sdl/libui/unix/gl.c

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt
index 9300bcb..ec9ab75 100644
--- a/src/libui_sdl/libui/unix/CMakeLists.txt
+++ b/src/libui_sdl/libui/unix/CMakeLists.txt
@@ -43,6 +43,7 @@ list(APPEND _LIBUI_SOURCES
 	unix/text.c
 	unix/util.c
 	unix/window.c
+	unix/gl.c
 )
 set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
 
diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index 2da9bab..e518ae5 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -38,7 +38,10 @@ struct uiArea {
 
 	GtkWidget *areaWidget;
 	GtkDrawingArea *drawingArea;
+	GtkGLArea *glArea;
 	areaWidget *area;
+
+	GdkGLContext *glContext;
 	
 	int bgR, bgG, bgB;
 
@@ -730,6 +733,44 @@ uiArea *uiNewArea(uiAreaHandler *ah)
 	return a;
 }
 
+uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
+{
+	uiArea *a;
+
+	uiUnixNewControl(uiArea, a);
+
+	a->ah = ah;
+	a->scrolling = FALSE;
+
+	GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
+	GdkGLContext* ctx = NULL;
+
+	for (int i = 0; req_versions[i] && !ctx; i++) {
+		int major = uiGLVerMajor(req_versions[i]);
+		int minor = uiGLVerMinor(req_versions[i]);
+		gtk_gl_area_set_required_version(gla, major, minor);
+		ctx = createGLContext(gla, major, minor);
+	}
+
+	a->glContext = ctx;
+	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area",
+				a, NULL));
+	a->glArea = gla;
+	a->area = areaWidget(a->areaWidget);
+
+	a->widget = a->areaWidget;
+
+	uiAreaSetBackgroundColor(a, -1, -1, -1);
+
+	return a;
+}
+
+uiGLContext *uiAreaGetGLContext(uiArea* a)
+{
+	if (!a) return NULL;
+	return a->glContext;
+}
+
 uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
 {
 	uiArea *a;
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
new file mode 100644
index 0000000..da41437
--- /dev/null
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -0,0 +1,47 @@
+// 26 may 2019
+#include "uipriv_unix.h"
+
+/*
+ *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed
+
+(melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget'
+ */
+
+struct uiGLContext {
+	GtkGLArea *gla;
+	GdkGLContext *gctx;
+	int vermaj, vermin;
+};
+
+uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min)
+{
+	uiGLContext *ret = uiAlloc(sizeof(uiGLContext), "uiGLContext");
+	ret->gla = gla;
+	ret->gctx = gtk_gl_area_get_context(gla);
+	ret->vermaj = maj; ret->vermin = min;
+	return ret;
+}
+
+void uiGLSwapBuffers(uiGLContext* ctx)
+{
+	if (!ctx) return;
+	gtk_gl_area_attach_buffers(ctx->gla);
+}
+
+void uiGLMakeContextCurrent(uiGLContext* ctx)
+{
+	if (!ctx) return;
+	gtk_gl_area_make_current(ctx->gla);
+}
+void *uiGLGetProcAddress(const char* proc)
+{
+	// this *will* break for older systems that don't have libglvnd!
+	// TODO: use a real solution
+	return dlsym(NULL /* RTLD_DEFAULT */, proc);
+}
+unsigned int uiGLGetVersion(uiGLContext* ctx)
+{
+	if (!ctx) return 0;
+	return uiGLVersion(ctx->vermaj, ctx->vermin);
+}
+
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
index 33ff1e3..42d5d76 100644
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ b/src/libui_sdl/libui/unix/uipriv_unix.h
@@ -5,7 +5,7 @@
 #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10
 #include <gtk/gtk.h>
 #include <math.h>
-#include <dlfcn.h>		// see drawtext.c
+#include <dlfcn.h>		// see drawtext.c, gl.c
 #include <langinfo.h>
 #include <string.h>
 #include <stdlib.h>
@@ -63,3 +63,7 @@ extern GtkCellRenderer *newCellRendererButton(void);
 extern void loadFutures(void);
 extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha);
 extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name);
+
+// gl.c
+extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min);
+
diff --git a/src/libui_sdl/libui/unix/window.c b/src/libui_sdl/libui/unix/window.c
index 7da1134..6d5e2de 100644
--- a/src/libui_sdl/libui/unix/window.c
+++ b/src/libui_sdl/libui/unix/window.c
@@ -102,6 +102,23 @@ static void uiWindowDestroy(uiControl *c)
 	uiFreeControl(uiControl(w));
 }
 
+void uiWindowSetPosition(uiWindow *w, int x, int y)
+{
+	if (!w) return;
+
+	gtk_window_move(w->window, x, y);
+}
+
+void uiWindowPosition(uiWindow *w, int *x, int *y)
+{
+	if (!w) return;
+
+	int xx, yy;
+	gtk_window_get_position(w->window, &xx, &yy);
+	if (x) *x = xx;
+	if (y) *y = yy;
+}
+
 uiUnixControlDefaultHandle(uiWindow)
 
 uiControl *uiWindowParent(uiControl *c)
@@ -442,3 +459,4 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int maximized, i
 
 	return w;
 }
+
-- 
cgit v1.2.3