diff --git a/Makefile b/Makefile
index 6527777..5d6e6e9 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ HAVE_PROJM = $(shell pkg-config --exists libprojectM && echo true)
# --------------------------------------------------------------
dgl:
-ifeq ($(HAVE_DGL),true)
+ifeq ($(HAVE_CAIRO_OR_OPENGL),true)
$(MAKE) -C dpf/dgl
endif
@@ -50,7 +50,7 @@ plugins: dgl
$(MAKE) all -C plugins/gigaverb
$(MAKE) all -C plugins/pitchshift
-ifeq ($(HAVE_DGL),true)
+ifeq ($(HAVE_CAIRO_OR_OPENGL),true)
# glBars (needs OpenGL)
$(MAKE) all -C plugins/glBars
@@ -58,7 +58,7 @@ ifeq ($(HAVE_PROJM),true)
# ProM (needs OpenGL + ProjectM)
$(MAKE) all -C plugins/ProM
endif # HAVE_PROJM
-endif # HAVE_DGL
+endif # HAVE_CAIRO_OR_OPENGL
ifneq ($(CROSS_COMPILING),true)
gen: plugins dpf/utils/lv2_ttl_generator
@@ -123,9 +123,9 @@ install:
install -m 644 bin/*-dssi.* $(DESTDIR)$(PREFIX)/lib/dssi/
install -m 644 bin/*-vst.* $(DESTDIR)$(PREFIX)/lib/vst/
-ifeq ($(HAVE_DGL),true)
+ifeq ($(HAVE_CAIRO_OR_OPENGL),true)
cp -r bin/*-dssi $(DESTDIR)$(PREFIX)/lib/dssi/
-endif # HAVE_DGL
+endif # HAVE_CAIRO_OR_OPENGL
cp -r bin/*.lv2 $(DESTDIR)$(PREFIX)/lib/lv2/
ifeq ($(HAVE_JACK),true)
@@ -142,12 +142,12 @@ ifeq ($(HAVE_JACK),true)
install -m 755 bin/MaFreeverb $(DESTDIR)$(PREFIX)/bin/
install -m 755 bin/MaGigaverb $(DESTDIR)$(PREFIX)/bin/
install -m 755 bin/MaPitchshift $(DESTDIR)$(PREFIX)/bin/
-ifeq ($(HAVE_DGL),true)
+ifeq ($(HAVE_CAIRO_OR_OPENGL),true)
install -m 755 bin/glBars $(DESTDIR)$(PREFIX)/bin/
ifeq ($(HAVE_PROJM),true)
install -m 755 bin/ProM $(DESTDIR)$(PREFIX)/bin/
endif # HAVE_PROJM
-endif # HAVE_DGL
+endif # HAVE_CAIRO_OR_OPENGL
endif # HAVE_JACK
# --------------------------------------------------------------
diff --git a/dpf/Makefile.base.mk b/dpf/Makefile.base.mk
index 5e10d7d..83ef5c4 100644
--- a/dpf/Makefile.base.mk
+++ b/dpf/Makefile.base.mk
@@ -16,7 +16,7 @@ ifneq ($(HAIKU),true)
ifneq ($(HURD),true)
ifneq ($(LINUX),true)
ifneq ($(MACOS),true)
-ifneq ($(WIN32),true)
+ifneq ($(WINDOWS),true)
TARGET_MACHINE := $(shell $(CC) -dumpmachine)
ifneq (,$(findstring bsd,$(TARGET_MACHINE)))
@@ -35,7 +35,7 @@ ifneq (,$(findstring apple,$(TARGET_MACHINE)))
MACOS=true
endif
ifneq (,$(findstring mingw,$(TARGET_MACHINE)))
-WIN32=true
+WINDOWS=true
endif
endif
@@ -45,6 +45,16 @@ endif
endif
endif
+# ---------------------------------------------------------------------------------------------------------------------
+# Set PKG_CONFIG (can be overridden by environment variable)
+
+ifeq ($(WINDOWS),true)
+# Build statically on Windows by default
+PKG_CONFIG ?= pkg-config --static
+else
+PKG_CONFIG ?= pkg-config
+endif
+
# ---------------------------------------------------------------------------------------------------------------------
# Set LINUX_OR_MACOS
@@ -57,14 +67,20 @@ LINUX_OR_MACOS=true
endif
# ---------------------------------------------------------------------------------------------------------------------
-# Set MACOS_OR_WIN32
+# Set MACOS_OR_WINDOWS and HAIKU_OR_MACOS_OR_WINDOWS
+
+ifeq ($(HAIKU),true)
+HAIKU_OR_MACOS_OR_WINDOWS=true
+endif
ifeq ($(MACOS),true)
-MACOS_OR_WIN32=true
+MACOS_OR_WINDOWS=true
+HAIKU_OR_MACOS_OR_WINDOWS=true
endif
-ifeq ($(WIN32),true)
-MACOS_OR_WIN32=true
+ifeq ($(WINDOWS),true)
+MACOS_OR_WINDOWS=true
+HAIKU_OR_MACOS_OR_WINDOWS=true
endif
# ---------------------------------------------------------------------------------------------------------------------
@@ -108,10 +124,12 @@ ifeq ($(NOOPT),true)
BASE_OPTS = -O2 -ffast-math -fdata-sections -ffunction-sections
endif
-ifeq ($(WIN32),true)
+ifeq ($(WINDOWS),true)
# mingw has issues with this specific optimization
# See https://github.com/falkTX/Carla/issues/696
BASE_OPTS += -fno-rerun-cse-after-loop
+# See https://github.com/falkTX/Carla/issues/855
+BASE_OPTS += -mstackrealign
ifeq ($(BUILDING_FOR_WINDOWS),true)
BASE_FLAGS += -DBUILDING_CARLA_FOR_WINDOWS
endif
@@ -141,7 +159,7 @@ ifeq ($(MACOS_OLD),true)
BUILD_CXX_FLAGS = $(BASE_FLAGS) $(CXXFLAGS) -DHAVE_CPP11_SUPPORT=0
endif
-ifeq ($(WIN32),true)
+ifeq ($(WINDOWS),true)
# Always build statically on windows
LINK_FLAGS += -static
endif
@@ -170,44 +188,81 @@ CXXFLAGS += -Weffc++ -Wnon-virtual-dtor -Woverloaded-virtual
endif
# ---------------------------------------------------------------------------------------------------------------------
-# Check for optional libs
+# Check for required libraries
-ifeq ($(MACOS_OR_WIN32),true)
-HAVE_DGL = true
+HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true)
+
+ifeq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
+HAVE_OPENGL = true
else
-HAVE_DGL = $(shell pkg-config --exists gl x11 && echo true)
-HAVE_JACK = $(shell pkg-config --exists jack && echo true)
-HAVE_LIBLO = $(shell pkg-config --exists liblo && echo true)
+HAVE_OPENGL = $(shell $(PKG_CONFIG) --exists gl && echo true)
+HAVE_X11 = $(shell $(PKG_CONFIG) --exists x11 && echo true)
endif
-ifneq ($(HAVE_DGL),true)
-$(error DGL missing 22)
+# ---------------------------------------------------------------------------------------------------------------------
+# Check for optional libraries
+
+HAVE_JACK = $(shell $(PKG_CONFIG) --exists jack && echo true)
+HAVE_LIBLO = $(shell $(PKG_CONFIG) --exists liblo && echo true)
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Set Generic DGL stuff
+
+ifeq ($(MACOS),true)
+DGL_SYSTEM_LIBS += -framework Cocoa
+endif
+
+ifeq ($(WINDOWS),true)
+DGL_SYSTEM_LIBS += -lgdi32
+endif
+
+ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
+DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags x11)
+DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs x11)
+endif
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Set Cairo specific stuff
+
+ifeq ($(HAVE_CAIRO),true)
+
+DGL_FLAGS += -DHAVE_CAIRO
+
+CAIRO_FLAGS = $(shell $(PKG_CONFIG) --cflags cairo)
+CAIRO_LIBS = $(shell $(PKG_CONFIG) --libs cairo)
+
+HAVE_CAIRO_OR_OPENGL = true
+
endif
# ---------------------------------------------------------------------------------------------------------------------
-# Set libs stuff
+# Set OpenGL specific stuff
+
+ifeq ($(HAVE_OPENGL),true)
-ifeq ($(HAVE_DGL),true)
+DGL_FLAGS += -DHAVE_OPENGL
ifeq ($(MACOS),true)
-DGL_LIBS = -framework OpenGL -framework Cocoa
+OPENGL_LIBS = -framework OpenGL
endif
-ifeq ($(WIN32),true)
-DGL_LIBS = -lopengl32 -lgdi32
+ifeq ($(WINDOWS),true)
+OPENGL_LIBS = -lopengl32
endif
-ifneq ($(MACOS_OR_WIN32),true)
-DGL_FLAGS = $(shell pkg-config --cflags gl x11)
-DGL_LIBS = $(shell pkg-config --libs gl x11)
+ifneq ($(MACOS_OR_WINDOWS),true)
+OPENGL_FLAGS = $(shell $(PKG_CONFIG) --cflags gl x11)
+OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl x11)
endif
-endif # HAVE_DGL
+HAVE_CAIRO_OR_OPENGL = true
+
+endif
# ---------------------------------------------------------------------------------------------------------------------
# Set app extension
-ifeq ($(WIN32),true)
+ifeq ($(WINDOWS),true)
APP_EXT = .exe
endif
@@ -220,17 +275,17 @@ ifeq ($(MACOS),true)
LIB_EXT = .dylib
endif
-ifeq ($(WIN32),true)
+ifeq ($(WINDOWS),true)
LIB_EXT = .dll
endif
# ---------------------------------------------------------------------------------------------------------------------
# Set shared library CLI arg
-SHARED = -shared
-
ifeq ($(MACOS),true)
SHARED = -dynamiclib
+else
+SHARED = -shared
endif
# ---------------------------------------------------------------------------------------------------------------------
diff --git a/dpf/Makefile.plugins.mk b/dpf/Makefile.plugins.mk
index aa69a91..4afe6b4 100644
--- a/dpf/Makefile.plugins.mk
+++ b/dpf/Makefile.plugins.mk
@@ -15,10 +15,6 @@ endif
include $(DPF_PATH)/Makefile.base.mk
-ifeq ($(FILES_UI),)
-HAVE_DGL = false
-endif
-
# ---------------------------------------------------------------------------------------------------------------------
# Basic setup
@@ -28,8 +24,12 @@ BUILD_DIR = ../../build/$(NAME)
BUILD_C_FLAGS += -I.
BUILD_CXX_FLAGS += -I. -I$(DPF_PATH)/distrho -I$(DPF_PATH)/dgl
-ifeq ($(HAVE_DGL),true)
-BASE_FLAGS += -DHAVE_DGL
+ifeq ($(HAVE_CAIRO),true)
+DGL_FLAGS += -DHAVE_CAIRO
+endif
+
+ifeq ($(HAVE_OPENGL),true)
+DGL_FLAGS += -DHAVE_OPENGL
endif
ifeq ($(HAVE_JACK),true)
@@ -59,7 +59,39 @@ lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui$(LIB_EXT)
vst = $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT)
# ---------------------------------------------------------------------------------------------------------------------
-# Handle plugins without UI
+# Handle UI stuff, disable UI support automatically
+
+ifeq ($(FILES_UI),)
+UI_TYPE = none
+endif
+
+ifeq ($(UI_TYPE),)
+UI_TYPE = opengl
+endif
+
+ifeq ($(UI_TYPE),cairo)
+ifeq ($(HAVE_CAIRO),true)
+DGL_FLAGS += $(CAIRO_FLAGS) -DDGL_CAIRO
+DGL_LIBS += $(CAIRO_LIBS)
+DGL_LIB = $(DPF_PATH)/build/libdgl-cairo.a
+HAVE_DGL = true
+else
+HAVE_DGL = false
+endif
+endif
+
+ifeq ($(UI_TYPE),opengl)
+ifeq ($(HAVE_OPENGL),true)
+DGL_FLAGS += $(OPENGL_FLAGS) -DDGL_OPENGL
+DGL_LIBS += $(OPENGL_LIBS)
+DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a
+HAVE_DGL = true
+else
+HAVE_DGL = false
+endif
+endif
+
+DGL_LIBS += $(DGL_SYSTEM_LIBS)
ifneq ($(HAVE_DGL),true)
dssi_ui =
@@ -68,6 +100,9 @@ DGL_LIBS =
OBJS_UI =
endif
+# TODO split dsp and ui object build flags
+BASE_FLAGS += $(DGL_FLAGS)
+
# ---------------------------------------------------------------------------------------------------------------------
# all needs to be first
@@ -81,6 +116,11 @@ $(BUILD_DIR)/%.c.o: %.c
@echo "Compiling $<"
@$(CC) $< $(BUILD_C_FLAGS) -c -o $@
+$(BUILD_DIR)/%.cc.o: %.cc
+ -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
+ @echo "Compiling $<"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@
+
$(BUILD_DIR)/%.cpp.o: %.cpp
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<"
@@ -105,12 +145,12 @@ $(BUILD_DIR)/DistrhoUIMain_%.cpp.o: $(DPF_PATH)/distrho/DistrhoUIMain.cpp
$(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o: $(DPF_PATH)/distrho/DistrhoPluginMain.cpp
-@mkdir -p $(BUILD_DIR)
@echo "Compiling DistrhoPluginMain.cpp (JACK)"
- @$(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags jack) -DDISTRHO_PLUGIN_TARGET_JACK -c -o $@
+ @$(CXX) $< $(BUILD_CXX_FLAGS) $(shell $(PKG_CONFIG) --cflags jack) -DDISTRHO_PLUGIN_TARGET_JACK -c -o $@
$(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o: $(DPF_PATH)/distrho/DistrhoUIMain.cpp
-@mkdir -p $(BUILD_DIR)
@echo "Compiling DistrhoUIMain.cpp (DSSI)"
- @$(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags liblo) -DDISTRHO_PLUGIN_TARGET_DSSI -c -o $@
+ @$(CXX) $< $(BUILD_CXX_FLAGS) $(shell $(PKG_CONFIG) --cflags liblo) -DDISTRHO_PLUGIN_TARGET_DSSI -c -o $@
# ---------------------------------------------------------------------------------------------------------------------
# JACK
@@ -118,13 +158,13 @@ $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o: $(DPF_PATH)/distrho/DistrhoUIMain.cpp
jack: $(jack)
ifeq ($(HAVE_DGL),true)
-$(jack): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o $(BUILD_DIR)/DistrhoUIMain_JACK.cpp.o $(DPF_PATH)/build/libdgl.a
+$(jack): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o $(BUILD_DIR)/DistrhoUIMain_JACK.cpp.o $(DGL_LIB)
else
$(jack): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o
endif
-@mkdir -p $(shell dirname $@)
@echo "Creating JACK standalone for $(NAME)"
- @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --libs jack) -o $@
+ @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell $(PKG_CONFIG) --libs jack) -o $@
# ---------------------------------------------------------------------------------------------------------------------
# LADSPA
@@ -148,10 +188,10 @@ $(dssi_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_DSSI.cpp.o
@echo "Creating DSSI plugin library for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@
-$(dssi_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o $(DPF_PATH)/build/libdgl.a
+$(dssi_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@)
@echo "Creating DSSI UI for $(NAME)"
- @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --libs liblo) -o $@
+ @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell $(PKG_CONFIG) --libs liblo) -o $@
# ---------------------------------------------------------------------------------------------------------------------
# LV2
@@ -160,7 +200,7 @@ lv2: $(lv2)
lv2_dsp: $(lv2_dsp)
lv2_sep: $(lv2_dsp) $(lv2_ui)
-$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DPF_PATH)/build/libdgl.a
+$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -o $@
@@ -170,7 +210,7 @@ $(lv2_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o
@echo "Creating LV2 plugin library for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@
-$(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DPF_PATH)/build/libdgl.a
+$(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin UI for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -o $@
@@ -181,7 +221,7 @@ $(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DPF_PATH)/build/lib
vst: $(vst)
ifeq ($(HAVE_DGL),true)
-$(vst): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST.cpp.o $(DPF_PATH)/build/libdgl.a
+$(vst): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST.cpp.o $(DGL_LIB)
else
$(vst): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.o
endif
diff --git a/dpf/README.md b/dpf/README.md
index b8788fc..5dda160 100644
--- a/dpf/README.md
+++ b/dpf/README.md
@@ -28,7 +28,7 @@ List of plugins made with DPF:
- [Juice Plugins](https://github.com/DISTRHO/JuicePlugins) (work in progress)
- [ZamAudio Suite](https://github.com/zamaudio/zam-plugins)
- [DragonFly-Reverb](https://github.com/michaelwillis/dragonfly-reverb)
- - [Wolf-Shaper](https://github.com/pdesaulniers/wolf-shaper)
+ - [Wolf-Shaper](https://github.com/pdesaulniers/wolf-shaper) and [Wolf-Spectrum](https://github.com/pdesaulniers/wolf-spectrum)
- [YK Chorus](https://github.com/SpotlightKid/ykchorus)
diff --git a/dpf/dgl/Base.hpp b/dpf/dgl/Base.hpp
index 30d10e0..9037788 100644
--- a/dpf/dgl/Base.hpp
+++ b/dpf/dgl/Base.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -31,89 +31,6 @@
#define END_NAMESPACE_DGL }
#define USE_NAMESPACE_DGL using namespace DGL_NAMESPACE;
-#ifdef DISTRHO_OS_WINDOWS
-// -----------------------------------------------------------------------
-// Fix OpenGL includes for Windows, based on glfw code
-
-#ifndef APIENTRY
-# define APIENTRY __stdcall
-#endif // APIENTRY
-
-/* We need WINGDIAPI defined */
-#ifndef WINGDIAPI
-# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)
-# define WINGDIAPI __declspec(dllimport)
-# elif defined(__LCC__)
-# define WINGDIAPI __stdcall
-# else
-# define WINGDIAPI extern
-# endif
-# define DGL_WINGDIAPI_DEFINED
-#endif // WINGDIAPI
-
-/* Some files also need CALLBACK defined */
-#ifndef CALLBACK
-# if defined(_MSC_VER)
-# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
-# define CALLBACK __stdcall
-# else
-# define CALLBACK
-# endif
-# else
-# define CALLBACK __stdcall
-# endif
-# define DGL_CALLBACK_DEFINED
-#endif // CALLBACK
-
-/* Most GL/glu.h variants on Windows need wchar_t */
-#include
-
-#endif // DISTRHO_OS_WINDOWS
-
-// -----------------------------------------------------------------------
-// OpenGL includes
-
-#ifdef DISTRHO_OS_MAC
-# include
-#else
-# ifndef DISTRHO_OS_WINDOWS
-# define GL_GLEXT_PROTOTYPES
-# endif
-# include
-# include
-#endif
-
-// -----------------------------------------------------------------------
-// Missing OpenGL defines
-
-#if defined(GL_BGR_EXT) && ! defined(GL_BGR)
-# define GL_BGR GL_BGR_EXT
-#endif
-
-#if defined(GL_BGRA_EXT) && ! defined(GL_BGRA)
-# define GL_BGRA GL_BGRA_EXT
-#endif
-
-#ifndef GL_CLAMP_TO_BORDER
-# define GL_CLAMP_TO_BORDER 0x812D
-#endif
-
-#ifdef DISTRHO_OS_WINDOWS
-// -----------------------------------------------------------------------
-// Fix OpenGL includes for Windows, based on glfw code
-
-#ifdef DGL_WINGDIAPI_DEFINED
-# undef WINGDIAPI
-# undef DGL_WINGDIAPI_DEFINED
-#endif
-
-#ifdef DGL_CALLBACK_DEFINED
-# undef CALLBACK
-# undef DGL_CALLBACK_DEFINED
-#endif
-
-#endif // DISTRHO_OS_WINDOWS
-
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
@@ -172,6 +89,11 @@ enum Key {
// -----------------------------------------------------------------------
// Base DGL classes
+/**
+ Graphics context, definition depends on build type.
+ */
+struct GraphicsContext;
+
/**
Idle callback.
*/
diff --git a/dpf/dgl/Cairo.hpp b/dpf/dgl/Cairo.hpp
new file mode 100644
index 0000000..ce0c920
--- /dev/null
+++ b/dpf/dgl/Cairo.hpp
@@ -0,0 +1,40 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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.
+ */
+
+#ifndef DGL_CAIRO_HPP_INCLUDED
+#define DGL_CAIRO_HPP_INCLUDED
+
+#include "Base.hpp"
+
+#include
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+/**
+ Graphics context.
+ */
+struct GraphicsContext
+{
+ cairo_t* cairo; // FIXME proper name..
+};
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
+
+#endif
diff --git a/dpf/dgl/Color.hpp b/dpf/dgl/Color.hpp
index 2fc8c64..a874f66 100644
--- a/dpf/dgl/Color.hpp
+++ b/dpf/dgl/Color.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
diff --git a/dpf/dgl/Geometry.hpp b/dpf/dgl/Geometry.hpp
index 3dbf706..f7fe31e 100644
--- a/dpf/dgl/Geometry.hpp
+++ b/dpf/dgl/Geometry.hpp
@@ -482,6 +482,7 @@ private:
// cached values
float fTheta, fCos, fSin;
+ /** @internal */
void _draw(const bool outline);
};
@@ -516,16 +517,6 @@ public:
*/
Triangle(const Triangle& tri) noexcept;
- /**
- Draw this triangle using the current OpenGL state.
- */
- void draw();
-
- /**
- Draw lines (outline of this triangle) using the current OpenGL state.
- */
- void drawOutline();
-
/**
Return true if triangle is null (all its points are equal).
An null triangle is also invalid.
@@ -549,6 +540,16 @@ public:
*/
bool isInvalid() const noexcept;
+ /**
+ Draw this triangle using the current OpenGL state.
+ */
+ void draw();
+
+ /**
+ Draw lines (outline of this triangle) using the current OpenGL state.
+ */
+ void drawOutline();
+
Triangle& operator=(const Triangle& tri) noexcept;
bool operator==(const Triangle& tri) const noexcept;
bool operator!=(const Triangle& tri) const noexcept;
@@ -556,6 +557,7 @@ public:
private:
Point fPos1, fPos2, fPos3;
+ /** @internal */
void _draw(const bool outline);
};
@@ -740,6 +742,7 @@ private:
Point fPos;
Size fSize;
+ /** @internal */
void _draw(const bool outline);
};
diff --git a/dpf/dgl/Image.hpp b/dpf/dgl/Image.hpp
index 3df5bd8..634665f 100644
--- a/dpf/dgl/Image.hpp
+++ b/dpf/dgl/Image.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -17,14 +17,15 @@
#ifndef DGL_IMAGE_HPP_INCLUDED
#define DGL_IMAGE_HPP_INCLUDED
-#include "Geometry.hpp"
+#include "ImageBase.hpp"
+#include "OpenGL.hpp"
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
/**
- Base DGL Image class.
+ OpenGL Image class.
This is an Image class that handles raw image data in pixels.
You can init the image data on the contructor or later on by calling loadFromMemory().
@@ -35,7 +36,7 @@ START_NAMESPACE_DGL
Images are drawn on screen via 2D textures.
*/
-class Image
+class Image : public ImageBase
{
public:
/**
@@ -47,13 +48,20 @@ public:
Constructor using raw image data.
@note @a rawData must remain valid for the lifetime of this Image.
*/
- Image(const char* const rawData, const uint width, const uint height, const GLenum format = GL_BGRA, const GLenum type = GL_UNSIGNED_BYTE);
+ Image(const char* const rawData,
+ const uint width,
+ const uint height,
+ const GLenum format = GL_BGRA,
+ const GLenum type = GL_UNSIGNED_BYTE);
/**
Constructor using raw image data.
@note @a rawData must remain valid for the lifetime of this Image.
*/
- Image(const char* const rawData, const Size& size, const GLenum format = GL_BGRA, const GLenum type = GL_UNSIGNED_BYTE);
+ Image(const char* const rawData,
+ const Size& size,
+ const GLenum format = GL_BGRA,
+ const GLenum type = GL_UNSIGNED_BYTE);
/**
Constructor using another image data.
@@ -63,44 +71,26 @@ public:
/**
Destructor.
*/
- ~Image();
+ ~Image() override;
/**
Load image data from memory.
@note @a rawData must remain valid for the lifetime of this Image.
*/
- void loadFromMemory(const char* const rawData, const uint width, const uint height, const GLenum format = GL_BGRA, const GLenum type = GL_UNSIGNED_BYTE) noexcept;
+ void loadFromMemory(const char* const rawData,
+ const uint width,
+ const uint height,
+ const GLenum format = GL_BGRA,
+ const GLenum type = GL_UNSIGNED_BYTE) noexcept;
/**
Load image data from memory.
@note @a rawData must remain valid for the lifetime of this Image.
*/
- void loadFromMemory(const char* const rawData, const Size& size, const GLenum format = GL_BGRA, const GLenum type = GL_UNSIGNED_BYTE) noexcept;
-
- /**
- Check if this image is valid.
- */
- bool isValid() const noexcept;
-
- /**
- Get width.
- */
- uint getWidth() const noexcept;
-
- /**
- Get height.
- */
- uint getHeight() const noexcept;
-
- /**
- Get size.
- */
- const Size& getSize() const noexcept;
-
- /**
- Get the raw image data.
- */
- const char* getRawData() const noexcept;
+ void loadFromMemory(const char* const rawData,
+ const Size& size,
+ const GLenum format = GL_BGRA,
+ const GLenum type = GL_UNSIGNED_BYTE) noexcept;
/**
Get the image format.
@@ -113,27 +103,15 @@ public:
GLenum getType() const noexcept;
/**
- Draw this image at (0, 0) point.
- */
- void draw();
-
- /**
- Draw this image at (x, y) point.
+ TODO document this.
*/
- void drawAt(const int x, const int y);
-
- /**
- Draw this image at position @a pos.
- */
- void drawAt(const Point& pos);
-
Image& operator=(const Image& image) noexcept;
- bool operator==(const Image& image) const noexcept;
- bool operator!=(const Image& image) const noexcept;
+
+protected:
+ /** @internal */
+ void _drawAt(const Point& pos) override;
private:
- const char* fRawData;
- Size fSize;
GLenum fFormat;
GLenum fType;
GLuint fTextureId;
@@ -144,4 +122,4 @@ private:
END_NAMESPACE_DGL
-#endif // DGL_IMAGE_HPP_INCLUDED
+#endif
diff --git a/dpf/dgl/ImageBase.hpp b/dpf/dgl/ImageBase.hpp
new file mode 100644
index 0000000..0a7ee78
--- /dev/null
+++ b/dpf/dgl/ImageBase.hpp
@@ -0,0 +1,125 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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.
+ */
+
+#ifndef DGL_IMAGE_BASE_HPP_INCLUDED
+#define DGL_IMAGE_BASE_HPP_INCLUDED
+
+#include "Geometry.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+/**
+ Base DGL Image class.
+
+ This is an Image class that handles raw image data in pixels.
+ It is an abstract class that provides the common methods to build on top.
+ Cairo and OpenGL Image classes are based upon this one.
+
+ @see Image
+ */
+class ImageBase
+{
+protected:
+ /**
+ Constructor for a null Image.
+ */
+ ImageBase();
+
+ /**
+ Constructor using raw image data.
+ @note @a rawData must remain valid for the lifetime of this Image.
+ */
+ ImageBase(const char* const rawData, const uint width, const uint height);
+
+ /**
+ Constructor using raw image data.
+ @note @a rawData must remain valid for the lifetime of this Image.
+ */
+ ImageBase(const char* const rawData, const Size& size);
+
+ /**
+ Constructor using another image data.
+ */
+ ImageBase(const ImageBase& image);
+
+public:
+ /**
+ Destructor.
+ */
+ virtual ~ImageBase();
+
+ /**
+ Check if this image is valid.
+ */
+ bool isValid() const noexcept;
+
+ /**
+ Get width.
+ */
+ uint getWidth() const noexcept;
+
+ /**
+ Get height.
+ */
+ uint getHeight() const noexcept;
+
+ /**
+ Get size.
+ */
+ const Size& getSize() const noexcept;
+
+ /**
+ Get the raw image data.
+ */
+ const char* getRawData() const noexcept;
+
+ /**
+ Draw this image at (0, 0) point.
+ */
+ void draw();
+
+ /**
+ Draw this image at (x, y) point.
+ */
+ void drawAt(const int x, const int y);
+
+ /**
+ Draw this image at position @a pos.
+ */
+ void drawAt(const Point& pos);
+
+ /**
+ TODO document this.
+ */
+ ImageBase& operator=(const ImageBase& image) noexcept;
+ bool operator==(const ImageBase& image) const noexcept;
+ bool operator!=(const ImageBase& image) const noexcept;
+
+protected:
+ /** @internal */
+ virtual void _drawAt(const Point& pos) = 0;
+
+ const char* fRawData;
+ Size fSize;
+};
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
+
+#endif // DGL_IMAGE_HPP_INCLUDED
diff --git a/dpf/dgl/Makefile b/dpf/dgl/Makefile
index b0b4f41..9d6f31a 100644
--- a/dpf/dgl/Makefile
+++ b/dpf/dgl/Makefile
@@ -9,7 +9,7 @@ include ../Makefile.base.mk
# ---------------------------------------------------------------------------------------------------------------------
BUILD_C_FLAGS += $(DGL_FLAGS) -I. -Isrc
-BUILD_CXX_FLAGS += $(DGL_FLAGS) -I. -Isrc
+BUILD_CXX_FLAGS += $(DGL_FLAGS) -I. -Isrc -DDONT_SET_USING_DGL_NAMESPACE -Wno-unused-parameter
LINK_FLAGS += $(DGL_LIBS)
# ifneq ($(MACOS_OLD),true)
@@ -19,36 +19,78 @@ LINK_FLAGS += $(DGL_LIBS)
# ---------------------------------------------------------------------------------------------------------------------
-OBJS = \
+OBJS_common = \
../build/dgl/Application.cpp.o \
../build/dgl/Color.cpp.o \
../build/dgl/Geometry.cpp.o \
- ../build/dgl/Image.cpp.o \
- ../build/dgl/ImageWidgets.cpp.o \
- ../build/dgl/NanoVG.cpp.o \
+ ../build/dgl/ImageBase.cpp.o \
../build/dgl/Resources.cpp.o \
../build/dgl/Widget.cpp.o
+# TODO: ImageWidgets.cpp
+
+# ---------------------------------------------------------------------------------------------------------------------
+
+OBJS_cairo = $(OBJS_common) \
+ ../build/dgl/Cairo.cpp.cairo.o \
+ ../build/dgl/WidgetPrivateData.cpp.cairo.o
+
+ifeq ($(MACOS),true)
+OBJS_cairo += ../build/dgl/Window.mm.cairo.o
+else
+OBJS_cairo += ../build/dgl/Window.cpp.cairo.o
+endif
+
+# ---------------------------------------------------------------------------------------------------------------------
+
+OBJS_opengl = $(OBJS_common) \
+ ../build/dgl/OpenGL.cpp.opengl.o \
+ ../build/dgl/Image.cpp.opengl.o \
+ ../build/dgl/ImageWidgets.cpp.opengl.o \
+ ../build/dgl/NanoVG.cpp.opengl.o \
+ ../build/dgl/WidgetPrivateData.cpp.opengl.o
+
ifeq ($(MACOS),true)
-OBJS += ../build/dgl/Window.mm.o
+OBJS_opengl += ../build/dgl/Window.mm.opengl.o
else
-OBJS += ../build/dgl/Window.cpp.o
+OBJS_opengl += ../build/dgl/Window.cpp.opengl.o
endif
-TARGET = ../build/libdgl.a
+# ---------------------------------------------------------------------------------------------------------------------
+
+ifeq ($(HAVE_CAIRO),true)
+TARGETS += ../build/libdgl-cairo.a
+endif
+
+ifeq ($(HAVE_OPENGL),true)
+TARGETS += ../build/libdgl-opengl.a
+# Compat name, to be removed soon
+TARGETS += ../build/libdgl.a
+endif
# ---------------------------------------------------------------------------------------------------------------------
-all: $(TARGET)
+all: $(TARGETS)
# ---------------------------------------------------------------------------------------------------------------------
-../build/libdgl.a: $(OBJS)
+../build/libdgl-cairo.a: $(OBJS_cairo)
+ -@mkdir -p ../build
+ @echo "Creating libdgl-cairo.a"
+ @rm -f $@
+ @$(AR) crs $@ $^
+
+../build/libdgl-opengl.a: $(OBJS_opengl)
-@mkdir -p ../build
- @echo "Creating libdgl.a"
+ @echo "Creating libdgl-opengl.a"
@rm -f $@
@$(AR) crs $@ $^
+# Compat name, to be removed soon
+../build/libdgl.a: ../build/libdgl-opengl.a
+ @echo "Symlinking libdgl.a"
+ @ln -sf $< $@
+
# ---------------------------------------------------------------------------------------------------------------------
../build/dgl/%.c.o: src/%.c
@@ -61,26 +103,52 @@ all: $(TARGET)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@
-../build/dgl/Window.cpp.o: src/Window.cpp src/sofd/* src/pugl/*
+# ---------------------------------------------------------------------------------------------------------------------
+
+../build/dgl/%.cpp.cairo.o: src/%.cpp
-@mkdir -p ../build/dgl
- @echo "Compiling $<"
- @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@
+ @echo "Compiling $< (Cairo variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_CAIRO -c -o $@
-../build/dgl/Window.mm.o: src/Window.cpp src/sofd/* src/pugl/*
+../build/dgl/Window.cpp.cairo.o: src/Window.cpp src/sofd/* src/pugl/*
-@mkdir -p ../build/dgl
- @echo "Compiling $<"
- @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@
+ @echo "Compiling $< (Cairo variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_CAIRO -c -o $@
+
+../build/dgl/Window.mm.cairo.o: src/Window.cpp src/sofd/* src/pugl/*
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (Cairo variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_CAIRO -ObjC++ -c -o $@
+
+# ---------------------------------------------------------------------------------------------------------------------
+
+../build/dgl/%.cpp.opengl.o: src/%.cpp
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (OpenGL variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_OPENGL -c -o $@
+
+../build/dgl/Window.cpp.opengl.o: src/Window.cpp src/sofd/* src/pugl/*
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (OpenGL variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_OPENGL -c -o $@
+
+../build/dgl/Window.mm.opengl.o: src/Window.cpp src/sofd/* src/pugl/*
+ -@mkdir -p ../build/dgl
+ @echo "Compiling $< (OpenGL variant)"
+ @$(CXX) $< $(BUILD_CXX_FLAGS) -DDGL_OPENGL -ObjC++ -c -o $@
# ---------------------------------------------------------------------------------------------------------------------
clean:
- rm -rf ../build/dgl ../build/libdgl.*
+ rm -rf ../build/dgl ../build/libdgl*.*
debug:
$(MAKE) DEBUG=true
# ---------------------------------------------------------------------------------------------------------------------
--include $(OBJS:%.o=%.d)
+-include $(OBJS_common:%.o=%.d)
+-include $(OBJS_cairo:%.o=%.d)
+-include $(OBJS_opengl:%.o=%.d)
# ---------------------------------------------------------------------------------------------------------------------
diff --git a/dpf/dgl/NanoVG.hpp b/dpf/dgl/NanoVG.hpp
index e94da10..ea07df2 100644
--- a/dpf/dgl/NanoVG.hpp
+++ b/dpf/dgl/NanoVG.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -18,6 +18,7 @@
#define DGL_NANO_WIDGET_HPP_INCLUDED
#include "Color.hpp"
+#include "OpenGL.hpp"
#include "Widget.hpp"
#ifndef DGL_NO_SHARED_RESOURCES
diff --git a/dpf/dgl/OpenGL.hpp b/dpf/dgl/OpenGL.hpp
new file mode 100644
index 0000000..5466161
--- /dev/null
+++ b/dpf/dgl/OpenGL.hpp
@@ -0,0 +1,121 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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.
+ */
+
+#ifndef DGL_OPENGL_HPP_INCLUDED
+#define DGL_OPENGL_HPP_INCLUDED
+
+#include "ImageBase.hpp"
+
+// -----------------------------------------------------------------------
+// Fix OpenGL includes for Windows, based on glfw code (part 1)
+
+#undef DGL_CALLBACK_DEFINED
+#undef DGL_WINGDIAPI_DEFINED
+
+#ifdef DISTRHO_OS_WINDOWS
+
+#ifndef APIENTRY
+# define APIENTRY __stdcall
+#endif // APIENTRY
+
+/* We need WINGDIAPI defined */
+#ifndef WINGDIAPI
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)
+# define WINGDIAPI __declspec(dllimport)
+# elif defined(__LCC__)
+# define WINGDIAPI __stdcall
+# else
+# define WINGDIAPI extern
+# endif
+# define DGL_WINGDIAPI_DEFINED
+#endif // WINGDIAPI
+
+/* Some files also need CALLBACK defined */
+#ifndef CALLBACK
+# if defined(_MSC_VER)
+# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
+# define CALLBACK __stdcall
+# else
+# define CALLBACK
+# endif
+# else
+# define CALLBACK __stdcall
+# endif
+# define DGL_CALLBACK_DEFINED
+#endif // CALLBACK
+
+/* Most GL/glu.h variants on Windows need wchar_t */
+#include
+
+#endif // DISTRHO_OS_WINDOWS
+
+// -----------------------------------------------------------------------
+// OpenGL includes
+
+#ifdef DISTRHO_OS_MAC
+# include
+#else
+# ifndef DISTRHO_OS_WINDOWS
+# define GL_GLEXT_PROTOTYPES
+# endif
+# include
+# include
+#endif
+
+// -----------------------------------------------------------------------
+// Missing OpenGL defines
+
+#if defined(GL_BGR_EXT) && !defined(GL_BGR)
+# define GL_BGR GL_BGR_EXT
+#endif
+
+#if defined(GL_BGRA_EXT) && !defined(GL_BGRA)
+# define GL_BGRA GL_BGRA_EXT
+#endif
+
+#ifndef GL_CLAMP_TO_BORDER
+# define GL_CLAMP_TO_BORDER 0x812D
+#endif
+
+// -----------------------------------------------------------------------
+// Fix OpenGL includes for Windows, based on glfw code (part 2)
+
+#ifdef DGL_CALLBACK_DEFINED
+# undef CALLBACK
+# undef DGL_CALLBACK_DEFINED
+#endif
+
+#ifdef DGL_WINGDIAPI_DEFINED
+# undef WINGDIAPI
+# undef DGL_WINGDIAPI_DEFINED
+#endif
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+/**
+ Graphics context.
+ */
+struct GraphicsContext
+{
+};
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
+
+#endif
diff --git a/dpf/dgl/Widget.hpp b/dpf/dgl/Widget.hpp
index 73d2d6e..f8d7139 100644
--- a/dpf/dgl/Widget.hpp
+++ b/dpf/dgl/Widget.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
diff --git a/dpf/dgl/Window.hpp b/dpf/dgl/Window.hpp
index 465bb1c..931177e 100644
--- a/dpf/dgl/Window.hpp
+++ b/dpf/dgl/Window.hpp
@@ -77,7 +77,7 @@ public:
explicit Window(Application& app);
explicit Window(Application& app, Window& parent);
- explicit Window(Application& app, intptr_t parentId, bool resizable);
+ explicit Window(Application& app, intptr_t parentId, double scaling, bool resizable);
virtual ~Window();
void show();
@@ -113,7 +113,6 @@ public:
void setTransientWinId(uintptr_t winId);
double getScaling() const noexcept;
- void setScaling(double scaling) noexcept;
bool getIgnoringKeyRepeat() const noexcept;
void setIgnoringKeyRepeat(bool ignore) noexcept;
@@ -121,6 +120,8 @@ public:
Application& getApp() const noexcept;
intptr_t getWindowId() const noexcept;
+ const GraphicsContext& getGraphicsContext() const noexcept;
+
void addIdleCallback(IdleCallback* const callback);
void removeIdleCallback(IdleCallback* const callback);
@@ -134,6 +135,9 @@ protected:
virtual void fileBrowserSelected(const char* filename);
#endif
+ // internal
+ void _setAutoScaling(double scaling) noexcept;
+
private:
struct PrivateData;
PrivateData* const pData;
diff --git a/dpf/dgl/src/Cairo.cpp b/dpf/dgl/src/Cairo.cpp
new file mode 100644
index 0000000..2c9e42e
--- /dev/null
+++ b/dpf/dgl/src/Cairo.cpp
@@ -0,0 +1,27 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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 "../Base.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+// nothing here yet
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/Color.cpp b/dpf/dgl/src/Color.cpp
index 2ea9819..3fc570c 100644
--- a/dpf/dgl/src/Color.cpp
+++ b/dpf/dgl/src/Color.cpp
@@ -16,12 +16,27 @@
#include "../Color.hpp"
+#ifndef HAVE_DCAIRO
#include "nanovg/nanovg.h"
+#endif
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
+static float computeHue(float h, float m1, float m2)
+{
+ if (h < 0) h += 1;
+ if (h > 1) h -= 1;
+ if (h < 1.0f/6.0f)
+ return m1 + (m2 - m1) * h * 6.0f;
+ if (h < 3.0f/6.0f)
+ return m2;
+ if (h < 4.0f/6.0f)
+ return m1 + (m2 - m1) * (2.0f/3.0f - h) * 6.0f;
+ return m1;
+}
+
static void fixRange(float& value)
{
/**/ if (value < 0.0f)
@@ -105,7 +120,20 @@ Color::Color(const Color& color1, const Color& color2, float u) noexcept
Color Color::fromHSL(float hue, float saturation, float lightness, float alpha)
{
- return nvgHSLA(hue, saturation, lightness, static_cast(getFixedRange(alpha)*255.0f));
+ float m1, m2;
+ Color col;
+ hue = fmodf(hue, 1.0f);
+ if (hue < 0.0f) hue += 1.0f;
+ fixRange(saturation);
+ fixRange(lightness);
+ m2 = lightness <= 0.5f ? (lightness * (1 + saturation)) : (lightness + saturation - lightness * saturation);
+ m1 = 2 * lightness - m2;
+ col.red = computeHue(hue + 1.0f/3.0f, m1, m2);
+ col.green = computeHue(hue, m1, m2);
+ col.blue = computeHue(hue - 1.0f/3.0f, m1, m2);
+ col.alpha = alpha;
+ col.fixBounds();
+ return col;
}
Color Color::fromHTML(const char* rgb, float alpha)
@@ -224,22 +252,4 @@ void Color::fixBounds() noexcept
// -----------------------------------------------------------------------
-Color::Color(const NVGcolor& c) noexcept
- : red(c.r), green(c.g), blue(c.b), alpha(c.a)
-{
- fixBounds();
-}
-
-Color::operator NVGcolor() const noexcept
-{
- NVGcolor nc;
- nc.r = red;
- nc.g = green;
- nc.b = blue;
- nc.a = alpha;
- return nc;
-}
-
-// -----------------------------------------------------------------------
-
END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/Geometry.cpp b/dpf/dgl/src/Geometry.cpp
index c76809d..d133985 100644
--- a/dpf/dgl/src/Geometry.cpp
+++ b/dpf/dgl/src/Geometry.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -441,21 +441,6 @@ void Line::moveBy(const Point& pos) noexcept
fPosEnd.moveBy(pos);
}
-template
-void Line::draw()
-{
- DISTRHO_SAFE_ASSERT_RETURN(fPosStart != fPosEnd,);
-
- glBegin(GL_LINES);
-
- {
- glVertex2d(fPosStart.fX, fPosStart.fY);
- glVertex2d(fPosEnd.fX, fPosEnd.fY);
- }
-
- glEnd();
-}
-
template
bool Line::isNull() const noexcept
{
@@ -650,27 +635,6 @@ bool Circle::operator!=(const Circle& cir) const noexcept
return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments);
}
-template
-void Circle::_draw(const bool outline)
-{
- DISTRHO_SAFE_ASSERT_RETURN(fNumSegments >= 3 && fSize > 0.0f,);
-
- double t, x = fSize, y = 0.0;
-
- glBegin(outline ? GL_LINE_LOOP : GL_POLYGON);
-
- for (uint i=0; i::Triangle(const Triangle& tri) noexcept
fPos2(tri.fPos2),
fPos3(tri.fPos3) {}
-template
-void Triangle::draw()
-{
- _draw(false);
-}
-
-template
-void Triangle::drawOutline()
-{
- _draw(true);
-}
-
template
bool Triangle::isNull() const noexcept
{
@@ -734,6 +686,18 @@ bool Triangle::isInvalid() const noexcept
return fPos1 == fPos2 || fPos1 == fPos3;
}
+template
+void Triangle::draw()
+{
+ _draw(false);
+}
+
+template
+void Triangle::drawOutline()
+{
+ _draw(true);
+}
+
template
Triangle& Triangle::operator=(const Triangle& tri) noexcept
{
@@ -755,22 +719,6 @@ bool Triangle::operator!=(const Triangle& tri) const noexcept
return (fPos1 != tri.fPos1 || fPos2 != tri.fPos2 || fPos3 != tri.fPos3);
}
-template
-void Triangle::_draw(const bool outline)
-{
- DISTRHO_SAFE_ASSERT_RETURN(fPos1 != fPos2 && fPos1 != fPos3,);
-
- glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES);
-
- {
- glVertex2d(fPos1.fX, fPos1.fY);
- glVertex2d(fPos2.fX, fPos2.fY);
- glVertex2d(fPos3.fX, fPos3.fY);
- }
-
- glEnd();
-}
-
// -----------------------------------------------------------------------
// Rectangle
@@ -998,30 +946,6 @@ bool Rectangle::operator!=(const Rectangle& rect) const noexcept
return (fPos != rect.fPos || fSize != rect.fSize);
}
-template
-void Rectangle::_draw(const bool outline)
-{
- DISTRHO_SAFE_ASSERT_RETURN(fSize.isValid(),);
-
- glBegin(outline ? GL_LINE_LOOP : GL_QUADS);
-
- {
- glTexCoord2f(0.0f, 0.0f);
- glVertex2d(fPos.fX, fPos.fY);
-
- glTexCoord2f(1.0f, 0.0f);
- glVertex2d(fPos.fX+fSize.fWidth, fPos.fY);
-
- glTexCoord2f(1.0f, 1.0f);
- glVertex2d(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight);
-
- glTexCoord2f(0.0f, 1.0f);
- glVertex2d(fPos.fX, fPos.fY+fSize.fHeight);
- }
-
- glEnd();
-}
-
// -----------------------------------------------------------------------
// Possible template data types
diff --git a/dpf/dgl/src/Image.cpp b/dpf/dgl/src/Image.cpp
index b79b8d4..90596fe 100644
--- a/dpf/dgl/src/Image.cpp
+++ b/dpf/dgl/src/Image.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -21,8 +21,7 @@ START_NAMESPACE_DGL
// -----------------------------------------------------------------------
Image::Image()
- : fRawData(nullptr),
- fSize(0, 0),
+ : ImageBase(),
fFormat(0),
fType(0),
fTextureId(0),
@@ -31,20 +30,18 @@ Image::Image()
glGenTextures(1, &fTextureId);
}
-Image::Image(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type)
- : fRawData(rawData),
- fSize(width, height),
- fFormat(format),
- fType(type),
+Image::Image(const Image& image)
+ : ImageBase(image),
+ fFormat(image.fFormat),
+ fType(image.fType),
fTextureId(0),
fIsReady(false)
{
glGenTextures(1, &fTextureId);
}
-Image::Image(const char* const rawData, const Size& size, const GLenum format, const GLenum type)
- : fRawData(rawData),
- fSize(size),
+Image::Image(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type)
+ : ImageBase(rawData, width, height),
fFormat(format),
fType(type),
fTextureId(0),
@@ -53,11 +50,10 @@ Image::Image(const char* const rawData, const Size& size, const GLenum for
glGenTextures(1, &fTextureId);
}
-Image::Image(const Image& image)
- : fRawData(image.fRawData),
- fSize(image.fSize),
- fFormat(image.fFormat),
- fType(image.fType),
+Image::Image(const char* const rawData, const Size& size, const GLenum format, const GLenum type)
+ : ImageBase(rawData, size),
+ fFormat(format),
+ fType(type),
fTextureId(0),
fIsReady(false)
{
@@ -75,12 +71,19 @@ Image::~Image()
}
}
-void Image::loadFromMemory(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type) noexcept
+void Image::loadFromMemory(const char* const rawData,
+ const uint width,
+ const uint height,
+ const GLenum format,
+ const GLenum type) noexcept
{
loadFromMemory(rawData, Size(width, height), format, type);
}
-void Image::loadFromMemory(const char* const rawData, const Size& size, const GLenum format, const GLenum type) noexcept
+void Image::loadFromMemory(const char* const rawData,
+ const Size& size,
+ const GLenum format,
+ const GLenum type) noexcept
{
fRawData = rawData;
fSize = size;
@@ -89,31 +92,6 @@ void Image::loadFromMemory(const char* const rawData, const Size& size, co
fIsReady = false;
}
-bool Image::isValid() const noexcept
-{
- return (fRawData != nullptr && fSize.getWidth() > 0 && fSize.getHeight() > 0);
-}
-
-uint Image::getWidth() const noexcept
-{
- return fSize.getWidth();
-}
-
-uint Image::getHeight() const noexcept
-{
- return fSize.getHeight();
-}
-
-const Size& Image::getSize() const noexcept
-{
- return fSize;
-}
-
-const char* Image::getRawData() const noexcept
-{
- return fRawData;
-}
-
GLenum Image::getFormat() const noexcept
{
return fFormat;
@@ -124,17 +102,17 @@ GLenum Image::getType() const noexcept
return fType;
}
-void Image::draw()
-{
- drawAt(0, 0);
-}
-
-void Image::drawAt(const int x, const int y)
+Image& Image::operator=(const Image& image) noexcept
{
- drawAt(Point(x, y));
+ fRawData = image.fRawData;
+ fSize = image.fSize;
+ fFormat = image.fFormat;
+ fType = image.fType;
+ fIsReady = false;
+ return *this;
}
-void Image::drawAt(const Point& pos)
+void Image::_drawAt(const Point& pos)
{
if (fTextureId == 0 || ! isValid())
return;
@@ -169,26 +147,4 @@ void Image::drawAt(const Point& pos)
// -----------------------------------------------------------------------
-Image& Image::operator=(const Image& image) noexcept
-{
- fRawData = image.fRawData;
- fSize = image.fSize;
- fFormat = image.fFormat;
- fType = image.fType;
- fIsReady = false;
- return *this;
-}
-
-bool Image::operator==(const Image& image) const noexcept
-{
- return (fRawData == image.fRawData && fSize == image.fSize);
-}
-
-bool Image::operator!=(const Image& image) const noexcept
-{
- return !operator==(image);
-}
-
-// -----------------------------------------------------------------------
-
END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/ImageBase.cpp b/dpf/dgl/src/ImageBase.cpp
new file mode 100644
index 0000000..b5dfbb9
--- /dev/null
+++ b/dpf/dgl/src/ImageBase.cpp
@@ -0,0 +1,106 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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 "../ImageBase.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+ImageBase::ImageBase()
+ : fRawData(nullptr),
+ fSize(0, 0) {}
+
+ImageBase::ImageBase(const char* const rawData, const uint width, const uint height)
+ : fRawData(rawData),
+ fSize(width, height) {}
+
+ImageBase::ImageBase(const char* const rawData, const Size& size)
+ : fRawData(rawData),
+ fSize(size) {}
+
+ImageBase::ImageBase(const ImageBase& image)
+ : fRawData(image.fRawData),
+ fSize(image.fSize) {}
+
+ImageBase::~ImageBase() {}
+
+// -----------------------------------------------------------------------
+
+bool ImageBase::isValid() const noexcept
+{
+ return (fRawData != nullptr && fSize.isValid());
+}
+
+uint ImageBase::getWidth() const noexcept
+{
+ return fSize.getWidth();
+}
+
+uint ImageBase::getHeight() const noexcept
+{
+ return fSize.getHeight();
+}
+
+const Size& ImageBase::getSize() const noexcept
+{
+ return fSize;
+}
+
+const char* ImageBase::getRawData() const noexcept
+{
+ return fRawData;
+}
+
+// -----------------------------------------------------------------------
+
+void ImageBase::draw()
+{
+ _drawAt(Point());
+}
+
+void ImageBase::drawAt(const int x, const int y)
+{
+ _drawAt(Point(x, y));
+}
+
+void ImageBase::drawAt(const Point& pos)
+{
+ _drawAt(pos);
+}
+
+// -----------------------------------------------------------------------
+
+ImageBase& ImageBase::operator=(const ImageBase& image) noexcept
+{
+ fRawData = image.fRawData;
+ fSize = image.fSize;
+ return *this;
+}
+
+bool ImageBase::operator==(const ImageBase& image) const noexcept
+{
+ return (fRawData == image.fRawData && fSize == image.fSize);
+}
+
+bool ImageBase::operator!=(const ImageBase& image) const noexcept
+{
+ return !operator==(image);
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/ImageWidgets.cpp b/dpf/dgl/src/ImageWidgets.cpp
index 12f952e..71276e3 100644
--- a/dpf/dgl/src/ImageWidgets.cpp
+++ b/dpf/dgl/src/ImageWidgets.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -14,9 +14,13 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "../Image.hpp"
#include "Common.hpp"
#include "WidgetPrivateData.hpp"
+// FIXME make this code more generic and move GL specific bits to OpenGL.cpp
+#include "../OpenGL.hpp"
+
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
diff --git a/dpf/dgl/src/NanoVG.cpp b/dpf/dgl/src/NanoVG.cpp
index 3c29222..06fc49f 100644
--- a/dpf/dgl/src/NanoVG.cpp
+++ b/dpf/dgl/src/NanoVG.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2018 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -124,6 +124,25 @@ DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer)
START_NAMESPACE_DGL
+// -----------------------------------------------------------------------
+// DGL Color class conversion
+
+Color::Color(const NVGcolor& c) noexcept
+ : red(c.r), green(c.g), blue(c.b), alpha(c.a)
+{
+ fixBounds();
+}
+
+Color::operator NVGcolor() const noexcept
+{
+ NVGcolor nc;
+ nc.r = red;
+ nc.g = green;
+ nc.b = blue;
+ nc.a = alpha;
+ return nc;
+}
+
// -----------------------------------------------------------------------
// NanoImage
diff --git a/dpf/dgl/src/OpenGL.cpp b/dpf/dgl/src/OpenGL.cpp
new file mode 100644
index 0000000..25a3861
--- /dev/null
+++ b/dpf/dgl/src/OpenGL.cpp
@@ -0,0 +1,157 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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 "../Geometry.hpp"
+#include "../OpenGL.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+// Line
+
+template
+void Line::draw()
+{
+ DISTRHO_SAFE_ASSERT_RETURN(fPosStart != fPosEnd,);
+
+ glBegin(GL_LINES);
+
+ {
+ glVertex2d(fPosStart.fX, fPosStart.fY);
+ glVertex2d(fPosEnd.fX, fPosEnd.fY);
+ }
+
+ glEnd();
+}
+
+// -----------------------------------------------------------------------
+// Circle
+
+template
+void Circle::_draw(const bool outline)
+{
+ DISTRHO_SAFE_ASSERT_RETURN(fNumSegments >= 3 && fSize > 0.0f,);
+
+ double t, x = fSize, y = 0.0;
+
+ glBegin(outline ? GL_LINE_LOOP : GL_POLYGON);
+
+ for (uint i=0; i
+void Triangle::_draw(const bool outline)
+{
+ DISTRHO_SAFE_ASSERT_RETURN(fPos1 != fPos2 && fPos1 != fPos3,);
+
+ glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES);
+
+ {
+ glVertex2d(fPos1.fX, fPos1.fY);
+ glVertex2d(fPos2.fX, fPos2.fY);
+ glVertex2d(fPos3.fX, fPos3.fY);
+ }
+
+ glEnd();
+}
+
+// -----------------------------------------------------------------------
+// Rectangle
+
+template
+void Rectangle::_draw(const bool outline)
+{
+ DISTRHO_SAFE_ASSERT_RETURN(fSize.isValid(),);
+
+ glBegin(outline ? GL_LINE_LOOP : GL_QUADS);
+
+ {
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2d(fPos.fX, fPos.fY);
+
+ glTexCoord2f(1.0f, 0.0f);
+ glVertex2d(fPos.fX+fSize.fWidth, fPos.fY);
+
+ glTexCoord2f(1.0f, 1.0f);
+ glVertex2d(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight);
+
+ glTexCoord2f(0.0f, 1.0f);
+ glVertex2d(fPos.fX, fPos.fY+fSize.fHeight);
+ }
+
+ glEnd();
+}
+
+// -----------------------------------------------------------------------
+// Possible template data types
+
+template class Point;
+template class Point;
+template class Point;
+template class Point;
+template class Point;
+template class Point;
+
+template class Size;
+template class Size;
+template class Size;
+template class Size;
+template class Size;
+template class Size;
+
+template class Line;
+template class Line;
+template class Line;
+template class Line;
+template class Line;
+template class Line;
+
+template class Circle;
+template class Circle;
+template class Circle;
+template class Circle;
+template class Circle;
+template class Circle;
+
+template class Triangle;
+template class Triangle;
+template class Triangle;
+template class Triangle;
+template class Triangle;
+template class Triangle;
+
+template class Rectangle;
+template class Rectangle;
+template class Rectangle;
+template class Rectangle;
+template class Rectangle;
+template class Rectangle;
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/Widget.cpp b/dpf/dgl/src/Widget.cpp
index d200fb4..4ef69b8 100644
--- a/dpf/dgl/src/Widget.cpp
+++ b/dpf/dgl/src/Widget.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2016 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
diff --git a/dpf/dgl/src/WidgetPrivateData.cpp b/dpf/dgl/src/WidgetPrivateData.cpp
new file mode 100644
index 0000000..cef082b
--- /dev/null
+++ b/dpf/dgl/src/WidgetPrivateData.cpp
@@ -0,0 +1,107 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 Filipe Coelho
+ *
+ * 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 "WidgetPrivateData.hpp"
+
+#ifdef DGL_CAIRO
+# include "../Cairo.hpp"
+#endif
+#ifdef DGL_OPENGL
+# include "../OpenGL.hpp"
+#endif
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+
+void Widget::PrivateData::display(const uint width,
+ const uint height,
+ const double scaling,
+ const bool renderingSubWidget)
+{
+ if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible)
+ return;
+
+#ifdef DGL_OPENGL
+ bool needsDisableScissor = false;
+
+ // reset color
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ if (needsFullViewport || (absolutePos.isZero() && size == Size(width, height)))
+ {
+ // full viewport size
+ glViewport(0,
+ -(height * scaling - height),
+ width * scaling,
+ height * scaling);
+ }
+ else if (needsScaling)
+ {
+ // limit viewport to widget bounds
+ glViewport(absolutePos.getX(),
+ height - self->getHeight() - absolutePos.getY(),
+ self->getWidth(),
+ self->getHeight());
+ }
+ else
+ {
+ // only set viewport pos
+ glViewport(absolutePos.getX() * scaling,
+ -std::round((height * scaling - height) + (absolutePos.getY() * scaling)),
+ std::round(width * scaling),
+ std::round(height * scaling));
+
+ // then cut the outer bounds
+ glScissor(absolutePos.getX() * scaling,
+ height - std::round((self->getHeight() + absolutePos.getY()) * scaling),
+ std::round(self->getWidth() * scaling),
+ std::round(self->getHeight() * scaling));
+
+ glEnable(GL_SCISSOR_TEST);
+ needsDisableScissor = true;
+ }
+#endif
+
+#ifdef DGL_CAIRO
+ cairo_t* cr = parent.getGraphicsContext().cairo;
+ cairo_matrix_t matrix;
+ cairo_get_matrix(cr, &matrix);
+ cairo_translate(cr, absolutePos.getX(), absolutePos.getY());
+ // TODO: scaling and cropping
+#endif
+
+ // display widget
+ self->onDisplay();
+
+#ifdef DGL_CAIRO
+ cairo_set_matrix(cr, &matrix);
+#endif
+
+#ifdef DGL_OPENGL
+ if (needsDisableScissor)
+ {
+ glDisable(GL_SCISSOR_TEST);
+ needsDisableScissor = false;
+ }
+#endif
+
+ displaySubWidgets(width, height, scaling);
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
diff --git a/dpf/dgl/src/WidgetPrivateData.hpp b/dpf/dgl/src/WidgetPrivateData.hpp
index 5dbe2ac..f48a33b 100644
--- a/dpf/dgl/src/WidgetPrivateData.hpp
+++ b/dpf/dgl/src/WidgetPrivateData.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2018 Filipe Coelho
+ * Copyright (C) 2012-2019 Filipe Coelho
*
* 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
@@ -63,61 +63,8 @@ struct Widget::PrivateData {
subWidgets.clear();
}
- void display(const uint width, const uint height, const double scaling, const bool renderingSubWidget)
- {
- if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible)
- return;
-
- bool needsDisableScissor = false;
-
- // reset color
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- if (needsFullViewport || (absolutePos.isZero() && size == Size(width, height)))
- {
- // full viewport size
- glViewport(0,
- -(height * scaling - height),
- width * scaling,
- height * scaling);
- }
- else if (needsScaling)
- {
- // limit viewport to widget bounds
- glViewport(absolutePos.getX(),
- height - self->getHeight() - absolutePos.getY(),
- self->getWidth(),
- self->getHeight());
- }
- else
- {
- // only set viewport pos
- glViewport(absolutePos.getX() * scaling,
- -std::round((height * scaling - height) + (absolutePos.getY() * scaling)),
- std::round(width * scaling),
- std::round(height * scaling));
-
- // then cut the outer bounds
- glScissor(absolutePos.getX() * scaling,
- height - std::round((self->getHeight() + absolutePos.getY()) * scaling),
- std::round(self->getWidth() * scaling),
- std::round(self->getHeight() * scaling));
-
- glEnable(GL_SCISSOR_TEST);
- needsDisableScissor = true;
- }
-
- // display widget
- self->onDisplay();
-
- if (needsDisableScissor)
- {
- glDisable(GL_SCISSOR_TEST);
- needsDisableScissor = false;
- }
-
- displaySubWidgets(width, height, scaling);
- }
+ // display function is different depending on build type
+ void display(const uint width, const uint height, const double scaling, const bool renderingSubWidget);
void displaySubWidgets(const uint width, const uint height, const double scaling)
{
diff --git a/dpf/dgl/src/Window.cpp b/dpf/dgl/src/Window.cpp
index 7da52c7..bb9db16 100644
--- a/dpf/dgl/src/Window.cpp
+++ b/dpf/dgl/src/Window.cpp
@@ -19,6 +19,15 @@
#include "../Base.hpp"
+#ifdef DGL_CAIRO
+# define PUGL_CAIRO
+# include "../Cairo.hpp"
+#endif
+#ifdef DGL_OPENGL
+# define PUGL_OPENGL
+# include "../OpenGL.hpp"
+#endif
+
#include "pugl/pugl.h"
#if defined(__GNUC__) && (__GNUC__ >= 7)
@@ -84,6 +93,7 @@ struct Window::PrivateData {
fWidth(1),
fHeight(1),
fScaling(1.0),
+ fAutoScaling(1.0),
fTitle(nullptr),
fWidgets(),
fModal(),
@@ -115,6 +125,7 @@ struct Window::PrivateData {
fWidth(1),
fHeight(1),
fScaling(1.0),
+ fAutoScaling(1.0),
fTitle(nullptr),
fWidgets(),
fModal(parent.pData),
@@ -147,7 +158,7 @@ struct Window::PrivateData {
#endif
}
- PrivateData(Application& app, Window* const self, const intptr_t parentId, const bool resizable)
+ PrivateData(Application& app, Window* const self, const intptr_t parentId, const double scaling, const bool resizable)
: fApp(app),
fSelf(self),
fView(puglInit()),
@@ -157,7 +168,8 @@ struct Window::PrivateData {
fUsingEmbed(parentId != 0),
fWidth(1),
fHeight(1),
- fScaling(1.0),
+ fScaling(scaling),
+ fAutoScaling(1.0),
fTitle(nullptr),
fWidgets(),
fModal(),
@@ -222,11 +234,12 @@ struct Window::PrivateData {
puglCreateWindow(fView, nullptr);
PuglInternals* impl = fView->impl;
+
#if defined(DISTRHO_OS_WINDOWS)
hwnd = impl->hwnd;
DISTRHO_SAFE_ASSERT(hwnd != 0);
#elif defined(DISTRHO_OS_MAC)
- mView = impl->glview;
+ mView = impl->view;
mWindow = impl->window;
DISTRHO_SAFE_ASSERT(mView != nullptr);
if (fUsingEmbed) {
@@ -555,6 +568,7 @@ struct Window::PrivateData {
void setGeometryConstraints(uint width, uint height, bool aspect)
{
+ // Did you forget to set DISTRHO_UI_USER_RESIZABLE ?
DISTRHO_SAFE_ASSERT_RETURN(fResizable,);
fView->min_width = width;
@@ -701,11 +715,11 @@ struct Window::PrivateData {
return fScaling;
}
- void setScaling(double scaling) noexcept
+ void setAutoScaling(const double scaling) noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,);
- fScaling = scaling;
+ fAutoScaling = scaling;
}
// -------------------------------------------------------------------
@@ -773,7 +787,7 @@ struct Window::PrivateData {
FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
- widget->pData->display(fWidth, fHeight, fScaling, false);
+ widget->pData->display(fWidth, fHeight, fAutoScaling, false);
}
fSelf->onDisplayAfter();
@@ -843,8 +857,8 @@ struct Window::PrivateData {
if (fModal.childFocus != nullptr)
return fModal.childFocus->focus();
- x /= fScaling;
- y /= fScaling;
+ x /= fAutoScaling;
+ y /= fAutoScaling;
Widget::MouseEvent ev;
ev.button = button;
@@ -870,8 +884,8 @@ struct Window::PrivateData {
if (fModal.childFocus != nullptr)
return;
- x /= fScaling;
- y /= fScaling;
+ x /= fAutoScaling;
+ y /= fAutoScaling;
Widget::MotionEvent ev;
ev.mod = static_cast(puglGetModifiers(fView));
@@ -895,10 +909,10 @@ struct Window::PrivateData {
if (fModal.childFocus != nullptr)
return;
- x /= fScaling;
- y /= fScaling;
- dx /= fScaling;
- dy /= fScaling;
+ x /= fAutoScaling;
+ y /= fAutoScaling;
+ dx /= fAutoScaling;
+ dy /= fAutoScaling;
Widget::ScrollEvent ev;
ev.delta = Point(dx, dy);
@@ -1038,9 +1052,10 @@ struct Window::PrivateData {
// -------------------------------------------------------------------
- Application& fApp;
- Window* fSelf;
- PuglView* fView;
+ Application& fApp;
+ Window* fSelf;
+ GraphicsContext fContext;
+ PuglView* fView;
bool fFirstInit;
bool fVisible;
@@ -1049,6 +1064,7 @@ struct Window::PrivateData {
uint fWidth;
uint fHeight;
double fScaling;
+ double fAutoScaling;
char* fTitle;
std::list fWidgets;
@@ -1081,7 +1097,7 @@ struct Window::PrivateData {
HWND hwndParent;
#elif defined(DISTRHO_OS_MAC)
bool fNeedsIdle;
- PuglOpenGLView* mView;
+ NSView* mView;
id mWindow;
id mParentWindow;
#else
@@ -1155,8 +1171,8 @@ Window::Window(Application& app)
Window::Window(Application& app, Window& parent)
: pData(new PrivateData(app, this, parent)) {}
-Window::Window(Application& app, intptr_t parentId, bool resizable)
- : pData(new PrivateData(app, this, parentId, resizable)) {}
+Window::Window(Application& app, intptr_t parentId, double scaling, bool resizable)
+ : pData(new PrivateData(app, this, parentId, scaling, resizable)) {}
Window::~Window()
{
@@ -1347,11 +1363,6 @@ double Window::getScaling() const noexcept
return pData->getScaling();
}
-void Window::setScaling(double scaling) noexcept
-{
- pData->setScaling(scaling);
-}
-
bool Window::getIgnoringKeyRepeat() const noexcept
{
return pData->getIgnoringKeyRepeat();
@@ -1372,6 +1383,20 @@ intptr_t Window::getWindowId() const noexcept
return puglGetNativeWindow(pData->fView);
}
+const GraphicsContext& Window::getGraphicsContext() const noexcept
+{
+ GraphicsContext& context = pData->fContext;
+#ifdef DGL_CAIRO
+ context.cairo = (cairo_t*)puglGetContext(pData->fView);
+#endif
+ return context;
+}
+
+void Window::_setAutoScaling(double scaling) noexcept
+{
+ pData->setAutoScaling(scaling);
+}
+
void Window::_addWidget(Widget* const widget)
{
pData->addWidget(widget);
@@ -1407,8 +1432,10 @@ void Window::removeIdleCallback(IdleCallback* const callback)
void Window::onDisplayBefore()
{
+#ifdef DGL_OPENGL
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
+#endif
}
void Window::onDisplayAfter()
@@ -1417,6 +1444,7 @@ void Window::onDisplayAfter()
void Window::onReshape(uint width, uint height)
{
+#ifdef DGL_OPENGL
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
@@ -1425,6 +1453,7 @@ void Window::onReshape(uint width, uint height)
glViewport(0, 0, static_cast(width), static_cast(height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+#endif
}
void Window::onClose()
diff --git a/dpf/dgl/src/pugl/pugl.h b/dpf/dgl/src/pugl/pugl.h
index 32a10a2..20a3814 100644
--- a/dpf/dgl/src/pugl/pugl.h
+++ b/dpf/dgl/src/pugl/pugl.h
@@ -1,5 +1,6 @@
/*
Copyright 2012-2014 David Robillard
+ Copyright 2012-2019 Filipe Coelho
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -29,19 +30,13 @@
platforms so they are included here to allow for pure portable programs.
*/
#ifdef __APPLE__
-# include "OpenGL/gl.h"
+# include
#else
# ifdef _WIN32
# include
# include /* Broken Windows GL headers require this */
# endif
-# include "GL/gl.h"
-#endif
-
-#ifdef _WIN32
-# define PUGL_API
-#else
-# define PUGL_API __attribute__((visibility("hidden")))
+# include
#endif
#ifdef __cplusplus
@@ -237,31 +232,31 @@ typedef void (*PuglFileSelectedFunc)(PuglView* view, const char* filename);
To create a window, call the various puglInit* functions as necessary, then
call puglCreateWindow().
*/
-PUGL_API PuglView*
+PuglView*
puglInit(void);
/**
Set the parent window before creating a window (for embedding).
*/
-PUGL_API void
+void
puglInitWindowParent(PuglView* view, PuglNativeWindow parent);
/**
Set the window size before creating a window.
*/
-PUGL_API void
+void
puglInitWindowSize(PuglView* view, int width, int height);
/**
Set the minimum window size before creating a window.
*/
-PUGL_API void
+void
puglInitWindowMinSize(PuglView* view, int width, int height);
/**
Enable or disable resizing before creating a window.
*/
-PUGL_API void
+void
puglInitUserResizable(PuglView* view, bool resizable);
/**
@@ -270,7 +265,7 @@ puglInitUserResizable(PuglView* view, bool resizable);
On X11, parent_id must be a Window.
On OSX, parent_id must be an NSView*.
*/
-PUGL_API void
+void
puglInitTransientFor(PuglView* view, uintptr_t parent);
/**
@@ -288,7 +283,7 @@ puglInitTransientFor(PuglView* view, uintptr_t parent);
@return 1 (pugl does not currently support multiple windows).
*/
-PUGL_API int
+int
puglCreateWindow(PuglView* view, const char* title);
/**
@@ -299,7 +294,7 @@ puglCreateWindow(PuglView* view, const char* title);
@param height Window height in pixels.
@param resizable Whether window should be user resizable.
*/
-PUGL_API PuglView*
+PuglView*
puglCreate(PuglNativeWindow parent,
const char* title,
int min_width,
@@ -312,19 +307,19 @@ puglCreate(PuglNativeWindow parent,
/**
Show Window (external ui)
*/
-PUGL_API void
+void
puglShowWindow(PuglView* view);
/**
Hide Window (external ui)
*/
-PUGL_API void
+void
puglHideWindow(PuglView* view);
/**
Return the native window handle.
*/
-PUGL_API PuglNativeWindow
+PuglNativeWindow
puglGetNativeWindow(PuglView* view);
/**
@@ -340,19 +335,27 @@ puglGetNativeWindow(PuglView* view);
Note the lack of this facility makes GLUT unsuitable for plugins or
non-trivial programs; this mistake is largely why Pugl exists.
*/
-PUGL_API void
+void
puglSetHandle(PuglView* view, PuglHandle handle);
/**
Get the handle to be passed to all callbacks.
*/
-PUGL_API PuglHandle
+PuglHandle
puglGetHandle(PuglView* view);
+/**
+ Get the drawing context.
+ For Cairo contexts, this returns a pointer to a cairo_t.
+ For everything else, this is unused and returns NULL.
+*/
+void*
+puglGetContext(PuglView* view);
+
/**
Return the timestamp (if any) of the currently-processing event.
*/
-PUGL_API uint32_t
+uint32_t
puglGetEventTimestamp(PuglView* view);
/**
@@ -360,13 +363,13 @@ puglGetEventTimestamp(PuglView* view);
This should only be called from an event handler.
*/
-PUGL_API int
+int
puglGetModifiers(PuglView* view);
/**
Ignore synthetic repeated key events.
*/
-PUGL_API void
+void
puglIgnoreKeyRepeat(PuglView* view, bool ignore);
/**
@@ -378,61 +381,61 @@ puglIgnoreKeyRepeat(PuglView* view, bool ignore);
/**
Set the function to call when the window is closed.
*/
-PUGL_API void
+void
puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc);
/**
Set the display function which should draw the UI using GL.
*/
-PUGL_API void
+void
puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc);
/**
Set the function to call on keyboard events.
*/
-PUGL_API void
+void
puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc);
/**
Set the function to call on mouse motion.
*/
-PUGL_API void
+void
puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc);
/**
Set the function to call on mouse button events.
*/
-PUGL_API void
+void
puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc);
/**
Set the function to call on scroll events.
*/
-PUGL_API void
+void
puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc);
/**
Set the function to call on special events.
*/
-PUGL_API void
+void
puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);
/**
Set the function to call when the window size changes.
*/
-PUGL_API void
+void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
/**
Set callback function to change window size.
*/
-PUGL_API void
+void
puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc);
/**
Set the function to call on file-browser selections.
*/
-PUGL_API void
+void
puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
/**
@@ -442,13 +445,13 @@ puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
/**
TODO document this.
*/
-PUGL_API int
+int
puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect);
/**
Grab the input focus.
*/
-PUGL_API void
+void
puglGrabFocus(PuglView* view);
/**
@@ -457,25 +460,25 @@ puglGrabFocus(PuglView* view);
This handles input events as well as rendering, so it should be called
regularly and rapidly enough to keep the UI responsive.
*/
-PUGL_API PuglStatus
+PuglStatus
puglProcessEvents(PuglView* view);
/**
Request a redisplay on the next call to puglProcessEvents().
*/
-PUGL_API void
+void
puglPostRedisplay(PuglView* view);
/**
Request a resize on the next call to puglProcessEvents().
*/
-PUGL_API void
+void
puglPostResize(PuglView* view);
/**
Destroy a GL window.
*/
-PUGL_API void
+void
puglDestroy(PuglView* view);
/**
diff --git a/dpf/dgl/src/pugl/pugl_internal.h b/dpf/dgl/src/pugl/pugl_internal.h
index fa52df4..609c97b 100644
--- a/dpf/dgl/src/pugl/pugl_internal.h
+++ b/dpf/dgl/src/pugl/pugl_internal.h
@@ -1,5 +1,6 @@
/*
Copyright 2012-2014 David Robillard
+ Copyright 2012-2019 Filipe Coelho
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -239,6 +240,7 @@ puglLeaveContext(PuglView* view, bool flush);
static void
puglDefaultReshape(int width, int height)
{
+#ifdef PUGL_OPENGL
#ifdef ROBTK_HERE
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
@@ -257,4 +259,5 @@ puglDefaultReshape(int width, int height)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#endif
+#endif // PUGL_OPENGL
}
diff --git a/dpf/dgl/src/pugl/pugl_osx.m b/dpf/dgl/src/pugl/pugl_osx.m
index 738103f..80b9930 100644
--- a/dpf/dgl/src/pugl/pugl_osx.m
+++ b/dpf/dgl/src/pugl/pugl_osx.m
@@ -1,5 +1,6 @@
/*
Copyright 2012 David Robillard
+ Copyright 2012-2019 Filipe Coelho
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +21,10 @@
#include
+#ifdef PUGL_CAIRO
+#import
+#import
+#endif
#import
#include "pugl_internal.h"
@@ -93,7 +98,200 @@ puglDisplay(PuglView* view)
}
}
-@interface PuglOpenGLView : NSOpenGLView
+@protocol PuglGenericView
+@required
+- (PuglView *) puglview;
+- (void) setPuglview:(PuglView *)pv;
+- (NSTrackingArea *) puglTrackingArea;
+- (void) setPuglTrackingArea:(NSTrackingArea *)area;
+@end
+
+static unsigned
+getModifiers(PuglView* view, NSEvent* ev)
+{
+ const unsigned modifierFlags = [ev modifierFlags];
+
+ view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
+
+ 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;
+}
+
+static int
+getFixedAppKitButton(NSInteger button)
+{
+ switch (button) {
+ case 0: return 1;
+ case 1: return 3;
+ case 2: return 2;
+ default: return button;
+ }
+}
+
+static void
+cursorUpdate(NSView *self, NSEvent* event)
+{
+ [[NSCursor arrowCursor] set];
+ (void)self;
+ (void)event;
+}
+
+static void
+updateTrackingAreas(NSView *self)
+{
+ static const int opts = NSTrackingMouseEnteredAndExited
+ | NSTrackingMouseMoved
+ | NSTrackingEnabledDuringMouseDrag
+ | NSTrackingInVisibleRect
+ | NSTrackingActiveAlways
+ | NSTrackingCursorUpdate;
+
+ NSTrackingArea *trackingArea = [self puglTrackingArea];
+ if (trackingArea != nil) {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ }
+
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:opts
+ owner:self
+ userInfo:nil];
+ [self setPuglTrackingArea:trackingArea];
+ [self addTrackingArea:trackingArea];
+}
+
+static void
+viewWillMoveToWindow(NSView *self, NSWindow* newWindow)
+{
+ if (newWindow != nil) {
+ [newWindow setAcceptsMouseMovedEvents:YES];
+ [newWindow makeFirstResponder:self];
+ }
+}
+
+static void
+reshape(NSView *self)
+{
+ PuglView* puglview = [self puglview];
+
+ NSRect bounds = [self bounds];
+ int width = bounds.size.width;
+ int height = bounds.size.height;
+
+ puglEnterContext(puglview);
+
+ if (puglview->reshapeFunc) {
+ puglview->reshapeFunc(puglview, width, height);
+ } else {
+ puglDefaultReshape(width, height);
+ }
+
+ puglLeaveContext(puglview, false);
+
+ puglview->width = width;
+ puglview->height = height;
+}
+
+static void
+mouseMoved(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->motionFunc) {
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->motionFunc(puglview, loc.x, loc.y);
+ }
+}
+
+static void
+mouseDown(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->mouseFunc) {
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), true, loc.x, loc.y);
+ }
+}
+
+static void
+mouseUp(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->mouseFunc) {
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), false, loc.x, loc.y);
+ }
+}
+
+static void
+scrollWheel(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->scrollFunc) {
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->scrollFunc(puglview,
+ loc.x, loc.y,
+ [event deltaX], [event deltaY]);
+ }
+}
+
+static void
+keyDown(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->keyboardFunc && !(puglview->ignoreKeyRepeat && [event isARepeat])) {
+ NSString* chars = [event characters];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->keyboardFunc(puglview, true, [chars characterAtIndex:0]);
+ }
+}
+
+static void
+keyUp(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->keyboardFunc) {
+ NSString* chars = [event characters];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->keyboardFunc(puglview, false, [chars characterAtIndex:0]);
+ }
+}
+
+static void
+flagsChanged(NSView *self, NSEvent *event)
+{
+ PuglView* puglview = [self puglview];
+
+ if (puglview->specialFunc) {
+ 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;
+ }
+}
+
+#ifdef PUGL_OPENGL
+@interface PuglOpenGLView : NSOpenGLView
{
@public
PuglView* puglview;
@@ -101,6 +299,11 @@ puglDisplay(PuglView* view)
bool doubleBuffered;
}
+- (PuglView *) puglview;
+- (void) setPuglview:(PuglView *)pv;
+- (NSTrackingArea *) puglTrackingArea;
+- (void) setPuglTrackingArea:(NSTrackingArea *)area;
+
- (BOOL) acceptsFirstMouse:(NSEvent*)e;
- (BOOL) acceptsFirstResponder;
- (BOOL) isFlipped;
@@ -130,6 +333,21 @@ puglDisplay(PuglView* view)
@end
@implementation PuglOpenGLView
+- (PuglView *) puglview {
+ return self->puglview;
+}
+
+- (void) setPuglview:(PuglView *)pv {
+ self->puglview = pv;
+}
+
+- (NSTrackingArea *) puglTrackingArea {
+ return self->trackingArea;
+}
+
+- (void) setPuglTrackingArea:(NSTrackingArea *)area {
+ self->trackingArea = area;
+}
- (BOOL) acceptsFirstMouse:(NSEvent*)e
{
@@ -209,22 +427,7 @@ puglDisplay(PuglView* view)
[[self openGLContext] update];
- NSRect bounds = [self bounds];
- int width = bounds.size.width;
- int height = bounds.size.height;
-
- puglEnterContext(puglview);
-
- if (puglview->reshapeFunc) {
- puglview->reshapeFunc(puglview, width, height);
- } else {
- puglDefaultReshape(width, height);
- }
-
- puglLeaveContext(puglview, false);
-
- puglview->width = width;
- puglview->height = height;
+ reshape(self);
}
- (void) drawRect:(NSRect)r
@@ -239,182 +442,326 @@ puglDisplay(PuglView* view)
- (void) cursorUpdate:(NSEvent*)e
{
- [[NSCursor arrowCursor] set];
-
- // unused
- return; (void)e;
+ cursorUpdate(self, e);
}
- (void) updateTrackingAreas
{
- static const int opts = NSTrackingMouseEnteredAndExited
- | NSTrackingMouseMoved
- | NSTrackingEnabledDuringMouseDrag
- | NSTrackingInVisibleRect
- | NSTrackingActiveAlways
- | NSTrackingCursorUpdate;
-
- if (trackingArea != nil) {
- [self removeTrackingArea:trackingArea];
- [trackingArea release];
- }
-
- trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
- options:opts
- owner:self
- userInfo:nil];
- [self addTrackingArea:trackingArea];
+ updateTrackingAreas(self);
[super updateTrackingAreas];
}
- (void) viewWillMoveToWindow:(NSWindow*)newWindow
{
- if (newWindow != nil) {
- [newWindow setAcceptsMouseMovedEvents:YES];
- [newWindow makeFirstResponder:self];
- }
-
+ viewWillMoveToWindow(self, newWindow);
[super viewWillMoveToWindow:newWindow];
}
-static unsigned
-getModifiers(PuglView* view, NSEvent* ev)
+- (void) mouseMoved:(NSEvent*)event
{
- const unsigned modifierFlags = [ev modifierFlags];
+ mouseMoved(self, event);
+}
- view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
+- (void) mouseDragged:(NSEvent*)event
+{
+ mouseMoved(self, event);
+}
- 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) rightMouseDragged:(NSEvent*)event
+{
+ mouseMoved(self, event);
}
-static int
-getFixedAppKitButton(NSInteger button)
+- (void) otherMouseDragged:(NSEvent*)event
{
- switch (button) {
- case 0: return 1;
- case 1: return 3;
- case 2: return 2;
- default: return button;
+ mouseMoved(self, event);
+}
+
+- (void) mouseDown:(NSEvent*)event
+{
+ mouseDown(self, event);
+}
+
+- (void) rightMouseDown:(NSEvent*)event
+{
+ mouseDown(self, event);
+}
+
+- (void) otherMouseDown:(NSEvent*)event
+{
+ mouseDown(self, event);
+}
+
+- (void) mouseUp:(NSEvent*)event
+{
+ mouseUp(self, event);
+}
+
+- (void) rightMouseUp:(NSEvent*)event
+{
+ mouseUp(self, event);
+}
+
+- (void) otherMouseUp:(NSEvent*)event
+{
+ mouseUp(self, event);
+}
+
+- (void) scrollWheel:(NSEvent*)event
+{
+ scrollWheel(self, event);
+}
+
+- (void) keyDown:(NSEvent*)event
+{
+ keyDown(self, event);
+}
+
+- (void) keyUp:(NSEvent*)event
+{
+ keyUp(self, event);
+}
+
+- (void) flagsChanged:(NSEvent*)event
+{
+ flagsChanged(self, event);
+}
+
+@end
+#endif
+
+#ifdef PUGL_CAIRO
+@interface PuglCairoView : NSView
+{
+ PuglView* puglview;
+ cairo_t* cr;
+ NSTrackingArea* trackingArea;
+}
+
+- (PuglView *) puglview;
+- (void) setPuglview:(PuglView *)pv;
+- (NSTrackingArea *) puglTrackingArea;
+- (void) setPuglTrackingArea:(NSTrackingArea *)area;
+
+- (cairo_t *) cairoContext;
+
+- (BOOL) acceptsFirstMouse:(NSEvent*)e;
+- (BOOL) acceptsFirstResponder;
+- (BOOL) isFlipped;
+- (BOOL) isOpaque;
+- (BOOL) preservesContentInLiveResize;
+- (id) initWithFrame:(NSRect)frame;
+- (void) reshape;
+- (void) drawRect:(NSRect)r;
+- (void) cursorUpdate:(NSEvent*)e;
+- (void) updateTrackingAreas;
+- (void) viewWillMoveToWindow:(NSWindow*)newWindow;
+- (void) mouseMoved:(NSEvent*)event;
+- (void) mouseDragged:(NSEvent*)event;
+- (void) rightMouseDragged:(NSEvent*)event;
+- (void) otherMouseDragged:(NSEvent*)event;
+- (void) mouseDown:(NSEvent*)event;
+- (void) rightMouseDown:(NSEvent*)event;
+- (void) otherMouseDown:(NSEvent*)event;
+- (void) mouseUp:(NSEvent*)event;
+- (void) rightMouseUp:(NSEvent*)event;
+- (void) otherMouseUp:(NSEvent*)event;
+- (void) scrollWheel:(NSEvent*)event;
+- (void) keyDown:(NSEvent*)event;
+- (void) keyUp:(NSEvent*)event;
+- (void) flagsChanged:(NSEvent*)event;
+@end
+
+@implementation PuglCairoView
+- (PuglView *) puglview {
+ return self->puglview;
+}
+
+- (void) setPuglview:(PuglView *)pv {
+ self->puglview = pv;
+}
+
+- (NSTrackingArea *) puglTrackingArea {
+ return self->trackingArea;
+}
+
+- (void) setPuglTrackingArea:(NSTrackingArea *)area {
+ self->trackingArea = area;
+}
+
+- (cairo_t *) cairoContext {
+ return cr;
+}
+
+- (BOOL) acceptsFirstMouse:(NSEvent*)e
+{
+ return YES;
+
+ // unused
+ (void)e;
+}
+
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+- (BOOL) isFlipped
+{
+ return YES;
+}
+
+- (BOOL) isOpaque
+{
+ return YES;
+}
+
+- (BOOL) preservesContentInLiveResize
+{
+ return NO;
+}
+
+- (id) initWithFrame:(NSRect)frame {
+ puglview = nil;
+ cr = NULL;
+ trackingArea = nil;
+ [super initWithFrame:frame];
+ return self;
+}
+
+- (void) reshape
+{
+ if (!puglview) {
+ /* NOTE: Apparently reshape gets called when the GC gets around to
+ deleting the view (?), so we must have reset puglview to NULL when
+ this comes around.
+ */
+ return;
}
+
+ reshape(self);
+}
+
+- (void) drawRect:(NSRect)r {
+ CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ NSRect bounds = [self bounds];
+ cairo_surface_t* surface;
+ cairo_t* cairo;
+
+ surface = cairo_quartz_surface_create_for_cg_context(ctx, bounds.size.width, bounds.size.height);
+ if (surface) {
+ cairo = cairo_create(surface);
+ if (cairo) {
+ self->cr = cairo;
+ puglEnterContext(puglview);
+ puglDisplay(puglview);
+ puglLeaveContext(puglview, true);
+ self->cr = NULL;
+ cairo_destroy(cairo);
+ }
+ cairo_surface_destroy(surface);
+ }
+}
+
+- (void) cursorUpdate:(NSEvent*)e
+{
+ cursorUpdate(self, e);
+}
+
+- (void) updateTrackingAreas
+{
+ updateTrackingAreas(self);
+ [super updateTrackingAreas];
+}
+
+- (void) viewWillMoveToWindow:(NSWindow*)newWindow
+{
+ viewWillMoveToWindow(self, newWindow);
+ [super viewWillMoveToWindow:newWindow];
}
- (void) mouseMoved:(NSEvent*)event
{
- if (puglview->motionFunc) {
- NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
- puglview->mods = getModifiers(puglview, event);
- puglview->motionFunc(puglview, loc.x, loc.y);
- }
+ mouseMoved(self, event);
}
- (void) mouseDragged:(NSEvent*)event
{
- [self mouseMoved:event];
+ mouseMoved(self, event);
}
- (void) rightMouseDragged:(NSEvent*)event
{
- [self mouseDragged:event];
+ mouseMoved(self, event);
}
- (void) otherMouseDragged:(NSEvent*)event
{
- [self mouseDragged:event];
+ mouseMoved(self, event);
}
- (void) mouseDown:(NSEvent*)event
{
- if (puglview->mouseFunc) {
- NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
- puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), true, loc.x, loc.y);
- }
+ mouseDown(self, event);
}
- (void) rightMouseDown:(NSEvent*)event
{
- [self mouseDown:event];
+ mouseDown(self, event);
}
- (void) otherMouseDown:(NSEvent*)event
{
- [self mouseDown:event];
+ mouseDown(self, event);
}
- (void) mouseUp:(NSEvent*)event
{
- if (puglview->mouseFunc) {
- NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
- puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), false, loc.x, loc.y);
- }
+ mouseUp(self, event);
}
- (void) rightMouseUp:(NSEvent*)event
{
- [self mouseUp:event];
+ mouseUp(self, event);
}
- (void) otherMouseUp:(NSEvent*)event
{
- [self mouseUp:event];
+ mouseUp(self, event);
}
- (void) scrollWheel:(NSEvent*)event
{
- if (puglview->scrollFunc) {
- NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
- puglview->mods = getModifiers(puglview, event);
- puglview->scrollFunc(puglview,
- loc.x, loc.y,
- [event deltaX], [event deltaY]);
- }
+ scrollWheel(self, event);
}
- (void) keyDown:(NSEvent*)event
{
- if (puglview->keyboardFunc && !(puglview->ignoreKeyRepeat && [event isARepeat])) {
- NSString* chars = [event characters];
- puglview->mods = getModifiers(puglview, event);
- puglview->keyboardFunc(puglview, true, [chars characterAtIndex:0]);
- }
+ keyDown(self, event);
}
- (void) keyUp:(NSEvent*)event
{
- if (puglview->keyboardFunc) {
- NSString* chars = [event characters];
- puglview->mods = getModifiers(puglview, event);
- puglview->keyboardFunc(puglview, false, [chars characterAtIndex:0]);
- }
+ keyUp(self, event);
}
- (void) flagsChanged:(NSEvent*)event
{
- if (puglview->specialFunc) {
- 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;
- }
+ flagsChanged(self, event);
}
-
@end
+#endif
struct PuglInternalsImpl {
- PuglOpenGLView* glview;
+ union {
+ NSView* view;
+#ifdef PUGL_OPENGL
+ PuglOpenGLView* glview;
+#endif
+#ifdef PUGL_CAIRO
+ PuglCairoView* cairoview;
+#endif
+ };
id window;
};
@@ -427,19 +774,23 @@ puglInitInternals()
void
puglEnterContext(PuglView* view)
{
+#ifdef PUGL_OPENGL
[[view->impl->glview openGLContext] makeCurrentContext];
+#endif
}
void
puglLeaveContext(PuglView* view, bool flush)
{
if (flush) {
+#ifdef PUGL_OPENGL
if (view->impl->glview->doubleBuffered) {
[[view->impl->glview openGLContext] flushBuffer];
} else {
glFlush();
}
//[NSOpenGLContext clearCurrentContext];
+#endif
}
}
@@ -451,22 +802,27 @@ puglCreateWindow(PuglView* view, const char* title)
[NSAutoreleasePool new];
[NSApplication sharedApplication];
+#ifdef PUGL_OPENGL
impl->glview = [PuglOpenGLView new];
+#endif
+#ifdef PUGL_CAIRO
+ impl->cairoview = [PuglCairoView new];
+#endif
- if (!impl->glview) {
+ if (!impl->view) {
return 1;
}
-
- impl->glview->puglview = view;
+
+ [impl->view setPuglview:view];
if (view->user_resizable) {
- [impl->glview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
+ [impl->view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
}
if (view->parent) {
- [impl->glview retain];
+ [impl->view retain];
NSView* pview = (NSView*)view->parent;
- [pview addSubview:impl->glview];
+ [pview addSubview:impl->view];
return 0;
}
@@ -482,8 +838,8 @@ puglCreateWindow(PuglView* view, const char* title)
}
[window setPuglview:view];
- [window setContentView:impl->glview];
- [window makeFirstResponder:impl->glview];
+ [window setContentView:impl->view];
+ [window makeFirstResponder:impl->view];
[window makeKeyAndOrderFront:window];
// wait for first puglShowWindow
@@ -505,7 +861,7 @@ puglShowWindow(PuglView* view)
if (impl->window) {
[impl->window setIsVisible:YES];
} else {
- [view->impl->glview setHidden:NO];
+ [view->impl->view setHidden:NO];
}
}
@@ -517,21 +873,21 @@ puglHideWindow(PuglView* view)
if (impl->window) {
[impl->window setIsVisible:NO];
} else {
- [impl->glview setHidden:YES];
+ [impl->view setHidden:YES];
}
}
void
puglDestroy(PuglView* view)
{
- view->impl->glview->puglview = NULL;
+ [view->impl->view setPuglview:NULL];
if (view->impl->window) {
[view->impl->window close];
- [view->impl->glview release];
+ [view->impl->view release];
[view->impl->window release];
} else {
- [view->impl->glview release];
+ [view->impl->view release];
}
free(view->impl);
@@ -551,13 +907,25 @@ void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
- [view->impl->glview setNeedsDisplay:YES];
+ [view->impl->view setNeedsDisplay:YES];
}
PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
- return (PuglNativeWindow)view->impl->glview;
+ return (PuglNativeWindow)view->impl->view;
+}
+
+void*
+puglGetContext(PuglView* view)
+{
+#ifdef PUGL_CAIRO
+ return [view->impl->cairoview cairoContext];
+#endif
+ return NULL;
+
+ // may be unused
+ (void)view;
}
int
diff --git a/dpf/dgl/src/pugl/pugl_win.cpp b/dpf/dgl/src/pugl/pugl_win.cpp
index 9990b8e..d8b3866 100644
--- a/dpf/dgl/src/pugl/pugl_win.cpp
+++ b/dpf/dgl/src/pugl/pugl_win.cpp
@@ -1,5 +1,6 @@
/*
Copyright 2012-2014 David Robillard
+ Copyright 2012-2019 Filipe Coelho
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -18,16 +19,22 @@
@file pugl_win.cpp Windows/WGL Pugl Implementation.
*/
+#include
+#include
+#include
+
#include
#include
#include
+#ifdef PUGL_CAIRO
+#include
+#include
+#endif
+#ifdef PUGL_OPENGL
#include
+#endif
-#include
-#include
-#include
-
-#include "pugl/pugl_internal.h"
+#include "pugl_internal.h"
#ifndef WM_MOUSEWHEEL
# define WM_MOUSEWHEEL 0x020A
@@ -48,8 +55,15 @@ HINSTANCE hInstance = NULL;
struct PuglInternalsImpl {
HWND hwnd;
+#ifdef PUGL_OPENGL
HDC hdc;
HGLRC hglrc;
+#endif
+#ifdef PUGL_CAIRO
+ cairo_t* buffer_cr;
+ cairo_surface_t* buffer_surface;
+#endif
+ HDC paintHdc;
WNDCLASS wc;
};
@@ -76,17 +90,21 @@ puglInitInternals()
void
puglEnterContext(PuglView* view)
{
+#ifdef PUGL_OPENGL
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
+#endif
}
void
puglLeaveContext(PuglView* view, bool flush)
{
+#ifdef PUGL_OPENGL
if (flush) {
glFlush();
SwapBuffers(view->impl->hdc);
}
wglMakeCurrent(NULL, NULL);
+#endif
}
int
@@ -124,7 +142,6 @@ puglCreateWindow(PuglView* view, const char* title)
if (!RegisterClass(&impl->wc)) {
free((void*)impl->wc.lpszClassName);
free(impl);
- free(view);
return 1;
}
@@ -155,12 +172,12 @@ puglCreateWindow(PuglView* view, const char* title)
UnregisterClass(impl->wc.lpszClassName, NULL);
free((void*)impl->wc.lpszClassName);
free(impl);
- free(view);
return 1;
}
SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
+#ifdef PUGL_OPENGL
impl->hdc = GetDC(impl->hwnd);
PIXELFORMATDESCRIPTOR pfd;
@@ -183,9 +200,9 @@ puglCreateWindow(PuglView* view, const char* title)
UnregisterClass (impl->wc.lpszClassName, NULL);
free((void*)impl->wc.lpszClassName);
free(impl);
- free(view);
return 1;
}
+#endif
return PUGL_SUCCESS;
}
@@ -205,13 +222,25 @@ puglHideWindow(PuglView* view)
void
puglDestroy(PuglView* view)
{
+ if (!view) {
+ return;
+ }
+
+ PuglInternals* const impl = view->impl;
+
+#ifdef PUGL_OPENGL
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((void*)view->impl->wc.lpszClassName);
- free(view->impl);
+ wglDeleteContext(impl->hglrc);
+ ReleaseDC(impl->hwnd, impl->hdc);
+#endif
+#ifdef PUGL_CAIRO
+ cairo_destroy(impl->buffer_cr);
+ cairo_surface_destroy(impl->buffer_surface);
+#endif
+ DestroyWindow(impl->hwnd);
+ UnregisterClass(impl->wc.lpszClassName, NULL);
+ free((void*)impl->wc.lpszClassName);
+ free(impl);
free(view);
}
@@ -233,14 +262,57 @@ puglReshape(PuglView* view, int width, int height)
static void
puglDisplay(PuglView* view)
{
+ PuglInternals* impl = view->impl;
+ bool success = true;
+
puglEnterContext(view);
- view->redisplay = false;
- if (view->displayFunc) {
- view->displayFunc(view);
+#ifdef PUGL_CAIRO
+ cairo_t *wc = NULL;
+ cairo_t *bc = NULL;
+ cairo_surface_t *ws = NULL;
+ cairo_surface_t *bs = NULL;
+
+ HDC hdc = impl->paintHdc;
+ bc = impl->buffer_cr;
+ bs = impl->buffer_surface;
+ int w = view->width;
+ int h = view->height;
+ int bw = bs ? cairo_image_surface_get_width(bs) : -1;
+ int bh = bs ? cairo_image_surface_get_height(bs) : -1;
+ ws = hdc ? cairo_win32_surface_create(hdc) : NULL;
+ wc = ws ? cairo_create(ws) : NULL;
+ if (wc && (!bc || bw != w || bh != h)) {
+ cairo_destroy(bc);
+ cairo_surface_destroy(bs);
+ bs = cairo_surface_create_similar_image(ws, CAIRO_FORMAT_ARGB32, w, h);
+ bc = bs ? cairo_create(bs) : NULL;
+ impl->buffer_cr = bc;
+ impl->buffer_surface = bs;
+ }
+ success = wc != NULL && bc != NULL;
+#endif
+
+ if (success) {
+ view->redisplay = false;
+ if (view->displayFunc) {
+ view->displayFunc(view);
+ }
+#ifdef PUGL_CAIRO
+ cairo_set_source_surface(wc, bs, 0, 0);
+ cairo_paint(wc);
+#endif
}
- puglLeaveContext(view, true);
+ puglLeaveContext(view, success);
+
+#ifdef PUGL_CAIRO
+ cairo_destroy(wc);
+ cairo_surface_destroy(ws);
+#endif
+
+ return;
+ (void)impl;
}
static PuglKey
@@ -329,8 +401,9 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
mmi->ptMinTrackSize.y = view->min_height;
break;
case WM_PAINT:
- BeginPaint(view->impl->hwnd, &ps);
+ view->impl->paintHdc = BeginPaint(view->impl->hwnd, &ps);
puglDisplay(view);
+ view->impl->paintHdc = NULL;
EndPaint(view->impl->hwnd, &ps);
break;
case WM_MOUSEMOVE:
@@ -469,6 +542,18 @@ puglGetNativeWindow(PuglView* view)
return (PuglNativeWindow)view->impl->hwnd;
}
+void*
+puglGetContext(PuglView* view)
+{
+#ifdef PUGL_CAIRO
+ return view->impl->buffer_cr;
+#endif
+ return NULL;
+
+ // may be unused
+ (void)view;
+}
+
int
puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect)
{
diff --git a/dpf/dgl/src/pugl/pugl_x11.c b/dpf/dgl/src/pugl/pugl_x11.c
index ea70db1..3146cfc 100644
--- a/dpf/dgl/src/pugl/pugl_x11.c
+++ b/dpf/dgl/src/pugl/pugl_x11.c
@@ -2,6 +2,7 @@
Copyright 2012-2014 David Robillard
Copyright 2011-2012 Ben Loftis, Harrison Consoles
Copyright 2013,2015 Robin Gareus
+ Copyright 2012-2019 Filipe Coelho
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -24,8 +25,14 @@
#include
#include
+#ifdef PUGL_CAIRO
+#include
+#include
+#endif
+#ifdef PUGL_OPENGL
#include
#include
+#endif
#include
#include
#include
@@ -53,10 +60,19 @@ struct PuglInternalsImpl {
Display* display;
int screen;
Window win;
+#ifdef PUGL_CAIRO
+ cairo_t* xlib_cr;
+ cairo_t* buffer_cr;
+ cairo_surface_t* xlib_surface;
+ cairo_surface_t* buffer_surface;
+#endif
+#ifdef PUGL_OPENGL
GLXContext ctx;
Bool doubleBuffered;
+#endif
};
+#ifdef PUGL_OPENGL
/**
Attributes for single-buffered RGBA with at least
4 bits per color and a 16 bit depth buffer.
@@ -102,6 +118,7 @@ static int attrListDblMS[] = {
GLX_SAMPLES, 4,
None
};
+#endif
PuglInternals*
puglInitInternals(void)
@@ -112,12 +129,15 @@ puglInitInternals(void)
void
puglEnterContext(PuglView* view)
{
+#ifdef PUGL_OPENGL
glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
+#endif
}
void
puglLeaveContext(PuglView* view, bool flush)
{
+#ifdef PUGL_OPENGL
if (flush) {
glFlush();
if (view->impl->doubleBuffered) {
@@ -125,12 +145,13 @@ puglLeaveContext(PuglView* view, bool flush)
}
}
glXMakeCurrent(view->impl->display, None, NULL);
+#endif
}
int
puglCreateWindow(PuglView* view, const char* title)
{
- PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
+ PuglInternals* impl = view->impl;
if (!impl) {
return 1;
}
@@ -142,9 +163,12 @@ puglCreateWindow(PuglView* view, const char* title)
return 1;
}
impl->screen = DefaultScreen(impl->display);
- impl->doubleBuffered = True;
- XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS);
+ XVisualInfo* vi = NULL;
+
+#ifdef PUGL_OPENGL
+ impl->doubleBuffered = True;
+ vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS);
if (!vi) {
vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
@@ -157,6 +181,13 @@ puglCreateWindow(PuglView* view, const char* title)
vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
impl->doubleBuffered = False;
}
+#endif
+#ifdef PUGL_CAIRO
+ XVisualInfo pat;
+ int n;
+ pat.screen = impl->screen;
+ vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n);
+#endif
if (!vi) {
XCloseDisplay(impl->display);
@@ -165,18 +196,23 @@ puglCreateWindow(PuglView* view, const char* title)
}
#ifdef PUGL_VERBOSE
+#ifdef PUGL_OPENGL
int glxMajor, glxMinor;
glXQueryVersion(impl->display, &glxMajor, &glxMinor);
printf("puGL: GLX-Version : %d.%d\n", glxMajor, glxMinor);
#endif
+#endif
+#ifdef PUGL_OPENGL
impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
if (!impl->ctx) {
+ XFree(vi);
XCloseDisplay(impl->display);
free(impl);
return 1;
}
+#endif
Window xParent = view->parent
? (Window)view->parent
@@ -201,11 +237,36 @@ puglCreateWindow(PuglView* view, const char* title)
CWBorderPixel | CWColormap | CWEventMask, &attr);
if (!impl->win) {
+#ifdef PUGL_OPENGL
+ glXDestroyContext(impl->display, impl->ctx);
+#endif
+ XFree(vi);
XCloseDisplay(impl->display);
free(impl);
return 1;
}
+#ifdef PUGL_CAIRO
+ impl->xlib_surface = cairo_xlib_surface_create(
+ impl->display, impl->win, vi->visual, view->width, view->height);
+ if (impl->xlib_surface == NULL || cairo_surface_status(impl->xlib_surface) != CAIRO_STATUS_SUCCESS) {
+ printf("puGL: failed to create cairo surface\n");
+ }
+ else {
+ impl->xlib_cr = cairo_create(impl->xlib_surface);
+ }
+ if (impl->xlib_cr == NULL || cairo_status(impl->xlib_cr) != CAIRO_STATUS_SUCCESS) {
+ cairo_destroy(impl->xlib_cr);
+ cairo_surface_destroy(impl->xlib_surface);
+ XDestroyWindow(impl->display, impl->win);
+ XFree(vi);
+ XCloseDisplay(impl->display);
+ free(impl);
+ printf("puGL: failed to create cairo context\n");
+ return 1;
+ }
+#endif
+
if (view->width > 1 || view->height > 1) {
puglUpdateGeometryConstraints(view, view->min_width, view->min_height, view->min_width != view->width);
XResizeWindow(view->impl->display, view->impl->win, view->width, view->height);
@@ -227,11 +288,13 @@ puglCreateWindow(PuglView* view, const char* title)
}
#ifdef PUGL_VERBOSE
+#ifdef PUGL_OPENGL
if (glXIsDirect(impl->display, impl->ctx)) {
printf("puGL: DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n");
} else {
printf("puGL: No DRI available\n");
}
+#endif
#endif
XFree(vi);
@@ -244,14 +307,25 @@ puglDestroy(PuglView* view)
if (!view) {
return;
}
+
+ PuglInternals* const impl = view->impl;
+
#ifndef DGL_FILE_BROWSER_DISABLED
- x_fib_close(view->impl->display);
+ x_fib_close(impl->display);
#endif
- glXDestroyContext(view->impl->display, view->impl->ctx);
- XDestroyWindow(view->impl->display, view->impl->win);
- XCloseDisplay(view->impl->display);
- free(view->impl);
+#ifdef PUGL_OPENGL
+ glXDestroyContext(impl->display, impl->ctx);
+#endif
+#ifdef PUGL_CAIRO
+ cairo_destroy(impl->xlib_cr);
+ cairo_destroy(impl->buffer_cr);
+ cairo_surface_destroy(impl->xlib_surface);
+ cairo_surface_destroy(impl->buffer_surface);
+#endif
+ XDestroyWindow(impl->display, impl->win);
+ XCloseDisplay(impl->display);
+ free(impl);
free(view);
}
@@ -287,14 +361,47 @@ puglReshape(PuglView* view, int width, int height)
static void
puglDisplay(PuglView* view)
{
+ PuglInternals* impl = view->impl;
+
puglEnterContext(view);
+#ifdef PUGL_CAIRO
+ cairo_t* bc = impl->buffer_cr;
+ cairo_surface_t* xs = impl->xlib_surface;
+ cairo_surface_t* bs = impl->buffer_surface;
+ int w = cairo_xlib_surface_get_width(xs);
+ int h = cairo_xlib_surface_get_height(xs);
+
+ int bw = bs ? cairo_image_surface_get_width(bs) : -1;
+ int bh = bs ? cairo_image_surface_get_height(bs) : -1;
+ if (!bc || bw != w || bh != h) {
+ cairo_destroy(bc);
+ cairo_surface_destroy(bs);
+ bs = cairo_surface_create_similar_image(xs, CAIRO_FORMAT_ARGB32, w, h);
+ bc = bs ? cairo_create(bs) : NULL;
+ impl->buffer_cr = bc;
+ impl->buffer_surface = bs;
+ }
+
+ if (!bc) {
+ puglLeaveContext(view, false);
+ return;
+ }
+#endif
+
view->redisplay = false;
if (view->displayFunc) {
view->displayFunc(view);
}
+#ifdef PUGL_CAIRO
+ cairo_t* xc = impl->xlib_cr;
+ cairo_set_source_surface(xc, impl->buffer_surface, 0, 0);
+ cairo_paint(xc);
+#endif
+
puglLeaveContext(view, true);
+ (void)impl;
}
static void
@@ -554,6 +661,12 @@ puglProcessEvents(PuglView* view)
}
if (conf_width != -1) {
+#ifdef PUGL_CAIRO
+ // Resize surfaces/contexts before dispatching
+ view->redisplay = true;
+ cairo_xlib_surface_set_size(view->impl->xlib_surface,
+ conf_width, conf_height);
+#endif
puglReshape(view, conf_width, conf_height);
}
@@ -586,6 +699,18 @@ puglGetNativeWindow(PuglView* view)
return view->impl->win;
}
+void*
+puglGetContext(PuglView* view)
+{
+#ifdef PUGL_CAIRO
+ return view->impl->buffer_cr;
+#endif
+ return NULL;
+
+ // may be unused
+ (void)view;
+}
+
int
puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect)
{
diff --git a/dpf/distrho/DistrhoInfo.hpp b/dpf/distrho/DistrhoInfo.hpp
index b38976f..4117790 100644
--- a/dpf/distrho/DistrhoInfo.hpp
+++ b/dpf/distrho/DistrhoInfo.hpp
@@ -417,6 +417,10 @@ START_NAMESPACE_DISTRHO
};
@endcode
+ This is a work-in-progress documentation page. States, MIDI, Latency, Time-Position and UI are still TODO.
+*/
+
+#if 0
@section States
describe them
@@ -431,7 +435,7 @@ START_NAMESPACE_DISTRHO
@section UI
describe them
-*/
+#endif
/* ------------------------------------------------------------------------------------------------------------
* Plugin Macros */
@@ -543,6 +547,16 @@ START_NAMESPACE_DISTRHO
*/
#define DISTRHO_PLUGIN_WANT_STATE 1
+/**
+ Wherever the plugin implements the full state API.
+ When this macro is enabled, the plugin must implement a new getState(const char* key) function, which the host calls when saving its session/project.
+ This is useful for plugins that have custom internal values not exposed to the host as key-value state pairs or parameters.
+ Most simple effects and synths will not need this.
+ @note this macro is automatically enabled if a plugin has programs and state, as the key-value state pairs need to be updated when the current program changes.
+ @see Plugin::getState(const char*)
+ */
+#define DISTRHO_PLUGIN_WANT_FULL_STATE 1
+
/**
Wherever the plugin wants time position information from the host.
@see Plugin::getTimePosition()
diff --git a/dpf/distrho/DistrhoPlugin.hpp b/dpf/distrho/DistrhoPlugin.hpp
index 1da2bdb..ebc5407 100644
--- a/dpf/distrho/DistrhoPlugin.hpp
+++ b/dpf/distrho/DistrhoPlugin.hpp
@@ -226,7 +226,7 @@ struct ParameterRanges {
/**
Get a fixed value within range.
*/
- const float& getFixedValue(const float& value) const noexcept
+ float getFixedValue(const float& value) const noexcept
{
if (value <= min)
return min;
diff --git a/dpf/distrho/DistrhoUI.hpp b/dpf/distrho/DistrhoUI.hpp
index 0fa45b2..ecebc36 100644
--- a/dpf/distrho/DistrhoUI.hpp
+++ b/dpf/distrho/DistrhoUI.hpp
@@ -32,6 +32,13 @@ typedef DGL_NAMESPACE::NanoWidget UIWidget;
typedef DGL_NAMESPACE::Widget UIWidget;
#endif
+#ifdef DGL_CAIRO
+# include "Cairo.hpp"
+#endif
+#ifdef DGL_OPENGL
+# include "OpenGL.hpp"
+#endif
+
START_NAMESPACE_DISTRHO
/* ------------------------------------------------------------------------------------------------------------
@@ -62,7 +69,7 @@ public:
*/
virtual ~UI();
-#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+#if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
/**
Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically.
@see Window::setGeometryConstraints(uint,uint,bool)
@@ -82,13 +89,17 @@ public:
/**
editParameter.
- @TODO Document this.
+
+ Touch/pressed-down event.
+ Lets the host know the user is tweaking a parameter.
+ Required in some hosts to record automation.
*/
void editParameter(uint32_t index, bool started);
/**
setParameterValue.
- @TODO Document this.
+
+ Change a parameter value in the Plugin.
*/
void setParameterValue(uint32_t index, float value);
@@ -131,6 +142,13 @@ public:
*/
static const char* getNextBundlePath() noexcept;
+ /**
+ Get the scale factor that will be used for the next UI.
+ @note: This function is only valid during createUI(),
+ it will return 1.0 when called from anywhere else.
+ */
+ static double getNextScaleFactor() noexcept;
+
# if DISTRHO_PLUGIN_HAS_EMBED_UI
/**
Get the Window Id that will be used for the next created window.
diff --git a/dpf/distrho/src/DistrhoPluginChecks.h b/dpf/distrho/src/DistrhoPluginChecks.h
index 2c543b1..01a52a1 100644
--- a/dpf/distrho/src/DistrhoPluginChecks.h
+++ b/dpf/distrho/src/DistrhoPluginChecks.h
@@ -97,7 +97,7 @@
// Define DISTRHO_PLUGIN_HAS_EMBED_UI if needed
#ifndef DISTRHO_PLUGIN_HAS_EMBED_UI
-# ifdef HAVE_DGL
+# if defined(HAVE_CAIRO) || defined(HAVE_OPENGL)
# define DISTRHO_PLUGIN_HAS_EMBED_UI 1
# else
# define DISTRHO_PLUGIN_HAS_EMBED_UI 0
@@ -139,7 +139,7 @@
// -----------------------------------------------------------------------
// Disable UI if DGL or External UI is not available
-#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI && ! defined(HAVE_DGL)
+#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI && ! defined(HAVE_CAIRO) && ! defined(HAVE_OPENGL)
# undef DISTRHO_PLUGIN_HAS_UI
# define DISTRHO_PLUGIN_HAS_UI 0
#endif
diff --git a/dpf/distrho/src/DistrhoPluginJack.cpp b/dpf/distrho/src/DistrhoPluginJack.cpp
index edafaf6..7cb0684 100644
--- a/dpf/distrho/src/DistrhoPluginJack.cpp
+++ b/dpf/distrho/src/DistrhoPluginJack.cpp
@@ -81,6 +81,16 @@ static void initSignalHandler()
// -----------------------------------------------------------------------
+#if DISTRHO_PLUGIN_HAS_UI
+// TODO
+static double getDesktopScaleFactor() noexcept
+{
+ return 1.0;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
#if DISTRHO_PLUGIN_HAS_UI
class PluginJack : public IdleCallback
#else
@@ -91,7 +101,7 @@ public:
PluginJack(jack_client_t* const client)
: fPlugin(this, writeMidiCallback),
#if DISTRHO_PLUGIN_HAS_UI
- fUI(this, 0, nullptr, setParameterValueCallback, setStateCallback, nullptr, setSizeCallback, fPlugin.getInstancePointer()),
+ fUI(this, 0, nullptr, setParameterValueCallback, setStateCallback, nullptr, setSizeCallback, getDesktopScaleFactor(), fPlugin.getInstancePointer()),
#endif
fClient(client)
{
diff --git a/dpf/distrho/src/DistrhoPluginLV2.cpp b/dpf/distrho/src/DistrhoPluginLV2.cpp
index e66ec1d..ed97052 100644
--- a/dpf/distrho/src/DistrhoPluginLV2.cpp
+++ b/dpf/distrho/src/DistrhoPluginLV2.cpp
@@ -545,7 +545,7 @@ public:
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
for (uint32_t i=0; i 0)
diff --git a/dpf/distrho/src/DistrhoPluginVST.cpp b/dpf/distrho/src/DistrhoPluginVST.cpp
index c5cdd6e..d8e7640 100644
--- a/dpf/distrho/src/DistrhoPluginVST.cpp
+++ b/dpf/distrho/src/DistrhoPluginVST.cpp
@@ -161,12 +161,12 @@ public:
class UIVst
{
public:
- UIVst(const audioMasterCallback audioMaster, AEffect* const effect, ParameterCheckHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId)
+ UIVst(const audioMasterCallback audioMaster, AEffect* const effect, ParameterCheckHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId, const float scaleFactor)
: fAudioMaster(audioMaster),
fEffect(effect),
fUiHelper(uiHelper),
fPlugin(plugin),
- fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, plugin->getInstancePointer()),
+ fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, scaleFactor, plugin->getInstancePointer()),
fShouldCaptureVstKeys(false)
{
// FIXME only needed for windows?
@@ -575,8 +575,11 @@ public:
else
{
d_lastUiSampleRate = fPlugin.getSampleRate();
+
+ // TODO
+ const float scaleFactor = 1.0f;
- UIExporter tmpUI(nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, fPlugin.getInstancePointer());
+ UIExporter tmpUI(nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, scaleFactor, fPlugin.getInstancePointer());
fVstRect.right = tmpUI.getWidth();
fVstRect.bottom = tmpUI.getHeight();
tmpUI.quit();
@@ -595,8 +598,11 @@ public:
}
# endif
d_lastUiSampleRate = fPlugin.getSampleRate();
+
+ // TODO
+ const float scaleFactor = 1.0f;
- fVstUI = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr);
+ fVstUI = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr, scaleFactor);
# if DISTRHO_PLUGIN_WANT_FULL_STATE
// Update current state from plugin side
diff --git a/dpf/distrho/src/DistrhoUI.cpp b/dpf/distrho/src/DistrhoUI.cpp
index 4170c82..cc08140 100644
--- a/dpf/distrho/src/DistrhoUI.cpp
+++ b/dpf/distrho/src/DistrhoUI.cpp
@@ -27,8 +27,9 @@ START_NAMESPACE_DISTRHO
double d_lastUiSampleRate = 0.0;
void* d_lastUiDspPtr = nullptr;
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-uintptr_t g_nextWindowId = 0;
const char* g_nextBundlePath = nullptr;
+double g_nextScaleFactor = 1.0;
+uintptr_t g_nextWindowId = 0;
#else
Window* d_lastUiWindow = nullptr;
#endif
@@ -57,7 +58,7 @@ UI::~UI()
delete pData;
}
-#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+#if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale)
{
DISTRHO_SAFE_ASSERT_RETURN(minWidth > 0,);
@@ -67,7 +68,13 @@ void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRa
pData->minWidth = minWidth;
pData->minHeight = minHeight;
- getParentWindow().setGeometryConstraints(minWidth, minHeight, keepAspectRatio);
+ Window& window(getParentWindow());
+
+ const double uiScaleFactor = window.getScaling();
+ window.setGeometryConstraints(minWidth * uiScaleFactor, minHeight * uiScaleFactor, keepAspectRatio);
+
+ if (d_isNotZero(uiScaleFactor - 1.0))
+ setSize(getWidth() * uiScaleFactor, getHeight() * uiScaleFactor);
}
#endif
@@ -122,6 +129,11 @@ const char* UI::getNextBundlePath() noexcept
return g_nextBundlePath;
}
+double UI::getNextScaleFactor() noexcept
+{
+ return g_nextScaleFactor;
+}
+
# if DISTRHO_PLUGIN_HAS_EMBED_UI
uintptr_t UI::getNextWindowId() noexcept
{
@@ -147,6 +159,7 @@ void UI::uiFileBrowserSelected(const char*)
void UI::uiReshape(uint width, uint height)
{
+#ifdef DGL_OPENGL
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
@@ -155,6 +168,11 @@ void UI::uiReshape(uint width, uint height)
glViewport(0, 0, static_cast(width), static_cast(height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+#else
+ // unused
+ (void)width;
+ (void)height;
+#endif
}
/* ------------------------------------------------------------------------------------------------------------
diff --git a/dpf/distrho/src/DistrhoUIInternal.hpp b/dpf/distrho/src/DistrhoUIInternal.hpp
index b81e150..f1ebb33 100644
--- a/dpf/distrho/src/DistrhoUIInternal.hpp
+++ b/dpf/distrho/src/DistrhoUIInternal.hpp
@@ -37,11 +37,13 @@ START_NAMESPACE_DISTRHO
extern double d_lastUiSampleRate;
extern void* d_lastUiDspPtr;
-#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+extern const char* g_nextBundlePath;
+extern double g_nextScaleFactor;
+extern uintptr_t g_nextWindowId;
+#else
extern Window* d_lastUiWindow;
#endif
-extern uintptr_t g_nextWindowId;
-extern const char* g_nextBundlePath;
// -----------------------------------------------------------------------
// UI callbacks
@@ -149,15 +151,17 @@ struct UI::PrivateData {
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
static inline
-UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const char* const bundlePath)
+UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath)
{
- d_lastUiDspPtr = dspPtr;
- g_nextWindowId = winId;
- g_nextBundlePath = bundlePath;
- UI* const ret = createUI();
- d_lastUiDspPtr = nullptr;
- g_nextWindowId = 0;
- g_nextBundlePath = nullptr;
+ d_lastUiDspPtr = dspPtr;
+ g_nextWindowId = winId;
+ g_nextScaleFactor = scaleFactor;
+ g_nextBundlePath = bundlePath;
+ UI* const ret = createUI();
+ d_lastUiDspPtr = nullptr;
+ g_nextWindowId = 0;
+ g_nextScaleFactor = 1.0;
+ g_nextBundlePath = nullptr;
return ret;
}
#else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
@@ -175,8 +179,8 @@ UI* createUiWrapper(void* const dspPtr, Window* const window)
class UIExporterWindow : public Window
{
public:
- UIExporterWindow(Application& app, const intptr_t winId, void* const dspPtr)
- : Window(app, winId, DISTRHO_UI_USER_RESIZABLE),
+ UIExporterWindow(Application& app, const intptr_t winId, const double scaleFactor, void* const dspPtr)
+ : Window(app, winId, scaleFactor, DISTRHO_UI_USER_RESIZABLE),
fUI(createUiWrapper(dspPtr, this)),
fIsReady(false)
{
@@ -214,7 +218,7 @@ protected:
{
const double scaleHorizontal = static_cast(width) / static_cast(pData->minWidth);
const double scaleVertical = static_cast(height) / static_cast(pData->minHeight);
- setScaling(scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical);
+ _setAutoScaling(scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical);
}
pData->resizeInProgress = true;
@@ -254,13 +258,14 @@ public:
const setStateFunc setStateCall,
const sendNoteFunc sendNoteCall,
const setSizeFunc setSizeCall,
+ const float scaleFactor = 1.0f,
void* const dspPtr = nullptr,
const char* const bundlePath = nullptr)
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- : fUI(createUiWrapper(dspPtr, winId, bundlePath)),
+ : fUI(createUiWrapper(dspPtr, winId, scaleFactor, bundlePath)),
#else
: glApp(),
- glWindow(glApp, winId, dspPtr),
+ glWindow(glApp, winId, scaleFactor, dspPtr),
fChangingSize(false),
fUI(glWindow.getUI()),
#endif
diff --git a/dpf/distrho/src/DistrhoUILV2.cpp b/dpf/distrho/src/DistrhoUILV2.cpp
index 6431f9d..140909b 100644
--- a/dpf/distrho/src/DistrhoUILV2.cpp
+++ b/dpf/distrho/src/DistrhoUILV2.cpp
@@ -53,8 +53,8 @@ public:
UiLv2(const char* const bundlePath, const intptr_t winId,
const LV2_Options_Option* options, const LV2_URID_Map* const uridMap, const LV2UI_Resize* const uiResz, const LV2UI_Touch* uiTouch,
const LV2UI_Controller controller, const LV2UI_Write_Function writeFunc,
- LV2UI_Widget* const widget, void* const dspPtr)
- : fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, dspPtr, bundlePath),
+ const float scaleFactor, LV2UI_Widget* const widget, void* const dspPtr)
+ : fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, scaleFactor, dspPtr, bundlePath),
fUridMap(uridMap),
fUiResize(uiResz),
fUiTouch(uiTouch),
@@ -286,7 +286,7 @@ protected:
atomMidiEvent.data[2] = velocity;
// send to DSP side
- fWriteFunction(fController, eventInPortIndex, sizeof(LV2_Atom_MidiEvent), fEventTransferURID, &atomMidiEvent);
+ fWriteFunction(fController, eventInPortIndex, lv2_atom_total_size(&atomMidiEvent.atom), fEventTransferURID, &atomMidiEvent);
}
#endif
@@ -434,22 +434,30 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri,
}
#endif
+ float scaleFactor = 1.0f;
const intptr_t winId((intptr_t)parentId);
if (options != nullptr)
{
+ const LV2_URID uridAtomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float));
const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_PARAMETERS__sampleRate));
+ const LV2_URID uridScaleFactor(uridMap->map(uridMap->handle, LV2_UI__scaleFactor));
for (int i=0; options[i].key != 0; ++i)
{
- if (options[i].key == uridSampleRate)
+ /**/ if (options[i].key == uridSampleRate)
{
- if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Float))
+ if (options[i].type == uridAtomFloat)
d_lastUiSampleRate = *(const float*)options[i].value;
else
d_stderr("Host provides UI sample-rate but has wrong value type");
-
- break;
+ }
+ else if (options[i].key == uridScaleFactor)
+ {
+ if (options[i].type == uridAtomFloat)
+ scaleFactor = *(const float*)options[i].value;
+ else
+ d_stderr("Host provides UI scale factor but has wrong value type");
}
}
}
@@ -460,7 +468,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri,
d_lastUiSampleRate = 44100.0;
}
- return new UiLv2(bundlePath, winId, options, uridMap, uiResize, uiTouch, controller, writeFunction, widget, instance);
+ return new UiLv2(bundlePath, winId, options, uridMap, uiResize, uiTouch, controller, writeFunction, scaleFactor, widget, instance);
}
#define uiPtr ((UiLv2*)ui)
diff --git a/dpf/distrho/src/lv2/ui.h b/dpf/distrho/src/lv2/ui.h
index 9ee4bd1..171549c 100644
--- a/dpf/distrho/src/lv2/ui.h
+++ b/dpf/distrho/src/lv2/ui.h
@@ -52,6 +52,7 @@
#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"
#define LV2_UI__portSubscribe LV2_UI_PREFIX "portSubscribe"
#define LV2_UI__resize LV2_UI_PREFIX "resize"
+#define LV2_UI__scaleFactor LV2_UI_PREFIX "scaleFactor"
#define LV2_UI__showInterface LV2_UI_PREFIX "showInterface"
#define LV2_UI__touch LV2_UI_PREFIX "touch"
#define LV2_UI__ui LV2_UI_PREFIX "ui"
diff --git a/dpf/dpf.doxygen b/dpf/dpf.doxygen
index 9c05ec0..2516e93 100644
--- a/dpf/dpf.doxygen
+++ b/dpf/dpf.doxygen
@@ -242,7 +242,8 @@ SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = DOXYGEN \
- HAVE_DGL=1 \
+ HAVE_CAIRO=1 \
+ HAVE_OPENGL=1 \
DISTRHO_PLUGIN_NAME="Plugin Name" \
DISTRHO_PLUGIN_NUM_INPUTS=2 \
DISTRHO_PLUGIN_NUM_OUTPUTS=2 \
diff --git a/dpf/utils/lv2-ttl-generator/GNUmakefile b/dpf/utils/lv2-ttl-generator/GNUmakefile
index 1042b7b..490e934 100644
--- a/dpf/utils/lv2-ttl-generator/GNUmakefile
+++ b/dpf/utils/lv2-ttl-generator/GNUmakefile
@@ -2,7 +2,7 @@
all: build
-ifeq ($(WIN32),true)
+ifeq ($(WINDOWS),true)
build: ../lv2_ttl_generator.exe
else
build: ../lv2_ttl_generator
diff --git a/dpf/utils/png2c.py b/dpf/utils/res2c.py
similarity index 82%
rename from dpf/utils/png2c.py
rename to dpf/utils/res2c.py
index ab02365..978af8b 100755
--- a/dpf/utils/png2c.py
+++ b/dpf/utils/res2c.py
@@ -19,7 +19,7 @@ import os, sys
# -----------------------------------------------------
-def png2c(namespace, filenames):
+def res2c(namespace, filenames):
fdH = open("%s.hpp" % namespace, "w")
fdH.write("/* (Auto-generated binary data file). */\n")
@@ -42,12 +42,12 @@ def png2c(namespace, filenames):
shortFilename = filename.rsplit(os.sep, 1)[-1].split(".", 1)[0]
shortFilename = shortFilename.replace("-", "_")
- pngData = open(filename, 'rb').read()
+ resData = open(filename, 'rb').read()
print("Generating data for \"%s\"" % (filename))
fdH.write(" extern const char* %sData;\n" % shortFilename)
- fdH.write(" const unsigned int %sDataSize = %i;\n" % (shortFilename, len(pngData)))
+ fdH.write(" const unsigned int %sDataSize = %i;\n" % (shortFilename, len(resData)))
if tempIndex != len(filenames):
fdH.write("\n")
@@ -57,7 +57,7 @@ def png2c(namespace, filenames):
curColumn = 1
fdC.write(" ")
- for data in pngData:
+ for data in resData:
if curColumn == 0:
fdC.write(" ")
@@ -90,24 +90,24 @@ def png2c(namespace, filenames):
if __name__ == '__main__':
if len(sys.argv) != 3:
- print("Usage: %s " % sys.argv[0])
+ print("Usage: %s " % sys.argv[0])
quit()
namespace = sys.argv[1].replace("-","_")
- artFolder = sys.argv[2]
+ resFolder = sys.argv[2]
- if not os.path.exists(artFolder):
- print("Folder '%s' does not exist" % artFolder)
+ if not os.path.exists(resFolder):
+ print("Folder '%s' does not exist" % resFolder)
quit()
- # find png files
- pngFiles = []
+ # find resource files
+ resFiles = []
- for root, dirs, files in os.walk(artFolder):
- for name in [name for name in files if name.lower().endswith(".png")]:
- pngFiles.append(os.path.join(root, name))
+ for root, dirs, files in os.walk(resFolder):
+ for name in files:
+ resFiles.append(os.path.join(root, name))
- pngFiles.sort()
+ resFiles.sort()
# create code now
- png2c(namespace, pngFiles)
+ res2c(namespace, resFiles)
diff --git a/plugins/Kars/DistrhoPluginKars.cpp b/plugins/Kars/DistrhoPluginKars.cpp
index 910a4dc..b3d1b43 100644
--- a/plugins/Kars/DistrhoPluginKars.cpp
+++ b/plugins/Kars/DistrhoPluginKars.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Kars Plugin, based on karplong by Chris Cannam.
- * Copyright (C) 2015 Filipe Coelho
+ * Copyright (C) 2015-2019 Filipe Coelho
*
* 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
@@ -158,7 +158,8 @@ public:
midiEvents(m),
midiEventCount(0),
remainingFrames(f),
- remainingMidiEventCount(mc) {}
+ remainingMidiEventCount(mc),
+ totalFramesUsed(0) {}
/**
Process a batch of events untill no more are available.
@@ -166,41 +167,76 @@ public:
*/
bool nextEvent()
{
- if (remainingMidiEventCount == 0)
+ // nothing else to do
+ if (remainingFrames == 0)
+ return false;
+
+ // initial setup, need to find first MIDI event
+ if (totalFramesUsed == 0)
{
- if (remainingFrames == 0)
- return false;
+ // no MIDI events at all in this process cycle
+ if (remainingMidiEventCount == 0)
+ {
+ frames = remainingFrames;
+ remainingFrames = 0;
+ totalFramesUsed += frames;
+ return true;
+ }
+ // render audio until first midi event, if needed
+ if (const uint32_t firstEventFrame = midiEvents[0].frame)
+ {
+ frames = midiEvents[0].frame;
+ remainingFrames -= frames;
+ totalFramesUsed += frames;
+ return true;
+ }
+ }
+ else
+ {
for (uint32_t i=0; i(midiEvents);
+ for (uint32_t i=0; i < midiEventCount; ++i)
+ rwEvents[i].frame -= totalFramesUsed;
+ }
+
+ frames = remainingFrames - firstEventFrame;
remainingFrames -= frames;
remainingMidiEventCount -= midiEventCount;
+ totalFramesUsed += frames;
return true;
}
@@ -208,6 +244,7 @@ private:
/** @internal */
uint32_t remainingFrames;
uint32_t remainingMidiEventCount;
+ uint32_t totalFramesUsed;
};
void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)
@@ -254,9 +291,9 @@ void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, con
if (fNotes[i].on != kNoteNull)
addSamples(out, i, amsh.frames);
}
- }
- fBlockStart += frames;
+ fBlockStart += amsh.frames;
+ }
}
void DistrhoPluginKars::addSamples(float* out, int voice, uint32_t frames)
diff --git a/plugins/Kars/DistrhoPluginKars.hpp b/plugins/Kars/DistrhoPluginKars.hpp
index 605cc6d..e7010d3 100644
--- a/plugins/Kars/DistrhoPluginKars.hpp
+++ b/plugins/Kars/DistrhoPluginKars.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Kars Plugin, based on karplong by Chris Cannam.
- * Copyright (C) 2015 Filipe Coelho
+ * Copyright (C) 2015-2019 Filipe Coelho
*
* 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
@@ -70,7 +70,7 @@ protected:
uint32_t getVersion() const noexcept override
{
- return d_version(1, 0, 0);
+ return d_version(1, 1, 0);
}
int64_t getUniqueId() const noexcept override
diff --git a/plugins/bitcrush/Makefile b/plugins/bitcrush/Makefile
index ffa5d81..db1f481 100644
--- a/plugins/bitcrush/Makefile
+++ b/plugins/bitcrush/Makefile
@@ -24,6 +24,7 @@ include ../../dpf/Makefile.plugins.mk
# Extra flags
BUILD_CXX_FLAGS += -I../common -I../common/gen_dsp
+BUILD_CXX_FLAGS += -Wno-unused-parameter
# --------------------------------------------------------------
# Enable all possible plugin types
diff --git a/plugins/freeverb/Makefile b/plugins/freeverb/Makefile
index 4d3830d..bf751bb 100644
--- a/plugins/freeverb/Makefile
+++ b/plugins/freeverb/Makefile
@@ -24,6 +24,7 @@ include ../../dpf/Makefile.plugins.mk
# Extra flags
BUILD_CXX_FLAGS += -I../common -I../common/gen_dsp
+BUILD_CXX_FLAGS += -Wno-unused-parameter
# --------------------------------------------------------------
# Enable all possible plugin types
diff --git a/plugins/gigaverb/Makefile b/plugins/gigaverb/Makefile
index 5cdf142..044d70f 100644
--- a/plugins/gigaverb/Makefile
+++ b/plugins/gigaverb/Makefile
@@ -24,6 +24,7 @@ include ../../dpf/Makefile.plugins.mk
# Extra flags
BUILD_CXX_FLAGS += -I../common -I../common/gen_dsp
+BUILD_CXX_FLAGS += -Wno-unused-parameter
# --------------------------------------------------------------
# Enable all possible plugin types
diff --git a/plugins/glBars/DistrhoUIGLBars.cpp b/plugins/glBars/DistrhoUIGLBars.cpp
index ef1421e..e1fa610 100644
--- a/plugins/glBars/DistrhoUIGLBars.cpp
+++ b/plugins/glBars/DistrhoUIGLBars.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
* Copyright (C) 2000 Christian Zander
* Copyright (C) 2015 Nedko Arnaudov
- * Copyright (C) 2016 Filipe Coelho
+ * Copyright (C) 2016-2019 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
diff --git a/plugins/glBars/DistrhoUIGLBars.hpp b/plugins/glBars/DistrhoUIGLBars.hpp
index 72139bd..997522b 100644
--- a/plugins/glBars/DistrhoUIGLBars.hpp
+++ b/plugins/glBars/DistrhoUIGLBars.hpp
@@ -3,7 +3,7 @@
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
* Copyright (C) 2000 Christian Zander
* Copyright (C) 2015 Nedko Arnaudov
- * Copyright (C) 2016 Filipe Coelho
+ * Copyright (C) 2016-2019 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -45,7 +45,6 @@ protected:
// UI Callbacks
void uiIdle() override;
-// void uiReshape(uint width, uint height) override;
// -------------------------------------------------------------------
// Widget Callbacks
diff --git a/plugins/glBars/glBars.hpp b/plugins/glBars/glBars.hpp
index 50df05c..66f7be5 100644
--- a/plugins/glBars/glBars.hpp
+++ b/plugins/glBars/glBars.hpp
@@ -3,7 +3,7 @@
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
* Copyright (C) 2000 Christian Zander
* Copyright (C) 2015 Nedko Arnaudov
- * Copyright (C) 2016 Filipe Coelho
+ * Copyright (C) 2016-2019 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
#ifndef GLBARS_STATE_HPP_INCLUDED
#define GLBARS_STATE_HPP_INCLUDED
-#include "Base.hpp"
+#include "OpenGL.hpp"
static inline
void draw_rectangle(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
diff --git a/plugins/pitchshift/Makefile b/plugins/pitchshift/Makefile
index 65090c2..bff87fa 100644
--- a/plugins/pitchshift/Makefile
+++ b/plugins/pitchshift/Makefile
@@ -24,6 +24,7 @@ include ../../dpf/Makefile.plugins.mk
# Extra flags
BUILD_CXX_FLAGS += -I../common -I../common/gen_dsp
+BUILD_CXX_FLAGS += -Wno-unused-parameter
# --------------------------------------------------------------
# Enable all possible plugin types