diff options
author | David Robillard <d@drobilla.net> | 2019-02-15 12:51:06 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-02-16 16:56:50 +0100 |
commit | f46b5124627e47a197ad41ff5b9e27b82e19d945 (patch) | |
tree | baa281528cfa2359630bf48f9d3fba2981e31b5d /pugl | |
parent | cf80f78f808e402d06dc891fce08b0f3b3865c15 (diff) | |
download | pugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.tar.gz pugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.tar.bz2 pugl-f46b5124627e47a197ad41ff5b9e27b82e19d945.zip |
Factor out drawing context from platform window implementation
Diffstat (limited to 'pugl')
-rw-r--r-- | pugl/pugl_internal_types.h | 26 | ||||
-rw-r--r-- | pugl/pugl_x11.c | 225 | ||||
-rw-r--r-- | pugl/pugl_x11.h | 31 | ||||
-rw-r--r-- | pugl/pugl_x11_cairo.c | 141 | ||||
-rw-r--r-- | pugl/pugl_x11_cairo.h | 22 | ||||
-rw-r--r-- | pugl/pugl_x11_gl.c | 145 | ||||
-rw-r--r-- | pugl/pugl_x11_gl.h | 22 |
7 files changed, 424 insertions, 188 deletions
diff --git a/pugl/pugl_internal_types.h b/pugl/pugl_internal_types.h index a0f5b91..dce5429 100644 --- a/pugl/pugl_internal_types.h +++ b/pugl/pugl_internal_types.h @@ -55,5 +55,31 @@ struct PuglViewImpl { bool visible; }; +/** Opaque surface used by draw context. */ +typedef void PuglSurface; + +/** Drawing context interface. */ +typedef struct { + /** Get visual information from display and setup view as necessary. */ + int (*configure)(PuglView*); + + /** Create surface and drawing context. */ + int (*create)(PuglView*); + + /** Destroy surface and drawing context. */ + int (*destroy)(PuglView*); + + /** Enter drawing context. */ + int (*enter)(PuglView*); + + /** Leave drawing context, explicitly flushing if parameter is true. */ + int (*leave)(PuglView*, bool); + + /** Resize drawing context to the given width and height. */ + int (*resize)(PuglView*, int, int); + + /** Return the puglGetContext() handle for the application, if any. */ + void* (*getHandle)(PuglView*); +} PuglDrawContext; #endif // PUGL_INTERNAL_TYPES_H diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 5acd797..7a334e3 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2016 David Robillard <http://drobilla.net> + Copyright 2012-2019 David Robillard <http://drobilla.net> Copyright 2013 Robin Gareus <robin@gareus.org> Copyright 2011-2012 Ben Loftis, Harrison Consoles @@ -29,18 +29,17 @@ #include <X11/Xutil.h> #include <X11/keysym.h> +#include "pugl/pugl_internal.h" +#include "pugl/pugl_x11.h" + #ifdef PUGL_HAVE_GL -#include <GL/gl.h> -#include <GL/glx.h> +#include "pugl/pugl_x11_gl.h" #endif #ifdef PUGL_HAVE_CAIRO -#include <cairo/cairo-xlib.h> -#include <cairo/cairo.h> +#include "pugl/pugl_x11_cairo.h" #endif -#include "pugl/pugl_internal.h" - #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -49,176 +48,22 @@ # define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif -#ifdef PUGL_HAVE_GL - -/** 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 }; - -#endif // PUGL_HAVE_GL - -struct PuglInternalsImpl { - Display* display; - int screen; - Window win; - XIM xim; - XIC xic; -#ifdef PUGL_HAVE_CAIRO - cairo_surface_t* surface; - cairo_t* cr; -#endif -#ifdef PUGL_HAVE_GL - GLXContext ctx; - int doubleBuffered; -#endif -}; - PuglInternals* puglInitInternals(void) { return (PuglInternals*)calloc(1, sizeof(PuglInternals)); } -static XVisualInfo* -getVisual(PuglView* view) -{ - PuglInternals* const impl = view->impl; - XVisualInfo* vi = NULL; - -#ifdef PUGL_HAVE_GL - if (view->ctx_type & PUGL_GL) { - for (int* attr = *attrLists; !vi && *attr; ++attr) { - vi = glXChooseVisual(impl->display, impl->screen, attr); - } - } -#endif -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type == PUGL_CAIRO) { - XVisualInfo pat; - int n; - pat.screen = impl->screen; - vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n); - } -#endif - - return vi; -} - -#ifdef PUGL_HAVE_CAIRO -static int -createCairoContext(PuglView* view) -{ - PuglInternals* const impl = view->impl; - - if (impl->cr) { - cairo_destroy(impl->cr); - } - - impl->cr = cairo_create(impl->surface); - return cairo_status(impl->cr); -} -#endif - -static bool -createContext(PuglView* view, XVisualInfo* vi) -{ - PuglInternals* const impl = view->impl; - -#ifdef PUGL_HAVE_GL - if (view->ctx_type & PUGL_GL) { - impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); - glXGetConfig(impl->display, vi, GLX_DOUBLEBUFFER, &impl->doubleBuffered); - } -#endif -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type == PUGL_CAIRO) { - impl->surface = cairo_xlib_surface_create( - impl->display, impl->win, vi->visual, view->width, view->height); - } -#endif - -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type & PUGL_CAIRO) { - if (cairo_surface_status(impl->surface) != CAIRO_STATUS_SUCCESS) { - fprintf(stderr, "error: failed to create cairo surface\n"); - return false; - } - - if (createCairoContext(view) != CAIRO_STATUS_SUCCESS) { - cairo_surface_destroy(impl->surface); - fprintf(stderr, "error: failed to create cairo context\n"); - return false; - } - } -#endif - - return true; -} - -static void -destroyContext(PuglView* view) -{ -#ifdef PUGL_HAVE_GL - if (view->ctx_type & PUGL_GL) { - glXDestroyContext(view->impl->display, view->impl->ctx); - } -#endif -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type & PUGL_CAIRO) { - cairo_destroy(view->impl->cr); - cairo_surface_destroy(view->impl->surface); - } -#endif -} - void puglEnterContext(PuglView* view) { -#ifdef PUGL_HAVE_GL - if (view->ctx_type & PUGL_GL) { - glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx); - } -#endif + view->impl->ctx.enter(view); } void puglLeaveContext(PuglView* view, bool flush) { -#ifdef PUGL_HAVE_GL - if (flush && view->ctx_type & PUGL_GL) { - glFlush(); - if (view->impl->doubleBuffered) { - glXSwapBuffers(view->impl->display, view->impl->win); - } - } - - glXMakeCurrent(view->impl->display, None, NULL); -#endif + view->impl->ctx.leave(view, flush); } int @@ -229,17 +74,32 @@ puglCreateWindow(PuglView* view, const char* title) impl->display = XOpenDisplay(0); impl->screen = DefaultScreen(impl->display); - XVisualInfo* const vi = getVisual(view); - if (!vi) { + if (view->ctx_type == PUGL_GL) { +#ifdef PUGL_HAVE_GL + impl->ctx = puglGetX11GlDrawContext(); +#endif + } + if (view->ctx_type == PUGL_CAIRO) { +#ifdef PUGL_HAVE_CAIRO + impl->ctx = puglGetX11CairoDrawContext(); +#endif + } + + if (!impl->ctx.configure) { return 1; } + impl->ctx.configure(view); + if (!impl->vi) { + return 2; + } + Window xParent = view->parent ? (Window)view->parent : RootWindow(impl->display, impl->screen); Colormap cmap = XCreateColormap( - impl->display, xParent, vi->visual, AllocNone); + impl->display, xParent, impl->vi->visual, AllocNone); XSetWindowAttributes attr; memset(&attr, 0, sizeof(XSetWindowAttributes)); @@ -252,11 +112,11 @@ puglCreateWindow(PuglView* view, const char* title) impl->win = XCreateWindow( impl->display, xParent, - 0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual, - CWColormap | CWEventMask, &attr); + 0, 0, view->width, view->height, 0, impl->vi->depth, InputOutput, + impl->vi->visual, CWColormap | CWEventMask, &attr); - if (!createContext(view, vi)) { - return 2; + if (impl->ctx.create(view)) { + return 3; } XSizeHints sizeHints; @@ -316,8 +176,6 @@ puglCreateWindow(PuglView* view, const char* title) fprintf(stderr, "warning: XCreateIC failed\n"); } - XFree(vi); - return 0; } @@ -339,9 +197,10 @@ void puglDestroy(PuglView* view) { if (view) { - destroyContext(view); + view->impl->ctx.destroy(view); XDestroyWindow(view->impl->display, view->impl->win); XCloseDisplay(view->impl->display); + XFree(view->impl->vi); free(view->windowClass); free(view->impl); free(view); @@ -633,15 +492,10 @@ puglProcessEvents(PuglView* view) } if (config_event.type) { -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type == PUGL_CAIRO) { - // Resize surfaces/contexts before dispatching - view->redisplay = true; - cairo_xlib_surface_set_size(view->impl->surface, - config_event.configure.width, - config_event.configure.height); - } -#endif + // Resize drawing context before dispatching + view->impl->ctx.resize(view, + config_event.configure.width, + config_event.configure.height); puglDispatchEvent(view, (const PuglEvent*)&config_event); } @@ -677,10 +531,5 @@ puglGetNativeWindow(PuglView* view) void* puglGetContext(PuglView* view) { -#ifdef PUGL_HAVE_CAIRO - if (view->ctx_type & PUGL_CAIRO) { - return view->impl->cr; - } -#endif - return NULL; + return view->impl->ctx.getHandle(view); } diff --git a/pugl/pugl_x11.h b/pugl/pugl_x11.h new file mode 100644 index 0000000..a8c8c02 --- /dev/null +++ b/pugl/pugl_x11.h @@ -0,0 +1,31 @@ +/* + 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 <X11/Xlib.h> + +#include "pugl/pugl.h" +#include "pugl/pugl_internal_types.h" + +struct PuglInternalsImpl { + Display* display; + int screen; + XVisualInfo* vi; + Window win; + XIM xim; + XIC xic; + PuglDrawContext ctx; + PuglSurface* surface; +}; diff --git a/pugl/pugl_x11_cairo.c b/pugl/pugl_x11_cairo.c new file mode 100644 index 0000000..3614c4b --- /dev/null +++ b/pugl/pugl_x11_cairo.c @@ -0,0 +1,141 @@ +/* + 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 <stdio.h> +#include <stdlib.h> + +#include <cairo/cairo-xlib.h> +#include <cairo/cairo.h> + +#include <X11/Xutil.h> + +#include "pugl/pugl_internal_types.h" +#include "pugl/pugl_x11.h" +#include "pugl/pugl_x11_cairo.h" + +typedef struct { + cairo_surface_t* surface; + cairo_t* cr; +} PuglX11CairoSurface; + +static int +puglX11CairoConfigure(PuglView* view) +{ + PuglInternals* const impl = view->impl; + + XVisualInfo pat; + int n; + pat.screen = impl->screen; + impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n); + + return 0; +} + +static int +puglX11CairoCreate(PuglView* view) +{ + PuglInternals* const impl = view->impl; + PuglX11CairoSurface* const surface = + (PuglX11CairoSurface*)calloc(1, sizeof(PuglX11CairoSurface)); + + impl->surface = surface; + + if (view->ctx_type == PUGL_CAIRO) { + surface->surface = cairo_xlib_surface_create( + impl->display, impl->win, impl->vi->visual, view->width, view->height); + } + + if (!surface->surface) { + return 1; + } + + int st = cairo_surface_status(surface->surface); + if (st) { + fprintf(stderr, "error: failed to create cairo surface (%s)\n", + cairo_status_to_string(st)); + } else if (!(surface->cr = cairo_create(surface->surface))) { + fprintf(stderr, "error: failed to create cairo context\n"); + } else if ((st = cairo_status(surface->cr))) { + cairo_surface_destroy(surface->surface); + fprintf(stderr, "error: cairo context is invalid (%s)\n", + cairo_status_to_string(st)); + } + return st; +} + +static int +puglX11CairoDestroy(PuglView* view) +{ + PuglInternals* const impl = view->impl; + PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface; + + cairo_destroy(surface->cr); + cairo_surface_destroy(surface->surface); + free(surface); + impl->surface = NULL; + return 0; +} + +static int +puglX11CairoEnter(PuglView* view) +{ + return 0; +} + +static int +puglX11CairoLeave(PuglView* view, bool flush) +{ + return 0; +} + +static int +puglX11CairoResize(PuglView* view, int width, int height) +{ + PuglInternals* const impl = view->impl; + PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface; + + view->redisplay = true; + + if (view->ctx_type == PUGL_CAIRO) { + cairo_xlib_surface_set_size(surface->surface, width, height); + } + + return 0; +} + +static void* +puglX11CairoGetHandle(PuglView* view) +{ + PuglInternals* const impl = view->impl; + PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface; + + return surface->cr; +} + +PuglDrawContext puglGetX11CairoDrawContext(void) +{ + static const PuglDrawContext puglX11CairoDrawContext = { + puglX11CairoConfigure, + puglX11CairoCreate, + puglX11CairoDestroy, + puglX11CairoEnter, + puglX11CairoLeave, + puglX11CairoResize, + puglX11CairoGetHandle + }; + + return puglX11CairoDrawContext; +} diff --git a/pugl/pugl_x11_cairo.h b/pugl/pugl_x11_cairo.h new file mode 100644 index 0000000..ffad90b --- /dev/null +++ b/pugl/pugl_x11_cairo.h @@ -0,0 +1,22 @@ +/* + 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. +*/ + +#ifndef PUGL_X11_CAIRO_H +#define PUGL_X11_CAIRO_H + +PuglDrawContext puglGetX11CairoDrawContext(void); + +#endif // PUGL_X11_CAIRO_H 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; +} diff --git a/pugl/pugl_x11_gl.h b/pugl/pugl_x11_gl.h new file mode 100644 index 0000000..cba6473 --- /dev/null +++ b/pugl/pugl_x11_gl.h @@ -0,0 +1,22 @@ +/* + 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. +*/ + +#ifndef PUGL_X11_GL_H +#define PUGL_X11_GL_H + +PuglDrawContext puglGetX11GlDrawContext(void); + +#endif // PUGL_X11_GL_H |