Browse Source

Update dpf

Signed-off-by: falkTX <falktx@falktx.com>
master
falkTX 4 months ago
parent
commit
0d682df5a4
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
100 changed files with 21293 additions and 7844 deletions
  1. +50
    -0
      dpf/CMakeLists.txt
  2. +1
    -1
      dpf/LICENSE
  3. +82
    -15
      dpf/Makefile.base.mk
  4. +146
    -29
      dpf/Makefile.plugins.mk
  5. +2
    -0
      dpf/README.md
  6. +660
    -0
      dpf/cmake/DPF-plugin.cmake
  7. +33
    -14
      dpf/dgl/Application.hpp
  8. +83
    -25
      dpf/dgl/Base.hpp
  9. +160
    -7
      dpf/dgl/Cairo.hpp
  10. +13
    -8
      dpf/dgl/Color.hpp
  11. +117
    -36
      dpf/dgl/Geometry.hpp
  12. +10
    -99
      dpf/dgl/Image.hpp
  13. +47
    -16
      dpf/dgl/ImageBase.hpp
  14. +223
    -0
      dpf/dgl/ImageBaseWidgets.hpp
  15. +13
    -255
      dpf/dgl/ImageWidgets.hpp
  16. +88
    -25
      dpf/dgl/Makefile
  17. +39
    -19
      dpf/dgl/NanoVG.hpp
  18. +175
    -3
      dpf/dgl/OpenGL.hpp
  19. +35
    -20
      dpf/dgl/StandaloneWindow.hpp
  20. +163
    -0
      dpf/dgl/SubWidget.hpp
  21. +125
    -0
      dpf/dgl/TopLevelWidget.hpp
  22. +103
    -0
      dpf/dgl/Vulkan.hpp
  23. +157
    -122
      dpf/dgl/Widget.hpp
  24. +336
    -64
      dpf/dgl/Window.hpp
  25. +33
    -30
      dpf/dgl/src/Application.cpp
  26. +159
    -0
      dpf/dgl/src/ApplicationPrivateData.cpp
  27. +68
    -38
      dpf/dgl/src/ApplicationPrivateData.hpp
  28. +733
    -36
      dpf/dgl/src/Cairo.cpp
  29. +34
    -37
      dpf/dgl/src/Color.cpp
  30. +72
    -8
      dpf/dgl/src/Common.hpp
  31. +231
    -182
      dpf/dgl/src/Geometry.cpp
  32. +0
    -150
      dpf/dgl/src/Image.cpp
  33. +57
    -31
      dpf/dgl/src/ImageBase.cpp
  34. +1061
    -0
      dpf/dgl/src/ImageBaseWidgets.cpp
  35. +0
    -1108
      dpf/dgl/src/ImageWidgets.cpp
  36. +56
    -68
      dpf/dgl/src/NanoVG.cpp
  37. +575
    -58
      dpf/dgl/src/OpenGL.cpp
  38. +163
    -0
      dpf/dgl/src/SubWidget.cpp
  39. +44
    -0
      dpf/dgl/src/SubWidgetPrivateData.cpp
  40. +49
    -0
      dpf/dgl/src/SubWidgetPrivateData.hpp
  41. +98
    -0
      dpf/dgl/src/TopLevelWidget.cpp
  42. +168
    -0
      dpf/dgl/src/TopLevelWidgetPrivateData.cpp
  43. +51
    -0
      dpf/dgl/src/TopLevelWidgetPrivateData.hpp
  44. +243
    -0
      dpf/dgl/src/Vulkan.cpp
  45. +46
    -94
      dpf/dgl/src/Widget.cpp
  46. +212
    -63
      dpf/dgl/src/WidgetPrivateData.cpp
  47. +22
    -47
      dpf/dgl/src/WidgetPrivateData.hpp
  48. +191
    -1660
      dpf/dgl/src/Window.cpp
  49. +1158
    -0
      dpf/dgl/src/WindowPrivateData.cpp
  50. +309
    -0
      dpf/dgl/src/WindowPrivateData.hpp
  51. +176
    -62
      dpf/dgl/src/nanovg/fontstash.h
  52. +268
    -94
      dpf/dgl/src/nanovg/nanovg.c
  53. +95
    -18
      dpf/dgl/src/nanovg/nanovg.h
  54. +197
    -62
      dpf/dgl/src/nanovg/nanovg_gl.h
  55. +29
    -7
      dpf/dgl/src/nanovg/nanovg_gl_utils.h
  56. +4160
    -1152
      dpf/dgl/src/nanovg/stb_image.h
  57. +5011
    -2081
      dpf/dgl/src/nanovg/stb_truetype.h
  58. +0
    -0
      dpf/dgl/src/pugl-custom/pugl.h
  59. +0
    -0
      dpf/dgl/src/pugl-custom/pugl_haiku.cpp
  60. +0
    -0
      dpf/dgl/src/pugl-custom/pugl_internal.h
  61. +0
    -0
      dpf/dgl/src/pugl-custom/pugl_osx.m
  62. +0
    -0
      dpf/dgl/src/pugl-custom/pugl_win.cpp
  63. +3
    -0
      dpf/dgl/src/pugl-custom/pugl_x11.c
  64. +29
    -0
      dpf/dgl/src/pugl-extra/extras.c
  65. +50
    -0
      dpf/dgl/src/pugl-extra/extras.h
  66. +81
    -0
      dpf/dgl/src/pugl-extra/haiku.cpp
  67. +35
    -0
      dpf/dgl/src/pugl-extra/haiku.h
  68. +48
    -0
      dpf/dgl/src/pugl-extra/mac.m
  69. +118
    -0
      dpf/dgl/src/pugl-extra/win.c
  70. +111
    -0
      dpf/dgl/src/pugl-extra/x11.c
  71. +28
    -0
      dpf/dgl/src/pugl-upstream/.clang-format
  72. +4
    -0
      dpf/dgl/src/pugl-upstream/.clang-tidy
  73. +13
    -0
      dpf/dgl/src/pugl-upstream/.clant.json
  74. +19
    -0
      dpf/dgl/src/pugl-upstream/.editorconfig
  75. +3
    -0
      dpf/dgl/src/pugl-upstream/.gitignore
  76. +153
    -0
      dpf/dgl/src/pugl-upstream/.gitlab-ci.yml
  77. +15
    -0
      dpf/dgl/src/pugl-upstream/.includes.imp
  78. +13
    -0
      dpf/dgl/src/pugl-upstream/AUTHORS
  79. +13
    -0
      dpf/dgl/src/pugl-upstream/COPYING
  80. +98
    -0
      dpf/dgl/src/pugl-upstream/README.md
  81. +14
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/.clang-tidy
  82. +12
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/meson.build
  83. +45
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/pugl/cairo.hpp
  84. +70
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/pugl/gl.hpp
  85. +734
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/pugl/pugl.hpp
  86. +45
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/pugl/stub.hpp
  87. +168
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/pugl/vulkan.hpp
  88. +7
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/meson.build
  89. +2
    -0
      dpf/dgl/src/pugl-upstream/doc/_static/meson.build
  90. +32
    -0
      dpf/dgl/src/pugl-upstream/doc/c/Doxyfile.in
  91. +5
    -0
      dpf/dgl/src/pugl-upstream/doc/c/api/meson.build
  92. +101
    -0
      dpf/dgl/src/pugl-upstream/doc/c/event-loop.rst
  93. +84
    -0
      dpf/dgl/src/pugl-upstream/doc/c/events.rst
  94. +11
    -0
      dpf/dgl/src/pugl-upstream/doc/c/index.rst
  95. +48
    -0
      dpf/dgl/src/pugl-upstream/doc/c/meson.build
  96. +26
    -0
      dpf/dgl/src/pugl-upstream/doc/c/overview.rst
  97. +20
    -0
      dpf/dgl/src/pugl-upstream/doc/c/shutting-down.rst
  98. +321
    -0
      dpf/dgl/src/pugl-upstream/doc/c/view.rst
  99. +65
    -0
      dpf/dgl/src/pugl-upstream/doc/c/world.rst
  100. +19
    -0
      dpf/dgl/src/pugl-upstream/doc/c/xml/meson.build

+ 50
- 0
dpf/CMakeLists.txt View File

@@ -0,0 +1,50 @@
# DISTRHO Plugin Framework (DPF)
# Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
#
# SPDX-License-Identifier: ISC

cmake_minimum_required(VERSION 3.7)

project(DPF)

# ensure c++11 at minimum, the parent project can override
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
endif()

# check if we are building from this project, or are imported by another
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(DPF_BUILD_FROM_HERE TRUE)
else()
set(DPF_BUILD_FROM_HERE FALSE)
endif()

option(DPF_LIBRARIES "Build the libraries" "${DPF_BUILD_FROM_HERE}")
option(DPF_EXAMPLES "Build the examples" "${DPF_BUILD_FROM_HERE}")

