diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..25a2ce75 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,48 @@ +name: build + +on: + push: + branches: + - '*' + tags: + - '*' + pull_request: + branches: + - '*' + +env: + BUILD_TYPE: Release + +jobs: + build_for_linux: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up dependencies + run: | + sudo apt-get update && \ + sudo apt-get install \ + cmake \ + ninja-build \ + libjack-jackd2-dev \ + liblo-dev \ + libgl-dev \ + libcairo2-dev \ + libx11-dev + - name: Create Build Environment + shell: bash + working-directory: ${{runner.workspace}} + run: cmake -E make_directory build + - name: Configure CMake + shell: bash + working-directory: ${{runner.workspace}}/build + run: | + cmake "$GITHUB_WORKSPACE" -G Ninja \ + -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ + -DDPF_EXAMPLES=ON + - name: Build all + shell: bash + working-directory: ${{runner.workspace}}/build + run: cmake --build . --config "$BUILD_TYPE" -j 2 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d4a7de15 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +# DISTRHO Plugin Framework (DPF) +# Copyright (C) 2021 Jean Pierre Cimalando +# +# SPDX-License-Identifier: ISC + +cmake_minimum_required(VERSION 3.7) + +project(DPF) + +# 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) + dpf__add_dgl_cairo() + dpf__add_dgl_opengl() +endif() + +if(DPF_EXAMPLES) + add_subdirectory("examples/CairoUI") + #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() diff --git a/Makefile.base.mk b/Makefile.base.mk index 34286c37..eda2c83d 100644 --- a/Makefile.base.mk +++ b/Makefile.base.mk @@ -139,7 +139,7 @@ BASE_FLAGS = -Wall -Wextra -pipe -MD -MP BASE_OPTS = -O3 -ffast-math -fdata-sections -ffunction-sections ifeq ($(CPU_I386_OR_X86_64),true) -BASE_OPTS += -mtune=generic -msse -msse2 +BASE_OPTS += -mtune=generic -msse -msse2 -mfpmath=sse endif ifeq ($(CPU_ARM),true) @@ -310,6 +310,7 @@ OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl) endif ifeq ($(MACOS),true) +OPENGL_FLAGS = -DGL_SILENCE_DEPRECATION=1 OPENGL_LIBS = -framework OpenGL endif diff --git a/Makefile.plugins.mk b/Makefile.plugins.mk index e7ff2dc9..e5e319c2 100644 --- a/Makefile.plugins.mk +++ b/Makefile.plugins.mk @@ -144,7 +144,7 @@ HAVE_DGL = false endif endif -DGL_LIBS += $(DGL_SYSTEM_LIBS) +DGL_LIBS += $(DGL_SYSTEM_LIBS) -lm ifneq ($(HAVE_DGL),true) dssi_ui = diff --git a/cmake/DPF-plugin.cmake b/cmake/DPF-plugin.cmake new file mode 100644 index 00000000..dc3813ca --- /dev/null +++ b/cmake/DPF-plugin.cmake @@ -0,0 +1,574 @@ +# DISTRHO Plugin Framework (DPF) +# Copyright (C) 2021 Jean Pierre Cimalando +# +# 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 ) +# ------------------------------------------------------------------------------ +# +# Add a plugin built using the DISTRHO Plugin Framework. +# +# ------------------------------------------------------------------------------ +# Created targets: +# +# `` +# static library: the common part of the plugin +# The public properties set on this target apply to both DSP and UI. +# +# `-dsp` +# static library: the DSP part of the plugin +# The public properties set on this target apply to the DSP only. +# +# `-ui` +# static library: the UI part of the plugin +# The public properties set on this target apply to the UI only. +# +# `-` for each target specified with the `TARGETS` argument. +# This is target-dependent and not intended for public use. +# +# ------------------------------------------------------------------------------ +# Arguments: +# +# `TARGETS` ... +# a list of one of more of the following target types: +# `jack`, `ladspa`, `dssi`, `lv2`, `vst2` +# +# `UI_TYPE` +# the user interface type: `opengl` (default), `cairo` +# +# `MONOLITHIC` +# build LV2 as a single binary for UI and DSP +# +# `FILES_DSP` ... +# list of sources which are part of the DSP +# +# `FILES_UI` ... +# list of sources which are part of the UI +# empty indicates the plugin does not have UI +# +# `FILES_COMMON` ... +# 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) + 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") + 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}) + 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) + find_package(PkgConfig) + pkg_check_modules(JACK "jack") + if(NOT JACK_FOUND) + dpf__warn_once_only(missing_jack + "JACK is not found, skipping the `jack` plugin targets") + return() + endif() + + link_directories(${JACK_LIBRARY_DIRS}) + + 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}") + + target_include_directories("${NAME}-jack" PRIVATE ${JACK_INCLUDE_DIRS}) + target_link_libraries("${NAME}-jack" PRIVATE ${JACK_LIBRARIES}) +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} + "$" + "$" + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2") +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/Color.cpp" + "${DPF_ROOT_DIR}/dgl/src/Geometry.cpp" + "${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp" + "${DPF_ROOT_DIR}/dgl/src/Resources.cpp" + "${DPF_ROOT_DIR}/dgl/src/Widget.cpp" + "${DPF_ROOT_DIR}/dgl/src/Cairo.cpp" + "${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp") + if(NOT APPLE) + target_sources(dgl-cairo PRIVATE + "${DPF_ROOT_DIR}/dgl/src/Window.cpp") + else() + target_sources(dgl-cairo PRIVATE + "${DPF_ROOT_DIR}/dgl/src/Window.mm") + endif() + target_include_directories(dgl-cairo PUBLIC + "${DPF_ROOT_DIR}/dgl") + + 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}) + target_link_libraries(dgl-cairo PRIVATE dgl-cairo-definitions ${CAIRO_LIBRARIES}) +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/Color.cpp" + "${DPF_ROOT_DIR}/dgl/src/Geometry.cpp" + "${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp" + "${DPF_ROOT_DIR}/dgl/src/Resources.cpp" + "${DPF_ROOT_DIR}/dgl/src/Widget.cpp" + "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" + "${DPF_ROOT_DIR}/dgl/src/Image.cpp" + "${DPF_ROOT_DIR}/dgl/src/ImageWidgets.cpp" + "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp" + "${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp") + if(NOT APPLE) + target_sources(dgl-opengl PRIVATE + "${DPF_ROOT_DIR}/dgl/src/Window.cpp") + else() + target_sources(dgl-opengl PRIVATE + "${DPF_ROOT_DIR}/dgl/src/Window.mm") + endif() + target_include_directories(dgl-opengl PUBLIC + "${DPF_ROOT_DIR}/dgl") + + 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_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) + 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") + target_link_libraries(dgl-system-libs INTERFACE "${APPLE_COCOA_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}") + endif() +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}) + set_target_properties("${NAME}" PROPERTIES + POSITION_INDEPENDENT_CODE TRUE + C_VISIBILITY_PRESET "hidden" + CXX_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN TRUE) +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}) + set_target_properties("${NAME}" PROPERTIES + POSITION_INDEPENDENT_CODE TRUE + C_VISIBILITY_PRESET "hidden" + CXX_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN TRUE) + if ((NOT WIN32 AND NOT APPLE) OR MINGW) + target_link_libraries("${NAME}" PRIVATE "-Wl,--no-undefined") + 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}) + set_target_properties("${NAME}" PROPERTIES + POSITION_INDEPENDENT_CODE TRUE + C_VISIBILITY_PRESET "hidden" + CXX_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN TRUE) +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) + + # resolve the alias into the proper name + # the name "vst2" is new, "vst" is legacy + if(_upperTarget STREQUAL "VST2") + set(_upperTarget "VST") + endif() + + 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 WINDOWS AND NOT APPLE AND NOT HAIKU) + target_link_libraries(lv2_ttl_generator "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() diff --git a/dgl/src/ImageBaseWidgets.cpp b/dgl/src/ImageBaseWidgets.cpp index 976887d3..f5fc7503 100644 --- a/dgl/src/ImageBaseWidgets.cpp +++ b/dgl/src/ImageBaseWidgets.cpp @@ -520,9 +520,10 @@ bool ImageBaseKnob::onScroll(const ScrollEvent& ev) if (! contains(ev.pos)) return false; + const float dir = (ev.delta.getY() > 0.f) ? 1.f : -1.f; const float d = (ev.mod & kModifierControl) ? 2000.0f : 200.0f; float value = (pData->usingLog ? pData->invlogscale(pData->valueTmp) : pData->valueTmp) - + ((pData->maximum - pData->minimum) / d * 10.f * static_cast(ev.delta.getY())); + + ((pData->maximum - pData->minimum) / d * 10.f * dir); if (pData->usingLog) value = pData->logscale(value); diff --git a/examples/CairoUI/CMakeLists.txt b/examples/CairoUI/CMakeLists.txt new file mode 100644 index 00000000..580c9896 --- /dev/null +++ b/examples/CairoUI/CMakeLists.txt @@ -0,0 +1,15 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_cairoui + TARGETS jack dssi lv2 vst2 + UI_TYPE cairo + FILES_DSP + CairoExamplePlugin.cpp + FILES_UI + DemoWidgetBanner.cpp + DemoWidgetClickable.cpp + CairoExampleUI.cpp) + +target_include_directories( + d_cairoui PUBLIC ".") diff --git a/examples/FileHandling/CMakeLists.txt b/examples/FileHandling/CMakeLists.txt new file mode 100644 index 00000000..6007a260 --- /dev/null +++ b/examples/FileHandling/CMakeLists.txt @@ -0,0 +1,13 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_files + TARGETS jack lv2 vst2 + FILES_DSP + FileHandlingPlugin.cpp + FILES_UI + FileHandlingUI.cpp + NanoButton.cpp) + +target_include_directories( + d_files PUBLIC ".") diff --git a/examples/Info/CMakeLists.txt b/examples/Info/CMakeLists.txt new file mode 100644 index 00000000..9efc9620 --- /dev/null +++ b/examples/Info/CMakeLists.txt @@ -0,0 +1,12 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_info + TARGETS jack lv2 vst2 + FILES_DSP + InfoExamplePlugin.cpp + FILES_UI + InfoExampleUI.cpp) + +target_include_directories( + d_info PUBLIC ".") diff --git a/examples/Latency/CMakeLists.txt b/examples/Latency/CMakeLists.txt new file mode 100644 index 00000000..fd0ddcb8 --- /dev/null +++ b/examples/Latency/CMakeLists.txt @@ -0,0 +1,10 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_latency + TARGETS ladspa lv2 vst2 + FILES_DSP + LatencyExamplePlugin.cpp) + +target_include_directories( + d_latency PUBLIC ".") diff --git a/examples/Meters/CMakeLists.txt b/examples/Meters/CMakeLists.txt new file mode 100644 index 00000000..0d7807a4 --- /dev/null +++ b/examples/Meters/CMakeLists.txt @@ -0,0 +1,12 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_meters + TARGETS jack dssi lv2 vst2 + FILES_DSP + ExamplePluginMeters.cpp + FILES_UI + ExampleUIMeters.cpp) + +target_include_directories( + d_meters PUBLIC ".") diff --git a/examples/MidiThrough/CMakeLists.txt b/examples/MidiThrough/CMakeLists.txt new file mode 100644 index 00000000..38facaa5 --- /dev/null +++ b/examples/MidiThrough/CMakeLists.txt @@ -0,0 +1,10 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_midiThrough + TARGETS jack lv2 vst2 + FILES_DSP + MidiThroughExamplePlugin.cpp) + +target_include_directories( + d_midiThrough PUBLIC ".") diff --git a/examples/Parameters/CMakeLists.txt b/examples/Parameters/CMakeLists.txt new file mode 100644 index 00000000..4d1e77e9 --- /dev/null +++ b/examples/Parameters/CMakeLists.txt @@ -0,0 +1,12 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_parameters + TARGETS jack ladspa dssi lv2 vst2 + FILES_DSP + ExamplePluginParameters.cpp + FILES_UI + ExampleUIParameters.cpp) + +target_include_directories( + d_parameters PUBLIC ".") diff --git a/examples/States/CMakeLists.txt b/examples/States/CMakeLists.txt new file mode 100644 index 00000000..fdbb2f25 --- /dev/null +++ b/examples/States/CMakeLists.txt @@ -0,0 +1,12 @@ +# CMake file for DISTRHO Plugins # +# ------------------------------ # + +dpf_add_plugin(d_states + TARGETS jack lv2 vst2 + FILES_DSP + ExamplePluginStates.cpp + FILES_UI + ExampleUIStates.cpp) + +target_include_directories( + d_states PUBLIC ".")