summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-08-27 07:09:58 +0000
committerDavid Robillard <d@drobilla.net>2014-08-27 07:09:58 +0000
commitb4dbb3616865cd236cda4f2e4ac806b3b4840b29 (patch)
tree4a78f8298e42b95a074844e44d69a2446cb5eea3
parentf25f829a3038db39c83ad8cc92dd5fdc4876751b (diff)
Cairo support on X11.
-rw-r--r--pugl/gl.h32
-rw-r--r--pugl/glu.h32
-rw-r--r--pugl/pugl.h37
-rw-r--r--pugl/pugl_internal.h13
-rw-r--r--pugl/pugl_x11.c173
-rw-r--r--pugl_cairo_test.c167
-rw-r--r--pugl_test.c9
-rw-r--r--wscript72
8 files changed, 430 insertions, 105 deletions
diff --git a/pugl/gl.h b/pugl/gl.h
new file mode 100644
index 0000000..9a6aeef
--- /dev/null
+++ b/pugl/gl.h
@@ -0,0 +1,32 @@
+/*
+ Copyright 2012-2014 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.
+*/
+
+/**
+ @file gl.h Portable header wrapper for gl.h.
+
+ Unfortunately, GL includes vary across platforms so this header allows for
+ pure portable programs.
+*/
+
+#ifdef __APPLE__
+# include "OpenGL/gl.h"
+#else
+# ifdef _WIN32
+# include <windows.h> /* Broken Windows GL headers require this */
+# endif
+# include "GL/gl.h"
+#endif
+
diff --git a/pugl/glu.h b/pugl/glu.h
new file mode 100644
index 0000000..0ed0055
--- /dev/null
+++ b/pugl/glu.h
@@ -0,0 +1,32 @@
+/*
+ Copyright 2012-2014 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.
+*/
+
+/**
+ @file gl.h Portable header wrapper for glu.h.
+
+ Unfortunately, GL includes vary across platforms so this header allows for
+ pure portable programs.
+*/
+
+#ifdef __APPLE__
+# include "OpenGL/glu.h"
+#else
+# ifdef _WIN32
+# include <windows.h> /* Broken Windows GL headers require this */
+# endif
+# include "GL/glu.h"
+#endif
+
diff --git a/pugl/pugl.h b/pugl/pugl.h
index 360f8e8..8cd8afb 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -23,20 +23,6 @@
#include <stdint.h>
-/*
- This API is pure portable C and contains no platform specific elements, or
- even a GL dependency. However, unfortunately GL includes vary across
- platforms so they are included here to allow for pure portable programs.
-*/
-#ifdef __APPLE__
-# include "OpenGL/gl.h"
-#else
-# ifdef _WIN32
-# include <windows.h> /* Broken Windows GL headers require this */
-# endif
-# include "GL/gl.h"
-#endif
-
#ifdef PUGL_SHARED
# ifdef _WIN32
# define PUGL_LIB_IMPORT __declspec(dllimport)
@@ -88,6 +74,14 @@ typedef enum {
} PuglStatus;
/**
+ Drawing context type.
+*/
+typedef enum {
+ PUGL_GL,
+ PUGL_CAIRO
+} PuglContextType;
+
+/**
Convenience symbols for ASCII control characters.
*/
typedef enum {
@@ -247,6 +241,12 @@ PUGL_API void
puglInitResizable(PuglView* view, bool resizable);
/**
+ Set the context type before creating a window.
+*/
+PUGL_API void
+puglInitContextType(PuglView* view, PuglContextType type);
+
+/**
Create a window with the settings given by the various puglInit functions.
@return 1 (pugl does not currently support multiple windows).
@@ -285,6 +285,15 @@ PUGL_API PuglHandle
puglGetHandle(PuglView* view);
/**
+ Get the drawing context.
+
+ For PUGL_GL contexts, this is unused and returns NULL.
+ For PUGL_CAIRO contexts, this returns a pointer to a cairo_t.
+*/
+PUGL_API void*
+puglGetContext(PuglView* view);
+
+/**
Return the timestamp (if any) of the currently-processing event.
*/
PUGL_API uint32_t
diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h
index b86533a..3db08f7 100644
--- a/pugl/pugl_internal.h
+++ b/pugl/pugl_internal.h
@@ -25,7 +25,9 @@
symbols can be defined to tweak pugl behaviour:
PUGL_GRAB_FOCUS: Work around reparent keyboard issues by grabbing focus.
- PUGL_VERBOSE: Print GL information to console.
+ PUGL_VERBOSE: Print graphics information to console.
+ PUGL_HAVE_CAIRO: Include Cairo support code.
+ PUGL_HAVE_GL: Include OpenGL support code.
*/
#include "pugl.h"
@@ -55,6 +57,7 @@ struct PuglViewImpl {
PuglInternals* impl;
PuglNativeWindow parent;
+ PuglContextType ctx_type;
int width;
int height;
@@ -110,6 +113,12 @@ puglInitResizable(PuglView* view, bool resizable)
}
void
+puglInitContextType(PuglView* view, PuglContextType type)
+{
+ view->ctx_type = type;
+}
+
+void
puglSetHandle(PuglView* view, PuglHandle handle)
{
view->handle = handle;
@@ -136,6 +145,7 @@ puglGetModifiers(PuglView* view)
void
puglDefaultReshape(PuglView* view, int width, int height)
{
+#ifdef PUGL_HAVE_GL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
@@ -143,6 +153,7 @@ puglDefaultReshape(PuglView* view, int width, int height)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+#endif
return;
// unused
diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c
index e29e3bd..509e527 100644
--- a/pugl/pugl_x11.c
+++ b/pugl/pugl_x11.c
@@ -24,46 +24,34 @@
#include <stdlib.h>
#include <string.h>
-#include <GL/gl.h>
-#include <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#include <X11/keysym.h>
+#ifdef PUGL_HAVE_GL
+#include <GL/gl.h>
+#include <GL/glx.h>
+#endif
+
+#ifdef PUGL_HAVE_CAIRO
+#include <cairo/cairo.h>
+#include <cairo/cairo-xlib.h>
+#endif
+
#include "pugl_internal.h"
struct PuglInternalsImpl {
Display* display;
int screen;
Window win;
+#ifdef PUGL_HAVE_CAIRO
+ cairo_t* cr;
+#endif
+#ifdef PUGL_HAVE_GL
GLXContext ctx;
Bool doubleBuffered;
-};
-
-/**
- Attributes for single-buffered RGBA with at least
- 4 bits per color and a 16 bit depth buffer.
-*/
-static int attrListSgl[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- GLX_DEPTH_SIZE, 16,
- None
-};
-
-/**
- Attributes for double-buffered RGBA with at least
- 4 bits per color and a 16 bit depth buffer.
-*/
-static int attrListDbl[] = {
- GLX_RGBA, GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- GLX_DEPTH_SIZE, 16,
- None
+#endif
};
PuglInternals*
@@ -80,21 +68,49 @@ puglCreateWindow(PuglView* view, const char* title)
impl->display = XOpenDisplay(0);
impl->screen = DefaultScreen(impl->display);
- XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
- if (!vi) {
- vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
- impl->doubleBuffered = False;
- PUGL_LOG("no double-buffering available, using single-buffering\n");
- } else {
- impl->doubleBuffered = True;
- PUGL_LOG("using double-buffered rendering\n");
+ XVisualInfo* vi = NULL;
+
+#ifdef PUGL_HAVE_GL
+ if (view->ctx_type == PUGL_GL) {
+ // Try to create double-buffered visual
+ int double_attrs[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ None };
+ vi = glXChooseVisual(impl->display, impl->screen, double_attrs);
+ if (!vi) {
+ // Failed, create single-buffered visual
+ int single_attrs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ None };
+ vi = glXChooseVisual(impl->display, impl->screen, single_attrs);
+ impl->doubleBuffered = False;
+ } else {
+ impl->doubleBuffered = True;
+ }
+
+ impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
+ PUGL_LOGF("GLX depth %d, %s-buffered, %s\n",
+ vi->depth,
+ impl->doubleBuffered ? "double" : "single",
+ (glXIsDirect(impl->display, impl->ctx)
+ ? "direct (set LIBGL_ALWAYS_INDIRECT=1 to disable)"
+ : "indirect"));
}
-
- int glxMajor, glxMinor;
- glXQueryVersion(impl->display, &glxMajor, &glxMinor);
- PUGL_LOGF("GLX Version %d.%d\n", glxMajor, glxMinor);
-
- impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
+#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
Window xParent = view->parent
? (Window)view->parent
@@ -105,10 +121,10 @@ puglCreateWindow(PuglView* view, const char* title)
XSetWindowAttributes attr;
memset(&attr, 0, sizeof(XSetWindowAttributes));
- attr.colormap = cmap;
- attr.border_pixel = 0;
-
- attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask
+ attr.background_pixel = BlackPixel(impl->display, impl->screen);
+ attr.border_pixel = BlackPixel(impl->display, impl->screen);
+ attr.colormap = cmap;
+ attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask
| ButtonPressMask | ButtonReleaseMask
#ifdef PUGL_GRAB_FOCUS
| EnterWindowMask
@@ -118,7 +134,17 @@ puglCreateWindow(PuglView* view, const char* title)
impl->win = XCreateWindow(
impl->display, xParent,
0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual,
- CWBorderPixel | CWColormap | CWEventMask, &attr);
+ CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+#ifdef PUGL_HAVE_CAIRO
+ if (view->ctx_type == PUGL_CAIRO) {
+ cairo_surface_t* surface = cairo_xlib_surface_create(
+ impl->display, impl->win, vi->visual, view->width, view->height);
+ if (!(impl->cr = cairo_create(surface))) {
+ fprintf(stderr, "failed to create cairo context\n");
+ }
+ }
+#endif
XSizeHints sizeHints;
memset(&sizeHints, 0, sizeof(sizeHints));
@@ -140,12 +166,6 @@ puglCreateWindow(PuglView* view, const char* title)
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1);
}
- if (glXIsDirect(impl->display, impl->ctx)) {
- PUGL_LOG("DRI enabled (set LIBGL_ALWAYS_INDIRECT=1 to disable)\n");
- } else {
- PUGL_LOG("no DRI available\n");
- }
-
XFree(vi);
return 0;
@@ -174,7 +194,12 @@ puglDestroy(PuglView* view)
return;
}
- glXDestroyContext(view->impl->display, view->impl->ctx);
+#ifdef PUGL_HAVE_GL
+ if (view->ctx_type == PUGL_GL) {
+ glXDestroyContext(view->impl->display, view->impl->ctx);
+ }
+#endif
+
XDestroyWindow(view->impl->display, view->impl->win);
XCloseDisplay(view->impl->display);
free(view->impl);
@@ -184,7 +209,11 @@ puglDestroy(PuglView* view)
static void
puglReshape(PuglView* view, int width, int height)
{
- glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
+#ifdef PUGL_HAVE_GL
+ if (view->ctx_type == PUGL_GL) {
+ glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
+ }
+#endif
if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
@@ -199,20 +228,27 @@ puglReshape(PuglView* view, int width, int height)
static void
puglDisplay(PuglView* view)
{
- glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
+#ifdef PUGL_HAVE_GL
+ if (view->ctx_type == PUGL_GL) {
+ glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ }
+#endif
if (view->displayFunc) {
view->displayFunc(view);
}
+ view->redisplay = false;
- glFlush();
- if (view->impl->doubleBuffered) {
- glXSwapBuffers(view->impl->display, view->impl->win);
+#ifdef PUGL_HAVE_GL
+ if (view->ctx_type == PUGL_GL) {
+ glFlush();
+ if (view->impl->doubleBuffered) {
+ glXSwapBuffers(view->impl->display, view->impl->win);
+ }
}
-
- view->redisplay = false;
+#endif
}
static PuglKey
@@ -402,3 +438,14 @@ puglGetNativeWindow(PuglView* view)
{
return view->impl->win;
}
+
+void*
+puglGetContext(PuglView* view)
+{
+#ifdef PUGL_HAVE_CAIRO
+ if (view->ctx_type == PUGL_CAIRO) {
+ return view->impl->cr;
+ }
+#endif
+ return NULL;
+}
diff --git a/pugl_cairo_test.c b/pugl_cairo_test.c
new file mode 100644
index 0000000..6ff5bd5
--- /dev/null
+++ b/pugl_cairo_test.c
@@ -0,0 +1,167 @@
+/*
+ Copyright 2012-2014 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.
+*/
+
+/**
+ @file pugl_cairo_test.c A simple Pugl test that creates a top-level window.
+*/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cairo/cairo.h>
+
+#include "pugl/pugl.h"
+
+static int quit = 0;
+
+typedef struct {
+ int x;
+ int y;
+ int w;
+ int h;
+ bool pressed;
+ const char* label;
+} Button;
+
+static Button toggle_button = { 16, 16, 128, 64, false, "Test" };
+
+static void
+roundedBox(cairo_t* cr, double x, double y, double w, double h)
+{
+ static const double radius = 10;
+ static const double degrees = 3.14159265 / 180.0;
+
+ cairo_new_sub_path(cr);
+ cairo_arc(cr,
+ x + w - radius,
+ y + radius,
+ radius, -90 * degrees, 0 * degrees);
+ cairo_arc(cr,
+ x + w - radius, y + h - radius,
+ radius, 0 * degrees, 90 * degrees);
+ cairo_arc(cr,
+ x + radius, y + h - radius,
+ radius, 90 * degrees, 180 * degrees);
+ cairo_arc(cr,
+ x + radius, y + radius,
+ radius, 180 * degrees, 270 * degrees);
+ cairo_close_path(cr);
+}
+
+static void
+drawButton(cairo_t* cr, const Button* but)
+{
+ // Draw base
+ if (but->pressed) {
+ cairo_set_source_rgba(cr, 0.4, 0.9, 0.1, 1);
+ } else {
+ cairo_set_source_rgba(cr, 0.3, 0.5, 0.1, 1);
+ }
+ roundedBox(cr, but->x, but->y, but->w, but->h);
+ cairo_fill_preserve(cr);
+
+ // Draw border
+ cairo_set_source_rgba(cr, 0.4, 0.9, 0.1, 1);
+ cairo_set_line_width(cr, 4.0);
+ cairo_stroke(cr);
+
+ // Draw label
+ cairo_text_extents_t extents;
+ cairo_set_font_size(cr, 32.0);
+ cairo_text_extents(cr, but->label, &extents);
+ cairo_move_to(cr,
+ (but->x + but->w / 2) - extents.width / 2,
+ (but->y + but->h / 2) + extents.height / 2);
+ cairo_set_source_rgba(cr, 0, 0, 0, 1);
+ cairo_show_text(cr, but->label);
+}
+
+static void
+onDisplay(PuglView* view)
+{
+ cairo_t* cr = puglGetContext(view);
+
+ drawButton(cr, &toggle_button);
+}
+
+static void
+onKeyboard(PuglView* view, bool press, uint32_t key)
+{
+ if (key == 'q' || key == 'Q' || key == PUGL_CHAR_ESCAPE) {
+ quit = 1;
+ }
+}
+
+static void
+onMouse(PuglView* view, int button, bool press, int x, int y)
+{
+ if (press &&
+ x >= toggle_button.x && x <= toggle_button.x + toggle_button.w &&
+ y >= toggle_button.y && y <= toggle_button.y + toggle_button.h) {
+ toggle_button.pressed = !toggle_button.pressed;
+ puglPostRedisplay(view);
+ }
+}
+
+static void
+onClose(PuglView* view)
+{
+ quit = 1;
+}
+
+int
+main(int argc, char** argv)
+{
+ bool ignoreKeyRepeat = false;
+ bool resizable = false;
+ for (int i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "-h")) {
+ printf("USAGE: %s [OPTIONS]...\n\n"
+ " -h Display this help\n"
+ " -i Ignore key repeat\n"
+ " -r Resizable window\n", argv[0]);
+ return 0;
+ } else if (!strcmp(argv[i], "-i")) {
+ ignoreKeyRepeat = true;
+ } else if (!strcmp(argv[i], "-r")) {
+ resizable = true;
+ } else {
+ fprintf(stderr, "Unknown option: %s\n", argv[i]);
+ }
+ }
+
+ PuglView* view = puglInit(NULL, NULL);
+ puglInitWindowSize(view, 512, 512);
+ puglInitResizable(view, resizable);
+ puglInitContextType(view, PUGL_CAIRO);
+
+ puglIgnoreKeyRepeat(view, ignoreKeyRepeat);
+ puglSetKeyboardFunc(view, onKeyboard);
+ puglSetMouseFunc(view, onMouse);
+ puglSetDisplayFunc(view, onDisplay);
+ puglSetCloseFunc(view, onClose);
+
+ puglCreateWindow(view, "Pugl Test");
+ puglShowWindow(view);
+
+ while (!quit) {
+ puglProcessEvents(view);
+ }
+
+ puglDestroy(view);
+ return 0;
+}
diff --git a/pugl_test.c b/pugl_test.c
index 9282420..aa7997d 100644
--- a/pugl_test.c
+++ b/pugl_test.c
@@ -22,13 +22,8 @@
#include <string.h>
#include "pugl/pugl.h"
-
-// Argh!
-#ifdef __APPLE__
-# include <OpenGL/glu.h>
-#else
-# include <GL/glu.h>
-#endif
+#include "pugl/gl.h"
+#include "pugl/glu.h"
static int quit = 0;
static float xAngle = 0.0f;
diff --git a/wscript b/wscript
index 7da324d..cebf807 100644
--- a/wscript
+++ b/wscript
@@ -30,13 +30,17 @@ def options(opt):
if Options.platform == 'win32':
opt.load('compiler_cxx')
autowaf.set_options(opt)
+ opt.add_option('--no-gl', action='store_true', default=False, dest='no_gl',
+ help='Do not build OpenGL support')
+ opt.add_option('--no-cairo', action='store_true', default=False, dest='no_cairo',
+ help='Do not build Cairo support')
opt.add_option('--test', action='store_true', default=False, dest='build_tests',
help='Build unit tests')
opt.add_option('--static', action='store_true', default=False, dest='static',
help='Build static library')
opt.add_option('--shared', action='store_true', default=False, dest='shared',
help='Build shared library')
- opt.add_option('--verbose', action='store_true', default=False, dest='verbose',
+ opt.add_option('--log', action='store_true', default=False, dest='log',
help='Print GL information to console')
opt.add_option('--grab-focus', action='store_true', default=False, dest='grab_focus',
help='Work around reparent keyboard issues by grabbing focus')
@@ -46,15 +50,28 @@ def configure(conf):
if Options.platform == 'win32':
conf.load('compiler_cxx')
autowaf.configure(conf)
+ autowaf.set_c99_mode(conf)
autowaf.display_header('Pugl Configuration')
- if conf.env['MSVC_COMPILER']:
- conf.env.append_unique('CFLAGS', ['-TP', '-MD'])
- else:
- conf.env.append_unique('CFLAGS', '-std=c99')
-
- if Options.options.verbose:
- autowaf.define(conf, 'PUGL_VERBOSE', PUGL_VERBOSE)
+ if not Options.options.no_gl:
+ conf.check(function_name = 'glLoadIdentity',
+ header_name = 'GL/gl.h',
+ define_name = 'HAVE_GL',
+ lib = ['GL'],
+ mandatory = False)
+ if conf.is_defined('HAVE_GL'):
+ autowaf.define(conf, 'PUGL_HAVE_GL', 1)
+
+ if not Options.options.no_cairo:
+ autowaf.check_pkg(conf, 'cairo',
+ uselib_store = 'CAIRO',
+ atleast_version = '1.0.0',
+ mandatory = False)
+ if conf.is_defined('HAVE_CAIRO'):
+ autowaf.define(conf, 'PUGL_HAVE_CAIRO', 1)
+
+ if Options.options.log:
+ autowaf.define(conf, 'PUGL_VERBOSE', 1)
# Shared library building is broken on win32 for some reason
conf.env['BUILD_TESTS'] = Options.options.build_tests
@@ -71,6 +88,9 @@ def configure(conf):
conf.env['LIBPATH_PUGL'] = [conf.env['LIBDIR']]
conf.env['LIB_PUGL'] = ['pugl-%s' % PUGL_MAJOR_VERSION];
+ autowaf.display_msg(conf, "OpenGL support", conf.is_defined('HAVE_GL'))
+ autowaf.display_msg(conf, "Cairo support", conf.is_defined('HAVE_CAIRO'))
+ autowaf.display_msg(conf, "Verbose console output", conf.is_defined('PUGL_VERBOSE'))
autowaf.display_msg(conf, "Static library", str(conf.env['BUILD_STATIC']))
autowaf.display_msg(conf, "Unit tests", str(conf.env['BUILD_TESTS']))
print('')
@@ -100,8 +120,10 @@ def build(bld):
else:
lang = 'c'
lib_source = ['pugl/pugl_x11.c']
- libs = ['X11', 'GL', 'GLU']
+ libs = ['X11']
defines = []
+ if bld.is_defined('HAVE_GL'):
+ libs += ['GL', 'GLU']
if bld.env['MSVC_COMPILER']:
libflags = []
@@ -112,6 +134,7 @@ def build(bld):
source = lib_source,
includes = ['.', './src'],
lib = libs,
+ uselib = ['CAIRO'],
framework = framework,
name = 'libpugl',
target = 'pugl-%s' % PUGL_MAJOR_VERSION,
@@ -128,6 +151,7 @@ def build(bld):
source = lib_source,
includes = ['.', './src'],
lib = libs,
+ uselib = ['CAIRO'],
framework = framework,
name = 'libpugl_static',
target = 'pugl-%s' % PUGL_MAJOR_VERSION,
@@ -140,17 +164,25 @@ def build(bld):
test_libs = libs
test_cflags = ['']
- # Unit test program
- obj = bld(features = 'c cprogram',
- source = 'pugl_test.c',
- includes = ['.', './src'],
- use = 'libpugl_static',
- lib = test_libs,
- framework = framework,
- target = 'pugl_test',
- install_path = '',
- defines = defines,
- cflags = test_cflags)
+ # Test programs
+ progs = []
+ if bld.is_defined('HAVE_GL'):
+ progs += ['pugl_test']
+ if bld.is_defined('HAVE_CAIRO'):
+ progs += ['pugl_cairo_test']
+
+ for prog in progs:
+ obj = bld(features = 'c cprogram',
+ source = '%s.c' % prog,
+ includes = ['.', './src'],
+ use = 'libpugl_static',
+ lib = test_libs,
+ uselib = ['CAIRO'],
+ framework = framework,
+ target = prog,
+ install_path = '',
+ defines = defines,
+ cflags = test_cflags)
def lint(ctx):
subprocess.call('cpplint.py --filter=+whitespace/comments,-whitespace/tab,-whitespace/braces,-whitespace/labels,-build/header_guard,-readability/casting,-readability/todo,-build/include src/* pugl/*', shell=True)