commit 272e1bbfbd9d70e3852fcd666716c72310e3ac23
parent 05c6d04adbd2018ca50e8e41a4ddb2ce45c9bd89
Author: falkTX <falktx@falktx.com>
Date: Mon, 3 May 2021 23:40:21 +0100
Start coupling widget and window
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
12 files changed, 266 insertions(+), 145 deletions(-)
diff --git a/dgl/Makefile b/dgl/Makefile
@@ -10,7 +10,7 @@ include ../Makefile.base.mk
BUILD_C_FLAGS += $(DGL_FLAGS) -I. -Isrc
BUILD_CXX_FLAGS += $(DGL_FLAGS) -I. -Isrc -DDONT_SET_USING_DGL_NAMESPACE -Wno-unused-parameter
-# -Isrc/pugl-upstream/include
+BUILD_CXX_FLAGS += -Isrc/pugl-upstream/include
LINK_FLAGS += $(DGL_LIBS)
# TODO fix these after pugl-upstream is done
@@ -27,22 +27,24 @@ OBJS_common = \
../build/dgl/Application.cpp.o \
../build/dgl/ApplicationPrivateData.cpp.o \
../build/dgl/Color.cpp.o \
- ../build/dgl/Geometry.cpp.o
+ ../build/dgl/Geometry.cpp.o \
+ ../build/dgl/TopLevelWidget.cpp.o \
+ ../build/dgl/Window.cpp.o \
+ ../build/dgl/WindowPrivateData.cpp.o
# ../build/dgl/ImageBase.cpp.o \
# ../build/dgl/Resources.cpp.o\
# ../build/dgl/StandaloneWindow.cpp.o \
# ../build/dgl/Widget.cpp.o \
-# ../build/dgl/Window.cpp.o\
# ../build/dgl/WindowFileBrowser.cpp.o
# TODO: ImageWidgets.cpp
# ---------------------------------------------------------------------------------------------------------------------
-OBJS_cairo = $(OBJS_common)
+OBJS_cairo = $(OBJS_common) \
+ ../build/dgl/pugl.cpp.cairo.o
# ../build/dgl/Cairo.cpp.cairo.o \
-# ../build/dgl/WidgetPrivateData.cpp.cairo.o \
-# ../build/dgl/WindowPrivateData.cpp.cairo.o
+# ../build/dgl/WidgetPrivateData.cpp.cairo.o
# ifeq ($(MACOS),true)
# OBJS_cairo += ../build/dgl/Window.mm.cairo.o
@@ -52,7 +54,8 @@ OBJS_cairo = $(OBJS_common)
# ---------------------------------------------------------------------------------------------------------------------
-OBJS_opengl = $(OBJS_common)
+OBJS_opengl = $(OBJS_common) \
+ ../build/dgl/pugl.cpp.opengl.o
# ../build/dgl/OpenGL.cpp.opengl.o \
# ../build/dgl/Image.cpp.opengl.o \
# ../build/dgl/ImageWidgets.cpp.opengl.o \
@@ -115,10 +118,10 @@ all: $(TARGETS)
# ---------------------------------------------------------------------------------------------------------------------
-# ../build/dgl/%.cpp.cairo.o: src/%.cpp
-# -@mkdir -p ../build/dgl
-# @echo "Compiling $< (Cairo variant)"
-# $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@
+../build/dgl/%.cpp.cairo.o: src/%.cpp
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (Cairo variant)"
+ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@
# ../build/dgl/Window.cpp.cairo.o: src/Window.cpp src/sofd/* src/pugl-upstream/*
# -@mkdir -p ../build/dgl
@@ -132,10 +135,10 @@ all: $(TARGETS)
# ---------------------------------------------------------------------------------------------------------------------
-# ../build/dgl/%.cpp.opengl.o: src/%.cpp
-# -@mkdir -p ../build/dgl
-# @echo "Compiling $< (OpenGL variant)"
-# $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@
+../build/dgl/%.cpp.opengl.o: src/%.cpp
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (OpenGL variant)"
+ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@
# ../build/dgl/Window.cpp.opengl.o: src/Window.cpp src/sofd/* src/pugl-upstream/*
# -@mkdir -p ../build/dgl
diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp
@@ -21,6 +21,8 @@
START_NAMESPACE_DGL
+class Window;
+
// -----------------------------------------------------------------------
/**
@@ -31,6 +33,9 @@ START_NAMESPACE_DGL
This widget takes the full size of the Window it is mapped to.
Sub-widgets can be added on top of this top-level widget, by creating them with this class as parent.
Doing so allows for custom position and sizes.
+
+ This class is used as the type for DPF Plugin UIs.
+ So anything that a plugin UI might need that does not belong in a simple Widget will go here.
*/
class TopLevelWidget : public Widget
{
@@ -45,9 +50,32 @@ public:
*/
virtual ~TopLevelWidget();
+protected:
+ /**
+ A function called before any draw operations begin (in the current event-loop cycle).
+ Can be used to setup any resources for needed drawing.
+ The default implementation simply paints the full Widget contents black.
+ */
+ virtual void onDisplayBefore();
+
+ /**
+ A function called after all draw operations have ended (in the current event-loop cycle).
+ Can be used to clear any resources setup during onDisplayBefore().
+ The default implementation does nothing.
+ */
+ virtual void onDisplayAfter();
+
+ /**
+ A function called when the widget is resized.
+ Reimplemented from Widget::onResize.
+ */
+ void onResize(const ResizeEvent&) override;
+
private:
struct PrivateData;
PrivateData* const pData;
+ friend class Window;
+
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopLevelWidget)
};
diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp
@@ -22,19 +22,19 @@
// -----------------------------------------------------------------------
// Forward class names
-#ifdef DISTRHO_DEFINES_H_INCLUDED
-START_NAMESPACE_DISTRHO
-class UI;
-END_NAMESPACE_DISTRHO
-#endif
+// #ifdef DISTRHO_DEFINES_H_INCLUDED
+// START_NAMESPACE_DISTRHO
+// class UI;
+// END_NAMESPACE_DISTRHO
+// #endif
START_NAMESPACE_DGL
// class Application;
// class NanoWidget;
-class Window;
+// class Window;
// class StandaloneWindow;
-class SubWidget;
+// class SubWidget;
class TopLevelWidget;
using namespace Events;
@@ -208,10 +208,10 @@ private:
// friend class NanoWidget;
// friend class Window;
// friend class StandaloneWindow;
- friend class SubWidget;
-#ifdef DISTRHO_DEFINES_H_INCLUDED
- friend class DISTRHO_NAMESPACE::UI;
-#endif
+ friend class TopLevelWidget;
+// #ifdef DISTRHO_DEFINES_H_INCLUDED
+// friend class DISTRHO_NAMESPACE::UI;
+// #endif
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -37,12 +37,13 @@ class Application;
Typically the event handling functions as following:
Application -> Window -> Top-Level-Widget -> SubWidgets
- ...
-
Please note that, unlike many other graphical toolkits out there,
DGL makes a clear distinction between a Window and a Widget.
You cannot directly draw in a Window, you need to create a Widget for that.
+ Also, a Window MUST have a single top-level Widget.
+ The Window will take care of global screen positioning and resizing, everything else is sent for widgets to handle.
+
...
*/
class Window
@@ -160,11 +161,6 @@ public:
*/
uintptr_t getNativeWindowHandle() const noexcept;
-protected:
- virtual void onDisplayBefore();
- virtual void onDisplayAfter();
- virtual void onReshape(uint width, uint height);
-
private:
struct PrivateData;
PrivateData* const pData;
diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp
@@ -15,11 +15,34 @@
*/
#include "TopLevelWidgetPrivateData.hpp"
+#include "pugl.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
TopLevelWidget::TopLevelWidget(Window& windowToMapTo)
- : pData(new PrivateData(this, windowToMapTo)) {}
+ : Widget(*this),
+ pData(new PrivateData(this, windowToMapTo)) {}
TopLevelWidget::~TopLevelWidget()
{
delete pData;
}
+
+void TopLevelWidget::onDisplayBefore()
+{
+}
+
+void TopLevelWidget::onDisplayAfter()
+{
+}
+
+void TopLevelWidget::onResize(const ResizeEvent& ev)
+{
+ Widget::onResize(ev);
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp
@@ -0,0 +1,68 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "TopLevelWidgetPrivateData.hpp"
+#include "../Window.hpp"
+// #include "pugl.hpp"
+
+START_NAMESPACE_DGL
+
+#define FOR_EACH_WIDGET(it) \
+ for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it)
+
+#define FOR_EACH_WIDGET_INV(rit) \
+ for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit)
+
+// -----------------------------------------------------------------------
+
+TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w)
+ : self(s),
+ window(w),
+ widgets() {}
+
+void TopLevelWidget::PrivateData::display()
+{
+ if (widgets.size() == 0)
+ return;
+
+ const Size<uint> size(window.getSize());
+// const int width = rect.width;
+// const int height = rect.height;
+
+ FOR_EACH_WIDGET(it)
+ {
+ Widget* const widget(*it);
+ widget->pData->display(width, height, fAutoScaling, false);
+ }
+}
+
+void TopLevelWidget::PrivateData::resize(const uint width, const uint height)
+{
+ if (widgets.size() == 0)
+ return;
+
+ FOR_EACH_WIDGET(it)
+ {
+ Widget* const widget(*it);
+
+ if (widget->pData->needsFullViewport)
+ widget->setSize(width, height);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dgl/src/TopLevelWidgetPrivateData.hpp b/dgl/src/TopLevelWidgetPrivateData.hpp
@@ -18,7 +18,8 @@
#define DGL_TOP_LEVEL_WIDGET_PRIVATE_DATA_HPP_INCLUDED
#include "../TopLevelWidget.hpp"
-// #include "../WidgetPrivateData.hpp"
+
+#include <list>
START_NAMESPACE_DGL
@@ -27,12 +28,13 @@ START_NAMESPACE_DGL
struct TopLevelWidget::PrivateData {
TopLevelWidget* const self;
Window& window;
+ std::list<Widget*> widgets;
- PrivateData(TopLevelWidget* const s, Window& w)
- : self(s),
- window(w) {}
+ PrivateData(TopLevelWidget* const s, Window& w);
+ void display();
+ void resize(uint width, uint height);
- DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData)
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};
// -----------------------------------------------------------------------
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -128,24 +128,6 @@ uintptr_t Window::getNativeWindowHandle() const noexcept
return puglGetNativeWindow(pData->view);
}
-void Window::onDisplayBefore()
-{
- const GraphicsContext& context(pData->getGraphicsContext());
- PrivateData::Fallback::onDisplayBefore(context);
-}
-
-void Window::onDisplayAfter()
-{
- const GraphicsContext& context(pData->getGraphicsContext());
- PrivateData::Fallback::onDisplayAfter(context);
-}
-
-void Window::onReshape(const uint width, const uint height)
-{
- const GraphicsContext& context(pData->getGraphicsContext());
- PrivateData::Fallback::onReshape(context, width, height);
-}
-
#if 0
#if 0
void Window::exec(bool lockWait)
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -15,10 +15,12 @@
*/
#include "WindowPrivateData.hpp"
-#include "../Widget.hpp"
+#include "../TopLevelWidget.hpp"
#include "pugl.hpp"
+#include <cinttypes>
+
START_NAMESPACE_DGL
#define DGL_DEBUG_EVENTS
@@ -42,6 +44,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
+ topLevelWidget(nullptr),
isClosed(true),
isVisible(false),
isEmbed(false)
@@ -53,6 +56,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
+ topLevelWidget(nullptr),
isClosed(true),
isVisible(false),
isEmbed(false)
@@ -69,6 +73,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
+ topLevelWidget(nullptr),
isClosed(parentWindowHandle == 0),
isVisible(parentWindowHandle != 0),
isEmbed(parentWindowHandle != 0)
@@ -115,15 +120,7 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r
return;
}
-#ifdef DGL_CAIRO
- puglSetBackend(view, puglCairoBackend());
-#endif
-#ifdef DGL_OPENGL
- puglSetBackend(view, puglGlBackend());
-#endif
-#ifdef DGL_Vulkan
- puglSetBackend(view, puglVulkanBackend());
-#endif
+ puglSetMatchingBackendForCurrentBuild(view);
puglSetHandle(view, this);
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);
@@ -238,17 +235,6 @@ void Window::PrivateData::close()
// -----------------------------------------------------------------------
-const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
-{
- GraphicsContext& context((GraphicsContext&)graphicsContext);
-#ifdef DGL_CAIRO
- ((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view);
-#endif
- return context;
-}
-
-// -----------------------------------------------------------------------
-
void Window::PrivateData::idleCallback()
{
// #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED)
@@ -268,24 +254,18 @@ void Window::PrivateData::idleCallback()
void Window::PrivateData::onPuglDisplay()
{
- self->onDisplayBefore();
-
- /*
- if (fWidgets.size() != 0)
+#ifndef DPF_TEST_WINDOW_CPP
+ if (topLevelWidget != nullptr)
{
- const PuglRect rect = puglGetFrame(fView);
- const int width = rect.width;
- const int height = rect.height;
-
- FOR_EACH_WIDGET(it)
- {
- Widget* const widget(*it);
- widget->pData->display(width, height, fAutoScaling, false);
- }
+ topLevelWidget->onDisplayBefore();
+ topLevelWidget->onDisplay();
+ topLevelWidget->onDisplayAfter();
+ }
+ else
+#endif
+ {
+ puglFallbackOnDisplay(view);
}
- */
-
- self->onDisplayAfter();
}
void Window::PrivateData::onPuglReshape(const int width, const int height)
@@ -294,17 +274,12 @@ void Window::PrivateData::onPuglReshape(const int width, const int height)
DGL_DBGp("PUGL: onReshape : %i %i\n", width, height);
- self->onReshape(width, height);
-
- /*
- FOR_EACH_WIDGET(it)
- {
- Widget* const widget(*it);
-
- if (widget->pData->needsFullViewport)
- widget->setSize(width, height);
- }
- */
+#ifndef DPF_TEST_WINDOW_CPP
+ if (topLevelWidget != nullptr)
+ topLevelWidget->setSize(width, height);
+ else
+#endif
+ puglFallbackOnResize(view);
}
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);
@@ -467,38 +442,6 @@ static int printEvent(const PuglEvent* event, const char* prefix, const bool ver
// -----------------------------------------------------------------------
-void Window::PrivateData::Fallback::onDisplayBefore(const GraphicsContext&)
-{
-#ifdef DGL_OPENGL
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
-#endif
-}
-
-void Window::PrivateData::Fallback::onDisplayAfter(const GraphicsContext&)
-{
-}
-
-void Window::PrivateData::Fallback::onReshape(const GraphicsContext&, const uint width, const uint height)
-{
-#ifdef DGL_OPENGL
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0);
- glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-#else
- // unused
- (void)width;
- (void)height;
-#endif
-}
-
-// -----------------------------------------------------------------------
-
END_NAMESPACE_DGL
#if 0
@@ -555,12 +498,6 @@ extern "C" {
START_NAMESPACE_DGL
-#define FOR_EACH_WIDGET(it) \
- for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it)
-
-#define FOR_EACH_WIDGET_INV(rit) \
- for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit)
-
// -----------------------------------------------------------------------
void Window::PrivateData::addWidget(Widget* const widget)
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -18,12 +18,13 @@
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED
#include "../Window.hpp"
+#include "ApplicationPrivateData.hpp"
#include "pugl.hpp"
START_NAMESPACE_DGL
-class Widget;
+class TopLevelWidget;
// -----------------------------------------------------------------------
@@ -43,6 +44,9 @@ struct Window::PrivateData : IdleCallback {
/** Reserved space for graphics context. */
mutable uint8_t graphicsContext[sizeof(void*)];
+ /** The top-level widget associated with this Window. */
+ TopLevelWidget* topLevelWidget;
+
/** Whether this Window is closed (not visible or counted in the Application it is tied to).
Defaults to true unless embed (embed windows are never closed). */
bool isClosed;
@@ -92,12 +96,14 @@ struct Window::PrivateData : IdleCallback {
// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
+#if 0
// Fallback build-specific Window functions
struct Fallback {
static void onDisplayBefore(const GraphicsContext& context);
static void onDisplayAfter(const GraphicsContext& context);
static void onReshape(const GraphicsContext& context, uint width, uint height);
};
+#endif
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};
@@ -115,7 +121,6 @@ END_NAMESPACE_DGL
bool fUsingEmbed;
double fScaling;
double fAutoScaling;
- std::list<Widget*> fWidgets;
struct Modal {
bool enabled;
diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp
@@ -154,5 +154,70 @@ PuglStatus puglSetWindowSize(PuglView* view, unsigned int width, unsigned int he
}
// --------------------------------------------------------------------------------------------------------------------
+// set backend that matches current build
+
+void puglSetMatchingBackendForCurrentBuild(PuglView* view)
+{
+#ifdef DGL_CAIRO
+ puglSetBackend(view, puglCairoBackend());
+#endif
+#ifdef DGL_OPENGL
+ puglSetBackend(view, puglGlBackend());
+#endif
+#ifdef DGL_Vulkan
+ puglSetBackend(view, puglVulkanBackend());
+#endif
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// DGL specific, build-specific fallback drawing
+void puglFallbackOnDisplay(PuglView*)
+{
+#ifdef DGL_OPENGL
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+#endif
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// DGL specific, build-specific fallback resize
+
+void puglFallbackOnResize(PuglView* view)
+{
+#ifdef DGL_OPENGL
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, static_cast<GLdouble>(view->frame.width), static_cast<GLdouble>(view->frame.height), 0.0, 0.0, 1.0);
+ glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height));
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+#endif
+}
+
+END_NAMESPACE_DGL
+
+// --------------------------------------------------------------------------------------------------------------------
+// extra, build-specific stuff
+
+#include "WindowPrivateData.hpp"
+
+#ifdef DGL_CAIRO
+# include "../Cairo.hpp"
+#endif
+
+START_NAMESPACE_DGL
+
+const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
+{
+ GraphicsContext& context((GraphicsContext&)graphicsContext);
+#ifdef DGL_CAIRO
+ ((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view);
+#endif
+ return context;
+}
END_NAMESPACE_DGL
+
+// --------------------------------------------------------------------------------------------------------------------
diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp
@@ -41,6 +41,18 @@ puglGetWindowTitle(const PuglView* view);
PUGL_API PuglStatus
puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height);
+// DGL specific, assigns backend that matches current DGL build
+PUGL_API void
+puglSetMatchingBackendForCurrentBuild(PuglView* view);
+
+// DGL specific, build-specific fallback drawing
+PUGL_API void
+puglFallbackOnDisplay(PuglView* view);
+
+// DGL specific, build-specific fallback resize
+PUGL_API void
+puglFallbackOnResize(PuglView* view);
+
PUGL_END_DECLS
// --------------------------------------------------------------------------------------------------------------------