set(DPF_ROOT_DIR "${PROJECT_SOURCE_DIR}" CACHE INTERNAL
"Root directory of the DISTRHO Plugin Framework.")

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(DPF-plugin)

if(DPF_LIBRARIES)
if(NOT (MSVC OR APPLE)) # TODO skip this one for now
dpf__add_dgl_cairo()
endif()
dpf__add_dgl_opengl()
endif()

if(DPF_EXAMPLES)
if(NOT (MSVC OR APPLE)) # TODO skip this one for now
add_subdirectory("examples/CairoUI")
endif()
#add_subdirectory("examples/ExternalUI")
add_subdirectory("examples/FileHandling")
add_subdirectory("examples/Info")
add_subdirectory("examples/Latency")
add_subdirectory("examples/Meters")
add_subdirectory("examples/MidiThrough")
add_subdirectory("examples/Parameters")
add_subdirectory("examples/States")
endif()

+ 1
- 1
dpf/LICENSE View File

@@ -1,5 +1,5 @@
DISTRHO Plugin Framework (DPF)
Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>

Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this


+ 82
- 15
dpf/Makefile.base.mk View File

@@ -38,6 +38,9 @@ endif
ifneq (,$(findstring mingw,$(TARGET_MACHINE)))
WINDOWS=true
endif
ifneq (,$(findstring windows,$(TARGET_MACHINE)))
WINDOWS=true
endif

endif
endif
@@ -148,6 +151,9 @@ endif
ifeq ($(MACOS),true)
# MacOS linker flags
LINK_OPTS = -fdata-sections -ffunction-sections -Wl,-dead_strip -Wl,-dead_strip_dylibs
ifneq ($(SKIP_STRIPPING),true)
LINK_OPTS += -Wl,-x
endif
else
# Common linker flags
LINK_OPTS = -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed
@@ -157,19 +163,13 @@ endif
endif

ifeq ($(NOOPT),true)
# No CPU-specific optimization flags
# Non-CPU-specific optimization flags
BASE_OPTS = -O2 -ffast-math -fdata-sections -ffunction-sections
endif

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
# Needed for windows, see https://github.com/falkTX/Carla/issues/855
BASE_OPTS += -mstackrealign
ifeq ($(BUILDING_FOR_WINDOWS),true)
BASE_FLAGS += -DBUILDING_CARLA_FOR_WINDOWS
endif
else
# Not needed for Windows
BASE_FLAGS += -fPIC -DPIC
@@ -206,7 +206,7 @@ endif

ifeq ($(TESTBUILD),true)
BASE_FLAGS += -Werror -Wcast-qual -Wconversion -Wformat -Wformat-security -Wredundant-decls -Wshadow -Wstrict-overflow -fstrict-overflow -Wundef -Wwrite-strings
BASE_FLAGS += -Wpointer-arith -Wabi -Winit-self -Wuninitialized -Wstrict-overflow=5
BASE_FLAGS += -Wpointer-arith -Wabi=98 -Winit-self -Wuninitialized -Wstrict-overflow=5
# BASE_FLAGS += -Wfloat-equal
ifeq ($(CC),clang)
BASE_FLAGS += -Wdocumentation -Wdocumentation-unknown-command
@@ -228,20 +228,28 @@ endif
# Check for required libraries

HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true)
HAVE_VULKAN = $(shell $(PKG_CONFIG) --exists vulkan && echo true)

ifeq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
ifeq ($(MACOS_OR_WINDOWS),true)
HAVE_OPENGL = true
else
HAVE_OPENGL = $(shell $(PKG_CONFIG) --exists gl && echo true)
HAVE_X11 = $(shell $(PKG_CONFIG) --exists x11 && echo true)
ifneq ($(HAIKU),true)
HAVE_X11 = $(shell $(PKG_CONFIG) --exists x11 && echo true)
HAVE_XCURSOR = $(shell $(PKG_CONFIG) --exists xcursor && echo true)
HAVE_XEXT = $(shell $(PKG_CONFIG) --exists xext && echo true)
HAVE_XRANDR = $(shell $(PKG_CONFIG) --exists xrandr && echo true)
endif
endif

# ---------------------------------------------------------------------------------------------------------------------
# Check for optional libraries

HAVE_JACK = $(shell $(PKG_CONFIG) --exists jack && echo true)
HAVE_LIBLO = $(shell $(PKG_CONFIG) --exists liblo && echo true)

# backwards compat
HAVE_JACK = true

# ---------------------------------------------------------------------------------------------------------------------
# Set Generic DGL stuff

@@ -250,7 +258,7 @@ DGL_SYSTEM_LIBS += -lbe
endif

ifeq ($(MACOS),true)
DGL_SYSTEM_LIBS += -framework Cocoa
DGL_SYSTEM_LIBS += -framework Cocoa -framework CoreVideo
endif

ifeq ($(WINDOWS),true)
@@ -259,8 +267,21 @@ endif

ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
ifeq ($(HAVE_X11),true)
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags x11)
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags x11) -DHAVE_X11
DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs x11)
ifeq ($(HAVE_XCURSOR),true)
# TODO -DHAVE_XCURSOR
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags xcursor)
DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs xcursor)
endif
ifeq ($(HAVE_XEXT),true)
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags xext) -DHAVE_XEXT -DHAVE_XSYNC
DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs xext)
endif
ifeq ($(HAVE_XRANDR),true)
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags xrandr) -DHAVE_XRANDR
DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs xrandr)
endif
endif
endif

@@ -291,7 +312,7 @@ OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl)
endif

ifeq ($(MACOS),true)
OPENGL_FLAGS = -DGL_SILENCE_DEPRECATION=1
OPENGL_FLAGS = -DGL_SILENCE_DEPRECATION=1 -Wno-deprecated-declarations
OPENGL_LIBS = -framework OpenGL
endif

@@ -308,6 +329,52 @@ HAVE_CAIRO_OR_OPENGL = true

endif

# ---------------------------------------------------------------------------------------------------------------------
# Set Stub specific stuff

ifeq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
HAVE_STUB = true
else
HAVE_STUB = $(HAVE_X11)
endif

# ---------------------------------------------------------------------------------------------------------------------
# Set Vulkan specific stuff

ifeq ($(HAVE_VULKAN),true)

DGL_FLAGS += -DHAVE_VULKAN

VULKAN_FLAGS = $(shell $(PKG_CONFIG) --cflags vulkan)
VULKAN_LIBS = $(shell $(PKG_CONFIG) --libs vulkan)

ifneq ($(WINDOWS),true)
VULKAN_LIBS += -ldl
endif

endif

# ---------------------------------------------------------------------------------------------------------------------
# Set optional libraries specific stuff

ifeq ($(HAVE_LIBLO),true)
LIBLO_FLAGS = $(shell $(PKG_CONFIG) --cflags liblo)
LIBLO_LIBS = $(shell $(PKG_CONFIG) --libs liblo)
endif

# ---------------------------------------------------------------------------------------------------------------------
# Backwards-compatible HAVE_DGL

ifeq ($(MACOS_OR_WINDOWS),true)
HAVE_DGL = true
else ifeq ($(HAVE_OPENGL),true)
ifeq ($(HAIKU),true)
HAVE_DGL = true
else
HAVE_DGL = $(HAVE_X11)
endif
endif

# ---------------------------------------------------------------------------------------------------------------------
# Set app extension



+ 146
- 29
dpf/Makefile.plugins.mk View File

@@ -7,37 +7,62 @@
# NOTE: NAME, FILES_DSP and FILES_UI must have been defined before including this file!


ifeq ($(DPF_CUSTOM_PATH),)
ifeq (,$(wildcard ../../Makefile.base.mk))
DPF_PATH=../../dpf
else
DPF_PATH=../..
endif
else
DPF_PATH = $(DPF_CUSTOM_PATH)
endif

include $(DPF_PATH)/Makefile.base.mk

# ---------------------------------------------------------------------------------------------------------------------
# Basic setup

ifeq ($(DPF_CUSTOM_PATH),)
TARGET_DIR = ../../bin
BUILD_DIR = ../../build/$(NAME)
else
ifeq ($(DPF_CUSTOM_TARGET_DIR),)
$(error DPF_CUSTOM_TARGET_DIR is not set)
else
TARGET_DIR = $(DPF_CUSTOM_TARGET_DIR)
endif
ifeq ($(DPF_CUSTOM_BUILD_DIR),)
$(error DPF_CUSTOM_BUILD_DIR is not set)
else
BUILD_DIR = $(DPF_CUSTOM_BUILD_DIR)
endif
endif

BUILD_C_FLAGS += -I.
BUILD_CXX_FLAGS += -I. -I$(DPF_PATH)/distrho -I$(DPF_PATH)/dgl

ifeq ($(HAVE_CAIRO),true)
DGL_FLAGS += -DHAVE_CAIRO
ifeq ($(HAVE_LIBLO),true)
BASE_FLAGS += -DHAVE_LIBLO
endif

