diff --git a/README.md b/README.md index 6c0b913e2..5d09e6421 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ Features * GIG, SF2 and SFZ sound banks * Internal audio and midi file player * Automation of plugin parameters via MIDI CC -* Full OSC control -* Rack and Patchbay engine modes, plus Single and Multi-Client if using JACK -* Native audio drivers (ALSA, DirectSound, CoreAudio) and low-latency (ASIO and JACK) +* Remote control over OSC +* Rack and Patchbay processing modes, plus Single and Multi-Client if using JACK +* Native audio drivers (ALSA, DirectSound, CoreAudio, etc) and JACK In experimental phase / work in progress: * Export any Carla loadable plugin or sound bank as an LV2 plugin diff --git a/data/linux/README b/data/linux/README index 579aae124..a99d1da7f 100644 --- a/data/linux/README +++ b/data/linux/README @@ -13,9 +13,9 @@ Features * GIG, SF2 and SFZ sound banks * Internal audio and midi file player * Automation of plugin parameters via MIDI CC -* Full OSC control -* Rack and Patchbay engine modes, plus Single and Multi-Client if using JACK -* Native audio drivers (ALSA, DirectSound, CoreAudio) and low-latency (ASIO and JACK) +* Remote control over OSC +* Rack and Patchbay processing modes, plus Single and Multi-Client if using JACK +* Native audio drivers (ALSA, DirectSound, CoreAudio, etc) and JACK In experimental phase / work in progress: * Export any Carla loadable plugin or sound bank as an LV2 plugin diff --git a/data/linux/build-all.sh b/data/linux/build-all.sh index e1a947c7b..77390dddd 100755 --- a/data/linux/build-all.sh +++ b/data/linux/build-all.sh @@ -25,6 +25,7 @@ source common.env CHROOT_CARLA_DIR="/tmp/carla-src" PKG_FOLDER="Carla_2.0-beta6-linux" +export MAKE_ARGS="${MAKE_ARGS} SKIP_ZYN_SYNTH=true" # --------------------------------------------------------------------------------------------------------------------- # function to remove old stuff @@ -95,6 +96,7 @@ if [ ! -f /tmp/setup-repo-packages ]; then apt-get install -y build-essential libglib2.0-dev uuid-dev git-core apt-get install -y autoconf libtool apt-get install -y bison flex libxml-libxml-perl libxml-parser-perl + apt-get install -y libgl1-mesa-dev libglu1-mesa-dev apt-get clean rm /usr/lib/libuuid.so touch /tmp/setup-repo-packages @@ -175,6 +177,7 @@ chroot_build_carla() { CHROOT_DIR=${TARGETDIR}/chroot${ARCH} +CHROOT_TARGET_DIR=/root/builds cat <&1 | sed -n 's/.*version \([0-9]\).*/\1/p') -lt 9 ]; then + export MACOS_OLD="true" +fi export CC=clang export CXX=clang++ diff --git a/data/macos/common.env b/data/macos/common.env index 21f8abe9c..11f27dfb2 100644 --- a/data/macos/common.env +++ b/data/macos/common.env @@ -15,6 +15,9 @@ GETTEXT_VERSION=0.18.3.2 GLIB_VERSION=2.44.1 GLIB_MVERSION=2.44 FLUIDSYNTH_VERSION=1.1.6 +ZLIB_VERSION=1.2.11 +MXML_VERSION=2.11 +FFTW3_VERSION=3.3.7 QT5_VERSION=5.5.1 QT5_MVERSION=5.5 PYTHON_VERSION=3.4.7 diff --git a/data/macos/env.sh b/data/macos/env.sh index 1e4ffd026..07b7f3c48 100644 --- a/data/macos/env.sh +++ b/data/macos/env.sh @@ -5,13 +5,14 @@ source data/macos/common.env -export MACOS="true" -export MACOS_OLD="true" export CC=clang export CXX=clang++ export MACOS="true" -export MACOS_OLD="true" + +if [ $(clang -v 2>&1 | sed -n 's/.*version \([0-9]\).*/\1/p') -lt 9 ]; then + export MACOS_OLD="true" +fi export CC=clang export CXX=clang++ diff --git a/data/macos/patches/qt55-newosx-fix.patch b/data/macos/patches/qt55-newosx-fix.patch new file mode 100644 index 000000000..8c2a56d87 --- /dev/null +++ b/data/macos/patches/qt55-newosx-fix.patch @@ -0,0 +1,71 @@ +From 0707260a4f8e64dfadf1df5f935e74cabb7c7d27 Mon Sep 17 00:00:00 2001 +From: Jake Petroules +Date: Sun, 1 Oct 2017 21:48:17 -0700 +Subject: [PATCH] Fix build error with macOS 10.13 SDK +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +Several of these variables/macros are no longer defined. We didn't +validate the preconditions on iOS, tvOS, or watchOS, so no +need to bother validating them on macOS either. Nor did we check the +OSStatus result on any platform anyways. + +Task-number: QTBUG-63401 +Change-Id: Ife64dff767cf6d3f4b839fc53ec486181c176bf3 +(cherry-picked from 861544583511d4e6f7745d2339b26ff1cd44132b) +Reviewed-by: Timur Pocheptsov +Reviewed-by: Tor Arne Vestbø +--- + src/plugins/platforms/cocoa/qcocoahelpers.h | 2 +- + src/plugins/platforms/cocoa/qcocoahelpers.mm | 13 +------------ + 2 files changed, 2 insertions(+), 13 deletions(-) + +diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h +index bbb3793..74371d5 100644 +--- a/src/plugins/platforms/cocoa/qcocoahelpers.h ++++ b/src/plugins/platforms/cocoa/qcocoahelpers.h +@@ -80,7 +80,7 @@ QColor qt_mac_toQColor(CGColorRef color); + // Creates a mutable shape, it's the caller's responsibility to release. + HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); + +-OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); ++void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); + + NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); + NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); +diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm +index cd73148..3f8429e 100644 +--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm ++++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm +@@ -544,15 +544,8 @@ NSRect qt_mac_flipRect(const QRect &rect) + return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); + } + +-OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) ++void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) + { +- // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) +- OSStatus err = noErr; +- +- require_action(inContext != NULL, InvalidContext, err = paramErr); +- require_action(inBounds != NULL, InvalidBounds, err = paramErr); +- require_action(inImage != NULL, InvalidImage, err = paramErr); +- + CGContextSaveGState( inContext ); + CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); + CGContextScaleCTM(inContext, 1, -1); +@@ -560,10 +553,6 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm + CGContextDrawImage(inContext, *inBounds, inImage); + + CGContextRestoreGState(inContext); +-InvalidImage: +-InvalidBounds: +-InvalidContext: +- return err; + } + + Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) +-- +2.7.4 + diff --git a/data/windows/README.txt b/data/windows/README.txt index 3b36f030f..757fced7c 100644 --- a/data/windows/README.txt +++ b/data/windows/README.txt @@ -13,9 +13,9 @@ Features * GIG, SF2 and SFZ sound banks * Internal audio and midi file player * Automation of plugin parameters via MIDI CC -* Full OSC control -* Rack and Patchbay engine modes, plus Single and Multi-Client if using JACK -* Native audio drivers (ALSA, DirectSound, CoreAudio) and low-latency (ASIO and JACK) +* Remote control over OSC +* Rack and Patchbay processing modes, plus Single and Multi-Client if using JACK +* Native audio drivers (ALSA, DirectSound, CoreAudio, etc) and JACK In experimental phase / work in progress: * Export any Carla loadable plugin or sound bank as an LV2 plugin diff --git a/data/windows/build-deps.sh b/data/windows/build-deps.sh index 749907f36..679605bff 100755 --- a/data/windows/build-deps.sh +++ b/data/windows/build-deps.sh @@ -74,7 +74,7 @@ unset CXXFLAGS unset LDFLAGS export PREFIX=${TARGETDIR}/carla-w${ARCH} -export PATH=${PREFIX}/bin/usr/sbin:/usr/bin:/sbin:/bin +export PATH=${PREFIX}/bin:/usr/sbin:/usr/bin:/sbin:/bin export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig # --------------------------------------------------------------------------------------------------------------------- @@ -352,11 +352,68 @@ if [ ! -f fluidsynth-${FLUIDSYNTH_VERSION}/build-done ]; then cd .. fi +# --------------------------------------------------------------------------------------------------------------------- +# mxml + +if [ ! -d mxml-${MXML_VERSION} ]; then + wget -c https://github.com/michaelrsweet/mxml/releases/download/v${MXML_VERSION}/mxml-${MXML_VERSION}.tar.gz -O mxml-${MXML_VERSION}.tar.gz + mkdir mxml-${MXML_VERSION} + cd mxml-${MXML_VERSION} + tar -xf ../mxml-${MXML_VERSION}.tar.gz + cd .. +fi + +if [ ! -f mxml-${MXML_VERSION}/build-done ]; then + cd mxml-${MXML_VERSION} + ./configure --disable-shared --prefix=${PREFIX} \ + --target=${MINGW_PREFIX} --host=${MINGW_PREFIX} --build=${HOST_ARCH} + make libmxml.a + cp *.a ${PREFIX}/lib/ + cp *.pc ${PREFIX}/lib/pkgconfig/ + cp mxml.h ${PREFIX}/include/ + touch build-done + cd .. +fi + +# --------------------------------------------------------------------------------------------------------------------- +# fftw3 (needs to be last as it modifies C[XX]FLAGS) + +if [ ! -d fftw-${FFTW3_VERSION} ]; then + curl -O http://www.fftw.org/fftw-${FFTW3_VERSION}.tar.gz + tar -xf fftw-${FFTW3_VERSION}.tar.gz +fi + +if [ ! -f fftw-${FFTW3_VERSION}/build-done ]; then + export CFLAGS="${CFLAGS} -ffast-math" + export CXXFLAGS="${CXXFLAGS} -ffast-math" + cd fftw-${FFTW3_VERSION} + ./configure --enable-static --disable-shared --prefix=${PREFIX} \ + --target=${MINGW_PREFIX} --host=${MINGW_PREFIX} --build=${HOST_ARCH} \ + --enable-sse2 \ + --disable-debug --disable-alloca --disable-fortran \ + --with-our-malloc + make + make install + make clean + ./configure --enable-static --disable-shared --prefix=${PREFIX} \ + --target=${MINGW_PREFIX} --host=${MINGW_PREFIX} --build=${HOST_ARCH} \ + --enable-sse2 --enable-sse --enable-single \ + --disable-debug --disable-alloca --disable-fortran \ + --with-our-malloc + make + make install + make clean + touch build-done + cd .. +fi + } # --------------------------------------------------------------------------------------------------------------------- # build base libs +cleanup_prefix + export ARCH=32 build_base cleanup_pkgs diff --git a/data/windows/build-win.sh b/data/windows/build-win.sh index f417c2d9e..1421d8f29 100755 --- a/data/windows/build-win.sh +++ b/data/windows/build-win.sh @@ -27,8 +27,8 @@ fi source data/windows/common.env -MAKE_ARGS="${MAKE_ARGS} HAVE_QT4=false HAVE_QT5=false HAVE_PYQT5=true HAVE_FFMPEG=false" -MAKE_ARGS="${MAKE_ARGS} BUILDING_FOR_WINDOWS=true EXTERNAL_PLUGINS=false" +MAKE_ARGS="${MAKE_ARGS} HAVE_QT4=false HAVE_QT5=false HAVE_PYQT5=true HAVE_FFMPEG=false HAVE_PROJECTM=false" +MAKE_ARGS="${MAKE_ARGS} BUILDING_FOR_WINDOWS=true" if [ x"${ARCH}" != x"32" ]; then CPUARCH="x86_64" diff --git a/data/windows/common.env b/data/windows/common.env index b8ac7e965..8ab3e5e37 100644 --- a/data/windows/common.env +++ b/data/windows/common.env @@ -15,6 +15,8 @@ GETTEXT_VERSION=0.18.3.2 GLIB_VERSION=2.22.5 GLIB_MVERSION=2.22 FLUIDSYNTH_VERSION=1.1.6 +MXML_VERSION=2.11 +FFTW3_VERSION=3.3.7 QT5_VERSION=5.5.1 QT5_MVERSION=5.5 PYTHON_VERSION=3.4.7 diff --git a/data/windows/create-wineprefixes.sh b/data/windows/create-wineprefixes.sh index dcd25816e..44e6c7447 100755 --- a/data/windows/create-wineprefixes.sh +++ b/data/windows/create-wineprefixes.sh @@ -8,6 +8,7 @@ rm -rf ~/.winepy3_x64 export WINEARCH=win32 export WINEPREFIX=~/.winepy3_x32 wineboot +winetricks winxp winetricks vcrun2010 winetricks corefonts winetricks fontsmooth=rgb @@ -21,6 +22,7 @@ winetricks fontsmooth=rgb export WINEARCH=win64 export WINEPREFIX=~/.winepy3_x64 wineboot +winetricks win7 winetricks vcrun2010 winetricks corefonts winetricks fontsmooth=rgb diff --git a/doc/Carla-TODO b/doc/Carla-TODO index e2e8923c6..747140ff2 100644 --- a/doc/Carla-TODO +++ b/doc/Carla-TODO @@ -35,12 +35,9 @@ GENERAL: - implement midi-learn (new dialog) - implement favorite plugins, add in new tab near file-browser - blender style canvas theme - - make it possible to use backend as fake standalone app (using pipes) instead of a shared library - - artwork about tab - NSM rework FRONTEND: - - options for UIs on top of carla (managed) - make always-on-top depend on it^ - complete zynfx, knob values on top - synth skin @@ -49,13 +46,10 @@ FRONTEND: ENGINE: - allow to change position of plugins (up/down) - allow to add plugins when engine is stopped - - complete RtAudio+RtMidi support (only MIDI out missing) - - complete Juce engine driver support - implement Haiku Media support (based from JACK?, LATER) - implement latency in continuous-rack mode - - handle sample-rate changes in JACK (made possible by switch-master) - add MIDI-bank change type (GM, GS, XG and MMA). See fluidsynth and los docs - - allow to use static OSC ports + ~ allow to use static OSC ports - switch engine modes when opening project - don't pass audio buffers to plugin process, make them request via ports @@ -66,10 +60,6 @@ PLUGINS: - implement LSCP file support (new native plugin?) - implement Csound file support -Native: - - Cleanup API - - Document API from daz - - update zynaddsubfx LADSPA: @@ -103,8 +93,6 @@ misc -allow in-line edit window (i.e. right of rack/canvas) -> shows as soon as plugin/instr. is selected -indicate engine at work top right -if engine is jack, show load top right (percent and/or gauge) --don't show jack transport on start --allow to re-open jack transport, i.e. settings/show ... and/or via toolbar -warn on quit if unsaved patchbay diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui index d997e6c84..091fd58fc 100644 --- a/resources/ui/carla_settings.ui +++ b/resources/ui/carla_settings.ui @@ -7,7 +7,7 @@ 0 0 612 - 587 + 507 @@ -708,7 +708,7 @@ - + 2 @@ -924,7 +924,7 @@ - + How much time to wait for OSC GUIs to ping back the host @@ -989,6 +989,13 @@ + + + + NOTE: Plugin-bridge UIs cannot be managed by Carla on macOS + + + @@ -1006,9 +1013,9 @@ - + - + Qt::Horizontal @@ -1021,7 +1028,7 @@ - + 22 @@ -1040,14 +1047,14 @@ - + Restart the engine to load the new settings - + Qt::Horizontal @@ -1069,7 +1076,7 @@ 20 - 225 + 300 @@ -1893,6 +1900,9 @@ This mode is not available for VST plugins. + + false + Whenever possible, run the plugins in bridge mode. @@ -2085,5 +2095,21 @@ This mode is not available for VST plugins. + + cb_exp_plugin_bridges + toggled(bool) + ch_engine_prefer_plugin_bridges + setEnabled(bool) + + + 402 + 145 + + + 402 + 433 + + + diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index 72ff5e778..a6c5c60d8 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -1,6 +1,6 @@ -/* +/* * Carla Standalone - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,7 +28,7 @@ #include "CarlaBase64Utils.hpp" #ifdef BUILD_BRIDGE -# include "water/water.h" +# include "water/files/File.h" #else # include "CarlaLogThread.hpp" #endif @@ -36,7 +36,7 @@ namespace CB = CarlaBackend; using CB::EngineOptions; -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // Single, standalone engine struct CarlaBackendStandalone { @@ -78,13 +78,13 @@ struct CarlaBackendStandalone { CarlaBackendStandalone gStandalone; -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // API #define CARLA_COMMON_NEED_CHECKSTRINGPTR #include "CarlaHostCommon.cpp" -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- uint carla_get_engine_driver_count() { @@ -114,20 +114,20 @@ const EngineDriverDeviceInfo* carla_get_engine_driver_device_info(uint index, co if (const EngineDriverDeviceInfo* const ret = CarlaEngine::getDriverDeviceInfo(index, name)) { - static EngineDriverDeviceInfo devInfo; + static EngineDriverDeviceInfo retDevInfo; static const uint32_t nullBufferSizes[] = { 0 }; static const double nullSampleRates[] = { 0.0 }; - devInfo.hints = ret->hints; - devInfo.bufferSizes = (ret->bufferSizes != nullptr) ? ret->bufferSizes : nullBufferSizes; - devInfo.sampleRates = (ret->sampleRates != nullptr) ? ret->sampleRates : nullSampleRates; - return &devInfo; + retDevInfo.hints = ret->hints; + retDevInfo.bufferSizes = (ret->bufferSizes != nullptr) ? ret->bufferSizes : nullBufferSizes; + retDevInfo.sampleRates = (ret->sampleRates != nullptr) ? ret->sampleRates : nullSampleRates; + return &retDevInfo; } return nullptr; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- CarlaEngine* carla_get_engine() { @@ -136,7 +136,7 @@ CarlaEngine* carla_get_engine() return gStandalone.engine; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static void carla_engine_init_common() { @@ -386,7 +386,7 @@ bool carla_engine_close() if (gStandalone.engine == nullptr) { - carla_stderr2("Engine is not running"); + carla_stderr2("carla_engine_close() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -659,7 +659,7 @@ void carla_set_file_callback(FileCallbackFunc func, void* ptr) gStandalone.engine->setFileCallback(func, ptr); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- bool carla_load_file(const char* filename) { @@ -669,7 +669,7 @@ bool carla_load_file(const char* filename) if (gStandalone.engine != nullptr) return gStandalone.engine->loadFile(filename); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_load_file() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -682,7 +682,7 @@ bool carla_load_project(const char* filename) if (gStandalone.engine != nullptr) return gStandalone.engine->loadProject(filename); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_load_project() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -695,13 +695,13 @@ bool carla_save_project(const char* filename) if (gStandalone.engine != nullptr) return gStandalone.engine->saveProject(filename); - carla_stderr2("Engine was never initiated"); - gStandalone.lastError = "Engine was never initiated"; + carla_stderr2("carla_save_project() failed, engine is not initialized"); + gStandalone.lastError = "Engine is not initialized"; return false; } #ifndef BUILD_BRIDGE -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint portIdB) { @@ -710,7 +710,7 @@ bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint por if (gStandalone.engine != nullptr) return gStandalone.engine->patchbayConnect(groupIdA, portIdA, groupIdB, portIdB); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_patchbay_connect() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -722,7 +722,7 @@ bool carla_patchbay_disconnect(uint connectionId) if (gStandalone.engine != nullptr) return gStandalone.engine->patchbayDisconnect(connectionId); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_patchbay_disconnect() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -734,12 +734,12 @@ bool carla_patchbay_refresh(bool external) if (gStandalone.engine != nullptr) return gStandalone.engine->patchbayRefresh(external); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_patchbay_refresh() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_transport_play() { @@ -805,7 +805,7 @@ const CarlaTransportInfo* carla_get_transport_info() } #endif -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- uint32_t carla_get_current_plugin_count() { @@ -823,16 +823,21 @@ uint32_t carla_get_max_plugin_number() return 0; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- -bool carla_add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* name, const char* label, int64_t uniqueId, const void* extraPtr, uint options) +bool carla_add_plugin(BinaryType btype, PluginType ptype, + const char* filename, const char* name, const char* label, int64_t uniqueId, + const void* extraPtr, uint options) { - carla_debug("carla_add_plugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", btype, CB::BinaryType2Str(btype), ptype, CB::PluginType2Str(ptype), filename, name, label, uniqueId, extraPtr, options); + carla_debug("carla_add_plugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", + btype, CB::BinaryType2Str(btype), + ptype, CB::PluginType2Str(ptype), + filename, name, label, uniqueId, extraPtr, options); if (gStandalone.engine != nullptr) return gStandalone.engine->addPlugin(btype, ptype, filename, name, label, uniqueId, extraPtr, options); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_add_plugin() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -844,7 +849,7 @@ bool carla_remove_plugin(uint pluginId) if (gStandalone.engine != nullptr) return gStandalone.engine->removePlugin(pluginId); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_remove_plugin() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -856,7 +861,7 @@ bool carla_remove_all_plugins() if (gStandalone.engine != nullptr) return gStandalone.engine->removeAllPlugins(); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_remove_all_plugins() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -870,7 +875,7 @@ const char* carla_rename_plugin(uint pluginId, const char* newName) if (gStandalone.engine != nullptr) return gStandalone.engine->renamePlugin(pluginId, newName); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_rename_plugin() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return nullptr; } @@ -882,7 +887,7 @@ bool carla_clone_plugin(uint pluginId) if (gStandalone.engine != nullptr) return gStandalone.engine->clonePlugin(pluginId); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_clone_plugin() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -894,7 +899,7 @@ bool carla_replace_plugin(uint pluginId) if (gStandalone.engine != nullptr) return gStandalone.engine->replacePlugin(pluginId); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_replace_plugin() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -907,13 +912,13 @@ bool carla_switch_plugins(uint pluginIdA, uint pluginIdB) if (gStandalone.engine != nullptr) return gStandalone.engine->switchPlugins(pluginIdA, pluginIdB); - carla_stderr2("Engine is not running"); + carla_stderr2("carla_switch_plugins() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } #endif -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- bool carla_load_plugin_state(uint pluginId, const char* filename) { @@ -922,7 +927,7 @@ bool carla_load_plugin_state(uint pluginId, const char* filename) if (gStandalone.engine == nullptr || ! gStandalone.engine->isRunning()) { - carla_stderr2("Engine is not running"); + carla_stderr2("carla_load_plugin_state() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; return false; } @@ -930,7 +935,7 @@ bool carla_load_plugin_state(uint pluginId, const char* filename) if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) return plugin->loadStateFromFile(filename); - carla_stderr2("carla_load_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename); + carla_stderr2("carla_load_plugin_state(%i, \"%s\") failed, could not find plugin", pluginId, filename); return false; } @@ -941,8 +946,8 @@ bool carla_save_plugin_state(uint pluginId, const char* filename) if (gStandalone.engine == nullptr) { - carla_stderr2("Engine is not running"); - gStandalone.lastError = "Engine is not running"; + carla_stderr2("carla_save_plugin_state() failed, engine is not initialized"); + gStandalone.lastError = "Engine is not initialized"; return false; } @@ -951,7 +956,7 @@ bool carla_save_plugin_state(uint pluginId, const char* filename) if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) return plugin->saveStateToFile(filename); - carla_stderr2("carla_save_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename); + carla_stderr2("carla_save_plugin_state(%i, \"%s\") failed, could not find plugin", pluginId, filename); return false; } @@ -962,199 +967,198 @@ bool carla_export_plugin_lv2(uint pluginId, const char* lv2path) if (gStandalone.engine == nullptr) { - carla_stderr2("Engine is not running"); - gStandalone.lastError = "Engine is not running"; + carla_stderr2("carla_export_plugin_lv2() failed, engine is not initialized"); + gStandalone.lastError = "Engine is not initialized"; return false; } + // allow to export even if engine isn't running + if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) return plugin->exportAsLV2(lv2path); - carla_stderr2("carla_export_plugin_lv2(%i, \"%s\") - could not find plugin", pluginId, lv2path); + carla_stderr2("carla_export_plugin_lv2(%i, \"%s\") failed, could not find plugin", pluginId, lv2path); return false; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- const CarlaPluginInfo* carla_get_plugin_info(uint pluginId) { carla_debug("carla_get_plugin_info(%i)", pluginId); - static CarlaPluginInfo info; + static CarlaPluginInfo retInfo; // reset - info.type = CB::PLUGIN_NONE; - info.category = CB::PLUGIN_CATEGORY_NONE; - info.hints = 0x0; - info.optionsAvailable = 0x0; - info.optionsEnabled = 0x0; - info.filename = gNullCharPtr; - info.name = gNullCharPtr; - info.iconName = gNullCharPtr; - info.uniqueId = 0; + retInfo.type = CB::PLUGIN_NONE; + retInfo.category = CB::PLUGIN_CATEGORY_NONE; + retInfo.hints = 0x0; + retInfo.optionsAvailable = 0x0; + retInfo.optionsEnabled = 0x0; + retInfo.filename = gNullCharPtr; + retInfo.name = gNullCharPtr; + retInfo.iconName = gNullCharPtr; + retInfo.uniqueId = 0; // cleanup - if (info.label != gNullCharPtr) + if (retInfo.label != gNullCharPtr) { - delete[] info.label; - info.label = gNullCharPtr; + delete[] retInfo.label; + retInfo.label = gNullCharPtr; } - if (info.maker != gNullCharPtr) + if (retInfo.maker != gNullCharPtr) { - delete[] info.maker; - info.maker = gNullCharPtr; + delete[] retInfo.maker; + retInfo.maker = gNullCharPtr; } - if (info.copyright != gNullCharPtr) + if (retInfo.copyright != gNullCharPtr) { - delete[] info.copyright; - info.copyright = gNullCharPtr; + delete[] retInfo.copyright; + retInfo.copyright = gNullCharPtr; } - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - char strBufLabel[STR_MAX+1]; - char strBufMaker[STR_MAX+1]; - char strBufCopyright[STR_MAX+1]; - - carla_zeroChars(strBufLabel, STR_MAX+1); - carla_zeroChars(strBufMaker, STR_MAX+1); - carla_zeroChars(strBufCopyright, STR_MAX+1); - - info.type = plugin->getType(); - info.category = plugin->getCategory(); - info.hints = plugin->getHints(); - info.filename = plugin->getFilename(); - info.name = plugin->getName(); - info.iconName = plugin->getIconName(); - info.uniqueId = plugin->getUniqueId(); - - info.optionsAvailable = plugin->getOptionsAvailable(); - info.optionsEnabled = plugin->getOptionsEnabled(); - - plugin->getLabel(strBufLabel); - info.label = carla_strdup_safe(strBufLabel); - - plugin->getMaker(strBufMaker); - info.maker = carla_strdup_safe(strBufMaker); - - plugin->getCopyright(strBufCopyright); - info.copyright = carla_strdup_safe(strBufCopyright); - - checkStringPtr(info.filename); - checkStringPtr(info.name); - checkStringPtr(info.iconName); - checkStringPtr(info.label); - checkStringPtr(info.maker); - checkStringPtr(info.copyright); - - return &info; - } + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); + + char strBuf[STR_MAX+1]; + + retInfo.type = plugin->getType(); + retInfo.category = plugin->getCategory(); + retInfo.hints = plugin->getHints(); + retInfo.filename = plugin->getFilename(); + retInfo.name = plugin->getName(); + retInfo.iconName = plugin->getIconName(); + retInfo.uniqueId = plugin->getUniqueId(); - carla_stderr2("carla_get_plugin_info(%i) - could not find plugin", pluginId); - return &info; + retInfo.optionsAvailable = plugin->getOptionsAvailable(); + retInfo.optionsEnabled = plugin->getOptionsEnabled(); + + carla_zeroChars(strBuf, STR_MAX+1); + plugin->getLabel(strBuf); + retInfo.label = carla_strdup_safe(strBuf); + + carla_zeroChars(strBuf, STR_MAX+1); + plugin->getMaker(strBuf); + retInfo.maker = carla_strdup_safe(strBuf); + + carla_zeroChars(strBuf, STR_MAX+1); + plugin->getCopyright(strBuf); + retInfo.copyright = carla_strdup_safe(strBuf); + + checkStringPtr(retInfo.filename); + checkStringPtr(retInfo.name); + checkStringPtr(retInfo.iconName); + checkStringPtr(retInfo.label); + checkStringPtr(retInfo.maker); + checkStringPtr(retInfo.copyright); + + return &retInfo; } const CarlaPortCountInfo* carla_get_audio_port_count_info(uint pluginId) { carla_debug("carla_get_audio_port_count_info(%i)", pluginId); - static CarlaPortCountInfo info; + static CarlaPortCountInfo retInfo; + carla_zeroStruct(retInfo); - // reset - info.ins = 0; - info.outs = 0; + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { - info.ins = plugin->getAudioInCount(); - info.outs = plugin->getAudioOutCount(); - return &info; + retInfo.ins = plugin->getAudioInCount(); + retInfo.outs = plugin->getAudioOutCount(); + return &retInfo; } carla_stderr2("carla_get_audio_port_count_info(%i) - could not find plugin", pluginId); - return &info; + return &retInfo; } const CarlaPortCountInfo* carla_get_midi_port_count_info(uint pluginId) { carla_debug("carla_get_midi_port_count_info(%i)", pluginId); - static CarlaPortCountInfo info; + static CarlaPortCountInfo retInfo; + carla_zeroStruct(retInfo); - // reset - info.ins = 0; - info.outs = 0; + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { - info.ins = plugin->getMidiInCount(); - info.outs = plugin->getMidiOutCount(); - return &info; + retInfo.ins = plugin->getMidiInCount(); + retInfo.outs = plugin->getMidiOutCount(); + return &retInfo; } carla_stderr2("carla_get_midi_port_count_info(%i) - could not find plugin", pluginId); - return &info; + return &retInfo; } const CarlaPortCountInfo* carla_get_parameter_count_info(uint pluginId) { carla_debug("carla_get_parameter_count_info(%i)", pluginId); - static CarlaPortCountInfo info; + static CarlaPortCountInfo retInfo; + carla_zeroStruct(retInfo); - // reset - info.ins = 0; - info.outs = 0; + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { - plugin->getParameterCountInfo(info.ins, info.outs); - return &info; + plugin->getParameterCountInfo(retInfo.ins, retInfo.outs); + return &retInfo; } carla_stderr2("carla_get_parameter_count_info(%i) - could not find plugin", pluginId); - return &info; + return &retInfo; } const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t parameterId) { carla_debug("carla_get_parameter_info(%i, %i)", pluginId, parameterId); - static CarlaParameterInfo info; + static CarlaParameterInfo retInfo; // reset - info.scalePointCount = 0; + retInfo.scalePointCount = 0; // cleanup - if (info.name != gNullCharPtr) + if (retInfo.name != gNullCharPtr) { - delete[] info.name; - info.name = gNullCharPtr; + delete[] retInfo.name; + retInfo.name = gNullCharPtr; } - if (info.symbol != gNullCharPtr) + if (retInfo.symbol != gNullCharPtr) { - delete[] info.symbol; - info.symbol = gNullCharPtr; + delete[] retInfo.symbol; + retInfo.symbol = gNullCharPtr; } - if (info.unit != gNullCharPtr) + if (retInfo.unit != gNullCharPtr) { - delete[] info.unit; - info.unit = gNullCharPtr; + delete[] retInfo.unit; + retInfo.unit = gNullCharPtr; } - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); + + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { @@ -1168,29 +1172,29 @@ const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t param carla_zeroChars(strBufSymbol, STR_MAX+1); carla_zeroChars(strBufUnit, STR_MAX+1); - info.scalePointCount = plugin->getParameterScalePointCount(parameterId); + retInfo.scalePointCount = plugin->getParameterScalePointCount(parameterId); plugin->getParameterName(parameterId, strBufName); - info.name = carla_strdup_safe(strBufName); + retInfo.name = carla_strdup_safe(strBufName); plugin->getParameterSymbol(parameterId, strBufSymbol); - info.symbol = carla_strdup_safe(strBufSymbol); + retInfo.symbol = carla_strdup_safe(strBufSymbol); plugin->getParameterUnit(parameterId, strBufUnit); - info.unit = carla_strdup_safe(strBufUnit); + retInfo.unit = carla_strdup_safe(strBufUnit); - checkStringPtr(info.name); - checkStringPtr(info.symbol); - checkStringPtr(info.unit); + checkStringPtr(retInfo.name); + checkStringPtr(retInfo.symbol); + checkStringPtr(retInfo.unit); } else carla_stderr2("carla_get_parameter_info(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return &info; + return &retInfo; } carla_stderr2("carla_get_parameter_info(%i, %i) - could not find plugin", pluginId, parameterId); - return &info; + return &retInfo; } const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, uint32_t parameterId, uint32_t scalePointId) @@ -1198,19 +1202,22 @@ const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, ui carla_debug("carla_get_parameter_scalepoint_info(%i, %i, %i)", pluginId, parameterId, scalePointId); CARLA_ASSERT(gStandalone.engine != nullptr); - static CarlaScalePointInfo info; + static CarlaScalePointInfo retInfo; // reset - info.value = 0.0f; + retInfo.value = 0.0f; // cleanup - if (info.label != gNullCharPtr) + if (retInfo.label != gNullCharPtr) { - delete[] info.label; - info.label = gNullCharPtr; + delete[] retInfo.label; + retInfo.label = gNullCharPtr; } - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retInfo); + + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retInfo); if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) { @@ -1221,11 +1228,11 @@ const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, ui char strBufLabel[STR_MAX+1]; carla_zeroChars(strBufLabel, STR_MAX+1); - info.value = plugin->getParameterScalePointValue(parameterId, scalePointId); + retInfo.value = plugin->getParameterScalePointValue(parameterId, scalePointId); plugin->getParameterScalePointLabel(parameterId, scalePointId, strBufLabel); - info.label = carla_strdup_safe(strBufLabel); - checkStringPtr(info.label); + retInfo.label = carla_strdup_safe(strBufLabel); + checkStringPtr(retInfo.label); } else carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - scalePointId out of bounds", pluginId, parameterId, scalePointId); @@ -1233,360 +1240,330 @@ const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, ui else carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, scalePointId); - return &info; + return &retInfo; } carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - could not find plugin", pluginId, parameterId, scalePointId); - return &info; + return &retInfo; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterId) { - carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId); + static ParameterData retParamData; - static const ParameterData fallbackParameterData = { CB::PARAMETER_UNKNOWN, 0x0, CB::PARAMETER_NULL, -1, -1, 0 }; + // reset + retParamData.type = CB::PARAMETER_UNKNOWN; + retParamData.hints = 0x0; + retParamData.index = CB::PARAMETER_NULL; + retParamData.rindex = -1; + retParamData.midiCC = -1; + retParamData.midiChannel = 0; - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParameterData); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retParamData); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return &plugin->getParameterData(parameterId); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retParamData); - carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return &fallbackParameterData; - } + carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), &retParamData); - carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId); - return &fallbackParameterData; + const ParameterData& pluginParamData(plugin->getParameterData(parameterId)); + retParamData.type = pluginParamData.type; + retParamData.hints = pluginParamData.hints; + retParamData.index = pluginParamData.index; + retParamData.rindex = pluginParamData.rindex; + retParamData.midiCC = pluginParamData.midiCC; + retParamData.midiChannel = pluginParamData.midiChannel; + return &plugin->getParameterData(parameterId); } const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId) { - carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId); + static ParameterRanges retParamRanges; - static const ParameterRanges fallbackParamRanges = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f }; + // reset + retParamRanges.def = 0.0f; + retParamRanges.min = 0.0f; + retParamRanges.max = 1.0f; + retParamRanges.step = 0.01f; + retParamRanges.stepSmall = 0.0001f; + retParamRanges.stepLarge = 0.1f; - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retParamRanges); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return &plugin->getParameterRanges(parameterId); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retParamRanges); - carla_stderr2("carla_get_parameter_ranges(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return &fallbackParamRanges; - } + carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), &retParamRanges); - carla_stderr2("carla_get_parameter_ranges(%i, %i) - could not find plugin", pluginId, parameterId); - return &fallbackParamRanges; + const ParameterRanges& pluginParamRanges(plugin->getParameterRanges(parameterId)); + retParamRanges.def = pluginParamRanges.def; + retParamRanges.min = pluginParamRanges.min; + retParamRanges.max = pluginParamRanges.max; + retParamRanges.step = pluginParamRanges.step; + retParamRanges.stepSmall = pluginParamRanges.stepSmall; + retParamRanges.stepLarge = pluginParamRanges.stepLarge; + return &pluginParamRanges; } const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiProgramId) { - carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); - - static MidiProgramData midiProgData; + static MidiProgramData retMidiProgData = { 0, 0, gNullCharPtr }; // reset - midiProgData.bank = 0; - midiProgData.program = 0; - midiProgData.name = gNullCharPtr; - - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &midiProgData); + retMidiProgData.bank = 0; + retMidiProgData.program = 0; - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) + if (retMidiProgData.name != nullptr) { - if (midiProgramId < plugin->getMidiProgramCount()) - { - const MidiProgramData& ret(plugin->getMidiProgramData(midiProgramId)); - carla_copyStruct(midiProgData, ret); - checkStringPtr(midiProgData.name); - return &midiProgData; - } - - carla_stderr2("carla_get_midi_program_data(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); - return &midiProgData; + delete[] retMidiProgData.name; + retMidiProgData.name = gNullCharPtr; } - carla_stderr2("carla_get_midi_program_data(%i, %i) - could not find plugin", pluginId, midiProgramId); - return &midiProgData; + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retMidiProgData); + + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retMidiProgData); + + carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); + CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(),); + + const MidiProgramData& pluginMidiProgData(plugin->getMidiProgramData(midiProgramId)); + retMidiProgData.bank = pluginMidiProgData.bank; + retMidiProgData.program = pluginMidiProgData.program; + retMidiProgData.name = carla_strdup_safe(pluginMidiProgData.name); + checkStringPtr(retMidiProgData.name); + return &retMidiProgData; } const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId) { - carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); - - static CustomData customData; + static CustomData retCustomData = { gNullCharPtr, gNullCharPtr, gNullCharPtr }; // reset - customData.type = gNullCharPtr; - customData.key = gNullCharPtr; - customData.value = gNullCharPtr; - - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &customData); + if (retCustomData.type != gNullCharPtr) + { + delete[] retCustomData.type; + retCustomData.type = gNullCharPtr; + } - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) + if (retCustomData.key != gNullCharPtr) { - if (customDataId < plugin->getCustomDataCount()) - { - const CustomData& ret(plugin->getCustomData(customDataId)); - carla_copyStruct(customData, ret); - checkStringPtr(customData.type); - checkStringPtr(customData.key); - checkStringPtr(customData.value); - return &customData; - } + delete[] retCustomData.key; + retCustomData.key = gNullCharPtr; + } - carla_stderr2("carla_get_custom_data(%i, %i) - customDataId out of bounds", pluginId, customDataId); - return &customData; + if (retCustomData.value != gNullCharPtr) + { + delete[] retCustomData.value; + retCustomData.value = gNullCharPtr; } - carla_stderr2("carla_get_custom_data(%i, %i) - could not find plugin", pluginId, customDataId); - return &customData; + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &retCustomData); + + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, &retCustomData); + + carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); + CARLA_SAFE_ASSERT_RETURN(customDataId < plugin->getCustomDataCount(), &retCustomData) + + const CustomData& pluginCustomData(plugin->getCustomData(customDataId)); + retCustomData.type = carla_strdup_safe(pluginCustomData.type); + retCustomData.key = carla_strdup_safe(pluginCustomData.key); + retCustomData.value = carla_strdup_safe(pluginCustomData.value); + checkStringPtr(retCustomData.type); + checkStringPtr(retCustomData.key); + checkStringPtr(retCustomData.value); + return &retCustomData; } const char* carla_get_chunk_data(uint pluginId) { - carla_debug("carla_get_chunk_data(%i)", pluginId); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, gNullCharPtr); - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - - static CarlaString chunkData; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, gNullCharPtr); - // cleanup - chunkData.clear(); + carla_debug("carla_get_chunk_data(%i)", pluginId); + CARLA_SAFE_ASSERT_RETURN(plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS, gNullCharPtr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS) - { - void* data = nullptr; - const std::size_t dataSize(plugin->getChunkData(&data)); + void* data = nullptr; + const std::size_t dataSize(plugin->getChunkData(&data)); + CARLA_SAFE_ASSERT_RETURN(data != nullptr && dataSize > 0, gNullCharPtr); - if (data != nullptr && dataSize > 0) - { - chunkData = CarlaString::asBase64(data, static_cast(dataSize)); - return chunkData; - } - else - carla_stderr2("carla_get_chunk_data(%i) - got invalid chunk data", pluginId); - } - else - carla_stderr2("carla_get_chunk_data(%i) - plugin does not use chunks", pluginId); - - return nullptr; - } + static CarlaString chunkData; - carla_stderr2("carla_get_chunk_data(%i) - could not find plugin", pluginId); - return nullptr; + chunkData = CarlaString::asBase64(data, static_cast(dataSize)); + return chunkData.buffer(); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- uint32_t carla_get_parameter_count(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); - carla_debug("carla_get_parameter_count(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getParameterCount(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0); - carla_stderr2("carla_get_parameter_count(%i) - could not find plugin", pluginId); - return 0; + carla_debug("carla_get_parameter_count(%i)", pluginId); + return plugin->getParameterCount(); } uint32_t carla_get_program_count(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); - carla_debug("carla_get_program_count(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getProgramCount(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0); - carla_stderr2("carla_get_program_count(%i) - could not find plugin", pluginId); - return 0; + carla_debug("carla_get_program_count(%i)", pluginId); + return plugin->getProgramCount(); } uint32_t carla_get_midi_program_count(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); - carla_debug("carla_get_midi_program_count(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getMidiProgramCount(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0); - carla_stderr2("carla_get_midi_program_count(%i) - could not find plugin", pluginId); - return 0; + carla_debug("carla_get_midi_program_count(%i)", pluginId); + return plugin->getMidiProgramCount(); } uint32_t carla_get_custom_data_count(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); - carla_debug("carla_get_custom_data_count(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getCustomDataCount(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0); - carla_stderr2("carla_get_custom_data_count(%i) - could not find plugin", pluginId); - return 0; + carla_debug("carla_get_custom_data_count(%i)", pluginId); + return plugin->getCustomDataCount(); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId) { - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - carla_debug("carla_get_parameter_text(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, gNullCharPtr); - static char textBuf[STR_MAX+1]; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, gNullCharPtr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - { - carla_zeroChars(textBuf, STR_MAX+1); - plugin->getParameterText(parameterId, textBuf); - return textBuf; - } + carla_debug("carla_get_parameter_text(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); - carla_stderr2("carla_get_parameter_text(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return nullptr; - } + static char textBuf[STR_MAX+1]; + carla_zeroChars(textBuf, STR_MAX+1); - carla_stderr2("carla_get_parameter_text(%i, %i) - could not find plugin", pluginId, parameterId); - return nullptr; + plugin->getParameterText(parameterId, textBuf); + return textBuf; } const char* carla_get_program_name(uint pluginId, uint32_t programId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - carla_debug("carla_get_program_name(%i, %i)", pluginId, programId); - static char programName[STR_MAX+1]; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, gNullCharPtr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (programId < plugin->getProgramCount()) - { - carla_zeroChars(programName, STR_MAX+1); - plugin->getProgramName(programId, programName); - return programName; - } + carla_debug("carla_get_program_name(%i, %i)", pluginId, programId); + CARLA_SAFE_ASSERT_RETURN(programId < plugin->getProgramCount(),); - carla_stderr2("carla_get_program_name(%i, %i) - programId out of bounds", pluginId, programId); - return nullptr; - } + static char programName[STR_MAX+1]; + carla_zeroChars(programName, STR_MAX+1); - carla_stderr2("carla_get_program_name(%i, %i) - could not find plugin", pluginId, programId); - return nullptr; + plugin->getProgramName(programId, programName); + return programName; } const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId) { - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - carla_debug("carla_get_midi_program_name(%i, %i)", pluginId, midiProgramId); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, gNullCharPtr); - static char midiProgramName[STR_MAX+1]; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, gNullCharPtr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (midiProgramId < plugin->getMidiProgramCount()) - { - carla_zeroChars(midiProgramName, STR_MAX+1); - plugin->getMidiProgramName(midiProgramId, midiProgramName); - return midiProgramName; - } + carla_debug("carla_get_midi_program_name(%i, %i)", pluginId, midiProgramId); + CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(),); - carla_stderr2("carla_get_midi_program_name(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); - return nullptr; - } + static char midiProgramName[STR_MAX+1]; + carla_zeroChars(midiProgramName, STR_MAX+1); - carla_stderr2("carla_get_midi_program_name(%i, %i) - could not find plugin", pluginId, midiProgramId); - return nullptr; + plugin->getMidiProgramName(midiProgramId, midiProgramName); + return midiProgramName; } const char* carla_get_real_plugin_name(uint pluginId) { - CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - carla_debug("carla_get_real_plugin_name(%i)", pluginId); + CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, gNullCharPtr); - static char realPluginName[STR_MAX+1]; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, gNullCharPtr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - carla_zeroChars(realPluginName, STR_MAX+1); - plugin->getRealName(realPluginName); - return realPluginName; - } + carla_debug("carla_get_real_plugin_name(%i)", pluginId); + static char realPluginName[STR_MAX+1]; + carla_zeroChars(realPluginName, STR_MAX+1); - carla_stderr2("carla_get_real_plugin_name(%i) - could not find plugin", pluginId); - return nullptr; + plugin->getRealName(realPluginName); + return realPluginName; } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- int32_t carla_get_current_program_index(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1); - carla_debug("carla_get_current_program_index(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getCurrentProgram(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, -1); - carla_stderr2("carla_get_current_program_index(%i) - could not find plugin", pluginId); - return -1; + carla_debug("carla_get_current_program_index(%i)", pluginId); + return plugin->getCurrentProgram(); } int32_t carla_get_current_midi_program_index(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1); - carla_debug("carla_get_current_midi_program_index(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getCurrentMidiProgram(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, -1); - carla_stderr2("carla_get_current_midi_program_index(%i) - could not find plugin", pluginId); - return -1; + carla_debug("carla_get_current_midi_program_index(%i)", pluginId); + return plugin->getCurrentMidiProgram(); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- float carla_get_default_parameter_value(uint pluginId, uint32_t parameterId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f); - carla_debug("carla_get_default_parameter_value(%i, %i)", pluginId, parameterId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return plugin->getParameterRanges(parameterId).def; + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0.0f); - carla_stderr2("carla_get_default_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return 0.0f; - } + carla_debug("carla_get_default_parameter_value(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), 0.0f); - carla_stderr2("carla_get_default_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId); - return 0.0f; + return plugin->getParameterRanges(parameterId).def; } float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return plugin->getParameterValue(parameterId); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0.0f); - carla_stderr2("carla_get_current_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId); - return 0.0f; - } + carla_debug("carla_get_current_parameter_value(%i, %i)", pluginId, parameterId); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), 0.0f); - carla_stderr2("carla_get_current_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId); - return 0.0f; + return plugin->getParameterValue(parameterId); } float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId) @@ -1598,14 +1575,14 @@ float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId) #endif CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->getInternalParameterValue(parameterId); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, 0.0f); - carla_stderr2("carla_get_internal_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId); - return 0.0f; + carla_debug("carla_get_internal_parameter_value(%i, %i)", pluginId, parameterId); + return plugin->getInternalParameterValue(parameterId); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- float carla_get_input_peak_value(uint pluginId, bool isLeft) { @@ -1621,7 +1598,7 @@ float carla_get_output_peak_value(uint pluginId, bool isLeft) return gStandalone.engine->getOutputPeak(pluginId, isLeft); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- CARLA_BACKEND_START_NAMESPACE @@ -1634,126 +1611,121 @@ CarlaInlineDisplayImageSurface* carla_render_inline_display(uint pluginId, int w { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - CARLA_SAFE_ASSERT_RETURN(plugin->getType() == CB::PLUGIN_LV2, nullptr); - return (CarlaInlineDisplayImageSurface*)CB::carla_render_inline_display_lv2(plugin, width, height); - } + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr); - carla_stderr2("carla_render_inline_display(%i, %i, %i) - could not find plugin", pluginId, width, height); - return nullptr; + carla_debug("carla_render_inline_display(%i, %i, %i)", pluginId, width, height); + CARLA_SAFE_ASSERT_RETURN(plugin->getType() == CB::PLUGIN_LV2, nullptr); + + return (CarlaInlineDisplayImageSurface*)CB::carla_render_inline_display_lv2(plugin, width, height); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_set_active(uint pluginId, bool onOff) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_active(%i, %s)", pluginId, bool2str(onOff)); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setActive(onOff, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_active(%i, %s) - could not find plugin", pluginId, bool2str(onOff)); + carla_debug("carla_set_active(%i, %s)", pluginId, bool2str(onOff)); + return plugin->setActive(onOff, true, false); } #ifndef BUILD_BRIDGE void carla_set_drywet(uint pluginId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_drywet(%i, %f)", pluginId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setDryWet(value, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_drywet(%i, %f) - could not find plugin", pluginId, value); + carla_debug("carla_set_drywet(%i, %f)", pluginId, value); + return plugin->setDryWet(value, true, false); } void carla_set_volume(uint pluginId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_volume(%i, %f)", pluginId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setVolume(value, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_volume(%i, %f) - could not find plugin", pluginId, value); + carla_debug("carla_set_volume(%i, %f)", pluginId, value); + return plugin->setVolume(value, true, false); } void carla_set_balance_left(uint pluginId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_balance_left(%i, %f)", pluginId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setBalanceLeft(value, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_balance_left(%i, %f) - could not find plugin", pluginId, value); + carla_debug("carla_set_balance_left(%i, %f)", pluginId, value); + return plugin->setBalanceLeft(value, true, false); } void carla_set_balance_right(uint pluginId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_balance_right(%i, %f)", pluginId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setBalanceRight(value, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_balance_right(%i, %f) - could not find plugin", pluginId, value); + carla_debug("carla_set_balance_right(%i, %f)", pluginId, value); + return plugin->setBalanceRight(value, true, false); } void carla_set_panning(uint pluginId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_panning(%i, %f)", pluginId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setPanning(value, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_panning(%i, %f) - could not find plugin", pluginId, value); + carla_debug("carla_set_panning(%i, %f)", pluginId, value); + return plugin->setPanning(value, true, false); } void carla_set_ctrl_channel(uint pluginId, int8_t channel) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,); - carla_debug("carla_set_ctrl_channel(%i, %i)", pluginId, channel); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setCtrlChannel(channel, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_ctrl_channel(%i, %i) - could not find plugin", pluginId, channel); + carla_debug("carla_set_ctrl_channel(%i, %i)", pluginId, channel); + return plugin->setCtrlChannel(channel, true, false); } void carla_set_option(uint pluginId, uint option, bool yesNo) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_option(%i, %i, %s)", pluginId, option, bool2str(yesNo)); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setOption(option, yesNo, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_option(%i, %i, %s) - could not find plugin", pluginId, option, bool2str(yesNo)); + carla_debug("carla_set_option(%i, %i, %s)", pluginId, option, bool2str(yesNo)); + return plugin->setOption(option, yesNo, false); } #endif -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_parameter_value(%i, %i, %f)", pluginId, parameterId, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return plugin->setParameterValue(parameterId, value, true, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_parameter_value(%i, %i, %f) - parameterId out of bounds", pluginId, parameterId, value); - return; - } + carla_debug("carla_set_parameter_value(%i, %i, %f)", pluginId, parameterId, value); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); - carla_stderr2("carla_set_parameter_value(%i, %i, %f) - could not find plugin", pluginId, parameterId, value); + return plugin->setParameterValue(parameterId, value, true, true, false); } #ifndef BUILD_BRIDGE @@ -1761,76 +1733,60 @@ void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8 { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - carla_debug("carla_set_parameter_midi_channel(%i, %i, %i)", pluginId, parameterId, channel); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return plugin->setParameterMidiChannel(parameterId, channel, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, channel); - return; - } + carla_debug("carla_set_parameter_midi_channel(%i, %i, %i)", pluginId, parameterId, channel); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); - carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - could not find plugin", pluginId, parameterId, channel); + return plugin->setParameterMidiChannel(parameterId, channel, true, false); } void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,); - carla_debug("carla_set_parameter_midi_cc(%i, %i, %i)", pluginId, parameterId, cc); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (parameterId < plugin->getParameterCount()) - return plugin->setParameterMidiCC(parameterId, cc, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, cc); - return; - } + carla_debug("carla_set_parameter_midi_cc(%i, %i, %i)", pluginId, parameterId, cc); + CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); - carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - could not find plugin", pluginId, parameterId, cc); + return plugin->setParameterMidiCC(parameterId, cc, true, false); } #endif -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_set_program(uint pluginId, uint32_t programId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_program(%i, %i)", pluginId, programId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (programId < plugin->getProgramCount()) - return plugin->setProgram(static_cast(programId), true, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId); - return; - } + carla_debug("carla_set_program(%i, %i)", pluginId, programId); + CARLA_SAFE_ASSERT_RETURN(programId < plugin->getProgramCount(),); - carla_stderr2("carla_set_program(%i, %i) - could not find plugin", pluginId, programId); + return plugin->setProgram(static_cast(programId), true, true, false); } void carla_set_midi_program(uint pluginId, uint32_t midiProgramId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_set_midi_program(%i, %i)", pluginId, midiProgramId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (midiProgramId < plugin->getMidiProgramCount()) - return plugin->setMidiProgram(static_cast(midiProgramId), true, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); - return; - } + carla_debug("carla_set_midi_program(%i, %i)", pluginId, midiProgramId); + CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(),); - carla_stderr2("carla_set_midi_program(%i, %i) - could not find plugin", pluginId, midiProgramId); + return plugin->setMidiProgram(static_cast(midiProgramId), true, true, false); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_set_custom_data(uint pluginId, const char* type, const char* key, const char* value) { @@ -1838,117 +1794,111 @@ void carla_set_custom_data(uint pluginId, const char* type, const char* key, con CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(value != nullptr,); - carla_debug("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\")", pluginId, type, key, value); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->setCustomData(type, key, value, true); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\") - could not find plugin", pluginId, type, key, value); + carla_debug("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\")", pluginId, type, key, value); + return plugin->setCustomData(type, key, value, true); } void carla_set_chunk_data(uint pluginId, const char* chunkData) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); CARLA_SAFE_ASSERT_RETURN(chunkData != nullptr && chunkData[0] != '\0',); + + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + carla_debug("carla_set_chunk_data(%i, \"%s\")", pluginId, chunkData); + CARLA_SAFE_ASSERT_RETURN(plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS,); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - { - if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS) - { - std::vector chunk(carla_getChunkFromBase64String(chunkData)); + std::vector chunk(carla_getChunkFromBase64String(chunkData)); #ifdef CARLA_PROPER_CPP11_SUPPORT - return plugin->setChunkData(chunk.data(), chunk.size()); + return plugin->setChunkData(chunk.data(), chunk.size()); #else - return plugin->setChunkData(&chunk.front(), chunk.size()); + return plugin->setChunkData(&chunk.front(), chunk.size()); #endif - } - - carla_stderr2("carla_set_chunk_data(%i, \"%s\") - plugin does not use chunks", pluginId, chunkData); - return; - } - - carla_stderr2("carla_set_chunk_data(%i, \"%s\") - could not find plugin", pluginId, chunkData); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- void carla_prepare_for_save(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_prepare_for_save(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->prepareForSave(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_prepare_for_save(%i) - could not find plugin", pluginId); + carla_debug("carla_prepare_for_save(%i)", pluginId); + return plugin->prepareForSave(); } void carla_reset_parameters(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_reset_parameters(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->resetParameters(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_reset_parameters(%i) - could not find plugin", pluginId); + carla_debug("carla_reset_parameters(%i)", pluginId); + return plugin->resetParameters(); } void carla_randomize_parameters(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_randomize_parameters(%i)", pluginId); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->randomizeParameters(); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_randomize_parameters(%i) - could not find plugin", pluginId); + carla_debug("carla_randomize_parameters(%i)", pluginId); + return plugin->randomizeParameters(); } #ifndef BUILD_BRIDGE void carla_send_midi_note(uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),); - carla_debug("carla_send_midi_note(%i, %i, %i, %i)", pluginId, channel, note, velocity); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_send_midi_note(%i, %i, %i, %i) - could not find plugin", pluginId, channel, note, velocity); + carla_debug("carla_send_midi_note(%i, %i, %i, %i)", pluginId, channel, note, velocity); + return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false); } #endif void carla_show_custom_ui(uint pluginId, bool yesNo) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); - carla_debug("carla_show_custom_ui(%i, %s)", pluginId, bool2str(yesNo)); - if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) - return plugin->showCustomUI(yesNo); + CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); - carla_stderr2("carla_show_custom_ui(%i, %s) - could not find plugin", pluginId, bool2str(yesNo)); + carla_debug("carla_show_custom_ui(%i, %s)", pluginId, bool2str(yesNo)); + return plugin->showCustomUI(yesNo); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- uint32_t carla_get_buffer_size() { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); - carla_debug("carla_get_buffer_size()"); + carla_debug("carla_get_buffer_size()"); return gStandalone.engine->getBufferSize(); } double carla_get_sample_rate() { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0); - carla_debug("carla_get_sample_rate()"); + carla_debug("carla_get_sample_rate()"); return gStandalone.engine->getSampleRate(); } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- const char* carla_get_last_error() { @@ -1967,14 +1917,14 @@ const char* carla_get_host_osc_url_tcp() #ifdef HAVE_LIBLO if (gStandalone.engine == nullptr) { - carla_stderr2("Engine is not running"); + carla_stderr2("carla_get_host_osc_url_tcp() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; - return nullptr; + return gNullCharPtr; } return gStandalone.engine->getOscServerPathTCP(); #else - return nullptr; + return gNullCharPtr; #endif } @@ -1985,23 +1935,24 @@ const char* carla_get_host_osc_url_udp() #ifdef HAVE_LIBLO if (gStandalone.engine == nullptr) { - carla_stderr2("Engine is not running"); + carla_stderr2("carla_get_host_osc_url_udp() failed, engine is not running"); gStandalone.lastError = "Engine is not running"; - return nullptr; + return gNullCharPtr; } return gStandalone.engine->getOscServerPathUDP(); #else - return nullptr; + return gNullCharPtr; #endif } -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- +#define CARLA_PLUGIN_UI_CLASS_PREFIX Standalone #include "CarlaPluginUI.cpp" #include "CarlaDssiUtils.cpp" #include "CarlaPatchbayUtils.cpp" #include "CarlaPipeUtils.cpp" #include "CarlaStateUtils.cpp" -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 1766a2ca9..52f837bf3 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -2323,6 +2323,7 @@ const EngineDriverDeviceInfo* CarlaEngine::getRtAudioDeviceInfo(const uint, cons CARLA_BACKEND_END_NAMESPACE +#define CARLA_PLUGIN_UI_CLASS_PREFIX EngineNative #include "CarlaHostCommon.cpp" #include "CarlaPluginUI.cpp" #include "CarlaDssiUtils.cpp" diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index c866899e4..1f56ffc6f 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -478,6 +478,7 @@ public: } // MIDI In + try { RtMidiIn midiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), "carla-discovery-in"); @@ -488,9 +489,10 @@ public: extGraph.midiPorts.ins.append(portNameToId); } - } + } CARLA_SAFE_EXCEPTION("RtMidiIn discovery"); // MIDI Out + try { RtMidiOut midiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), "carla-discovery-out"); @@ -501,7 +503,7 @@ public: extGraph.midiPorts.outs.append(portNameToId); } - } + } CARLA_SAFE_EXCEPTION("RtMidiOut discovery"); // --------------------------------------------------------------- // now refresh @@ -789,7 +791,12 @@ protected: newRtMidiPortName += ":"; newRtMidiPortName += portName; - RtMidiIn* const rtMidiIn(new RtMidiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer(), 512)); + RtMidiIn* rtMidiIn; + + try { + rtMidiIn = new RtMidiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer(), 512); + } CARLA_SAFE_EXCEPTION_RETURN("new RtMidiIn", false); + rtMidiIn->ignoreTypes(); rtMidiIn->setCallback(carla_rtmidi_callback, this); @@ -836,7 +843,11 @@ protected: newRtMidiPortName += ":"; newRtMidiPortName += portName; - RtMidiOut* const rtMidiOut(new RtMidiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer())); + RtMidiOut* rtMidiOut; + + try { + rtMidiOut = new RtMidiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer()); + } CARLA_SAFE_EXCEPTION_RETURN("new RtMidiOut", false); bool found = false; uint rtMidiPortIndex; diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index df622104d..e1609a897 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -2328,6 +2328,7 @@ void CarlaPlugin::uiIdle() pData->postUiEvents.data.clear(); } +#ifndef BUILD_BRIDGE if (pData->transientTryCounter == 0) return; if (++pData->transientTryCounter % 10 != 0) @@ -2340,8 +2341,13 @@ void CarlaPlugin::uiIdle() CarlaString uiTitle(pData->name); uiTitle += " (GUI)"; - if (CarlaPluginUI::tryTransientWinIdMatch(getUiBridgeProcessId(), uiTitle, pData->engine->getOptions().frontendWinId, true)) + if (CarlaPluginUI::tryTransientWinIdMatch(getUiBridgeProcessId(), uiTitle, + pData->engine->getOptions().frontendWinId, pData->transientFirstTry)) + { pData->transientTryCounter = 0; + pData->transientFirstTry = false; + } +#endif } void CarlaPlugin::uiParameterChange(const uint32_t index, const float value) noexcept diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 4d65ca8d9..8a3884bb7 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -391,9 +391,11 @@ public: { carla_debug("CarlaPluginBridge::~CarlaPluginBridge()"); +#ifndef BUILD_BRIDGE // close UI if (pData->hints & PLUGIN_HAS_CUSTOM_UI) pData->transientTryCounter = 0; +#endif pData->singleMutex.lock(); pData->masterMutex.lock(); @@ -2189,7 +2191,9 @@ public: break; case kPluginBridgeNonRtServerUiClosed: +#ifndef BUILD_BRIDGE pData->transientTryCounter = 0; +#endif pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); break; diff --git a/source/backend/plugin/CarlaPluginDSSI.cpp b/source/backend/plugin/CarlaPluginDSSI.cpp index 8df4693c1..e427dd117 100644 --- a/source/backend/plugin/CarlaPluginDSSI.cpp +++ b/source/backend/plugin/CarlaPluginDSSI.cpp @@ -697,7 +697,9 @@ public: } else { +#ifndef BUILD_BRIDGE pData->transientTryCounter = 0; +#endif if (fOscData.target != nullptr) { @@ -2357,8 +2359,10 @@ public: for (uint32_t i=0; i < pData->param.count; ++i) osc_send_control(fOscData, pData->param.data[i].rindex, getParameterValue(i)); +#ifndef BUILD_BRIDGE if (pData->engine->getOptions().frontendWinId != 0) pData->transientTryCounter = 1; +#endif carla_stdout("CarlaPluginDSSI::updateOscData() - done"); } diff --git a/source/backend/plugin/CarlaPluginInternal.cpp b/source/backend/plugin/CarlaPluginInternal.cpp index c0028e596..7b618b1d9 100644 --- a/source/backend/plugin/CarlaPluginInternal.cpp +++ b/source/backend/plugin/CarlaPluginInternal.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin - * Copyright (C) 2011-2014 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -600,7 +600,10 @@ CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx uiLib(nullptr), ctrlChannel(0), extraHints(0x0), +#ifndef BUILD_BRIDGE transientTryCounter(0), + transientFirstTry(true), +#endif name(nullptr), filename(nullptr), iconName(nullptr), @@ -628,7 +631,9 @@ CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx CarlaPlugin::ProtectedData::~ProtectedData() noexcept { CARLA_SAFE_ASSERT(! (active && needsReset)); +#ifndef BUILD_BRIDGE CARLA_SAFE_ASSERT(transientTryCounter == 0); +#endif { // mutex MUST have been locked before diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index 91614214d..805b11302 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -1,6 +1,6 @@ /* * Carla Plugin - * Copyright (C) 2011-2014 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -227,7 +227,10 @@ struct CarlaPlugin::ProtectedData { // misc int8_t ctrlChannel; uint extraHints; +#ifndef BUILD_BRIDGE uint transientTryCounter; + bool transientFirstTry; +#endif // data 1 const char* name; diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index 35ab8ede4..e7727980b 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin JACK - * Copyright (C) 2016-2017 Filipe Coelho + * Copyright (C) 2016-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -221,9 +221,11 @@ public: { carla_debug("CarlaPluginJack::~CarlaPluginJack()"); +#ifndef BUILD_BRIDGE // close UI if (pData->hints & PLUGIN_HAS_CUSTOM_UI) pData->transientTryCounter = 0; +#endif pData->singleMutex.lock(); pData->masterMutex.lock(); diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 93615297b..299c380a1 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -1322,8 +1322,10 @@ public: const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); +#ifndef BUILD_BRIDGE if (! yesNo) pData->transientTryCounter = 0; +#endif if (fUI.type == UI::TYPE_BRIDGE) { @@ -1613,7 +1615,9 @@ public: fPipeServer.stopPipeServer(2000); // fall through case CarlaPipeServerLV2::UiCrashed: +#ifndef BUILD_BRIDGE pData->transientTryCounter = 0; +#endif pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); break; } diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp index 20a0ba5dc..b939a9446 100644 --- a/source/backend/plugin/CarlaPluginNative.cpp +++ b/source/backend/plugin/CarlaPluginNative.cpp @@ -229,7 +229,9 @@ public: if (fIsUiVisible && fDescriptor != nullptr && fDescriptor->ui_show != nullptr && fHandle != nullptr) fDescriptor->ui_show(fHandle, false); +#ifndef BUILD_BRIDGE pData->transientTryCounter = 0; +#endif } pData->singleMutex.lock(); @@ -800,7 +802,9 @@ public: if (! yesNo) { +#ifndef BUILD_BRIDGE pData->transientTryCounter = 0; +#endif return; } diff --git a/source/bridges-ui/CarlaBridgeToolkitNative.cpp b/source/bridges-ui/CarlaBridgeToolkitNative.cpp index 1f8293f86..cbd859919 100644 --- a/source/bridges-ui/CarlaBridgeToolkitNative.cpp +++ b/source/bridges-ui/CarlaBridgeToolkitNative.cpp @@ -1,6 +1,6 @@ /* * Carla Bridge UI - * Copyright (C) 2014-2017 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -68,8 +68,7 @@ public: fHostUI->setTitle(options.windowTitle.buffer()); -#ifdef HAVE_X11 - // Out-of-process reparenting only possible on X11 +#if (defined(CARLA_OS_WIN) && defined(BRIDGE_HWND)) || (defined(HAVE_X11) && defined(BRIDGE_X11)) if (options.transientWindowId != 0) { fHostUI->setTransientWinId(options.transientWindowId); @@ -225,6 +224,7 @@ CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeFormat* const forma CARLA_BRIDGE_UI_END_NAMESPACE +#define CARLA_PLUGIN_UI_CLASS_PREFIX ToolkitNative #include "CarlaPluginUI.cpp" // ------------------------------------------------------------------------- diff --git a/source/carla_host.py b/source/carla_host.py index 91fbae39d..f8506e788 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -309,6 +309,9 @@ class HostWindow(QMainWindow): self.ui.cb_transport_link.setEnabled(False) self.ui.dsb_transport_bpm.setEnabled(False) + if MACOS: + self.ui.cb_transport_link.setEnabled(False) + self.ui.w_transport.setEnabled(False) # ---------------------------------------------------------------------------------------------------- diff --git a/source/carla_settings.py b/source/carla_settings.py index 3faeaa923..8c4a74c3c 100755 --- a/source/carla_settings.py +++ b/source/carla_settings.py @@ -243,10 +243,6 @@ class CarlaSettingsW(QDialog): self.ui.ch_main_show_logs.setEnabled(False) self.ui.ch_main_show_logs.setVisible(False) - if WINDOWS: - self.ui.ch_engine_manage_uis.setEnabled(False) - self.ui.ch_engine_manage_uis.setVisible(False) - if host.isControl: self.ui.lw_page.hideRow(self.TAB_INDEX_CANVAS) self.ui.lw_page.hideRow(self.TAB_INDEX_ENGINE) @@ -287,11 +283,16 @@ class CarlaSettingsW(QDialog): self.ui.ch_exp_prevent_bad_behaviour.setVisible(False) self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + if not MACOS: + self.ui.label_engine_ui_bridges_mac_note.setVisible(False) + # FIXME, pipes on win32 not working, and mis-behaving on macOS if MACOS or WINDOWS: self.ui.ch_engine_prefer_ui_bridges.setChecked(False) self.ui.ch_engine_prefer_ui_bridges.setEnabled(False) self.ui.ch_engine_prefer_ui_bridges.setVisible(False) + self.ui.label_engine_ui_bridges_timeout.setEnabled(False) + self.ui.label_engine_ui_bridges_timeout.setVisible(False) self.ui.sb_engine_ui_bridges_timeout.setEnabled(False) self.ui.sb_engine_ui_bridges_timeout.setVisible(False) @@ -328,8 +329,10 @@ class CarlaSettingsW(QDialog): self.ui.ch_main_experimental.toggled.connect(self.slot_enableExperimental) self.ui.ch_exp_wine_bridges.toggled.connect(self.slot_enableWineBridges) + self.ui.cb_exp_plugin_bridges.toggled.connect(self.slot_pluginBridgesToggled) self.ui.cb_canvas_eyecandy.toggled.connect(self.slot_canvasEyeCandyToggled) self.ui.cb_canvas_fancy_eyecandy.toggled.connect(self.slot_canvasFancyEyeCandyToggled) + self.ui.cb_canvas_use_opengl.toggled.connect(self.slot_canvasOpenGLToggled) # ---------------------------------------------------------------------------------------------------- # Post-connect setup @@ -344,6 +347,8 @@ class CarlaSettingsW(QDialog): self.ui.lw_page.setCurrentCell(0, 0) + self.adjustSize() + # -------------------------------------------------------------------------------------------------------- def loadSettings(self): @@ -862,6 +867,13 @@ class CarlaSettingsW(QDialog): else: self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + @pyqtSlot(bool) + def slot_pluginBridgesToggled(self, toggled): + if not toggled: + self.ui.ch_exp_wine_bridges.setChecked(False) + self.ui.ch_engine_prefer_plugin_bridges.setChecked(False) + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + @pyqtSlot(bool) def slot_canvasEyeCandyToggled(self, toggled): if not toggled: @@ -872,6 +884,11 @@ class CarlaSettingsW(QDialog): if toggled: self.ui.cb_canvas_eyecandy.setChecked(True) + @pyqtSlot(bool) + def slot_canvasOpenGLToggled(self, toggled): + if not toggled: + self.ui.cb_canvas_render_hq_aa.setChecked(False) + # -------------------------------------------------------------------------------------------------------- @pyqtSlot() diff --git a/source/libjack/Makefile b/source/libjack/Makefile index 4e6985f60..fe29759ce 100644 --- a/source/libjack/Makefile +++ b/source/libjack/Makefile @@ -27,11 +27,8 @@ LINK_FLAGS += -lpthread -lrt # ---------------------------------------------------------------------------------------------------------------------- -OBJS = -TARGETS = - ifeq ($(LINUX),true) -OBJS = \ +OBJS = \ $(OBJDIR)/libjack.cpp.o \ $(OBJDIR)/libjack_base.cpp.o \ $(OBJDIR)/libjack_callbacks.cpp.o \ @@ -49,6 +46,8 @@ OBJS = \ $(OBJDIR)/libjack_transport.cpp.o \ $(OBJDIR)/ringbuffer.c.o TARGET = $(BINDIR)/jack/libjack.so.0 +else +OBJS = endif # ---------------------------------------------------------------------------------------------------------------------- @@ -58,7 +57,7 @@ all: $(TARGET) # ---------------------------------------------------------------------------------------------------------------------- clean: - rm -f $(OBJDIR)/*.o $(TARGETS) + rm -f $(OBJDIR)/*.o $(TARGET) debug: $(MAKE) DEBUG=true diff --git a/source/modules/dgl/src/Window.cpp b/source/modules/dgl/src/Window.cpp index 85975f67b..cb848067a 100644 --- a/source/modules/dgl/src/Window.cpp +++ b/source/modules/dgl/src/Window.cpp @@ -87,11 +87,13 @@ struct Window::PrivateData { fWidgets(), fModal(), #if defined(DISTRHO_OS_WINDOWS) - hwnd(0) + hwnd(nullptr), + hwndParent(nullptr) #elif defined(DISTRHO_OS_MAC) fNeedsIdle(true), mView(nullptr), - mWindow(nullptr) + mWindow(nullptr), + mParentWindow(nullptr) #else xDisplay(nullptr), xWindow(0) @@ -115,11 +117,13 @@ struct Window::PrivateData { fWidgets(), fModal(parent.pData), #if defined(DISTRHO_OS_WINDOWS) - hwnd(0) + hwnd(nullptr), + hwndParent(nullptr) #elif defined(DISTRHO_OS_MAC) fNeedsIdle(false), mView(nullptr), - mWindow(nullptr) + mWindow(nullptr), + mParentWindow(nullptr) #else xDisplay(nullptr), xWindow(0) @@ -129,17 +133,16 @@ struct Window::PrivateData { init(); const PuglInternals* const parentImpl(parent.pData->fView->impl); + + // NOTE: almost a 1:1 copy of setTransientWinId() #if defined(DISTRHO_OS_WINDOWS) - // TODO + hwndParent = parentImpl->hwnd; + SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)hwndParent); #elif defined(DISTRHO_OS_MAC) - [parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]]; + mParentWindow = parentImpl->window; #else XSetTransientForHint(xDisplay, xWindow, parentImpl->win); #endif - return; - - // maybe unused - (void)parentImpl; } PrivateData(Application& app, Window* const self, const intptr_t parentId) @@ -156,11 +159,13 @@ struct Window::PrivateData { fWidgets(), fModal(), #if defined(DISTRHO_OS_WINDOWS) - hwnd(0) + hwnd(nullptr), + hwndParent(nullptr) #elif defined(DISTRHO_OS_MAC) fNeedsIdle(parentId == 0), mView(nullptr), - mWindow(nullptr) + mWindow(nullptr), + mParentWindow(nullptr) #else xDisplay(nullptr), xWindow(0) @@ -344,22 +349,6 @@ struct Window::PrivateData { fModal.enabled = true; fModal.parent->fModal.childFocus = this; -#ifdef DISTRHO_OS_WINDOWS - // Center this window - PuglInternals* const parentImpl = fModal.parent->fView->impl; - - RECT curRect; - RECT parentRect; - GetWindowRect(hwnd, &curRect); - GetWindowRect(parentImpl->hwnd, &parentRect); - - int x = parentRect.left+(parentRect.right-curRect.right)/2; - int y = parentRect.top +(parentRect.bottom-curRect.bottom)/2; - - SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); - UpdateWindow(hwnd); -#endif - fModal.parent->setVisible(true); setVisible(true); @@ -436,25 +425,65 @@ struct Window::PrivateData { #if defined(DISTRHO_OS_WINDOWS) if (yesNo) - ShowWindow(hwnd, fFirstInit ? SW_SHOWNORMAL : SW_RESTORE); + { + if (fFirstInit) + { + RECT rectChild, rectParent; + + if (hwndParent != nullptr && + GetWindowRect(hwnd, &rectChild) && + GetWindowRect(hwndParent, &rectParent)) + { + SetWindowPos(hwnd, hwndParent, + rectParent.left + (rectChild.right-rectChild.left)/2, + rectParent.top + (rectChild.bottom-rectChild.top)/2, + 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); + } + else + { + ShowWindow(hwnd, SW_SHOWNORMAL); + } + } + else + { + ShowWindow(hwnd, SW_RESTORE); + } + } else + { ShowWindow(hwnd, SW_HIDE); + } UpdateWindow(hwnd); #elif defined(DISTRHO_OS_MAC) if (yesNo) { if (mWindow != nullptr) + { + if (mParentWindow != nullptr) + [mParentWindow addChildWindow:mWindow + ordered:NSWindowAbove]; + [mWindow setIsVisible:YES]; + } else + { [mView setHidden:NO]; + } } else { if (mWindow != nullptr) + { + if (mParentWindow != nullptr) + [mParentWindow removeChildWindow:mWindow]; + [mWindow setIsVisible:NO]; + } else + { [mView setHidden:YES]; + } } #else if (yesNo) @@ -626,14 +655,14 @@ struct Window::PrivateData { DISTRHO_SAFE_ASSERT_RETURN(winId != 0,); #if defined(DISTRHO_OS_WINDOWS) - // TODO + hwndParent = (HWND)winId; + SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)winId); #elif defined(DISTRHO_OS_MAC) - NSWindow* const window = [NSApp windowWithWindowNumber:winId]; - DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,); + NSWindow* const parentWindow = [NSApp windowWithWindowNumber:winId]; + DISTRHO_SAFE_ASSERT_RETURN(parentWindow != nullptr,); - [window addChildWindow:mWindow - ordered:NSWindowAbove]; - [mWindow makeKeyWindow]; + [parentWindow addChildWindow:mWindow + ordered:NSWindowAbove]; #else XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); #endif @@ -984,11 +1013,13 @@ struct Window::PrivateData { } fModal; #if defined(DISTRHO_OS_WINDOWS) - HWND hwnd; + HWND hwnd; + HWND hwndParent; #elif defined(DISTRHO_OS_MAC) bool fNeedsIdle; PuglOpenGLView* mView; id mWindow; + id mParentWindow; #else Display* xDisplay; ::Window xWindow; diff --git a/source/modules/rtmidi/RtMidi.cpp b/source/modules/rtmidi/RtMidi.cpp index a3c9dcd85..b9b323732 100644 --- a/source/modules/rtmidi/RtMidi.cpp +++ b/source/modules/rtmidi/RtMidi.cpp @@ -931,7 +931,7 @@ void MidiOutCore :: initialize( const std::string& clientName ) OSStatus result = MIDIClientCreate(name, NULL, NULL, &client ); if ( result != noErr ) { std::ostringstream ost; - ost << "MidiInCore::initialize: error creating OS-X MIDI client object (" << result << ")."; + ost << "MidiOutCore::initialize: error creating OS-X MIDI client object (" << result << ")."; errorString_ = ost.str(); error( RtMidiError::DRIVER_ERROR, errorString_ ); return; diff --git a/source/native-plugins/_all.all.c b/source/native-plugins/_all.all.c index fd3043c40..1d102bca7 100644 --- a/source/native-plugins/_all.all.c +++ b/source/native-plugins/_all.all.c @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,7 +19,6 @@ #include "CarlaNative.h" #ifdef CARLA_OS_WIN -# define DISABLE_PLUGINS_FOR_WINDOWS_BUILD # undef HAVE_PYQT #endif diff --git a/source/native-plugins/_all.base.c b/source/native-plugins/_all.base.c index 44edcc844..24f80c4a8 100644 --- a/source/native-plugins/_all.base.c +++ b/source/native-plugins/_all.base.c @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,7 +19,6 @@ #include "CarlaNative.h" #ifdef CARLA_OS_WIN -# define DISABLE_PLUGINS_FOR_WINDOWS_BUILD # undef HAVE_PYQT #endif diff --git a/source/native-plugins/_data.all.cpp b/source/native-plugins/_data.all.cpp index f0380acdb..ecbf9fac6 100644 --- a/source/native-plugins/_data.all.cpp +++ b/source/native-plugins/_data.all.cpp @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,7 +20,6 @@ #include "CarlaUtils.hpp" #ifdef CARLA_OS_WIN -# define DISABLE_PLUGINS_FOR_WINDOWS_BUILD # undef HAVE_PYQT #endif diff --git a/source/native-plugins/_data.base.cpp b/source/native-plugins/_data.base.cpp index 37056c40d..0956d3514 100644 --- a/source/native-plugins/_data.base.cpp +++ b/source/native-plugins/_data.base.cpp @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,7 +20,6 @@ #include "CarlaUtils.hpp" #ifdef CARLA_OS_WIN -# define DISABLE_PLUGINS_FOR_WINDOWS_BUILD # undef HAVE_PYQT #endif diff --git a/source/native-plugins/external/Makefile b/source/native-plugins/external/Makefile index 3205b7598..6a31bf2c6 100644 --- a/source/native-plugins/external/Makefile +++ b/source/native-plugins/external/Makefile @@ -35,8 +35,12 @@ OBJS_all += \ ifeq ($(HAVE_ZYN_DEPS),true) OBJS_all += \ $(OBJDIR)/zynaddsubfx-fx.cpp.o \ - $(OBJDIR)/zynaddsubfx-src.cpp.o \ + $(OBJDIR)/zynaddsubfx-src.cpp.o + +ifneq ($(SKIP_ZYN_SYNTH),true) +OBJS_all += \ $(OBJDIR)/zynaddsubfx-synth.cpp.o +endif ifeq ($(HAVE_ZYN_UI_DEPS),true) TARGETS += resources/zynaddsubfx-ui$(APP_EXT) diff --git a/source/native-plugins/external/Makefile.mk b/source/native-plugins/external/Makefile.mk index 74b0cd86a..36e9123a7 100644 --- a/source/native-plugins/external/Makefile.mk +++ b/source/native-plugins/external/Makefile.mk @@ -12,6 +12,7 @@ endif ifeq ($(MACOS_OR_WIN32),true) HAVE_DGL = true +SKIP_ZYN_SYNTH = true else HAVE_DGL = $(shell pkg-config --exists gl x11 && echo true) endif @@ -98,7 +99,9 @@ endif DPF_FLAGS = -I$(CWDE)/modules/distrho ifeq ($(HAVE_DGL),true) +ifneq ($(MACOS_OR_WIN32),true) DPF_FLAGS += $(shell pkg-config --cflags gl) +endif DPF_FLAGS += -I$(CWDE)/modules/dgl -DDGL_NAMESPACE=CarlaDGL -DDGL_FILE_BROWSER_DISABLED -DDGL_NO_SHARED_RESOURCES endif @@ -123,6 +126,9 @@ ZYN_DSP_FLAGS += $(shell pkg-config --cflags fftw3 zlib) ZYN_DSP_LIBS = $(ZYN_BASE_LIBS) ZYN_DSP_LIBS += $(shell pkg-config --libs fftw3 zlib) +ifeq ($(SKIP_ZYN_SYNTH),true) +BASE_FLAGS += -DSKIP_ZYN_SYNTH +else # UI flags ifeq ($(HAVE_ZYN_UI_DEPS),true) @@ -154,6 +160,7 @@ else # HAVE_ZYN_UI_DEPS ZYN_DSP_FLAGS += -DNO_UI +endif # SKIP_ZYN_SYNTH endif # HAVE_ZYN_UI_DEPS endif # HAVE_ZYN_DEPS diff --git a/source/native-plugins/external/_all.c b/source/native-plugins/external/_all.c index 2bd3e300f..bd096fdd1 100644 --- a/source/native-plugins/external/_all.c +++ b/source/native-plugins/external/_all.c @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -62,7 +62,7 @@ void carla_register_all_native_external_plugins(void) #ifdef HAVE_ZYN_DEPS // ZynAddSubFX carla_register_native_plugin_zynaddsubfx_fx(); -# ifndef DISABLE_PLUGINS_FOR_WINDOWS_BUILD +# ifndef SKIP_ZYN_SYNTH carla_register_native_plugin_zynaddsubfx_synth(); # endif #endif diff --git a/source/native-plugins/external/_data.cpp b/source/native-plugins/external/_data.cpp index 6e71e7198..9e20f6a36 100644 --- a/source/native-plugins/external/_data.cpp +++ b/source/native-plugins/external/_data.cpp @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2017 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -356,7 +356,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* copyright */ "GNU GPL v2+", DESCFUNCS }, -# ifndef DISABLE_PLUGINS_FOR_WINDOWS_BUILD +# ifndef SKIP_ZYN_SYNTH { /* category */ NATIVE_PLUGIN_CATEGORY_SYNTH, /* hints */ static_cast(NATIVE_PLUGIN_IS_SYNTH @@ -381,7 +381,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* copyright */ "GNU GPL v2+", DESCFUNCS }, -# endif // ! DISABLE_PLUGINS_FOR_WINDOWS_BUILD +# endif // ! SKIP_ZYN_SYNTH #endif // HAVE_ZYN_DEPS // -------------------------------------------------------------------------------------------------------------------- diff --git a/source/native-plugins/zynaddsubfx-src.cpp b/source/native-plugins/zynaddsubfx-src.cpp index 31414c0fc..4161ba34b 100644 --- a/source/native-plugins/zynaddsubfx-src.cpp +++ b/source/native-plugins/zynaddsubfx-src.cpp @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2016 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,16 +26,28 @@ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Winconsistent-missing-override" # pragma clang diagnostic ignored "-Wunused-private-field" -#elif defined(__GNUC__) && (__GNUC__ >= 6) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) # pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wshift-negative-value" -# pragma GCC diagnostic ignored "-Wmisleading-indentation" +# pragma GCC diagnostic ignored "-Wliteral-suffix" +# if __GNUC__ >= 6 +# pragma GCC diagnostic ignored "-Wshift-negative-value" +# pragma GCC diagnostic ignored "-Wmisleading-indentation" +# endif #endif // base c-style headers #include "zynaddsubfx/tlsf/tlsf.h" #include "zynaddsubfx/rtosc/rtosc.h" +#ifdef SKIP_ZYN_SYNTH +# define PRId64 P_INT64 +# define PRIi64 P_INT64 +# define PRIx64 P_UINT64 +# define PRId32 "%d" +# define PRIi32 "%i" +# define PRIx32 "%x" +#endif + // C-code includes extern "C" { #include "zynaddsubfx/tlsf/tlsf.c" @@ -53,6 +65,9 @@ extern "C" { #include "zynaddsubfx/rtosc/dispatch.c" #include "zynaddsubfx/rtosc/rtosc.c" +#ifdef CARLA_OS_WIN +# include "zynaddsubfx/rtosc/pretty-format.c" +#endif } // rtosc includes @@ -71,6 +86,7 @@ extern "C" { // zynaddsubfx includes #include "zynaddsubfx/version.cpp" +#ifndef SKIP_ZYN_SYNTH #include "zynaddsubfx/Containers/MultiPseudoStack.cpp" #undef rBegin #undef rObject @@ -95,7 +111,9 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/AnalogFilter.cpp" +#include "zynaddsubfx/Misc/Bank.cpp" +#undef INSTRUMENT_EXTENSION +#undef FORCE_BANK_DIR_FILE #undef rBegin #undef rObject #undef rStdString @@ -103,7 +121,9 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/FFTwrapper.cpp" +#define INSTRUMENT_EXTENSION INSTRUMENT_EXTENSION_DB +#include "zynaddsubfx/Misc/BankDb.cpp" +#undef INSTRUMENT_EXTENSION #undef rBegin #undef rObject #undef rStdString @@ -111,7 +131,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/Filter.cpp" +#include "zynaddsubfx/Misc/CallbackRepeater.cpp" #undef rBegin #undef rObject #undef rStdString @@ -119,7 +139,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/FormantFilter.cpp" +#include "zynaddsubfx/Misc/Config.cpp" #undef rBegin #undef rObject #undef rStdString @@ -127,15 +147,15 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/SVFilter.cpp" -#undef rBegin +#include "zynaddsubfx/Misc/Master.cpp" #undef rObject #undef rStdString #undef rStdStringCb #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/DSP/Unison.cpp" +#include "zynaddsubfx/Misc/Microtonal.cpp" +#undef MAX_LINE_SIZE #undef rBegin #undef rObject #undef rStdString @@ -143,7 +163,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Alienwah.cpp" +#include "zynaddsubfx/Misc/MiddleWare.cpp" #undef rBegin #undef rObject #undef rStdString @@ -151,7 +171,8 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Chorus.cpp" +#include "zynaddsubfx/Misc/Part.cpp" +#undef CLONE #undef rBegin #undef rObject #undef rStdString @@ -159,7 +180,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Distorsion.cpp" +#include "zynaddsubfx/Misc/PresetExtractor.cpp" #undef rBegin #undef rObject #undef rStdString @@ -167,7 +188,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/DynamicFilter.cpp" +#include "zynaddsubfx/Misc/Recorder.cpp" #undef rBegin #undef rObject #undef rStdString @@ -175,8 +196,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Echo.cpp" -#undef MAX_DELAY +#include "zynaddsubfx/Misc/WavFile.cpp" #undef rBegin #undef rObject #undef rStdString @@ -184,7 +204,8 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Effect.cpp" +#include "zynaddsubfx/Params/ADnoteParameters.cpp" +#undef EXPAND #undef rBegin #undef rObject #undef rStdString @@ -192,7 +213,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/EffectLFO.cpp" +#include "zynaddsubfx/Params/Controller.cpp" #undef rBegin #undef rObject #undef rStdString @@ -200,7 +221,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/EffectMgr.cpp" +#include "zynaddsubfx/Params/EnvelopeParams.cpp" #undef rBegin #undef rObject #undef rStdString @@ -208,7 +229,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/EQ.cpp" +#include "zynaddsubfx/Params/LFOParams.cpp" #undef rBegin #undef rObject #undef rStdString @@ -216,10 +237,9 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Phaser.cpp" -#undef PHASER_LFO_SHAPE -#undef ONE_ -#undef ZERO_ +#include "zynaddsubfx/Params/PADnoteParameters.cpp" +#undef PC +#undef P_C #undef rBegin #undef rObject #undef rStdString @@ -227,7 +247,9 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Effects/Reverb.cpp" +#include "zynaddsubfx/Params/SUBnoteParameters.cpp" +#undef doPaste +#undef doPPaste #undef rBegin #undef rObject #undef rStdString @@ -235,7 +257,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Allocator.cpp" +#include "zynaddsubfx/Synth/ADnote.cpp" #undef rBegin #undef rObject #undef rStdString @@ -243,9 +265,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Bank.cpp" -#undef INSTRUMENT_EXTENSION -#undef FORCE_BANK_DIR_FILE +#include "zynaddsubfx/Synth/Envelope.cpp" #undef rBegin #undef rObject #undef rStdString @@ -253,9 +273,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#define INSTRUMENT_EXTENSION INSTRUMENT_EXTENSION_DB -#include "zynaddsubfx/Misc/BankDb.cpp" -#undef INSTRUMENT_EXTENSION +#include "zynaddsubfx/Synth/LFO.cpp" #undef rBegin #undef rObject #undef rStdString @@ -263,7 +281,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/CallbackRepeater.cpp" +#include "zynaddsubfx/Synth/ModFilter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -271,7 +289,13 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Config.cpp" +#include "zynaddsubfx/Synth/OscilGen.cpp" +#undef PC +#undef DIFF +#undef PRESERVE +#undef RESTORE +#undef FUNC +#undef FILTER #undef rBegin #undef rObject #undef rStdString @@ -279,15 +303,15 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Master.cpp" +#include "zynaddsubfx/Synth/PADnote.cpp" +#undef rBegin #undef rObject #undef rStdString #undef rStdStringCb #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Microtonal.cpp" -#undef MAX_LINE_SIZE +#include "zynaddsubfx/Synth/Resonance.cpp" #undef rBegin #undef rObject #undef rStdString @@ -295,7 +319,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/MiddleWare.cpp" +#include "zynaddsubfx/Synth/SUBnote.cpp" #undef rBegin #undef rObject #undef rStdString @@ -303,8 +327,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Part.cpp" -#undef CLONE +#include "zynaddsubfx/Synth/SynthNote.cpp" #undef rBegin #undef rObject #undef rStdString @@ -312,7 +335,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/PresetExtractor.cpp" +#include "zynaddsubfx/Synth/WatchPoint.cpp" #undef rBegin #undef rObject #undef rStdString @@ -320,7 +343,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Recorder.cpp" +#include "zynaddsubfx/UI/ConnectionDummy.cpp" #undef rBegin #undef rObject #undef rStdString @@ -328,7 +351,10 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/Util.cpp" +#include "zynaddsubfx/globals.cpp" +#endif // ! SKIP_ZYN_SYNTH + +#include "zynaddsubfx/DSP/AnalogFilter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -336,7 +362,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/WavFile.cpp" +#include "zynaddsubfx/DSP/FFTwrapper.cpp" #undef rBegin #undef rObject #undef rStdString @@ -344,7 +370,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/WaveShapeSmps.cpp" +#include "zynaddsubfx/DSP/Filter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -352,7 +378,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Misc/XMLwrapper.cpp" +#include "zynaddsubfx/DSP/FormantFilter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -360,8 +386,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/ADnoteParameters.cpp" -#undef EXPAND +#include "zynaddsubfx/DSP/SVFilter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -369,7 +394,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/Controller.cpp" +#include "zynaddsubfx/DSP/Unison.cpp" #undef rBegin #undef rObject #undef rStdString @@ -377,7 +402,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/EnvelopeParams.cpp" +#include "zynaddsubfx/Effects/Alienwah.cpp" #undef rBegin #undef rObject #undef rStdString @@ -385,7 +410,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/FilterParams.cpp" +#include "zynaddsubfx/Effects/Chorus.cpp" #undef rBegin #undef rObject #undef rStdString @@ -393,7 +418,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/LFOParams.cpp" +#include "zynaddsubfx/Effects/Distorsion.cpp" #undef rBegin #undef rObject #undef rStdString @@ -401,9 +426,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/PADnoteParameters.cpp" -#undef PC -#undef P_C +#include "zynaddsubfx/Effects/DynamicFilter.cpp" #undef rBegin #undef rObject #undef rStdString @@ -411,7 +434,8 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/Presets.cpp" +#include "zynaddsubfx/Effects/Echo.cpp" +#undef MAX_DELAY #undef rBegin #undef rObject #undef rStdString @@ -419,7 +443,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/PresetsArray.cpp" +#include "zynaddsubfx/Effects/Effect.cpp" #undef rBegin #undef rObject #undef rStdString @@ -427,7 +451,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/PresetsStore.cpp" +#include "zynaddsubfx/Effects/EffectLFO.cpp" #undef rBegin #undef rObject #undef rStdString @@ -435,9 +459,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Params/SUBnoteParameters.cpp" -#undef doPaste -#undef doPPaste +#include "zynaddsubfx/Effects/EffectMgr.cpp" #undef rBegin #undef rObject #undef rStdString @@ -445,7 +467,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/ADnote.cpp" +#include "zynaddsubfx/Effects/EQ.cpp" #undef rBegin #undef rObject #undef rStdString @@ -453,7 +475,10 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/Envelope.cpp" +#include "zynaddsubfx/Effects/Phaser.cpp" +#undef PHASER_LFO_SHAPE +#undef ONE_ +#undef ZERO_ #undef rBegin #undef rObject #undef rStdString @@ -461,7 +486,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/LFO.cpp" +#include "zynaddsubfx/Effects/Reverb.cpp" #undef rBegin #undef rObject #undef rStdString @@ -469,7 +494,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/ModFilter.cpp" +#include "zynaddsubfx/Misc/Allocator.cpp" #undef rBegin #undef rObject #undef rStdString @@ -477,13 +502,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/OscilGen.cpp" -#undef PC -#undef DIFF -#undef PRESERVE -#undef RESTORE -#undef FUNC -#undef FILTER +#include "zynaddsubfx/Misc/Util.cpp" #undef rBegin #undef rObject #undef rStdString @@ -491,7 +510,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/PADnote.cpp" +#include "zynaddsubfx/Misc/WaveShapeSmps.cpp" #undef rBegin #undef rObject #undef rStdString @@ -499,7 +518,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/Resonance.cpp" +#include "zynaddsubfx/Misc/XMLwrapper.cpp" #undef rBegin #undef rObject #undef rStdString @@ -507,7 +526,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/SUBnote.cpp" +#include "zynaddsubfx/Params/FilterParams.cpp" #undef rBegin #undef rObject #undef rStdString @@ -515,7 +534,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/SynthNote.cpp" +#include "zynaddsubfx/Params/Presets.cpp" #undef rBegin #undef rObject #undef rStdString @@ -523,7 +542,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/Synth/WatchPoint.cpp" +#include "zynaddsubfx/Params/PresetsArray.cpp" #undef rBegin #undef rObject #undef rStdString @@ -531,7 +550,7 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/UI/ConnectionDummy.cpp" +#include "zynaddsubfx/Params/PresetsStore.cpp" #undef rBegin #undef rObject #undef rStdString @@ -539,14 +558,13 @@ extern "C" { #undef rChangeCb #define rChangeCb -#include "zynaddsubfx/globals.cpp" - #if defined(__clang__) # pragma clang diagnostic pop #elif defined(__GNUC__) && (__GNUC__ >= 6) # pragma GCC diagnostic pop #endif +#ifndef SKIP_ZYN_SYNTH // Dummy variables and functions for linking purposes namespace zyncarla { class WavFile; @@ -563,3 +581,18 @@ namespace Nio { void waveStop(){} } } +#endif // ! SKIP_ZYN_SYNTH + +#ifdef CARLA_OS_WIN +rtosc_version rtosc_current_version() +{ + return ((rtosc_version) { 0, 0, 0 } ); +} + +void rtosc_version_print_to_12byte_str(const rtosc_version* v, + char* _12bytes) +{ + snprintf(_12bytes, 12, "%u.%u.%u", + (unsigned)v->major, (unsigned)v->minor, (unsigned)v->revision); +} +#endif diff --git a/source/native-plugins/zynaddsubfx/rtosc/pretty-format.c b/source/native-plugins/zynaddsubfx/rtosc/pretty-format.c index a34ed3512..529c0128a 100644 --- a/source/native-plugins/zynaddsubfx/rtosc/pretty-format.c +++ b/source/native-plugins/zynaddsubfx/rtosc/pretty-format.c @@ -23,8 +23,8 @@ static int asnprintf(char* str, size_t size, const char* format, ...) return written; } -static const rtosc_print_options* default_print_options - = &((rtosc_print_options) { true, 2, " ", 80}); +static const rtosc_print_options default_print_options + = ((rtosc_print_options) { true, 2, " ", 80}); /** * Return the char that represents the escape sequence @@ -73,7 +73,7 @@ size_t rtosc_print_arg_val(const rtosc_arg_val_t *arg, { size_t wrt = 0; if(!opt) - opt = default_print_options; + opt = &default_print_options; assert(arg); const rtosc_arg_t* val = &arg->val; @@ -301,7 +301,7 @@ size_t rtosc_print_arg_vals(const rtosc_arg_val_t *args, size_t n, size_t wrt=0; int args_written_this_line = (cols_used) ? 1 : 0; if(!opt) - opt = default_print_options; + opt = &default_print_options; size_t sep_len = strlen(opt->sep); char* last_sep = buffer - 1; for(size_t i = 0; i < n; ++i) diff --git a/source/plugin/Makefile b/source/plugin/Makefile index 0466d95f8..eb62aa1d4 100644 --- a/source/plugin/Makefile +++ b/source/plugin/Makefile @@ -81,6 +81,12 @@ LINK_FLAGS += $(LINUXSAMPLER_LIBS) LINK_FLAGS += $(MAGIC_LIBS) LINK_FLAGS += $(X11_LIBS) +ifeq ($(MACOS),true) +# NOTE: this assumes only LV2 version will be built +SHARED += -Wl,-exported_symbol,_lv2_descriptor +SHARED += -Wl,-exported_symbol,_lv2ui_descriptor +endif + # ---------------------------------------------------------------------------------------------------------------------------- TARGETS = \ diff --git a/source/utils/CarlaPluginUI.cpp b/source/utils/CarlaPluginUI.cpp index 722bbc4b7..8dffcdaa4 100644 --- a/source/utils/CarlaPluginUI.cpp +++ b/source/utils/CarlaPluginUI.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin UI - * Copyright (C) 2014-2017 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -33,6 +33,10 @@ # include #endif +#ifndef CARLA_PLUGIN_UI_CLASS_PREFIX +# error CARLA_PLUGIN_UI_CLASS_PREFIX undefined +#endif + // --------------------------------------------------------------------------------------------------------------------- // X11 @@ -359,6 +363,12 @@ private: #ifdef CARLA_OS_MAC +#ifdef BUILD_BRIDGE +# define CarlaPluginWindow CARLA_JOIN_MACRO(CarlaPluginWindowBridged, CARLA_PLUGIN_UI_CLASS_PREFIX) +#else +# define CarlaPluginWindow CARLA_JOIN_MACRO(CarlaPluginWindow, CARLA_PLUGIN_UI_CLASS_PREFIX) +#endif + @interface CarlaPluginWindow : NSWindow { @public @@ -443,8 +453,7 @@ public: CocoaPluginUI(Callback* const cb, const uintptr_t parentId, const bool isResizable) noexcept : CarlaPluginUI(cb, isResizable), fView(nullptr), - fWindow(0), - fParentId(parentId) + fWindow(0) { [NSAutoreleasePool new]; [NSApplication sharedApplication]; @@ -495,9 +504,6 @@ public: [fView setHidden:NO]; [fWindow setIsVisible:YES]; - - if (fParentId != 0) - setTransientWinId(fParentId); } void hide() override @@ -559,12 +565,11 @@ public: { CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); - NSWindow* window = [NSApp windowWithWindowNumber:winId]; - CARLA_SAFE_ASSERT_RETURN(window != nullptr,); + NSWindow* const parentWindow = [NSApp windowWithWindowNumber:winId]; + CARLA_SAFE_ASSERT_RETURN(parentWindow != nullptr,); - [window addChildWindow:fWindow - ordered:NSWindowAbove]; - [fWindow makeKeyWindow]; + [parentWindow addChildWindow:fWindow + ordered:NSWindowAbove]; } void setChildWindow(void* const winId) override @@ -585,7 +590,6 @@ public: private: NSView* fView; id fWindow; - uintptr_t fParentId; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CocoaPluginUI) }; @@ -606,7 +610,8 @@ class WindowsPluginUI : public CarlaPluginUI public: WindowsPluginUI(Callback* const cb, const uintptr_t parentId, const bool isResizable) noexcept : CarlaPluginUI(cb, isResizable), - fWindow(0), + fWindow(nullptr), + fParentWindow(nullptr), fIsVisible(false), fFirstShow(true) { @@ -675,9 +680,31 @@ public: { CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); - ShowWindow(fWindow, fFirstShow ? SW_SHOWNORMAL : SW_RESTORE); + if (fFirstShow) + { + fFirstShow = false; + RECT rectChild, rectParent; + + if (fParentWindow != nullptr && + GetWindowRect(fWindow, &rectChild) && + GetWindowRect(fParentWindow, &rectParent)) + { + SetWindowPos(fWindow, fParentWindow, + rectParent.left + (rectChild.right-rectChild.left)/2, + rectParent.top + (rectChild.bottom-rectChild.top)/2, + 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); + } + else + { + ShowWindow(fWindow, SW_SHOWNORMAL); + } + } + else + { + ShowWindow(fWindow, SW_RESTORE); + } + fIsVisible = true; - fFirstShow = false; UpdateWindow(fWindow); } @@ -769,7 +796,8 @@ public: { CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); - // TODO + fParentWindow = (HWND)winId; + SetWindowLongPtr(fWindow, GWLP_HWNDPARENT, (LONG_PTR)winId); } void setChildWindow(void* const winId) override @@ -789,6 +817,7 @@ public: private: HWND fWindow; + HWND fParentWindow; WNDCLASS fWindowClass; bool fIsVisible; @@ -824,6 +853,7 @@ LRESULT CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // ----------------------------------------------------- +#ifndef BUILD_BRIDGE bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* const uiTitle, const uintptr_t winId, const bool centerUI) { CARLA_SAFE_ASSERT_RETURN(uiTitle != nullptr && uiTitle[0] != '\0', true); @@ -1028,11 +1058,90 @@ bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* cons XFlush(sd.display); return true; -#else +#endif + +#ifdef CARLA_OS_MAC + uint const hints = kCGWindowListOptionOnScreenOnly|kCGWindowListExcludeDesktopElements; + + CFArrayRef const windowListRef = CGWindowListCopyWindowInfo(hints, kCGNullWindowID); + const NSArray* const windowList = (const NSArray*)windowListRef; + + int windowToMap, windowWithPID = 0, windowWithNameAndPID = 0; + + for (NSDictionary* const entry in windowList) + { + if ([entry[(id)kCGWindowSharingState] intValue] == kCGWindowSharingNone) + continue; + + NSString* const windowName = entry[(id)kCGWindowName]; + int const windowNumber = [entry[(id)kCGWindowNumber] intValue]; + uintptr_t const windowPID = [entry[(id)kCGWindowOwnerPID] intValue]; + + if (windowPID != pid) + continue; + + windowWithPID = windowNumber; + + if (windowName != nullptr && std::strcmp([windowName UTF8String], uiTitle) == 0) + windowWithNameAndPID = windowNumber; + } + + CFRelease(windowListRef); + + if (windowWithNameAndPID != 0) + { + carla_stdout("Match found using pid and name"); + windowToMap = windowWithNameAndPID; + } + else if (windowWithPID != 0) + { + carla_stdout("Match found using pid"); + windowToMap = windowWithPID; + } + else + { + return false; + } + + NSWindow* const parentWindow = [NSApp windowWithWindowNumber:winId]; + CARLA_SAFE_ASSERT_RETURN(parentWindow != nullptr, false); + + [parentWindow orderWindow:NSWindowBelow + relativeTo:windowToMap]; return true; - (void)pid; (void)centerUI; #endif + +#ifdef CARLA_OS_WIN + if (HWND const childWindow = FindWindowA(nullptr, uiTitle)) + { + HWND const parentWindow = (HWND)winId; + SetWindowLongPtr(childWindow, GWLP_HWNDPARENT, (LONG_PTR)parentWindow); + + if (centerUI) + { + RECT rectChild, rectParent; + + if (GetWindowRect(childWindow, &rectChild) && GetWindowRect(parentWindow, &rectParent)) + { + SetWindowPos(childWindow, parentWindow, + rectParent.left + (rectChild.right-rectChild.left)/2, + rectParent.top + (rectChild.bottom-rectChild.top)/2, + 0, 0, SWP_NOSIZE); + } + } + + carla_stdout("Match found using window name"); + return true; + } + + return false; +#endif + + // fallback, may be unused + return true; + (void)pid; (void)centerUI; } +#endif // BUILD_BRIDGE // ----------------------------------------------------- diff --git a/source/utils/CarlaPluginUI.hpp b/source/utils/CarlaPluginUI.hpp index 19996aeb3..32d794899 100644 --- a/source/utils/CarlaPluginUI.hpp +++ b/source/utils/CarlaPluginUI.hpp @@ -1,6 +1,6 @@ /* * Carla Plugin UI - * Copyright (C) 2014 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -46,7 +46,9 @@ public: virtual void* getDisplay() const noexcept = 0; #endif +#ifndef BUILD_BRIDGE static bool tryTransientWinIdMatch(const uintptr_t pid, const char* const uiTitle, const uintptr_t winId, const bool centerUI); +#endif #ifdef CARLA_OS_MAC static CarlaPluginUI* newCocoa(Callback*, uintptr_t, bool);