diff --git a/dpf/cmake/DPF-plugin.cmake b/dpf/cmake/DPF-plugin.cmake index 18860e7..a0b316b 100644 --- a/dpf/cmake/DPF-plugin.cmake +++ b/dpf/cmake/DPF-plugin.cmake @@ -22,7 +22,7 @@ # add_subdirectory(DPF) # # dpf_add_plugin(MyPlugin -# TARGETS lv2 vst2 +# TARGETS lv2 vst2 vst3 # UI_TYPE opengl # FILES_DSP # src/MyPlugin.cpp @@ -71,7 +71,7 @@ include(CMakeParseArguments) # # `TARGETS` ... # a list of one of more of the following target types: -# `jack`, `ladspa`, `dssi`, `lv2`, `vst2` +# `jack`, `ladspa`, `dssi`, `lv2`, `vst2`, `vst3` # # `UI_TYPE` # the user interface type: `opengl` (default), `cairo` @@ -153,6 +153,8 @@ function(dpf_add_plugin NAME) dpf__build_lv2("${NAME}" "${_dgl_library}" "${_dpf_plugin_MONOLITHIC}") elseif(_target STREQUAL "vst2") dpf__build_vst2("${NAME}" "${_dgl_library}") + elseif(_target STREQUAL "vst3") + dpf__build_vst3("${NAME}" "${_dgl_library}") else() message(FATAL_ERROR "Unrecognized target type for plugin: ${_target}") endif() @@ -199,7 +201,7 @@ endfunction() # dpf__build_ladspa # ------------------------------------------------------------------------------ # -# Add build rules for a DSSI plugin. +# Add build rules for a LADSPA plugin. # function(dpf__build_ladspa NAME) dpf__create_dummy_source_list(_no_srcs) @@ -259,7 +261,7 @@ endfunction() # dpf__build_lv2 # ------------------------------------------------------------------------------ # -# Add build rules for a LV2 plugin. +# Add build rules for an LV2 plugin. # function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) dpf__create_dummy_source_list(_no_srcs) @@ -339,6 +341,95 @@ function(dpf__build_vst2 NAME DGL_LIBRARY) endif() endfunction() +# dpf__determine_vst3_package_architecture +# ------------------------------------------------------------------------------ +# +# Determines the package architecture for a VST3 plugin target. +# +function(dpf__determine_vst3_package_architecture OUTPUT_VARIABLE) + # if set by variable, override the detection + if(DPF_VST3_ARCHITECTURE) + set("${OUTPUT_VARIABLE}" "${DPF_VST3_ARCHITECTURE}" PARENT_SCOPE) + return() + endif() + + # not used on Apple, which supports universal binary + if(APPLE) + set("${OUTPUT_VARIABLE}" "universal" PARENT_SCOPE) + return() + endif() + + # identify the target processor (special case of MSVC, problematic sometimes) + if(MSVC) + set(vst3_system_arch "${MSVC_CXX_ARCHITECTURE_ID}") + else() + set(vst3_system_arch "${CMAKE_SYSTEM_PROCESSOR}") + endif() + + # transform the processor name to a format that VST3 recognizes + if(vst3_system_arch MATCHES "^(x86_64|amd64|AMD64|x64|X64)$") + set(vst3_package_arch "x86_64") + elseif(vst3_system_arch MATCHES "^(i.86|x86|X86)$") + if(WIN32) + set(vst3_package_arch "x86") + else() + set(vst3_package_arch "i386") + endif() + elseif(vst3_system_arch MATCHES "^(armv[3-8][a-z]*)$") + set(vst3_package_arch "${vst3_system_arch}") + elseif(vst3_system_arch MATCHES "^(aarch64)$") + set(vst3_package_arch "aarch64") + else() + message(FATAL_ERROR "We don't know this architecture for VST3: ${vst3_system_arch}.") + endif() + + # TODO: the detections for Windows arm/arm64 when supported + + set("${OUTPUT_VARIABLE}" "${vst3_package_arch}" PARENT_SCOPE) +endfunction() + +# dpf__build_vst3 +# ------------------------------------------------------------------------------ +# +# Add build rules for a VST3 plugin. +# +function(dpf__build_vst3 NAME DGL_LIBRARY) + dpf__determine_vst3_package_architecture(vst3_arch) + + dpf__create_dummy_source_list(_no_srcs) + + dpf__add_module("${NAME}-vst3" ${_no_srcs}) + dpf__add_plugin_main("${NAME}-vst3" "vst3") + dpf__add_ui_main("${NAME}-vst3" "vst3" "${DGL_LIBRARY}") + dpf__set_module_export_list("${NAME}-vst3" "vst3") + target_link_libraries("${NAME}-vst3" PRIVATE "${NAME}-dsp" "${NAME}-ui") + set_target_properties("${NAME}-vst3" PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst3/$<0:>" + OUTPUT_NAME "${NAME}" + PREFIX "") + + if(APPLE) + set_target_properties("${NAME}-vst3" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/MacOS/$<0:>" + SUFFIX "") + elseif(WIN32) + set_target_properties("${NAME}-vst3" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-win/$<0:>") + else() + set_target_properties("${NAME}-vst3" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-linux/$<0:>") + endif() + + if(APPLE) + # Uses the same macOS bundle template as VST2 + set(INFO_PLIST_PROJECT_NAME "${NAME}") + configure_file("${DPF_ROOT_DIR}/utils/plugin.vst/Contents/Info.plist" + "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/Info.plist" @ONLY) + file(COPY "${DPF_ROOT_DIR}/utils/plugin.vst/Contents/PkgInfo" + DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents") + endif() +endfunction() + # dpf__add_dgl_cairo # ------------------------------------------------------------------------------ # diff --git a/dpf/dgl/src/.kdev_include_paths b/dpf/dgl/src/.kdev_include_paths deleted file mode 100644 index 2103f66..0000000 --- a/dpf/dgl/src/.kdev_include_paths +++ /dev/null @@ -1 +0,0 @@ -pugl-upstream/include/ diff --git a/dpf/distrho/src/DistrhoPluginVST3.cpp b/dpf/distrho/src/DistrhoPluginVST3.cpp index f8b3de2..eff8bb1 100644 --- a/dpf/distrho/src/DistrhoPluginVST3.cpp +++ b/dpf/distrho/src/DistrhoPluginVST3.cpp @@ -310,9 +310,9 @@ ScopedUTF16String::ScopedUTF16String(const char* const s) noexcept : str(nullptr) { const size_t len = strlen(s); - str = (int16_t*)malloc(sizeof(int16_t) * len); + str = (int16_t*)malloc(sizeof(int16_t) * (len + 1)); DISTRHO_SAFE_ASSERT_RETURN(str != nullptr,); - strncpy_utf16(str, s, len); + strncpy_utf16(str, s, len + 1); } ScopedUTF16String::~ScopedUTF16String() noexcept @@ -1402,11 +1402,11 @@ public: v3_result getParameterInfo(int32_t rindex, v3_param_info* const info) const noexcept { DISTRHO_SAFE_ASSERT_RETURN(rindex >= 0, V3_INVALID_ARG); + std::memset(info, 0, sizeof(v3_param_info)); #if DISTRHO_PLUGIN_WANT_PROGRAMS if (rindex == 0) { - std::memset(info, 0, sizeof(v3_param_info)); info->param_id = rindex; info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE; info->step_count = fProgramCountMinusOne; @@ -1417,10 +1417,12 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) { - std::memset(info, 0, sizeof(v3_param_info)); info->param_id = rindex; +# if DISTRHO_PLUGIN_WANT_PROGRAMS + ++info->param_id; +# endif info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_HIDDEN; info->step_count = 127; char ccstr[24]; @@ -1465,7 +1467,6 @@ public: if ((hints & kParameterIsInteger) && ranges.max - ranges.min > 1) step_count = ranges.max - ranges.min - 1; - std::memset(info, 0, sizeof(v3_param_info)); info->param_id = index + fParameterOffset; info->flags = flags; info->step_count = step_count; @@ -1493,7 +1494,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) { snprintf_f32_utf16(output, std::round(normalised * 127), 128); return V3_OK; @@ -1519,7 +1520,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) { // TODO return V3_NOT_IMPLEMENTED; @@ -1542,7 +1543,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) return std::round(normalised * 127); rindex -= 130*16; #endif @@ -1561,7 +1562,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) return std::max(0.0, std::min(1.0, plain / 127)); rindex -= 130*16; #endif @@ -1580,7 +1581,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) { // TODO return 0.0; @@ -1625,7 +1626,7 @@ public: --rindex; #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) { // TODO fChangedParameterValues[rindex] = true; @@ -1775,7 +1776,7 @@ public: --rindex; # endif # if DISTRHO_PLUGIN_WANT_MIDI_INPUT - if (rindex <= 130*16) + if (rindex < 130*16) continue; rindex -= 130*16; # endif @@ -1835,26 +1836,42 @@ public: # if DISTRHO_PLUGIN_WANT_STATE if (std::strcmp(msgid, "state-set") == 0) { - int16_t* key16; - int16_t* value16; - uint32_t keySize, valueSize; + int64_t keyLength = -1; + int64_t valueLength = -1; v3_result res; - res = v3_cpp_obj(attrs)->get_binary(attrs, "key", (const void**)&key16, &keySize); + res = v3_cpp_obj(attrs)->get_int(attrs, "key:length", &keyLength); + DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); + DISTRHO_SAFE_ASSERT_INT_RETURN(keyLength >= 0, keyLength, V3_INTERNAL_ERR); + + res = v3_cpp_obj(attrs)->get_int(attrs, "value:length", &valueLength); + DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); + DISTRHO_SAFE_ASSERT_INT_RETURN(valueLength >= 0, valueLength, V3_INTERNAL_ERR); + + int16_t* const key16 = (int16_t*)std::malloc(sizeof(int16_t)*(keyLength + 1)); + DISTRHO_SAFE_ASSERT_RETURN(key16 != nullptr, V3_NOMEM); + + int16_t* const value16 = (int16_t*)std::malloc(sizeof(int16_t)*(valueLength + 1)); + DISTRHO_SAFE_ASSERT_RETURN(value16 != nullptr, V3_NOMEM); + + res = v3_cpp_obj(attrs)->get_string(attrs, "key", key16, sizeof(int16_t)*keyLength); DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); - res = v3_cpp_obj(attrs)->get_binary(attrs, "value", (const void**)&value16, &valueSize); + res = v3_cpp_obj(attrs)->get_string(attrs, "value", value16, sizeof(int16_t)*valueLength); DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); // do cheap inline conversion char* const key = (char*)key16; char* const value = (char*)value16; - for (uint32_t i=0; isecond = value; + std::free(key16); + std::free(value16); return V3_OK; } } @@ -1874,6 +1893,8 @@ public: d_stderr("Failed to find plugin state with key \"%s\"", key); } + std::free(key16); + std::free(value16); return V3_OK; } # endif @@ -2042,6 +2063,8 @@ private: DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,); v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 2); + v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); + v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); v3_cpp_obj(fConnection)->notify(fConnection, message); @@ -3085,6 +3108,10 @@ struct dpf_component : v3_component_cpp { hostContextFromFactory(h), hostContextFromInitialize(nullptr) { + // make sure context is valid through this component lifetime + if (hostContextFromFactory != nullptr) + v3_cpp_obj_ref(hostContextFromFactory); + // v3_funknown, everything custom query_interface = query_interface_component; ref = ref_component; @@ -3541,6 +3568,10 @@ struct dpf_factory : v3_plugin_factory_cpp { ~dpf_factory() { + // unref old context if there is one + if (hostContext != nullptr) + v3_cpp_obj_unref(hostContext); + if (gComponentGarbage.size() == 0) return; @@ -3696,7 +3727,18 @@ struct dpf_factory : v3_plugin_factory_cpp { { d_stdout("dpf_factory::set_host_context => %p %p", self, context); dpf_factory* const factory = *static_cast(self); + + // unref old context if there is one + if (factory->hostContext != nullptr) + v3_cpp_obj_unref(factory->hostContext); + + // store new context factory->hostContext = context; + + // make sure the object keeps being valid for a while + if (context != nullptr) + v3_cpp_obj_ref(context); + return V3_OK; } diff --git a/dpf/distrho/src/DistrhoUIVST3.cpp b/dpf/distrho/src/DistrhoUIVST3.cpp index 0bd6ce0..d50bb20 100644 --- a/dpf/distrho/src/DistrhoUIVST3.cpp +++ b/dpf/distrho/src/DistrhoUIVST3.cpp @@ -299,27 +299,46 @@ public: #if DISTRHO_PLUGIN_WANT_STATE if (std::strcmp(msgid, "state-set") == 0) { - int16_t* key16; - int16_t* value16; - uint32_t keySize, valueSize; + int64_t keyLength = -1; + int64_t valueLength = -1; v3_result res; - res = v3_cpp_obj(attrs)->get_binary(attrs, "key", (const void**)&key16, &keySize); + res = v3_cpp_obj(attrs)->get_int(attrs, "key:length", &keyLength); DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); + DISTRHO_SAFE_ASSERT_INT_RETURN(keyLength >= 0, keyLength, V3_INTERNAL_ERR); - res = v3_cpp_obj(attrs)->get_binary(attrs, "value", (const void**)&value16, &valueSize); + res = v3_cpp_obj(attrs)->get_int(attrs, "value:length", &valueLength); + DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); + DISTRHO_SAFE_ASSERT_INT_RETURN(valueLength >= 0, valueLength, V3_INTERNAL_ERR); + + int16_t* const key16 = (int16_t*)std::malloc(sizeof(int16_t)*(keyLength + 1)); + DISTRHO_SAFE_ASSERT_RETURN(key16 != nullptr, V3_NOMEM); + + int16_t* const value16 = (int16_t*)std::malloc(sizeof(int16_t)*(valueLength + 1)); + DISTRHO_SAFE_ASSERT_RETURN(value16 != nullptr, V3_NOMEM); + + res = v3_cpp_obj(attrs)->get_string(attrs, "key", key16, sizeof(int16_t)*keyLength); + DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); + + res = v3_cpp_obj(attrs)->get_string(attrs, "value", value16, sizeof(int16_t)*valueLength); DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); // do cheap inline conversion char* const key = (char*)key16; char* const value = (char*)value16; - for (uint32_t i=0; iset_int(attrlist, "__dpf_msg_target__", 1); + v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); + v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); v3_cpp_obj(fConnection)->notify(fConnection, message); diff --git a/dpf/tests/Demo.cpp b/dpf/tests/Demo.cpp index 744044a..41759d2 100644 --- a/dpf/tests/Demo.cpp +++ b/dpf/tests/Demo.cpp @@ -103,12 +103,13 @@ protected: void onDisplay() override { const GraphicsContext& context(getGraphicsContext()); + const double scaleFactor = getWindow().getScaleFactor(); const int iconSize = bgIcon.getWidth(); Color(0.027f, 0.027f, 0.027f).setFor(context); Rectangle(0, 0, getSize()).draw(context); - bgIcon.setY(curPage*iconSize + curPage*3); + bgIcon.setY(curPage * iconSize + curPage * 3 * scaleFactor); Color(0.129f, 0.129f, 0.129f).setFor(context); bgIcon.draw(context); @@ -118,7 +119,8 @@ protected: if (curHover != curPage && curHover != -1) { - Rectangle rHover(1, curHover*iconSize + curHover*3, iconSize-2, iconSize-2); + Rectangle rHover(1 * scaleFactor, curHover * iconSize + curHover * 3 * scaleFactor, + iconSize - 2 * scaleFactor, iconSize - 2 * scaleFactor); Color(0.071f, 0.071f, 0.071f).setFor(context); rHover.draw(context); @@ -146,13 +148,13 @@ protected: // draw some text nvg.beginFrame(this); - nvg.fontSize(23.0f); + nvg.fontSize(23.0f * scaleFactor); nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP); //nvg.textLineHeight(20.0f); nvg.fillColor(220,220,220,220); - nvg.textBox(10, 420, iconSize, "Haha,", nullptr); - nvg.textBox(15, 440, iconSize, "Look!", nullptr); + nvg.textBox(10 * scaleFactor, 420 * scaleFactor, iconSize, "Haha,", nullptr); + nvg.textBox(15 * scaleFactor, 440 * scaleFactor, iconSize, "Look!", nullptr); nvg.endFrame(); #endif @@ -226,9 +228,10 @@ protected: { const uint width = ev.size.getWidth(); const uint height = ev.size.getHeight(); + const double scaleFactor = getWindow().getScaleFactor(); - bgIcon.setWidth(width-4); - bgIcon.setHeight(width-4); + bgIcon.setWidth(width - 4 * scaleFactor); + bgIcon.setHeight(width - 4 * scaleFactor); lineSep.setStartPos(width, 0); lineSep.setEndPos(width, height); @@ -420,30 +423,31 @@ public: curWidget(nullptr) { const ScopedGraphicsContext sgc(*this); + const double scaleFactor = getScaleFactor(); wColor = new ExampleColorSubWidget(this); wColor->hide(); - wColor->setAbsoluteX(kSidebarWidth); + wColor->setAbsoluteX(kSidebarWidth * scaleFactor); wImages = new ExampleImagesSubWidget(this); wImages->hide(); - wImages->setAbsoluteX(kSidebarWidth); + wImages->setAbsoluteX(kSidebarWidth * scaleFactor); wRects = new ExampleRectanglesSubWidget(this); wRects->hide(); - wRects->setAbsoluteX(kSidebarWidth); + wRects->setAbsoluteX(kSidebarWidth * scaleFactor); wShapes = new ExampleShapesSubWidget(this); wShapes->hide(); - wShapes->setAbsoluteX(kSidebarWidth); + wShapes->setAbsoluteX(kSidebarWidth * scaleFactor); #ifdef DGL_OPENGL wText = new ExampleTextSubWidget(this), wText->hide(); - wText->setAbsoluteX(kSidebarWidth); + wText->setAbsoluteX(kSidebarWidth * scaleFactor); #endif wLeft = new LeftSideWidget(this, this), - wLeft->setAbsolutePos(2, 2); + wLeft->setAbsolutePos(2 * scaleFactor, 2 * scaleFactor); resizer = new ResizeHandle(this); @@ -493,10 +497,12 @@ protected: { StandaloneWindow::onReshape(width, height); - if (width < kSidebarWidth) + const double scaleFactor = getScaleFactor(); + + if (width < kSidebarWidth * scaleFactor) return; - Size size(width-kSidebarWidth, height); + const Size size(width - kSidebarWidth * scaleFactor, height); wColor->setSize(size); wImages->setSize(size); wRects->setSize(size); @@ -504,7 +510,7 @@ protected: #ifdef DGL_OPENGL wText->setSize(size); #endif - wLeft->setSize(kSidebarWidth-4, height-4); + wLeft->setSize((kSidebarWidth - 4) * scaleFactor, (height - 4) * scaleFactor); } private: @@ -528,8 +534,9 @@ template void createAndShowExampleWidgetStandaloneWindow(Application& app) { ExampleWidgetStandaloneWindow swin(app); + const double scaleFactor = swin.getScaleFactor(); swin.setResizable(true); - swin.setSize(600, 500); + swin.setSize(600 * scaleFactor, 500 * scaleFactor); swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); swin.show(); app.exec(); diff --git a/dpf/tests/FileBrowserDialog.cpp b/dpf/tests/FileBrowserDialog.cpp index 3a9b4ab..3733c38 100644 --- a/dpf/tests/FileBrowserDialog.cpp +++ b/dpf/tests/FileBrowserDialog.cpp @@ -38,21 +38,26 @@ public: loadSharedResources(); #endif setResizable(true); - setSize(500, 200); - setGeometryConstraints(500, 200, true); setTitle("FileBrowserDialog"); + + const double scaleFactor = getScaleFactor(); + setGeometryConstraints(500 * scaleFactor, 200 * scaleFactor, true); + setSize(500 * scaleFactor, 200 * scaleFactor); + done(); } protected: void onNanoDisplay() override { + const double scaleFactor = getScaleFactor(); + // Selected file beginPath(); - fontSize(14); + fontSize(14 * scaleFactor); textAlign(ALIGN_LEFT | ALIGN_MIDDLE); fillColor(255, 255, 255, 255); - text(20, getHeight()/2, selectedFile, NULL); + text(20 * scaleFactor, getHeight()/2, selectedFile, NULL); closePath(); // Button background @@ -66,7 +71,7 @@ protected: // Button label beginPath(); - fontSize(14); + fontSize(14 * scaleFactor); Rectangle buttonTextBounds; textBounds(0, 0, "Press me", NULL, buttonTextBounds); textAlign(ALIGN_CENTER | ALIGN_MIDDLE); @@ -138,8 +143,12 @@ protected: { const uint width = ev.size.getWidth(); const uint height = ev.size.getHeight(); + const double scaleFactor = getScaleFactor(); - buttonBounds = Rectangle(width - 120, height/2 - 20, 100, 40); + buttonBounds = Rectangle(width - 120 * scaleFactor, + height/2 - 20 * scaleFactor, + 100 * scaleFactor, + 40 * scaleFactor); } void onFocus(const bool focus, CrossingMode) override diff --git a/dpf/tests/NanoImage.cpp b/dpf/tests/NanoImage.cpp index 5140bfd..9b719d1 100644 --- a/dpf/tests/NanoImage.cpp +++ b/dpf/tests/NanoImage.cpp @@ -85,7 +85,7 @@ public: setResizable(true); setSize(500, 500); - // setGeometryConstraints(500, 500, false); + setGeometryConstraints(500, 500, false, true); setTitle("NanoImage"); done(); diff --git a/dpf/tests/widgets/ExampleTextWidget.hpp b/dpf/tests/widgets/ExampleTextWidget.hpp index b7062e6..60faae2 100644 --- a/dpf/tests/widgets/ExampleTextWidget.hpp +++ b/dpf/tests/widgets/ExampleTextWidget.hpp @@ -42,23 +42,28 @@ public: // StandaloneWindow explicit ExampleTextWidget(Application& app); + // helper + double getScaleFactor(); + protected: void onNanoDisplay() override { const int width = BaseWidget::getWidth(); const int height = BaseWidget::getHeight(); + const double scaleFactor = getScaleFactor(); - NanoVG::fontSize(40.0f); + NanoVG::fontSize(40.0f * scaleFactor); NanoVG::textAlign(NanoVG::Align(NanoVG::ALIGN_CENTER|NanoVG::ALIGN_MIDDLE)); - NanoVG::textLineHeight(20.0f); + NanoVG::textLineHeight(20.0f * scaleFactor); NanoVG::beginPath(); NanoVG::fillColor(220,220,220,255); - NanoVG::roundedRect(10, height/4+10, width-20, height/2-20, 3); + NanoVG::roundedRect(10 * scaleFactor, height/4 + 10 * scaleFactor, + width - 20 * scaleFactor, height/2 - 20 * scaleFactor, 3 * scaleFactor); NanoVG::fill(); NanoVG::fillColor(0,150,0,220); - NanoVG::textBox(10, height/2, width-20, "Hello World!", nullptr); + NanoVG::textBox(10 * scaleFactor, height/2, width - 20 * scaleFactor, "Hello World!", nullptr); } }; @@ -71,6 +76,12 @@ ExampleTextWidget::ExampleTextWidget(Widget* const parent) setSize(500, 300); } +template<> inline +double ExampleTextWidget::getScaleFactor() +{ + return getWindow().getScaleFactor(); +} + // TopLevelWidget template<> inline ExampleTextWidget::ExampleTextWidget(Window& windowToMapTo) @@ -80,6 +91,12 @@ ExampleTextWidget::ExampleTextWidget(Window& windowToMapTo) setSize(500, 300); } +template<> inline +double ExampleTextWidget::getScaleFactor() +{ + return NanoTopLevelWidget::getScaleFactor(); +} + // StandaloneWindow template<> inline ExampleTextWidget::ExampleTextWidget(Application& app) @@ -90,6 +107,12 @@ ExampleTextWidget::ExampleTextWidget(Application& app) done(); } +template<> inline +double ExampleTextWidget::getScaleFactor() +{ + return Window::getScaleFactor(); +} + template class ExampleTextWidget; template class ExampleTextWidget; template class ExampleTextWidget; diff --git a/plugins/MVerb/DistrhoPluginInfo.h b/plugins/MVerb/DistrhoPluginInfo.h index b36d5ee..d3b92ad 100644 --- a/plugins/MVerb/DistrhoPluginInfo.h +++ b/plugins/MVerb/DistrhoPluginInfo.h @@ -29,6 +29,7 @@ #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 -#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ReverbPlugin" +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ReverbPlugin" +#define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Reverb" #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/plugins/MVerb/Makefile b/plugins/MVerb/Makefile index b5b9abe..0d0e5db 100644 --- a/plugins/MVerb/Makefile +++ b/plugins/MVerb/Makefile @@ -29,6 +29,7 @@ include ../../dpf/Makefile.plugins.mk TARGETS += jack TARGETS += ladspa +TARGETS += lv2_sep TARGETS += vst2 TARGETS += vst3 @@ -38,12 +39,6 @@ TARGETS += dssi endif endif -ifeq ($(HAVE_DGL),true) -TARGETS += lv2_sep -else -TARGETS += lv2_dsp -endif - all: $(TARGETS) # -------------------------------------------------------------- diff --git a/plugins/ProM/DistrhoUIProM.cpp b/plugins/ProM/DistrhoUIProM.cpp index 1d91980..9ccc883 100644 --- a/plugins/ProM/DistrhoUIProM.cpp +++ b/plugins/ProM/DistrhoUIProM.cpp @@ -14,7 +14,6 @@ * For a full copy of the license see the LICENSE file. */ -#include "libprojectM/projectM-opengl.h" #include "libprojectM/projectM.hpp" #include "DistrhoPluginProM.hpp" @@ -69,6 +68,12 @@ static String getCurrentExecutableDataDir() } else # endif + if (datadir.endsWith("/x86_64-linux")) + { + datadir.truncate(datadir.rfind('/')); + datadir += "/Resources"; + } + else #endif { datadir += "/resources"; @@ -166,9 +171,6 @@ void DistrhoUIProM::onDisplay() return; fPM->renderFrame(); - - // turn off shaders at the end of the drawing cycle, so other things can draw properly - glUseProgram(0); } static projectMKeycode dgl2pmkey(const DGL_NAMESPACE::Key key) noexcept @@ -251,33 +253,6 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) if (fPM == nullptr) return false; -#if 0 - if (ev.press && (ev.key == '1' || ev.key == '+' || ev.key == '-')) - { - if (ev.key == '1') - { - if (getWidth() != 512 || getHeight() != 512) - setSize(512, 512); - } - else if (ev.key == '+') - { - /**/ if (getWidth() < 1100 && getHeight() < 1100) - setSize(getWidth()+100, getHeight()+100); - else if (getWidth() != 1100 || getHeight() != 1100) - setSize(1100, 1100); - } - else if (ev.key == '-') - { - /**/ if (getWidth() >= 200 && getHeight() >= 200) - setSize(getWidth()-100, getHeight()-100); - else if (getWidth() != 100 || getHeight() != 100) - setSize(100, 100); - } - - return true; - } -#endif - // special handling for text if (fPM->isTextInputActive(true) && !ev.press) { @@ -357,20 +332,6 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) return true; } -bool DistrhoUIProM::onSpecial(const SpecialEvent& ev) -{ - if (fPM == nullptr) - return false; - - const projectMKeycode pmKey = dgl2pmkey(ev.key); - - if (pmKey == PROJECTM_K_NONE) - return false; - - fPM->default_key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey); - return true; -} - // ----------------------------------------------------------------------- UI* createUI() diff --git a/plugins/ProM/DistrhoUIProM.hpp b/plugins/ProM/DistrhoUIProM.hpp index f778158..98e1ba6 100644 --- a/plugins/ProM/DistrhoUIProM.hpp +++ b/plugins/ProM/DistrhoUIProM.hpp @@ -49,7 +49,6 @@ protected: void onDisplay() override; bool onKeyboard(const KeyboardEvent&) override; - bool onSpecial(const SpecialEvent&) override; private: ScopedPointer fPM; diff --git a/plugins/ProM/Makefile b/plugins/ProM/Makefile index 7e29de9..3d78b6c 100644 --- a/plugins/ProM/Makefile +++ b/plugins/ProM/Makefile @@ -195,9 +195,7 @@ LINK_FLAGS += -lpthread # -------------------------------------------------------------- # Enable all possible plugin types -TARGETS += lv2 -TARGETS += vst2 -TARGETS += vst3 +TARGETS = lv2 vst2 vst3 all: $(TARGETS) diff --git a/plugins/ProM/ResizeHandle.hpp b/plugins/ProM/ResizeHandle.hpp index c24c9eb..9729f8e 100644 --- a/plugins/ProM/ResizeHandle.hpp +++ b/plugins/ProM/ResizeHandle.hpp @@ -56,6 +56,11 @@ protected: const GraphicsContext& context(getGraphicsContext()); const double lineWidth = 1.0 * getScaleFactor(); +#ifdef DGL_OPENGL + glUseProgram(0); + glMatrixMode(GL_MODELVIEW); +#endif + // draw white lines, 1px wide Color(1.0f, 1.0f, 1.0f).setFor(context); l1.draw(context, lineWidth); diff --git a/plugins/glBars/DistrhoPluginInfo.h b/plugins/glBars/DistrhoPluginInfo.h index 73e22a0..e06c41d 100644 --- a/plugins/glBars/DistrhoPluginInfo.h +++ b/plugins/glBars/DistrhoPluginInfo.h @@ -30,6 +30,7 @@ #define DISTRHO_PLUGIN_NUM_OUTPUTS 1 #define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 #define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:AnalyserPlugin" +#define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Analyzer" #define DISTRHO_UI_USER_RESIZABLE 1 enum Parameters { diff --git a/plugins/glBars/DistrhoUIGLBars.cpp b/plugins/glBars/DistrhoUIGLBars.cpp index 8cb7e3e..ad27ee1 100644 --- a/plugins/glBars/DistrhoUIGLBars.cpp +++ b/plugins/glBars/DistrhoUIGLBars.cpp @@ -3,7 +3,7 @@ * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * Copyright (C) 2000 Christian Zander * Copyright (C) 2015 Nedko Arnaudov - * Copyright (C) 2016-2019 Filipe Coelho + * Copyright (C) 2016-2021 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,9 +27,14 @@ START_NAMESPACE_DISTRHO DistrhoUIGLBars::DistrhoUIGLBars() : UI(512, 512), - fInitialized(false) + fInitialized(false), + fResizeHandle(this) { setGeometryConstraints(256, 256, true); + + // no need to show resize handle if window is user-resizable + if (isResizable()) + fResizeHandle.hide(); } DistrhoUIGLBars::~DistrhoUIGLBars() @@ -100,36 +105,6 @@ void DistrhoUIGLBars::onDisplay() fState.Render(); } -bool DistrhoUIGLBars::onKeyboard(const KeyboardEvent& ev) -{ - if (ev.press && (ev.key == '1' || ev.key == '+' || ev.key == '-')) - { - if (ev.key == '1') - { - if (getWidth() != 512 || getHeight() != 512) - setSize(512, 512); - } - else if (ev.key == '+') - { - /**/ if (getWidth() < 1100 && getHeight() < 1100) - setSize(std::min(getWidth()+100, 1100U), std::min(getHeight()+100, 1100U)); - else if (getWidth() != 1100 || getHeight() != 1100) - setSize(1100, 1100); - } - else if (ev.key == '-') - { - /**/ if (getWidth() > 100 && getHeight() > 100) - setSize(std::max(getWidth()-100, 100U), std::max(getHeight()-100, 100U)); - else if (getWidth() != 100 || getHeight() != 100) - setSize(100, 100); - } - - return true; - } - - return true; -} - // ----------------------------------------------------------------------- UI* createUI() diff --git a/plugins/glBars/DistrhoUIGLBars.hpp b/plugins/glBars/DistrhoUIGLBars.hpp index 953ad88..34dfbcb 100644 --- a/plugins/glBars/DistrhoUIGLBars.hpp +++ b/plugins/glBars/DistrhoUIGLBars.hpp @@ -3,7 +3,7 @@ * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * Copyright (C) 2000 Christian Zander * Copyright (C) 2015 Nedko Arnaudov - * Copyright (C) 2016-2019 Filipe Coelho + * Copyright (C) 2016-2021 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,6 +24,7 @@ #include "DistrhoUI.hpp" #include "glBars.hpp" +#include "ResizeHandle.hpp" START_NAMESPACE_DISTRHO @@ -50,11 +51,11 @@ protected: // Widget Callbacks void onDisplay() override; - bool onKeyboard(const KeyboardEvent&) override; private: bool fInitialized; glBarsState fState; + ResizeHandle fResizeHandle; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoUIGLBars) }; diff --git a/plugins/glBars/Makefile b/plugins/glBars/Makefile index 0cc4dc3..f87fa8b 100644 --- a/plugins/glBars/Makefile +++ b/plugins/glBars/Makefile @@ -31,10 +31,7 @@ LINK_FLAGS += -lpthread # -------------------------------------------------------------- # Enable all possible plugin types -TARGETS += jack -TARGETS += lv2 -TARGETS += vst2 -TARGETS += vst3 +TARGETS = jack lv2 vst2 vst3 all: $(TARGETS)