ifeq ($(HAVE_OPENGL),true)
DGL_FLAGS += -DHAVE_OPENGL
ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true)
JACK_LIBS = -ldl
endif

ifeq ($(HAVE_JACK),true)
# backwards compat
BASE_FLAGS += -DHAVE_JACK
endif

ifeq ($(HAVE_LIBLO),true)
BASE_FLAGS += -DHAVE_LIBLO
# ---------------------------------------------------------------------------------------------------------------------
# Set VST3 filename, see https://vst3sdk-doc.diatonic.jp/doc/vstinterfaces/vst3loc.html

ifeq ($(LINUX),true)
VST3_FILENAME = $(TARGET_PROCESSOR)-linux/$(NAME).so
endif
ifeq ($(MACOS),true)
VST3_FILENAME = MacOS/$(NAME)
endif
ifeq ($(WINDOWS),true)
VST3_FILENAME = $(TARGET_PROCESSOR)-win/$(NAME).vst3
endif

# ---------------------------------------------------------------------------------------------------------------------
@@ -46,6 +71,10 @@ endif
OBJS_DSP = $(FILES_DSP:%=$(BUILD_DIR)/%.o)
OBJS_UI = $(FILES_UI:%=$(BUILD_DIR)/%.o)

ifeq ($(MACOS),true)
OBJS_UI += $(BUILD_DIR)/DistrhoUI_macOS_$(NAME).mm.o
endif

# ---------------------------------------------------------------------------------------------------------------------
# Set plugin binary file targets

@@ -56,12 +85,28 @@ dssi_ui = $(TARGET_DIR)/$(NAME)-dssi/$(NAME)_ui$(APP_EXT)
lv2 = $(TARGET_DIR)/$(NAME).lv2/$(NAME)$(LIB_EXT)
lv2_dsp = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_dsp$(LIB_EXT)
lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui$(LIB_EXT)
vst = $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT)
vst2 = $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT)
ifneq ($(VST3_FILENAME),)
vst3 = $(TARGET_DIR)/$(NAME).vst3/Contents/$(VST3_FILENAME)
endif

# ---------------------------------------------------------------------------------------------------------------------
# Set plugin symbols to export

ifeq ($(MACOS),true)
SYMBOLS_LADSPA = -Wl,-exported_symbol,_ladspa_descriptor
SYMBOLS_DSSI = -Wl,-exported_symbol,_ladspa_descriptor -Wl,-exported_symbol,_dssi_descriptor
SYMBOLS_LV2 = -Wl,-exported_symbol,_lv2_descriptor -Wl,-exported_symbol,_lv2_generate_ttl
SYMBOLS_LV2UI = -Wl,-exported_symbol,_lv2ui_descriptor
SYMBOLS_VST2 = -Wl,-exported_symbol,_VSTPluginMain
SYMBOLS_VST3 = -Wl,-exported_symbol,_GetPluginFactory -Wl,-exported_symbol,_bundleEntry -Wl,-exported_symbol,_bundleExit
endif

# ---------------------------------------------------------------------------------------------------------------------
# Handle UI stuff, disable UI support automatically

ifeq ($(FILES_UI),)
HAVE_DGL = false
UI_TYPE = none
endif

@@ -69,9 +114,17 @@ ifeq ($(UI_TYPE),)
UI_TYPE = opengl
endif

ifeq ($(UI_TYPE),generic)
ifeq ($(HAVE_OPENGL),true)
UI_TYPE = opengl
else ifeq ($(HAVE_CAIRO),true)
UI_TYPE = cairo
endif
endif

ifeq ($(UI_TYPE),cairo)
DGL_FLAGS += -DDGL_CAIRO
ifeq ($(HAVE_CAIRO),true)
DGL_FLAGS += -DDGL_CAIRO
DGL_FLAGS += $(CAIRO_FLAGS)
DGL_LIBS += $(CAIRO_LIBS)
DGL_LIB = $(DPF_PATH)/build/libdgl-cairo.a
@@ -82,8 +135,8 @@ endif
endif

ifeq ($(UI_TYPE),opengl)
DGL_FLAGS += -DDGL_OPENGL
ifeq ($(HAVE_OPENGL),true)
DGL_FLAGS += -DDGL_OPENGL
DGL_FLAGS += $(OPENGL_FLAGS)
DGL_LIBS += $(OPENGL_LIBS)
DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a
@@ -93,11 +146,32 @@ HAVE_DGL = false
endif
endif

ifeq ($(UI_TYPE),vulkan)
ifeq ($(HAVE_VULKAN),true)
DGL_FLAGS += -DDGL_VULKAN
DGL_FLAGS += $(VULKAN_FLAGS)
DGL_LIBS += $(VULKAN_LIBS)
DGL_LIB = $(DPF_PATH)/build/libdgl-vulkan.a
HAVE_DGL = true
else
HAVE_DGL = false
endif
endif

ifeq ($(UI_TYPE),external)
DGL_FLAGS += -DDGL_EXTERNAL
HAVE_DGL = true
endif

ifeq ($(UI_TYPE),stub)
ifeq ($(HAVE_STUB),true)
DGL_LIB = $(DPF_PATH)/build/libdgl-stub.a
HAVE_DGL = true
else
HAVE_DGL = false
endif
endif

DGL_LIBS += $(DGL_SYSTEM_LIBS) -lm

ifneq ($(HAVE_DGL),true)
@@ -107,6 +181,10 @@ DGL_LIBS =
OBJS_UI =
endif

ifneq ($(HAVE_LIBLO),true)
dssi_ui =
endif

# TODO split dsp and ui object build flags
BASE_FLAGS += $(DGL_FLAGS)

@@ -118,6 +196,11 @@ all:
# ---------------------------------------------------------------------------------------------------------------------
# Common

$(BUILD_DIR)/%.S.o: %.S
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<"
@$(CC) $< $(BUILD_C_FLAGS) -c -o $@

$(BUILD_DIR)/%.c.o: %.c
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<"
@@ -138,6 +221,23 @@ clean:
rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2

# ---------------------------------------------------------------------------------------------------------------------
# DGL

$(DPF_PATH)/build/libdgl-cairo.a:
$(MAKE) -C $(DPF_PATH)/dgl cairo

$(DPF_PATH)/build/libdgl-opengl.a:
$(MAKE) -C $(DPF_PATH)/dgl opengl

$(DPF_PATH)/build/libdgl-stub.a:
$(MAKE) -C $(DPF_PATH)/dgl stub

$(DPF_PATH)/build/libdgl-vulkan.a:
$(MAKE) -C $(DPF_PATH)/dgl vulkan

# ---------------------------------------------------------------------------------------------------------------------

AS_PUGL_NAMESPACE = $(subst -,_,$(1))

$(BUILD_DIR)/DistrhoPluginMain_%.cpp.o: $(DPF_PATH)/distrho/DistrhoPluginMain.cpp
-@mkdir -p $(BUILD_DIR)
@@ -149,15 +249,20 @@ $(BUILD_DIR)/DistrhoUIMain_%.cpp.o: $(DPF_PATH)/distrho/DistrhoUIMain.cpp
@echo "Compiling DistrhoUIMain.cpp ($*)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -DDISTRHO_PLUGIN_TARGET_$* -c -o $@

$(BUILD_DIR)/DistrhoUI_macOS_%.mm.o: $(DPF_PATH)/distrho/DistrhoUI_macOS.mm
-@mkdir -p $(BUILD_DIR)
@echo "Compiling DistrhoUI_macOS.mm ($*)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -DPUGL_NAMESPACE=$(call AS_PUGL_NAMESPACE,$*) -DGL_SILENCE_DEPRECATION -Wno-deprecated-declarations -I$(DPF_PATH)/dgl/src -I$(DPF_PATH)/dgl/src/pugl-upstream/include -ObjC++ -c -o $@

$(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o: $(DPF_PATH)/distrho/DistrhoPluginMain.cpp
-@mkdir -p $(BUILD_DIR)
@echo "Compiling DistrhoPluginMain.cpp (JACK)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(shell $(PKG_CONFIG) --cflags jack) -DDISTRHO_PLUGIN_TARGET_JACK -c -o $@
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -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)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(shell $(PKG_CONFIG) --cflags liblo) -DDISTRHO_PLUGIN_TARGET_DSSI -c -o $@
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(LIBLO_FLAGS) -DDISTRHO_PLUGIN_TARGET_DSSI -c -o $@

# ---------------------------------------------------------------------------------------------------------------------
# JACK
@@ -171,7 +276,7 @@ $(jack): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o
endif
-@mkdir -p $(shell dirname $@)
@echo "Creating JACK standalone for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell $(PKG_CONFIG) --libs jack) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(JACK_LIBS) -o $@

