aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt144
-rw-r--r--canvas.c (renamed from test/canvas.c)2
-rw-r--r--canvas.lv2/canvas.h195
-rw-r--r--canvas.lv2/forge.h326
-rw-r--r--canvas.lv2/render.h592
-rw-r--r--canvas_display.ttl (renamed from test/canvas.ttl)3
-rw-r--r--canvas_display_ui.ttl (renamed from test/canvas_ui.ttl)6
-rw-r--r--canvas_ui.c (renamed from test/canvas_ui.c)2
-rw-r--r--cmake/arm-linux-gnueabihf.cmake23
-rw-r--r--cmake/i686-linux-gnu.cmake10
-rw-r--r--cmake/i686-w64-mingw32.cmake24
-rw-r--r--cmake/universal-apple-darwin.cmake23
-rw-r--r--cmake/x86_64-linux-gnu.cmake7
-rw-r--r--cmake/x86_64-w64-mingw32.cmake24
-rwxr-xr-xdocker_build.sh25
-rwxr-xr-xdocker_run.sh5
-rw-r--r--manifest.ttl.in (renamed from test/manifest.ttl.in)22
-rw-r--r--meson.build105
-rw-r--r--meson/arm-linux-gnueabihf18
-rw-r--r--meson/i686-linux-gnu19
-rw-r--r--meson/i686-w64-mingw3217
-rw-r--r--meson/universal-apple-darwin19
-rw-r--r--meson/x86_64-linux-gnu16
-rw-r--r--meson/x86_64-w64-mingw3217
-rw-r--r--pugl/.gitignore3
-rw-r--r--pugl/AUTHORS11
-rw-r--r--pugl/COPYING13
-rw-r--r--pugl/Doxyfile.in2415
-rw-r--r--pugl/README.md28
-rw-r--r--pugl/pugl.pc.in10
-rw-r--r--pugl/pugl/cairo_gl.h105
-rw-r--r--pugl/pugl/gl.h32
-rw-r--r--pugl/pugl/glew.h32
-rw-r--r--pugl/pugl/glu.h32
-rw-r--r--pugl/pugl/pugl.h622
-rw-r--r--pugl/pugl/pugl.hpp106
-rw-r--r--pugl/pugl/pugl_internal.h241
-rw-r--r--pugl/pugl/pugl_osx.m648
-rw-r--r--pugl/pugl/pugl_win.cpp644
-rw-r--r--pugl/pugl/pugl_x11.c721
-rw-r--r--pugl/pugl_cairo_test.c205
-rw-r--r--pugl/pugl_test.c261
-rwxr-xr-xpugl/wafbin97489 -> 0 bytes
-rw-r--r--pugl/wscript203
44 files changed, 229 insertions, 7747 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 21be30d..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,144 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-project(canvas.lv2)
-
-include_directories(${PROJECT_SOURCE_DIR})
-include_directories(${PROJECT_SOURCE_DIR}/pugl)
-include_directories(${PROJECT_SOURCE_DIR}/ardour.lv2)
-
-set(CMAKE_FIND_FRAMEWORK FIRST)
-
-set(CMAKE_C_FLAGS "-fdata-sections -ffunction-sections ${CMAKE_C_FLAGS}")
-set(CMAKE_C_FLAGS "-std=gnu11 -Wextra -Wno-unused-parameter -ffast-math -fvisibility=hidden ${CMAKE_C_FLAGS}")
-set(CMAKE_C_FLAGS "-Wshadow -Wimplicit-function-declaration -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes ${CMAKE_C_FLAGS}")
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
- set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-z,defs ${CMAKE_MODULE_LINKER_FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-z,nodelete ${CMAKE_MODULE_LINKER_FLAGS}")
-elseif(WIN32)
- set(CMAKE_C_FLAGS "-mstackrealign ${CMAKE_C_FLAGS}")
-endif()
-
-if(CMAKE_BUILD_TYPE STREQUAL "Release")
- if(APPLE)
- set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-dead_strip ${CMAKE_MODULE_LINKER_FLAGS}")
- else()
- set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections -Wl,-s ${CMAKE_MODULE_LINKER_FLAGS}")
- endif()
-endif()
-
-add_definitions("-D_GNU_SOURCE=1") # asprintf
-
-if(WIN32)
- set(CANVAS_UI_TYPE "WindowsUI")
-elseif(APPLE)
- set(CANVAS_UI_TYPE "CocoaUI")
-else()
- set(CANVAS_UI_TYPE "X11UI")
-endif()
-
-file(STRINGS "VERSION" CANVAS_VERSION)
-string(REPLACE "." ";" VERSION_LIST ${CANVAS_VERSION})
-list(GET VERSION_LIST 0 CANVAS_MAJOR_VERSION)
-list(GET VERSION_LIST 1 CANVAS_MINOR_VERSION)
-list(GET VERSION_LIST 2 CANVAS_MICRO_VERSION)
-add_definitions("-DCANVAS_VERSION=\"${CANVAS_VERSION}\"")
-
-if(NOT DEFINED PLUGIN_DEST)
- set(PLUGIN_DEST lib/lv2/canvas.lv2)
-endif()
-
-find_package(PkgConfig) # ${PKG_CONFIG_FOUND}
-
-set(LIBS m)
-set(LIBS_UI m)
-set(TAR_UI test/canvas_ui.c)
-
-pkg_search_module(LV2 REQUIRED lv2>=1.10)
-include_directories(${LV2_INCLUDE_DIRS})
-
-pkg_search_module(CAIRO REQUIRED cairo>=1.14)
-include_directories(${CAIRO_INCLUDE_DIRS})
-if(DEFINED STATIC_CAIRO)
- set(LIBS ${STATIC_CAIRO} ${STATIC_PIXMAN} ${LIBS})
- set(LIBS_UI ${STATIC_CAIRO} ${STATIC_PIXMAN} ${LIBS})
-
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- set(LIBS ${LIBS} pthread)
- set(LIBS_UI ${LIBS_UI} pthread)
- endif()
-else()
- set(LIBS ${LIBS} ${CAIRO_LDFLAGS})
- set(LIBS_UI ${LIBS_UI} ${CAIRO_LDFLAGS})
-endif()
-add_definitions("-DPUGL_HAVE_CAIRO")
-
-find_package(OpenGL)
-if(${OPENGL_FOUND})
- set(LIBS_UI ${LIBS_UI} ${OPENGL_LIBRARIES})
- add_definitions("-DPUGL_HAVE_GL")
-else()
- message(STATUS "OpenGL not found")
-endif()
-
-if(WIN32)
- find_library(GDI32_LIBRARY NAMES gdi32)
- if(GDI32_LIBRARY)
- set(LIBS_UI ${LIBS_UI} ${GDI32_LIBRARY})
- else()
- message(FATAL_ERROR "gdi32 library not found")
- endif()
-
- find_library(USER32_LIBRARY NAMES user32)
- if(USER32_LIBRARY)
- set(LIBS_UI ${LIBS_UI} ${USER32_LIBRARY})
- else()
- message(FATAL_ERROR "user32 library not found")
- endif()
-
- set(TAR_UI ${TAR_UI} pugl/pugl/pugl_win.cpp)
-
-elseif(APPLE)
- find_library(COCOA_LIBRARY NAMES Cocoa)
- if(COCOA_LIBRARY)
- set(LIBS_UI ${LIBS_UI} ${COCOA_LIBRARY})
- else()
- message(FATAL_ERROR "Cocoa framework not found")
- endif()
-
- set(TAR_UI ${TAR_UI} pugl/pugl/pugl_osx.m)
-
-else() # GNU/Linux
- pkg_search_module(X11 REQUIRED x11>=1.6)
- include_directories(${X11_INCLUDE_DIRS})
- set(LIBS_UI ${LIBS_UI} ${X11_LDFLAGS})
-
- pkg_search_module(XEXT REQUIRED xext>=1.3)
- include_directories(${XEXT_INCLUDE_DIRS})
- set(LIBS_UI ${LIBS_UI} ${XEXT_LDFLAGS})
-
- set(TAR_UI ${TAR_UI} pugl/pugl/pugl_x11.c)
-endif()
-
-add_library(canvas MODULE test/canvas.c)
-target_link_libraries(canvas ${LIBS})
-set_target_properties(canvas PROPERTIES PREFIX "")
-set_target_properties(canvas PROPERTIES INTERPROCEDURAL_OPTIMIZATION true) # -flto
-if(NOT WIN32)
-set_target_properties(canvas PROPERTIES LINK_FLAGS "-Wl,-e,lv2_descriptor")
-endif()
-install(TARGETS canvas DESTINATION ${PLUGIN_DEST})
-
-add_library(canvas_ui MODULE ${TAR_UI})
-target_link_libraries(canvas_ui ${LIBS_UI})
-set_target_properties(canvas_ui PROPERTIES PREFIX "")
-set_target_properties(canvas_ui PROPERTIES INTERPROCEDURAL_OPTIMIZATION true) # -flto
-if(NOT WIN32)
-set_target_properties(canvas_ui PROPERTIES LINK_FLAGS "-Wl,-e,lv2ui_descriptor")
-endif()
-install(TARGETS canvas_ui DESTINATION ${PLUGIN_DEST})
-
-configure_file(${PROJECT_SOURCE_DIR}/test/manifest.ttl.in ${PROJECT_BINARY_DIR}/manifest.ttl)
-install(FILES ${PROJECT_BINARY_DIR}/manifest.ttl DESTINATION ${PLUGIN_DEST})
-install(FILES ${PROJECT_SOURCE_DIR}/test/canvas.ttl DESTINATION ${PLUGIN_DEST})
-install(FILES ${PROJECT_SOURCE_DIR}/test/canvas_ui.ttl DESTINATION ${PLUGIN_DEST})
diff --git a/test/canvas.c b/canvas.c
index 6186c9a..af2df7b 100644
--- a/test/canvas.c
+++ b/canvas.c
@@ -695,7 +695,7 @@ extension_data(const char *uri)
}
const LV2_Descriptor canvas_canvas = {
- .URI = CANVAS_PREFIX"canvas",
+ .URI = "http://open-music-kontrollers.ch/lv2/canvas_display#canvas",
.instantiate = instantiate,
.connect_port = connect_port,
.activate = NULL,
diff --git a/canvas.lv2/canvas.h b/canvas.lv2/canvas.h
deleted file mode 100644
index 7cca0fa..0000000
--- a/canvas.lv2/canvas.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the Artistic License 2.0 as published by
- * The Perl Foundation.
- *
- * This source is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Artistic License 2.0 for more details.
- *
- * You should have received a copy of the Artistic License 2.0
- * along the source as a COPYING file. If not, obtain it from
- * http://www.perlfoundation.org/artistic_license_2_0.
- */
-
-#ifndef _LV2_CANVAS_H
-#define _LV2_CANVAS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
-#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
-#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
-
-#define CANVAS_URI "http://open-music-kontrollers.ch/lv2/canvas"
-#define CANVAS_PREFIX CANVAS_URI"#"
-
-#define CANVAS__graph CANVAS_PREFIX"graph"
-#define CANVAS__body CANVAS_PREFIX"body"
-#define CANVAS__aspectRatio CANVAS_PREFIX"aspectRatio"
-
-// Graph properties and attributes
-#define CANVAS__BeginPath CANVAS_PREFIX"BeginPath"
-#define CANVAS__ClosePath CANVAS_PREFIX"ClosePath"
-#define CANVAS__Arc CANVAS_PREFIX"Arc"
-#define CANVAS__CurveTo CANVAS_PREFIX"CurveTo"
-#define CANVAS__LineTo CANVAS_PREFIX"LineTo"
-#define CANVAS__MoveTo CANVAS_PREFIX"MoveTo"
-#define CANVAS__Rectangle CANVAS_PREFIX"Rectangle"
-#define CANVAS__PolyLine CANVAS_PREFIX"PolyLine"
-#define CANVAS__Style CANVAS_PREFIX"Style"
-#define CANVAS__LineWidth CANVAS_PREFIX"LineWidth"
-#define CANVAS__LineDash CANVAS_PREFIX"LineDash"
-#define CANVAS__LineCap CANVAS_PREFIX"LineCap"
-#define CANVAS__LineJoin CANVAS_PREFIX"LineJoin"
-#define CANVAS__MiterLimit CANVAS_PREFIX"MiterLimig"
-#define CANVAS__Stroke CANVAS_PREFIX"Stroke"
-#define CANVAS__Fill CANVAS_PREFIX"Fill"
-#define CANVAS__Clip CANVAS_PREFIX"Clip"
-#define CANVAS__Save CANVAS_PREFIX"Save"
-#define CANVAS__Restore CANVAS_PREFIX"Restore"
-#define CANVAS__Translate CANVAS_PREFIX"Translate"
-#define CANVAS__Scale CANVAS_PREFIX"Scale"
-#define CANVAS__Rotate CANVAS_PREFIX"Rotate"
-#define CANVAS__Transform CANVAS_PREFIX"Transform"
-#define CANVAS__Reset CANVAS_PREFIX"Reset"
-#define CANVAS__FontSize CANVAS_PREFIX"FontSize"
-#define CANVAS__FillText CANVAS_PREFIX"FillText"
-
-#define CANVAS__lineCapButt CANVAS_PREFIX"lineCapButt"
-#define CANVAS__lineCapRound CANVAS_PREFIX"lineCapRound"
-#define CANVAS__lineCapSquare CANVAS_PREFIX"lineCapSquare"
-
-#define CANVAS__lineJoinMiter CANVAS_PREFIX"lineJoinMiter"
-#define CANVAS__lineJoinRound CANVAS_PREFIX"lineJoinRound"
-#define CANVAS__lineJoinBevel CANVAS_PREFIX"lineJoinBevel"
-
-// Input properties and attributes
-
-#define CANVAS__mouseButtonLeft CANVAS_PREFIX"mouseButtonLeft"
-#define CANVAS__mouseButtonMiddle CANVAS_PREFIX"mouseButtonMiddle"
-#define CANVAS__mouseButtonRight CANVAS_PREFIX"mouseButtonRight"
-#define CANVAS__mouseWheelX CANVAS_PREFIX"mouseWheelX"
-#define CANVAS__mouseWheelY CANVAS_PREFIX"mouseWheelY"
-#define CANVAS__mousePositionX CANVAS_PREFIX"mousePositionX"
-#define CANVAS__mousePositionY CANVAS_PREFIX"mousePositionY"
-#define CANVAS__mouseFocus CANVAS_PREFIX"mouseFocus"
-
-typedef struct _LV2_Canvas_URID LV2_Canvas_URID;
-
-struct _LV2_Canvas_URID {
- LV2_URID Canvas_graph;
- LV2_URID Canvas_body;
- LV2_URID Canvas_aspectRatio;
-
- LV2_URID Canvas_BeginPath;
- LV2_URID Canvas_ClosePath;
- LV2_URID Canvas_Arc;
- LV2_URID Canvas_CurveTo;
- LV2_URID Canvas_LineTo;
- LV2_URID Canvas_MoveTo;
- LV2_URID Canvas_Rectangle;
- LV2_URID Canvas_PolyLine;
- LV2_URID Canvas_Style;
- LV2_URID Canvas_LineWidth;
- LV2_URID Canvas_LineDash;
- LV2_URID Canvas_LineCap;
- LV2_URID Canvas_LineJoin;
- LV2_URID Canvas_MiterLimit;
- LV2_URID Canvas_Stroke;
- LV2_URID Canvas_Fill;
- LV2_URID Canvas_Clip;
- LV2_URID Canvas_Save;
- LV2_URID Canvas_Restore;
- LV2_URID Canvas_Translate;
- LV2_URID Canvas_Scale;
- LV2_URID Canvas_Rotate;
- LV2_URID Canvas_Transform;
- LV2_URID Canvas_Reset;
- LV2_URID Canvas_FontSize;
- LV2_URID Canvas_FillText;
-
- LV2_URID Canvas_lineCapButt;
- LV2_URID Canvas_lineCapRound;
- LV2_URID Canvas_lineCapSquare;
-
- LV2_URID Canvas_lineJoinMiter;
- LV2_URID Canvas_lineJoinRound;
- LV2_URID Canvas_lineJoinBevel;
-
- LV2_URID Canvas_mouseButtonLeft;
- LV2_URID Canvas_mouseButtonMiddle;
- LV2_URID Canvas_mouseButtonRight;
- LV2_URID Canvas_mouseWheelX;
- LV2_URID Canvas_mouseWheelY;
- LV2_URID Canvas_mousePositionX;
- LV2_URID Canvas_mousePositionY;
- LV2_URID Canvas_mouseFocus;
-
- LV2_Atom_Forge forge;
-};
-
-static inline void
-lv2_canvas_urid_init(LV2_Canvas_URID *urid, LV2_URID_Map *map)
-{
- urid->Canvas_graph = map->map(map->handle, CANVAS__graph);
- urid->Canvas_body = map->map(map->handle, CANVAS__body);
- urid->Canvas_aspectRatio = map->map(map->handle, CANVAS__aspectRatio);
-
- urid->Canvas_BeginPath = map->map(map->handle, CANVAS__BeginPath);
- urid->Canvas_ClosePath = map->map(map->handle, CANVAS__ClosePath);
- urid->Canvas_Arc = map->map(map->handle, CANVAS__Arc);
- urid->Canvas_CurveTo = map->map(map->handle, CANVAS__CurveTo);
- urid->Canvas_LineTo = map->map(map->handle, CANVAS__LineTo);
- urid->Canvas_MoveTo = map->map(map->handle, CANVAS__MoveTo);
- urid->Canvas_Rectangle = map->map(map->handle, CANVAS__Rectangle);
- urid->Canvas_PolyLine = map->map(map->handle, CANVAS__PolyLine);
- urid->Canvas_Style = map->map(map->handle, CANVAS__Style);
- urid->Canvas_LineWidth = map->map(map->handle, CANVAS__LineWidth);
- urid->Canvas_LineDash = map->map(map->handle, CANVAS__LineDash);
- urid->Canvas_LineCap = map->map(map->handle, CANVAS__LineCap);
- urid->Canvas_LineJoin = map->map(map->handle, CANVAS__LineJoin);
- urid->Canvas_MiterLimit = map->map(map->handle, CANVAS__MiterLimit);
- urid->Canvas_Stroke = map->map(map->handle, CANVAS__Stroke);
- urid->Canvas_Fill = map->map(map->handle, CANVAS__Fill);
- urid->Canvas_Clip = map->map(map->handle, CANVAS__Clip);
- urid->Canvas_Save = map->map(map->handle, CANVAS__Save);
- urid->Canvas_Restore = map->map(map->handle, CANVAS__Restore);
- urid->Canvas_Translate = map->map(map->handle, CANVAS__Translate);
- urid->Canvas_Scale = map->map(map->handle, CANVAS__Scale);
- urid->Canvas_Rotate = map->map(map->handle, CANVAS__Rotate);
- urid->Canvas_Transform = map->map(map->handle, CANVAS__Transform);
- urid->Canvas_Reset = map->map(map->handle, CANVAS__Reset);
- urid->Canvas_FontSize = map->map(map->handle, CANVAS__FontSize);
- urid->Canvas_FillText = map->map(map->handle, CANVAS__FillText);
-
- urid->Canvas_lineCapButt = map->map(map->handle, CANVAS__lineCapButt);
- urid->Canvas_lineCapRound = map->map(map->handle, CANVAS__lineCapRound);
- urid->Canvas_lineCapSquare = map->map(map->handle, CANVAS__lineCapSquare);
-
- urid->Canvas_lineJoinMiter = map->map(map->handle, CANVAS__lineJoinMiter);
- urid->Canvas_lineJoinRound = map->map(map->handle, CANVAS__lineJoinRound);
- urid->Canvas_lineJoinBevel = map->map(map->handle, CANVAS__lineJoinBevel);
-
- urid->Canvas_mouseButtonLeft = map->map(map->handle, CANVAS__mouseButtonLeft);
- urid->Canvas_mouseButtonMiddle = map->map(map->handle, CANVAS__mouseButtonMiddle);
- urid->Canvas_mouseButtonRight = map->map(map->handle, CANVAS__mouseButtonRight);
- urid->Canvas_mouseWheelX = map->map(map->handle, CANVAS__mouseWheelX);
- urid->Canvas_mouseWheelY = map->map(map->handle, CANVAS__mouseWheelY);
- urid->Canvas_mousePositionX = map->map(map->handle, CANVAS__mousePositionX);
- urid->Canvas_mousePositionY = map->map(map->handle, CANVAS__mousePositionY);
- urid->Canvas_mouseFocus = map->map(map->handle, CANVAS__mouseFocus);
-
- lv2_atom_forge_init(&urid->forge, map);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _LV2_CANVAS_H
diff --git a/canvas.lv2/forge.h b/canvas.lv2/forge.h
deleted file mode 100644
index c5ce5fe..0000000
--- a/canvas.lv2/forge.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the Artistic License 2.0 as published by
- * The Perl Foundation.
- *
- * This source is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Artistic License 2.0 for more details.
- *
- * You should have received a copy of the Artistic License 2.0
- * along the source as a COPYING file. If not, obtain it from
- * http://www.perlfoundation.org/artistic_license_2_0.
- */
-
-#ifndef _LV2_CANVAS_FORGE_H
-#define _LV2_CANVAS_FORGE_H
-
-#include <canvas.lv2/canvas.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_simple(LV2_Atom_Forge *forge, LV2_URID otype)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_vec(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, uint32_t n, const float *vec)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_vector(forge, sizeof(float), forge->Float, n, vec);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_flt(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, float flt)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_float(forge, flt);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_lng(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, int64_t lng)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_long(forge, lng);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_prp(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, LV2_URID prop)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_urid(forge, prop);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_str(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, const char *text)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_string(forge, text, strlen(text));
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_beginPath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_BeginPath);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_closePath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_ClosePath);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_arc(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y, float r, float a1, float a2)
-{
- const float vec [5] = {x, y, r, a1, a2};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Arc, 5, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_curveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x1, float y1, float x2, float y2, float x3, float y3)
-{
- const float vec [6] = {x1, y1, x2, y2, x3, y3};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_CurveTo, 6, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_lineTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineTo, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_moveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_MoveTo, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_rectangle(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y, float w, float h)
-{
- const float vec [4] = {x, y, w, h};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Rectangle, 4, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_polyLine(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- uint32_t n, const float *vec)
-{
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_PolyLine, n, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_style(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- uint32_t style)
-{
- return _lv2_canvas_forge_lng(forge, urid, urid->Canvas_Style, style);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_lineWidth(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float line_width)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_LineWidth, line_width);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_lineDash(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float dash_length, float separator_length)
-{
- const float vec [2] = {dash_length, separator_length};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineDash, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_lineCap(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID line_cap)
-{
- return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineCap, line_cap);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_lineJoin(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID line_join)
-{
- return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineJoin, line_join);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_miterLimit(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float miter_limit)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_MiterLimit, miter_limit);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_stroke(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Stroke);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_fill(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Fill);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_clip(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Clip);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_save(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Save);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_restore(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Restore);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_translate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Translate, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_scale(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float w, float h)
-{
- const float vec [2] = {w, h};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Scale, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_rotate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float a)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_Rotate, a);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_transform(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float xx, float xy, float x0, float yy, float yx, float y0)
-{
- const float vec [6] = {xx, xy, x0, yy, yx, y0};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Transform, 6, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_reset(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Reset);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_fontSize(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float size)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_FontSize, size);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_fillText(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- const char *text)
-{
- return _lv2_canvas_forge_str(forge, urid, urid->Canvas_FillText, text);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _LV2_CANVAS_FORGE_H
diff --git a/canvas.lv2/render.h b/canvas.lv2/render.h
deleted file mode 100644
index 2882c87..0000000
--- a/canvas.lv2/render.h
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (c) 2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the Artistic License 2.0 as published by
- * The Perl Foundation.
- *
- * This source is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Artistic License 2.0 for more details.
- *
- * You should have received a copy of the Artistic License 2.0
- * along the source as a COPYING file. If not, obtain it from
- * http://www.perlfoundation.org/artistic_license_2_0.
- */
-
-#ifndef _LV2_CANVAS_RENDER_H
-#define _LV2_CANVAS_RENDER_H
-
-#include <assert.h>
-
-#include <canvas.lv2/canvas.h>
-
-#include <cairo/cairo.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LV2_CANVAS_NUM_METHODS 26
-
-typedef struct _LV2_Canvas_Meth LV2_Canvas_Meth;
-typedef struct _LV2_Canvas LV2_Canvas;
-typedef void (*LV2_Canvas_Func)(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body);
-
-struct _LV2_Canvas_Meth {
- LV2_URID command;
- LV2_Canvas_Func func;
-};
-
-struct _LV2_Canvas {
- LV2_Canvas_URID urid;
- LV2_Canvas_Meth methods [LV2_CANVAS_NUM_METHODS];
-};
-
-static inline const float *
-_lv2_canvas_render_get_float_vecs(LV2_Canvas_URID *urid, const LV2_Atom *body,
- uint32_t *n)
-{
- const LV2_Atom_Vector *vec = (const LV2_Atom_Vector *)body;
- const float *flt = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Vector, vec);
- *n = (vec->atom.type == urid->forge.Vector)
- && (vec->body.child_type == urid->forge.Float)
- && (vec->body.child_size == sizeof(float))
- ? (vec->atom.size - sizeof(LV2_Atom_Vector_Body)) / vec->body.child_size
- : 0;
-
- return flt;
-}
-
-static inline const float *
-_lv2_canvas_render_get_float_vec(LV2_Canvas_URID *urid, const LV2_Atom *body,
- uint32_t n)
-{
- uint32_t N;
- const float *flt = _lv2_canvas_render_get_float_vecs(urid, body, &N);
-
- return n == N ? flt : NULL;
-}
-
-static inline const void *
-_lv2_canvas_render_get_type(const LV2_Atom *body, LV2_URID type)
-{
- return body->type == type
- ? LV2_ATOM_BODY_CONST(body)
- : NULL;
-}
-
-static inline void
-_lv2_canvas_render_beginPath(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_new_sub_path(ctx);
-}
-
-static inline void
-_lv2_canvas_render_closePath(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_close_path(ctx);
-}
-
-static inline void
-_lv2_canvas_render_arc(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 5);
-
- if(v)
- {
- cairo_arc(ctx, v[0], v[1], v[2], v[3], v[4]);
- }
-}
-
-static inline void
-_lv2_canvas_render_curveTo(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 6);
-
- if(v)
- {
- cairo_curve_to(ctx, v[0], v[1], v[2], v[3], v[4], v[5]);
- }
-}
-
-static inline void
-_lv2_canvas_render_lineTo(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 2);
-
- if(v)
- {
- cairo_line_to(ctx, v[0], v[1]);
- }
-}
-
-static inline void
-_lv2_canvas_render_moveTo(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 2);
-
- if(v)
- {
- cairo_move_to(ctx, v[0], v[1]);
- }
-}
-
-static inline void
-_lv2_canvas_render_rectangle(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 4);
-
- if(v)
- {
- cairo_rectangle(ctx, v[0], v[1], v[2], v[3]);
- }
-}
-
-static inline void
-_lv2_canvas_render_polyline(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- uint32_t N;
- const float *v = _lv2_canvas_render_get_float_vecs(urid, body, &N);
-
- if(v)
- {
- for(uint32_t i = 0; i < 2; i += 2)
- {
- cairo_move_to(ctx, v[i], v[i+1]);
- }
-
- for(uint32_t i = 2; i < N; i += 2)
- {
- cairo_line_to(ctx, v[i], v[i+1]);
- }
- }
-}
-
-static inline void
-_lv2_canvas_render_style(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const int64_t *v = _lv2_canvas_render_get_type(body, urid->forge.Long);
-
- if(v)
- {
- const float r = (float)((*v >> 24) & 0xff) / 0xff;
- const float g = (float)((*v >> 16) & 0xff) / 0xff;
- const float b = (float)((*v >> 8) & 0xff) / 0xff;
- const float a = (float)((*v >> 0) & 0xff) / 0xff;
-
- cairo_set_source_rgba(ctx, r, g, b, a);
- }
-}
-
-static inline void
-_lv2_canvas_render_lineWidth(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_type(body, urid->forge.Float);
-
- if(v)
- {
- cairo_set_line_width(ctx, *v);
- }
-}
-
-static inline void
-_lv2_canvas_render_lineDash(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 2);
-
- if(v)
- {
- const double d[2] = {v[0], v[1]};
- cairo_set_dash(ctx, d, 2, 0);
- }
-}
-
-static inline void
-_lv2_canvas_render_lineCap(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const LV2_URID *v = _lv2_canvas_render_get_type(body, urid->forge.URID);
-
- if(v)
- {
- cairo_line_cap_t cap = CAIRO_LINE_CAP_BUTT;
-
- if(*v == urid->Canvas_lineCapButt)
- cap = CAIRO_LINE_CAP_BUTT;
- else if(*v == urid->Canvas_lineCapRound)
- cap = CAIRO_LINE_CAP_ROUND;
- else if(*v == urid->Canvas_lineCapSquare)
- cap = CAIRO_LINE_CAP_SQUARE;
-
- cairo_set_line_cap(ctx, cap);
- }
-}
-
-static inline void
-_lv2_canvas_render_lineJoin(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const LV2_URID *v = _lv2_canvas_render_get_type(body, urid->forge.URID);
-
- if(v)
- {
- cairo_line_join_t join = CAIRO_LINE_JOIN_MITER;
-
- if(*v == urid->Canvas_lineJoinMiter)
- join = CAIRO_LINE_JOIN_MITER;
- else if(*v == urid->Canvas_lineJoinRound)
- join = CAIRO_LINE_JOIN_ROUND;
- else if(*v == urid->Canvas_lineJoinBevel)
- join = CAIRO_LINE_JOIN_BEVEL;
-
- cairo_set_line_join(ctx, join);
- }
-}
-
-static inline void
-_lv2_canvas_render_miterLimit(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_type(body, urid->forge.Float);
-
- if(v)
- {
- cairo_set_miter_limit(ctx, *v);
- }
-}
-
-static inline void
-_lv2_canvas_render_stroke(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_stroke(ctx);
-}
-
-static inline void
-_lv2_canvas_render_fill(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_fill(ctx);
-}
-
-static inline void
-_lv2_canvas_render_clip(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_clip(ctx);
-}
-
-static inline void
-_lv2_canvas_render_save(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_save(ctx);
-}
-
-static inline void
-_lv2_canvas_render_restore(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_restore(ctx);
-}
-
-static inline void
-_lv2_canvas_render_translate(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 2);
-
- if(v)
- {
- cairo_translate(ctx, v[0], v[1]);
- }
-}
-
-static inline void
-_lv2_canvas_render_scale(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 2);
-
- if(v)
- {
- cairo_scale(ctx, v[0], v[1]);
- }
-}
-
-static inline void
-_lv2_canvas_render_rotate(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_type(body, urid->forge.Float);
-
- if(v)
- {
- cairo_rotate(ctx, *v);
- }
-}
-
-static inline void
-_lv2_canvas_render_transform(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_float_vec(urid, body, 6);
-
- if(v)
- {
- const cairo_matrix_t matrix = {
- .xx = v[0],
- .xy = v[1],
- .x0 = v[2],
- .yy = v[3],
- .yx = v[4],
- .y0 = v[5]
- };
-
- cairo_transform(ctx, &matrix);
- }
-}
-
-static inline void
-_lv2_canvas_render_reset(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- cairo_identity_matrix(ctx);
-}
-
-static inline void
-_lv2_canvas_render_fontSize(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const float *v = _lv2_canvas_render_get_type(body, urid->forge.Float);
-
- if(v)
- {
- cairo_set_font_size(ctx, *v);
- }
-}
-
-static inline void
-_lv2_canvas_render_fillText(cairo_t *ctx,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
-{
- const char *v = _lv2_canvas_render_get_type(body, urid->forge.String);
-
- if(v)
- {
- cairo_text_extents_t extents;
- cairo_text_extents(ctx, v, &extents);
- const float dx = extents.width/2 + extents.x_bearing;
- const float dy = extents.height/2 + extents.y_bearing;
- cairo_rel_move_to(ctx, -dx, -dy);
- cairo_show_text(ctx, v);
- }
-}
-
-static inline void
-_lv2_canvas_qsort(LV2_Canvas_Meth *A, int n)
-{
- if(n < 2)
- return;
-
- LV2_Canvas_Meth *p = A;
-
- int i = -1;
- int j = n;
-
- while(true)
- {
- do {
- i += 1;
- } while(A[i].command < p->command);
-
- do {
- j -= 1;
- } while(A[j].command > p->command);
-
- if(i >= j)
- break;
-
- const LV2_Canvas_Meth tmp = A[i];
- A[i] = A[j];
- A[j] = tmp;
- }
-
- _lv2_canvas_qsort(A, j + 1);
- _lv2_canvas_qsort(A + j + 1, n - j - 1);
-}
-
-static inline LV2_Canvas_Meth *
-_lv2_canvas_bsearch(LV2_URID p, LV2_Canvas_Meth *a, int n)
-{
- LV2_Canvas_Meth *base = a;
-
- for(int N = n, half; N > 1; N -= half)
- {
- half = N/2;
- LV2_Canvas_Meth *dst = &base[half];
- base = (dst->command > p) ? base : dst;
- }
-
- return (base->command == p) ? base : NULL;
-}
-
-static inline void
-lv2_canvas_init(LV2_Canvas *canvas, LV2_URID_Map *map)
-{
- lv2_canvas_urid_init(&canvas->urid, map);
-
- unsigned ptr = 0;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_BeginPath;
- canvas->methods[ptr++].func = _lv2_canvas_render_beginPath;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_ClosePath;
- canvas->methods[ptr++].func = _lv2_canvas_render_closePath;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Arc;
- canvas->methods[ptr++].func = _lv2_canvas_render_arc;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_CurveTo;
- canvas->methods[ptr++].func = _lv2_canvas_render_curveTo;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_LineTo;
- canvas->methods[ptr++].func = _lv2_canvas_render_lineTo;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_MoveTo;
- canvas->methods[ptr++].func = _lv2_canvas_render_moveTo;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Rectangle;
- canvas->methods[ptr++].func = _lv2_canvas_render_rectangle;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_PolyLine;
- canvas->methods[ptr++].func = _lv2_canvas_render_polyline;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Style;
- canvas->methods[ptr++].func = _lv2_canvas_render_style;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_LineWidth;
- canvas->methods[ptr++].func = _lv2_canvas_render_lineWidth;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_LineDash;
- canvas->methods[ptr++].func = _lv2_canvas_render_lineDash;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_LineCap;
- canvas->methods[ptr++].func = _lv2_canvas_render_lineCap;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_LineJoin;
- canvas->methods[ptr++].func = _lv2_canvas_render_lineJoin;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_MiterLimit;
- canvas->methods[ptr++].func = _lv2_canvas_render_miterLimit;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Stroke;
- canvas->methods[ptr++].func = _lv2_canvas_render_stroke;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Fill;
- canvas->methods[ptr++].func = _lv2_canvas_render_fill;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Clip;
- canvas->methods[ptr++].func = _lv2_canvas_render_clip;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Save;
- canvas->methods[ptr++].func = _lv2_canvas_render_save;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Restore;
- canvas->methods[ptr++].func = _lv2_canvas_render_restore;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Translate;
- canvas->methods[ptr++].func = _lv2_canvas_render_translate;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Scale;
- canvas->methods[ptr++].func = _lv2_canvas_render_scale;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Rotate;
- canvas->methods[ptr++].func = _lv2_canvas_render_rotate;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Transform;
- canvas->methods[ptr++].func = _lv2_canvas_render_transform;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_Reset;
- canvas->methods[ptr++].func = _lv2_canvas_render_reset;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_FontSize;
- canvas->methods[ptr++].func = _lv2_canvas_render_fontSize;
-
- canvas->methods[ptr].command = canvas->urid.Canvas_FillText;
- canvas->methods[ptr++].func = _lv2_canvas_render_fillText;
-
- assert(ptr == LV2_CANVAS_NUM_METHODS);
-
- _lv2_canvas_qsort(canvas->methods, LV2_CANVAS_NUM_METHODS);
-}
-
-static inline bool
-lv2_canvas_render(LV2_Canvas *canvas, cairo_t *ctx, const LV2_Atom_Tuple *tup)
-{
- LV2_Canvas_URID *urid = &canvas->urid;
-
- if(!tup || (tup->atom.type != urid->forge.Tuple) )
- return false;
-
- // save state
- cairo_save(ctx);
-
- // clear surface
- cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR);
- cairo_paint(ctx);
-
- // default attributes
- cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
- cairo_set_font_size(ctx, 0.1);
- cairo_set_line_width(ctx, 0.01);
- cairo_set_source_rgba(ctx, 1.0, 1.0, 1.0, 1.0);
-
- LV2_ATOM_TUPLE_FOREACH(tup, itm)
- {
- if(lv2_atom_forge_is_object_type(&urid->forge, itm->type))
- {
- const LV2_Atom_Object *obj = (const LV2_Atom_Object *)itm;
- const LV2_Atom *body = NULL;
-
- lv2_atom_object_get(obj, urid->Canvas_body, &body, 0);
-
- LV2_Canvas_Meth *meth = _lv2_canvas_bsearch(obj->body.otype,
- canvas->methods, LV2_CANVAS_NUM_METHODS);
-
- if(meth)
- {
- meth->func(ctx, urid, body);
- }
- }
- }
-
- // save state
- cairo_restore(ctx);
-
- // flush
- cairo_surface_t *surface = cairo_get_target(ctx);
- cairo_surface_flush(surface);
-
- return true;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // CANVAS_IMPLEMENTATION
diff --git a/test/canvas.ttl b/canvas_display.ttl
index 29c9b6c..2c89758 100644
--- a/test/canvas.ttl
+++ b/canvas_display.ttl
@@ -28,6 +28,7 @@
@prefix lic: <http://opensource.org/licenses/> .
@prefix omk: <http://open-music-kontrollers.ch/ventosus#> .
@prefix proj: <http://open-music-kontrollers.ch/lv2/> .
+@prefix canvasdisp: <http://open-music-kontrollers.ch/lv2/canvas_display#> .
@prefix canvas: <http://open-music-kontrollers.ch/lv2/canvas#> .
# to please sord_validate
@@ -65,7 +66,7 @@ canvas:aspectRatio
lv2:default 1.0 .
# Canvas Plugin
-canvas:canvas
+canvasdisp:canvas
a lv2:Plugin,
lv2:AnalyserPlugin ;
doap:name "Canvas" ;
diff --git a/test/canvas_ui.ttl b/canvas_display_ui.ttl
index 045eb6a..ab185be 100644
--- a/test/canvas_ui.ttl
+++ b/canvas_display_ui.ttl
@@ -18,11 +18,11 @@
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
-@prefix canvas: <http://open-music-kontrollers.ch/lv2/canvas#> .
+@prefix canvasdisp: <http://open-music-kontrollers.ch/lv2/canvas_display#> .
-canvas:canvas_ui
+canvasdisp:canvas_ui
ui:portNotification [
- ui:plugin canvas:canvas ;
+ ui:plugin canvasdisp:canvas ;
lv2:symbol "notify" ;
ui:protocol atom:eventTransfer
] ;
diff --git a/test/canvas_ui.c b/canvas_ui.c
index d6850e6..eef5d19 100644
--- a/test/canvas_ui.c
+++ b/canvas_ui.c
@@ -554,7 +554,7 @@ extension_data(const char *uri)
}
const LV2UI_Descriptor canvas_canvas_ui = {
- .URI = CANVAS_PREFIX"canvas_ui",
+ .URI = "http://open-music-kontrollers.ch/lv2/canvas_display#canvas_ui",
.instantiate = instantiate,
.cleanup = cleanup,
.port_event = port_event,
diff --git a/cmake/arm-linux-gnueabihf.cmake b/cmake/arm-linux-gnueabihf.cmake
deleted file mode 100644
index ac43290..0000000
--- a/cmake/arm-linux-gnueabihf.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Linux)
-set(CMAKE_SYSTEM_PROCESSOR "armv7h")
-set(TOOLCHAIN "arm-linux-gnueabihf")
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER "${TOOLCHAIN}-gcc")
-set(CMAKE_CXX_COMPILER "${TOOLCHAIN}-g++")
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH "usr/${TOOLCHAIN}")
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
-
-set(QEMU qemu-arm)
diff --git a/cmake/i686-linux-gnu.cmake b/cmake/i686-linux-gnu.cmake
deleted file mode 100644
index 6148f85..0000000
--- a/cmake/i686-linux-gnu.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Linux)
-set(CMAKE_SYSTEM_PROCESSOR "i686")
-set(TOOLCHAIN "i686-linux-gnu")
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32" CACHE STRING "c++ flags")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32" CACHE STRING "c flags")
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
diff --git a/cmake/i686-w64-mingw32.cmake b/cmake/i686-w64-mingw32.cmake
deleted file mode 100644
index df7d2d0..0000000
--- a/cmake/i686-w64-mingw32.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR "i686")
-set(TOOLCHAIN "i686-w64-mingw32")
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER "${TOOLCHAIN}-gcc")
-set(CMAKE_CXX_COMPILER "${TOOLCHAIN}-g++")
-set(CMAKE_RC_COMPILER "${TOOLCHAIN}-windres")
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH "/usr/${TOOLCHAIN}")
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
-
-set(WINE wine32)
diff --git a/cmake/universal-apple-darwin.cmake b/cmake/universal-apple-darwin.cmake
deleted file mode 100644
index 3efab34..0000000
--- a/cmake/universal-apple-darwin.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Darwin)
-set(CMAKE_SYSTEM_PROCESSOR "x86_64")
-set(TOOLCHAIN "universal-apple-darwin")
-
-set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER "/usr/${TOOLCHAIN}/bin/x86_64-apple-darwin15-clang")
-set(CMAKE_CXX_COMPILER "/usr/${TOOLCHAIN}/bin/x86_64-apple-darwin15-clang++")
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH "/usr/${TOOLCHAIN}/SDK/MacOSX10.11.sdk")
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
diff --git a/cmake/x86_64-linux-gnu.cmake b/cmake/x86_64-linux-gnu.cmake
deleted file mode 100644
index 290d01b..0000000
--- a/cmake/x86_64-linux-gnu.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Linux)
-set(CMAKE_SYSTEM_PROCESSOR "x86_64")
-set(TOOLCHAIN "x86_64-linux-gnu")
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
diff --git a/cmake/x86_64-w64-mingw32.cmake b/cmake/x86_64-w64-mingw32.cmake
deleted file mode 100644
index d699ad3..0000000
--- a/cmake/x86_64-w64-mingw32.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR "x86_64")
-set(TOOLCHAIN "x86_64-w64-mingw32")
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER "${TOOLCHAIN}-gcc")
-set(CMAKE_CXX_COMPILER "${TOOLCHAIN}-g++")
-set(CMAKE_RC_COMPILER "${TOOLCHAIN}-windres")
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH "/usr/${TOOLCHAIN}")
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-set(STATIC_CAIRO "/opt/${TOOLCHAIN}/lib/libcairo.a")
-set(STATIC_PIXMAN "/opt/${TOOLCHAIN}/lib/libpixman-1.a")
-
-set(WINE wine64)
diff --git a/docker_build.sh b/docker_build.sh
deleted file mode 100755
index 6ee1b96..0000000
--- a/docker_build.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-TARGET=$1
-
-CI_PROJECT_DIR=$(pwd)
-CI_BUILD_NAME=${TARGET}
-
-BASE_NAME="canvas.lv2"
-PKG_CONFIG_PATH="/opt/lv2/lib/pkgconfig:/opt/${CI_BUILD_NAME}/lib/pkgconfig"
-TOOLCHAIN_FILE="${CI_PROJECT_DIR}/cmake/${CI_BUILD_NAME}.cmake"
-
-rm -rf ${TARGET}
-mkdir -p ${TARGET}
-pushd ${TARGET}
- PKG_CONFIG_PATH=${PKG_CONFIG_PATH} cmake \
- -DCAIRO_INCLUDE_DIRS="/opt/${CI_BUILD_NAME}/include" \
- -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX=${CI_PROJECT_DIR} \
- -DPLUGIN_DEST="${BASE_NAME}-$(cat ../VERSION)/${CI_BUILD_NAME}/${BASE_NAME}" \
- -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
- ..
- make -j4
- make install
- #ARGS='-VV' make test
-popd
diff --git a/docker_run.sh b/docker_run.sh
deleted file mode 100755
index ea1c47a..0000000
--- a/docker_run.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/bash
-
-TARGET=$1
-
-docker run --rm -it -v $(pwd):/workdir/canvas.lv2 ventosus/${TARGET}
diff --git a/test/manifest.ttl.in b/manifest.ttl.in
index 679b95a..a085c66 100644
--- a/test/manifest.ttl.in
+++ b/manifest.ttl.in
@@ -18,17 +18,17 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
-@prefix canvas: <http://open-music-kontrollers.ch/lv2/canvas#> .
+@prefix canvasdisp: <http://open-music-kontrollers.ch/lv2/canvas_display#> .
-canvas:canvas
+canvasdisp:canvas
a lv2:Plugin ;
- lv2:minorVersion @CANVAS_MINOR_VERSION@ ;
- lv2:microVersion @CANVAS_MICRO_VERSION@ ;
- lv2:binary <canvas@CMAKE_SHARED_MODULE_SUFFIX@> ;
- ui:ui canvas:canvas_ui ;
- rdfs:seeAlso <canvas.ttl> .
+ lv2:minorVersion @MINOR_VERSION@ ;
+ lv2:microVersion @MICRO_VERSION@ ;
+ lv2:binary <canvas_display@MODULE_SUFFIX@> ;
+ ui:ui canvasdisp:canvas_ui ;
+ rdfs:seeAlso <canvas_display.ttl> .
-canvas:canvas_ui
- a ui:@CANVAS_UI_TYPE@ ;
- ui:binary <canvas_ui@CMAKE_SHARED_MODULE_SUFFIX@> ;
- rdfs:seeAlso <canvas_ui.ttl> .
+canvasdisp:canvas_ui
+ a ui:@UI_TYPE@ ;
+ ui:binary <canvas_display_ui@MODULE_SUFFIX@> ;
+ rdfs:seeAlso <canvas_display_ui.ttl> .
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..35776d4
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,105 @@
+project('canvas_display.lv2', 'c', default_options : [
+ 'buildtype=release',
+ 'warning_level=1',
+ 'werror=false',
+ 'b_lto=true',
+ 'c_std=c11'])
+
+cc = meson.get_compiler('c')
+
+m_dep = cc.find_library('m')
+lv2_dep = dependency('lv2', version : '>=1.14.0')
+cairo_dep = dependency('cairo', version : '>=1.0.0',
+ static : meson.is_cross_build())
+
+dsp_deps = [m_dep, lv2_dep, cairo_dep]
+ui_deps = [m_dep, lv2_dep, cairo_dep]
+
+pugl_inc = include_directories('pugl')
+canvas_inc = include_directories('canvas.lv2')
+ardour_inc = include_directories('ardour.lv2')
+inc_dir = [pugl_inc, canvas_inc, ardour_inc]
+
+inst_dir = join_paths(get_option('libdir'), 'lv2', meson.project_name())
+
+rawvers = run_command('cat', 'VERSION').stdout().strip()
+version = rawvers.split('.')
+
+conf_data = configuration_data()
+conf_data.set('MAJOR_VERSION', version[0])
+conf_data.set('MINOR_VERSION', version[1])
+conf_data.set('MICRO_VERSION', version[2])
+
+add_project_arguments('-D_GNU_SOURCE', language : 'c')
+add_project_arguments('-DPUGL_HAVE_GL', language : 'c')
+add_project_arguments('-DPUGL_HAVE_CAIRO', language : 'c')
+
+cp = find_program('cp')
+clone = [cp, '@INPUT@', '@OUTPUT@']
+
+dsp_srcs = ['canvas.c']
+
+ui_srcs = ['canvas_ui.c']
+
+c_args = ['-fvisibility=hidden',
+ '-ffast-math']
+
+if host_machine.system() == 'linux'
+ conf_data.set('UI_TYPE', 'X11UI')
+ ui_deps += dependency('gl')
+ ui_deps += dependency('x11', version : '>=1.6.0')
+ ui_deps += dependency('xext', version : '>=1.3.0')
+ ui_srcs += 'pugl/pugl/pugl_x11.c'
+elif host_machine.system() == 'windows'
+ add_languages('cpp')
+ conf_data.set('UI_TYPE', 'WindowsUI')
+ ui_deps += cc.find_library('opengl32')
+ ui_deps += cc.find_library('gdi32')
+ ui_deps += cc.find_library('user32')
+ ui_srcs += 'pugl/pugl/pugl_win.cpp'
+elif host_machine.system() == 'darwin'
+ #add_languages('objc')
+ conf_data.set('UI_TYPE', 'CocoaUI')
+ #ui_deps += cc.find_library('Cocoa')
+ #ui_deps += cc.find_library('gl')
+ #ui_deps += dependency('appleframeworks', modules : 'cocoa')
+ #ui_srcs += 'pugl/pugl/pugl_osx.m'
+endif
+
+mod = shared_module('canvas_display', dsp_srcs,
+ c_args : c_args,
+ include_directories : inc_dir,
+ name_prefix : '',
+ dependencies : dsp_deps,
+ install : true,
+ install_dir : inst_dir)
+
+ui = shared_module('canvas_display_ui', ui_srcs,
+ c_args : c_args,
+ include_directories : inc_dir,
+ name_prefix : '',
+ dependencies : ui_deps,
+ install : true,
+ install_dir : inst_dir)
+
+suffix = mod.full_path().strip().split('.')[-1]
+conf_data.set('MODULE_SUFFIX', '.' + suffix)
+
+configure_file(input : 'manifest.ttl.in', output : 'manifest.ttl',
+ configuration : conf_data,
+ install : true,
+ install_dir : inst_dir)
+
+custom_target('dsp_ttl',
+ input : 'canvas_display.ttl',
+ output : 'canvas_display.ttl',
+ command : clone,
+ install : true,
+ install_dir : inst_dir)
+
+custom_target('ui_ttl',
+ input : 'canvas_display_ui.ttl',
+ output : 'canvas_display_ui.ttl',
+ command : clone,
+ install : true,
+ install_dir : inst_dir)
diff --git a/meson/arm-linux-gnueabihf b/meson/arm-linux-gnueabihf
new file mode 100644
index 0000000..241266e
--- /dev/null
+++ b/meson/arm-linux-gnueabihf
@@ -0,0 +1,18 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'arm'
+cpu = 'armv7hl'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/arm-linux-gnueabihf-gcc'
+cpp = '/usr/bin/arm-linux-gnueabihf-g++'
+ar = '/usr/bin/arm-linux-gnueabihf-ar'
+strip = '/usr/bin/arm-linux-gnueabihf-strip'
+pkgconfig = '/usr/bin/pkg-config'
+exe_wrapper = '/usr/bin/qemu-arm'
+
+[properties]
+root = '/usr/arm-linux-gnueabihf'
+c_link_args = ['-Wl,-z,defs']
+needs_exe_wrapper = true
diff --git a/meson/i686-linux-gnu b/meson/i686-linux-gnu
new file mode 100644
index 0000000..17d5a41
--- /dev/null
+++ b/meson/i686-linux-gnu
@@ -0,0 +1,19 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'x86'
+cpu = 'i686'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/x86_64-linux-gnu-gcc'
+cpp = '/usr/bin/x86_64-linux-gnu-g++'
+ar = '/usr/bin/x86_64-linux-gnu-ar'
+strip = '/usr/bin/x86_64-linux-gnu-strip'
+pkgconfig = '/usr/bin/pkg-config'
+
+[properties]
+c_args = ['-m32']
+cpp_args = ['-m32']
+c_link_args = ['-m32', '-Wl,-z,defs']
+cpp_link_args = ['-m32', '-Wl,-z,defs']
+needs_exe_wrapper = false
diff --git a/meson/i686-w64-mingw32 b/meson/i686-w64-mingw32
new file mode 100644
index 0000000..4966ba7
--- /dev/null
+++ b/meson/i686-w64-mingw32
@@ -0,0 +1,17 @@
+[host_machine]
+system = 'windows'
+cpu_family = 'i686'
+cpu = 'i686'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/i686-w64-mingw32-gcc'
+cpp = '/usr/bin/i686-w64-mingw32-g++'
+ar = '/usr/bin/i686-w64-mingw32-ar'
+strip = '/usr/bin/i686-w64-mingw32-strip'
+pkgconfig = '/usr/bin/pkg-config'
+exe_wrapper = '/usr/bin/wine'
+
+[properties]
+root = '/usr/i686-w64-mingw32'
+needs_exe_wrapper = true
diff --git a/meson/universal-apple-darwin b/meson/universal-apple-darwin
new file mode 100644
index 0000000..0ee2e02
--- /dev/null
+++ b/meson/universal-apple-darwin
@@ -0,0 +1,19 @@
+[host_machine]
+system = 'darwin'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[binaries]
+c = '/usr/universal-apple-darwin/bin/x86_64-apple-darwin15-clang'
+cpp = '/usr/universal-apple-darwin/bin/x86_64-apple-darwin15-clang++'
+objc = '/usr/universal-apple-darwin/bin/x86_64-apple-darwin15-clang'
+ar = '/usr/universal-apple-darwin/bin/x86_64-apple-darwin15-ar'
+strip = '/usr/universal-apple-darwin/bin/x86_64-apple-darwin15-strip'
+pkgconfig = '/usr/bin/pkg-config'
+
+[properties]
+root = '/usr/universal-apple-darwin/SDK/MacOSX10.11.sdk'
+c_args = ['-arch', 'i386', '-arch', 'x86_64']
+c_link_args = ['-arch', 'i386', '-arch', 'x86_64']
+needs_exe_wrapper = true
diff --git a/meson/x86_64-linux-gnu b/meson/x86_64-linux-gnu
new file mode 100644
index 0000000..b09321c
--- /dev/null
+++ b/meson/x86_64-linux-gnu
@@ -0,0 +1,16 @@
+[host_machine]
+system = 'linux'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/x86_64-linux-gnu-gcc'
+cpp = '/usr/bin/x86_64-linux-gnu-g++'
+ar = '/usr/bin/x86_64-linux-gnu-ar'
+strip = '/usr/bin/x86_64-linux-gnu-strip'
+pkgconfig = '/usr/bin/pkg-config'
+
+[properties]
+c_link_args = ['-Wl,-z,defs']
+needs_exe_wrapper = false
diff --git a/meson/x86_64-w64-mingw32 b/meson/x86_64-w64-mingw32
new file mode 100644
index 0000000..40c8a32
--- /dev/null
+++ b/meson/x86_64-w64-mingw32
@@ -0,0 +1,17 @@
+[host_machine]
+system = 'windows'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[binaries]
+c = '/usr/bin/x86_64-w64-mingw32-gcc'
+cpp = '/usr/bin/x86_64-w64-mingw32-g++'
+ar = '/usr/bin/x86_64-w64-mingw32-ar'
+strip = '/usr/bin/x86_64-w64-mingw32-strip'
+pkgconfig = '/usr/bin/pkg-config'
+exe_wrapper = '/usr/bin/wine64'
+
+[properties]
+root = '/usr/x86_64-w64-mingw32'
+needs_exe_wrapper = true
diff --git a/pugl/.gitignore b/pugl/.gitignore
deleted file mode 100644
index e511642..0000000
--- a/pugl/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.waf*/
-build/
-.lock-waf*
diff --git a/pugl/AUTHORS b/pugl/AUTHORS
deleted file mode 100644
index 5625baa..0000000
--- a/pugl/AUTHORS
+++ /dev/null
@@ -1,11 +0,0 @@
-Author:
- David Robillard <d@drobilla.net>
-
-Original GLX inspiration, portability fixes:
- Ben Loftis
-
-Various fixes and improvements:
- Robin Gareus <robin@gareus.org>
-
-UTF-8 and Windows event work:
- Erik Åldstedt Sund <erikalds@gmail.com>
diff --git a/pugl/COPYING b/pugl/COPYING
deleted file mode 100644
index e1e203d..0000000
--- a/pugl/COPYING
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2011-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.
diff --git a/pugl/Doxyfile.in b/pugl/Doxyfile.in
deleted file mode 100644
index 59e3331..0000000
--- a/pugl/Doxyfile.in
+++ /dev/null
@@ -1,2415 +0,0 @@
-# Doxyfile 1.8.12
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME = Pugl
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER = @PUGL_VERSION@
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF =
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = doc
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC = NO
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES = NO
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT = YES
-
-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
-# to that level are automatically included in the table of contents, even if
-# they do not have an id attribute.
-# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-TOC_INCLUDE_HEADINGS = 0
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = YES
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = YES
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS = YES
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT = YES
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES = NO
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES = YES
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS = YES
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC = NO
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME = YES
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST = NO
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST = NO
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST = NO
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES = NO
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC = YES
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT = pugl
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS = *.c
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX = NO
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE = 130
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT = 30
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA = 100
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP = NO
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS = YES
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE =
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX = YES
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE = 1
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN = YES
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME =
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH = NO
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH = NO
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH = NO
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH = NO
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY = NO
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH = NO
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND = NO
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP = YES
diff --git a/pugl/README.md b/pugl/README.md
deleted file mode 100644
index 77809d8..0000000
--- a/pugl/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-PUGL
-====
-
-Pugl is a minimal portable API for GUIs which supports embedding and is
-suitable for use in plugins. It works on X11, Mac OS X, and Windows. GUIs can
-be drawn with OpenGL or Cairo.
-
-Pugl is vaguely similar to GLUT, but with some significant distinctions:
-
- * Minimal in scope, providing only what is necessary to draw and receive
- keyboard and mouse input.
-
- * No reliance on static data whatsoever, so the API can be used in plugins or
- multiple independent parts of a program.
-
- * Single implementation, which is small, liberally licensed Free / Open Source
- Software, and suitable for direct inclusion in programs if avoiding a
- library dependency is desired.
-
- * Support for embedding in other windows, so Pugl code can draw to a widget
- inside a larger GUI.
-
- * More complete support for keyboard input, including additional "special"
- keys, modifiers, and support for detecting individual modifier key presses.
-
-For more information, see <http://drobilla.net/software/pugl>.
-
- -- David Robillard <d@drobilla.net>
diff --git a/pugl/pugl.pc.in b/pugl/pugl.pc.in
deleted file mode 100644
index d3606cd..0000000
--- a/pugl/pugl.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-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/cairo_gl.h b/pugl/pugl/cairo_gl.h
deleted file mode 100644
index 5c0f1f9..0000000
--- a/pugl/pugl/cairo_gl.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- Copyright 2016 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.
-*/
-
-#if defined(PUGL_HAVE_GL) && defined(PUGL_HAVE_CAIRO)
-
-#include <cairo/cairo.h>
-#include <stdint.h>
-
-#include "pugl/gl.h"
-
-typedef struct {
- unsigned texture_id;
- uint8_t* buffer;
-} PuglCairoGL;
-
-static cairo_surface_t*
-pugl_cairo_gl_create(PuglCairoGL* ctx, int width, int height, int bpp)
-{
- free(ctx->buffer);
- ctx->buffer = (uint8_t*)calloc(bpp * width * height, sizeof(uint8_t));
- if (!ctx->buffer) {
- fprintf(stderr, "failed to allocate surface buffer\n");
- return NULL;
- }
-
- return cairo_image_surface_create_for_data(
- ctx->buffer, CAIRO_FORMAT_ARGB32, width, height, bpp * width);
-}
-
-static void
-pugl_cairo_gl_free(PuglCairoGL* ctx)
-{
- free(ctx->buffer);
- ctx->buffer = NULL;
-}
-
-static void
-pugl_cairo_gl_configure(PuglCairoGL* ctx, int width, int height)
-{
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glDeleteTextures(1, &ctx->texture_id);
- glGenTextures(1, &ctx->texture_id);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ctx->texture_id);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
-}
-
-static void
-pugl_cairo_gl_draw(PuglCairoGL* ctx, int width, int height)
-{
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glViewport(0, 0, width, height);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushMatrix();
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glEnable(GL_TEXTURE_2D);
-
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
- width, height, 0,
- GL_BGRA, GL_UNSIGNED_BYTE, ctx->buffer);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0f, (GLfloat)height);
- glVertex2f(-1.0f, -1.0f);
-
- glTexCoord2f((GLfloat)width, (GLfloat)height);
- glVertex2f(1.0f, -1.0f);
-
- glTexCoord2f((GLfloat)width, 0.0f);
- glVertex2f(1.0f, 1.0f);
-
- glTexCoord2f(0.0f, 0.0f);
- glVertex2f(-1.0f, 1.0f);
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_TEXTURE_RECTANGLE_ARB);
- glPopMatrix();
-}
-
-#endif
diff --git a/pugl/pugl/gl.h b/pugl/pugl/gl.h
deleted file mode 100644
index 9a6aeef..0000000
--- a/pugl/pugl/gl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- 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/pugl/glew.h b/pugl/pugl/glew.h
deleted file mode 100644
index 5374406..0000000
--- a/pugl/pugl/glew.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright 2016 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 glew.h.
-
- Unfortunately, GL includes vary across platforms so this header allows for
- pure portable programs.
-*/
-
-#ifdef __APPLE__
-# include "OpenGL/glew.h"
-#else
-# ifdef _WIN32
-# include <windows.h> /* Broken Windows GL headers require this */
-# endif
-# include "GL/glew.h"
-#endif
-
diff --git a/pugl/pugl/glu.h b/pugl/pugl/glu.h
deleted file mode 100644
index 0d3e8e1..0000000
--- a/pugl/pugl/glu.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright 2012-2015 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/pugl.h b/pugl/pugl/pugl.h
deleted file mode 100644
index 1b22260..0000000
--- a/pugl/pugl/pugl.h
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- Copyright 2012-2016 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 minimal portable API for OpenGL.
-*/
-
-#ifndef PUGL_H_INCLUDED
-#define PUGL_H_INCLUDED
-
-#include <stdint.h>
-
-#ifdef PUGL_SHARED
-# ifdef _WIN32
-# define PUGL_LIB_IMPORT __declspec(dllimport)
-# define PUGL_LIB_EXPORT __declspec(dllexport)
-# else
-# define PUGL_LIB_IMPORT __attribute__((visibility("default")))
-# define PUGL_LIB_EXPORT __attribute__((visibility("default")))
-# endif
-# ifdef PUGL_INTERNAL
-# define PUGL_API PUGL_LIB_EXPORT
-# else
-# define PUGL_API PUGL_LIB_IMPORT
-# endif
-#else
-# define PUGL_API
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#else
-# include <stdbool.h>
-#endif
-
-/**
- @defgroup pugl Pugl
- A minimal portable API for OpenGL.
- @{
-*/
-
-/**
- A Pugl view.
-*/
-typedef struct PuglViewImpl PuglView;
-
-/**
- A native window handle.
-
- On X11, this is a Window.
- On OSX, this is an NSView*.
- On Windows, this is a HWND.
-*/
-typedef intptr_t PuglNativeWindow;
-
-/**
- Handle for opaque user data.
-*/
-typedef void* PuglHandle;
-
-/**
- Return status code.
-*/
-typedef enum {
- PUGL_SUCCESS = 0
-} PuglStatus;
-
-/**
- Drawing context type.
-*/
-typedef enum {
- PUGL_GL = 0x1,
- PUGL_CAIRO = 0x2,
- PUGL_CAIRO_GL = 0x3
-} PuglContextType;
-
-/**
- Convenience symbols for ASCII control characters.
-*/
-typedef enum {
- PUGL_CHAR_BACKSPACE = 0x08,
- PUGL_CHAR_ESCAPE = 0x1B,
- PUGL_CHAR_DELETE = 0x7F
-} PuglChar;
-
-/**
- Keyboard modifier flags.
-*/
-typedef enum {
- PUGL_MOD_SHIFT = 1, /**< Shift key */
- PUGL_MOD_CTRL = 1 << 1, /**< Control key */
- PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */
- PUGL_MOD_SUPER = 1 << 3 /**< Mod4/Command/Windows key */
-} PuglMod;
-
-/**
- Special (non-Unicode) keyboard keys.
-
- The numerical values of these symbols occupy a reserved range of Unicode
- points, so it is possible to express either a PuglKey value or a Unicode
- character in the same variable. This is sometimes useful for interfacing
- with APIs that do not make this distinction.
-*/
-typedef enum {
- PUGL_KEY_F1 = 0xE000,
- PUGL_KEY_F2,
- PUGL_KEY_F3,
- PUGL_KEY_F4,
- PUGL_KEY_F5,
- PUGL_KEY_F6,
- PUGL_KEY_F7,
- PUGL_KEY_F8,
- PUGL_KEY_F9,
- PUGL_KEY_F10,
- PUGL_KEY_F11,
- PUGL_KEY_F12,
- PUGL_KEY_LEFT,
- PUGL_KEY_UP,
- PUGL_KEY_RIGHT,
- PUGL_KEY_DOWN,
- PUGL_KEY_PAGE_UP,
- PUGL_KEY_PAGE_DOWN,
- PUGL_KEY_HOME,
- PUGL_KEY_END,
- PUGL_KEY_INSERT,
- PUGL_KEY_SHIFT,
- PUGL_KEY_CTRL,
- PUGL_KEY_ALT,
- PUGL_KEY_SUPER
-} PuglKey;
-
-/**
- The type of a PuglEvent.
-*/
-typedef enum {
- PUGL_NOTHING, /**< No event */
- PUGL_BUTTON_PRESS, /**< Mouse button press */
- PUGL_BUTTON_RELEASE, /**< Mouse button release */
- PUGL_CONFIGURE, /**< View moved and/or resized */
- PUGL_EXPOSE, /**< View exposed, redraw required */
- PUGL_CLOSE, /**< Close view */
- PUGL_KEY_PRESS, /**< Key press */
- PUGL_KEY_RELEASE, /**< Key release */
- PUGL_ENTER_NOTIFY, /**< Pointer entered view */
- PUGL_LEAVE_NOTIFY, /**< Pointer left view */
- PUGL_MOTION_NOTIFY, /**< Pointer motion */
- PUGL_SCROLL, /**< Scroll */
- PUGL_FOCUS_IN, /**< Keyboard focus entered view */
- PUGL_FOCUS_OUT /**< Keyboard focus left view */
-} PuglEventType;
-
-typedef enum {
- PUGL_IS_SEND_EVENT = 1
-} PuglEventFlag;
-
-/**
- Reason for a PuglEventCrossing.
-*/
-typedef enum {
- PUGL_CROSSING_NORMAL, /**< Crossing due to pointer motion. */
- PUGL_CROSSING_GRAB, /**< Crossing due to a grab. */
- PUGL_CROSSING_UNGRAB /**< Crossing due to a grab release. */
-} PuglCrossingMode;
-
-/**
- Common header for all event structs.
-*/
-typedef struct {
- PuglEventType type; /**< Event type. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
-} PuglEventAny;
-
-/**
- Button press or release event.
-
- For event types PUGL_BUTTON_PRESS and PUGL_BUTTON_RELEASE.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_BUTTON_PRESS or PUGL_BUTTON_RELEASE. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double x_root; /**< Root-relative X coordinate. */
- double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- unsigned button; /**< 1-relative button number. */
-} PuglEventButton;
-
-/**
- Configure event for when window size or position has changed.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_CONFIGURE. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- double x; /**< New parent-relative X coordinate. */
- double y; /**< New parent-relative Y coordinate. */
- double width; /**< New width. */
- double height; /**< New height. */
-} PuglEventConfigure;
-
-/**
- Expose event for when a region must be redrawn.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_EXPOSE. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double width; /**< Width of exposed region. */
- double height; /**< Height of exposed region. */
- int count; /**< Number of expose events to follow. */
-} PuglEventExpose;
-
-/**
- Window close event.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_CLOSE. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
-} PuglEventClose;
-
-/**
- Key press/release event.
-
- Keys that correspond to a Unicode character have `character` and `utf8` set.
- Other keys will have `character` 0, but `special` may be set if this is a
- known special key.
-
- A key press may be part of a multi-key sequence to generate a wide
- character. If `filter` is set, this event is part of a multi-key sequence
- and should be ignored if the application is reading textual input.
- Following the series of filtered press events, a press event with
- `character` and `utf8` (but `keycode` 0) will be sent. This event will have
- no corresponding release event.
-
- Generally, an application should either work with raw keyboard press/release
- events based on `keycode` (ignoring events with `keycode` 0), or
- read textual input based on `character` or `utf8` (ignoring releases and
- events with `filter` 1). Note that blindly appending `utf8` will yield
- incorrect text, since press events are sent for both individually composed
- keys and the resulting synthetic multi-byte press.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_KEY_PRESS or PUGL_KEY_RELEASE. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double x_root; /**< Root-relative X coordinate. */
- double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- unsigned keycode; /**< Raw key code. */
- uint32_t character; /**< Unicode character code, or 0. */
- PuglKey special; /**< Special key, or 0. */
- uint8_t utf8[8]; /**< UTF-8 string. */
- bool filter; /**< True if part of a multi-key sequence. */
-} PuglEventKey;
-
-/**
- Pointer crossing event (enter and leave).
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_ENTER_NOTIFY or PUGL_LEAVE_NOTIFY. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double x_root; /**< Root-relative X coordinate. */
- double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- PuglCrossingMode mode; /**< Reason for crossing. */
-} PuglEventCrossing;
-
-/**
- Pointer motion event.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_MOTION_NOTIFY. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double x_root; /**< Root-relative X coordinate. */
- double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- bool is_hint; /**< True iff this event is a motion hint. */
- bool focus; /**< True iff this is the focused window. */
-} PuglEventMotion;
-
-/**
- Scroll event.
-
- The scroll distance is expressed in "lines", an arbitrary unit that
- corresponds to a single tick of a detented mouse wheel. For example, `dy` =
- 1.0 scrolls 1 line up. Some systems and devices support finer resolution
- and/or higher values for fast scrolls, so programs should handle any value
- gracefully.
- */
-typedef struct {
- PuglEventType type; /**< PUGL_SCROLL. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
- double x; /**< View-relative X coordinate. */
- double y; /**< View-relative Y coordinate. */
- double x_root; /**< Root-relative X coordinate. */
- double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- double dx; /**< Scroll X distance in lines. */
- double dy; /**< Scroll Y distance in lines. */
-} PuglEventScroll;
-
-/**
- Keyboard focus event.
-*/
-typedef struct {
- PuglEventType type; /**< PUGL_FOCUS_IN or PUGL_FOCUS_OUT. */
- PuglView* view; /**< View that received this event. */
- uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- bool grab; /**< True iff this is a grab/ungrab event. */
-} PuglEventFocus;
-
-/**
- Interface event.
-
- This is a union of all event structs. The `type` must be checked to
- determine which fields are safe to access. A pointer to PuglEvent can
- either be cast to the appropriate type, or the union members used.
-*/
-typedef union {
- PuglEventType type; /**< Event type. */
- PuglEventAny any; /**< Valid for all event types. */
- PuglEventButton button; /**< PUGL_BUTTON_PRESS, PUGL_BUTTON_RELEASE. */
- PuglEventConfigure configure; /**< PUGL_CONFIGURE. */
- PuglEventExpose expose; /**< PUGL_EXPOSE. */
- PuglEventClose close; /**< PUGL_CLOSE. */
- PuglEventKey key; /**< PUGL_KEY_PRESS, PUGL_KEY_RELEASE. */
- PuglEventCrossing crossing; /**< PUGL_ENTER_NOTIFY, PUGL_LEAVE_NOTIFY. */
- PuglEventMotion motion; /**< PUGL_MOTION_NOTIFY. */
- PuglEventScroll scroll; /**< PUGL_SCROLL. */
- PuglEventFocus focus; /**< PUGL_FOCUS_IN, PUGL_FOCUS_OUT. */
-} PuglEvent;
-
-/**
- @name Initialization
- Configuration functions which must be called before creating a window.
- @{
-*/
-
-/**
- Create a Pugl view.
-
- To create a window, call the various puglInit* functions as necessary, then
- call puglCreateWindow().
-
- @param pargc Pointer to argument count (currently unused).
- @param argv Arguments (currently unused).
- @return A newly created view.
-*/
-PUGL_API PuglView*
-puglInit(int* pargc, char** argv);
-
-/**
- Set the window class name before creating a window.
-*/
-PUGL_API void
-puglInitWindowClass(PuglView* view, const char* name);
-
-/**
- Set the parent window before creating a window (for embedding).
-*/
-PUGL_API void
-puglInitWindowParent(PuglView* view, PuglNativeWindow parent);
-
-/**
- Set the window size before creating a window.
-*/
-PUGL_API void
-puglInitWindowSize(PuglView* view, int width, int height);
-
-/**
- Set the minimum window size before creating a window.
-*/
-PUGL_API void
-puglInitWindowMinSize(PuglView* view, int width, int height);
-
-/**
- Set the window aspect ratio range before creating a window.
-
- The x and y values here represent a ratio of width to height. To set a
- fixed aspect ratio, set the minimum and maximum values to the same ratio.
-*/
-PUGL_API void
-puglInitWindowAspectRatio(PuglView* view,
- int min_x,
- int min_y,
- int max_x,
- int max_y);
-
-/**
- Enable or disable resizing before creating a window.
-*/
-PUGL_API void
-puglInitResizable(PuglView* view, bool resizable);
-
-/**
- Set transient parent before creating a window.
-
- On X11, parent must be a Window.
- On OSX, parent must be an NSView*.
-*/
-PUGL_API void
-puglInitTransientFor(PuglView* view, uintptr_t parent);
-
-/**
- Set the context type before creating a window.
-*/
-PUGL_API void
-puglInitContextType(PuglView* view, PuglContextType type);
-
-/**
- @}
-*/
-
-/**
- @name Windows
- Functions for creating and managing a visible window for a view.
- @{
-*/
-
-/**
- Create a window with the settings given by the various puglInit functions.
-
- @return 1 (pugl does not currently support multiple windows).
-*/
-PUGL_API int
-puglCreateWindow(PuglView* view, const char* title);
-
-/**
- Show the current window.
-*/
-PUGL_API void
-puglShowWindow(PuglView* view);
-
-/**
- Hide the current window.
-*/
-PUGL_API void
-puglHideWindow(PuglView* view);
-
-/**
- Return the native window handle.
-*/
-PUGL_API PuglNativeWindow
-puglGetNativeWindow(PuglView* view);
-
-/**
- @}
-*/
-
-/**
- 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.
-*/
-PUGL_API void
-puglSetHandle(PuglView* view, PuglHandle handle);
-
-/**
- Get the handle to be passed to all callbacks.
-*/
-PUGL_API PuglHandle
-puglGetHandle(PuglView* view);
-
-/**
- Return true iff the view is currently visible.
-*/
-PUGL_API bool
-puglGetVisible(PuglView* view);
-
-/**
- Get the current size of the view.
-*/
-PUGL_API void
-puglGetSize(PuglView* view, int* width, int* height);
-
-/**
- @name Context
- Functions for accessing the drawing context.
- @{
-*/
-
-/**
- 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);
-
-
-/**
- Enter the drawing context.
-
- This must be called before any code that accesses the drawing context,
- including any GL functions. This is only necessary for code that does so
- outside the usual draw callback or handling of an expose event.
-*/
-PUGL_API void
-puglEnterContext(PuglView* view);
-
-/**
- Leave the drawing context.
-
- This must be called after puglEnterContext and applies the results of the
- drawing code (for example, by swapping buffers).
-*/
-PUGL_API void
-puglLeaveContext(PuglView* view, bool flush);
-
-/**
- @}
-*/
-
-/**
- @name Event Handling
- @{
-*/
-
-/**
- A function called when an event occurs.
-*/
-typedef void (*PuglEventFunc)(PuglView* view, const PuglEvent* event);
-
-/**
- Set the function to call when an event occurs.
-*/
-PUGL_API void
-puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc);
-
-/**
- Ignore synthetic repeated key events.
-*/
-PUGL_API void
-puglIgnoreKeyRepeat(PuglView* view, bool ignore);
-
-/**
- Grab the input focus.
-*/
-PUGL_API void
-puglGrabFocus(PuglView* view);
-
-/**
- Block and wait for an event to be ready.
-
- This can be used in a loop to only process events via puglProcessEvents when
- necessary. This function will block indefinitely if no events are
- available, so is not appropriate for use in programs that need to perform
- regular updates (e.g. animation).
-*/
-PUGL_API PuglStatus
-puglWaitForEvent(PuglView* view);
-
-/**
- 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. This function does
- not block if no events are pending.
-*/
-PUGL_API PuglStatus
-puglProcessEvents(PuglView* view);
-
-/**
- @}
-*/
-
-/**
- Request a redisplay on the next call to puglProcessEvents().
-*/
-PUGL_API void
-puglPostRedisplay(PuglView* view);
-
-/**
- Destroy a GL window.
-*/
-PUGL_API void
-puglDestroy(PuglView* view);
-
-/**
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* PUGL_H_INCLUDED */
diff --git a/pugl/pugl/pugl.hpp b/pugl/pugl/pugl.hpp
deleted file mode 100644
index 8232887..0000000
--- a/pugl/pugl/pugl.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- Copyright 2012-2015 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.hpp C++ API for Pugl, a minimal portable API for OpenGL.
-*/
-
-#ifndef PUGL_HPP_INCLUDED
-#define PUGL_HPP_INCLUDED
-
-#include "pugl/pugl.h"
-
-/**
- @defgroup puglmm Puglmm
- C++ API wrapper for Pugl.
- @{
-*/
-
-namespace pugl {
-
-class View {
-public:
- View(int* pargc, char** argv)
- : _view(puglInit(pargc, argv))
- {
- puglSetHandle(_view, this);
- puglSetEventFunc(_view, _onEvent);
- }
-
- virtual ~View() { puglDestroy(_view); }
-
- virtual void initWindowParent(PuglNativeWindow parent) {
- puglInitWindowParent(_view, parent);
- }
-
- virtual void initWindowSize(int width, int height) {
- puglInitWindowSize(_view, width, height);
- }
-
- virtual void initWindowMinSize(int width, int height) {
- puglInitWindowMinSize(_view, width, height);
- }
-
- virtual void initWindowAspectRatio(int min_x, int min_y, int max_x, int max_y) {
- puglInitWindowAspectRatio(_view, min_x, min_y, max_x, max_y);
- }
-
- virtual void initResizable(bool resizable) {
- puglInitResizable(_view, resizable);
- }
-
- virtual void initTransientFor(uintptr_t parent) {
- puglInitTransientFor(_view, parent);
- }
-
- virtual void initContextType(PuglContextType type) {
- puglInitContextType(_view, type);
- }
-
- virtual void createWindow(const char* title) {
- puglCreateWindow(_view, title);
- }
-
- virtual void showWindow() { puglShowWindow(_view); }
- virtual void hideWindow() { puglHideWindow(_view); }
- virtual PuglNativeWindow getNativeWindow() { return puglGetNativeWindow(_view); }
-
- virtual void onEvent(const PuglEvent* event) = 0;
-
- virtual void* getContext() { return puglGetContext(_view); }
- virtual void ignoreKeyRepeat(bool ignore) { puglIgnoreKeyRepeat(_view, ignore); }
- virtual void grabFocus() { puglGrabFocus(_view); }
- virtual PuglStatus waitForEvent() { return puglWaitForEvent(_view); }
- virtual PuglStatus processEvents() { return puglProcessEvents(_view); }
- virtual void postRedisplay() { puglPostRedisplay(_view); }
-
- PuglView* cobj() { return _view; }
-
-private:
- static void _onEvent(PuglView* view, const PuglEvent* event) {
- ((View*)puglGetHandle(view))->onEvent(event);
- }
-
- PuglView* _view;
-};
-
-} // namespace pugl
-
-/**
- @}
-*/
-
-#endif /* PUGL_HPP_INCLUDED */
diff --git a/pugl/pugl/pugl_internal.h b/pugl/pugl/pugl_internal.h
deleted file mode 100644
index 4a3fc0c..0000000
--- a/pugl/pugl/pugl_internal.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- Copyright 2012-2016 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_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.
-
- If you are copying the pugl code into your source tree, the following
- symbols can be defined to tweak pugl behaviour:
-
- PUGL_HAVE_CAIRO: Include Cairo support code.
- PUGL_HAVE_GL: Include OpenGL support code.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "pugl/pugl.h"
-
-typedef struct PuglInternalsImpl PuglInternals;
-
-struct PuglViewImpl {
- PuglHandle handle;
- PuglEventFunc eventFunc;
-
- PuglInternals* impl;
-
- char* windowClass;
- PuglNativeWindow parent;
- PuglContextType ctx_type;
- uintptr_t transient_parent;
-
- int width;
- int height;
- int min_width;
- int min_height;
- int min_aspect_x;
- int min_aspect_y;
- int max_aspect_x;
- int max_aspect_y;
- bool ignoreKeyRepeat;
- bool redisplay;
- bool resizable;
- bool visible;
-};
-
-PuglInternals* puglInitInternals(void);
-
-PuglView*
-puglInit(int* pargc, char** argv)
-{
- PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
- if (!view) {
- return NULL;
- }
-
- PuglInternals* impl = puglInitInternals();
- if (!impl) {
- return NULL;
- }
-
- view->ctx_type = PUGL_GL;
- view->impl = impl;
- view->width = 640;
- view->height = 480;
-
- return view;
-}
-
-void
-puglInitWindowSize(PuglView* view, int width, int height)
-{
- view->width = width;
- view->height = height;
-}
-
-void
-puglInitWindowMinSize(PuglView* view, int width, int height)
-{
- view->min_width = width;
- view->min_height = height;
-}
-
-void
-puglInitWindowAspectRatio(PuglView* view,
- int min_x,
- int min_y,
- int max_x,
- int max_y)
-{
- view->min_aspect_x = min_x;
- view->min_aspect_y = min_y;
- view->max_aspect_x = max_x;
- view->max_aspect_y = max_y;
-}
-
-void
-puglInitWindowClass(PuglView* view, const char* name)
-{
- const size_t len = strlen(name);
-
- free(view->windowClass);
- view->windowClass = (char*)calloc(1, len + 1);
- memcpy(view->windowClass, name, len);
-}
-
-void
-puglInitWindowParent(PuglView* view, PuglNativeWindow parent)
-{
- view->parent = parent;
-}
-
-void
-puglInitResizable(PuglView* view, bool resizable)
-{
- view->resizable = resizable;
-}
-
-void
-puglInitTransientFor(PuglView* view, uintptr_t parent)
-{
- view->transient_parent = parent;
-}
-
-void
-puglInitContextType(PuglView* view, PuglContextType type)
-{
- view->ctx_type = type;
-}
-
-void
-puglSetHandle(PuglView* view, PuglHandle handle)
-{
- view->handle = handle;
-}
-
-PuglHandle
-puglGetHandle(PuglView* view)
-{
- return view->handle;
-}
-
-bool
-puglGetVisible(PuglView* view)
-{
- return view->visible;
-}
-
-void
-puglGetSize(PuglView* view, int* width, int* height)
-{
- *width = view->width;
- *height = view->height;
-}
-
-void
-puglIgnoreKeyRepeat(PuglView* view, bool ignore)
-{
- view->ignoreKeyRepeat = ignore;
-}
-
-void
-puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc)
-{
- view->eventFunc = eventFunc;
-}
-
-/** Return the code point for buf, or the replacement character on error. */
-static uint32_t
-puglDecodeUTF8(const uint8_t* buf)
-{
-#define FAIL_IF(cond) { if (cond) return 0xFFFD; }
-
- // http://en.wikipedia.org/wiki/UTF-8
-
- if (buf[0] < 0x80) {
- return buf[0];
- } else if (buf[0] < 0xC2) {
- return 0xFFFD;
- } else if (buf[0] < 0xE0) {
- FAIL_IF((buf[1] & 0xC0) != 0x80);
- return (buf[0] << 6) + buf[1] - 0x3080;
- } else if (buf[0] < 0xF0) {
- FAIL_IF((buf[1] & 0xC0) != 0x80);
- FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0);
- FAIL_IF((buf[2] & 0xC0) != 0x80);
- return (buf[0] << 12) + (buf[1] << 6) + buf[2] - 0xE2080;
- } else if (buf[0] < 0xF5) {
- FAIL_IF((buf[1] & 0xC0) != 0x80);
- FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90);
- FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90);
- FAIL_IF((buf[2] & 0xC0) != 0x80);
- FAIL_IF((buf[3] & 0xC0) != 0x80);
- return ((buf[0] << 18) +
- (buf[1] << 12) +
- (buf[2] << 6) +
- buf[3] - 0x3C82080);
- }
- return 0xFFFD;
-}
-
-static void
-puglDispatchEvent(PuglView* view, const PuglEvent* event)
-{
- switch (event->type) {
- case PUGL_NOTHING:
- break;
- case PUGL_CONFIGURE:
- view->width = event->configure.width;
- view->height = event->configure.height;
- puglEnterContext(view);
- view->eventFunc(view, event);
- puglLeaveContext(view, false);
- break;
- case PUGL_EXPOSE:
- if (event->expose.count == 0) {
- puglEnterContext(view);
- view->eventFunc(view, event);
- puglLeaveContext(view, true);
- }
- break;
- default:
- view->eventFunc(view, event);
- }
-}
diff --git a/pugl/pugl/pugl_osx.m b/pugl/pugl/pugl_osx.m
deleted file mode 100644
index d2681cb..0000000
--- a/pugl/pugl/pugl_osx.m
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- Copyright 2012-2016 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_osx.m OSX/Cocoa Pugl Implementation.
-*/
-
-#include <stdlib.h>
-
-#import <Cocoa/Cocoa.h>
-
-#include "pugl/cairo_gl.h"
-#include "pugl/gl.h"
-#include "pugl/pugl_internal.h"
-
-@class PuglOpenGLView;
-
-struct PuglInternalsImpl {
- NSApplication* app;
- PuglOpenGLView* glview;
- id window;
- NSEvent* nextEvent;
-#ifdef PUGL_HAVE_CAIRO
- cairo_surface_t* surface;
- cairo_t* cr;
- PuglCairoGL cairo_gl;
-#endif
-};
-
-@interface PuglWindow : NSWindow
-{
-@public
- PuglView* puglview;
-}
-
-- (id) initWithContentRect:(NSRect)contentRect
- styleMask:(unsigned int)aStyle
- backing:(NSBackingStoreType)bufferingType
- defer:(BOOL)flag;
-- (void) setPuglview:(PuglView*)view;
-- (BOOL) windowShouldClose:(id)sender;
-- (BOOL) canBecomeKeyWindow:(id)sender;
-@end
-
-@implementation PuglWindow
-
-- (id)initWithContentRect:(NSRect)contentRect
- styleMask:(unsigned int)aStyle
- backing:(NSBackingStoreType)bufferingType
- defer:(BOOL)flag
-{
- if (![super initWithContentRect:contentRect
- styleMask:(NSClosableWindowMask |
- NSTitledWindowMask |
- NSResizableWindowMask)
- backing:NSBackingStoreBuffered defer:NO]) {
- return nil;
- }
-
- [self setAcceptsMouseMovedEvents:YES];
- return (PuglWindow*)self;
-}
-
-- (void)setPuglview:(PuglView*)view
-{
- puglview = view;
- [self setContentSize:NSMakeSize(view->width, view->height)];
-}
-
-- (BOOL)windowShouldClose:(id)sender
-{
- const PuglEventClose ev = {
- PUGL_CLOSE,
- puglview,
- 0
- };
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-
- return YES;
-}
-
-- (BOOL) canBecomeKeyWindow
-{
- return YES;
-}
-
-- (BOOL) canBecomeMainWindow
-{
- return YES;
-}
-
-- (BOOL) canBecomeKeyWindow:(id)sender
-{
- return NO;
-}
-
-@end
-
-@interface PuglOpenGLView : NSOpenGLView
-{
-@public
- PuglView* puglview;
-
- NSTrackingArea* trackingArea;
-}
-
-- (id) initWithFrame:(NSRect)frame;
-- (void) reshape;
-- (void) drawRect:(NSRect)rect;
-- (NSPoint) eventLocation:(NSEvent*)event;
-- (void) mouseEntered:(NSEvent*)event;
-- (void) mouseExited:(NSEvent*)event;
-- (void) mouseMoved:(NSEvent*)event;
-- (void) mouseDragged:(NSEvent*)event;
-- (void) rightMouseDragged:(NSEvent*)event;
-- (void) mouseDown:(NSEvent*)event;
-- (void) mouseUp:(NSEvent*)event;
-- (void) rightMouseDragged:(NSEvent*)event;
-- (void) rightMouseDown:(NSEvent*)event;
-- (void) rightMouseUp:(NSEvent*)event;
-- (void) otherMouseDragged:(NSEvent*)event;
-- (void) otherMouseDown:(NSEvent*)event;
-- (void) otherMouseUp:(NSEvent*)event;
-- (void) scrollWheel:(NSEvent*)event;
-- (void) keyDown:(NSEvent*)event;
-- (void) keyUp:(NSEvent*)event;
-- (void) flagsChanged:(NSEvent*)event;
-
-@end
-
-@implementation PuglOpenGLView
-
-- (id) initWithFrame:(NSRect)frame
-{
- NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAColorSize, 32,
- NSOpenGLPFADepthSize, 32,
- 0
- };
-
- NSOpenGLPixelFormat* pixelFormat = [
- [NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttribs];
-
- if (pixelFormat) {
- self = [super initWithFrame:frame pixelFormat:pixelFormat];
- [pixelFormat release];
- } else {
- self = [super initWithFrame:frame];
- }
-
- if (self) {
- [[self openGLContext] makeCurrentContext];
- [self reshape];
- }
- return self;
-}
-
-- (void) reshape
-{
- [[self openGLContext] update];
-
- if (!puglview) {
- return;
- }
-
- const NSRect bounds = [self bounds];
- const PuglEventConfigure ev = {
- PUGL_CONFIGURE,
- puglview,
- 0,
- bounds.origin.x,
- bounds.origin.y,
- bounds.size.width,
- bounds.size.height,
- };
-
-#ifdef PUGL_HAVE_CAIRO
- PuglInternals* impl = puglview->impl;
- if (puglview->ctx_type & PUGL_CAIRO) {
- cairo_surface_destroy(impl->surface);
- cairo_destroy(impl->cr);
- impl->surface = pugl_cairo_gl_create(
- &impl->cairo_gl, ev.width, ev.height, 4);
- impl->cr = cairo_create(impl->surface);
- pugl_cairo_gl_configure(&impl->cairo_gl, ev.width, ev.height);
- }
-#endif
-
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-}
-
-- (void) drawRect:(NSRect)rect
-{
- const PuglEventExpose ev = {
- PUGL_EXPOSE,
- puglview,
- 0,
- rect.origin.x,
- rect.origin.y,
- rect.size.width,
- rect.size.height,
- 0
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-
-#ifdef PUGL_HAVE_CAIRO
- if (puglview->ctx_type & PUGL_CAIRO) {
- pugl_cairo_gl_draw(
- &puglview->impl->cairo_gl, puglview->width, puglview->height);
- }
-#endif
-}
-
-- (BOOL) acceptsFirstResponder
-{
- return YES;
-}
-
-static unsigned
-getModifiers(PuglView* view, NSEvent* ev)
-{
- const unsigned modifierFlags = [ev modifierFlags];
-
- unsigned mods = 0;
- mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0;
- mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0;
- mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0;
- mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0;
- return mods;
-}
-
--(void)updateTrackingAreas
-{
- if (trackingArea != nil) {
- [self removeTrackingArea:trackingArea];
- [trackingArea release];
- }
-
- const int opts = (NSTrackingMouseEnteredAndExited |
- NSTrackingMouseMoved |
- NSTrackingActiveAlways);
- trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
- options:opts
- owner:self
- userInfo:nil];
- [self addTrackingArea:trackingArea];
-}
-
-- (NSPoint) eventLocation:(NSEvent*)event
-{
- return [self convertPoint:[event locationInWindow] fromView:nil];
-}
-
-- (void)mouseEntered:(NSEvent*)theEvent
-{
- [self updateTrackingAreas];
-}
-
-- (void)mouseExited:(NSEvent*)theEvent
-{
-}
-
-- (void) mouseMoved:(NSEvent*)event
-{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventMotion ev = {
- PUGL_MOTION_NOTIFY,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- 0,
- 1
- };
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-}
-
-- (void) mouseDragged:(NSEvent*)event
-{
- [self mouseMoved: event];
-}
-
-- (void) rightMouseDragged:(NSEvent*)event
-{
- [self mouseMoved: event];
-}
-
-- (void) otherMouseDragged:(NSEvent*)event
-{
- [self mouseMoved: event];
-}
-
-- (void) mouseDown:(NSEvent*)event
-{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventButton ev = {
- PUGL_BUTTON_PRESS,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- [event buttonNumber] + 1
- };
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-}
-
-- (void) mouseUp:(NSEvent*)event
-{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventButton ev = {
- PUGL_BUTTON_RELEASE,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- [event buttonNumber] + 1
- };
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
- [self updateTrackingAreas];
-}
-
-- (void) rightMouseDown:(NSEvent*)event
-{
- [self mouseDown: event];
-}
-
-- (void) rightMouseUp:(NSEvent*)event
-{
- [self mouseUp: event];
-}
-
-- (void) otherMouseDown:(NSEvent*)event
-{
- [self mouseDown: event];
-}
-
-- (void) otherMouseUp:(NSEvent*)event
-{
- [self mouseUp: event];
-}
-
-- (void) scrollWheel:(NSEvent*)event
-{
- [self updateTrackingAreas];
-
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventScroll ev = {
- PUGL_SCROLL,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- [event deltaX],
- [event deltaY]
- };
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
- [self updateTrackingAreas];
-}
-
-- (void) keyDown:(NSEvent*)event
-{
- if (puglview->ignoreKeyRepeat && [event isARepeat]) {
- return;
- }
-
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const NSString* chars = [event characters];
- const char* str = [chars UTF8String];
- PuglEventKey ev = {
- PUGL_KEY_PRESS,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- [event keyCode],
- puglDecodeUTF8((const uint8_t*)str),
- 0, // TODO: Special keys?
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- false
- };
- strncpy((char*)ev.utf8, str, 8);
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-}
-
-- (void) keyUp:(NSEvent*)event
-{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const NSString* chars = [event characters];
- const char* str = [chars UTF8String];
- const PuglEventKey ev = {
- PUGL_KEY_RELEASE,
- puglview,
- 0,
- [event timestamp],
- wloc.x,
- puglview->height - wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(puglview, event),
- [event keyCode],
- puglDecodeUTF8((const uint8_t*)str),
- 0, // TODO: Special keys?
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- false,
- };
- strncpy((char*)ev.utf8, str, 8);
- puglDispatchEvent(puglview, (PuglEvent*)&ev);
-}
-
-- (void) flagsChanged:(NSEvent*)event
-{
- // TODO: Is this a sensible way to handle special keys?
- /*
- const unsigned mods = getModifiers(puglview, event);
- if ((mods & PUGL_MOD_SHIFT) != (puglview->mods & PUGL_MOD_SHIFT)) {
- puglview->specialFunc(puglview, mods & PUGL_MOD_SHIFT, PUGL_KEY_SHIFT);
- } else if ((mods & PUGL_MOD_CTRL) != (puglview->mods & PUGL_MOD_CTRL)) {
- puglview->specialFunc(puglview, mods & PUGL_MOD_CTRL, PUGL_KEY_CTRL);
- } else if ((mods & PUGL_MOD_ALT) != (puglview->mods & PUGL_MOD_ALT)) {
- puglview->specialFunc(puglview, mods & PUGL_MOD_ALT, PUGL_KEY_ALT);
- } else if ((mods & PUGL_MOD_SUPER) != (puglview->mods & PUGL_MOD_SUPER)) {
- puglview->specialFunc(puglview, mods & PUGL_MOD_SUPER, PUGL_KEY_SUPER);
- }
- puglview->mods = mods;
- }
- */
-}
-
-@end
-
-PuglInternals*
-puglInitInternals(void)
-{
- return (PuglInternals*)calloc(1, sizeof(PuglInternals));
-}
-
-void
-puglEnterContext(PuglView* view)
-{
- [[view->impl->glview openGLContext] makeCurrentContext];
-#ifdef PUGL_HAVE_CAIRO
- if (view->ctx_type & PUGL_CAIRO) {
- cairo_set_source_rgb(view->impl->cr, 0, 0, 0);
- cairo_paint(view->impl->cr);
- }
-#endif
-}
-
-void
-puglLeaveContext(PuglView* view, bool flush)
-{
-#ifdef PUGL_HAVE_CAIRO
- if (view->ctx_type & PUGL_CAIRO) {
- pugl_cairo_gl_draw(&view->impl->cairo_gl, view->width, view->height);
- }
-#endif
-
- if (flush) {
- [[view->impl->glview openGLContext] flushBuffer];
- }
-}
-
-int
-puglCreateWindow(PuglView* view, const char* title)
-{
- PuglInternals* impl = view->impl;
-
- [NSAutoreleasePool new];
- impl->app = [NSApplication sharedApplication];
-
- impl->glview = [PuglOpenGLView new];
- impl->glview->puglview = view;
-
- if (view->transient_parent) {
- NSView* pview = (NSView*)view->transient_parent;
- [pview addSubview:impl->glview];
- [impl->glview setHidden:NO];
- } else {
- NSString* titleString = [[NSString alloc]
- initWithBytes:title
- length:strlen(title)
- encoding:NSUTF8StringEncoding];
-
- id window = [[PuglWindow new] retain];
- [window setPuglview:view];
- [window setTitle:titleString];
- if (view->min_width || view->min_height) {
- [window setContentMinSize:NSMakeSize(view->min_width,
- view->min_height)];
- }
- impl->window = window;
-
- [window setContentView:impl->glview];
- [impl->app activateIgnoringOtherApps:YES];
- [window makeFirstResponder:impl->glview];
- [window makeKeyAndOrderFront:window];
-#if 0
- if (resizable) {
- [impl->glview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
- }
-#endif
- }
-
- return 0;
-}
-
-void
-puglShowWindow(PuglView* view)
-{
- [view->impl->window setIsVisible:YES];
- view->visible = true;
-}
-
-void
-puglHideWindow(PuglView* view)
-{
- [view->impl->window setIsVisible:NO];
- view->visible = false;
-}
-
-void
-puglDestroy(PuglView* view)
-{
-#ifdef PUGL_HAVE_CAIRO
- pugl_cairo_gl_free(&view->impl->cairo_gl);
-#endif
- view->impl->glview->puglview = NULL;
- [view->impl->glview removeFromSuperview];
- if (view->impl->window) {
- [view->impl->window close];
- }
- [view->impl->glview release];
- if (view->impl->window) {
- [view->impl->window release];
- }
- free(view->windowClass);
- free(view->impl);
- free(view);
-}
-
-void
-puglGrabFocus(PuglView* view)
-{
- // TODO
-}
-
-PuglStatus
-puglWaitForEvent(PuglView* view)
-{
- /* OSX supposedly has queue: and untilDate: selectors that can be used for
- a blocking non-queueing event check, but if used here cause an
- unsupported selector error at runtime. I have no idea why, so just get
- the event and keep it around until the call to puglProcessEvents. */
- if (!view->impl->nextEvent) {
- view->impl->nextEvent = [view->impl->window
- nextEventMatchingMask: NSAnyEventMask];
- }
-
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglProcessEvents(PuglView* view)
-{
- while (true) {
- // Get the next event, or use the cached one from puglWaitForEvent
- if (!view->impl->nextEvent) {
- view->impl->nextEvent = [view->impl->window
- nextEventMatchingMask: NSAnyEventMask];
- }
-
- if (!view->impl->nextEvent) {
- break; // No events to process, done
- }
-
- // Dispatch event
- [view->impl->app sendEvent: view->impl->nextEvent];
- view->impl->nextEvent = NULL;
- }
-
- return PUGL_SUCCESS;
-}
-
-void
-puglPostRedisplay(PuglView* view)
-{
- //view->redisplay = true; // unused
- [view->impl->glview setNeedsDisplay: YES];
-}
-
-PuglNativeWindow
-puglGetNativeWindow(PuglView* view)
-{
- return (PuglNativeWindow)view->impl->glview;
-}
-
-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/pugl/pugl_win.cpp b/pugl/pugl/pugl_win.cpp
deleted file mode 100644
index 83d4474..0000000
--- a/pugl/pugl/pugl_win.cpp
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- Copyright 2012-2015 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_win.cpp Windows/WGL Pugl Implementation.
-*/
-
-#include <windows.h>
-#include <windowsx.h>
-#include <GL/gl.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wctype.h>
-
-#include "pugl/pugl_internal.h"
-
-#ifndef WM_MOUSEWHEEL
-# define WM_MOUSEWHEEL 0x020A
-#endif
-#ifndef WM_MOUSEHWHEEL
-# define WM_MOUSEHWHEEL 0x020E
-#endif
-#ifndef WHEEL_DELTA
-# define WHEEL_DELTA 120
-#endif
-#ifdef _WIN64
-# ifndef GWLP_USERDATA
-# define GWLP_USERDATA (-21)
-# endif
-#else
-# ifndef GWL_USERDATA
-# define GWL_USERDATA (-21)
-# endif
-#endif
-
-#define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50)
-
-struct PuglInternalsImpl {
- HWND hwnd;
- HDC hdc;
- HGLRC hglrc;
- WNDCLASS wc;
-};
-
-LRESULT CALLBACK
-wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
-
-PuglView*
-puglInit()
-{
- PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
- PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
- if (!view || !impl) {
- return NULL;
- }
-
- view->impl = impl;
- view->width = 640;
- view->height = 480;
-
- return view;
-}
-
-PuglInternals*
-puglInitInternals(void)
-{
- return (PuglInternals*)calloc(1, sizeof(PuglInternals));
-}
-
-void
-puglEnterContext(PuglView* view)
-{
- PAINTSTRUCT ps;
- BeginPaint(view->impl->hwnd, &ps);
-
-#ifdef PUGL_HAVE_GL
- if (view->ctx_type == PUGL_GL) {
- wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
- }
-#endif
-}
-
-void
-puglLeaveContext(PuglView* view, bool flush)
-{
-#ifdef PUGL_HAVE_GL
- if (view->ctx_type == PUGL_GL && flush) {
- glFlush();
- SwapBuffers(view->impl->hdc);
- }
-#endif
-
- PAINTSTRUCT ps;
- EndPaint(view->impl->hwnd, &ps);
-}
-
-int
-puglCreateWindow(PuglView* view, const char* title)
-{
- static const TCHAR* DEFAULT_CLASSNAME = "Pugl";
-
- PuglInternals* impl = view->impl;
-
- if (!title) {
- title = "Window";
- }
-
- WNDCLASSEX wc;
- memset(&wc, 0, sizeof(wc));
- wc.cbSize = sizeof(wc);
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = wndProc;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // TODO: user-specified icon
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszClassName = view->windowClass ? view->windowClass : DEFAULT_CLASSNAME;
- if (!RegisterClassEx(&wc)) {
- free((void*)impl->wc.lpszClassName);
- free(impl);
- free(view);
- return NULL;
- }
-
- int winFlags = WS_POPUPWINDOW | WS_CAPTION;
- if (view->resizable) {
- winFlags |= WS_SIZEBOX;
- if (view->min_width || view->min_height) {
- // Adjust the minimum window size to accomodate requested view size
- RECT mr = { 0, 0, view->min_width, view->min_height };
- AdjustWindowRectEx(&mr, winFlags, FALSE, WS_EX_TOPMOST);
- view->min_width = mr.right - mr.left;
- view->min_height = mr.bottom - mr.top;
- }
- }
-
- // Adjust the window size to accomodate requested view size
- RECT wr = { 0, 0, view->width, view->height };
- AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST);
-
- impl->hwnd = CreateWindowEx(
- WS_EX_TOPMOST,
- wc.lpszClassName, title,
- (view->parent ? WS_CHILD : winFlags),
- CW_USEDEFAULT, CW_USEDEFAULT, wr.right-wr.left, wr.bottom-wr.top,
- (HWND)view->parent, NULL, NULL, NULL);
-
- if (!impl->hwnd) {
- free((void*)impl->wc.lpszClassName);
- free(impl);
- free(view);
- return 1;
- }
-
-#ifdef _WIN64
- SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
-#else
- SetWindowLongPtr(impl->hwnd, GWL_USERDATA, (LONG)view);
-#endif
-
- impl->hdc = GetDC(impl->hwnd);
-
- PIXELFORMATDESCRIPTOR pfd;
- ZeroMemory(&pfd, sizeof(pfd));
- pfd.nSize = sizeof(pfd);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = 24;
- pfd.cDepthBits = 16;
- pfd.iLayerType = PFD_MAIN_PLANE;
-
- int format = ChoosePixelFormat(impl->hdc, &pfd);
- SetPixelFormat(impl->hdc, format, &pfd);
-
- impl->hglrc = wglCreateContext(impl->hdc);
- if (!impl->hglrc) {
- ReleaseDC(impl->hwnd, impl->hdc);
- DestroyWindow(impl->hwnd);
- UnregisterClass(impl->wc.lpszClassName, NULL);
- free((void*)impl->wc.lpszClassName);
- free(impl);
- free(view);
- return NULL;
- }
- wglMakeCurrent(impl->hdc, impl->hglrc);
-
- return 0;
-}
-
-void
-puglShowWindow(PuglView* view)
-{
- PuglInternals* impl = view->impl;
-
- ShowWindow(impl->hwnd, SW_SHOWNORMAL);
- view->visible = true;
-}
-
-void
-puglHideWindow(PuglView* view)
-{
- PuglInternals* impl = view->impl;
-
- ShowWindow(impl->hwnd, SW_HIDE);
- view->visible = false;
-}
-
-void
-puglDestroy(PuglView* view)
-{
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(view->impl->hglrc);
- ReleaseDC(view->impl->hwnd, view->impl->hdc);
- DestroyWindow(view->impl->hwnd);
- UnregisterClass(view->impl->wc.lpszClassName, NULL);
- free(view->windowClass);
- free(view->impl);
- free(view);
-}
-
-static PuglKey
-keySymToSpecial(int sym)
-{
- switch (sym) {
- case VK_F1: return PUGL_KEY_F1;
- case VK_F2: return PUGL_KEY_F2;
- case VK_F3: return PUGL_KEY_F3;
- case VK_F4: return PUGL_KEY_F4;
- case VK_F5: return PUGL_KEY_F5;
- case VK_F6: return PUGL_KEY_F6;
- case VK_F7: return PUGL_KEY_F7;
- case VK_F8: return PUGL_KEY_F8;
- case VK_F9: return PUGL_KEY_F9;
- case VK_F10: return PUGL_KEY_F10;
- case VK_F11: return PUGL_KEY_F11;
- case VK_F12: return PUGL_KEY_F12;
- case VK_LEFT: return PUGL_KEY_LEFT;
- case VK_UP: return PUGL_KEY_UP;
- case VK_RIGHT: return PUGL_KEY_RIGHT;
- case VK_DOWN: return PUGL_KEY_DOWN;
- case VK_PRIOR: return PUGL_KEY_PAGE_UP;
- case VK_NEXT: return PUGL_KEY_PAGE_DOWN;
- case VK_HOME: return PUGL_KEY_HOME;
- case VK_END: return PUGL_KEY_END;
- case VK_INSERT: return PUGL_KEY_INSERT;
- case VK_SHIFT: return PUGL_KEY_SHIFT;
- case VK_CONTROL: return PUGL_KEY_CTRL;
- case VK_MENU: return PUGL_KEY_ALT;
- case VK_LWIN: return PUGL_KEY_SUPER;
- case VK_RWIN: return PUGL_KEY_SUPER;
- }
- return (PuglKey)0;
-}
-
-static unsigned int
-getModifiers()
-{
- unsigned int mods = 0;
- mods |= (GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0;
- mods |= (GetKeyState(VK_CONTROL) < 0) ? PUGL_MOD_CTRL : 0;
- mods |= (GetKeyState(VK_MENU) < 0) ? PUGL_MOD_ALT : 0;
- mods |= (GetKeyState(VK_LWIN) < 0) ? PUGL_MOD_SUPER : 0;
- mods |= (GetKeyState(VK_RWIN) < 0) ? PUGL_MOD_SUPER : 0;
- return mods;
-}
-
-static void
-initMouseEvent(PuglEvent* event,
- PuglView* view,
- int button,
- bool press,
- LPARAM lParam)
-{
- POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
- ClientToScreen(view->impl->hwnd, &pt);
-
- if (press) {
- SetCapture(view->impl->hwnd);
- } else {
- ReleaseCapture();
- }
-
- event->button.time = GetMessageTime();
- event->button.type = press ? PUGL_BUTTON_PRESS : PUGL_BUTTON_RELEASE;
- event->button.x = GET_X_LPARAM(lParam);
- event->button.y = GET_Y_LPARAM(lParam);
- event->button.x_root = pt.x;
- event->button.y_root = pt.y;
- event->button.state = getModifiers();
- event->button.button = button;
-}
-
-static void
-initScrollEvent(PuglEvent* event, PuglView* view, LPARAM lParam, WPARAM wParam)
-{
- POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
- ScreenToClient(view->impl->hwnd, &pt);
-
- event->scroll.time = GetMessageTime();
- event->scroll.type = PUGL_SCROLL;
- event->scroll.x = pt.x;
- event->scroll.y = pt.y;
- event->scroll.x_root = GET_X_LPARAM(lParam);
- event->scroll.y_root = GET_Y_LPARAM(lParam);
- event->scroll.state = getModifiers();
- event->scroll.dx = 0;
- event->scroll.dy = 0;
-}
-
-static unsigned int
-utf16_to_code_point(const wchar_t* input, size_t input_size)
-{
- unsigned int code_unit = *input;
- // Equiv. range check between 0xD800 to 0xDBFF inclusive
- if ((code_unit & 0xFC00) == 0xD800) {
- if (input_size < 2) {
- // "Error: is surrogate but input_size too small"
- return 0xFFFD; // replacement character
- }
-
- unsigned int code_unit_2 = *++input;
- // Equiv. range check between 0xDC00 to 0xDFFF inclusive
- if ((code_unit_2 & 0xFC00) == 0xDC00) {
- return (code_unit << 10) + code_unit_2 - 0x35FDC00;
- }
-
- // TODO: push_back(code_unit_2);
- // "Error: Unpaired surrogates."
- return 0xFFFD; // replacement character
- }
- return code_unit;
-}
-
-static void
-initKeyEvent(PuglEvent* event, PuglView* view, bool press, LPARAM lParam)
-{
- POINT rpos = { 0, 0 };
- GetCursorPos(&rpos);
-
- POINT cpos = { rpos.x, rpos.y };
- ScreenToClient(view->impl->hwnd, &rpos);
-
- event->key.type = press ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- event->key.time = GetMessageTime();
- event->key.state = getModifiers();
- event->key.x_root = rpos.x;
- event->key.y_root = rpos.y;
- event->key.x = cpos.x;
- event->key.y = cpos.y;
- event->key.keycode = (lParam & 0xFF0000) >> 16;
- event->key.character = 0;
- event->key.special = static_cast<PuglKey>(0);
- event->key.filter = 0;
-}
-
-static void
-wcharBufToEvent(wchar_t* buf, int n, PuglEvent* event)
-{
- if (n > 0) {
- char* charp = reinterpret_cast<char*>(event->key.utf8);
- if (!WideCharToMultiByte(CP_UTF8, 0, buf, n,
- charp, 8, NULL, NULL)) {
- /* error: could not convert to utf-8,
- GetLastError has details */
- memset(event->key.utf8, 0, 8);
- // replacement character
- event->key.utf8[0] = 0xEF;
- event->key.utf8[1] = 0xBF;
- event->key.utf8[2] = 0xBD;
- }
-
- event->key.character = utf16_to_code_point(buf, n);
- } else {
- // replacement character
- event->key.utf8[0] = 0xEF;
- event->key.utf8[1] = 0xBF;
- event->key.utf8[2] = 0xBD;
- event->key.character = 0xFFFD;
- }
-}
-
-static void
-translateMessageParamsToEvent(LPARAM lParam, WPARAM wParam, PuglEvent* event)
-{
- /* TODO: This is a kludge. Would be nice to use ToUnicode here, but this
- breaks composed keys because it messes with the keyboard state. Not
- sure how to correctly handle this on Windows. */
-
- // This is how I really want to do this, but it breaks composed keys (é,
- // è, ü, ö, and so on) because ToUnicode messes with the keyboard state.
-
- //wchar_t buf[5];
- //BYTE keyboard_state[256];
- //int wcharCount = 0;
- //GetKeyboardState(keyboard_state);
- //wcharCount = ToUnicode(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC),
- // keyboard_state, buf, 4, 0);
- //wcharBufToEvent(buf, wcharCount, event);
-
- // So, since Google refuses to give me a better solution, and if no one
- // else has a better solution, I will make a hack...
- wchar_t buf[5] = { 0, 0, 0, 0, 0 };
- UINT c = MapVirtualKey(wParam, MAPVK_VK_TO_CHAR);
- buf[0] = c & 0xffff;
- // TODO: This does not take caps lock into account
- // TODO: Dead keys should affect key releases as well
- if (!(event->key.state && PUGL_MOD_SHIFT))
- buf[0] = towlower(buf[0]);
- wcharBufToEvent(buf, 1, event);
- event->key.filter = ((c >> 31) & 0x1);
-}
-
-static void
-translateCharEventToEvent(WPARAM wParam, PuglEvent* event)
-{
- wchar_t buf[2];
- int wcharCount;
- if (wParam & 0xFFFF0000) {
- wcharCount = 2;
- buf[0] = (wParam & 0xFFFF);
- buf[1] = ((wParam >> 16) & 0xFFFF);
- } else {
- wcharCount = 1;
- buf[0] = (wParam & 0xFFFF);
- }
- wcharBufToEvent(buf, wcharCount, event);
-}
-
-static bool
-ignoreKeyEvent(PuglView* view, LPARAM lParam)
-{
- return view->ignoreKeyRepeat && (lParam & (1 << 30));
-}
-
-static LRESULT
-handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
-{
- PuglEvent event;
- void* dummy_ptr = NULL;
- RECT rect;
- MINMAXINFO* mmi;
- POINT pt;
- bool dispatchThisEvent = true;
-
- memset(&event, 0, sizeof(event));
-
- event.any.type = PUGL_NOTHING;
- event.any.view = view;
- if (InSendMessageEx(dummy_ptr)) {
- event.any.flags |= PUGL_IS_SEND_EVENT;
- }
-
- switch (message) {
- case WM_CREATE:
- case WM_SHOWWINDOW:
- case WM_SIZE:
- GetWindowRect(view->impl->hwnd, &rect);
- event.configure.type = PUGL_CONFIGURE;
- event.configure.x = rect.left;
- event.configure.y = rect.top;
- view->width = rect.right - rect.left;
- view->height = rect.bottom - rect.top;
- event.configure.width = view->width;
- event.configure.height = view->height;
- break;
- case WM_GETMINMAXINFO:
- mmi = (MINMAXINFO*)lParam;
- mmi->ptMinTrackSize.x = view->min_width;
- mmi->ptMinTrackSize.y = view->min_height;
- break;
- case WM_PAINT:
- GetUpdateRect(view->impl->hwnd, &rect, false);
- event.expose.type = PUGL_EXPOSE;
- event.expose.x = rect.left;
- event.expose.y = rect.top;
- event.expose.width = rect.right - rect.left;
- event.expose.height = rect.bottom - rect.top;
- event.expose.count = 0;
- break;
- case WM_MOUSEMOVE:
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- ClientToScreen(view->impl->hwnd, &pt);
-
- event.motion.type = PUGL_MOTION_NOTIFY;
- event.motion.time = GetMessageTime();
- event.motion.x = GET_X_LPARAM(lParam);
- event.motion.y = GET_Y_LPARAM(lParam);
- event.motion.x_root = pt.x;
- event.motion.y_root = pt.y;
- event.motion.state = getModifiers();
- event.motion.is_hint = false;
- break;
- case WM_LBUTTONDOWN:
- initMouseEvent(&event, view, 1, true, lParam);
- break;
- case WM_MBUTTONDOWN:
- initMouseEvent(&event, view, 2, true, lParam);
- break;
- case WM_RBUTTONDOWN:
- initMouseEvent(&event, view, 3, true, lParam);
- break;
- case WM_LBUTTONUP:
- initMouseEvent(&event, view, 1, false, lParam);
- break;
- case WM_MBUTTONUP:
- initMouseEvent(&event, view, 2, false, lParam);
- break;
- case WM_RBUTTONUP:
- initMouseEvent(&event, view, 3, false, lParam);
- break;
- case WM_MOUSEWHEEL:
- initScrollEvent(&event, view, lParam, wParam);
- event.scroll.dy = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
- break;
- case WM_MOUSEHWHEEL:
- initScrollEvent(&event, view, lParam, wParam);
- event.scroll.dx = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
- break;
- case WM_KEYDOWN:
- if (!ignoreKeyEvent(view, lParam)) {
- initKeyEvent(&event, view, true, lParam);
- if (!(event.key.special = keySymToSpecial(wParam))) {
- event.key.type = PUGL_NOTHING;
- }
- }
- break;
- case WM_CHAR:
- if (!ignoreKeyEvent(view, lParam)) {
- initKeyEvent(&event, view, true, lParam);
- translateCharEventToEvent(wParam, &event);
- }
- break;
- case WM_DEADCHAR:
- if (!ignoreKeyEvent(view, lParam)) {
- initKeyEvent(&event, view, true, lParam);
- translateCharEventToEvent(wParam, &event);
- event.key.filter = 1;
- }
- break;
- case WM_KEYUP:
- initKeyEvent(&event, view, false, lParam);
- if (!(event.key.special = keySymToSpecial(wParam))) {
- translateMessageParamsToEvent(lParam, wParam, &event);
- }
- break;
- case WM_QUIT:
- case PUGL_LOCAL_CLOSE_MSG:
- event.close.type = PUGL_CLOSE;
- break;
- default:
- return DefWindowProc(
- view->impl->hwnd, message, wParam, lParam);
- }
-
- puglDispatchEvent(view, &event);
-
- return 0;
-}
-
-void
-puglGrabFocus(PuglView* view)
-{
- // TODO
-}
-
-PuglStatus
-puglWaitForEvent(PuglView* view)
-{
- WaitMessage();
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglProcessEvents(PuglView* view)
-{
- MSG msg;
- while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- handleMessage(view, msg.message, msg.wParam, msg.lParam);
- }
-
- if (view->redisplay) {
- InvalidateRect(view->impl->hwnd, NULL, FALSE);
- view->redisplay = false;
- }
-
- return PUGL_SUCCESS;
-}
-
-LRESULT CALLBACK
-wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-#ifdef _WIN64
- PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-#else
- PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWL_USERDATA);
-#endif
-
- switch (message) {
- case WM_CREATE:
- PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
- return 0;
- case WM_CLOSE:
- PostMessage(hwnd, PUGL_LOCAL_CLOSE_MSG, wParam, lParam);
- return 0;
- case WM_DESTROY:
- return 0;
- default:
- if (view && hwnd == view->impl->hwnd) {
- return handleMessage(view, message, wParam, lParam);
- } else {
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- }
-}
-
-void
-puglPostRedisplay(PuglView* view)
-{
- view->redisplay = true;
-}
-
-PuglNativeWindow
-puglGetNativeWindow(PuglView* view)
-{
- return (PuglNativeWindow)view->impl->hwnd;
-}
diff --git a/pugl/pugl/pugl_x11.c b/pugl/pugl/pugl_x11.c
deleted file mode 100644
index 6a9135b..0000000
--- a/pugl/pugl/pugl_x11.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- Copyright 2012-2016 David Robillard <http://drobilla.net>
- Copyright 2013 Robin Gareus <robin@gareus.org>
- 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_x11.c X11 Pugl Implementation.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.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/cairo_gl.h"
-#include "pugl/pugl_internal.h"
-
-#ifndef MIN
-# define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#ifndef MAX
-# 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
-#if defined(PUGL_HAVE_CAIRO) && defined(PUGL_HAVE_GL)
- PuglCairoGL cairo_gl;
-#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
-#if defined(PUGL_HAVE_GL) && defined(PUGL_HAVE_CAIRO)
- if (view->ctx_type == PUGL_CAIRO_GL) {
- impl->surface = pugl_cairo_gl_create(
- &impl->cairo_gl, view->width, view->height, 4);
- }
-#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)
-{
-#if defined(PUGL_HAVE_CAIRO) && defined(PUGL_HAVE_GL)
- if (view->ctx_type == PUGL_CAIRO_GL) {
- pugl_cairo_gl_free(&view->impl->cairo_gl);
- }
-#endif
-#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
-#ifdef PUGL_HAVE_CAIRO
- if (view->ctx_type & PUGL_CAIRO) {
- cairo_set_source_rgb(view->impl->cr, 0, 0, 0);
- cairo_paint(view->impl->cr);
- }
-#endif
-}
-
-void
-puglLeaveContext(PuglView* view, bool flush)
-{
-#ifdef PUGL_HAVE_GL
- if (flush && view->ctx_type & PUGL_GL) {
-#ifdef PUGL_HAVE_CAIRO
- if (view->ctx_type == PUGL_CAIRO_GL) {
- pugl_cairo_gl_draw(&view->impl->cairo_gl, view->width, view->height);
- }
-#endif
-
- glFlush();
- if (view->impl->doubleBuffered) {
- glXSwapBuffers(view->impl->display, view->impl->win);
- }
- }
-
- glXMakeCurrent(view->impl->display, None, NULL);
-#endif
-}
-
-int
-puglCreateWindow(PuglView* view, const char* title)
-{
- PuglInternals* const impl = view->impl;
-
- impl->display = XOpenDisplay(0);
- impl->screen = DefaultScreen(impl->display);
-
- XVisualInfo* const vi = getVisual(view);
- if (!vi) {
- return 1;
- }
-
- Window xParent = view->parent
- ? (Window)view->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.event_mask = (ExposureMask | StructureNotifyMask |
- EnterWindowMask | LeaveWindowMask |
- KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | FocusChangeMask);
-
- impl->win = XCreateWindow(
- impl->display, xParent,
- 0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual,
- CWColormap | CWEventMask, &attr);
-
- if (!createContext(view, vi)) {
- return 2;
- }
-
- XSizeHints sizeHints;
- memset(&sizeHints, 0, sizeof(sizeHints));
- if (!view->resizable) {
- sizeHints.flags = PMinSize|PMaxSize;
- sizeHints.min_width = view->width;
- sizeHints.min_height = view->height;
- sizeHints.max_width = view->width;
- sizeHints.max_height = view->height;
- XSetNormalHints(impl->display, impl->win, &sizeHints);
- } else {
- if (view->min_width || view->min_height) {
- sizeHints.flags = PMinSize;
- sizeHints.min_width = view->min_width;
- sizeHints.min_height = view->min_height;
- }
- if (view->min_aspect_x) {
- sizeHints.flags |= PAspect;
- sizeHints.min_aspect.x = view->min_aspect_x;
- sizeHints.min_aspect.y = view->min_aspect_y;
- sizeHints.max_aspect.x = view->max_aspect_x;
- sizeHints.max_aspect.y = view->max_aspect_y;
- }
-
- XSetNormalHints(impl->display, impl->win, &sizeHints);
- }
-
- if (title) {
- XStoreName(impl->display, impl->win, title);
- }
-
- if (!view->parent) {
- Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True);
- XSetWMProtocols(impl->display, impl->win, &wmDelete, 1);
- }
-
- if (view->transient_parent) {
- XSetTransientForHint(impl->display, impl->win,
- (Window)(view->transient_parent));
- }
-
- XSetLocaleModifiers("");
- if (!(impl->xim = XOpenIM(impl->display, NULL, NULL, NULL))) {
- XSetLocaleModifiers("@im=");
- if (!(impl->xim = XOpenIM(impl->display, NULL, NULL, NULL))) {
- fprintf(stderr, "warning: XOpenIM failed\n");
- }
- }
-
- const XIMStyle im_style = XIMPreeditNothing | XIMStatusNothing;
- if (!(impl->xic = XCreateIC(impl->xim,
- XNInputStyle, im_style,
- XNClientWindow, impl->win,
- XNFocusWindow, impl->win,
- NULL))) {
- fprintf(stderr, "warning: XCreateIC failed\n");
- }
-
- XFree(vi);
-
- return 0;
-}
-
-void
-puglShowWindow(PuglView* view)
-{
- XMapRaised(view->impl->display, view->impl->win);
- view->visible = true;
-}
-
-void
-puglHideWindow(PuglView* view)
-{
- XUnmapWindow(view->impl->display, view->impl->win);
- view->visible = false;
-}
-
-void
-puglDestroy(PuglView* view)
-{
- if (view) {
- destroyContext(view);
- XDestroyWindow(view->impl->display, view->impl->win);
- XCloseDisplay(view->impl->display);
- free(view->windowClass);
- free(view->impl);
- free(view);
- }
-}
-
-static PuglKey
-keySymToSpecial(KeySym sym)
-{
- switch (sym) {
- case XK_F1: return PUGL_KEY_F1;
- case XK_F2: return PUGL_KEY_F2;
- case XK_F3: return PUGL_KEY_F3;
- case XK_F4: return PUGL_KEY_F4;
- case XK_F5: return PUGL_KEY_F5;
- case XK_F6: return PUGL_KEY_F6;
- case XK_F7: return PUGL_KEY_F7;
- case XK_F8: return PUGL_KEY_F8;
- case XK_F9: return PUGL_KEY_F9;
- case XK_F10: return PUGL_KEY_F10;
- case XK_F11: return PUGL_KEY_F11;
- case XK_F12: return PUGL_KEY_F12;
- case XK_Left: return PUGL_KEY_LEFT;
- case XK_Up: return PUGL_KEY_UP;
- case XK_Right: return PUGL_KEY_RIGHT;
- case XK_Down: return PUGL_KEY_DOWN;
- case XK_Page_Up: return PUGL_KEY_PAGE_UP;
- case XK_Page_Down: return PUGL_KEY_PAGE_DOWN;
- case XK_Home: return PUGL_KEY_HOME;
- case XK_End: return PUGL_KEY_END;
- case XK_Insert: return PUGL_KEY_INSERT;
- case XK_Shift_L: return PUGL_KEY_SHIFT;
- case XK_Shift_R: return PUGL_KEY_SHIFT;
- case XK_Control_L: return PUGL_KEY_CTRL;
- case XK_Control_R: return PUGL_KEY_CTRL;
- case XK_Alt_L: return PUGL_KEY_ALT;
- case XK_Alt_R: return PUGL_KEY_ALT;
- case XK_Super_L: return PUGL_KEY_SUPER;
- case XK_Super_R: return PUGL_KEY_SUPER;
- }
- return (PuglKey)0;
-}
-
-static void
-translateKey(PuglView* view, XEvent* xevent, PuglEvent* event)
-{
- KeySym sym = 0;
- char* str = (char*)event->key.utf8;
- memset(str, 0, 8);
- event->key.filter = XFilterEvent(xevent, None);
- if (xevent->type == KeyRelease || event->key.filter || !view->impl->xic) {
- if (XLookupString(&xevent->xkey, str, 7, &sym, NULL) == 1) {
- event->key.character = str[0];
- }
- } else {
- /* TODO: Not sure about this. On my system, some characters work with
- Xutf8LookupString but not with XmbLookupString, and some are the
- opposite. */
- Status status = 0;
-#ifdef X_HAVE_UTF8_STRING
- const int n = Xutf8LookupString(
- view->impl->xic, &xevent->xkey, str, 7, &sym, &status);
-#else
- const int n = XmbLookupString(
- view->impl->xic, &xevent->xkey, str, 7, &sym, &status);
-#endif
- if (n > 0) {
- event->key.character = puglDecodeUTF8((const uint8_t*)str);
- }
- }
- event->key.special = keySymToSpecial(sym);
- event->key.keycode = xevent->xkey.keycode;
-}
-
-static unsigned
-translateModifiers(unsigned xstate)
-{
- unsigned state = 0;
- state |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0;
- state |= (xstate & ControlMask) ? PUGL_MOD_CTRL : 0;
- state |= (xstate & Mod1Mask) ? PUGL_MOD_ALT : 0;
- state |= (xstate & Mod4Mask) ? PUGL_MOD_SUPER : 0;
- return state;
-}
-
-static PuglEvent
-translateEvent(PuglView* view, XEvent xevent)
-{
- PuglEvent event;
- memset(&event, 0, sizeof(event));
-
- event.any.view = view;
- if (xevent.xany.send_event) {
- event.any.flags |= PUGL_IS_SEND_EVENT;
- }
-
- switch (xevent.type) {
- case ClientMessage: {
- char* type = XGetAtomName(view->impl->display,
- xevent.xclient.message_type);
- if (!strcmp(type, "WM_PROTOCOLS")) {
- event.type = PUGL_CLOSE;
- }
- break;
- }
- case ConfigureNotify:
- event.type = PUGL_CONFIGURE;
- event.configure.x = xevent.xconfigure.x;
- event.configure.y = xevent.xconfigure.y;
- event.configure.width = xevent.xconfigure.width;
- event.configure.height = xevent.xconfigure.height;
- break;
- case Expose:
- event.type = PUGL_EXPOSE;
- event.expose.x = xevent.xexpose.x;
- event.expose.y = xevent.xexpose.y;
- event.expose.width = xevent.xexpose.width;
- event.expose.height = xevent.xexpose.height;
- event.expose.count = xevent.xexpose.count;
- break;
- case MotionNotify:
- event.type = PUGL_MOTION_NOTIFY;
- event.motion.time = xevent.xmotion.time;
- event.motion.x = xevent.xmotion.x;
- event.motion.y = xevent.xmotion.y;
- event.motion.x_root = xevent.xmotion.x_root;
- event.motion.y_root = xevent.xmotion.y_root;
- event.motion.state = translateModifiers(xevent.xmotion.state);
- event.motion.is_hint = (xevent.xmotion.is_hint == NotifyHint);
- break;
- case ButtonPress:
- if (xevent.xbutton.button >= 4 && xevent.xbutton.button <= 7) {
- event.type = PUGL_SCROLL;
- event.scroll.time = xevent.xbutton.time;
- event.scroll.x = xevent.xbutton.x;
- event.scroll.y = xevent.xbutton.y;
- event.scroll.x_root = xevent.xbutton.x_root;
- event.scroll.y_root = xevent.xbutton.y_root;
- event.scroll.state = translateModifiers(xevent.xbutton.state);
- event.scroll.dx = 0.0;
- event.scroll.dy = 0.0;
- switch (xevent.xbutton.button) {
- case 4: event.scroll.dy = 1.0f; break;
- case 5: event.scroll.dy = -1.0f; break;
- case 6: event.scroll.dx = -1.0f; break;
- case 7: event.scroll.dx = 1.0f; break;
- }
- }
- // nobreak
- case ButtonRelease:
- if (xevent.xbutton.button < 4 || xevent.xbutton.button > 7) {
- event.button.type = ((xevent.type == ButtonPress)
- ? PUGL_BUTTON_PRESS
- : PUGL_BUTTON_RELEASE);
- event.button.time = xevent.xbutton.time;
- event.button.x = xevent.xbutton.x;
- event.button.y = xevent.xbutton.y;
- event.button.x_root = xevent.xbutton.x_root;
- event.button.y_root = xevent.xbutton.y_root;
- event.button.state = translateModifiers(xevent.xbutton.state);
- event.button.button = xevent.xbutton.button;
- }
- break;
- case KeyPress:
- case KeyRelease:
- event.type = ((xevent.type == KeyPress)
- ? PUGL_KEY_PRESS
- : PUGL_KEY_RELEASE);
- event.key.time = xevent.xkey.time;
- event.key.x = xevent.xkey.x;
- event.key.y = xevent.xkey.y;
- event.key.x_root = xevent.xkey.x_root;
- event.key.y_root = xevent.xkey.y_root;
- event.key.state = translateModifiers(xevent.xkey.state);
- translateKey(view, &xevent, &event);
- break;
- case EnterNotify:
- case LeaveNotify:
- event.type = ((xevent.type == EnterNotify)
- ? PUGL_ENTER_NOTIFY
- : PUGL_LEAVE_NOTIFY);
- event.crossing.time = xevent.xcrossing.time;
- event.crossing.x = xevent.xcrossing.x;
- event.crossing.y = xevent.xcrossing.y;
- event.crossing.x_root = xevent.xcrossing.x_root;
- event.crossing.y_root = xevent.xcrossing.y_root;
- event.crossing.state = translateModifiers(xevent.xcrossing.state);
- event.crossing.mode = PUGL_CROSSING_NORMAL;
- if (xevent.xcrossing.mode == NotifyGrab) {
- event.crossing.mode = PUGL_CROSSING_GRAB;
- } else if (xevent.xcrossing.mode == NotifyUngrab) {
- event.crossing.mode = PUGL_CROSSING_UNGRAB;
- }
- break;
-
- case FocusIn:
- case FocusOut:
- event.type = ((xevent.type == FocusIn)
- ? PUGL_FOCUS_IN
- : PUGL_FOCUS_OUT);
- event.focus.grab = (xevent.xfocus.mode != NotifyNormal);
- break;
-
- default:
- break;
- }
-
- return event;
-}
-
-void
-puglGrabFocus(PuglView* view)
-{
- XSetInputFocus(
- view->impl->display, view->impl->win, RevertToPointerRoot, CurrentTime);
-}
-
-PuglStatus
-puglWaitForEvent(PuglView* view)
-{
- XEvent xevent;
- XPeekEvent(view->impl->display, &xevent);
- return PUGL_SUCCESS;
-}
-
-static void
-merge_draw_events(PuglEvent* dst, const PuglEvent* src)
-{
- if (!dst->type) {
- *dst = *src;
- } else {
- dst->expose.x = MIN(dst->expose.x, src->expose.x);
- dst->expose.y = MIN(dst->expose.y, src->expose.y);
- dst->expose.width = MAX(dst->expose.width, src->expose.width);
- dst->expose.height = MAX(dst->expose.height, src->expose.height);
- }
-}
-
-PuglStatus
-puglProcessEvents(PuglView* view)
-{
- /* Maintain a single expose/configure event to execute after all pending
- events. This avoids redundant drawing/configuration which prevents a
- series of window resizes in the same loop from being laggy. */
- PuglEvent expose_event = { 0 };
- PuglEvent config_event = { 0 };
- XEvent xevent;
- while (XPending(view->impl->display) > 0) {
- XNextEvent(view->impl->display, &xevent);
- if (xevent.type == KeyRelease) {
- // Ignore key repeat if necessary
- if (view->ignoreKeyRepeat &&
- XEventsQueued(view->impl->display, QueuedAfterReading)) {
- XEvent next;
- XPeekEvent(view->impl->display, &next);
- if (next.type == KeyPress &&
- next.xkey.time == xevent.xkey.time &&
- next.xkey.keycode == xevent.xkey.keycode) {
- XNextEvent(view->impl->display, &xevent);
- continue;
- }
- }
- } else if (xevent.type == FocusIn) {
- XSetICFocus(view->impl->xic);
- } else if (xevent.type == FocusOut) {
- XUnsetICFocus(view->impl->xic);
- }
-
- // Translate X11 event to Pugl event
- const PuglEvent event = translateEvent(view, xevent);
-
- if (event.type == PUGL_EXPOSE) {
- // Expand expose event to be dispatched after loop
- merge_draw_events(&expose_event, &event);
- } else if (event.type == PUGL_CONFIGURE) {
- // Expand configure event to be dispatched after loop
- merge_draw_events(&config_event, &event);
- } else {
- // Dispatch event to application immediately
- puglDispatchEvent(view, &event);
- }
- }
-
- 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);
- }
-#ifdef PUGL_HAVE_GL
- if (view->ctx_type == PUGL_CAIRO_GL) {
- view->redisplay = true;
- cairo_surface_destroy(view->impl->surface);
- view->impl->surface = pugl_cairo_gl_create(
- &view->impl->cairo_gl,
- config_event.configure.width,
- config_event.configure.height,
- 4);
- pugl_cairo_gl_configure(&view->impl->cairo_gl,
- config_event.configure.width,
- config_event.configure.height);
- createCairoContext(view);
- }
-#endif
-#endif
- puglDispatchEvent(view, (const PuglEvent*)&config_event);
- }
-
- if (view->redisplay) {
- expose_event.expose.type = PUGL_EXPOSE;
- expose_event.expose.view = view;
- expose_event.expose.x = 0;
- expose_event.expose.y = 0;
- expose_event.expose.width = view->width;
- expose_event.expose.height = view->height;
- view->redisplay = false;
- }
-
- if (expose_event.type) {
- puglDispatchEvent(view, (const PuglEvent*)&expose_event);
- }
-
- return PUGL_SUCCESS;
-}
-
-void
-puglPostRedisplay(PuglView* view)
-{
- view->redisplay = true;
-}
-
-PuglNativeWindow
-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/pugl_cairo_test.c b/pugl/pugl_cairo_test.c
deleted file mode 100644
index c04c785..0000000
--- a/pugl/pugl_cairo_test.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- 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;
-static bool entered = false;
-
-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
-buttonDraw(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 bool
-buttonTouches(const Button* but, double x, double y)
-{
- return (x >= toggle_button.x && x <= toggle_button.x + toggle_button.w &&
- y >= toggle_button.y && y <= toggle_button.y + toggle_button.h);
-}
-
-static void
-onDisplay(PuglView* view)
-{
- cairo_t* cr = puglGetContext(view);
-
- // Draw background
- int width, height;
- puglGetSize(view, &width, &height);
- if (entered) {
- cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
- } else {
- cairo_set_source_rgb(cr, 0, 0, 0);
- }
- cairo_rectangle(cr, 0, 0, width, height);
- cairo_fill(cr);
-
- // Draw button
- buttonDraw(cr, &toggle_button);
-}
-
-static void
-onClose(PuglView* view)
-{
- quit = 1;
-}
-
-static void
-onEvent(PuglView* view, const PuglEvent* event)
-{
- switch (event->type) {
- case PUGL_KEY_PRESS:
- if (event->key.character == 'q' ||
- event->key.character == 'Q' ||
- event->key.character == PUGL_CHAR_ESCAPE) {
- quit = 1;
- }
- break;
- case PUGL_BUTTON_PRESS:
- if (buttonTouches(&toggle_button, event->button.x, event->button.y)) {
- toggle_button.pressed = !toggle_button.pressed;
- puglPostRedisplay(view);
- }
- break;
- case PUGL_ENTER_NOTIFY:
- entered = true;
- puglPostRedisplay(view);
- break;
- case PUGL_LEAVE_NOTIFY:
- entered = false;
- puglPostRedisplay(view);
- break;
- case PUGL_EXPOSE:
- onDisplay(view);
- break;
- case PUGL_CLOSE:
- onClose(view);
- break;
- default: break;
- }
-}
-
-int
-main(int argc, char** argv)
-{
- bool useGL = false;
- bool ignoreKeyRepeat = false;
- bool resizable = false;
- for (int i = 1; i < argc; ++i) {
- if (!strcmp(argv[i], "-h")) {
- printf("USAGE: %s [OPTIONS]...\n\n"
- " -g Use OpenGL\n"
- " -h Display this help\n"
- " -i Ignore key repeat\n"
- " -r Resizable window\n", argv[0]);
- return 0;
- } else if (!strcmp(argv[i], "-g")) {
- useGL = true;
- } 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, useGL ? PUGL_CAIRO_GL : PUGL_CAIRO);
-
- puglIgnoreKeyRepeat(view, ignoreKeyRepeat);
- puglSetEventFunc(view, onEvent);
-
- puglCreateWindow(view, "Pugl Test");
- puglShowWindow(view);
-
- while (!quit) {
- puglWaitForEvent(view);
- puglProcessEvents(view);
- }
-
- puglDestroy(view);
- return 0;
-}
diff --git a/pugl/pugl_test.c b/pugl/pugl_test.c
deleted file mode 100644
index 367e7a4..0000000
--- a/pugl/pugl_test.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- Copyright 2012-2016 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 <locale.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "pugl/gl.h"
-#include "pugl/pugl.h"
-
-static int quit = 0;
-static float xAngle = 0.0f;
-static float yAngle = 0.0f;
-static float dist = 10.0f;
-
-static const float cubeVertices[] = {
- -1.0f, -1.0f, -1.0f,
- -1.0f, -1.0f, 1.0f,
- -1.0f, 1.0f, 1.0f,
-
- 1.0f, 1.0f, -1.0f,
- -1.0f, -1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f,
-
- 1.0f, -1.0f, 1.0f,
- -1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
-
- 1.0f, 1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f,
- -1.0f, -1.0f, -1.0f,
-
- -1.0f, -1.0f, -1.0f,
- -1.0f, 1.0f, 1.0f,
- -1.0f, 1.0f, -1.0f,
-
- 1.0f, -1.0f, 1.0f,
- -1.0f, -1.0f, 1.0f,
- -1.0f, -1.0f, -1.0f,
-
- -1.0f, 1.0f, 1.0f,
- -1.0f, -1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f,
-
- 1.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, -1.0f,
- 1.0f, 1.0f, -1.0f,
-
- 1.0f, -1.0f, -1.0f,
- 1.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f,
-
- 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f,
-
- 1.0f, 1.0f, 1.0f,
- -1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, 1.0f,
-
- 1.0f, 1.0f, 1.0f,
- -1.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f
-};
-
-/** Calculate a projection matrix for a given perspective. */
-static void
-perspective(float* m, float fov, float aspect, float zNear, float zFar)
-{
- const float h = tan(fov);
- const float w = h / aspect;
- const float depth = zNear - zFar;
- const float q = (zFar + zNear) / depth;
- const float qn = 2 * zFar * zNear / depth;
-
- m[0] = w; m[1] = 0; m[2] = 0; m[3] = 0;
- m[4] = 0; m[5] = h; m[6] = 0; m[7] = 0;
- m[8] = 0; m[9] = 0; m[10] = q; m[11] = -1;
- m[12] = 0; m[13] = 0; m[14] = qn; m[15] = 0;
-}
-
-static void
-onReshape(PuglView* view, int width, int height)
-{
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glViewport(0, 0, width, height);
-
- float projection[16];
- perspective(projection, 1.8f, width / (float)height, 1.0, 100.0f);
- glLoadMatrixf(projection);
-}
-
-static void
-onDisplay(PuglView* view)
-{
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0f, 0.0f, dist * -1);
- glRotatef(xAngle, 0.0f, 1.0f, 0.0f);
- glRotatef(yAngle, 1.0f, 0.0f, 0.0f);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, 0, cubeVertices);
- glColorPointer(3, GL_FLOAT, 0, cubeVertices);
- glDrawArrays(GL_TRIANGLES, 0, 12 * 3);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-}
-
-static void
-printModifiers(PuglView* view, unsigned mods)
-{
- fprintf(stderr, "Modifiers:%s%s%s%s\n",
- (mods & PUGL_MOD_SHIFT) ? " Shift" : "",
- (mods & PUGL_MOD_CTRL) ? " Ctrl" : "",
- (mods & PUGL_MOD_ALT) ? " Alt" : "",
- (mods & PUGL_MOD_SUPER) ? " Super" : "");
-}
-
-static void
-onEvent(PuglView* view, const PuglEvent* event)
-{
- switch (event->type) {
- case PUGL_NOTHING:
- break;
- case PUGL_CONFIGURE:
- onReshape(view, event->configure.width, event->configure.height);
- break;
- case PUGL_EXPOSE:
- onDisplay(view);
- break;
- case PUGL_CLOSE:
- quit = 1;
- break;
- case PUGL_KEY_PRESS:
- fprintf(stderr, "Key %u (char %u) press (%s)%s\n",
- event->key.keycode, event->key.character, event->key.utf8,
- event->key.filter ? " (filtered)" : "");
- if (event->key.character == 'q' ||
- event->key.character == 'Q' ||
- event->key.character == PUGL_CHAR_ESCAPE) {
- quit = 1;
- }
- break;
- case PUGL_KEY_RELEASE:
- fprintf(stderr, "Key %u (char %u) release (%s)%s\n",
- event->key.keycode, event->key.character, event->key.utf8,
- event->key.filter ? " (filtered)" : "");
- break;
- case PUGL_MOTION_NOTIFY:
- xAngle = -(int)event->motion.x % 360;
- yAngle = (int)event->motion.y % 360;
- puglPostRedisplay(view);
- break;
- case PUGL_BUTTON_PRESS:
- case PUGL_BUTTON_RELEASE:
- fprintf(stderr, "Mouse %d %s at %f,%f ",
- event->button.button,
- (event->type == PUGL_BUTTON_PRESS) ? "down" : "up",
- event->button.x,
- event->button.y);
- printModifiers(view, event->scroll.state);
- break;
- case PUGL_SCROLL:
- fprintf(stderr, "Scroll %f %f %f %f ",
- event->scroll.x, event->scroll.y, event->scroll.dx, event->scroll.dy);
- printModifiers(view, event->scroll.state);
- dist += event->scroll.dy;
- if (dist < 10.0f) {
- dist = 10.0f;
- }
- puglPostRedisplay(view);
- break;
- case PUGL_ENTER_NOTIFY:
- fprintf(stderr, "Entered\n");
- break;
- case PUGL_LEAVE_NOTIFY:
- fprintf(stderr, "Exited\n");
- break;
- case PUGL_FOCUS_IN:
- fprintf(stderr, "Focus in\n");
- break;
- case PUGL_FOCUS_OUT:
- fprintf(stderr, "Focus out\n");
- break;
- }
-}
-
-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]);
- }
- }
-
- setlocale(LC_CTYPE, "");
-
- PuglView* view = puglInit(NULL, NULL);
- puglInitWindowClass(view, "PuglTest");
- puglInitWindowSize(view, 512, 512);
- puglInitWindowMinSize(view, 256, 256);
- puglInitResizable(view, resizable);
-
- puglIgnoreKeyRepeat(view, ignoreKeyRepeat);
- puglSetEventFunc(view, onEvent);
-
- puglCreateWindow(view, "Pugl Test");
-
- puglEnterContext(view);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
- puglLeaveContext(view, false);
-
- puglShowWindow(view);
-
- while (!quit) {
- puglWaitForEvent(view);
- puglProcessEvents(view);
- }
-
- puglDestroy(view);
- return 0;
-}
diff --git a/pugl/waf b/pugl/waf
deleted file mode 100755
index 2dbb06b..0000000
--- a/pugl/waf
+++ /dev/null
Binary files differ
diff --git a/pugl/wscript b/pugl/wscript
deleted file mode 100644
index 349ee14..0000000
--- a/pugl/wscript
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-import glob
-import os
-import subprocess
-import sys
-import waflib.Logs as Logs
-import waflib.Options as Options
-import waflib.extras.autowaf as autowaf
-
-# Library and package version (UNIX style major, minor, micro)
-# major increment <=> incompatible changes
-# minor increment <=> compatible changes (additions)
-# micro increment <=> no interface changes
-PUGL_VERSION = '0.2.0'
-PUGL_MAJOR_VERSION = '0'
-
-# Mandatory waf variables
-APPNAME = 'pugl' # Package name for waf dist
-VERSION = PUGL_VERSION # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-def options(opt):
- opt.load('compiler_c')
- 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('--target', default=None, dest='target',
- help='Target platform (e.g. "win32" or "darwin")')
- 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')
-
-def configure(conf):
- conf.env.TARGET_PLATFORM = Options.options.target or Options.platform
- conf.load('compiler_c')
- if conf.env.TARGET_PLATFORM == 'win32':
- conf.load('compiler_cxx')
-
- autowaf.configure(conf)
- autowaf.set_c99_mode(conf)
- autowaf.display_header('Pugl Configuration')
-
- if not Options.options.no_gl:
- # TODO: Portable check for OpenGL
- conf.define('HAVE_GL', 1)
- 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
- conf.env['BUILD_SHARED'] = (conf.env.TARGET_PLATFORM != 'win32' or
- Options.options.shared)
- 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, "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('')
-
-def build(bld):
- # C Headers
- includedir = '${INCLUDEDIR}/pugl-%s/pugl' % PUGL_MAJOR_VERSION
- bld.install_files(includedir, bld.path.ant_glob('pugl/*.h'))
- bld.install_files(includedir, bld.path.ant_glob('pugl/*.hpp'))
-
- # Pkgconfig file
- autowaf.build_pc(bld, 'PUGL', PUGL_VERSION, PUGL_MAJOR_VERSION, [],
- {'PUGL_MAJOR_VERSION' : PUGL_MAJOR_VERSION})
-
- libflags = [ '-fvisibility=hidden' ]
- framework = []
- libs = []
- if bld.env.TARGET_PLATFORM == 'win32':
- lang = 'cxx'
- lib_source = ['pugl/pugl_win.cpp']
- libs = ['opengl32', 'gdi32', 'user32']
- defines = []
- elif bld.env.TARGET_PLATFORM == 'darwin':
- lang = 'c' # Objective C, actually
- lib_source = ['pugl/pugl_osx.m']
- framework = ['Cocoa', 'OpenGL']
- defines = []
- else:
- lang = 'c'
- lib_source = ['pugl/pugl_x11.c']
- libs = ['X11']
- defines = []
- if bld.is_defined('HAVE_GL'):
- libs += ['GL']
- if bld.env['MSVC_COMPILER']:
- libflags = []
- else:
- libs += ['m']
-
- # Shared Library
- if bld.env['BUILD_SHARED']:
- obj = bld(features = '%s %sshlib' % (lang, lang),
- export_includes = ['.'],
- source = lib_source,
- includes = ['.', './src'],
- lib = libs,
- uselib = ['CAIRO'],
- framework = framework,
- name = 'libpugl',
- target = 'pugl-%s' % PUGL_MAJOR_VERSION,
- vnum = PUGL_VERSION,
- install_path = '${LIBDIR}',
- defines = defines,
- cflags = libflags + [ '-DPUGL_SHARED',
- '-DPUGL_INTERNAL' ])
-
- # Static library
- if bld.env['BUILD_STATIC']:
- obj = bld(features = '%s %sstlib' % (lang, lang),
- export_includes = ['.'],
- source = lib_source,
- includes = ['.', './src'],
- lib = libs,
- uselib = ['CAIRO'],
- framework = framework,
- name = 'libpugl_static',
- target = 'pugl-%s' % PUGL_MAJOR_VERSION,
- vnum = PUGL_VERSION,
- install_path = '${LIBDIR}',
- defines = defines,
- cflags = ['-DPUGL_INTERNAL'])
-
- if bld.env['BUILD_TESTS']:
- test_libs = libs
- 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)
-
- if bld.env['DOCS']:
- bld(features = 'subst',
- source = 'Doxyfile.in',
- target = 'Doxyfile',
- install_path = '',
- name = 'Doxyfile',
- PUGL_VERSION = PUGL_VERSION)
-
- bld(features = 'doxygen',
- doxyfile = 'Doxyfile')
-
-def lint(ctx):
- "checks code for style issues"
- 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)
-
-# Alias .m files to be compiled the same as .c files, gcc will do the right thing.
-from waflib import TaskGen
-@TaskGen.extension('.m')
-def m_hook(self, node):
- return self.create_compiled_task('c', node)