Signed-off-by: falkTX <falktx@falktx.com>tags/v1.5
| @@ -138,7 +138,6 @@ endif # HAVE_CAIRO_OR_OPENGL | |||||
| endif # MACOS | endif # MACOS | ||||
| cp -r bin/*.lv2 $(DESTDIR)$(PREFIX)/lib/lv2/ | cp -r bin/*.lv2 $(DESTDIR)$(PREFIX)/lib/lv2/ | ||||
| ifeq ($(HAVE_JACK),true) | |||||
| install -m 755 bin/Kars$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | install -m 755 bin/Kars$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | ||||
| install -m 755 bin/3BandEQ$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | install -m 755 bin/3BandEQ$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | ||||
| install -m 755 bin/3BandSplitter$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | install -m 755 bin/3BandSplitter$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | ||||
| @@ -158,7 +157,6 @@ ifeq ($(HAVE_PROJM),true) | |||||
| install -m 755 bin/ProM$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | install -m 755 bin/ProM$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | ||||
| endif # HAVE_PROJM | endif # HAVE_PROJM | ||||
| endif # HAVE_OPENGL | endif # HAVE_OPENGL | ||||
| endif # HAVE_JACK | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| @@ -26,11 +26,10 @@ endif | |||||
| ifneq (,$(findstring haiku,$(TARGET_MACHINE))) | ifneq (,$(findstring haiku,$(TARGET_MACHINE))) | ||||
| HAIKU=true | HAIKU=true | ||||
| endif | endif | ||||
| ifneq (,$(findstring gnu,$(TARGET_MACHINE))) | |||||
| HURD=true | |||||
| endif | |||||
| ifneq (,$(findstring linux,$(TARGET_MACHINE))) | ifneq (,$(findstring linux,$(TARGET_MACHINE))) | ||||
| LINUX=true | LINUX=true | ||||
| else ifneq (,$(findstring gnu,$(TARGET_MACHINE))) | |||||
| HURD=true | |||||
| endif | endif | ||||
| ifneq (,$(findstring apple,$(TARGET_MACHINE))) | ifneq (,$(findstring apple,$(TARGET_MACHINE))) | ||||
| MACOS=true | MACOS=true | ||||
| @@ -184,7 +183,7 @@ CXXFLAGS += -fvisibility-inlines-hidden | |||||
| endif | endif | ||||
| BUILD_C_FLAGS = $(BASE_FLAGS) -std=gnu99 $(CFLAGS) | BUILD_C_FLAGS = $(BASE_FLAGS) -std=gnu99 $(CFLAGS) | ||||
| BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=gnu++0x $(CXXFLAGS) | |||||
| BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=gnu++11 $(CXXFLAGS) | |||||
| LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS) | LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS) | ||||
| ifneq ($(MACOS),true) | ifneq ($(MACOS),true) | ||||
| @@ -438,3 +437,47 @@ SILENT = @ | |||||
| endif | endif | ||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| # all needs to be first | |||||
| all: | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # helper to print what is available/possible to build | |||||
| print_available = @echo $(1): $(shell echo $($(1)) | grep -q true && echo Yes || echo No) | |||||
| features: | |||||
| @echo === Detected CPU | |||||
| $(call print_available,CPU_AARCH64) | |||||
| $(call print_available,CPU_ARM) | |||||
| $(call print_available,CPU_ARM64) | |||||
| $(call print_available,CPU_ARM_OR_AARCH64) | |||||
| $(call print_available,CPU_I386) | |||||
| $(call print_available,CPU_I386_OR_X86_64) | |||||
| @echo === Detected OS | |||||
| $(call print_available,BSD) | |||||
| $(call print_available,HAIKU) | |||||
| $(call print_available,HURD) | |||||
| $(call print_available,LINUX) | |||||
| $(call print_available,MACOS) | |||||
| $(call print_available,WINDOWS) | |||||
| $(call print_available,HAIKU_OR_MACOS_OR_WINDOWS) | |||||
| $(call print_available,LINUX_OR_MACOS) | |||||
| $(call print_available,MACOS_OR_WINDOWS) | |||||
| $(call print_available,UNIX) | |||||
| @echo === Detected features | |||||
| $(call print_available,HAVE_ALSA) | |||||
| $(call print_available,HAVE_CAIRO) | |||||
| $(call print_available,HAVE_DGL) | |||||
| $(call print_available,HAVE_LIBLO) | |||||
| $(call print_available,HAVE_OPENGL) | |||||
| $(call print_available,HAVE_PULSEAUDIO) | |||||
| $(call print_available,HAVE_RTAUDIO) | |||||
| $(call print_available,HAVE_STUB) | |||||
| $(call print_available,HAVE_VULKAN) | |||||
| $(call print_available,HAVE_X11) | |||||
| $(call print_available,HAVE_XCURSOR) | |||||
| $(call print_available,HAVE_XEXT) | |||||
| $(call print_available,HAVE_XRANDR) | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -75,8 +75,10 @@ ifeq ($(LINUX),true) | |||||
| VST3_FILENAME = $(TARGET_PROCESSOR)-linux/$(NAME).so | VST3_FILENAME = $(TARGET_PROCESSOR)-linux/$(NAME).so | ||||
| endif | endif | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| ifneq ($(MACOS_OLD),true) | |||||
| VST3_FILENAME = MacOS/$(NAME) | VST3_FILENAME = MacOS/$(NAME) | ||||
| endif | endif | ||||
| endif | |||||
| ifeq ($(WINDOWS),true) | ifeq ($(WINDOWS),true) | ||||
| VST3_FILENAME = $(TARGET_PROCESSOR)-win/$(NAME).vst3 | VST3_FILENAME = $(TARGET_PROCESSOR)-win/$(NAME).vst3 | ||||
| endif | endif | ||||
| @@ -140,7 +142,7 @@ endif | |||||
| ifeq ($(UI_TYPE),cairo) | ifeq ($(UI_TYPE),cairo) | ||||
| ifeq ($(HAVE_CAIRO),true) | ifeq ($(HAVE_CAIRO),true) | ||||
| DGL_FLAGS += -DDGL_CAIRO | |||||
| DGL_FLAGS += -DDGL_CAIRO -DHAVE_DGL | |||||
| DGL_FLAGS += $(CAIRO_FLAGS) | DGL_FLAGS += $(CAIRO_FLAGS) | ||||
| DGL_LIBS += $(CAIRO_LIBS) | DGL_LIBS += $(CAIRO_LIBS) | ||||
| DGL_LIB = $(DPF_PATH)/build/libdgl-cairo.a | DGL_LIB = $(DPF_PATH)/build/libdgl-cairo.a | ||||
| @@ -152,7 +154,7 @@ endif | |||||
| ifeq ($(UI_TYPE),opengl) | ifeq ($(UI_TYPE),opengl) | ||||
| ifeq ($(HAVE_OPENGL),true) | ifeq ($(HAVE_OPENGL),true) | ||||
| DGL_FLAGS += -DDGL_OPENGL | |||||
| DGL_FLAGS += -DDGL_OPENGL -DHAVE_DGL | |||||
| DGL_FLAGS += $(OPENGL_FLAGS) | DGL_FLAGS += $(OPENGL_FLAGS) | ||||
| DGL_LIBS += $(OPENGL_LIBS) | DGL_LIBS += $(OPENGL_LIBS) | ||||
| DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a | DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a | ||||
| @@ -164,7 +166,7 @@ endif | |||||
| ifeq ($(UI_TYPE),vulkan) | ifeq ($(UI_TYPE),vulkan) | ||||
| ifeq ($(HAVE_VULKAN),true) | ifeq ($(HAVE_VULKAN),true) | ||||
| DGL_FLAGS += -DDGL_VULKAN | |||||
| DGL_FLAGS += -DDGL_VULKAN -DHAVE_DGL | |||||
| DGL_FLAGS += $(VULKAN_FLAGS) | DGL_FLAGS += $(VULKAN_FLAGS) | ||||
| DGL_LIBS += $(VULKAN_LIBS) | DGL_LIBS += $(VULKAN_LIBS) | ||||
| DGL_LIB = $(DPF_PATH)/build/libdgl-vulkan.a | DGL_LIB = $(DPF_PATH)/build/libdgl-vulkan.a | ||||
| @@ -328,7 +330,11 @@ lv2: $(lv2) | |||||
| lv2_dsp: $(lv2_dsp) | lv2_dsp: $(lv2_dsp) | ||||
| lv2_sep: $(lv2_dsp) $(lv2_ui) | lv2_sep: $(lv2_dsp) $(lv2_ui) | ||||
| ifeq ($(HAVE_DGL),true) | |||||
| $(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB) | $(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB) | ||||
| else | |||||
| $(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o | |||||
| endif | |||||
| -@mkdir -p $(shell dirname $@) | -@mkdir -p $(shell dirname $@) | ||||
| @echo "Creating LV2 plugin for $(NAME)" | @echo "Creating LV2 plugin for $(NAME)" | ||||
| $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2) $(SYMBOLS_LV2UI) -o $@ | $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_LV2) $(SYMBOLS_LV2UI) -o $@ | ||||
| @@ -209,6 +209,7 @@ function(dpf__build_ladspa NAME) | |||||
| target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp") | target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp") | ||||
| set_target_properties("${NAME}-ladspa" PROPERTIES | set_target_properties("${NAME}-ladspa" PROPERTIES | ||||
| LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | ||||
| ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/ladspa/$<0:>" | |||||
| OUTPUT_NAME "${NAME}-ladspa" | OUTPUT_NAME "${NAME}-ladspa" | ||||
| PREFIX "") | PREFIX "") | ||||
| endfunction() | endfunction() | ||||
| @@ -236,6 +237,7 @@ function(dpf__build_dssi NAME DGL_LIBRARY) | |||||
| target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp") | target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp") | ||||
| set_target_properties("${NAME}-dssi" PROPERTIES | set_target_properties("${NAME}-dssi" PROPERTIES | ||||
| LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | ||||
| ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/dssi/$<0:>" | |||||
| OUTPUT_NAME "${NAME}-dssi" | OUTPUT_NAME "${NAME}-dssi" | ||||
| PREFIX "") | PREFIX "") | ||||
| @@ -265,6 +267,7 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||||
| target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp") | target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp") | ||||
| set_target_properties("${NAME}-lv2" PROPERTIES | set_target_properties("${NAME}-lv2" PROPERTIES | ||||
| LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | ||||
| ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" | |||||
| OUTPUT_NAME "${NAME}_dsp" | OUTPUT_NAME "${NAME}_dsp" | ||||
| PREFIX "") | PREFIX "") | ||||
| @@ -280,6 +283,7 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||||
| target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui") | target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui") | ||||
| set_target_properties("${NAME}-lv2-ui" PROPERTIES | set_target_properties("${NAME}-lv2-ui" PROPERTIES | ||||
| LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | ||||
| ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" | |||||
| OUTPUT_NAME "${NAME}_ui" | OUTPUT_NAME "${NAME}_ui" | ||||
| PREFIX "") | PREFIX "") | ||||
| endif() | endif() | ||||
| @@ -310,6 +314,7 @@ function(dpf__build_vst2 NAME DGL_LIBRARY) | |||||
| target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui") | target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui") | ||||
| set_target_properties("${NAME}-vst2" PROPERTIES | set_target_properties("${NAME}-vst2" PROPERTIES | ||||
| LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | ||||
| ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst2/$<0:>" | |||||
| OUTPUT_NAME "${NAME}-vst2" | OUTPUT_NAME "${NAME}-vst2" | ||||
| PREFIX "") | PREFIX "") | ||||
| endfunction() | endfunction() | ||||
| @@ -363,7 +368,7 @@ function(dpf__add_dgl_cairo) | |||||
| target_link_libraries(dgl-cairo PRIVATE dgl-system-libs) | target_link_libraries(dgl-cairo PRIVATE dgl-system-libs) | ||||
| add_library(dgl-cairo-definitions INTERFACE) | add_library(dgl-cairo-definitions INTERFACE) | ||||
| target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO") | |||||
| target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO" "HAVE_DGL") | |||||
| target_include_directories(dgl-cairo PUBLIC ${CAIRO_INCLUDE_DIRS}) | target_include_directories(dgl-cairo PUBLIC ${CAIRO_INCLUDE_DIRS}) | ||||
| if(MINGW) | if(MINGW) | ||||
| @@ -429,7 +434,7 @@ function(dpf__add_dgl_opengl) | |||||
| target_link_libraries(dgl-opengl PRIVATE dgl-system-libs) | target_link_libraries(dgl-opengl PRIVATE dgl-system-libs) | ||||
| add_library(dgl-opengl-definitions INTERFACE) | add_library(dgl-opengl-definitions INTERFACE) | ||||
| target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL") | |||||
| target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL" "HAVE_DGL") | |||||
| target_include_directories(dgl-opengl PUBLIC "${OPENGL_INCLUDE_DIR}") | target_include_directories(dgl-opengl PUBLIC "${OPENGL_INCLUDE_DIR}") | ||||
| target_link_libraries(dgl-opengl PRIVATE dgl-opengl-definitions "${OPENGL_gl_LIBRARY}") | target_link_libraries(dgl-opengl PRIVATE dgl-opengl-definitions "${OPENGL_gl_LIBRARY}") | ||||
| @@ -753,6 +753,11 @@ public: | |||||
| */ | */ | ||||
| bool contains(const Point<T>& pos) const noexcept; | bool contains(const Point<T>& pos) const noexcept; | ||||
| /** | |||||
| Check if this rectangle contains the point @a pos affected by a custom scale. | |||||
| */ | |||||
| bool containsAfterScaling(const Point<T>& pos, double scaling) const noexcept; | |||||
| /** | /** | ||||
| Check if this rectangle contains the point @a pos of another type. | Check if this rectangle contains the point @a pos of another type. | ||||
| */ | */ | ||||
| @@ -14,7 +14,10 @@ BUILD_CXX_FLAGS += -Isrc/pugl-upstream/include | |||||
| LINK_FLAGS += $(DGL_LIBS) | LINK_FLAGS += $(DGL_LIBS) | ||||
| # TODO fix these after pugl-upstream is done | # TODO fix these after pugl-upstream is done | ||||
| BUILD_CXX_FLAGS += -Wno-attributes -Wno-extra -Wno-missing-field-initializers -Wno-narrowing | |||||
| BUILD_CXX_FLAGS += -Wno-attributes -Wno-extra -Wno-missing-field-initializers | |||||
| ifneq ($(MACOS),true) | |||||
| BUILD_CXX_FLAGS += -Wno-narrowing | |||||
| endif | |||||
| # ifneq ($(MACOS_OLD),true) | # ifneq ($(MACOS_OLD),true) | ||||
| # needed by sofd right now, fix later | # needed by sofd right now, fix later | ||||
| @@ -107,6 +107,14 @@ public: | |||||
| DISTRHO_DEPRECATED_BY("getWindow()") | DISTRHO_DEPRECATED_BY("getWindow()") | ||||
| Window& getParentWindow() const noexcept { return getWindow(); } | Window& getParentWindow() const noexcept { return getWindow(); } | ||||
| protected: | |||||
| bool onKeyboard(const KeyboardEvent&) override; | |||||
| bool onSpecial(const SpecialEvent&) override; | |||||
| bool onCharacterInput(const CharacterInputEvent&) override; | |||||
| bool onMouse(const MouseEvent&) override; | |||||
| bool onMotion(const MotionEvent&) override; | |||||
| bool onScroll(const ScrollEvent&) override; | |||||
| private: | private: | ||||
| struct PrivateData; | struct PrivateData; | ||||
| PrivateData* const pData; | PrivateData* const pData; | ||||
| @@ -150,7 +150,11 @@ public: | |||||
| : BaseEvent(), | : BaseEvent(), | ||||
| keycode(0), | keycode(0), | ||||
| character(0), | character(0), | ||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| string{'\0','\0','\0','\0','\0','\0','\0','\0'} {} | string{'\0','\0','\0','\0','\0','\0','\0','\0'} {} | ||||
| #else | |||||
| string() { std::memset(string, 0, sizeof(string)); } | |||||
| #endif | |||||
| }; | }; | ||||
| /** | /** | ||||
| @@ -64,6 +64,11 @@ Application::PrivateData::PrivateData(const bool standalone) | |||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| sofdFileDialogSetup(world); | sofdFileDialogSetup(world); | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_OS_MAC | |||||
| if (standalone) | |||||
| puglMacOSActivateApp(); | |||||
| #endif | |||||
| } | } | ||||
| Application::PrivateData::~PrivateData() | Application::PrivateData::~PrivateData() | ||||
| @@ -726,21 +726,21 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||||
| cairo_matrix_t matrix; | cairo_matrix_t matrix; | ||||
| cairo_get_matrix(handle, &matrix); | cairo_get_matrix(handle, &matrix); | ||||
| if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | |||||
| { | |||||
| // full viewport size | |||||
| cairo_translate(handle, 0, 0); | |||||
| } | |||||
| else if (needsViewportScaling) | |||||
| if (needsViewportScaling) | |||||
| { | { | ||||
| // limit viewport to widget bounds | // limit viewport to widget bounds | ||||
| // NOTE only used for nanovg for now, which is not relevant here | // NOTE only used for nanovg for now, which is not relevant here | ||||
| } | |||||
| else if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | |||||
| { | |||||
| // full viewport size | |||||
| cairo_translate(handle, 0, 0); | cairo_translate(handle, 0, 0); | ||||
| cairo_scale(handle, autoScaleFactor, autoScaleFactor); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // set viewport pos | // set viewport pos | ||||
| cairo_translate(handle, absolutePos.getX(), absolutePos.getY()); | |||||
| cairo_translate(handle, absolutePos.getX() * autoScaleFactor, absolutePos.getY() * autoScaleFactor); | |||||
| // then cut the outer bounds | // then cut the outer bounds | ||||
| cairo_rectangle(handle, | cairo_rectangle(handle, | ||||
| @@ -751,6 +751,9 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||||
| cairo_clip(handle); | cairo_clip(handle); | ||||
| needsResetClip = true; | needsResetClip = true; | ||||
| // set viewport scaling | |||||
| cairo_scale(handle, autoScaleFactor, autoScaleFactor); | |||||
| } | } | ||||
| // display widget | // display widget | ||||
| @@ -771,24 +774,34 @@ void TopLevelWidget::PrivateData::display() | |||||
| if (! selfw->pData->visible) | if (! selfw->pData->visible) | ||||
| return; | return; | ||||
| cairo_t* const handle = static_cast<const CairoGraphicsContext&>(self->getGraphicsContext()).handle; | |||||
| const Size<uint> size(window.getSize()); | const Size<uint> size(window.getSize()); | ||||
| const uint width = size.getWidth(); | const uint width = size.getWidth(); | ||||
| const uint height = size.getHeight(); | const uint height = size.getHeight(); | ||||
| const double autoScaleFactor = window.pData->autoScaleFactor; | const double autoScaleFactor = window.pData->autoScaleFactor; | ||||
| // FIXME anything needed here? | |||||
| #if 0 | |||||
| cairo_matrix_t matrix; | |||||
| cairo_get_matrix(handle, &matrix); | |||||
| // full viewport size | // full viewport size | ||||
| if (window.pData->autoScaling) | if (window.pData->autoScaling) | ||||
| glViewport(0, -(height * autoScaleFactor - height), width * autoScaleFactor, height * autoScaleFactor); | |||||
| { | |||||
| cairo_translate(handle, 0, 0); | |||||
| cairo_scale(handle, autoScaleFactor, autoScaleFactor); | |||||
| } | |||||
| else | else | ||||
| glViewport(0, 0, width, height); | |||||
| #endif | |||||
| { | |||||
| cairo_translate(handle, 0, 0); | |||||
| cairo_scale(handle, 1.0, 1.0); | |||||
| } | |||||
| // main widget drawing | // main widget drawing | ||||
| self->onDisplay(); | self->onDisplay(); | ||||
| cairo_set_matrix(handle, &matrix); | |||||
| // now draw subwidgets if there are any | // now draw subwidgets if there are any | ||||
| selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | ||||
| } | } | ||||
| @@ -925,6 +925,12 @@ bool Rectangle<uint>::contains(const Point<double>& p) const noexcept | |||||
| return (p.x >= pos.x && p.y >= pos.y && p.x <= pos.x+size.fWidth && p.y <= pos.y+size.fHeight); | return (p.x >= pos.x && p.y >= pos.y && p.x <= pos.x+size.fWidth && p.y <= pos.y+size.fHeight); | ||||
| } | } | ||||
| template<typename T> | |||||
| bool Rectangle<T>::containsAfterScaling(const Point<T>& p, const double scaling) const noexcept | |||||
| { | |||||
| return (p.x >= pos.x && p.y >= pos.y && p.x/scaling <= pos.x+size.fWidth && p.y/scaling <= pos.y+size.fHeight); | |||||
| } | |||||
| template<typename T> | template<typename T> | ||||
| bool Rectangle<T>::containsX(const T& x) const noexcept | bool Rectangle<T>::containsX(const T& x) const noexcept | ||||
| { | { | ||||
| @@ -29,8 +29,11 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(Window& parentWindow, cons | |||||
| setResizable(false); | setResizable(false); | ||||
| setTitle("About"); | setTitle("About"); | ||||
| if (image.isValid()) | |||||
| setSize(image.getSize()); | |||||
| if (image.isInvalid()) | |||||
| return; | |||||
| setSize(image.getSize()); | |||||
| setGeometryConstraints(image.getWidth(), image.getHeight(), true, true); | |||||
| } | } | ||||
| template <class ImageType> | template <class ImageType> | ||||
| @@ -41,8 +44,11 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(TopLevelWidget* const pare | |||||
| setResizable(false); | setResizable(false); | ||||
| setTitle("About"); | setTitle("About"); | ||||
| if (image.isValid()) | |||||
| setSize(image.getSize()); | |||||
| if (image.isInvalid()) | |||||
| return; | |||||
| setSize(image.getSize()); | |||||
| setGeometryConstraints(image.getWidth(), image.getHeight(), true, true); | |||||
| } | } | ||||
| template <class ImageType> | template <class ImageType> | ||||
| @@ -52,7 +58,12 @@ void ImageBaseAboutWindow<ImageType>::setImage(const ImageType& image) | |||||
| return; | return; | ||||
| img = image; | img = image; | ||||
| if (image.isInvalid()) | |||||
| return; | |||||
| setSize(image.getSize()); | setSize(image.getSize()); | ||||
| setGeometryConstraints(image.getWidth(), image.getHeight(), true, true); | |||||
| } | } | ||||
| template <class ImageType> | template <class ImageType> | ||||
| @@ -598,7 +598,10 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||||
| else if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | else if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | ||||
| { | { | ||||
| // full viewport size | // full viewport size | ||||
| glViewport(0, 0, static_cast<int>(width), static_cast<int>(height)); | |||||
| glViewport(0, | |||||
| -static_cast<int>(height * autoScaleFactor - height + 0.5), | |||||
| static_cast<int>(width * autoScaleFactor + 0.5), | |||||
| static_cast<int>(height * autoScaleFactor + 0.5)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -646,9 +649,9 @@ void TopLevelWidget::PrivateData::display() | |||||
| if (window.pData->autoScaling) | if (window.pData->autoScaling) | ||||
| { | { | ||||
| glViewport(0, | glViewport(0, | ||||
| -static_cast<int>(height * autoScaleFactor - height), | |||||
| static_cast<int>(width * autoScaleFactor), | |||||
| static_cast<int>(height * autoScaleFactor)); | |||||
| -static_cast<int>(height * autoScaleFactor - height + 0.5), | |||||
| static_cast<int>(width * autoScaleFactor + 0.5), | |||||
| static_cast<int>(height * autoScaleFactor + 0.5)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -19,7 +19,7 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | ||||
| : Widget(this), | : Widget(this), | ||||
| @@ -93,6 +93,38 @@ void TopLevelWidget::setGeometryConstraints(const uint minimumWidth, | |||||
| pData->window.setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale); | pData->window.setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| bool TopLevelWidget::onKeyboard(const KeyboardEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool TopLevelWidget::onSpecial(const SpecialEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool TopLevelWidget::onCharacterInput(const CharacterInputEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool TopLevelWidget::onMouse(const MouseEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool TopLevelWidget::onMotion(const MotionEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool TopLevelWidget::onScroll(const ScrollEvent&) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| @@ -156,12 +156,16 @@ void Window::setSize(uint width, uint height) | |||||
| if (pData->isEmbed) | if (pData->isEmbed) | ||||
| { | { | ||||
| const double scaleFactor = pData->scaleFactor; | |||||
| const uint minWidth = static_cast<uint>(pData->minWidth * scaleFactor + 0.5); | |||||
| const uint minHeight = static_cast<uint>(pData->minHeight * scaleFactor + 0.5); | |||||
| // handle geometry constraints here | // handle geometry constraints here | ||||
| if (width < pData->minWidth) | |||||
| width = pData->minWidth; | |||||
| if (width < minWidth) | |||||
| width = minWidth; | |||||
| if (height < pData->minHeight) | |||||
| height = pData->minHeight; | |||||
| if (height < minHeight) | |||||
| height = minHeight; | |||||
| if (pData->keepAspectRatio) | if (pData->keepAspectRatio) | ||||
| { | { | ||||
| @@ -265,12 +269,21 @@ void Window::repaint() noexcept | |||||
| void Window::repaint(const Rectangle<uint>& rect) noexcept | void Window::repaint(const Rectangle<uint>& rect) noexcept | ||||
| { | { | ||||
| const PuglRect prect = { | |||||
| PuglRect prect = { | |||||
| static_cast<double>(rect.getX()), | static_cast<double>(rect.getX()), | ||||
| static_cast<double>(rect.getY()), | static_cast<double>(rect.getY()), | ||||
| static_cast<double>(rect.getWidth()), | static_cast<double>(rect.getWidth()), | ||||
| static_cast<double>(rect.getHeight()), | static_cast<double>(rect.getHeight()), | ||||
| }; | }; | ||||
| if (pData->autoScaling) | |||||
| { | |||||
| const double autoScaleFactor = pData->autoScaleFactor; | |||||
| prect.x *= autoScaleFactor; | |||||
| prect.y *= autoScaleFactor; | |||||
| prect.width *= autoScaleFactor; | |||||
| prect.height *= autoScaleFactor; | |||||
| } | |||||
| puglPostRedisplayRect(pData->view, prect); | puglPostRedisplayRect(pData->view, prect); | ||||
| } | } | ||||
| @@ -287,12 +300,6 @@ void Window::setGeometryConstraints(const uint minimumWidth, | |||||
| DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,); | DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,); | DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,); | ||||
| if (pData->isEmbed) { | |||||
| // nothing to do here | |||||
| } else if (! isResizable()) { | |||||
| setResizable(true); | |||||
| } | |||||
| pData->minWidth = minimumWidth; | pData->minWidth = minimumWidth; | ||||
| pData->minHeight = minimumHeight; | pData->minHeight = minimumHeight; | ||||
| pData->autoScaling = automaticallyScale; | pData->autoScaling = automaticallyScale; | ||||
| @@ -64,12 +64,13 @@ START_NAMESPACE_DGL | |||||
| static const char* const kWin32SelectedFileCancelled = "__dpf_cancelled__"; | static const char* const kWin32SelectedFileCancelled = "__dpf_cancelled__"; | ||||
| #endif | #endif | ||||
| static double getDesktopScaleFactor() | |||||
| static double getDesktopScaleFactor(const PuglView* const view) | |||||
| { | { | ||||
| // allow custom scale for testing | |||||
| if (const char* const scale = getenv("DPF_SCALE_FACTOR")) | if (const char* const scale = getenv("DPF_SCALE_FACTOR")) | ||||
| return std::max(1.0, std::atof(scale)); | return std::max(1.0, std::atof(scale)); | ||||
| return 1.0; | |||||
| return puglGetDesktopScaleFactor(view); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -84,7 +85,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||||
| isClosed(true), | isClosed(true), | ||||
| isVisible(false), | isVisible(false), | ||||
| isEmbed(false), | isEmbed(false), | ||||
| scaleFactor(getDesktopScaleFactor()), | |||||
| scaleFactor(getDesktopScaleFactor(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| @@ -137,7 +138,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
| isClosed(parentWindowHandle == 0), | isClosed(parentWindowHandle == 0), | ||||
| isVisible(parentWindowHandle != 0), | isVisible(parentWindowHandle != 0), | ||||
| isEmbed(parentWindowHandle != 0), | isEmbed(parentWindowHandle != 0), | ||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor()), | |||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| @@ -167,7 +168,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
| isClosed(parentWindowHandle == 0), | isClosed(parentWindowHandle == 0), | ||||
| isVisible(parentWindowHandle != 0), | isVisible(parentWindowHandle != 0), | ||||
| isEmbed(parentWindowHandle != 0), | isEmbed(parentWindowHandle != 0), | ||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor()), | |||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| @@ -362,7 +363,11 @@ void Window::PrivateData::focus() | |||||
| if (! isEmbed) | if (! isEmbed) | ||||
| puglRaiseWindow(view); | puglRaiseWindow(view); | ||||
| #ifdef HAVE_X11 | |||||
| puglX11GrabFocus(view); | |||||
| #else | |||||
| puglGrabFocus(view); | puglGrabFocus(view); | ||||
| #endif | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -110,6 +110,10 @@ START_NAMESPACE_DGL | |||||
| # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) | # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) | ||||
| # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) | # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) | ||||
| # endif | # endif | ||||
| # ifndef __MAC_10_9 | |||||
| # define NSModalResponseOK NSOKButton | |||||
| typedef NSUInteger NSEventSubtype; | |||||
| # endif | |||||
| # pragma clang diagnostic push | # pragma clang diagnostic push | ||||
| # pragma clang diagnostic ignored "-Wdeprecated-declarations" | # pragma clang diagnostic ignored "-Wdeprecated-declarations" | ||||
| # import "pugl-upstream/src/mac.m" | # import "pugl-upstream/src/mac.m" | ||||
| @@ -193,13 +197,35 @@ const char* puglGetWindowTitle(const PuglView* const view) | |||||
| return view->title; | return view->title; | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // get global scale factor | |||||
| double puglGetDesktopScaleFactor(const PuglView* const view) | |||||
| { | |||||
| #if defined(DISTRHO_OS_MAC) | |||||
| if (NSWindow* const window = view->impl->window ? view->impl->window | |||||
| : [view->impl->wrapperView window]) | |||||
| return [window screen].backingScaleFactor; | |||||
| return [NSScreen mainScreen].backingScaleFactor; | |||||
| #else | |||||
| return 1.0; | |||||
| // unused | |||||
| (void)view; | |||||
| #endif | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // bring view window into the foreground, aka "raise" window | // bring view window into the foreground, aka "raise" window | ||||
| void puglRaiseWindow(PuglView* view) | |||||
| void puglRaiseWindow(PuglView* const view) | |||||
| { | { | ||||
| #if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC) | |||||
| #if defined(DISTRHO_OS_HAIKU) | |||||
| // nothing here yet | // nothing here yet | ||||
| #elif defined(DISTRHO_OS_MAC) | |||||
| if (NSWindow* const window = view->impl->window ? view->impl->window | |||||
| : [view->impl->wrapperView window]) | |||||
| [window orderFrontRegardless]; | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| SetForegroundWindow(view->impl->hwnd); | SetForegroundWindow(view->impl->hwnd); | ||||
| SetActiveWindow(view->impl->hwnd); | SetActiveWindow(view->impl->hwnd); | ||||
| @@ -276,9 +302,30 @@ PuglStatus puglSetWindowSize(PuglView* const view, const uint width, const uint | |||||
| view->defaultHeight = height; | view->defaultHeight = height; | ||||
| #if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC) | #if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC) | ||||
| // keep upstream behaviour | |||||
| // replace the 2 views setFrame with setFrameSize | |||||
| const PuglRect frame = { view->frame.x, view->frame.y, (double)width, (double)height }; | const PuglRect frame = { view->frame.x, view->frame.y, (double)width, (double)height }; | ||||
| return puglSetFrame(view, frame); | |||||
| PuglInternals* const impl = view->impl; | |||||
| // Update view frame to exactly the requested frame in Pugl coordinates | |||||
| view->frame = frame; | |||||
| const NSRect framePx = rectToNsRect(frame); | |||||
| const NSRect framePt = nsRectToPoints(view, framePx); | |||||
| if (impl->window) | |||||
| { | |||||
| // Resize window to fit new content rect | |||||
| const NSRect screenPt = rectToScreen(viewScreen(view), framePt); | |||||
| const NSRect winFrame = [impl->window frameRectForContentRect:screenPt]; | |||||
| [impl->window setFrame:winFrame display:NO]; | |||||
| } | |||||
| // Resize views | |||||
| const NSSize sizePx = NSMakeSize(frame.width, frame.height); | |||||
| const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx]; | |||||
| [impl->wrapperView setFrameSize:(impl->window ? sizePt : framePt.size)]; | |||||
| [impl->drawView setFrameSize:sizePt]; | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| // matches upstream pugl, except we add SWP_NOMOVE flag | // matches upstream pugl, except we add SWP_NOMOVE flag | ||||
| if (view->impl->hwnd) | if (view->impl->hwnd) | ||||
| @@ -391,6 +438,15 @@ bool puglMacOSFilePanelOpen(PuglView* const view, | |||||
| return true; | return true; | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // macOS specific, allow standalone window to gain focus | |||||
| void puglMacOSActivateApp() | |||||
| { | |||||
| [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; | |||||
| [NSApp activateIgnoringOtherApps:YES]; | |||||
| } | |||||
| #endif | #endif | ||||
| #ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||
| @@ -450,6 +506,28 @@ void puglWin32SetWindowResizable(PuglView* const view, const bool resizable) | |||||
| #endif | #endif | ||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // X11 specific, safer way to grab focus | |||||
| PuglStatus puglX11GrabFocus(PuglView* const view) | |||||
| { | |||||
| PuglInternals* const impl = view->impl; | |||||
| XWindowAttributes wa; | |||||
| std::memset(&wa, 0, sizeof(wa)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(XGetWindowAttributes(impl->display, impl->win, &wa), PUGL_UNKNOWN_ERROR); | |||||
| if (wa.map_state == IsViewable) | |||||
| { | |||||
| XRaiseWindow(impl->display, impl->win); | |||||
| XSetInputFocus(impl->display, impl->win, RevertToPointerRoot, CurrentTime); | |||||
| XSync(impl->display, False); | |||||
| } | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // X11 specific, setup event loop filter for sofd file dialog | // X11 specific, setup event loop filter for sofd file dialog | ||||
| @@ -20,9 +20,14 @@ | |||||
| #include "../Base.hpp" | #include "../Base.hpp" | ||||
| /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ | /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ | ||||
| #include <cstdbool> | |||||
| #include <cstddef> | #include <cstddef> | ||||
| #include <cstdint> | |||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| # include <cstdbool> | |||||
| # include <cstdint> | |||||
| #else | |||||
| # include <stdbool.h> | |||||
| # include <stdint.h> | |||||
| #endif | |||||
| #define PUGL_API | #define PUGL_API | ||||
| #define PUGL_DISABLE_DEPRECATED | #define PUGL_DISABLE_DEPRECATED | ||||
| @@ -62,6 +67,10 @@ puglGetTransientParent(const PuglView* view); | |||||
| PUGL_API const char* | PUGL_API const char* | ||||
| puglGetWindowTitle(const PuglView* view); | puglGetWindowTitle(const PuglView* view); | ||||
| // get global scale factor | |||||
| PUGL_API double | |||||
| puglGetDesktopScaleFactor(const PuglView* view); | |||||
| // bring view window into the foreground, aka "raise" window | // bring view window into the foreground, aka "raise" window | ||||
| PUGL_API void | PUGL_API void | ||||
| puglRaiseWindow(PuglView* view); | puglRaiseWindow(PuglView* view); | ||||
| @@ -90,6 +99,10 @@ puglFallbackOnResize(PuglView* view); | |||||
| // macOS specific, setup file browser dialog | // macOS specific, setup file browser dialog | ||||
| typedef void (*openPanelCallback)(PuglView* view, const char* path); | typedef void (*openPanelCallback)(PuglView* view, const char* path); | ||||
| bool puglMacOSFilePanelOpen(PuglView* view, const char* startDir, const char* title, uint flags, openPanelCallback callback); | bool puglMacOSFilePanelOpen(PuglView* view, const char* startDir, const char* title, uint flags, openPanelCallback callback); | ||||
| // macOS specific, allow standalone window to gain focus | |||||
| PUGL_API void | |||||
| puglMacOSActivateApp(); | |||||
| #endif | #endif | ||||
| #ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||
| @@ -107,6 +120,10 @@ puglWin32SetWindowResizable(PuglView* view, bool resizable); | |||||
| #endif | #endif | ||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| // X11 specific, safer way to grab focus | |||||
| PUGL_API PuglStatus | |||||
| puglX11GrabFocus(PuglView* view); | |||||
| // X11 specific, setup event loop filter for sofd file dialog | // X11 specific, setup event loop filter for sofd file dialog | ||||
| PUGL_API void | PUGL_API void | ||||
| sofdFileDialogSetup(PuglWorld* world); | sofdFileDialogSetup(PuglWorld* world); | ||||
| @@ -74,8 +74,13 @@ public: | |||||
| /** | /** | ||||
| UI class constructor. | UI class constructor. | ||||
| The UI should be initialized to a default state that matches the plugin side. | The UI should be initialized to a default state that matches the plugin side. | ||||
| When @a automaticallyScale is set to true, DPF will automatically scale up the UI | |||||
| to fit the host/desktop scale factor.@n | |||||
| It assumes aspect ratio is meant to be kept. | |||||
| Manually call setGeometryConstraints instead if keeping UI aspect ratio is not required. | |||||
| */ | */ | ||||
| UI(uint width = 0, uint height = 0); | |||||
| UI(uint width = 0, uint height = 0, bool automaticallyScale = false); | |||||
| /** | /** | ||||
| Destructor. | Destructor. | ||||
| @@ -38,7 +38,7 @@ | |||||
| typedef SSIZE_T ssize_t; | typedef SSIZE_T ssize_t; | ||||
| #endif | #endif | ||||
| #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| #if ! defined(CARLA_MATH_UTILS_HPP_INCLUDED) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| namespace std { | namespace std { | ||||
| inline float fmin(float __x, float __y) | inline float fmin(float __x, float __y) | ||||
| { return __builtin_fminf(__x, __y); } | { return __builtin_fminf(__x, __y); } | ||||
| @@ -31,6 +31,8 @@ typedef HMODULE lib_t; | |||||
| typedef void* lib_t; | typedef void* lib_t; | ||||
| #endif | #endif | ||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // library related calls | // library related calls | ||||
| @@ -129,4 +131,6 @@ const char* lib_error(const char* const filename) noexcept | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| END_NAMESPACE_DISTRHO | |||||
| #endif // DISTRHO_LIBRARY_UTILS_HPP_INCLUDED | #endif // DISTRHO_LIBRARY_UTILS_HPP_INCLUDED | ||||
| @@ -59,12 +59,12 @@ public: | |||||
| /* | /* | ||||
| * Simple char string. | * Simple char string. | ||||
| */ | */ | ||||
| explicit String(char* const strBuf, const bool copyData = true) noexcept | |||||
| explicit String(char* const strBuf, const bool reallocData = true) noexcept | |||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0), | fBufferLen(0), | ||||
| fBufferAlloc(false) | fBufferAlloc(false) | ||||
| { | { | ||||
| if (copyData || strBuf == nullptr) | |||||
| if (reallocData || strBuf == nullptr) | |||||
| { | { | ||||
| _dup(strBuf); | _dup(strBuf); | ||||
| } | } | ||||
| @@ -930,7 +930,7 @@ String operator+(const String& strBefore, const char* const strBufAfter) noexcep | |||||
| std::memcpy(newBuf, strBefore.buffer(), strBeforeLen); | std::memcpy(newBuf, strBefore.buffer(), strBeforeLen); | ||||
| std::memcpy(newBuf + strBeforeLen, strBufAfter, strBufAfterLen + 1); | std::memcpy(newBuf + strBeforeLen, strBufAfter, strBufAfterLen + 1); | ||||
| return String(newBuf); | |||||
| return String(newBuf, false); | |||||
| } | } | ||||
| static inline | static inline | ||||
| @@ -950,7 +950,7 @@ String operator+(const char* const strBufBefore, const String& strAfter) noexcep | |||||
| std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | ||||
| std::memcpy(newBuf + strBufBeforeLen, strAfter.buffer(), strAfterLen + 1); | std::memcpy(newBuf + strBufBeforeLen, strAfter.buffer(), strAfterLen + 1); | ||||
| return String(newBuf); | |||||
| return String(newBuf, false); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -58,12 +58,13 @@ | |||||
| #elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) || (defined(_MSC_VER) && _MSVC_LANG >= 201103L) | #elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) || (defined(_MSC_VER) && _MSVC_LANG >= 201103L) | ||||
| # define DISTRHO_PROPER_CPP11_SUPPORT | # define DISTRHO_PROPER_CPP11_SUPPORT | ||||
| # if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 && ! defined(__clang__)) || (defined(__clang__) && ! __has_extension(cxx_override_control)) | # if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 && ! defined(__clang__)) || (defined(__clang__) && ! __has_extension(cxx_override_control)) | ||||
| # define override // gcc4.7+ only | |||||
| # define final // gcc4.7+ only | |||||
| # define override /* gcc4.7+ only */ | |||||
| # define final /* gcc4.7+ only */ | |||||
| # endif | # endif | ||||
| #endif | #endif | ||||
| #ifndef DISTRHO_PROPER_CPP11_SUPPORT | #ifndef DISTRHO_PROPER_CPP11_SUPPORT | ||||
| # define constexpr | |||||
| # define noexcept throw() | # define noexcept throw() | ||||
| # define override | # define override | ||||
| # define final | # define final | ||||
| @@ -71,7 +72,7 @@ | |||||
| #endif | #endif | ||||
| /* Define DISTRHO_DEPRECATED */ | /* Define DISTRHO_DEPRECATED */ | ||||
| #if defined(__GNUC__) | |||||
| #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 480 | |||||
| # define DISTRHO_DEPRECATED __attribute__((deprecated)) | # define DISTRHO_DEPRECATED __attribute__((deprecated)) | ||||
| #elif defined(_MSC_VER) | #elif defined(_MSC_VER) | ||||
| # define DISTRHO_DEPRECATED [[deprecated]] /* Note: __declspec(deprecated) it not applicable to enum members */ | # define DISTRHO_DEPRECATED [[deprecated]] /* Note: __declspec(deprecated) it not applicable to enum members */ | ||||
| @@ -80,9 +81,9 @@ | |||||
| #endif | #endif | ||||
| /* Define DISTRHO_DEPRECATED_BY */ | /* Define DISTRHO_DEPRECATED_BY */ | ||||
| #if defined(__clang__) | |||||
| #if defined(__clang__) && defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| # define DISTRHO_DEPRECATED_BY(other) __attribute__((deprecated("", other))) | # define DISTRHO_DEPRECATED_BY(other) __attribute__((deprecated("", other))) | ||||
| #elif defined(__GNUC__) | |||||
| #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 480 | |||||
| # define DISTRHO_DEPRECATED_BY(other) __attribute__((deprecated("Use " other))) | # define DISTRHO_DEPRECATED_BY(other) __attribute__((deprecated("Use " other))) | ||||
| #else | #else | ||||
| # define DISTRHO_DEPRECATED_BY(other) DISTRHO_DEPRECATED | # define DISTRHO_DEPRECATED_BY(other) DISTRHO_DEPRECATED | ||||
| @@ -51,7 +51,7 @@ | |||||
| # define DISTRHO_PLUGIN_LV2_STATE_PREFIX "urn:distrho:" | # define DISTRHO_PLUGIN_LV2_STATE_PREFIX "urn:distrho:" | ||||
| #endif | #endif | ||||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | |||||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) || DISTRHO_PLUGIN_WANT_STATEFILES) | |||||
| #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | ||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -74,7 +74,7 @@ | |||||
| # define DISTRHO_LV2_UI_TYPE "UI" | # define DISTRHO_LV2_UI_TYPE "UI" | ||||
| #endif | #endif | ||||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | |||||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) || DISTRHO_PLUGIN_WANT_STATEFILES) | |||||
| #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | ||||
| #define DISTRHO_BYPASS_PARAMETER_NAME "lv2_enabled" | #define DISTRHO_BYPASS_PARAMETER_NAME "lv2_enabled" | ||||
| @@ -22,6 +22,11 @@ | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| # include "DistrhoUIInternal.hpp" | # include "DistrhoUIInternal.hpp" | ||||
| # include "../extra/RingBuffer.hpp" | # include "../extra/RingBuffer.hpp" | ||||
| @@ -127,7 +132,7 @@ struct ParameterAndNotesHelper | |||||
| # endif | # endif | ||||
| #endif | #endif | ||||
| { | { | ||||
| #ifndef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| std::memset(¬esRingBuffer, 0, sizeof(notesRingBuffer)); | std::memset(¬esRingBuffer, 0, sizeof(notesRingBuffer)); | ||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -184,7 +189,8 @@ public: | |||||
| nullptr, // TODO file request | nullptr, // TODO file request | ||||
| nullptr, | nullptr, | ||||
| plugin->getInstancePointer(), | plugin->getInstancePointer(), | ||||
| scaleFactor) | |||||
| scaleFactor), | |||||
| fHasScaleFactor(d_isNotZero(scaleFactor)) | |||||
| # if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | # if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| , fKeyboardModifiers(0) | , fKeyboardModifiers(0) | ||||
| # endif | # endif | ||||
| @@ -223,11 +229,21 @@ public: | |||||
| return fUI.getHeight(); | return fUI.getHeight(); | ||||
| } | } | ||||
| double getScaleFactor() const | |||||
| { | |||||
| return fUI.getScaleFactor(); | |||||
| } | |||||
| void setSampleRate(const double newSampleRate) | void setSampleRate(const double newSampleRate) | ||||
| { | { | ||||
| fUI.setSampleRate(newSampleRate, true); | fUI.setSampleRate(newSampleRate, true); | ||||
| } | } | ||||
| void notifyScaleFactorChanged(const double scaleFactor) | |||||
| { | |||||
| fUI.notifyScaleFactorChanged(scaleFactor); | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // functions called from the plugin side, may block | // functions called from the plugin side, may block | ||||
| @@ -382,9 +398,15 @@ protected: | |||||
| hostCallback(audioMasterAutomate, index, 0, nullptr, perValue); | hostCallback(audioMasterAutomate, index, 0, nullptr, perValue); | ||||
| } | } | ||||
| void setSize(const uint width, const uint height) | |||||
| void setSize(uint width, uint height) | |||||
| { | { | ||||
| // fUI.setWindowSize(width, height); | |||||
| // figure out scale factor ourselves if the host doesn't support it | |||||
| if (! fHasScaleFactor) | |||||
| { | |||||
| const double scaleFactor = fUI.getScaleFactor(); | |||||
| width /= scaleFactor; | |||||
| height /= scaleFactor; | |||||
| } | |||||
| hostCallback(audioMasterSizeWindow, width, height); | hostCallback(audioMasterSizeWindow, width, height); | ||||
| } | } | ||||
| @@ -416,6 +438,7 @@ private: | |||||
| // Plugin UI | // Plugin UI | ||||
| UIExporter fUI; | UIExporter fUI; | ||||
| const bool fHasScaleFactor; | |||||
| # if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | # if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| uint16_t fKeyboardModifiers; | uint16_t fKeyboardModifiers; | ||||
| # endif | # endif | ||||
| @@ -494,7 +517,7 @@ public: | |||||
| fVstRect.left = 0; | fVstRect.left = 0; | ||||
| fVstRect.bottom = 0; | fVstRect.bottom = 0; | ||||
| fVstRect.right = 0; | fVstRect.right = 0; | ||||
| fLastScaleFactor = 1.0f; | |||||
| fLastScaleFactor = 0.0f; | |||||
| if (parameterCount != 0) | if (parameterCount != 0) | ||||
| { | { | ||||
| @@ -665,6 +688,13 @@ public: | |||||
| { | { | ||||
| fVstRect.right = fVstUI->getWidth(); | fVstRect.right = fVstUI->getWidth(); | ||||
| fVstRect.bottom = fVstUI->getHeight(); | fVstRect.bottom = fVstUI->getHeight(); | ||||
| // figure out scale factor ourselves if the host doesn't support it | |||||
| if (fLastScaleFactor == 0.0f) | |||||
| { | |||||
| const double scaleFactor = fVstUI->getScaleFactor(); | |||||
| fVstRect.right /= scaleFactor; | |||||
| fVstRect.bottom /= scaleFactor; | |||||
| } | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -673,6 +703,13 @@ public: | |||||
| fPlugin.getInstancePointer(), fLastScaleFactor); | fPlugin.getInstancePointer(), fLastScaleFactor); | ||||
| fVstRect.right = tmpUI.getWidth(); | fVstRect.right = tmpUI.getWidth(); | ||||
| fVstRect.bottom = tmpUI.getHeight(); | fVstRect.bottom = tmpUI.getHeight(); | ||||
| // figure out scale factor ourselves if the host doesn't support it | |||||
| if (fLastScaleFactor == 0.0f) | |||||
| { | |||||
| const double scaleFactor = tmpUI.getScaleFactor(); | |||||
| fVstRect.right /= scaleFactor; | |||||
| fVstRect.bottom /= scaleFactor; | |||||
| } | |||||
| tmpUI.quit(); | tmpUI.quit(); | ||||
| } | } | ||||
| *(ERect**)ptr = &fVstRect; | *(ERect**)ptr = &fVstRect; | ||||
| @@ -993,7 +1030,15 @@ public: | |||||
| case effVendorSpecific: | case effVendorSpecific: | ||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| if (index == CCONST('P', 'r', 'e', 'S') && value == CCONST('A', 'e', 'C', 's')) | if (index == CCONST('P', 'r', 'e', 'S') && value == CCONST('A', 'e', 'C', 's')) | ||||
| { | |||||
| if (d_isEqual(fLastScaleFactor, opt)) | |||||
| break; | |||||
| fLastScaleFactor = opt; | fLastScaleFactor = opt; | ||||
| if (fVstUI != nullptr) | |||||
| fVstUI->notifyScaleFactorChanged(opt); | |||||
| } | |||||
| #endif | #endif | ||||
| break; | break; | ||||
| @@ -46,13 +46,18 @@ PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, const uint width, | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI */ | * UI */ | ||||
| UI::UI(const uint width, const uint height) | |||||
| UI::UI(const uint width, const uint height, const bool automaticallyScale) | |||||
| : UIWidget(UI::PrivateData::createNextWindow(this, width, height)), | : UIWidget(UI::PrivateData::createNextWindow(this, width, height)), | ||||
| uiData(UI::PrivateData::s_nextPrivateData) | uiData(UI::PrivateData::s_nextPrivateData) | ||||
| { | { | ||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| if (width > 0 && height > 0) | if (width > 0 && height > 0) | ||||
| { | |||||
| Widget::setSize(width, height); | Widget::setSize(width, height); | ||||
| if (automaticallyScale) | |||||
| setGeometryConstraints(width, height, true, true); | |||||
| } | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -59,7 +59,7 @@ public: | |||||
| const fileRequestFunc fileRequestCall, | const fileRequestFunc fileRequestCall, | ||||
| const char* const bundlePath = nullptr, | const char* const bundlePath = nullptr, | ||||
| void* const dspPtr = nullptr, | void* const dspPtr = nullptr, | ||||
| const double scaleFactor = 1.0, | |||||
| const double scaleFactor = 0.0, | |||||
| const uint32_t bgColor = 0, | const uint32_t bgColor = 0, | ||||
| const uint32_t fgColor = 0xffffffff) | const uint32_t fgColor = 0xffffffff) | ||||
| : ui(nullptr), | : ui(nullptr), | ||||
| @@ -128,6 +128,11 @@ public: | |||||
| return uiData->window->getHeight(); | return uiData->window->getHeight(); | ||||
| } | } | ||||
| double getScaleFactor() const noexcept | |||||
| { | |||||
| return uiData->window->getScaleFactor(); | |||||
| } | |||||
| bool isVisible() const noexcept | bool isVisible() const noexcept | ||||
| { | { | ||||
| return uiData->window->isVisible(); | return uiData->window->isVisible(); | ||||
| @@ -321,7 +326,7 @@ public: | |||||
| bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) | bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) | ||||
| { | { | ||||
| // TODO also trigger Character input event | // TODO also trigger Character input event | ||||
| Widget::KeyboardEvent ev; | |||||
| DGL_NAMESPACE::Widget::KeyboardEvent ev; | |||||
| ev.press = press; | ev.press = press; | ||||
| ev.key = key; | ev.key = key; | ||||
| ev.mod = mods; | ev.mod = mods; | ||||
| @@ -330,7 +335,7 @@ public: | |||||
| bool handlePluginSpecial(const bool press, const DGL_NAMESPACE::Key key, const uint16_t mods) | bool handlePluginSpecial(const bool press, const DGL_NAMESPACE::Key key, const uint16_t mods) | ||||
| { | { | ||||
| Widget::SpecialEvent ev; | |||||
| DGL_NAMESPACE::Widget::SpecialEvent ev; | |||||
| ev.press = press; | ev.press = press; | ||||
| ev.key = key; | ev.key = key; | ||||
| ev.mod = mods; | ev.mod = mods; | ||||
| @@ -340,6 +345,13 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void notifyScaleFactorChanged(const double scaleFactor) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||||
| ui->uiScaleFactorChanged(scaleFactor); | |||||
| } | |||||
| void setSampleRate(const double sampleRate, const bool doCallback = false) | void setSampleRate(const double sampleRate, const bool doCallback = false) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | ||||
| @@ -70,10 +70,10 @@ public: | |||||
| // TODO external ui stuff | // TODO external ui stuff | ||||
| class PluginWindow | class PluginWindow | ||||
| { | { | ||||
| UI* const ui; | |||||
| DISTRHO_NAMESPACE::UI* const ui; | |||||
| public: | public: | ||||
| explicit PluginWindow(UI* const uiPtr, | |||||
| explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||||
| PluginApplication& app, | PluginApplication& app, | ||||
| const uintptr_t parentWindowHandle, | const uintptr_t parentWindowHandle, | ||||
| const uint width, | const uint width, | ||||
| @@ -107,10 +107,10 @@ public: | |||||
| #else | #else | ||||
| class PluginWindow : public Window | class PluginWindow : public Window | ||||
| { | { | ||||
| UI* const ui; | |||||
| DISTRHO_NAMESPACE::UI* const ui; | |||||
| public: | public: | ||||
| explicit PluginWindow(UI* const uiPtr, | |||||
| explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||||
| PluginApplication& app, | PluginApplication& app, | ||||
| const uintptr_t parentWindowHandle, | const uintptr_t parentWindowHandle, | ||||
| const uint width, | const uint width, | ||||
| @@ -312,7 +312,7 @@ inline bool UI::PrivateData::fileRequestCallback(const char* const key) | |||||
| snprintf(title, sizeof(title)-1u, DISTRHO_PLUGIN_NAME ": %s", key); | snprintf(title, sizeof(title)-1u, DISTRHO_PLUGIN_NAME ": %s", key); | ||||
| title[sizeof(title)-1u] = '\0'; | title[sizeof(title)-1u] = '\0'; | ||||
| Window::FileBrowserOptions opts; | |||||
| DGL_NAMESPACE::Window::FileBrowserOptions opts; | |||||
| opts.title = title; | opts.title = title; | ||||
| return window->openFileBrowser(opts); | return window->openFileBrowser(opts); | ||||
| #endif | #endif | ||||
| @@ -36,9 +36,11 @@ | |||||
| #include "../../extra/LibraryUtils.hpp" | #include "../../extra/LibraryUtils.hpp" | ||||
| // in case JACK fails, we fallback to RtAudio's native API | // in case JACK fails, we fallback to RtAudio's native API | ||||
| #include "RtAudioBridge.hpp" | |||||
| #ifdef RTAUDIO_API_TYPE | |||||
| # include "rtaudio/RtAudio.cpp" | |||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| # include "RtAudioBridge.hpp" | |||||
| # ifdef RTAUDIO_API_TYPE | |||||
| # include "rtaudio/RtAudio.cpp" | |||||
| # endif | |||||
| #endif | #endif | ||||
| // ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||||
| @@ -422,6 +424,7 @@ struct JackBridge { | |||||
| # else | # else | ||||
| const char* const filename("libjack.so.0"); | const char* const filename("libjack.so.0"); | ||||
| # endif | # endif | ||||
| USE_NAMESPACE_DISTRHO | |||||
| lib = lib_open(filename); | lib = lib_open(filename); | ||||
| @@ -561,6 +564,8 @@ struct JackBridge { | |||||
| ~JackBridge() noexcept | ~JackBridge() noexcept | ||||
| { | { | ||||
| USE_NAMESPACE_DISTRHO | |||||
| if (lib != nullptr) | if (lib != nullptr) | ||||
| { | { | ||||
| lib_close(lib); | lib_close(lib); | ||||
| @@ -37,8 +37,12 @@ | |||||
| # define Point CorePoint /* fix conflict between DGL and macOS Point name */ | # define Point CorePoint /* fix conflict between DGL and macOS Point name */ | ||||
| # include "rtaudio/RtAudio.h" | # include "rtaudio/RtAudio.h" | ||||
| # undef Point | # undef Point | ||||
| # include "../../extra/RingBuffer.hpp" | |||||
| # include "../../extra/ScopedPointer.hpp" | # include "../../extra/ScopedPointer.hpp" | ||||
| using DISTRHO_NAMESPACE::HeapRingBuffer; | |||||
| using DISTRHO_NAMESPACE::ScopedPointer; | |||||
| struct RtAudioBridge { | struct RtAudioBridge { | ||||
| // pointer to RtAudio instance | // pointer to RtAudio instance | ||||
| ScopedPointer<RtAudio> handle; | ScopedPointer<RtAudio> handle; | ||||
| @@ -58,9 +62,23 @@ struct RtAudioBridge { | |||||
| void* jackProcessArg = nullptr; | void* jackProcessArg = nullptr; | ||||
| // Runtime buffers | // Runtime buffers | ||||
| enum PortMask { | |||||
| kPortMaskAudio = 0x1000, | |||||
| kPortMaskMIDI = 0x2000, | |||||
| kPortMaskInput = 0x4000, | |||||
| kPortMaskOutput = 0x8000, | |||||
| kPortMaskInputMIDI = kPortMaskInput|kPortMaskMIDI, | |||||
| kPortMaskOutputMIDI = kPortMaskOutput|kPortMaskMIDI, | |||||
| }; | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | |||||
| float* audioBuffers[DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS]; | float* audioBuffers[DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS]; | ||||
| // TODO midi buffer, likely using ringbuffer class | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| HeapRingBuffer midiInBuffer; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |||||
| HeapRingBuffer midiOutBuffer; | |||||
| #endif | |||||
| bool open() | bool open() | ||||
| { | { | ||||
| @@ -90,6 +108,13 @@ struct RtAudioBridge { | |||||
| handle = rtAudio; | handle = rtAudio; | ||||
| bufferSize = rtAudioBufferFrames; | bufferSize = rtAudioBufferFrames; | ||||
| sampleRate = handle->getStreamSampleRate(); | sampleRate = handle->getStreamSampleRate(); | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| midiInBuffer.createBuffer(128); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |||||
| midiOutBuffer.createBuffer(128); | |||||
| #endif | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -148,7 +173,8 @@ struct RtAudioBridge { | |||||
| else | else | ||||
| return nullptr; | return nullptr; | ||||
| const uintptr_t ret = (isAudio ? 0x1000 : 0x2000) | (isInput ? 0x4000 : 0x8000); | |||||
| const uintptr_t ret = (isAudio ? kPortMaskAudio : kPortMaskMIDI) | |||||
| | (isInput ? kPortMaskInput : kPortMaskOutput); | |||||
| return (jack_port_t*)(ret + (isAudio ? (isInput ? numAudioIns++ : numAudioOuts++) | return (jack_port_t*)(ret + (isAudio ? (isInput ? numAudioIns++ : numAudioOuts++) | ||||
| : (isInput ? numMidiIns++ : numMidiOuts++))); | : (isInput ? numMidiIns++ : numMidiOuts++))); | ||||
| @@ -157,10 +183,19 @@ struct RtAudioBridge { | |||||
| void* getPortBuffer(jack_port_t* const port) | void* getPortBuffer(jack_port_t* const port) | ||||
| { | { | ||||
| const uintptr_t portMask = (uintptr_t)port; | const uintptr_t portMask = (uintptr_t)port; | ||||
| DISTRHO_SAFE_ASSERT_RETURN(portMask != 0x0, nullptr); | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | ||||
| if (portMask & 0x1000) | |||||
| return audioBuffers[(portMask & 0x4000 ? 0 : DISTRHO_PLUGIN_NUM_INPUTS) + (portMask & 0x0fff)]; | |||||
| if (portMask & kPortMaskAudio) | |||||
| return audioBuffers[(portMask & kPortMaskInput ? 0 : DISTRHO_PLUGIN_NUM_INPUTS) + (portMask & 0x0fff)]; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| if ((portMask & kPortMaskInputMIDI) == kPortMaskInputMIDI) | |||||
| return &midiInBuffer; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |||||
| if ((portMask & kPortMaskOutputMIDI) == kPortMaskOutputMIDI) | |||||
| return &midiOutBuffer; | |||||
| #endif | #endif | ||||
| return nullptr; | return nullptr; | ||||
| @@ -24,7 +24,7 @@ namespace Art = DistrhoArtwork3BandEQ; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUI3BandEQ::DistrhoUI3BandEQ() | DistrhoUI3BandEQ::DistrhoUI3BandEQ() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | ||||
| fAboutWindow(this) | fAboutWindow(this) | ||||
| { | { | ||||
| @@ -24,7 +24,7 @@ namespace Art = DistrhoArtwork3BandSplitter; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUI3BandSplitter::DistrhoUI3BandSplitter() | DistrhoUI3BandSplitter::DistrhoUI3BandSplitter() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | ||||
| fAboutWindow(this) | fAboutWindow(this) | ||||
| { | { | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO AmplitudeImposer, a DPF'ied AmplitudeImposer. | * DISTRHO AmplitudeImposer, a DPF'ied AmplitudeImposer. | ||||
| * Copyright (C) 2004 Niall Moody | * Copyright (C) 2004 Niall Moody | ||||
| * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission is hereby granted, free of charge, to any person obtaining a | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
| * copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
| @@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkAmplitudeImposer; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUIAmplitudeImposer::DistrhoUIAmplitudeImposer() | DistrhoUIAmplitudeImposer::DistrhoUIAmplitudeImposer() | ||||
| : UI(Art::backWidth, Art::backHeight), | |||||
| : UI(Art::backWidth, Art::backHeight, true), | |||||
| fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | ||||
| { | { | ||||
| // sliders | // sliders | ||||
| @@ -1,5 +1,5 @@ | |||||
| Copyright (C) 2004-2006 Niall Moody | Copyright (C) 2004-2006 Niall Moody | ||||
| Copyright (C) 2015 Filipe Coelho | |||||
| Copyright (C) 2015-2021 Filipe Coelho | |||||
| Permission is hereby granted, free of charge, to any person obtaining a | Permission is hereby granted, free of charge, to any person obtaining a | ||||
| copy of this software and associated documentation files (the "Software"), | copy of this software and associated documentation files (the "Software"), | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO CycleShifter, a DPF'ied CycleShifter. | * DISTRHO CycleShifter, a DPF'ied CycleShifter. | ||||
| * Copyright (C) 2004 Niall Moody | * Copyright (C) 2004 Niall Moody | ||||
| * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission is hereby granted, free of charge, to any person obtaining a | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
| * copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
| @@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkCycleShifter; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUICycleShifter::DistrhoUICycleShifter() | DistrhoUICycleShifter::DistrhoUICycleShifter() | ||||
| : UI(Art::backWidth, Art::backHeight), | |||||
| : UI(Art::backWidth, Art::backHeight, true), | |||||
| fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | ||||
| { | { | ||||
| // sliders | // sliders | ||||
| @@ -1,5 +1,5 @@ | |||||
| Copyright (C) 2004-2006 Niall Moody | Copyright (C) 2004-2006 Niall Moody | ||||
| Copyright (C) 2015 Filipe Coelho | |||||
| Copyright (C) 2015-2021 Filipe Coelho | |||||
| Permission is hereby granted, free of charge, to any person obtaining a | Permission is hereby granted, free of charge, to any person obtaining a | ||||
| copy of this software and associated documentation files (the "Software"), | copy of this software and associated documentation files (the "Software"), | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO MVerb, a DPF'ied MVerb. | * DISTRHO MVerb, a DPF'ied MVerb. | ||||
| * Copyright (c) 2010 Martin Eastwood | * Copyright (c) 2010 Martin Eastwood | ||||
| * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -28,7 +28,7 @@ using DGL::Color; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUIMVerb::DistrhoUIMVerb() | DistrhoUIMVerb::DistrhoUIMVerb() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR) | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR) | ||||
| { | { | ||||
| // text | // text | ||||
| @@ -122,9 +122,6 @@ DistrhoUIMVerb::DistrhoUIMVerb() | |||||
| // set initial values | // set initial values | ||||
| programLoaded(0); | programLoaded(0); | ||||
| // TODO auto-scale but non-resizable | |||||
| // setGeometryConstraints(Art::backgroundWidth, Art::backgroundHeight, true, true); | |||||
| } | } | ||||
| DistrhoUIMVerb::~DistrhoUIMVerb() | DistrhoUIMVerb::~DistrhoUIMVerb() | ||||
| @@ -25,7 +25,7 @@ namespace Art = DistrhoArtworkNekobi; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUINekobi::DistrhoUINekobi() | DistrhoUINekobi::DistrhoUINekobi() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | ||||
| fAboutWindow(this) | fAboutWindow(this) | ||||
| { | { | ||||
| @@ -24,7 +24,7 @@ namespace Art = DistrhoArtworkPingPongPan; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUIPingPongPan::DistrhoUIPingPongPan() | DistrhoUIPingPongPan::DistrhoUIPingPongPan() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | ||||
| fAboutWindow(this) | fAboutWindow(this) | ||||
| { | { | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO SoulForce, a DPF'ied SoulForce. | * DISTRHO SoulForce, a DPF'ied SoulForce. | ||||
| * Copyright (C) 2006 Niall Moody | * Copyright (C) 2006 Niall Moody | ||||
| * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission is hereby granted, free of charge, to any person obtaining a | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
| * copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
| @@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkSoulForce; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| DistrhoUISoulForce::DistrhoUISoulForce() | DistrhoUISoulForce::DistrhoUISoulForce() | ||||
| : UI(Art::backgroundWidth, Art::backgroundHeight), | |||||
| : UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||||
| fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | ||||
| fImgLedOff(Art::led_offData, Art::led_offWidth, Art::led_offHeight, kImageFormatBGR), | fImgLedOff(Art::led_offData, Art::led_offWidth, Art::led_offHeight, kImageFormatBGR), | ||||
| fImgLedOn(Art::led_onData, Art::led_onWidth, Art::led_onHeight, kImageFormatBGR), | fImgLedOn(Art::led_onData, Art::led_onWidth, Art::led_onHeight, kImageFormatBGR), | ||||
| @@ -1,5 +1,5 @@ | |||||
| Copyright (C) 2004-2006 Niall Moody | Copyright (C) 2004-2006 Niall Moody | ||||
| Copyright (C) 2015 Filipe Coelho | |||||
| Copyright (C) 2015-2021 Filipe Coelho | |||||
| Permission is hereby granted, free of charge, to any person obtaining a | Permission is hereby granted, free of charge, to any person obtaining a | ||||
| copy of this software and associated documentation files (the "Software"), | copy of this software and associated documentation files (the "Software"), | ||||