aboutsummaryrefslogtreecommitdiffstats
path: root/pugl/pugl_x11_gl.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-02-15 12:51:06 +0100
committerDavid Robillard <d@drobilla.net>2019-02-16 16:56:50 +0100
commitf46b5124627e47a197ad41ff5b9e27b82e19d945 (patch)
treebaa281528cfa2359630bf48f9d3fba2981e31b5d /pugl/pugl_x11_gl.c
parentcf80f78f808e402d06dc891fce08b0f3b3865c15 (diff)
downloadpugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.tar.gz
pugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.tar.bz2
pugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.zip
Factor out drawing context from platform window implementation
Diffstat (limited to 'pugl/pugl_x11_gl.c')
-rw-r--r--pugl/pugl_x11_gl.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/pugl/pugl_x11_gl.c b/pugl/pugl_x11_gl.c
new file mode 100644
index 0000000..809f4a3
--- /dev/null
+++ b/pugl/pugl_x11_gl.c
@@ -0,0 +1,145 @@
+/*
+ Copyright 2012-2019 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+#include "pugl/pugl_x11.h"
+#include "pugl/pugl_x11_gl.h"
+#include "pugl/pugl_internal_types.h"
+
+typedef struct {
+ GLXContext ctx;
+ int doubleBuffered;
+} PuglX11GlSurface;
+
+static int
+puglX11GlConfigure(PuglView* view)
+{
+ PuglInternals* const impl = view->impl;
+
+ /** Attributes for double-buffered RGBA. */
+ static int attrListDbl[] = { GLX_RGBA,
+ GLX_DOUBLEBUFFER, True,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ /* GLX_SAMPLE_BUFFERS , 1, */
+ /* GLX_SAMPLES , 4, */
+ None };
+
+ /** Attributes for single-buffered RGBA. */
+ static int attrListSgl[] = { GLX_RGBA,
+ GLX_DOUBLEBUFFER, False,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ /* GLX_SAMPLE_BUFFERS , 1, */
+ /* GLX_SAMPLES , 4, */
+ None };
+
+ /** Null-terminated list of attributes in order of preference. */
+ static int* attrLists[] = { attrListDbl, attrListSgl, NULL };
+
+ if (view->ctx_type & PUGL_GL) {
+ for (int* attr = *attrLists; !impl->vi && *attr; ++attr) {
+ impl->vi = glXChooseVisual(impl->display, impl->screen, attr);
+ }
+ }
+
+ return 0;
+}
+
+static int
+puglX11GlCreate(PuglView* view)
+{
+ PuglInternals* const impl = view->impl;
+
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)calloc(1, sizeof(PuglX11GlSurface));
+
+ impl->surface = surface;
+ surface->ctx = glXCreateContext(impl->display, impl->vi, 0, GL_TRUE);
+ glXGetConfig(
+ impl->display, impl->vi, GLX_DOUBLEBUFFER, &surface->doubleBuffered);
+
+ return 0;
+}
+
+static int
+puglX11GlDestroy(PuglView* view)
+{
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
+ glXDestroyContext(view->impl->display, surface->ctx);
+ free(surface);
+ view->impl->surface = NULL;
+ return 0;
+}
+
+static int
+puglX11GlEnter(PuglView* view)
+{
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
+ glXMakeCurrent(view->impl->display, view->impl->win, surface->ctx);
+ return 0;
+}
+
+static int
+puglX11GlLeave(PuglView* view, bool flush)
+{
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
+
+ if (flush) {
+ glFlush();
+ }
+
+ glXMakeCurrent(view->impl->display, None, NULL);
+ if (surface->doubleBuffered) {
+ glXSwapBuffers(view->impl->display, view->impl->win);
+ }
+
+ return 0;
+}
+
+static int
+puglX11GlResize(PuglView* view, int width, int height)
+{
+ return 0;
+}
+
+static void*
+puglX11GlGetHandle(PuglView* view)
+{
+ return NULL;
+}
+
+PuglDrawContext puglGetX11GlDrawContext(void)
+{
+ static const PuglDrawContext puglX11GlDrawContext = {
+ puglX11GlConfigure,
+ puglX11GlCreate,
+ puglX11GlDestroy,
+ puglX11GlEnter,
+ puglX11GlLeave,
+ puglX11GlResize,
+ puglX11GlGetHandle
+ };
+
+ return puglX11GlDrawContext;
+}