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"), | ||||