summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-04-28 23:34:25 +0000
committerDavid Robillard <d@drobilla.net>2012-04-28 23:34:25 +0000
commit43083a0ca80a876286b6a6ef39ec6f10c9b6f9bf (patch)
treecd835b2ce67291826979ce6fa8a15de046bc6151
parent0ed09c95b5d94eb4e109bd402de00c46036b8239 (diff)
Initial import.
-rw-r--r--pugl.pc.in10
-rw-r--r--pugl/pugl.h154
-rw-r--r--pugl/pugl_internal.h92
-rw-r--r--pugl/pugl_x11.c242
-rw-r--r--pugl_test.c88
-rwxr-xr-xwafbin0 -> 92192 bytes
-rw-r--r--wscript126
7 files changed, 712 insertions, 0 deletions
diff --git a/pugl.pc.in b/pugl.pc.in
new file mode 100644
index 0000000..d3606cd
--- /dev/null
+++ b/pugl.pc.in
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: Pugl
+Version: @PUGL_VERSION@
+Description: Lightweight portable OpenGL API
+Libs: -L${libdir} -l@LIB_PUGL@
+Cflags: -I${includedir}/pugl-@PUGL_MAJOR_VERSION@
diff --git a/pugl/pugl.h b/pugl/pugl.h
new file mode 100644
index 0000000..853a754
--- /dev/null
+++ b/pugl/pugl.h
@@ -0,0 +1,154 @@
+/*
+ Copyright 2012 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.h API for Pugl, a portable micro-framework for GL UIs.
+*/
+
+#ifndef PUGL_H_INCLUDED
+#define PUGL_H_INCLUDED
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#else
+# include <stdbool.h>
+#endif
+
+typedef struct PuglWindowImpl PuglWindow;
+
+/**
+ A native window handle.
+
+ For X11, this is a Window.
+*/
+typedef intptr_t PuglNativeWindow;
+
+typedef enum {
+ PUGL_SUCCESS = 0
+} PuglStatus;
+
+/**
+ Handle for opaque user data.
+*/
+typedef void* PuglHandle;
+
+typedef void (*PuglCloseFunc)(PuglWindow* handle);
+typedef void (*PuglDisplayFunc)(PuglWindow* handle);
+typedef void (*PuglKeyboardFunc)(PuglWindow* handle, bool press, uint32_t key);
+typedef void (*PuglMotionFunc)(PuglWindow* handle, int x, int y);
+typedef void (*PuglMouseFunc)(PuglWindow* handle,
+ int button, int state,
+ int x, int y);
+typedef void (*PuglReshapeFunc)(PuglWindow* handle, int width, int height);
+
+/**
+ Create a new GL window.
+ @param parent Parent window, or 0 for top level.
+ @param title Window title, or NULL.
+ @param width Window width in pixels.
+ @param height Window height in pixels.
+*/
+PuglWindow*
+puglCreate(PuglNativeWindow parent, const char* title, int width, int height);
+
+/**
+ Set the handle to be passed to all callbacks.
+
+ This is generally a pointer to a struct which contains all necessary state.
+ Everything needed in callbacks should be here, not in static variables.
+
+ Note the lack of this facility makes GLUT unsuitable for plugins or
+ non-trivial programs; this mistake is largely why Pugl exists.
+*/
+void
+puglSetHandle(PuglWindow* window, PuglHandle handle);
+
+/**
+ Get the handle to be passed to all callbacks.
+*/
+PuglHandle
+puglGetHandle(PuglWindow* window);
+
+/**
+ Set the function to call when the window is closed.
+*/
+void
+puglSetCloseFunc(PuglWindow* window, PuglCloseFunc closeFunc);
+
+/**
+ Set the display function which should draw the UI using GL.
+*/
+void
+puglSetDisplayFunc(PuglWindow* window, PuglDisplayFunc displayFunc);
+
+/**
+ Set the function to call on keyboard events.
+*/
+void
+puglSetKeyboardFunc(PuglWindow* window, PuglKeyboardFunc keyboardFunc);
+
+/**
+ Set the function to call on mouse motion.
+*/
+void
+puglSetMotionFunc(PuglWindow* window, PuglMotionFunc motionFunc);
+
+/**
+ Set the function to call on mouse button events.
+*/
+void
+puglSetMouseFunc(PuglWindow* window, PuglMouseFunc mouseFunc);
+
+/**
+ Set the function to call when the window size changes.
+*/
+void
+puglSetReshapeFunc(PuglWindow* window, PuglReshapeFunc reshapeFunc);
+
+/**
+ Return the native window handle.
+*/
+PuglNativeWindow
+puglGetNativeWindow(PuglWindow* win);
+
+/**
+ Process all pending window events.
+
+ This handles input events as well as rendering, so it should be called
+ regularly and rapidly enough to keep the UI responsive.
+*/
+PuglStatus
+puglProcessEvents(PuglWindow* win);
+
+/**
+ Request a redisplay on the next call to puglProcessEvents().
+*/
+void
+puglPostRedisplay(PuglWindow* win);
+
+/**
+ Destroy a GL window.
+*/
+void
+puglDestroy(PuglWindow* win);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PUGL_H_INCLUDED */
diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h
new file mode 100644
index 0000000..8a7b217
--- /dev/null
+++ b/pugl/pugl_internal.h
@@ -0,0 +1,92 @@
+/*
+ Copyright 2012 David Robillard <http://drobilla.net>
+ Copyright 2011-2012 Ben Loftis, Harrison Consoles
+
+ 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_internal.h Private platform-independent definitions.
+
+ Note this file contains function definitions, so it must be compiled into
+ the final binary exactly once. Each platform specific implementation file
+ including it once should achieve this.
+*/
+
+#include "pugl.h"
+
+typedef struct PuglPlatformDataImpl PuglPlatformData;
+
+struct PuglWindowImpl {
+ PuglHandle handle;
+ PuglCloseFunc closeFunc;
+ PuglDisplayFunc displayFunc;
+ PuglKeyboardFunc keyboardFunc;
+ PuglMotionFunc motionFunc;
+ PuglMouseFunc mouseFunc;
+ PuglReshapeFunc reshapeFunc;
+
+ PuglPlatformData* impl;
+
+ int width;
+ int height;
+ bool redisplay;
+};
+
+void
+puglSetHandle(PuglWindow* window, PuglHandle handle)
+{
+ window->handle = handle;
+}
+
+PuglHandle
+puglGetHandle(PuglWindow* window)
+{
+ return window->handle;
+}
+
+void
+puglSetCloseFunc(PuglWindow* window, PuglCloseFunc closeFunc)
+{
+ window->closeFunc = closeFunc;
+}
+
+void
+puglSetDisplayFunc(PuglWindow* window, PuglDisplayFunc displayFunc)
+{
+ window->displayFunc = displayFunc;
+}
+
+void
+puglSetKeyboardFunc(PuglWindow* window, PuglKeyboardFunc keyboardFunc)
+{
+ window->keyboardFunc = keyboardFunc;
+}
+
+void
+puglSetMotionFunc(PuglWindow* window, PuglMotionFunc motionFunc)
+{
+ window->motionFunc = motionFunc;
+}
+
+void
+puglSetMouseFunc(PuglWindow* window, PuglMouseFunc mouseFunc)
+{
+ window->mouseFunc = mouseFunc;
+}
+
+void
+puglSetReshapeFunc(PuglWindow* window, PuglReshapeFunc reshapeFunc)
+{
+ window->reshapeFunc = reshapeFunc;
+}
diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c
new file mode 100644
index 0000000..33f0b42
--- /dev/null
+++ b/pugl/pugl_x11.c
@@ -0,0 +1,242 @@
+/*
+ Copyright 2012 David Robillard <http://drobilla.net>
+ Copyright 2011-2012 Ben Loftis, Harrison Consoles
+
+ 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 <string.h>
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+#include "pugl_internal.h"
+
+struct PuglPlatformDataImpl {
+ Display* display;
+ int screen;
+ Window win;
+ 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
+};
+
+PuglWindow*
+puglCreate(PuglNativeWindow parent, const char* title, int width, int height)
+{
+ PuglWindow* win = (PuglWindow*)calloc(1, sizeof(PuglWindow));
+
+ win->impl = (PuglPlatformData*)calloc(1, sizeof(PuglPlatformData));
+
+ PuglPlatformData* impl = win->impl;
+
+ win->width = width;
+ win->height = height;
+ impl->display = XOpenDisplay(0);
+ impl->screen = DefaultScreen(impl->display);
+
+ XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
+ if (vi == NULL) {
+ vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
+ impl->doubleBuffered = False;
+ printf("singlebuffered rendering will be used, no doublebuffering available\n");
+ } else {
+ impl->doubleBuffered = True;
+ printf("doublebuffered rendering available\n");
+ }
+
+ int glxMajor, glxMinor;
+ glXQueryVersion(impl->display, &glxMajor, &glxMinor);
+ printf("GLX-Version %d.%d\n", glxMajor, glxMinor);
+
+ impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
+
+ Window xParent = parent
+ ? (Window)parent
+ : RootWindow(impl->display, impl->screen);
+
+ Colormap cmap = XCreateColormap(
+ impl->display, xParent, vi->visual, AllocNone);
+
+ XSetWindowAttributes attr;
+ memset(&attr, 0, sizeof(XSetWindowAttributes));
+ attr.colormap = cmap;
+ attr.border_pixel = 0;
+
+ attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask
+ | ButtonPressMask | PointerMotionMask | StructureNotifyMask;
+
+ impl->win = XCreateWindow(
+ impl->display, xParent,
+ 0, 0, win->width, win->height, 0, vi->depth, InputOutput, vi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &attr);
+
+ if (title) {
+ XStoreName(impl->display, impl->win, title);
+ }
+
+ if (!parent) {
+ Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True);
+ XSetWMProtocols(impl->display, impl->win, &wmDelete, 1);
+ }
+
+ XMapRaised(impl->display, impl->win);
+
+ if (glXIsDirect(impl->display, impl->ctx)) {
+ printf("DRI enabled\n");
+ } else {
+ printf("no DRI available\n");
+ }
+
+ return win;
+}
+
+void
+puglDestroy(PuglWindow* win)
+{
+ if (win->impl->ctx) {
+ if (!glXMakeCurrent(win->impl->display, None, NULL)) {
+ printf("Could not release drawing context.\n");
+ }
+ /* destroy the context */
+ glXDestroyContext(win->impl->display, win->impl->ctx);
+ win->impl->ctx = NULL;
+ }
+
+ XCloseDisplay(win->impl->display);
+ free(win);
+}
+
+void
+puglDisplay(PuglWindow* win)
+{
+ glXMakeCurrent(win->impl->display, win->impl->win, win->impl->ctx);
+ glViewport(0, 0, win->width, win->height);
+
+ if (win->displayFunc) {
+ win->displayFunc(win);
+ }
+
+ if (win->impl->doubleBuffered) {
+ glXSwapBuffers(win->impl->display, win->impl->win);
+ }
+}
+
+PuglStatus
+puglProcessEvents(PuglWindow* win)
+{
+ XEvent event;
+
+ /* handle the events in the queue */
+ while (XPending(win->impl->display) > 0) {
+ XNextEvent(win->impl->display, &event);
+ switch (event.type) {
+ case Expose:
+ if (event.xexpose.count != 0) {
+ break;
+ }
+ puglDisplay(win);
+ win->redisplay = false;
+ break;
+ case ConfigureNotify:
+ if ((event.xconfigure.width != win->width) ||
+ (event.xconfigure.height != win->height)) {
+ if (win->reshapeFunc) {
+ win->reshapeFunc(win,
+ event.xconfigure.width,
+ event.xconfigure.height);
+ }
+ }
+ break;
+ case MotionNotify:
+ if (win->motionFunc) {
+ win->motionFunc(win, event.xmotion.x, event.xmotion.y);
+ }
+ break;
+ case ButtonPress:
+ if (win->mouseFunc) {
+ win->mouseFunc(win,
+ event.xbutton.button, event.xbutton.state,
+ event.xbutton.x, event.xbutton.y);
+ }
+ break;
+ case KeyPress:
+ case KeyRelease:
+ if (win->keyboardFunc) {
+ KeySym sym = XKeycodeToKeysym(
+ win->impl->display, event.xkey.keycode, 0);
+ win->keyboardFunc(win, event.type == KeyPress, sym);
+ }
+ break;
+ case ClientMessage:
+ if (!strcmp(XGetAtomName(win->impl->display,
+ event.xclient.message_type),
+ "WM_PROTOCOLS")) {
+ if (win->closeFunc) {
+ win->closeFunc(win);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (win->redisplay) {
+ puglDisplay(win);
+ }
+
+ return PUGL_SUCCESS;
+}
+
+void
+puglPostRedisplay(PuglWindow* win)
+{
+ win->redisplay = true;
+}
+
+PuglNativeWindow
+puglGetNativeWindow(PuglWindow* win)
+{
+ return win->impl->win;
+}
diff --git a/pugl_test.c b/pugl_test.c
new file mode 100644
index 0000000..3122a89
--- /dev/null
+++ b/pugl_test.c
@@ -0,0 +1,88 @@
+/*
+ Copyright 2012 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_test.c A simple Pugl test that creates a top-level window.
+*/
+
+#include <stdio.h>
+
+#include "GL/gl.h"
+#include "pugl/pugl.h"
+
+static int quit = 0;
+static float xAngle = 0.0f;
+static float yAngle = 0.0f;
+
+#define KEY_ESCAPE 27
+
+static void
+onDisplay(PuglWindow* win)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+
+ glRotatef(xAngle, 1.0f, 0.0f, 0.0f);
+ glRotatef(xAngle, 0.0f, 1.0f, 0.0f);
+
+ glBegin(GL_TRIANGLES);
+ glColor3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, 1.0f, 0.0f);
+ glColor3f(0.0f, 1.0f, 0.0f);
+ glVertex3f(-1.0f, -1.0f, 0.0f);
+ glColor3f(0.0f, 0.0f, 1.0f);
+ glVertex3f(1.0f, -1.0f, 0.0f);
+ glEnd();
+}
+
+static void
+onKeyboard(PuglWindow* win, bool press, uint32_t key)
+{
+ if (key == 'q' || key == KEY_ESCAPE) {
+ quit = 1;
+ }
+}
+
+static void
+onMotion(PuglWindow* win, int x, int y)
+{
+ xAngle = x % 360;
+ yAngle = y % 360;
+ puglPostRedisplay(win);
+}
+
+static void
+onClose(PuglWindow* win)
+{
+ quit = 1;
+}
+
+int
+main(int argc, char** argv)
+{
+ PuglWindow* win = puglCreate(0, "Pugl Test", 512, 512);
+ puglSetKeyboardFunc(win, onKeyboard);
+ puglSetMotionFunc(win, onMotion);
+ puglSetDisplayFunc(win, onDisplay);
+ puglSetCloseFunc(win, onClose);
+
+ while (!quit) {
+ puglProcessEvents(win);
+ }
+
+ puglDestroy(win);
+ return 0;
+}
diff --git a/waf b/waf
new file mode 100755
index 0000000..32ae229
--- /dev/null
+++ b/waf
Binary files differ
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..1bf5b07
--- /dev/null
+++ b/wscript
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+import glob
+import os
+import sys
+
+from waflib.extras import autowaf as autowaf
+import waflib.Logs as Logs, waflib.Options as Options
+
+# Version of this package (even if built as a child)
+PUGL_VERSION = '0.0.0'
+PUGL_MAJOR_VERSION = '0'
+
+# Library version (UNIX style major, minor, micro)
+# major increment <=> incompatible changes
+# minor increment <=> compatible changes (additions)
+# micro increment <=> no interface changes
+# Pugl uses the same version number for both library and package
+PUGL_LIB_VERSION = PUGL_VERSION
+
+# Variables for 'waf dist'
+APPNAME = 'pugl'
+VERSION = PUGL_VERSION
+
+# Mandatory variables
+top = '.'
+out = 'build'
+
+def options(opt):
+ opt.load('compiler_c')
+ autowaf.set_options(opt)
+ 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")
+
+def configure(conf):
+ conf.load('compiler_c')
+ autowaf.configure(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')
+
+ conf.env['BUILD_TESTS'] = Options.options.build_tests
+ conf.env['BUILD_STATIC'] = (Options.options.build_tests or
+ Options.options.static)
+
+ autowaf.define(conf, 'PUGL_VERSION', PUGL_VERSION)
+ conf.write_config_header('pugl_config.h', remove=False)
+
+ conf.env['INCLUDES_PUGL'] = ['%s/pugl-%s' % (conf.env['INCLUDEDIR'],
+ PUGL_MAJOR_VERSION)]
+ conf.env['LIBPATH_PUGL'] = [conf.env['LIBDIR']]
+ conf.env['LIB_PUGL'] = ['pugl-%s' % PUGL_MAJOR_VERSION];
+
+ autowaf.display_msg(conf, "Static library", str(conf.env['BUILD_STATIC']))
+ autowaf.display_msg(conf, "Unit tests", str(conf.env['BUILD_TESTS']))
+ print('')
+
+def build(bld):
+ # C Headers
+ includedir = '${INCLUDEDIR}/pugl-%s/pugl' % PUGL_MAJOR_VERSION
+ bld.install_files(includedir, bld.path.ant_glob('pugl/*.h'))
+
+ # Pkgconfig file
+ autowaf.build_pc(bld, 'PUGL', PUGL_VERSION, PUGL_MAJOR_VERSION, [],
+ {'PUGL_MAJOR_VERSION' : PUGL_MAJOR_VERSION})
+
+ libflags = [ '-fvisibility=hidden' ]
+ libs = [ 'X11', 'GL' ]
+ defines = []
+ if bld.env['MSVC_COMPILER']:
+ libflags = []
+ libs = []
+ defines = ['snprintf=_snprintf']
+
+ lib_source = ['./pugl/pugl_x11.c']
+
+ # Shared Library
+ obj = bld(features = 'c cshlib',
+ export_includes = ['.'],
+ source = lib_source,
+ includes = ['.', './src'],
+ lib = libs,
+ name = 'libpugl',
+ target = 'pugl-%s' % PUGL_MAJOR_VERSION,
+ vnum = PUGL_LIB_VERSION,
+ install_path = '${LIBDIR}',
+ defines = defines,
+ cflags = libflags + [ '-DPUGL_SHARED',
+ '-DPUGL_INTERNAL' ])
+
+ # Static library
+ if bld.env['BUILD_STATIC']:
+ obj = bld(features = 'c cstlib',
+ export_includes = ['.'],
+ source = lib_source,
+ includes = ['.', './src'],
+ lib = libs,
+ name = 'libpugl_static',
+ target = 'pugl-%s' % PUGL_MAJOR_VERSION,
+ vnum = PUGL_LIB_VERSION,
+ install_path = '${LIBDIR}',
+ defines = defines,
+ cflags = ['-DPUGL_INTERNAL'])
+
+ if bld.env['BUILD_TESTS']:
+ 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,
+ target = 'pugl_test',
+ 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)
+