# ---------------------------------------------------------------------------------------------------------------------
# LADSPA
@@ -181,7 +286,7 @@ ladspa: $(ladspa_dsp)
$(ladspa_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_LADSPA.cpp.o
-@mkdir -p $(shell dirname $@)
@echo "Creating LADSPA plugin for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) $(SYMBOLS_LADSPA) -o $@

# ---------------------------------------------------------------------------------------------------------------------
# DSSI
@@ -193,12 +298,12 @@ dssi_ui: $(dssi_ui)
$(dssi_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_DSSI.cpp.o
-@mkdir -p $(shell dirname $@)
@echo "Creating DSSI plugin library for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) $(SYMBOLS_DSSI) -o $@

$(dssi_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@)
@echo "Creating DSSI UI for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell $(PKG_CONFIG) --libs liblo) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(LIBLO_LIBS) -o $@

# ---------------------------------------------------------------------------------------------------------------------
# LV2
@@ -210,36 +315,46 @@ lv2_sep: $(lv2_dsp) $(lv2_ui)
$(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)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2) $(SYMBOLS_LV2UI) -o $@

$(lv2_dsp): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin library for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) $(SYMBOLS_LV2) -o $@

$(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin UI for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -o $@
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2UI) -o $@

# ---------------------------------------------------------------------------------------------------------------------
# VST
# VST2

vst: $(vst)
vst2 vst: $(vst2)

