Signed-off-by: falkTX <falktx@falktx.com>tags/v1.5
@@ -138,7 +138,6 @@ endif # HAVE_CAIRO_OR_OPENGL | |||
endif # MACOS | |||
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/3BandEQ$(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/ | |||
endif # HAVE_PROJM | |||
endif # HAVE_OPENGL | |||
endif # HAVE_JACK | |||
# -------------------------------------------------------------- | |||
@@ -26,11 +26,10 @@ endif | |||
ifneq (,$(findstring haiku,$(TARGET_MACHINE))) | |||
HAIKU=true | |||
endif | |||
ifneq (,$(findstring gnu,$(TARGET_MACHINE))) | |||
HURD=true | |||
endif | |||
ifneq (,$(findstring linux,$(TARGET_MACHINE))) | |||
LINUX=true | |||
else ifneq (,$(findstring gnu,$(TARGET_MACHINE))) | |||
HURD=true | |||
endif | |||
ifneq (,$(findstring apple,$(TARGET_MACHINE))) | |||
MACOS=true | |||
@@ -184,7 +183,7 @@ CXXFLAGS += -fvisibility-inlines-hidden | |||
endif | |||
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) | |||
ifneq ($(MACOS),true) | |||
@@ -438,3 +437,47 @@ SILENT = @ | |||
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 | |||
endif | |||
ifeq ($(MACOS),true) | |||
ifneq ($(MACOS_OLD),true) | |||
VST3_FILENAME = MacOS/$(NAME) | |||
endif | |||
endif | |||
ifeq ($(WINDOWS),true) | |||
VST3_FILENAME = $(TARGET_PROCESSOR)-win/$(NAME).vst3 | |||
endif | |||
@@ -140,7 +142,7 @@ endif | |||
ifeq ($(UI_TYPE),cairo) | |||
ifeq ($(HAVE_CAIRO),true) | |||
DGL_FLAGS += -DDGL_CAIRO | |||
DGL_FLAGS += -DDGL_CAIRO -DHAVE_DGL | |||
DGL_FLAGS += $(CAIRO_FLAGS) | |||
DGL_LIBS += $(CAIRO_LIBS) | |||
DGL_LIB = $(DPF_PATH)/build/libdgl-cairo.a | |||
@@ -152,7 +154,7 @@ endif | |||
ifeq ($(UI_TYPE),opengl) | |||
ifeq ($(HAVE_OPENGL),true) | |||
DGL_FLAGS += -DDGL_OPENGL | |||
DGL_FLAGS += -DDGL_OPENGL -DHAVE_DGL | |||
DGL_FLAGS += $(OPENGL_FLAGS) | |||
DGL_LIBS += $(OPENGL_LIBS) | |||
DGL_LIB = $(DPF_PATH)/build/libdgl-opengl.a | |||
@@ -164,7 +166,7 @@ endif | |||
ifeq ($(UI_TYPE),vulkan) | |||
ifeq ($(HAVE_VULKAN),true) | |||
DGL_FLAGS += -DDGL_VULKAN | |||
DGL_FLAGS += -DDGL_VULKAN -DHAVE_DGL | |||
DGL_FLAGS += $(VULKAN_FLAGS) | |||
DGL_LIBS += $(VULKAN_LIBS) | |||
DGL_LIB = $(DPF_PATH)/build/libdgl-vulkan.a | |||
@@ -328,7 +330,11 @@ lv2: $(lv2) | |||
lv2_dsp: $(lv2_dsp) | |||
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) | |||
else | |||
$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o | |||
endif | |||
-@mkdir -p $(shell dirname $@) | |||
@echo "Creating LV2 plugin for $(NAME)" | |||
$(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") | |||
set_target_properties("${NAME}-ladspa" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/ladspa/$<0:>" | |||
OUTPUT_NAME "${NAME}-ladspa" | |||
PREFIX "") | |||
endfunction() | |||
@@ -236,6 +237,7 @@ function(dpf__build_dssi NAME DGL_LIBRARY) | |||
target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp") | |||
set_target_properties("${NAME}-dssi" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/dssi/$<0:>" | |||
OUTPUT_NAME "${NAME}-dssi" | |||
PREFIX "") | |||
@@ -265,6 +267,7 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||
target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp") | |||
set_target_properties("${NAME}-lv2" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" | |||
OUTPUT_NAME "${NAME}_dsp" | |||
PREFIX "") | |||
@@ -280,6 +283,7 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||
target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui") | |||
set_target_properties("${NAME}-lv2-ui" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" | |||
OUTPUT_NAME "${NAME}_ui" | |||
PREFIX "") | |||
endif() | |||
@@ -310,6 +314,7 @@ function(dpf__build_vst2 NAME DGL_LIBRARY) | |||
target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui") | |||
set_target_properties("${NAME}-vst2" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst2/$<0:>" | |||
OUTPUT_NAME "${NAME}-vst2" | |||
PREFIX "") | |||
endfunction() | |||
@@ -363,7 +368,7 @@ function(dpf__add_dgl_cairo) | |||
target_link_libraries(dgl-cairo PRIVATE dgl-system-libs) | |||
add_library(dgl-cairo-definitions INTERFACE) | |||
target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO") | |||
target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO" "HAVE_DGL") | |||
target_include_directories(dgl-cairo PUBLIC ${CAIRO_INCLUDE_DIRS}) | |||
if(MINGW) | |||
@@ -429,7 +434,7 @@ function(dpf__add_dgl_opengl) | |||
target_link_libraries(dgl-opengl PRIVATE dgl-system-libs) | |||
add_library(dgl-opengl-definitions INTERFACE) | |||
target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL") | |||
target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL" "HAVE_DGL") | |||
target_include_directories(dgl-opengl PUBLIC "${OPENGL_INCLUDE_DIR}") | |||
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; | |||
/** | |||
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. | |||
*/ | |||
@@ -14,7 +14,10 @@ BUILD_CXX_FLAGS += -Isrc/pugl-upstream/include | |||
LINK_FLAGS += $(DGL_LIBS) | |||
# 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) | |||
# needed by sofd right now, fix later | |||
@@ -107,6 +107,14 @@ public: | |||
DISTRHO_DEPRECATED_BY("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: | |||
struct PrivateData; | |||
PrivateData* const pData; | |||
@@ -150,7 +150,11 @@ public: | |||
: BaseEvent(), | |||
keycode(0), | |||
character(0), | |||
#ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||
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 | |||
sofdFileDialogSetup(world); | |||
#endif | |||
#ifdef DISTRHO_OS_MAC | |||
if (standalone) | |||
puglMacOSActivateApp(); | |||
#endif | |||
} | |||
Application::PrivateData::~PrivateData() | |||
@@ -726,21 +726,21 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||
cairo_matrix_t 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 | |||
// 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_scale(handle, autoScaleFactor, autoScaleFactor); | |||
} | |||
else | |||
{ | |||
// set viewport pos | |||
cairo_translate(handle, absolutePos.getX(), absolutePos.getY()); | |||
cairo_translate(handle, absolutePos.getX() * autoScaleFactor, absolutePos.getY() * autoScaleFactor); | |||
// then cut the outer bounds | |||
cairo_rectangle(handle, | |||
@@ -751,6 +751,9 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||
cairo_clip(handle); | |||
needsResetClip = true; | |||
// set viewport scaling | |||
cairo_scale(handle, autoScaleFactor, autoScaleFactor); | |||
} | |||
// display widget | |||
@@ -771,24 +774,34 @@ void TopLevelWidget::PrivateData::display() | |||
if (! selfw->pData->visible) | |||
return; | |||
cairo_t* const handle = static_cast<const CairoGraphicsContext&>(self->getGraphicsContext()).handle; | |||
const Size<uint> size(window.getSize()); | |||
const uint width = size.getWidth(); | |||
const uint height = size.getHeight(); | |||
const double autoScaleFactor = window.pData->autoScaleFactor; | |||
// FIXME anything needed here? | |||
#if 0 | |||
cairo_matrix_t matrix; | |||
cairo_get_matrix(handle, &matrix); | |||
// full viewport size | |||
if (window.pData->autoScaling) | |||
glViewport(0, -(height * autoScaleFactor - height), width * autoScaleFactor, height * autoScaleFactor); | |||
{ | |||
cairo_translate(handle, 0, 0); | |||
cairo_scale(handle, autoScaleFactor, autoScaleFactor); | |||
} | |||
else | |||
glViewport(0, 0, width, height); | |||
#endif | |||
{ | |||
cairo_translate(handle, 0, 0); | |||
cairo_scale(handle, 1.0, 1.0); | |||
} | |||
// main widget drawing | |||
self->onDisplay(); | |||
cairo_set_matrix(handle, &matrix); | |||
// now draw subwidgets if there are any | |||
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); | |||
} | |||
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> | |||
bool Rectangle<T>::containsX(const T& x) const noexcept | |||
{ | |||
@@ -29,8 +29,11 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(Window& parentWindow, cons | |||
setResizable(false); | |||
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> | |||
@@ -41,8 +44,11 @@ ImageBaseAboutWindow<ImageType>::ImageBaseAboutWindow(TopLevelWidget* const pare | |||
setResizable(false); | |||
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> | |||
@@ -52,7 +58,12 @@ void ImageBaseAboutWindow<ImageType>::setImage(const ImageType& image) | |||
return; | |||
img = image; | |||
if (image.isInvalid()) | |||
return; | |||
setSize(image.getSize()); | |||
setGeometryConstraints(image.getWidth(), image.getHeight(), true, true); | |||
} | |||
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))) | |||
{ | |||
// 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 | |||
{ | |||
@@ -646,9 +649,9 @@ void TopLevelWidget::PrivateData::display() | |||
if (window.pData->autoScaling) | |||
{ | |||
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 | |||
{ | |||
@@ -19,7 +19,7 @@ | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | |||
: Widget(this), | |||
@@ -93,6 +93,38 @@ void TopLevelWidget::setGeometryConstraints(const uint minimumWidth, | |||
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 |
@@ -156,12 +156,16 @@ void Window::setSize(uint width, uint height) | |||
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 | |||
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) | |||
{ | |||
@@ -265,12 +269,21 @@ void Window::repaint() noexcept | |||
void Window::repaint(const Rectangle<uint>& rect) noexcept | |||
{ | |||
const PuglRect prect = { | |||
PuglRect prect = { | |||
static_cast<double>(rect.getX()), | |||
static_cast<double>(rect.getY()), | |||
static_cast<double>(rect.getWidth()), | |||
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); | |||
} | |||
@@ -287,12 +300,6 @@ void Window::setGeometryConstraints(const uint minimumWidth, | |||
DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,); | |||
DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,); | |||
if (pData->isEmbed) { | |||
// nothing to do here | |||
} else if (! isResizable()) { | |||
setResizable(true); | |||
} | |||
pData->minWidth = minimumWidth; | |||
pData->minHeight = minimumHeight; | |||
pData->autoScaling = automaticallyScale; | |||
@@ -64,12 +64,13 @@ START_NAMESPACE_DGL | |||
static const char* const kWin32SelectedFileCancelled = "__dpf_cancelled__"; | |||
#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")) | |||
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), | |||
isVisible(false), | |||
isEmbed(false), | |||
scaleFactor(getDesktopScaleFactor()), | |||
scaleFactor(getDesktopScaleFactor(view)), | |||
autoScaling(false), | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
@@ -137,7 +138,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
isClosed(parentWindowHandle == 0), | |||
isVisible(parentWindowHandle != 0), | |||
isEmbed(parentWindowHandle != 0), | |||
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor()), | |||
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||
autoScaling(false), | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
@@ -167,7 +168,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
isClosed(parentWindowHandle == 0), | |||
isVisible(parentWindowHandle != 0), | |||
isEmbed(parentWindowHandle != 0), | |||
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor()), | |||
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||
autoScaling(false), | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
@@ -362,7 +363,11 @@ void Window::PrivateData::focus() | |||
if (! isEmbed) | |||
puglRaiseWindow(view); | |||
#ifdef HAVE_X11 | |||
puglX11GrabFocus(view); | |||
#else | |||
puglGrabFocus(view); | |||
#endif | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -110,6 +110,10 @@ START_NAMESPACE_DGL | |||
# define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) | |||
# define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) | |||
# endif | |||
# ifndef __MAC_10_9 | |||
# define NSModalResponseOK NSOKButton | |||
typedef NSUInteger NSEventSubtype; | |||
# endif | |||
# pragma clang diagnostic push | |||
# pragma clang diagnostic ignored "-Wdeprecated-declarations" | |||
# import "pugl-upstream/src/mac.m" | |||
@@ -193,13 +197,35 @@ const char* puglGetWindowTitle(const PuglView* const view) | |||
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 | |||
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 | |||
#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) | |||
SetForegroundWindow(view->impl->hwnd); | |||
SetActiveWindow(view->impl->hwnd); | |||
@@ -276,9 +302,30 @@ PuglStatus puglSetWindowSize(PuglView* const view, const uint width, const uint | |||
view->defaultHeight = height; | |||
#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 }; | |||
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) | |||
// matches upstream pugl, except we add SWP_NOMOVE flag | |||
if (view->impl->hwnd) | |||
@@ -391,6 +438,15 @@ bool puglMacOSFilePanelOpen(PuglView* const view, | |||
return true; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// macOS specific, allow standalone window to gain focus | |||
void puglMacOSActivateApp() | |||
{ | |||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; | |||
[NSApp activateIgnoringOtherApps:YES]; | |||
} | |||
#endif | |||
#ifdef DISTRHO_OS_WINDOWS | |||
@@ -450,6 +506,28 @@ void puglWin32SetWindowResizable(PuglView* const view, const bool resizable) | |||
#endif | |||
#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 | |||
@@ -20,9 +20,14 @@ | |||
#include "../Base.hpp" | |||
/* 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 <cstdint> | |||
#ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||
# include <cstdbool> | |||
# include <cstdint> | |||
#else | |||
# include <stdbool.h> | |||
# include <stdint.h> | |||
#endif | |||
#define PUGL_API | |||
#define PUGL_DISABLE_DEPRECATED | |||
@@ -62,6 +67,10 @@ puglGetTransientParent(const PuglView* view); | |||
PUGL_API const char* | |||
puglGetWindowTitle(const PuglView* view); | |||
// get global scale factor | |||
PUGL_API double | |||
puglGetDesktopScaleFactor(const PuglView* view); | |||
// bring view window into the foreground, aka "raise" window | |||
PUGL_API void | |||
puglRaiseWindow(PuglView* view); | |||
@@ -90,6 +99,10 @@ puglFallbackOnResize(PuglView* view); | |||
// macOS specific, setup file browser dialog | |||
typedef void (*openPanelCallback)(PuglView* view, const char* path); | |||
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 | |||
#ifdef DISTRHO_OS_WINDOWS | |||
@@ -107,6 +120,10 @@ puglWin32SetWindowResizable(PuglView* view, bool resizable); | |||
#endif | |||
#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 | |||
PUGL_API void | |||
sofdFileDialogSetup(PuglWorld* world); | |||
@@ -74,8 +74,13 @@ public: | |||
/** | |||
UI class constructor. | |||
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. | |||
@@ -38,7 +38,7 @@ | |||
typedef SSIZE_T ssize_t; | |||
#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 { | |||
inline float fmin(float __x, float __y) | |||
{ return __builtin_fminf(__x, __y); } | |||
@@ -31,6 +31,8 @@ typedef HMODULE lib_t; | |||
typedef void* lib_t; | |||
#endif | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
// 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 |
@@ -59,12 +59,12 @@ public: | |||
/* | |||
* 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()), | |||
fBufferLen(0), | |||
fBufferAlloc(false) | |||
{ | |||
if (copyData || strBuf == nullptr) | |||
if (reallocData || strBuf == nullptr) | |||
{ | |||
_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 + strBeforeLen, strBufAfter, strBufAfterLen + 1); | |||
return String(newBuf); | |||
return String(newBuf, false); | |||
} | |||
static inline | |||
@@ -950,7 +950,7 @@ String operator+(const char* const strBufBefore, const String& strAfter) noexcep | |||
std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | |||
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) | |||
# define DISTRHO_PROPER_CPP11_SUPPORT | |||
# 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 | |||
#ifndef DISTRHO_PROPER_CPP11_SUPPORT | |||
# define constexpr | |||
# define noexcept throw() | |||
# define override | |||
# define final | |||
@@ -71,7 +72,7 @@ | |||
#endif | |||
/* Define DISTRHO_DEPRECATED */ | |||
#if defined(__GNUC__) | |||
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 480 | |||
# define DISTRHO_DEPRECATED __attribute__((deprecated)) | |||
#elif defined(_MSC_VER) | |||
# define DISTRHO_DEPRECATED [[deprecated]] /* Note: __declspec(deprecated) it not applicable to enum members */ | |||
@@ -80,9 +81,9 @@ | |||
#endif | |||
/* Define DISTRHO_DEPRECATED_BY */ | |||
#if defined(__clang__) | |||
#if defined(__clang__) && defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||
# 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))) | |||
#else | |||
# define DISTRHO_DEPRECATED_BY(other) DISTRHO_DEPRECATED | |||
@@ -51,7 +51,7 @@ | |||
# define DISTRHO_PLUGIN_LV2_STATE_PREFIX "urn:distrho:" | |||
#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)) | |||
START_NAMESPACE_DISTRHO | |||
@@ -74,7 +74,7 @@ | |||
# define DISTRHO_LV2_UI_TYPE "UI" | |||
#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_BYPASS_PARAMETER_NAME "lv2_enabled" | |||
@@ -22,6 +22,11 @@ | |||
# define DISTRHO_PLUGIN_HAS_UI 0 | |||
#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 | |||
# include "DistrhoUIInternal.hpp" | |||
# include "../extra/RingBuffer.hpp" | |||
@@ -127,7 +132,7 @@ struct ParameterAndNotesHelper | |||
# 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)); | |||
#endif | |||
} | |||
@@ -184,7 +189,8 @@ public: | |||
nullptr, // TODO file request | |||
nullptr, | |||
plugin->getInstancePointer(), | |||
scaleFactor) | |||
scaleFactor), | |||
fHasScaleFactor(d_isNotZero(scaleFactor)) | |||
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
, fKeyboardModifiers(0) | |||
# endif | |||
@@ -223,11 +229,21 @@ public: | |||
return fUI.getHeight(); | |||
} | |||
double getScaleFactor() const | |||
{ | |||
return fUI.getScaleFactor(); | |||
} | |||
void setSampleRate(const double newSampleRate) | |||
{ | |||
fUI.setSampleRate(newSampleRate, true); | |||
} | |||
void notifyScaleFactorChanged(const double scaleFactor) | |||
{ | |||
fUI.notifyScaleFactorChanged(scaleFactor); | |||
} | |||
// ------------------------------------------------------------------- | |||
// functions called from the plugin side, may block | |||
@@ -382,9 +398,15 @@ protected: | |||
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); | |||
} | |||
@@ -416,6 +438,7 @@ private: | |||
// Plugin UI | |||
UIExporter fUI; | |||
const bool fHasScaleFactor; | |||
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
uint16_t fKeyboardModifiers; | |||
# endif | |||
@@ -494,7 +517,7 @@ public: | |||
fVstRect.left = 0; | |||
fVstRect.bottom = 0; | |||
fVstRect.right = 0; | |||
fLastScaleFactor = 1.0f; | |||
fLastScaleFactor = 0.0f; | |||
if (parameterCount != 0) | |||
{ | |||
@@ -665,6 +688,13 @@ public: | |||
{ | |||
fVstRect.right = fVstUI->getWidth(); | |||
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 | |||
{ | |||
@@ -673,6 +703,13 @@ public: | |||
fPlugin.getInstancePointer(), fLastScaleFactor); | |||
fVstRect.right = tmpUI.getWidth(); | |||
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(); | |||
} | |||
*(ERect**)ptr = &fVstRect; | |||
@@ -993,7 +1030,15 @@ public: | |||
case effVendorSpecific: | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
if (index == CCONST('P', 'r', 'e', 'S') && value == CCONST('A', 'e', 'C', 's')) | |||
{ | |||
if (d_isEqual(fLastScaleFactor, opt)) | |||
break; | |||
fLastScaleFactor = opt; | |||
if (fVstUI != nullptr) | |||
fVstUI->notifyScaleFactorChanged(opt); | |||
} | |||
#endif | |||
break; | |||
@@ -46,13 +46,18 @@ PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, const uint width, | |||
/* ------------------------------------------------------------------------------------------------------------ | |||
* 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)), | |||
uiData(UI::PrivateData::s_nextPrivateData) | |||
{ | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
if (width > 0 && height > 0) | |||
{ | |||
Widget::setSize(width, height); | |||
if (automaticallyScale) | |||
setGeometryConstraints(width, height, true, true); | |||
} | |||
#endif | |||
} | |||
@@ -59,7 +59,7 @@ public: | |||
const fileRequestFunc fileRequestCall, | |||
const char* const bundlePath = nullptr, | |||
void* const dspPtr = nullptr, | |||
const double scaleFactor = 1.0, | |||
const double scaleFactor = 0.0, | |||
const uint32_t bgColor = 0, | |||
const uint32_t fgColor = 0xffffffff) | |||
: ui(nullptr), | |||
@@ -128,6 +128,11 @@ public: | |||
return uiData->window->getHeight(); | |||
} | |||
double getScaleFactor() const noexcept | |||
{ | |||
return uiData->window->getScaleFactor(); | |||
} | |||
bool isVisible() const noexcept | |||
{ | |||
return uiData->window->isVisible(); | |||
@@ -321,7 +326,7 @@ public: | |||
bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) | |||
{ | |||
// TODO also trigger Character input event | |||
Widget::KeyboardEvent ev; | |||
DGL_NAMESPACE::Widget::KeyboardEvent ev; | |||
ev.press = press; | |||
ev.key = key; | |||
ev.mod = mods; | |||
@@ -330,7 +335,7 @@ public: | |||
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.key = key; | |||
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) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
@@ -70,10 +70,10 @@ public: | |||
// TODO external ui stuff | |||
class PluginWindow | |||
{ | |||
UI* const ui; | |||
DISTRHO_NAMESPACE::UI* const ui; | |||
public: | |||
explicit PluginWindow(UI* const uiPtr, | |||
explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||
PluginApplication& app, | |||
const uintptr_t parentWindowHandle, | |||
const uint width, | |||
@@ -107,10 +107,10 @@ public: | |||
#else | |||
class PluginWindow : public Window | |||
{ | |||
UI* const ui; | |||
DISTRHO_NAMESPACE::UI* const ui; | |||
public: | |||
explicit PluginWindow(UI* const uiPtr, | |||
explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||
PluginApplication& app, | |||
const uintptr_t parentWindowHandle, | |||
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); | |||
title[sizeof(title)-1u] = '\0'; | |||
Window::FileBrowserOptions opts; | |||
DGL_NAMESPACE::Window::FileBrowserOptions opts; | |||
opts.title = title; | |||
return window->openFileBrowser(opts); | |||
#endif | |||
@@ -36,9 +36,11 @@ | |||
#include "../../extra/LibraryUtils.hpp" | |||
// 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 | |||
// ----------------------------------------------------------------------------- | |||
@@ -422,6 +424,7 @@ struct JackBridge { | |||
# else | |||
const char* const filename("libjack.so.0"); | |||
# endif | |||
USE_NAMESPACE_DISTRHO | |||
lib = lib_open(filename); | |||
@@ -561,6 +564,8 @@ struct JackBridge { | |||
~JackBridge() noexcept | |||
{ | |||
USE_NAMESPACE_DISTRHO | |||
if (lib != nullptr) | |||
{ | |||
lib_close(lib); | |||
@@ -37,8 +37,12 @@ | |||
# define Point CorePoint /* fix conflict between DGL and macOS Point name */ | |||
# include "rtaudio/RtAudio.h" | |||
# undef Point | |||
# include "../../extra/RingBuffer.hpp" | |||
# include "../../extra/ScopedPointer.hpp" | |||
using DISTRHO_NAMESPACE::HeapRingBuffer; | |||
using DISTRHO_NAMESPACE::ScopedPointer; | |||
struct RtAudioBridge { | |||
// pointer to RtAudio instance | |||
ScopedPointer<RtAudio> handle; | |||
@@ -58,9 +62,23 @@ struct RtAudioBridge { | |||
void* jackProcessArg = nullptr; | |||
// 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]; | |||
// 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() | |||
{ | |||
@@ -90,6 +108,13 @@ struct RtAudioBridge { | |||
handle = rtAudio; | |||
bufferSize = rtAudioBufferFrames; | |||
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; | |||
} | |||
@@ -148,7 +173,8 @@ struct RtAudioBridge { | |||
else | |||
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++) | |||
: (isInput ? numMidiIns++ : numMidiOuts++))); | |||
@@ -157,10 +183,19 @@ struct RtAudioBridge { | |||
void* getPortBuffer(jack_port_t* const 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 (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 | |||
return nullptr; | |||
@@ -24,7 +24,7 @@ namespace Art = DistrhoArtwork3BandEQ; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUI3BandEQ::DistrhoUI3BandEQ() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | |||
fAboutWindow(this) | |||
{ | |||
@@ -24,7 +24,7 @@ namespace Art = DistrhoArtwork3BandSplitter; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUI3BandSplitter::DistrhoUI3BandSplitter() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | |||
fAboutWindow(this) | |||
{ | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* DISTRHO AmplitudeImposer, a DPF'ied AmplitudeImposer. | |||
* 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 | |||
* copy of this software and associated documentation files (the "Software"), | |||
@@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkAmplitudeImposer; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUIAmplitudeImposer::DistrhoUIAmplitudeImposer() | |||
: UI(Art::backWidth, Art::backHeight), | |||
: UI(Art::backWidth, Art::backHeight, true), | |||
fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | |||
{ | |||
// sliders | |||
@@ -1,5 +1,5 @@ | |||
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 | |||
copy of this software and associated documentation files (the "Software"), | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* DISTRHO CycleShifter, a DPF'ied CycleShifter. | |||
* 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 | |||
* copy of this software and associated documentation files (the "Software"), | |||
@@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkCycleShifter; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUICycleShifter::DistrhoUICycleShifter() | |||
: UI(Art::backWidth, Art::backHeight), | |||
: UI(Art::backWidth, Art::backHeight, true), | |||
fImgBackground(Art::backData, Art::backWidth, Art::backHeight, kImageFormatGrayscale) | |||
{ | |||
// sliders | |||
@@ -1,5 +1,5 @@ | |||
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 | |||
copy of this software and associated documentation files (the "Software"), | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* DISTRHO MVerb, a DPF'ied MVerb. | |||
* 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 | |||
* modify it under the terms of the GNU General Public License as | |||
@@ -28,7 +28,7 @@ using DGL::Color; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUIMVerb::DistrhoUIMVerb() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR) | |||
{ | |||
// text | |||
@@ -122,9 +122,6 @@ DistrhoUIMVerb::DistrhoUIMVerb() | |||
// set initial values | |||
programLoaded(0); | |||
// TODO auto-scale but non-resizable | |||
// setGeometryConstraints(Art::backgroundWidth, Art::backgroundHeight, true, true); | |||
} | |||
DistrhoUIMVerb::~DistrhoUIMVerb() | |||
@@ -25,7 +25,7 @@ namespace Art = DistrhoArtworkNekobi; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUINekobi::DistrhoUINekobi() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | |||
fAboutWindow(this) | |||
{ | |||
@@ -24,7 +24,7 @@ namespace Art = DistrhoArtworkPingPongPan; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUIPingPongPan::DistrhoUIPingPongPan() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | |||
fAboutWindow(this) | |||
{ | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* DISTRHO SoulForce, a DPF'ied SoulForce. | |||
* 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 | |||
* copy of this software and associated documentation files (the "Software"), | |||
@@ -32,7 +32,7 @@ namespace Art = DistrhoArtworkSoulForce; | |||
// ----------------------------------------------------------------------- | |||
DistrhoUISoulForce::DistrhoUISoulForce() | |||
: UI(Art::backgroundWidth, Art::backgroundHeight), | |||
: UI(Art::backgroundWidth, Art::backgroundHeight, true), | |||
fImgBackground(Art::backgroundData, Art::backgroundWidth, Art::backgroundHeight, kImageFormatBGR), | |||
fImgLedOff(Art::led_offData, Art::led_offWidth, Art::led_offHeight, kImageFormatBGR), | |||
fImgLedOn(Art::led_onData, Art::led_onWidth, Art::led_onHeight, kImageFormatBGR), | |||
@@ -1,5 +1,5 @@ | |||
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 | |||
copy of this software and associated documentation files (the "Software"), | |||