ifeq ($(HAVE_DGL),true)
$(vst): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST.cpp.o $(DGL_LIB)
$(vst2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST2.cpp.o $(DGL_LIB)
else
$(vst): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.o
$(vst2): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o
endif
-@mkdir -p $(shell dirname $@)
@echo "Creating VST plugin for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -o $@
@echo "Creating VST2 plugin for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_VST2) -o $@

# ---------------------------------------------------------------------------------------------------------------------
# VST3

vst3: $(vst3)

$(vst3): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.o
-@mkdir -p $(shell dirname $@)
@echo "Creating VST3 plugin for $(NAME)"
$(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_VST3) -o $@

# ---------------------------------------------------------------------------------------------------------------------

-include $(OBJS_DSP:%.o=%.d)
ifeq ($(HAVE_DGL),true)
ifneq ($(UI_TYPE),)
-include $(OBJS_UI:%.o=%.d)
endif

@@ -247,11 +362,13 @@ endif
-include $(BUILD_DIR)/DistrhoPluginMain_LADSPA.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_DSSI.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_VST.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.d

-include $(BUILD_DIR)/DistrhoUIMain_JACK.cpp.d
-include $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.d
-include $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.d
-include $(BUILD_DIR)/DistrhoUIMain_VST.cpp.d
-include $(BUILD_DIR)/DistrhoUIMain_VST2.cpp.d
-include $(BUILD_DIR)/DistrhoUIMain_VST3.cpp.d

# ---------------------------------------------------------------------------------------------------------------------

+ 2
- 0
dpf/README.md View File

@@ -45,12 +45,14 @@ Online help and discussion about DPF happens in the [KXStudio chat DPF room](htt
- [Stone Phaser](https://github.com/jpcima/stone-phaser)
- [String-machine](https://github.com/jpcima/string-machine)
- [Uhhyou Plugins](https://github.com/ryukau/LV2Plugins)
- [VL1-emulator](https://github.com/linuxmao-org/VL1-emulator)
- [Wolf Shaper](https://github.com/pdesaulniers/wolf-shaper)
- [Wolf Spectrum](https://github.com/pdesaulniers/wolf-spectrum)
- [YK Chorus](https://github.com/SpotlightKid/ykchorus)
- [ZamAudio Suite](https://github.com/zamaudio/zam-plugins)
## Work in progress
- [CV-LFO-blender-LV2](https://github.com/BramGiesen/cv-lfo-blender-lv2)
- [fverb](https://github.com/jpcima/fverb)
- [Juice Plugins](https://github.com/DISTRHO/JuicePlugins)
- [gunshot](https://github.com/soerenbnoergaard/gunshot)
- [midiomatic](https://github.com/SpotlightKid/midiomatic)


+ 660
- 0
dpf/cmake/DPF-plugin.cmake View File

@@ -0,0 +1,660 @@
# DISTRHO Plugin Framework (DPF)
# Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
#
# SPDX-License-Identifier: ISC

# ------------------------------------------------------------------------------
# CMake support module for the DISTRHO Plugin Framework
#
# The purpose of this module is to help building music plugins easily, when the
# project uses CMake as its build system.
#
# In order to use the helpers provided by this module, a plugin author should
# add DPF as a subproject, making the function `dpf_add_plugin` available.
# The usage of this function is documented below in greater detail.
#
# Example project `CMakeLists.txt`:
#
# ```
# cmake_minimum_required(VERSION 3.7)
# project(MyPlugin)
#
# add_subdirectory(DPF)
#
# dpf_add_plugin(MyPlugin
# TARGETS lv2 vst2
# UI_TYPE opengl
# FILES_DSP
# src/MyPlugin.cpp
# FILES_UI
# src/MyUI.cpp)
#
# target_include_directories(MyPlugin
# PUBLIC src)
# ```
#
# Important: note that properties, such as include directories, definitions,
# and linked libraries *must* be marked with `PUBLIC` so they take effect and
# propagate into all the plugin targets.

include(CMakeParseArguments)

# ------------------------------------------------------------------------------
# DPF public functions
# ------------------------------------------------------------------------------

# dpf_add_plugin(name <args...>)
# ------------------------------------------------------------------------------
#
# Add a plugin built using the DISTRHO Plugin Framework.
#
# ------------------------------------------------------------------------------
# Created targets:
#
# `<name>`
# static library: the common part of the plugin
# The public properties set on this target apply to both DSP and UI.
#
# `<name>-dsp`
# static library: the DSP part of the plugin
# The public properties set on this target apply to the DSP only.
#
# `<name>-ui`
# static library: the UI part of the plugin
# The public properties set on this target apply to the UI only.
#
# `<name>-<target>` for each target specified with the `TARGETS` argument.
# This is target-dependent and not intended for public use.
#
# ------------------------------------------------------------------------------
# Arguments:
#
# `TARGETS` <tgt1>...<tgtN>
# a list of one of more of the following target types:
# `jack`, `ladspa`, `dssi`, `lv2`, `vst2`
#
# `UI_TYPE` <type>
# the user interface type: `opengl` (default), `cairo`
#
# `MONOLITHIC`
# build LV2 as a single binary for UI and DSP
#
# `FILES_DSP` <file1>...<fileN>
# list of sources which are part of the DSP
#
# `FILES_UI` <file1>...<fileN>
# list of sources which are part of the UI
# empty indicates the plugin does not have UI
#
# `FILES_COMMON` <file1>...<fileN>
# list of sources which are part of both DSP and UI
#
function(dpf_add_plugin NAME)
set(options MONOLITHIC)
set(oneValueArgs UI_TYPE)
set(multiValueArgs TARGETS FILES_DSP FILES_UI FILES_COMMON)
cmake_parse_arguments(_dpf_plugin "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if("${_dpf_plugin_UI_TYPE}" STREQUAL "")
set(_dpf_plugin_UI_TYPE "opengl")
endif()

set(_dgl_library)
if(_dpf_plugin_FILES_UI)
if(_dpf_plugin_UI_TYPE STREQUAL "cairo")
dpf__add_dgl_cairo()
set(_dgl_library dgl-cairo)
elseif(_dpf_plugin_UI_TYPE STREQUAL "opengl")
dpf__add_dgl_opengl()
set(_dgl_library dgl-opengl)
else()
message(FATAL_ERROR "Unrecognized UI type for plugin: ${_dpf_plugin_UI_TYPE}")
endif()
endif()

###
dpf__ensure_sources_non_empty(_dpf_plugin_FILES_COMMON)
dpf__ensure_sources_non_empty(_dpf_plugin_FILES_DSP)
dpf__ensure_sources_non_empty(_dpf_plugin_FILES_UI)

###
dpf__add_static_library("${NAME}" ${_dpf_plugin_FILES_COMMON})
target_include_directories("${NAME}" PUBLIC
"${DPF_ROOT_DIR}/distrho")

if(_dgl_library)
# make sure that all code will see DGL_* definitions
target_link_libraries("${NAME}" PUBLIC
"${_dgl_library}-definitions"
dgl-system-libs-definitions)
endif()

dpf__add_static_library("${NAME}-dsp" ${_dpf_plugin_FILES_DSP})
target_link_libraries("${NAME}-dsp" PUBLIC "${NAME}")

if(_dgl_library)
dpf__add_static_library("${NAME}-ui" ${_dpf_plugin_FILES_UI})
target_link_libraries("${NAME}-ui" PUBLIC "${NAME}" ${_dgl_library})
# add the files containing Objective-C classes, recompiled under namespace
dpf__add_plugin_specific_ui_sources("${NAME}-ui")
else()
add_library("${NAME}-ui" INTERFACE)
endif()

###
foreach(_target ${_dpf_plugin_TARGETS})
if(_target STREQUAL "jack")
dpf__build_jack("${NAME}" "${_dgl_library}")
elseif(_target STREQUAL "ladspa")
dpf__build_ladspa("${NAME}")
elseif(_target STREQUAL "dssi")
dpf__build_dssi("${NAME}" "${_dgl_library}")
elseif(_target STREQUAL "lv2")
dpf__build_lv2("${NAME}" "${_dgl_library}" "${_dpf_plugin_MONOLITHIC}")
elseif(_target STREQUAL "vst2")
dpf__build_vst2("${NAME}" "${_dgl_library}")
else()
message(FATAL_ERROR "Unrecognized target type for plugin: ${_target}")
endif()
endforeach()
endfunction()

# ------------------------------------------------------------------------------
# DPF private functions (prefixed with `dpf__`)
# ------------------------------------------------------------------------------

# Note: The $<0:> trick is to prevent MSVC from appending the build type
# to the output directory.
#

# dpf__build_jack
# ------------------------------------------------------------------------------
#
# Add build rules for a JACK program.
#
function(dpf__build_jack NAME DGL_LIBRARY)
dpf__create_dummy_source_list(_no_srcs)

dpf__add_executable("${NAME}-jack" ${_no_srcs})
dpf__add_plugin_main("${NAME}-jack" "jack")
dpf__add_ui_main("${NAME}-jack" "jack" "${DGL_LIBRARY}")
target_link_libraries("${NAME}-jack" PRIVATE "${NAME}-dsp" "${NAME}-ui")
set_target_properties("${NAME}-jack" PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
OUTPUT_NAME "${NAME}")

# Note: libjack will be linked at runtime
if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU))
target_link_libraries("${NAME}-jack" PRIVATE "dl")
endif()
endfunction()

# dpf__build_ladspa
# ------------------------------------------------------------------------------
#
# Add build rules for a DSSI plugin.
#
function(dpf__build_ladspa NAME)
dpf__create_dummy_source_list(_no_srcs)

dpf__add_module("${NAME}-ladspa" ${_no_srcs})
dpf__add_plugin_main("${NAME}-ladspa" "ladspa")
target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-ladspa" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
OUTPUT_NAME "${NAME}-ladspa"
PREFIX "")
endfunction()

# dpf__build_dssi
# ------------------------------------------------------------------------------
#
# Add build rules for a DSSI plugin.
#
function(dpf__build_dssi NAME DGL_LIBRARY)
find_package(PkgConfig)
pkg_check_modules(LIBLO "liblo")
if(NOT LIBLO_FOUND)
dpf__warn_once_only(missing_liblo
"liblo is not found, skipping the `dssi` plugin targets")
return()
endif()

link_directories(${LIBLO_LIBRARY_DIRS})

dpf__create_dummy_source_list(_no_srcs)

dpf__add_module("${NAME}-dssi" ${_no_srcs})
dpf__add_plugin_main("${NAME}-dssi" "dssi")
target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-dssi" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
OUTPUT_NAME "${NAME}-dssi"
PREFIX "")

if(DGL_LIBRARY)
dpf__add_executable("${NAME}-dssi-ui" ${_no_srcs})
dpf__add_ui_main("${NAME}-dssi-ui" "dssi" "${DGL_LIBRARY}")
target_link_libraries("${NAME}-dssi-ui" PRIVATE "${NAME}-ui")
set_target_properties("${NAME}-dssi-ui" PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}-dssi/$<0:>"
OUTPUT_NAME "${NAME}_ui")

target_include_directories("${NAME}-dssi-ui" PRIVATE ${LIBLO_INCLUDE_DIRS})
target_link_libraries("${NAME}-dssi-ui" PRIVATE ${LIBLO_LIBRARIES})
endif()
endfunction()

# dpf__build_lv2
# ------------------------------------------------------------------------------
#
# Add build rules for a LV2 plugin.
#
function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC)
dpf__create_dummy_source_list(_no_srcs)

dpf__add_module("${NAME}-lv2" ${_no_srcs})
dpf__add_plugin_main("${NAME}-lv2" "lv2")
target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp")
set_target_properties("${NAME}-lv2" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>"
OUTPUT_NAME "${NAME}_dsp"
PREFIX "")

if(DGL_LIBRARY)
if(MONOLITHIC)
dpf__add_ui_main("${NAME}-lv2" "lv2" "${DGL_LIBRARY}")
target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-ui")
set_target_properties("${NAME}-lv2" PROPERTIES
OUTPUT_NAME "${NAME}")
else()
dpf__add_module("${NAME}-lv2-ui" ${_no_srcs})
dpf__add_ui_main("${NAME}-lv2-ui" "lv2" "${DGL_LIBRARY}")
target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui")
set_target_properties("${NAME}-lv2-ui" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>"
OUTPUT_NAME "${NAME}_ui"
PREFIX "")
endif()
endif()

dpf__add_lv2_ttl_generator()
add_dependencies("${NAME}-lv2" lv2_ttl_generator)

add_custom_command(TARGET "${NAME}-lv2" POST_BUILD
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
"$<TARGET_FILE:lv2_ttl_generator>"
"$<TARGET_FILE:${NAME}-lv2>"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2"
DEPENDS lv2_ttl_generator)
endfunction()

# dpf__build_vst2
# ------------------------------------------------------------------------------
#
# Add build rules for a VST2 plugin.
#
function(dpf__build_vst2 NAME DGL_LIBRARY)
dpf__create_dummy_source_list(_no_srcs)

dpf__add_module("${NAME}-vst2" ${_no_srcs})
dpf__add_plugin_main("${NAME}-vst2" "vst2")
dpf__add_ui_main("${NAME}-vst2" "vst2" "${DGL_LIBRARY}")
target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui")
set_target_properties("${NAME}-vst2" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>"
OUTPUT_NAME "${NAME}-vst2"
PREFIX "")
endfunction()

# dpf__add_dgl_cairo
# ------------------------------------------------------------------------------
#
# Add the Cairo variant of DGL, if not already available.
#
function(dpf__add_dgl_cairo)
if(TARGET dgl-cairo)
return()
endif()

find_package(PkgConfig)
pkg_check_modules(CAIRO "cairo" REQUIRED)

link_directories(${CAIRO_LIBRARY_DIRS})

dpf__add_static_library(dgl-cairo STATIC
"${DPF_ROOT_DIR}/dgl/src/Application.cpp"
"${DPF_ROOT_DIR}/dgl/src/ApplicationPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Color.cpp"
"${DPF_ROOT_DIR}/dgl/src/Geometry.cpp"
"${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp"
"${DPF_ROOT_DIR}/dgl/src/ImageBaseWidgets.cpp"
"${DPF_ROOT_DIR}/dgl/src/Resources.cpp"
"${DPF_ROOT_DIR}/dgl/src/SubWidget.cpp"
"${DPF_ROOT_DIR}/dgl/src/SubWidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/TopLevelWidget.cpp"
"${DPF_ROOT_DIR}/dgl/src/TopLevelWidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Widget.cpp"
"${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Window.cpp"
"${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Cairo.cpp")
if(NOT APPLE)
target_sources(dgl-cairo PRIVATE
"${DPF_ROOT_DIR}/dgl/src/pugl.cpp")
else() # Note: macOS pugl will be built as part of DistrhoUI_macOS.mm
#target_sources(dgl-opengl PRIVATE
# "${DPF_ROOT_DIR}/dgl/src/pugl.mm")
endif()
target_include_directories(dgl-cairo PUBLIC
"${DPF_ROOT_DIR}/dgl")
target_include_directories(dgl-cairo PUBLIC
"${DPF_ROOT_DIR}/dgl/src/pugl-upstream/include")

dpf__add_dgl_system_libs()
target_link_libraries(dgl-cairo PRIVATE dgl-system-libs)

add_library(dgl-cairo-definitions INTERFACE)
target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO")

target_include_directories(dgl-cairo PUBLIC ${CAIRO_INCLUDE_DIRS})
if(MINGW)
target_link_libraries(dgl-cairo PRIVATE ${CAIRO_STATIC_LIBRARIES})
else()
target_link_libraries(dgl-cairo PRIVATE ${CAIRO_LIBRARIES})
endif()
target_link_libraries(dgl-cairo PRIVATE dgl-cairo-definitions)
endfunction()

# dpf__add_dgl_opengl
# ------------------------------------------------------------------------------
#
# Add the OpenGL variant of DGL, if not already available.
#
function(dpf__add_dgl_opengl)
if(TARGET dgl-opengl)
return()
endif()

if(NOT OpenGL_GL_PREFERENCE)
set(OpenGL_GL_PREFERENCE "LEGACY")
endif()

find_package(OpenGL REQUIRED)

dpf__add_static_library(dgl-opengl STATIC
"${DPF_ROOT_DIR}/dgl/src/Application.cpp"
"${DPF_ROOT_DIR}/dgl/src/ApplicationPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Color.cpp"
"${DPF_ROOT_DIR}/dgl/src/Geometry.cpp"
"${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp"
"${DPF_ROOT_DIR}/dgl/src/ImageBaseWidgets.cpp"
"${DPF_ROOT_DIR}/dgl/src/Resources.cpp"
"${DPF_ROOT_DIR}/dgl/src/SubWidget.cpp"
"${DPF_ROOT_DIR}/dgl/src/SubWidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/TopLevelWidget.cpp"
"${DPF_ROOT_DIR}/dgl/src/TopLevelWidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Widget.cpp"
"${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/Window.cpp"
"${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp"
"${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp"
"${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp")
if(NOT APPLE)
target_sources(dgl-opengl PRIVATE
"${DPF_ROOT_DIR}/dgl/src/pugl.cpp")
else() # Note: macOS pugl will be built as part of DistrhoUI_macOS.mm
#target_sources(dgl-opengl PRIVATE
# "${DPF_ROOT_DIR}/dgl/src/pugl.mm")
endif()
target_include_directories(dgl-opengl PUBLIC
"${DPF_ROOT_DIR}/dgl")
target_include_directories(dgl-opengl PUBLIC
"${DPF_ROOT_DIR}/dgl/src/pugl-upstream/include")

if(APPLE)
target_compile_definitions(dgl-opengl PUBLIC "GL_SILENCE_DEPRECATION")
endif()

dpf__add_dgl_system_libs()
target_link_libraries(dgl-opengl PRIVATE dgl-system-libs)

add_library(dgl-opengl-definitions INTERFACE)
target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL")

target_include_directories(dgl-opengl PUBLIC "${OPENGL_INCLUDE_DIR}")
target_link_libraries(dgl-opengl PRIVATE dgl-opengl-definitions "${OPENGL_gl_LIBRARY}")
endfunction()

# dpf__add_plugin_specific_ui_sources
# ------------------------------------------------------------------------------
#
# Compile plugin-specific UI sources into the target designated by the given
# name. There are some special considerations here:
# - On most platforms, sources can be compiled only once, as part of DGL;
# - On macOS, for any sources which define Objective-C interfaces, these must
# be recompiled for each plugin under a unique namespace. In this case, the
# name must be a plugin-specific identifier, and it will be used for computing
# the unique ID along with the project version.
function(dpf__add_plugin_specific_ui_sources NAME)
if(APPLE)
target_sources("${NAME}" PRIVATE
"${DPF_ROOT_DIR}/distrho/DistrhoUI_macOS.mm")
string(SHA256 _hash "${NAME}:${PROJECT_VERSION}")
target_compile_definitions("${NAME}" PUBLIC "PUGL_NAMESPACE=${_hash}")
endif()
endfunction()

# dpf__add_dgl_system_libs
# ------------------------------------------------------------------------------
#
# Find system libraries required by DGL and add them as an interface target.
#
function(dpf__add_dgl_system_libs)
if(TARGET dgl-system-libs)
return()
endif()
add_library(dgl-system-libs INTERFACE)
add_library(dgl-system-libs-definitions INTERFACE)
if(HAIKU)
target_link_libraries(dgl-system-libs INTERFACE "be")
elseif(WIN32)
target_link_libraries(dgl-system-libs INTERFACE "gdi32" "comdlg32")
elseif(APPLE)
find_library(APPLE_COCOA_FRAMEWORK "Cocoa")
find_library(APPLE_COREVIDEO_FRAMEWORK "CoreVideo")
target_link_libraries(dgl-system-libs INTERFACE "${APPLE_COCOA_FRAMEWORK}" "${APPLE_COREVIDEO_FRAMEWORK}")
else()
find_package(X11 REQUIRED)
target_include_directories(dgl-system-libs INTERFACE "${X11_INCLUDE_DIR}")
target_link_libraries(dgl-system-libs INTERFACE "${X11_X11_LIB}")
target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_X11")
if(X11_Xext_FOUND)
target_link_libraries(dgl-system-libs INTERFACE "${X11_Xext_LIB}")
target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XEXT")
endif()
if(X11_XSync_FOUND)
target_link_libraries(dgl-system-libs INTERFACE "${X11_XSync_LIB}")
target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XSYNC")
endif()
if(X11_Xrandr_FOUND)
target_link_libraries(dgl-system-libs INTERFACE "${X11_Xrandr_LIB}")
target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XRANDR")
endif()
#if(X11_Xcursor_FOUND)
# target_link_libraries(dgl-system-libs INTERFACE "${X11_Xcursor_LIB}")
# target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XCURSOR")
#endif()
endif()

if(MSVC)
file(MAKE_DIRECTORY "${DPF_ROOT_DIR}/khronos/GL")
foreach(_gl_header "glext.h")
if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}")
file(DOWNLOAD "https://www.khronos.org/registry/OpenGL/api/GL/${_gl_header}" "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}" SHOW_PROGRESS)
endif()
endforeach()
foreach(_khr_header "khrplatform.h")
if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}")
file(DOWNLOAD "https://www.khronos.org/registry/EGL/api/KHR/${_khr_header}" "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}" SHOW_PROGRESS)
endif()
endforeach()
target_include_directories(dgl-system-libs-definitions INTERFACE "${DPF_ROOT_DIR}/khronos")
endif()

target_link_libraries(dgl-system-libs INTERFACE dgl-system-libs-definitions)
endfunction()

# dpf__add_executable
# ------------------------------------------------------------------------------
#
# Adds an executable target, and set some default properties on the target.
#
function(dpf__add_executable NAME)
add_executable("${NAME}" ${ARGN})
dpf__set_target_defaults("${NAME}")
if(MINGW)
target_link_libraries("${NAME}" PRIVATE "-static")
endif()
endfunction()

# dpf__add_module
# ------------------------------------------------------------------------------
#
# Adds a module target, and set some default properties on the target.
#
function(dpf__add_module NAME)
add_library("${NAME}" MODULE ${ARGN})
dpf__set_target_defaults("${NAME}")
if(MINGW)
target_link_libraries("${NAME}" PRIVATE "-static")
endif()
endfunction()

# dpf__add_static_library
# ------------------------------------------------------------------------------
#
# Adds a static library target, and set some default properties on the target.
#
function(dpf__add_static_library NAME)
add_library("${NAME}" STATIC ${ARGN})
dpf__set_target_defaults("${NAME}")
endfunction()

# dpf__set_target_defaults
# ------------------------------------------------------------------------------
#
# Set default properties which must apply to all DPF-defined targets.
#
function(dpf__set_target_defaults NAME)
set_target_properties("${NAME}" PROPERTIES
POSITION_INDEPENDENT_CODE TRUE
C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN TRUE)
if(WIN32)
target_compile_definitions("${NAME}" PUBLIC "NOMINMAX")
endif()
if (MINGW)
target_compile_options("${NAME}" PUBLIC "-mstackrealign")
endif()
if (MSVC)
target_compile_options("${NAME}" PUBLIC "/UTF-8")
target_compile_definitions("${NAME}" PUBLIC "_CRT_SECURE_NO_WARNINGS")
endif()
endfunction()

# dpf__add_plugin_main
# ------------------------------------------------------------------------------
#
# Adds plugin code to the given target.
#
function(dpf__add_plugin_main NAME TARGET)
target_sources("${NAME}" PRIVATE
"${DPF_ROOT_DIR}/distrho/DistrhoPluginMain.cpp")
dpf__add_plugin_target_definition("${NAME}" "${TARGET}")
endfunction()

# dpf__add_ui_main
# ------------------------------------------------------------------------------
#
# Adds UI code to the given target (only if the target has UI).
#
function(dpf__add_ui_main NAME TARGET HAS_UI)
if(HAS_UI)
target_sources("${NAME}" PRIVATE
"${DPF_ROOT_DIR}/distrho/DistrhoUIMain.cpp")
dpf__add_plugin_target_definition("${NAME}" "${TARGET}")
endif()
endfunction()

# dpf__add_plugin_target_definition
# ------------------------------------------------------------------------------
#
# Adds the plugins target macro definition.
# This selects which entry file is compiled according to the target type.
#
function(dpf__add_plugin_target_definition NAME TARGET)
string(TOUPPER "${TARGET}" _upperTarget)
target_compile_definitions("${NAME}" PRIVATE "DISTRHO_PLUGIN_TARGET_${_upperTarget}")
endfunction()

# dpf__add_lv2_ttl_generator
# ------------------------------------------------------------------------------
#
# Build the LV2 TTL generator.
#
function(dpf__add_lv2_ttl_generator)
if(TARGET lv2_ttl_generator)
return()
endif()
add_executable(lv2_ttl_generator "${DPF_ROOT_DIR}/utils/lv2-ttl-generator/lv2_ttl_generator.c")
if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU))
target_link_libraries(lv2_ttl_generator PRIVATE "dl")
endif()
endfunction()

# dpf__ensure_sources_non_empty
# ------------------------------------------------------------------------------
#
# Ensure the given source list contains at least one file.
# The function appends an empty source file to the list if necessary.
# This is useful when CMake does not permit to add targets without sources.
#
function(dpf__ensure_sources_non_empty VAR)
if(NOT "" STREQUAL "${${VAR}}")
return()
endif()
set(_file "${CMAKE_CURRENT_BINARY_DIR}/_dpf_empty.c")
if(NOT EXISTS "${_file}")
file(WRITE "${_file}" "")
endif()
set("${VAR}" "${_file}" PARENT_SCOPE)
endfunction()

# dpf__create_dummy_source_list
# ------------------------------------------------------------------------------
#
# Create a dummy source list which is equivalent to compiling nothing.
# This is only for compatibility with older CMake versions, which refuse to add
# targets without any sources.
#
macro(dpf__create_dummy_source_list VAR)
set("${VAR}")
if(CMAKE_VERSION VERSION_LESS "3.11")
dpf__ensure_sources_non_empty("${VAR}")
endif()
endmacro()

# dpf__warn_once
# ------------------------------------------------------------------------------
#
# Prints a warning message once only.
#
function(dpf__warn_once_only TOKEN MESSAGE)
get_property(_warned GLOBAL PROPERTY "dpf__have_warned_${TOKEN}")
if(NOT _warned)
set_property(GLOBAL PROPERTY "dpf__have_warned_${TOKEN}" TRUE)
message(WARNING "${MESSAGE}")
endif()
endfunction()

+ 33
- 14
dpf/dgl/Application.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -21,22 +21,15 @@

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// Forward class names

class Window;

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
Base DGL Application class.

One application instance is required for creating a window.
There's no single/global application instance in DGL, and multiple
windows can share the same app instance.
There's no single/global application instance in DGL, and multiple windows can share the same app instance.

In standalone mode an application will automatically quit its
event-loop when all its windows are closed.
In standalone mode an application will automatically quit its event-loop when all its windows are closed.
*/
class Application
{
@@ -44,7 +37,8 @@ public:
/**
Constructor.
*/
Application();
// NOTE: the default value is not yet passed, so we catch where we use this
Application(bool isStandalone = true);

/**
Destructor.
@@ -62,11 +56,12 @@ public:
idle() is called at regular intervals.
@note This function is meant for standalones only, *never* call this from plugins.
*/
void exec(int idleTime = 10);
void exec(uint idleTimeInMs = 30);

/**
Quit the application.
This stops the event-loop and closes all Windows.
@note This function is meant for standalones only, *never* call this from plugins.
*/
void quit();

@@ -76,6 +71,30 @@ public:
*/
bool isQuiting() const noexcept;

/**
Add a callback function to be triggered on every idle cycle.
You can add more than one, and remove them at anytime with removeIdleCallback().
Idle callbacks trigger right after OS event handling and Window idle events (within the same cycle).
There are no guarantees in terms of timing.
*/
void addIdleCallback(IdleCallback* callback);

/**
Remove an idle callback previously added via addIdleCallback().
*/
void removeIdleCallback(IdleCallback* callback);

/**
Set the class name of the application.

This is a stable identifier for the application, used as the window class/instance name on X11 and Windows.
It is not displayed to the user, but can be used in scripts and by window managers,
so it should be the same for every instance of the application, but different from other applications.

Plugins created with DPF have their class name automatically set based on DGL_NAMESPACE and plugin name.
*/
void setClassName(const char* name);

private:
struct PrivateData;
PrivateData* const pData;
@@ -84,7 +103,7 @@ private:
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Application)
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

END_NAMESPACE_DGL



+ 83
- 25
dpf/dgl/Base.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -20,7 +20,7 @@
#include "../distrho/extra/LeakDetector.hpp"
#include "../distrho/extra/ScopedPointer.hpp"

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Define namespace

#ifndef DGL_NAMESPACE
@@ -33,33 +33,46 @@

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Base DGL enums

/**
Convenience symbols for ASCII control characters.
*/
enum Char {
kCharBackspace = 0x08,
kCharEscape = 0x1B,
kCharDelete = 0x7F
};

/**
Keyboard modifier flags.
*/
enum Modifier {
kModifierShift = 1 << 0, /**< Shift key */
kModifierControl = 1 << 1, /**< Control key */
kModifierAlt = 1 << 2, /**< Alt/Option key */
kModifierSuper = 1 << 3 /**< Mod4/Command/Windows key */
kModifierShift = 1u << 0u, ///< Shift key
kModifierControl = 1u << 1u, ///< Control key
kModifierAlt = 1u << 2u, ///< Alt/Option key
kModifierSuper = 1u << 3u ///< Mod4/Command/Windows key
};

/**
Special (non-Unicode) keyboard keys.
Keyboard key codepoints.

All keys are identified by a Unicode code point in PuglEventKey::key. This
enumeration defines constants for special keys that do not have a standard
code point, and some convenience constants for control characters. Note
that all keys are handled in the same way, this enumeration is just for
convenience when writing hard-coded key bindings.

Keys that do not have a standard code point use values in the Private Use
Area in the Basic Multilingual Plane (`U+E000` to `U+F8FF`). Applications
must take care to not interpret these values beyond key detection, the
mapping used here is arbitrary and specific to DPF.
*/
enum Key {
kKeyF1 = 1,
// Convenience symbols for ASCII control characters
kKeyBackspace = 0x08,
kKeyEscape = 0x1B,
kKeyDelete = 0x7F,

// Backwards compatibility with old DPF
kCharBackspace DISTRHO_DEPRECATED_BY("kKeyBackspace") = kKeyBackspace,
kCharEscape DISTRHO_DEPRECATED_BY("kKeyEscape") = kKeyEscape,
kCharDelete DISTRHO_DEPRECATED_BY("kKeyDelete") = kKeyDelete,

// Unicode Private Use Area
kKeyF1 = 0xE000,
kKeyF2,
kKeyF3,
kKeyF4,
@@ -81,30 +94,75 @@ enum Key {
kKeyEnd,
kKeyInsert,
kKeyShift,
kKeyShiftL = kKeyShift,
kKeyShiftR,
kKeyControl,
kKeyControlL = kKeyControl,
kKeyControlR,
kKeyAlt,
kKeySuper
kKeyAltL = kKeyAlt,
kKeyAltR,
kKeySuper,
kKeySuperL = kKeySuper,
kKeySuperR,
kKeyMenu,
kKeyCapsLock,
kKeyScrollLock,
kKeyNumLock,
kKeyPrintScreen,
kKeyPause
};

/**
Common flags for all events.
*/
enum Flag {
kFlagSendEvent = 1, ///< Event is synthetic
kFlagIsHint = 2 ///< Event is a hint (not direct user input)
};

/**
Reason for a crossing event.
*/
enum CrossingMode {
kCrossingNormal, ///< Crossing due to pointer motion
kCrossingGrab, ///< Crossing due to a grab
kCrossingUngrab ///< Crossing due to a grab release
};

/**
Scroll direction.

Describes the direction of a scroll event along with whether the scroll is a "smooth" scroll.
The discrete directions are for devices like mouse wheels with constrained axes,
while a smooth scroll is for those with arbitrary scroll direction freedom, like some touchpads.
*/
enum ScrollDirection {
kScrollUp, ///< Scroll up
kScrollDown, ///< Scroll down
kScrollLeft, ///< Scroll left
kScrollRight, ///< Scroll right
kScrollSmooth ///< Smooth scroll in any direction
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Base DGL classes

/**
Graphics context, definition depends on build type.
*/
struct GraphicsContext;
struct GraphicsContext {};

/**
Idle callback.
*/
class IdleCallback
struct IdleCallback
{
public:
virtual ~IdleCallback() {}
virtual void idleCallback() = 0;
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

END_NAMESPACE_DGL

@@ -114,6 +172,6 @@ END_NAMESPACE_DGL
using namespace DGL_NAMESPACE;
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

#endif // DGL_BASE_HPP_INCLUDED

+ 160
- 7
dpf/dgl/Cairo.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -17,23 +17,176 @@
#ifndef DGL_CAIRO_HPP_INCLUDED
#define DGL_CAIRO_HPP_INCLUDED

#include "Base.hpp"
#include "ImageBase.hpp"
#include "ImageBaseWidgets.hpp"

#include <cairo/cairo.h>

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
Graphics context.
Cairo Graphics context.
*/
struct GraphicsContext
struct CairoGraphicsContext : GraphicsContext
{
cairo_t* cairo; // FIXME proper name..
cairo_t* handle;
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
Cairo Image class.

TODO ...
*/
class CairoImage : public ImageBase
{
public:
/**
Constructor for a null Image.
*/
CairoImage();

/**
Constructor using raw image data.
@note @a rawData must remain valid for the lifetime of this Image.
*/
CairoImage(const char* rawData, uint width, uint height, ImageFormat format);

/**
Constructor using raw image data.
@note @a rawData must remain valid for the lifetime of this Image.
*/
CairoImage(const char* rawData, const Size<uint>& size, ImageFormat format);

/**
Constructor using another image data.
*/
CairoImage(const CairoImage& image);

/**
Destructor.
*/
~CairoImage() override;

/**
Load raw image data from memory.
@note @a rawData must remain valid for the lifetime of this Image.
*/
void loadFromMemory(const char* rawData,
const Size<uint>& size,
ImageFormat format = kImageFormatBGRA) noexcept override;

/**
Load PNG image from memory.
Image size is read from PNG contents.
@note @a pngData must remain valid for the lifetime of this Image.
*/
void loadFromPNG(const char* pngData, uint dataSize) noexcept;

/**
Draw this image at position @a pos using the graphics context @a context.
*/
void drawAt(const GraphicsContext& context, const Point<int>& pos) override;

/**
Get the cairo surface currently associated with this image.
FIXME might be removed
*/
inline cairo_surface_t* getSurface() const noexcept
{
return surface;
}

/**
TODO document this.
*/
CairoImage& operator=(const CairoImage& image) noexcept;

// FIXME this should not be needed
inline void loadFromMemory(const char* rdata, uint w, uint h, ImageFormat fmt = kImageFormatBGRA)
{ loadFromMemory(rdata, Size<uint>(w, h), fmt); };
inline void draw(const GraphicsContext& context)
{ drawAt(context, Point<int>(0, 0)); };
inline void drawAt(const GraphicsContext& context, int x, int y)
{ drawAt(context, Point<int>(x, y)); };

private:
cairo_surface_t* surface;
uchar* surfacedata;
int* datarefcount;
};

// --------------------------------------------------------------------------------------------------------------------

/**
CairoWidget, handy class that takes graphics context during onDisplay and passes it in a new function.
*/
template <class BaseWidget>
class CairoBaseWidget : public BaseWidget
{
public:
/**
Constructor for a CairoSubWidget.
*/
explicit CairoBaseWidget(Widget* const parentGroupWidget);

/**
Constructor for a CairoTopLevelWidget.
*/
explicit CairoBaseWidget(Window& windowToMapTo);

/**
Constructor for a CairoStandaloneWindow without parent window.
*/
explicit CairoBaseWidget(Application& app);

/**
Constructor for a CairoStandaloneWindow with parent window.
*/
explicit CairoBaseWidget(Application& app, Window& parentWindow);

/**
Destructor.
*/
virtual ~CairoBaseWidget() {}

protected:
/**
New virtual onDisplay function.
@see onDisplay
*/
virtual void onCairoDisplay(const CairoGraphicsContext& context) = 0;

private:
/**
Widget display function.
Implemented internally to pass context into the drawing function.
*/
void onDisplay() override
{
const CairoGraphicsContext& context((const CairoGraphicsContext&)BaseWidget::getGraphicsContext());
onCairoDisplay(context);
}

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoBaseWidget);
};

typedef CairoBaseWidget<SubWidget> CairoSubWidget;
typedef CairoBaseWidget<TopLevelWidget> CairoTopLevelWidget;
typedef CairoBaseWidget<StandaloneWindow> CairoStandaloneWindow;

// --------------------------------------------------------------------------------------------------------------------

typedef ImageBaseAboutWindow<CairoImage> CairoImageAboutWindow;
typedef ImageBaseButton<CairoImage> CairoImageButton;
typedef ImageBaseKnob<CairoImage> CairoImageKnob;
typedef ImageBaseSlider<CairoImage> CairoImageSlider;
typedef ImageBaseSwitch<CairoImage> CairoImageSwitch;

// --------------------------------------------------------------------------------------------------------------------

END_NAMESPACE_DGL



+ 13
- 8
dpf/dgl/Color.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -23,7 +23,7 @@ struct NVGcolor;

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
A color made from red, green, blue and alpha floating-point values in [0..1] range.
@@ -44,13 +44,13 @@ struct Color {

/**
Create a color from red, green, blue and alpha numeric values.
Values must be in [0..255] range.
All values except alpha must be in [0..255] range, with alpha in [0..1] range.
*/
Color(int red, int green, int blue, int alpha = 255) noexcept;
Color(int red, int green, int blue, float alpha = 1.0f) noexcept;

/**
Create a color from red, green, blue and alpha floating-point values.
Values must in [0..1] range.
All values must in [0..1] range.
*/
Color(float red, float green, float blue, float alpha = 1.0f) noexcept;

@@ -74,7 +74,7 @@ struct Color {
/**
Create a color from a HTML string like "#333" or "#112233".
*/
static Color fromHTML(const char* rgb, float alpha = 1.0f);
static Color fromHTML(const char* rgb, float alpha = 1.0f) noexcept;

/**
Linearly interpolate this color against another.
@@ -83,7 +83,7 @@ struct Color {

/**
Check if this color matches another.
@note Comparison is forced within 8-bit color values.
@note Comparison is done within 8-bit color space.
*/
bool isEqual(const Color& color, bool withAlpha = true) noexcept;
bool isNotEqual(const Color& color, bool withAlpha = true) noexcept;
@@ -95,6 +95,11 @@ struct Color {
*/
void fixBounds() noexcept;

/**
Set this color for use in the next drawing operation for the provided context.
*/
void setFor(const GraphicsContext& context, bool includeAlpha = false);

/**
@internal
Needed for NanoVG compatibility.
@@ -103,7 +108,7 @@ struct Color {
operator NVGcolor() const noexcept;
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

END_NAMESPACE_DGL



+ 117
- 36
dpf/dgl/Geometry.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -21,7 +21,7 @@

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Forward class names

template<typename> class Line;
@@ -29,7 +29,7 @@ template<typename> class Circle;
template<typename> class Triangle;
template<typename> class Rectangle;

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
DGL Point class.
@@ -114,14 +114,14 @@ public:
bool operator!=(const Point<T>& pos) const noexcept;

private:
T fX, fY;
T x, y;
template<typename> friend class Line;
template<typename> friend class Circle;
template<typename> friend class Triangle;
template<typename> friend class Rectangle;
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

/**
DGL Size class.
@@ -195,7 +195,7 @@ public:

/**
Return true if size is not null (0x0).
A non-null size is still invalid if its width or height is negative.
A non-null size is still invalid if its width or height are negative.
*/
bool isNotNull() const noexcept;

@@ -210,6 +210,8 @@ public:
*/
bool isInvalid() const noexcept;

Size<int> toInt() const noexcept;

Size<T> operator+(const Size<T>& size) noexcept;
Size<T> operator-(const Size<T>& size) noexcept;
Size<T>& operator=(const Size<T>& size) noexcept;
@@ -217,6 +219,8 @@ public:
Size<T>& operator-=(const Size<T>& size) noexcept;
Size<T>& operator*=(double m) noexcept;
Size<T>& operator/=(double d) noexcept;
Size<T> operator*(double m) const noexcept;
Size<T> operator/(double m) const noexcept;
bool operator==(const Size<T>& size) const noexcept;
bool operator!=(const Size<T>& size) const noexcept;

@@ -346,11 +350,6 @@ public:
*/
void moveBy(const Point<T>& pos) noexcept;

/**
Draw this line using the current OpenGL state.
*/
void draw();

/**
Return true if line is null (start and end pos are equal).
*/
@@ -361,12 +360,28 @@ public:
*/
bool isNotNull() const noexcept;

#ifndef DPF_TEST_POINT_CPP
/**
Draw this line using the provided graphics context, optionally specifying line width.
*/
void draw(const GraphicsContext& context, T width = 1);
#endif

Line<T>& operator=(const Line<T>& line) noexcept;
bool operator==(const Line<T>& line) const noexcept;
bool operator!=(const Line<T>& line) const noexcept;

#ifndef DPF_TEST_POINT_CPP
/**
Draw this line using the current OpenGL state.@n
DEPRECATED Please use draw(const GraphicsContext&) instead.
*/
DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
void draw();
#endif

private:
Point<T> fPosStart, fPosEnd;
Point<T> posStart, posEnd;
};

// -----------------------------------------------------------------------
@@ -461,19 +476,35 @@ public:
void setNumSegments(const uint num);

/**
Draw this circle using the current OpenGL state.
Draw this circle using the provided graphics context.
*/
void draw();
void draw(const GraphicsContext& context);

/**
Draw lines (outline of this circle) using the current OpenGL state.
Draw lines (outline of this circle) using the provided graphics context, optionally specifying line width.
*/
void drawOutline();
void drawOutline(const GraphicsContext& context, T lineWidth = 1);

Circle<T>& operator=(const Circle<T>& cir) noexcept;
bool operator==(const Circle<T>& cir) const noexcept;
bool operator!=(const Circle<T>& cir) const noexcept;

#ifndef DPF_TEST_POINT_CPP
/**
Draw this circle using the current OpenGL state.@n
DEPRECATED Please use draw(const GraphicsContext&) instead.
*/
DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
void draw();

/**
Draw lines (outline of this circle) using the current OpenGL state.@n
DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
*/
DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
void drawOutline();
#endif

private:
Point<T> fPos;
float fSize;
@@ -481,9 +512,6 @@ private:

// cached values
float fTheta, fCos, fSin;

/** @internal */
void _draw(const bool outline);
};