diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe0974787..c2c79a69b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,8 +43,9 @@ jobs: strategy: matrix: include: - - target: macos-12 - target: macos-13 + - target: macos-14 + - target: macos-15 runs-on: ${{ matrix.target }} steps: - uses: actions/checkout@v4 @@ -59,7 +60,7 @@ jobs: run: make -j $(sysctl -n hw.logicalcpu) wasm: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: @@ -70,7 +71,7 @@ jobs: with: path: | ~/emsdk - key: emsdk-v1 + key: emsdk-v2 - name: Set up dependencies run: | [ -d ~/emsdk ] || git clone https://github.com/emscripten-core/emsdk.git ~/emsdk diff --git a/.github/workflows/dpf.yml b/.github/workflows/dpf.yml index ca06fdf2e..d8b0abac2 100644 --- a/.github/workflows/dpf.yml +++ b/.github/workflows/dpf.yml @@ -28,7 +28,7 @@ jobs: strategy: matrix: target: [macos-intel, macos-universal, macos-universal-10.15] - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 000000000..5ced74093 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,50 @@ +name: pylint + +on: [push] + +jobs: + pyqt5: + runs-on: ubuntu-24.04 + name: pyqt5 + steps: + - uses: actions/checkout@v3 + - name: Install deps + run: | + sudo apt install -yqq pyqt5-dev-tools python3-pyqt5 python3-pyqt5.qtsvg python3-virtualenv + virtualenv carla-env + source carla-env/bin/activate + pip3 install pylint pyqt5 + - name: Build frontend + run: | + make FRONTEND_TYPE=5 frontend -j $(nproc) + - name: Run pylint + run: | + virtualenv carla-env + source carla-env/bin/activate + pylint -E --extension-pkg-whitelist=PyQt5 source/frontend/carla_app.py + pylint -E --extension-pkg-whitelist=PyQt5 source/frontend/carla_backend.py + pylint -E --extension-pkg-whitelist=PyQt5 source/frontend/carla_shared.py + pylint -E --extension-pkg-whitelist=PyQt5 source/frontend/carla_utils.py + + pyqt6: + runs-on: ubuntu-24.04 + name: pyqt6 + steps: + - uses: actions/checkout@v3 + - name: Install deps + run: | + sudo apt install -yqq pyqt6-dev-tools python3-pyqt6 python3-pyqt6.qtsvg python3-virtualenv + virtualenv carla-env + source carla-env/bin/activate + pip3 install pylint pyqt6 + - name: Build frontend + run: | + make FRONTEND_TYPE=6 frontend -j $(nproc) + - name: Run pylint + run: | + virtualenv carla-env + source carla-env/bin/activate + pylint -E --extension-pkg-whitelist=PyQt6 source/frontend/carla_app.py + pylint -E --extension-pkg-whitelist=PyQt6 source/frontend/carla_backend.py + pylint -E --extension-pkg-whitelist=PyQt6 source/frontend/carla_shared.py + pylint -E --extension-pkg-whitelist=PyQt6 source/frontend/carla_utils.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 80091aa26..918d476cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,22 +3,20 @@ name: release on: [push, pull_request] env: - CACHE_VERSION: 1 + CACHE_VERSION: 4 DEBIAN_FRONTEND: noninteractive HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1 PAWPAW_SKIP_LTO: 1 PAWPAW_SKIP_TESTS: 1 - PAWPAW_VERSION: 9534e2b4f9bafc993e05fada89b824f3a2176708 + PAWPAW_VERSION: 2606d0d436471b12902d60edd2aeb2390db44e62 jobs: # macOS native universal build macos_universal: - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v4 - with: - submodules: recursive - name: Set up cache uses: actions/cache@v4 with: @@ -40,7 +38,7 @@ jobs: run: | source PawPaw/local.env macos-universal make features - make EXTERNAL_PLUGINS=false NOOPT=true ${MAKE_ARGS} + make NOOPT=true ${MAKE_ARGS} make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 @@ -62,39 +60,22 @@ jobs: # linux with win32 cross-compilation win32: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest + container: + image: ubuntu:22.04 steps: - uses: actions/checkout@v4 - with: - submodules: recursive - name: Set up cache uses: actions/cache@v4 with: path: | ~/PawPawBuilds key: win32-v${{ env.CACHE_VERSION }} - - name: Restore debian packages cache - run: | - if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ - sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ - fi - - name: Fix GitHub's mess - run: | - sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list - sudo dpkg --add-architecture i386 - sudo apt-get update -qq - sudo apt-get install -yqq --allow-downgrades libc6:i386 libgcc-s1:i386 libstdc++6:i386 - - name: Set up dependencies - run: | - sudo apt-get install -y build-essential curl cmake jq meson mingw-w64 gperf qttools5-dev qttools5-dev-tools xvfb \ - binutils-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64 wine-stable - - name: Cache debian packages - run: | - mkdir -p ~/PawPawBuilds/debs - sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win32 cross-compiled shell: bash run: | + apt-get update -qq + apt-get install -yqq git unzip zip git clone https://github.com/DISTRHO/PawPaw.git git -C PawPaw checkout ${{ env.PAWPAW_VERSION }} ./PawPaw/.github/workflows/bootstrap-deps.sh win32 @@ -104,7 +85,7 @@ jobs: run: | source PawPaw/local.env win32 make features - make EXTERNAL_PLUGINS=false NOOPT=true ${MAKE_ARGS} + make NOOPT=true ${MAKE_ARGS} make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 @@ -126,39 +107,22 @@ jobs: # linux with win64 cross-compilation win64: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest + container: + image: ubuntu:22.04 steps: - uses: actions/checkout@v4 - with: - submodules: recursive - name: Set up cache uses: actions/cache@v4 with: path: | ~/PawPawBuilds key: win64-v${{ env.CACHE_VERSION }} - - name: Restore debian packages cache - run: | - if [ -d ~/PawPawBuilds/debs ] && [ "$(ls ~/PawPawBuilds/debs | wc -l)" -ne 0 ]; then \ - sudo cp ~/PawPawBuilds/debs/*.deb /var/cache/apt/archives/; \ - fi - - name: Fix GitHub's mess - run: | - sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list - sudo dpkg --add-architecture i386 - sudo apt-get update -qq - sudo apt-get install -yqq --allow-downgrades libc6:i386 libgcc-s1:i386 libstdc++6:i386 - - name: Set up dependencies - run: | - sudo apt-get install -y build-essential curl cmake jq meson mingw-w64 gperf qttools5-dev qttools5-dev-tools xvfb \ - binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64 wine-stable - - name: Cache debian packages - run: | - mkdir -p ~/PawPawBuilds/debs - sudo mv /var/cache/apt/archives/*.deb ~/PawPawBuilds/debs/ - name: Bootstrap win64 cross-compiled shell: bash run: | + apt-get update -qq + apt-get install -yqq git unzip zip git clone https://github.com/DISTRHO/PawPaw.git git -C PawPaw checkout ${{ env.PAWPAW_VERSION }} ./PawPaw/.github/workflows/bootstrap-deps.sh win64 @@ -168,8 +132,8 @@ jobs: run: | source PawPaw/local.env win64 make features - make EXTERNAL_PLUGINS=false NOOPT=true ${MAKE_ARGS} - make EXTERNAL_PLUGINS=false NOOPT=true ${MAKE_ARGS} win32r + make NOOPT=true ${MAKE_ARGS} + make NOOPT=true ${MAKE_ARGS} win32r make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1 diff --git a/Makefile b/Makefile index 3d2359ed8..0f18d66e9 100644 --- a/Makefile +++ b/Makefile @@ -214,6 +214,11 @@ plugin-wine: else plugin-wine: $(MODULEDIR)/dgl.wine.a @$(MAKE) -C source/plugin wine +ifeq ($(CPU_X86_64),true) + @$(MAKE) plugin-wine AR=x86_64-w64-mingw32-ar CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ +else ifeq ($(CPU_I386),true) + @$(MAKE) plugin-wine AR=i686-w64-mingw32-ar CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ +endif endif rest: libs @@ -427,8 +432,6 @@ ifeq ($(HAVE_FRONTEND),true) install -d $(DESTDIR)$(DATADIR)/mime/packages install -d $(DESTDIR)$(DATADIR)/carla/resources/translations install -d $(DESTDIR)$(DATADIR)/carla/common - install -d $(DESTDIR)$(DATADIR)/carla/dialogs - install -d $(DESTDIR)$(DATADIR)/carla/modgui install -d $(DESTDIR)$(DATADIR)/carla/patchcanvas install -d $(DESTDIR)$(DATADIR)/carla/utils install -d $(DESTDIR)$(DATADIR)/carla/widgets @@ -511,7 +514,6 @@ endif source/backend/CarlaUtils.h \ source/backend/CarlaEngine.hpp \ source/backend/CarlaPlugin.hpp \ - source/backend/CarlaPluginPtr.hpp \ $(DESTDIR)$(INCLUDEDIR)/carla install -m 644 \ @@ -522,25 +524,6 @@ endif $(DESTDIR)$(INCLUDEDIR)/carla/includes install -m 644 \ - source/utils/CarlaBackendUtils.hpp \ - source/utils/CarlaBase64Utils.hpp \ - source/utils/CarlaBinaryUtils.hpp \ - source/utils/CarlaBridgeDefines.hpp \ - source/utils/CarlaBridgeUtils.hpp \ - source/utils/CarlaMacUtils.hpp \ - source/utils/CarlaMathUtils.hpp \ - source/utils/CarlaMemUtils.hpp \ - source/utils/CarlaMutex.hpp \ - source/utils/CarlaRingBuffer.hpp \ - source/utils/CarlaProcessUtils.hpp \ - source/utils/CarlaRunner.hpp \ - source/utils/CarlaScopeUtils.hpp \ - source/utils/CarlaSemUtils.hpp \ - source/utils/CarlaSha1Utils.hpp \ - source/utils/CarlaShmUtils.hpp \ - source/utils/CarlaString.hpp \ - source/utils/CarlaThread.hpp \ - source/utils/CarlaTimeUtils.hpp \ source/utils/CarlaUtils.hpp \ $(DESTDIR)$(INCLUDEDIR)/carla/utils @@ -582,14 +565,6 @@ ifeq ($(HAVE_LIBLO),true) $(DESTDIR)$(BINDIR)/carla-control endif - # Install the real modgui bridge - install -m 755 \ - data/carla-bridge-lv2-modgui \ - $(DESTDIR)$(LIBDIR)/carla - - sed $(SED_ARGS) 's?X-PREFIX-X?$(PREFIX)?' \ - $(DESTDIR)$(LIBDIR)/carla/carla-bridge-lv2-modgui - # Install frontend install -m 644 \ source/frontend/carla \ @@ -605,14 +580,6 @@ endif source/frontend/common/*.py \ $(DESTDIR)$(DATADIR)/carla/common/ - install -m 644 \ - source/frontend/dialogs/*.py \ - $(DESTDIR)$(DATADIR)/carla/dialogs/ - - install -m 644 \ - source/frontend/modgui/*.py \ - $(DESTDIR)$(DATADIR)/carla/modgui/ - install -m 644 \ source/frontend/patchcanvas/*.py \ $(DESTDIR)$(DATADIR)/carla/patchcanvas/ @@ -690,8 +657,6 @@ endif # Install resources (re-use python files) $(LINK) ../common $(DESTDIR)$(DATADIR)/carla/resources - $(LINK) ../dialogs $(DESTDIR)$(DATADIR)/carla/resources - $(LINK) ../modgui $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../patchcanvas $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../utils $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../widgets $(DESTDIR)$(DATADIR)/carla/resources @@ -799,16 +764,6 @@ ifeq ($(HAVE_FRONTEND),true) rm -rf $(DESTDIR)$(LIBDIR)/vst/carla.vst/styles $(LINK) ../../carla/styles $(DESTDIR)$(LIBDIR)/vst/carla.vst/styles endif -endif - - # ------------------------------------------------------------------------------------------------------------- - -ifneq ($(HAVE_FRONTEND),true) - # Remove gui files for non-gui build - rm $(DESTDIR)$(LIBDIR)/carla/carla-bridge-lv2-modgui -ifeq ($(CAN_GENERATE_LV2_TTL),true) - rm $(DESTDIR)$(LIBDIR)/lv2/carla.lv2/carla-bridge-lv2-modgui -endif endif # --------------------------------------------------------------------------------------------------------------------- diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 896789bf4..c4a730dde 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -184,6 +184,11 @@ function(set_common_target_properties TARGET) $<$:/wd4273> ) + target_include_directories(${TARGET} + PRIVATE + ../source/modules/distrho + ) + target_link_options(${TARGET} PRIVATE $<$:-Wl,--no-undefined> @@ -459,6 +464,7 @@ target_sources(carla-native-plugins ../source/native-plugins/bypass.c ../source/native-plugins/cv-to-audio.c ../source/native-plugins/lfo.c + ../source/native-plugins/quadpanner.c ../source/native-plugins/midi-channel-filter.c ../source/native-plugins/midi-channel-ab.c ../source/native-plugins/midi-channelize.c @@ -546,6 +552,7 @@ target_compile_options(carla-water target_include_directories(carla-water PRIVATE ../source/includes + ../source/modules ../source/utils ) @@ -581,6 +588,7 @@ target_compile_options(carla-water-files target_include_directories(carla-water-files PRIVATE ../source/includes + ../source/modules ../source/utils ) @@ -1228,7 +1236,6 @@ if(${CARLA_BUILD_FRAMEWORKS}) ../source/backend/CarlaHost.h ../source/backend/CarlaEngine.hpp ../source/backend/CarlaPlugin.hpp - ../source/backend/CarlaPluginPtr.hpp ) set_target_properties(carla-standalone @@ -1464,25 +1471,6 @@ if(${CARLA_BUILD_FRAMEWORKS}) DESTINATION ${CMAKE_INSTALL_LIBDIR}/carla-utils.framework/Versions/A/Headers/includes) install(FILES - ../source/utils/CarlaBackendUtils.hpp - ../source/utils/CarlaBase64Utils.hpp - ../source/utils/CarlaBinaryUtils.hpp - ../source/utils/CarlaBridgeDefines.hpp - ../source/utils/CarlaBridgeUtils.hpp - ../source/utils/CarlaMacUtils.hpp - ../source/utils/CarlaMathUtils.hpp - ../source/utils/CarlaMemUtils.hpp - ../source/utils/CarlaMutex.hpp - ../source/utils/CarlaRingBuffer.hpp - ../source/utils/CarlaProcessUtils.hpp - ../source/utils/CarlaRunner.hpp - ../source/utils/CarlaScopeUtils.hpp - ../source/utils/CarlaSemUtils.hpp - ../source/utils/CarlaSha1Utils.hpp - ../source/utils/CarlaShmUtils.hpp - ../source/utils/CarlaString.hpp - ../source/utils/CarlaThread.hpp - ../source/utils/CarlaTimeUtils.hpp ../source/utils/CarlaUtils.hpp DESTINATION ${CMAKE_INSTALL_LIBDIR}/carla-utils.framework/Versions/A/Headers/utils) @@ -1538,7 +1526,6 @@ set_property(TARGET carla-headers-backend ../source/backend/CarlaUtils.h ../source/backend/CarlaEngine.hpp ../source/backend/CarlaPlugin.hpp - ../source/backend/CarlaPluginPtr.hpp ) set_property(TARGET carla-headers-includes @@ -1551,25 +1538,6 @@ set_property(TARGET carla-headers-includes set_property(TARGET carla-headers-utils PROPERTY PUBLIC_HEADER - ../source/utils/CarlaBackendUtils.hpp - ../source/utils/CarlaBase64Utils.hpp - ../source/utils/CarlaBinaryUtils.hpp - ../source/utils/CarlaBridgeDefines.hpp - ../source/utils/CarlaBridgeUtils.hpp - ../source/utils/CarlaMacUtils.hpp - ../source/utils/CarlaMathUtils.hpp - ../source/utils/CarlaMemUtils.hpp - ../source/utils/CarlaMutex.hpp - ../source/utils/CarlaRingBuffer.hpp - ../source/utils/CarlaProcessUtils.hpp - ../source/utils/CarlaRunner.hpp - ../source/utils/CarlaScopeUtils.hpp - ../source/utils/CarlaSemUtils.hpp - ../source/utils/CarlaSha1Utils.hpp - ../source/utils/CarlaShmUtils.hpp - ../source/utils/CarlaString.hpp - ../source/utils/CarlaThread.hpp - ../source/utils/CarlaTimeUtils.hpp ../source/utils/CarlaUtils.hpp ) diff --git a/data/carla-bridge-lv2-modgui b/data/carla-bridge-lv2-modgui deleted file mode 100644 index ebe709ed1..000000000 --- a/data/carla-bridge-lv2-modgui +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -PYTHON=$(which python3 2>/dev/null) - -if [ ! -f ${PYTHON} ]; then - PYTHON=python -fi - -INSTALL_PREFIX="X-PREFIX-X" -export CARLA_LIB_PREFIX="$INSTALL_PREFIX" -exec $PYTHON "$INSTALL_PREFIX"/share/carla/carla_modgui.py "$@" diff --git a/data/macos/bundle.py b/data/macos/bundle.py index 472789ab4..d6955e805 100644 --- a/data/macos/bundle.py +++ b/data/macos/bundle.py @@ -10,7 +10,7 @@ from os import getenv # ------------------------------------------------------------------------------------------------------------ # Imports (Custom Stuff) -from carla_host import VERSION +from carla_backend import CARLA_VERSION_STRING # ------------------------------------------------------------------------------------------------------------ @@ -31,7 +31,7 @@ if SCRIPT_NAME in ("Carla", "Carla-Control"): boptions["custom_info_plist"] = "./data/macos/%s.plist" % SCRIPT_NAME setup(name = "Carla", - version = VERSION, + version = CARLA_VERSION_STRING, description = "Carla Plugin Host", options = {"build_exe": options, "bdist_mac": boptions}, executables = [Executable("./source/frontend/%s" % SCRIPT_NAME)]) diff --git a/data/update-dpf b/data/update-dpf index f2381e9e5..2b6a1288a 100755 --- a/data/update-dpf +++ b/data/update-dpf @@ -11,18 +11,23 @@ DPF_DIR=/tmp/dpf-carla rm -rf ${DPF_DIR} git clone git@github.com:DISTRHO/DPF.git ${DPF_DIR} --depth=1 --recursive -b develop -cp -v ${DPF_DIR}/dgl/*.hpp ${CARLA_DIR}/source/modules/dgl/ -cp -v ${DPF_DIR}/dgl/src/*.cpp ${CARLA_DIR}/source/modules/dgl/src/ -cp -v ${DPF_DIR}/dgl/src/*.hpp ${CARLA_DIR}/source/modules/dgl/src/ -cp -v ${DPF_DIR}/distrho/*.cpp ${CARLA_DIR}/source/modules/distrho/ -cp -v ${DPF_DIR}/distrho/*.hpp ${CARLA_DIR}/source/modules/distrho/ -cp -v ${DPF_DIR}/distrho/src/*.cpp ${CARLA_DIR}/source/modules/distrho/src/ -cp -v ${DPF_DIR}/distrho/src/*.hpp ${CARLA_DIR}/source/modules/distrho/src/ - +cp -v ${DPF_DIR}/dgl/*.hpp ${CARLA_DIR}/source/modules/dgl/ +cp -v ${DPF_DIR}/dgl/src/*.cpp ${CARLA_DIR}/source/modules/dgl/src/ +cp -v ${DPF_DIR}/dgl/src/*.hpp ${CARLA_DIR}/source/modules/dgl/src/ +cp -v ${DPF_DIR}/dgl/src/nanovg/*.* ${CARLA_DIR}/source/modules/dgl/src/nanovg/ +cp -v ${DPF_DIR}/distrho/*.cpp ${CARLA_DIR}/source/modules/distrho/ +cp -v ${DPF_DIR}/distrho/*.hpp ${CARLA_DIR}/source/modules/distrho/ +cp -v ${DPF_DIR}/distrho/src/*.cpp ${CARLA_DIR}/source/modules/distrho/src/ +cp -v ${DPF_DIR}/distrho/src/*.h ${CARLA_DIR}/source/modules/distrho/src/ +cp -v ${DPF_DIR}/distrho/src/*.hpp ${CARLA_DIR}/source/modules/distrho/src/ + +cp -v ${DPF_DIR}/distrho/extra/Base64.hpp ${CARLA_DIR}/source/modules/distrho/extra/ cp -v ${DPF_DIR}/distrho/extra/LeakDetector.hpp ${CARLA_DIR}/source/modules/distrho/extra/ cp -v ${DPF_DIR}/distrho/extra/ScopedPointer.hpp ${CARLA_DIR}/source/modules/distrho/extra/ cp -v ${DPF_DIR}/distrho/extra/ScopedSafeLocale.hpp ${CARLA_DIR}/source/modules/distrho/extra/ +cp -v ${DPF_DIR}/distrho/extra/Sleep.hpp ${CARLA_DIR}/source/modules/distrho/extra/ cp -v ${DPF_DIR}/distrho/extra/String.hpp ${CARLA_DIR}/source/modules/distrho/extra/ +cp -v ${DPF_DIR}/distrho/extra/Time.hpp ${CARLA_DIR}/source/modules/distrho/extra/ cp -r -v ${DPF_DIR}/dgl/src/pugl-upstream/include ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/ cp -r -v ${DPF_DIR}/dgl/src/pugl-upstream/src ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/ @@ -31,20 +36,25 @@ cp -r -v ${DPF_DIR}/dgl/src/pugl-upstream/COPYING ${CARLA_DIR}/source/modules/dg rm ${CARLA_DIR}/source/modules/dgl/Cairo.hpp rm ${CARLA_DIR}/source/modules/dgl/FileBrowserDialog.hpp +rm ${CARLA_DIR}/source/modules/dgl/Layout.hpp rm ${CARLA_DIR}/source/modules/dgl/Vulkan.hpp +rm ${CARLA_DIR}/source/modules/dgl/WebView.hpp rm ${CARLA_DIR}/source/modules/dgl/src/Cairo.cpp -rm ${CARLA_DIR}/source/modules/dgl/src/Vulkan.cpp +rm ${CARLA_DIR}/source/modules/dgl/src/Layout.cpp rm ${CARLA_DIR}/source/modules/dgl/src/Resources.{cpp,hpp} +rm ${CARLA_DIR}/source/modules/dgl/src/Stub.cpp +rm ${CARLA_DIR}/source/modules/dgl/src/Vulkan.cpp +rm ${CARLA_DIR}/source/modules/dgl/src/WebViewWin32.cpp -rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/src/.clang-tidy -rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/include/.clang-tidy rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/include/meson.build rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/include/pugl/cairo.h rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/include/pugl/vulkan.h +rm ${CARLA_DIR}/source/modules/dgl/src/pugl-upstream/src/.clang-tidy rm ${CARLA_DIR}/source/modules/distrho/DistrhoInfo.hpp -rm ${CARLA_DIR}/source/modules/distrho/src/DistrhoPlugin{JACK,LADSPA+DSSI,LV2,LV2export,VST2,VST3}.cpp +rm ${CARLA_DIR}/source/modules/distrho/DistrhoUI_win32.cpp +rm ${CARLA_DIR}/source/modules/distrho/src/DistrhoPlugin{AU,CLAP,Export,JACK,LADSPA+DSSI,LV2,LV2export,MAPI,Stub,VST2,VST3}.cpp rm ${CARLA_DIR}/source/modules/distrho/src/DistrhoPluginVST.hpp -rm ${CARLA_DIR}/source/modules/distrho/src/DistrhoUI{DSSI,LV2,VST3}.cpp +rm ${CARLA_DIR}/source/modules/distrho/src/DistrhoUI{DSSI,LV2,Stub,VST3}.cpp rm -rf ${DPF_DIR} diff --git a/data/update-juce b/data/update-juce deleted file mode 100755 index a03238dc1..000000000 --- a/data/update-juce +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -e - -cd $(dirname ${0}) -cd .. - -CARLA_DIR=$(pwd) -DISTRHO_PORTS_DIR=/tmp/distrho-ports-carla - -rm -rf ${DISTRHO_PORTS_DIR} -git clone git@github.com:DISTRHO/DISTRHO-Ports.git ${DISTRHO_PORTS_DIR} --depth=1 - -CARLA_MODULES_DIR=${CARLA_DIR}/source/modules -JUCE_MODULES_DIR=${DISTRHO_PORTS_DIR}/libs/juce7/source/modules - -MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_dsp juce_events juce_graphics juce_gui_basics juce_gui_extra") - -for M in ${MODULES}; do - echo ${CARLA_MODULES_DIR}/${M}; - rm -f ${CARLA_MODULES_DIR}/${M}/juce_* - rm -rf ${CARLA_MODULES_DIR}/${M}/{a..z}* - cp -r -v ${JUCE_MODULES_DIR}/${M}/* ${CARLA_MODULES_DIR}/${M}/ - rm ${CARLA_MODULES_DIR}/${M}/juce_*.mm -done - -find ${CARLA_MODULES_DIR} -name juce_module_info -delete - -rm -rf ${CARLA_MODULES_DIR}/../includes/vst3sdk -mv ${CARLA_MODULES_DIR}/juce_audio_processors/format_types/VST3_SDK ${CARLA_MODULES_DIR}/../includes/vst3sdk -rm -rf ${CARLA_MODULES_DIR}/../includes/vst3sdk/*.pdf - -# rm -rf ${DISTRHO_PORTS_DIR} diff --git a/data/windows/app-gui.py b/data/windows/app-gui.py index f06d8cd4a..8afa20f93 100644 --- a/data/windows/app-gui.py +++ b/data/windows/app-gui.py @@ -9,7 +9,7 @@ from cx_Freeze import setup, Executable # ------------------------------------------------------------------------------------------------------------ # Imports (Custom Stuff) -from carla_host import VERSION +from carla_backend import CARLA_VERSION_STRING from os import getenv # ------------------------------------------------------------------------------------------------------------ @@ -43,7 +43,7 @@ exe_options = { } setup(name = name, - version = VERSION, + version = CARLA_VERSION_STRING, description = description, options = {"build_exe": options}, executables = [Executable(**exe_options)]) diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui index 0e485507d..89c3c77a7 100644 --- a/resources/ui/carla_settings.ui +++ b/resources/ui/carla_settings.ui @@ -1444,9 +1444,6 @@ false - - Maximum number of parameters to allow in the built-in 'Edit' dialog - 1024 @@ -1515,9 +1512,6 @@ false - - Maximum number of parameters to allow in the built-in 'Edit' dialog - 1024 diff --git a/source/Makefile.mk b/source/Makefile.mk index 22aa5d319..c93840453 100644 --- a/source/Makefile.mk +++ b/source/Makefile.mk @@ -175,9 +175,6 @@ BASE_FLAGS += -DHAVE_DGL BASE_FLAGS += -DHAVE_OPENGL BASE_FLAGS += -DDGL_OPENGL BASE_FLAGS += -DDONT_SET_USING_DGL_NAMESPACE -ifeq ($(USING_CUSTOM_DPF),true) -BASE_FLAGS += -DDISTRHO_UI_FILE_BROWSER=0 -endif ifneq ($(DGL_NAMESPACE),) BASE_FLAGS += -DDGL_NAMESPACE=$(DGL_NAMESPACE) else @@ -185,9 +182,11 @@ BASE_FLAGS += -DDGL_NAMESPACE=CarlaDGL endif endif -ifneq ($(USING_CUSTOM_DPF),true) -BASE_FLAGS += -DDGL_FILE_BROWSER_DISABLED +ifeq ($(USING_CUSTOM_DPF),true) +BASE_FLAGS += -I$(CUSTOM_DPF_PATH)/distrho +else BASE_FLAGS += -DDGL_NO_SHARED_RESOURCES +BASE_FLAGS += -I$(CWD)/modules/distrho endif ifeq ($(HAVE_FLUIDSYNTH),true) diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index 33d9a51c4..ba0c66260 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -210,6 +210,11 @@ static constexpr const uint PLUGIN_HAS_CUSTOM_UI_USING_FILE_OPEN = 0x2000; */ static constexpr const uint PLUGIN_NEEDS_MAIN_THREAD_IDLE = 0x4000; +/*! + * Plugin has its own custom UI which is user resizable. + */ +static constexpr const uint PLUGIN_HAS_CUSTOM_RESIZABLE_UI = 0x8000; + /** @} */ /* ------------------------------------------------------------------------------------------------------------ diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 2b6e0b631..0ebd5ffbb 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -1,11 +1,11 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_ENGINE_HPP_INCLUDED #define CARLA_ENGINE_HPP_INCLUDED #include "CarlaBackend.h" -#include "CarlaPluginPtr.hpp" +#include "CarlaPlugin.hpp" namespace water { class MemoryOutputStream; diff --git a/source/backend/CarlaHostImpl.hpp b/source/backend/CarlaHostImpl.hpp index 24a885498..210a7a03f 100644 --- a/source/backend/CarlaHostImpl.hpp +++ b/source/backend/CarlaHostImpl.hpp @@ -20,13 +20,15 @@ #include "CarlaHost.h" #include "CarlaUtils.h" + #include "CarlaEngine.hpp" +#include "CarlaUtils.hpp" #if !(defined(BUILD_BRIDGE) || defined(CARLA_OS_WASM)) # define CARLA_CAN_USE_LOG_THREAD # include "CarlaLogThread.hpp" #else -# include "CarlaString.hpp" +# include "extra/String.hpp" #endif namespace CB = CARLA_BACKEND_NAMESPACE; @@ -64,7 +66,7 @@ struct CarlaHostStandalone : CarlaHostHandleImpl { bool logThreadEnabled; #endif - CarlaString lastError; + String lastError; CarlaHostStandalone() noexcept : CarlaHostHandleImpl(), diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 3dc5e0d1a..5ae7f50f7 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -1,11 +1,12 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_PLUGIN_HPP_INCLUDED #define CARLA_PLUGIN_HPP_INCLUDED #include "CarlaBackend.h" -#include "CarlaPluginPtr.hpp" + +#include // ----------------------------------------------------------------------- // Avoid including extra libs here @@ -37,9 +38,12 @@ class CarlaEngineCVPort; class CarlaEngineEventPort; class CarlaEngineCVSourcePorts; class CarlaEngineBridge; +class CarlaPlugin; struct CarlaStateSave; struct EngineEvent; +typedef std::shared_ptr CarlaPluginPtr; + // ----------------------------------------------------------------------- /*! diff --git a/source/backend/CarlaPluginPtr.hpp b/source/backend/CarlaPluginPtr.hpp deleted file mode 100644 index c69f3cc98..000000000 --- a/source/backend/CarlaPluginPtr.hpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2020 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#ifndef CARLA_CPP_COMPAT_HPP_INCLUDED -#define CARLA_CPP_COMPAT_HPP_INCLUDED - -#include "CarlaDefines.h" - -#ifdef CARLA_PROPER_CPP11_SUPPORT -# include -#else -# include -# include "CarlaUtils.hpp" -#endif - -// ----------------------------------------------------------------------- - -#ifndef CARLA_PROPER_CPP11_SUPPORT -namespace std { - -/* This code is part of shared_ptr.hpp: - * minimal implementation of smart pointer, a subset of the C++11 std::shared_ptr or boost::shared_ptr. - * Copyright (c) 2013-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com) - * Distributed under the MIT License (MIT) - */ -class shared_ptr_count -{ -public: - shared_ptr_count() : pn(nullptr) {} - shared_ptr_count(const shared_ptr_count& count) : pn(count.pn) {} - void swap(shared_ptr_count& lhs) noexcept { std::swap(pn, lhs.pn); } - - long use_count(void) const noexcept - { - long count = 0; - if (nullptr != pn) - { - count = *pn; - } - return count; - } - - template - void acquire(U* p) - { - if (nullptr != p) - { - if (nullptr == pn) - { - try - { - pn = new volatile long(1); - } - catch (std::bad_alloc&) - { - delete p; - throw; - } - } - else - { - ++(*pn); - } - } - } - - template - void release(U* p) noexcept - { - if (nullptr != pn) - { - --(*pn); - if (0 == *pn) - { - delete p; - delete pn; - } - pn = nullptr; - } - } - -public: - volatile long* pn; -}; - -template -class shared_ptr -{ -public: - typedef T element_type; - - shared_ptr(void) noexcept - : px(nullptr), - pn() {} - - /*explicit*/ shared_ptr(T* p) - : px(nullptr), - pn() - { - acquire(p); - } - - template - shared_ptr(const shared_ptr& ptr, T* p) : - px(nullptr), - pn(ptr.pn) - { - acquire(p); - } - - template - shared_ptr(const shared_ptr& ptr) noexcept : - px(nullptr), - pn(ptr.pn) - { - CARLA_SAFE_ASSERT_RETURN(nullptr == ptr.px || 0 != ptr.pn.use_count(),); - acquire(static_cast::element_type*>(ptr.px)); - } - - shared_ptr(const shared_ptr& ptr) noexcept : - px(nullptr), - pn(ptr.pn) - { - CARLA_SAFE_ASSERT_RETURN(nullptr == ptr.px || 0 != ptr.pn.use_count(),); - acquire(ptr.px); - } - - shared_ptr& operator=(shared_ptr ptr) noexcept - { - swap(ptr); - return *this; - } - - ~shared_ptr(void) noexcept - { - release(); - } - - void reset(void) noexcept - { - release(); - } - - void swap(shared_ptr& lhs) noexcept - { - std::swap(px, lhs.px); - pn.swap(lhs.pn); - } - - operator bool() const noexcept - { - return (0 < pn.use_count()); - } - long use_count(void) const noexcept - { - return pn.use_count(); - } - - // underlying pointer operations : - T& operator*() const noexcept - { - return *px; - } - T* operator->() const noexcept - { - return px; - } - T* get(void) const noexcept - { - return px; - } - -private: - void acquire(T* p) - { - pn.acquire(p); - px = p; - } - - void release(void) noexcept - { - pn.release(px); - px = nullptr; - } - -private: - template - friend class shared_ptr; - -private: - T* px; - shared_ptr_count pn; -}; - -template bool operator==(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() == r.get()); -} -template bool operator!=(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() != r.get()); -} -template bool operator<=(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() <= r.get()); -} -template bool operator<(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() < r.get()); -} -template bool operator>=(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() >= r.get()); -} -template bool operator>(const shared_ptr& l, const shared_ptr& r) noexcept -{ - return (l.get() > r.get()); -} -template -shared_ptr static_pointer_cast(const shared_ptr& ptr) -{ - return shared_ptr(ptr, static_cast::element_type*>(ptr.get())); -} -template -shared_ptr dynamic_pointer_cast(const shared_ptr& ptr) -{ - T* p = dynamic_cast::element_type*>(ptr.get()); - if (nullptr != p) - { - return shared_ptr(ptr, p); - } - else - { - return shared_ptr(); - } -} -template -bool operator==(const shared_ptr& pointer1, T* const pointer2) noexcept -{ - return static_cast(pointer1) == pointer2; -} -template -bool operator!=(const shared_ptr& pointer1, T* const pointer2) noexcept -{ - return static_cast(pointer1) != pointer2; -} - -} // namespace std -#endif // CARLA_PROPER_CPP11_SUPPORT - -CARLA_BACKEND_START_NAMESPACE - -typedef std::shared_ptr CarlaPluginPtr; - -CARLA_BACKEND_END_NAMESPACE - -// ----------------------------------------------------------------------- - -#endif // CARLA_CPP_COMPAT_HPP_INCLUDED diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index a4dcd29a7..ac5b0bb04 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later // TODO: @@ -11,9 +11,11 @@ #include "CarlaPlugin.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "ThreadSafeFFTW.hpp" +#include "extra/Base64.hpp" +#include "extra/ScopedPointer.hpp" + #include "water/files/File.h" #define CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(cond, msg, ret) \ @@ -455,10 +457,10 @@ bool carla_engine_init_bridge(CarlaHostHandle handle, CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->isStandalone, "Must be a standalone host handle", false); CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine == nullptr, "Engine is already initialized", false); - CarlaScopedPointer engine(CB::EngineInit::newBridge(audioBaseName, - rtClientBaseName, - nonRtClientBaseName, - nonRtServerBaseName)); + ScopedPointer engine(CB::EngineInit::newBridge(audioBaseName, + rtClientBaseName, + nonRtClientBaseName, + nonRtServerBaseName)); CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(engine != nullptr, "The selected audio driver is not available", false); @@ -1725,7 +1727,7 @@ const char* carla_get_custom_data_value(CarlaHostHandle handle, uint pluginId, c if (count == 0) return gNullCharPtr; - static CarlaString customDataValue; + static String customDataValue; for (uint32_t i=0; igetChunkData(&data)); CARLA_SAFE_ASSERT_RETURN(data != nullptr && dataSize > 0, gNullCharPtr); - static CarlaString chunkData; + static String chunkData; - chunkData = CarlaString::asBase64(data, static_cast(dataSize)); + chunkData = String::asBase64(data, static_cast(dataSize)); return chunkData.buffer(); } @@ -2218,7 +2220,8 @@ void carla_set_chunk_data(CarlaHostHandle handle, uint pluginId, const char* chu { CARLA_SAFE_ASSERT_RETURN(plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS,); - std::vector chunk(carla_getChunkFromBase64String(chunkData)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, chunkData); #ifdef CARLA_PROPER_CPP11_SUPPORT plugin->setChunkData(chunk.data(), chunk.size()); #else diff --git a/source/backend/CarlaStandaloneNSM.cpp b/source/backend/CarlaStandaloneNSM.cpp index 870f78fc3..61df50aa9 100644 --- a/source/backend/CarlaStandaloneNSM.cpp +++ b/source/backend/CarlaStandaloneNSM.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaHostImpl.hpp" @@ -14,7 +14,6 @@ #define NSM_CLIENT_FEATURES ":switch:optional-gui:" #include "CarlaOscUtils.hpp" -#include "CarlaString.hpp" #include "water/files/File.h" @@ -289,7 +288,7 @@ protected: projectPath); for (; ! fReadyActionOpen;) - carla_msleep(10); + d_msleep(10); } else { @@ -343,7 +342,7 @@ protected: 0, 0, 0.0f, nullptr); for (; ! fReadyActionSave;) - carla_msleep(10); + d_msleep(10); } else { @@ -471,7 +470,7 @@ protected: const CarlaPluginInfo* const pluginInfo(carla_get_plugin_info(i)); CARLA_SAFE_ASSERT_CONTINUE(pluginInfo != nullptr); - /*const*/ CarlaString pluginNameId(fClientNameId + "/" + CarlaString(pluginInfo->name).replace('/','_') + "/"); + /*const*/ String pluginNameId(fClientNameId + "/" + String(pluginInfo->name).replace('/','_') + "/"); for (uint32_t j=0, paramCount = carla_get_parameter_count(i); j < paramCount; ++j) { @@ -493,8 +492,8 @@ protected: if (paramData->hints & CB::PARAMETER_IS_READ_ONLY) continue; - const char* const dir = paramData->type == CB::PARAMETER_INPUT ? "in" : "out"; - const CarlaString paramNameId = pluginNameId + CarlaString(paramInfo->name).replace('/','_'); + const char* const dir = paramData->type == CB::PARAMETER_INPUT ? "in" : "out"; + const String paramNameId = pluginNameId + String(paramInfo->name).replace('/','_'); const float defNorm = paramRanges->getNormalizedValue(paramRanges->def); @@ -530,8 +529,8 @@ private: lo_server_thread fServerThread; char* fServerURL; - CarlaString fClientNameId; - CarlaString fProjectPath; + String fClientNameId; + String fProjectPath; bool fHasBroadcast; bool fHasOptionalGui; diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 100599b95..1731cd45e 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later /* TODO: @@ -46,7 +46,6 @@ using water::Array; using water::CharPointer_UTF8; using water::File; using water::MemoryOutputStream; -using water::String; using water::StringArray; using water::XmlDocument; using water::XmlElement; @@ -535,7 +534,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, }; CarlaPluginPtr plugin; - CarlaString bridgeBinary(pData->options.binaryDir); + String bridgeBinary(pData->options.binaryDir); if (bridgeBinary.isNotEmpty()) { @@ -1131,19 +1130,19 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) const CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name); - CarlaString sname; + String sname; sname = name; if (sname.isEmpty()) { sname = "(No name)"; - return sname.dup(); + return carla_strdup(sname); } const std::size_t maxNameSize(carla_minConstrained(getMaxClientNameSize(), 0xff, 6U) - 6); // 6 = strlen(" (10)") + 1 if (maxNameSize == 0 || ! isRunning()) - return sname.dup(); + return carla_strdup(sname); sname.truncate(maxNameSize); sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names @@ -1208,7 +1207,7 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) const sname += " (2)"; } - return sname.dup(); + return carla_strdup(sname); } // ----------------------------------------------------------------------- @@ -1223,8 +1222,8 @@ bool CarlaEngine::loadFile(const char* const filename) File file(filename); CARLA_SAFE_ASSERT_RETURN_ERR(file.exists(), "Requested file does not exist or is not a readable"); - CarlaString baseName(file.getFileNameWithoutExtension().toRawUTF8()); - CarlaString extension(file.getFileExtension().replace(".","").toLowerCase().toRawUTF8()); + String baseName(file.getFileNameWithoutExtension().toRawUTF8()); + String extension(file.getFileExtension().replace(".","").toLowerCase().toRawUTF8()); const uint curPluginId(pData->nextPluginId < pData->curPluginCount ? pData->nextPluginId : pData->curPluginCount); @@ -1331,7 +1330,7 @@ bool CarlaEngine::loadFile(const char* const filename) if (extension == "xmz" || extension == "xiz") { #ifdef HAVE_ZYN_DEPS - CarlaString nicerName("Zyn - "); + String nicerName("Zyn - "); const std::size_t sep(baseName.find('-')+1); @@ -2110,7 +2109,7 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch if (value != 0) { - CarlaString interposerPath(CarlaString(pData->options.binaryDir) + "/libcarla_interposer-safe.so"); + String interposerPath(String(pData->options.binaryDir) + "/libcarla_interposer-safe.so"); ::setenv("LD_PRELOAD", interposerPath.buffer(), 1); } else @@ -2367,8 +2366,8 @@ void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) cons outSettings << " " << bool2str(options.preferUiBridges) << "\n"; outSettings << " " << bool2str(options.uisAlwaysOnTop) << "\n"; - outSettings << " " << String(options.maxParameters) << "\n"; - outSettings << " " << String(options.uiBridgesTimeout) << "\n"; + outSettings << " " << water::String(options.maxParameters) << "\n"; + outSettings << " " << water::String(options.uiBridgesTimeout) << "\n"; if (isPlugin) { @@ -2585,12 +2584,12 @@ void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) cons outStream << "\n"; } -static String findBinaryInCustomPath(const char* const searchPath, const char* const binary) +static water::String findBinaryInCustomPath(const char* const searchPath, const char* const binary) { const StringArray searchPaths(StringArray::fromTokens(searchPath, CARLA_OS_SPLIT_STR, "")); // try direct filename first - String jbinary(binary); + water::String jbinary(binary); // adjust for current platform #ifdef CARLA_OS_WIN @@ -2601,7 +2600,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c jbinary = jbinary.substring(2).replaceCharacter('\\', '/'); #endif - String filename = File(jbinary.toRawUTF8()).getFileName(); + water::String filename = File(jbinary.toRawUTF8()).getFileName(); int searchFlags = File::findFiles|File::ignoreHiddenFiles; @@ -2613,7 +2612,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c #endif std::vector results; - for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) + for (const water::String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) { const File path(it->toRawUTF8()); @@ -2636,9 +2635,9 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c filename = File(jbinary.toRawUTF8()).getFileNameWithoutExtension() + ".so"; #endif else - return String(); + return {}; - for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) + for (const water::String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) { const File path(it->toRawUTF8()); @@ -2649,17 +2648,17 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c return results.front().getFullPathName(); } - return String(); + return {}; } bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alwaysLoadConnections) { carla_debug("CarlaEngine::loadProjectInternal(%p, %s) - START", &xmlDoc, bool2str(alwaysLoadConnections)); - CarlaScopedPointer xmlElement(xmlDoc.getDocumentElement(true)); + ScopedPointer xmlElement(xmlDoc.getDocumentElement(true)); CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to parse project file"); - const String& xmlType(xmlElement->getTagName()); + const water::String& xmlType(xmlElement->getTagName()); const bool isPreset(xmlType.equalsIgnoreCase("carla-preset")); if (! (xmlType.equalsIgnoreCase("carla-project") || isPreset)) @@ -2713,8 +2712,8 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw { for (XmlElement* settElem = elem->getFirstChildElement(); settElem != nullptr; settElem = settElem->getNextElement()) { - const String& tag(settElem->getTagName()); - const String text(settElem->getAllSubText().trim()); + const water::String& tag(settElem->getTagName()); + const water::String text(settElem->getAllSubText().trim()); /** some settings might be incorrect or require extra work, so we call setOption rather than modifying them direly */ @@ -2847,7 +2846,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw { if (XmlElement* const bpmElem = elem->getChildByName("BeatsPerMinute")) { - const String bpmText(bpmElem->getAllSubText().trim()); + const water::String bpmText(bpmElem->getAllSubText().trim()); const double bpm = bpmText.getDoubleValue(); // some sane limits @@ -2868,7 +2867,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw // and we handle plugins for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement()) { - const String& tagName(elem->getTagName()); + const water::String& tagName(elem->getTagName()); if (isPreset || tagName == "Plugin") { @@ -2906,7 +2905,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw return false; } - String lsState; + water::String lsState; lsState << "0.35\n"; lsState << "18 0 Chromatic\n"; lsState << "18 1 Drum Kits\n"; @@ -3013,7 +3012,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw switch (ptype) { case PLUGIN_SF2: - if (CarlaString(stateSave.label).endsWith(" (16 outs)")) + if (String(stateSave.label).endsWith(" (16 outs)")) extraStuff = kTrue; // fall through case PLUGIN_LADSPA: @@ -3046,7 +3045,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw carla_stderr("Plugin binary '%s' doesn't exist on this filesystem, let's look for it...", stateSave.binary); - String result = findBinaryInCustomPath(searchPath, stateSave.binary); + water::String result = findBinaryInCustomPath(searchPath, stateSave.binary); if (result.isEmpty()) { @@ -3198,12 +3197,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions")) { - String name; + water::String name; PatchbayPosition ppos = { nullptr, -1, 0, 0, 0, 0, false }; for (XmlElement* patchElem = elemPositions->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement()) { - const String& patchTag(patchElem->getTagName()); + const water::String& patchTag(patchElem->getTagName()); if (patchTag != "Position") continue; @@ -3211,7 +3210,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw XmlElement* const patchName = patchElem->getChildByName("Name"); CARLA_SAFE_ASSERT_CONTINUE(patchName != nullptr); - const String nameText(patchName->getAllSubText().trim()); + const water::String nameText(patchName->getAllSubText().trim()); name = xmlSafeString(nameText, false); ppos.name = name.toRawUTF8(); @@ -3256,12 +3255,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw { if (XmlElement* const elemPositions = elemPatchbay->getChildByName("Positions")) { - String name; + water::String name; PatchbayPosition ppos = { nullptr, -1, 0, 0, 0, 0, false }; for (XmlElement* patchElem = elemPositions->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement()) { - const String& patchTag(patchElem->getTagName()); + const water::String& patchTag(patchElem->getTagName()); if (patchTag != "Position") continue; @@ -3269,7 +3268,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw XmlElement* const patchName = patchElem->getChildByName("Name"); CARLA_SAFE_ASSERT_CONTINUE(patchName != nullptr); - const String nameText(patchName->getAllSubText().trim()); + const water::String nameText(patchName->getAllSubText().trim()); name = xmlSafeString(nameText, false); ppos.name = name.toRawUTF8(); @@ -3327,7 +3326,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement()) { - const String& patchTag(patchElem->getTagName()); + const water::String& patchTag(patchElem->getTagName()); if (patchTag != "Connection") continue; @@ -3337,8 +3336,8 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement()) { - const String& tag(connElem->getTagName()); - const String text(connElem->getAllSubText().trim()); + const water::String& tag(connElem->getTagName()); + const water::String text(connElem->getAllSubText().trim()); /**/ if (tag == "Source") sourcePort = xmlSafeString(text, false); @@ -3401,7 +3400,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement()) { - const String& tagName(elem->getTagName()); + const water::String& tagName(elem->getTagName()); // check if we want to load patchbay-mode connections into an external (multi-client) graph if (tagName == "Patchbay") @@ -3427,7 +3426,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement()) { - const String& patchTag(patchElem->getTagName()); + const water::String& patchTag(patchElem->getTagName()); if (patchTag != "Connection") continue; @@ -3437,8 +3436,8 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement()) { - const String& tag(connElem->getTagName()); - const String text(connElem->getAllSubText().trim()); + const water::String& tag(connElem->getTagName()); + const water::String text(connElem->getAllSubText().trim()); /**/ if (tag == "Source") sourcePort = xmlSafeString(text, false); diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp index ce6d3c26b..3cbcceb2e 100644 --- a/source/backend/engine/CarlaEngineBridge.cpp +++ b/source/backend/engine/CarlaEngineBridge.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #ifndef BUILD_BRIDGE @@ -16,15 +16,16 @@ #include "CarlaEngineInit.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaBridgeUtils.hpp" -#include "CarlaTimeUtils.hpp" #include "CarlaMIDI.h" #ifdef __SSE2_MATH__ # include #endif +#include "extra/Base64.hpp" +#include "extra/Time.hpp" + #include "water/files/File.h" #include "water/misc/Time.h" @@ -33,7 +34,6 @@ using water::File; using water::MemoryBlock; -using water::String; CARLA_BACKEND_START_NAMESPACE @@ -368,7 +368,7 @@ public: if (wasFirstIdle) { fFirstIdle = false; - fLastPingTime = carla_gettime_ms(); + fLastPingTime = d_gettime_ms(); char bufStr[STR_MAX+1]; carla_zeroChars(bufStr, STR_MAX+1); @@ -643,7 +643,7 @@ public: fShmNonRtServerControl.waitIfDataIsReachingLimit(); carla_stdout("Carla Bridge Ready!"); - fLastPingTime = carla_gettime_ms(); + fLastPingTime = d_gettime_ms(); } // send parameter outputs @@ -672,7 +672,7 @@ public: handleNonRtData(); } CARLA_SAFE_EXCEPTION("handleNonRtData"); - if (fLastPingTime != UINT32_MAX && carla_gettime_ms() > fLastPingTime + 30000 && ! wasFirstIdle) + if (fLastPingTime != UINT32_MAX && d_gettime_ms() > fLastPingTime + 30000 && ! wasFirstIdle) { carla_stderr("Did not receive ping message from server for 30 secs, closing..."); signalThreadShouldExit(); @@ -811,7 +811,7 @@ public: if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime != UINT32_MAX) - fLastPingTime = carla_gettime_ms(); + fLastPingTime = d_gettime_ms(); switch (opcode) { @@ -832,7 +832,7 @@ public: } break; case kPluginBridgeNonRtClientPingOnOff: - fLastPingTime = fShmNonRtClientControl.readBool() ? carla_gettime_ms() : UINT32_MAX; + fLastPingTime = fShmNonRtClientControl.readBool() ? d_gettime_ms() : UINT32_MAX; break; case kPluginBridgeNonRtClientActivate: @@ -925,7 +925,7 @@ public: CARLA_SAFE_ASSERT_BREAK(bigValueFilePathTry.text[0] != '\0'); if (! plugin->isEnabled()) break; - String bigValueFilePath(bigValueFilePathTry.text); + water::String bigValueFilePath(bigValueFilePathTry.text); #ifdef CARLA_OS_WIN // check if running under Wine @@ -966,7 +966,7 @@ public: CARLA_SAFE_ASSERT_BREAK(chunkFilePathTry.text[0] != '\0'); if (! plugin->isEnabled()) break; - String chunkFilePath(chunkFilePathTry.text); + water::String chunkFilePath(chunkFilePathTry.text); #ifdef CARLA_OS_WIN // check if running under Wine @@ -977,11 +977,12 @@ public: File chunkFile(chunkFilePath.toRawUTF8()); CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile()); - String chunkDataBase64(chunkFile.loadFileAsString()); + water::String chunkDataBase64(chunkFile.loadFileAsString()); chunkFile.deleteFile(); CARLA_SAFE_ASSERT_BREAK(chunkDataBase64.isNotEmpty()); - std::vector chunk(carla_getChunkFromBase64String(chunkDataBase64.toRawUTF8())); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, chunkDataBase64.toRawUTF8()); #ifdef CARLA_PROPER_CPP11_SUPPORT plugin->setChunkData(chunk.data(), chunk.size()); @@ -1103,7 +1104,7 @@ public: { if (valueLen > maxLocalValueLen) { - String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); + water::String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); filePath += CARLA_OS_SEP_STR ".CarlaCustomData_"; filePath += fShmAudioPool.getFilenameSuffix(); @@ -1138,10 +1139,10 @@ public: { CARLA_SAFE_ASSERT_BREAK(data != nullptr); - CarlaString dataBase64 = CarlaString::asBase64(data, dataSize); + String dataBase64 = String::asBase64(data, dataSize); CARLA_SAFE_ASSERT_BREAK(dataBase64.length() > 0); - String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); + water::String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += fShmAudioPool.getFilenameSuffix(); @@ -1664,10 +1665,10 @@ private: BridgeNonRtClientControl fShmNonRtClientControl; BridgeNonRtServerControl fShmNonRtServerControl; - CarlaString fBaseNameAudioPool; - CarlaString fBaseNameRtClientControl; - CarlaString fBaseNameNonRtClientControl; - CarlaString fBaseNameNonRtServerControl; + String fBaseNameAudioPool; + String fBaseNameRtClientControl; + String fBaseNameNonRtClientControl; + String fBaseNameNonRtServerControl; bool fClosingDown; bool fIsOffline; diff --git a/source/backend/engine/CarlaEngineClient.cpp b/source/backend/engine/CarlaEngineClient.cpp index 5d76b6dcf..5d6a1d448 100644 --- a/source/backend/engine/CarlaEngineClient.cpp +++ b/source/backend/engine/CarlaEngineClient.cpp @@ -1,30 +1,14 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2020 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineClient.hpp" #include "CarlaEngineUtils.hpp" -#include "CarlaString.hpp" - CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- -static void _getUniquePortName(CarlaString& sname, const CarlaStringList& list) +static void _getUniquePortName(String& sname, const CarlaStringList& list) { for (CarlaStringList::Itenerator it = list.begin2(); it.valid(); it.next()) { @@ -144,7 +128,7 @@ const char* CarlaEngineClient::ProtectedData::getUniquePortName(const char* cons { CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); - CarlaString sname; + String sname; sname = name; _getUniquePortName(sname, audioInList); @@ -154,7 +138,7 @@ const char* CarlaEngineClient::ProtectedData::getUniquePortName(const char* cons _getUniquePortName(sname, eventInList); _getUniquePortName(sname, eventOutList); - return sname.dup(); + return carla_strdup(sname); } void CarlaEngineClient::ProtectedData::clearPorts() diff --git a/source/backend/engine/CarlaEngineClient.hpp b/source/backend/engine/CarlaEngineClient.hpp index 7beb46707..9c62349ef 100644 --- a/source/backend/engine/CarlaEngineClient.hpp +++ b/source/backend/engine/CarlaEngineClient.hpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_ENGINE_CLIENT_HPP_INCLUDED #define CARLA_ENGINE_CLIENT_HPP_INCLUDED diff --git a/source/backend/engine/CarlaEngineDummy.cpp b/source/backend/engine/CarlaEngineDummy.cpp index 0d7c8f9a2..03ded4173 100644 --- a/source/backend/engine/CarlaEngineDummy.cpp +++ b/source/backend/engine/CarlaEngineDummy.cpp @@ -1,24 +1,11 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the GPL.txt file - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineGraph.hpp" #include "CarlaEngineInit.hpp" #include "CarlaEngineInternal.hpp" -#include "CarlaTimeUtils.hpp" + +#include "extra/Time.hpp" CARLA_BACKEND_START_NAMESPACE @@ -227,9 +214,9 @@ protected: while (! shouldThreadExit()) { if (delay > 0) - carla_sleep(static_cast(delay)); + d_sleep(static_cast(delay)); - oldTime = carla_gettime_us(); + oldTime = d_gettime_us(); const PendingRtEventsRunner prt(this, bufferSize, true); @@ -239,7 +226,7 @@ protected: pData->graph.process(pData, audioIns, audioOuts, bufferSize); - newTime = carla_gettime_us(); + newTime = d_gettime_us(); CARLA_SAFE_ASSERT_CONTINUE(newTime >= oldTime); const int64_t remainingTime = cycleTime - (newTime - oldTime); @@ -253,7 +240,7 @@ protected: else if (remainingTime >= 1000) { CARLA_SAFE_ASSERT_CONTINUE(remainingTime < 1000000); // 1 sec - carla_msleep(static_cast(remainingTime / 1000)); + d_msleep(static_cast(remainingTime / 1000)); } } diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index 814f62981..7870e4896 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineGraph.hpp" #include "CarlaEngineInternal.hpp" @@ -28,8 +14,6 @@ using water::jmax; using water::jmin; using water::AudioProcessor; using water::MidiBuffer; -using water::String; -using water::StringArray; #define MAX_GRAPH_AUDIO_IO 64U #define MAX_GRAPH_CV_IO 32U @@ -442,7 +426,7 @@ void ExternalGraph::refresh(const bool sendHost, const bool sendOSC, const char* 0, 0.0f, strBuf); - const CarlaString groupNameIn(strBuf); + const String groupNameIn(strBuf); for (LinkedList::Itenerator it = audioPorts.ins.begin2(); it.valid(); it.next()) { @@ -474,7 +458,7 @@ void ExternalGraph::refresh(const bool sendHost, const bool sendOSC, const char* 0, 0.0f, strBuf); - const CarlaString groupNameOut(strBuf); + const String groupNameOut(strBuf); for (LinkedList::Itenerator it = audioPorts.outs.begin2(); it.valid(); it.next()) { @@ -503,7 +487,7 @@ void ExternalGraph::refresh(const bool sendHost, const bool sendOSC, const char* 0, 0.0f, "Readable MIDI ports"); - const CarlaString groupNamePlus("Readable MIDI ports:"); + const String groupNamePlus("Readable MIDI ports:"); for (LinkedList::Itenerator it = midiPorts.ins.begin2(); it.valid(); it.next()) { @@ -532,7 +516,7 @@ void ExternalGraph::refresh(const bool sendHost, const bool sendOSC, const char* 0, 0.0f, "Writable MIDI ports"); - const CarlaString groupNamePlus("Writable MIDI ports:"); + const String groupNamePlus("Writable MIDI ports:"); for (LinkedList::Itenerator it = midiPorts.outs.begin2(); it.valid(); it.next()) { @@ -1271,53 +1255,53 @@ bool adjustPatchbayPortIdForWater(AudioProcessor::ChannelType& channelType, uint } static inline -const String getProcessorFullPortName(AudioProcessor* const proc, const uint32_t portId) +const water::String getProcessorFullPortName(AudioProcessor* const proc, const uint32_t portId) { - CARLA_SAFE_ASSERT_RETURN(proc != nullptr, String()); - CARLA_SAFE_ASSERT_RETURN(portId >= kAudioInputPortOffset, String()); - CARLA_SAFE_ASSERT_RETURN(portId < kMaxPortOffset, String()); + CARLA_SAFE_ASSERT_RETURN(proc != nullptr, {}); + CARLA_SAFE_ASSERT_RETURN(portId >= kAudioInputPortOffset, {}); + CARLA_SAFE_ASSERT_RETURN(portId < kMaxPortOffset, {}); - String fullPortName(proc->getName()); + water::String fullPortName(proc->getName()); /**/ if (portId >= kMidiOutputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeMIDI) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeMIDI) > 0, {}); fullPortName += ":" + proc->getOutputChannelName(AudioProcessor::ChannelTypeMIDI, portId-kMidiOutputPortOffset); } else if (portId >= kMidiInputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeMIDI) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeMIDI) > 0, {}); fullPortName += ":" + proc->getInputChannelName(AudioProcessor::ChannelTypeMIDI, portId-kMidiInputPortOffset); } else if (portId >= kCVOutputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeCV) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeCV) > 0, {}); fullPortName += ":" + proc->getOutputChannelName(AudioProcessor::ChannelTypeCV, portId-kCVOutputPortOffset); } else if (portId >= kCVInputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeCV) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeCV) > 0, {}); fullPortName += ":" + proc->getInputChannelName(AudioProcessor::ChannelTypeCV, portId-kCVInputPortOffset); } else if (portId >= kAudioOutputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeAudio) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeAudio) > 0, {}); fullPortName += ":" + proc->getOutputChannelName(AudioProcessor::ChannelTypeAudio, portId-kAudioOutputPortOffset); } else if (portId >= kAudioInputPortOffset) { - CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeAudio) > 0, String()); + CARLA_SAFE_ASSERT_RETURN(proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeAudio) > 0, {}); fullPortName += ":" + proc->getInputChannelName(AudioProcessor::ChannelTypeAudio, portId-kAudioInputPortOffset); } else { - return String(); + return {}; } return fullPortName; @@ -1539,10 +1523,10 @@ public: // ------------------------------------------------------------------- - const String getName() const override + const water::String getName() const override { const CarlaPluginPtr plugin = fPlugin; - CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, String()); + CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, {}); return plugin->getName(); } @@ -1652,10 +1636,10 @@ public: plugin->unlock(); } - const String getInputChannelName(ChannelType t, uint i) const override + const water::String getInputChannelName(ChannelType t, uint i) const override { const CarlaPluginPtr plugin = fPlugin; - CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, String()); + CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, {}); CarlaEngineClient* const client = plugin->getEngineClient(); @@ -1669,13 +1653,13 @@ public: return client->getEventPortName(true, i); } - return String(); + return {}; } - const String getOutputChannelName(ChannelType t, uint i) const override + const water::String getOutputChannelName(ChannelType t, uint i) const override { const CarlaPluginPtr plugin = fPlugin; - CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, String()); + CARLA_SAFE_ASSERT_RETURN(plugin.get() != nullptr, {}); CarlaEngineClient* const client(plugin->getEngineClient()); @@ -1689,7 +1673,7 @@ public: return client->getEventPortName(false, i); } - return String(); + return {}; } void prepareToPlay(double, int) override {} @@ -1729,23 +1713,23 @@ public: inputNames(), outputNames() {} - const String getInputChannelName (ChannelType, uint _index) const override + const water::String getInputChannelName (ChannelType, uint _index) const override { const int index = static_cast(_index); // FIXME if (index < inputNames.size()) return inputNames[index]; - return String("Playback ") + String(index+1); + return water::String("Playback ") + String(index+1); } - const String getOutputChannelName (ChannelType, uint _index) const override + const water::String getOutputChannelName (ChannelType, uint _index) const override { const int index = static_cast(_index); // FIXME if (index < outputNames.size()) return outputNames[index]; - return String("Capture ") + String(index+1); + return water::String("Capture ") + String(index+1); } - void setNames(const bool setInputNames, const StringArray& names) + void setNames(const bool setInputNames, const water::StringArray& names) { if (setInputNames) inputNames = names; @@ -1754,8 +1738,8 @@ public: } private: - StringArray inputNames; - StringArray outputNames; + water::StringArray inputNames; + water::StringArray outputNames; }; PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, @@ -1795,7 +1779,7 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); midiBuffer.clear(); - StringArray channelNames; + water::StringArray channelNames; switch (numAudioIns) { @@ -2378,10 +2362,10 @@ const char* const* PatchbayGraph::getConnections(const bool external) const AudioProcessor* const procB(nodeB->getProcessor()); CARLA_SAFE_ASSERT_CONTINUE(procB != nullptr); - String fullPortNameA(getProcessorFullPortName(procA, connectionToId.portA)); + water::String fullPortNameA(getProcessorFullPortName(procA, connectionToId.portA)); CARLA_SAFE_ASSERT_CONTINUE(fullPortNameA.isNotEmpty()); - String fullPortNameB(getProcessorFullPortName(procB, connectionToId.portB)); + water::String fullPortNameB(getProcessorFullPortName(procB, connectionToId.portB)); CARLA_SAFE_ASSERT_CONTINUE(fullPortNameB.isNotEmpty()); connList.append(fullPortNameA.toRawUTF8()); @@ -2512,8 +2496,8 @@ bool PatchbayGraph::getGroupAndPortIdFromFullName(const bool external, const cha if (external) return extGraph.getGroupAndPortIdFromFullName(fullPortName, groupId, portId); - String groupName(String(fullPortName).upToFirstOccurrenceOf(":", false, false)); - String portName(String(fullPortName).fromFirstOccurrenceOf(":", false, false)); + water::String groupName(water::String(fullPortName).upToFirstOccurrenceOf(":", false, false)); + water::String portName(water::String(fullPortName).fromFirstOccurrenceOf(":", false, false)); for (int i=0, count=graph.getNumNodes(); i - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineInternal.hpp" #include "CarlaPlugin.hpp" @@ -74,7 +60,7 @@ static const double kTicksPerBeat = 1920.0; #if defined(HAVE_HYLIA) && !defined(BUILD_BRIDGE) static uint32_t calculate_link_latency(const double bufferSize, const double sampleRate) noexcept { - CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate), 0); + CARLA_SAFE_ASSERT_RETURN(d_isNotZero(sampleRate), 0); const long long int latency = llround(1.0e6 * bufferSize / sampleRate); CARLA_SAFE_ASSERT_RETURN(latency >= 0 && latency < UINT32_MAX, 0); @@ -179,7 +165,7 @@ void EngineInternalTime::relocate(const uint64_t frame) noexcept void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept { - CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate),); + CARLA_SAFE_ASSERT_RETURN(d_isNotZero(sampleRate),); CARLA_SAFE_ASSERT_RETURN(newFrames > 0,); double ticktmp; @@ -262,7 +248,7 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint32_t newFrames) noexcept { - CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate),); + CARLA_SAFE_ASSERT_RETURN(d_isNotZero(sampleRate),); CARLA_SAFE_ASSERT_RETURN(newFrames > 0,); CARLA_SAFE_ASSERT(transportMode == ENGINE_TRANSPORT_MODE_JACK); @@ -294,12 +280,12 @@ void EngineInternalTime::preProcess(const uint32_t numFrames) const double new_bpb = hylia.timeInfo.beatsPerBar; const double new_bpm = hylia.timeInfo.beatsPerMinute; - if (new_bpb >= 1.0 && carla_isNotEqual(beatsPerBar, new_bpb)) + if (new_bpb >= 1.0 && d_isNotEqual(beatsPerBar, new_bpb)) { beatsPerBar = new_bpb; needsReset = true; } - if (new_bpm > 0.0 && carla_isNotEqual(beatsPerMinute, new_bpm)) + if (new_bpm > 0.0 && d_isNotEqual(beatsPerMinute, new_bpm)) { beatsPerMinute = new_bpm; needsReset = true; @@ -805,7 +791,7 @@ ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, } else { - carla_msleep(200); + d_msleep(200); } if (! engine->isRunning()) diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 1db6854c5..00cd79215 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_ENGINE_INTERNAL_HPP_INCLUDED #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED @@ -284,8 +270,8 @@ struct CarlaEngine::ProtectedData { #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH bool loadingProject; bool ignoreClientPrefix; // backwards compat only - CarlaString currentProjectFilename; - CarlaString currentProjectFolder; + String currentProjectFilename; + String currentProjectFolder; #endif uint32_t bufferSize; @@ -297,9 +283,9 @@ struct CarlaEngine::ProtectedData { uint maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255) uint nextPluginId; // invalid if == maxPluginNumber - CarlaMutex envMutex; - CarlaString lastError; - CarlaString name; + CarlaMutex envMutex; + String lastError; + String name; EngineOptions options; EngineTimeInfo timeInfo; diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 80ac9fa06..29156593a 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineClient.hpp" @@ -12,6 +12,7 @@ #include "CarlaMIDI.h" #include "CarlaPatchbayUtils.hpp" #include "CarlaStringList.hpp" +#include "extra/ScopedPointer.hpp" #include "jackey.h" @@ -23,7 +24,7 @@ #include "jackbridge/JackBridge.hpp" #ifdef JACKBRIDGE_DIRECT -# define JackPortIsControlVoltage 0x100 +# define JackPortIsCV 0x20 #endif #define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon" @@ -65,7 +66,7 @@ struct CarlaJackPortHints { ph.isCV = false; ph.isOSC = false; - if (ph.isAudio && portFlags & JackPortIsControlVoltage) + if (ph.isAudio && portFlags & JackPortIsCV) { ph.isAudio = false; ph.isCV = true; @@ -769,13 +770,13 @@ public: EngineInternalGraph& egraph, CarlaRecursiveMutex& rmutex, const CarlaPluginPtr plugin, - const CarlaString& mainClientName, + const String& mainClientName, jack_client_t* const jackClient) : CarlaEngineClientForSubclassing(engine, egraph, plugin), #else CarlaEngineJackClient(const CarlaEngine& engine, CarlaRecursiveMutex& rmutex, - const CarlaString& mainClientName, + const String& mainClientName, jack_client_t* const jackClient) : CarlaEngineClientForSubclassing(engine), #endif @@ -973,7 +974,7 @@ public: jackPort = jackbridge_port_register(fJackClient, realName, JACK_DEFAULT_AUDIO_TYPE, - static_cast(JackPortIsControlVoltage | + static_cast(JackPortIsCV | (isInput ? JackPortIsInput : JackPortIsOutput)), 0); @@ -1108,23 +1109,23 @@ public: } #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH - bool renameInSingleClient(const CarlaString& newClientName) + bool renameInSingleClient(const String& newClientName) { - const CarlaString clientNamePrefix(newClientName + ":"); + const String clientNamePrefix(newClientName + ":"); return _renamePorts(fAudioPorts, clientNamePrefix) && _renamePorts(fCVPorts, clientNamePrefix) && _renamePorts(fEventPorts, clientNamePrefix); } - void closeForRename(jack_client_t* const newClient, const CarlaString& newClientName) noexcept + void closeForRename(jack_client_t* const newClient, const String& newClientName) noexcept { if (fJackClient != nullptr) { if (isActive()) { { - const CarlaString clientNamePrefix(newClientName + ":"); + const String clientNamePrefix(newClientName + ":"); // store current client connections const CarlaMutexLocker cml(fPreRenameMutex); @@ -1203,13 +1204,13 @@ private: CarlaMutex fPreRenameMutex; CarlaStringList fPreRenameConnections; - CarlaString fPreRenamePluginId; - CarlaString fPreRenamePluginIcon; + String fPreRenamePluginId; + String fPreRenamePluginIcon; - CarlaScopedPointer fReservedPluginPtr; + ScopedPointer fReservedPluginPtr; template - bool _renamePorts(const LinkedList& t, const CarlaString& clientNamePrefix) + bool _renamePorts(const LinkedList& t, const String& clientNamePrefix) { for (typename LinkedList::Itenerator it = t.begin2(); it.valid(); it.next()) { @@ -1225,7 +1226,7 @@ private: shortPortName += oldClientNameSep-shortPortName + 1; - const CarlaString newPortName(clientNamePrefix + shortPortName); + const String newPortName(clientNamePrefix + shortPortName); if (! jackbridge_port_rename(fJackClient, port->fJackPort, newPortName)) return false; @@ -1235,7 +1236,7 @@ private: } template - void _savePortsConnections(const LinkedList& t, const CarlaString& clientNamePrefix) + void _savePortsConnections(const LinkedList& t, const String& clientNamePrefix) { for (typename LinkedList::Itenerator it = t.begin2(); it.valid(); it.next()) { @@ -1246,7 +1247,7 @@ private: const char* const shortPortName(jackbridge_port_short_name(port->fJackPort)); CARLA_SAFE_ASSERT_CONTINUE(shortPortName != nullptr && shortPortName[0] != '\0'); - const CarlaString portName(clientNamePrefix + shortPortName); + const String portName(clientNamePrefix + shortPortName); if (const char** const connections = jackbridge_port_get_all_connections(fJackClient, port->fJackPort)) { @@ -1311,7 +1312,7 @@ private: #endif // BUILD_BRIDGE_ALTERNATIVE_ARCH CarlaRecursiveMutex& fThreadSafeMetadataMutex; - const CarlaString& fMainClientName; + const String& fMainClientName; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient) }; @@ -1424,7 +1425,7 @@ public: fExternalPatchbayHost = true; fExternalPatchbayOsc = true; - CarlaString truncatedClientName; + String truncatedClientName; if (fClient == nullptr && clientName != nullptr) { @@ -1559,8 +1560,8 @@ public: # ifdef HAVE_LIBLO { - const CarlaString& tcp(pData->osc.getServerPathTCP()); - const CarlaString& udp(pData->osc.getServerPathUDP()); + const String& tcp(pData->osc.getServerPathTCP()); + const String& udp(pData->osc.getServerPathUDP()); if (tcp.isNotEmpty() || udp.isNotEmpty()) { @@ -2126,7 +2127,7 @@ public: saveStatePtr = &saveState; } - CarlaString uniqueName; + String uniqueName; try { const char* const tmpName = getUniquePluginName(newName); @@ -2747,7 +2748,7 @@ public: if (groupId != 0) break; - carla_msleep(100); + d_msleep(100); callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); } } @@ -3233,7 +3234,7 @@ protected: const CarlaJackPortHints& jackPortHints) { bool groupFound; - CarlaString groupName(portName); + String groupName(portName); groupName.truncate(groupName.rfind(shortPortName, &groupFound)-1); CARLA_SAFE_ASSERT_RETURN(groupFound,); @@ -3463,7 +3464,7 @@ protected: CARLA_SAFE_ASSERT_RETURN(newFullName != nullptr && newFullName[0] != '\0',); bool found; - CarlaString groupName(newFullName); + String groupName(newFullName); groupName.truncate(groupName.rfind(newShortName, &found)-1); CARLA_SAFE_ASSERT_RETURN(found,); @@ -3571,7 +3572,7 @@ private: bool fExternalPatchbayOsc; bool fFreewheel; - CarlaString fClientName; + String fClientName; CarlaRecursiveMutex fThreadSafeMetadataMutex; // ------------------------------------------------------------------- @@ -3579,7 +3580,7 @@ private: #ifdef BUILD_BRIDGE bool fIsRunning; #else - CarlaString fClientNamePrefix; + String fClientNamePrefix; enum RackPorts { kRackPortAudioIn1 = 0, @@ -3798,7 +3799,7 @@ private: uint groupId = 0; bool found; - CarlaString groupName(fullPortName); + String groupName(fullPortName); groupName.truncate(groupName.rfind(shortPortName, &found)-1); CARLA_SAFE_ASSERT_CONTINUE(found); @@ -4214,7 +4215,7 @@ private: if (fClient == nullptr) break; - carla_msleep(200); + d_msleep(200); } } #endif // BUILD_BRIDGE diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 0a83aaaaa..18987a7bf 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaDefines.h" @@ -16,7 +16,6 @@ #include "CarlaPlugin.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaBinaryUtils.hpp" #include "CarlaMathUtils.hpp" #include "CarlaStateUtils.hpp" @@ -26,6 +25,8 @@ #include "CarlaNative.hpp" #include "CarlaNativePlugin.h" +#include "extra/Base64.hpp" + #include "water/files/File.h" #include "water/streams/MemoryOutputStream.h" #include "water/xml/XmlDocument.h" @@ -37,7 +38,6 @@ using water::File; using water::MemoryOutputStream; -using water::String; using water::XmlDocument; using water::XmlElement; @@ -424,7 +424,7 @@ protected: carla_zeroChars(tmpBuf, STR_MAX+1); { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; std::snprintf(tmpBuf, STR_MAX, "%.12g\n", newSampleRate); } @@ -527,7 +527,7 @@ protected: carla_zeroChars(tmpBuf, STR_MAX+1); const CarlaMutexLocker cml(fUiServer.getPipeLock()); - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; const uint pluginId(plugin->getId()); @@ -786,7 +786,7 @@ protected: CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast(valuef)); } CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); @@ -826,7 +826,7 @@ protected: CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("sample-rate\n"),); { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; std::snprintf(tmpBuf, STR_MAX, "%.12g\n", pData->sampleRate); } CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); @@ -1233,7 +1233,7 @@ protected: return; } - CarlaString path(pHost->resourceDir); + String path(pHost->resourceDir); if (kIsPatchbay) path += CARLA_OS_SEP_STR "carla-plugin-patchbay"; @@ -1404,7 +1404,7 @@ protected: carla_zeroChars(tmpBuf, STR_MAX+1); const CarlaMutexLocker cml(fUiServer.getPipeLock()); - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; const EngineTimeInfo& timeInfo(pData->timeInfo); // ------------------------------------------------------------------------------------------------------------ @@ -1519,7 +1519,7 @@ protected: pData->runner.start(); fOptionsForced = true; - const String state(data); + const water::String state(data); XmlDocument xml(state); loadProjectInternal(xml, true); @@ -1719,7 +1719,7 @@ private: float fLastScaleFactor; float fParameters[kNumInParams+kNumOutParams]; - CarlaString fLastProjectFolder; + String fLastProjectFolder; CarlaMutex fPluginDeleterMutex; bool fOptionsForced; @@ -2248,7 +2248,8 @@ bool CarlaEngineNativeUI::msgReceived(const char* const msg) noexcept if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId)) { - std::vector chunk(carla_getChunkFromBase64String(cdata)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, cdata); #ifdef CARLA_PROPER_CPP11_SUPPORT plugin->setChunkData(chunk.data(), chunk.size()); #else diff --git a/source/backend/engine/CarlaEngineOsc.hpp b/source/backend/engine/CarlaEngineOsc.hpp index a4a102877..2ca3b1889 100644 --- a/source/backend/engine/CarlaEngineOsc.hpp +++ b/source/backend/engine/CarlaEngineOsc.hpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2020 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_ENGINE_OSC_HPP_INCLUDED #define CARLA_ENGINE_OSC_HPP_INCLUDED @@ -23,10 +9,11 @@ #ifdef HAVE_LIBLO #include "CarlaBackend.h" +#include "CarlaPlugin.hpp" #include "CarlaJuceUtils.hpp" -#include "CarlaPluginPtr.hpp" #include "CarlaOscUtils.hpp" -#include "CarlaString.hpp" + +#include "extra/String.hpp" #define CARLA_ENGINE_OSC_HANDLE_ARGS const CarlaPluginPtr& plugin, \ const int argc, const lo_arg* const* const argv, const char* const types @@ -70,12 +57,12 @@ public: // ------------------------------------------------------------------- - const CarlaString& getServerPathTCP() const noexcept + const String& getServerPathTCP() const noexcept { return fServerPathTCP; } - const CarlaString& getServerPathUDP() const noexcept + const String& getServerPathUDP() const noexcept { return fServerPathUDP; } @@ -127,11 +114,11 @@ private: CarlaOscData fControlDataTCP; CarlaOscData fControlDataUDP; - CarlaString fName; - CarlaString fServerPathTCP; - CarlaString fServerPathUDP; - lo_server fServerTCP; - lo_server fServerUDP; + String fName; + String fServerPathTCP; + String fServerPathUDP; + lo_server fServerTCP; + lo_server fServerUDP; // ------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineOscSend.cpp b/source/backend/engine/CarlaEngineOscSend.cpp index 670644cec..00207e99f 100644 --- a/source/backend/engine/CarlaEngineOscSend.cpp +++ b/source/backend/engine/CarlaEngineOscSend.cpp @@ -216,7 +216,7 @@ void CarlaEngineOsc::sendPluginProgramCount(const CarlaPluginPtr& plugin) const CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); carla_stdout("CarlaEngineOsc::sendPluginDataCount(%p)", plugin.get()); - char targetPath[std::strlen(fControlDataTCP.path)+7]; + char targetPath[std::strlen(fControlDataTCP.path)+8]; std::strcpy(targetPath, fControlDataTCP.path); std::strcat(targetPath, "/pcount"); try_lo_send(fControlDataTCP.target, targetPath, "iii", diff --git a/source/backend/engine/CarlaEnginePorts.cpp b/source/backend/engine/CarlaEnginePorts.cpp index e204fd166..184900a58 100644 --- a/source/backend/engine/CarlaEnginePorts.cpp +++ b/source/backend/engine/CarlaEnginePorts.cpp @@ -106,7 +106,7 @@ void CarlaEngineCVPort::setRange(const float min, const float max) noexcept carla_zeroChars(strBufMax, STR_MAX); { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; std::snprintf(strBufMin, STR_MAX-1, "%.12g", static_cast(min)); std::snprintf(strBufMax, STR_MAX-1, "%.12g", static_cast(max)); } diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index a393e09cf..61b84bf18 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineGraph.hpp" @@ -861,7 +861,7 @@ protected: return CarlaEngine::connectExternalGraphPort(connectionType, portId, portName); case kExternalGraphConnectionMidiInput: { - CarlaString newRtMidiPortName; + String newRtMidiPortName; newRtMidiPortName += getName(); newRtMidiPortName += ":"; newRtMidiPortName += portName; @@ -913,7 +913,7 @@ protected: } break; case kExternalGraphConnectionMidiOutput: { - CarlaString newRtMidiPortName; + String newRtMidiPortName; newRtMidiPortName += getName(); newRtMidiPortName += ":"; newRtMidiPortName += portName; @@ -1037,7 +1037,7 @@ private: uint64_t fLastEventTime; // current device name - CarlaString fDeviceName; + String fDeviceName; // temp buffer for interleaved audio float* fAudioIntBufIn; diff --git a/source/backend/engine/CarlaEngineSDL.cpp b/source/backend/engine/CarlaEngineSDL.cpp index 3003f6e05..2f0556ffc 100644 --- a/source/backend/engine/CarlaEngineSDL.cpp +++ b/source/backend/engine/CarlaEngineSDL.cpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaEngineGraph.hpp" #include "CarlaEngineInit.hpp" @@ -414,7 +400,7 @@ private: SDL_AudioDeviceID fDeviceId; // current device name - CarlaString fDeviceName; + String fDeviceName; // deinterleaved buffers uint fAudioOutCount; diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 6854395b5..b65dfb508 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -1,19 +1,21 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaMathUtils.hpp" #include "CarlaMIDI.h" #include "CarlaPluginUI.hpp" -#include "CarlaScopeUtils.hpp" +// #include "CarlaScopeUtils.hpp" #include "CarlaStringList.hpp" #include +#include "extra/Base64.hpp" +#include "extra/ScopedPointer.hpp" + #include "water/files/File.h" #include "water/streams/MemoryOutputStream.h" #include "water/xml/XmlDocument.h" @@ -23,7 +25,6 @@ using water::CharPointer_UTF8; using water::File; using water::MemoryOutputStream; using water::Result; -using water::String; using water::XmlDocument; using water::XmlElement; @@ -557,7 +558,7 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave) if (data != nullptr && dataSize > 0) { - pData->stateSave.chunk = CarlaString::asBase64(data, dataSize).dup(); + pData->stateSave.chunk = carla_strdup(String::asBase64(data, dataSize)); if (pluginType != PLUGIN_INTERNAL && pluginType != PLUGIN_JSFX) usingChunk = true; @@ -924,7 +925,8 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) if (stateSave.chunk != nullptr && (pData->options & PLUGIN_OPTION_USE_CHUNKS) != 0) { - std::vector chunk(carla_getChunkFromBase64String(stateSave.chunk)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, stateSave.chunk); #ifdef CARLA_PROPER_CPP11_SUPPORT setChunkData(chunk.data(), chunk.size()); #else @@ -993,7 +995,7 @@ bool CarlaPlugin::loadStateFromFile(const char* const filename) CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(), false); XmlDocument xml(file); - CarlaScopedPointer xmlElement(xml.getDocumentElement(true)); + ScopedPointer xmlElement(xml.getDocumentElement(true)); CARLA_SAFE_ASSERT_RETURN(xmlElement != nullptr, false); CARLA_SAFE_ASSERT_RETURN(xmlElement->getTagName().equalsIgnoreCase("carla-preset"), false); @@ -1016,7 +1018,7 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) CARLA_SAFE_ASSERT_RETURN(lv2path != nullptr && lv2path[0] != '\0', false); carla_debug("CarlaPlugin::exportAsLV2(\"%s\")", lv2path); - CarlaString bundlepath(lv2path); + String bundlepath(lv2path); if (! bundlepath.endsWith(".lv2")) bundlepath += ".lv2"; @@ -1040,11 +1042,11 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) } } - CarlaString symbol(pData->name); + String symbol(pData->name); symbol.toBasic(); { - const CarlaString pluginFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".xml"); + const String pluginFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".xml"); if (! saveStateToFile(pluginFilename)) return false; @@ -1070,7 +1072,7 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) manifestStream << " lv2:requiredFeature .\n"; manifestStream << "\n"; - const CarlaString manifestFilename(bundlepath + CARLA_OS_SEP_STR "manifest.ttl"); + const String manifestFilename(bundlepath + CARLA_OS_SEP_STR "manifest.ttl"); const File manifestFile(manifestFilename.buffer()); if (! manifestFile.replaceWithData(manifestStream.getData(), manifestStream.getDataSize())) @@ -1124,8 +1126,8 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) for (uint32_t i=1; iaudioIn.count; ++i) { - const String portIndexNum(portIndex++); - const String portIndexLabel(i+1); + const water::String portIndexNum(portIndex++); + const water::String portIndexLabel(i+1); mainStream << " lv2:port [\n"; mainStream << " a lv2:InputPort, lv2:AudioPort ;\n"; @@ -1191,8 +1193,8 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) for (uint32_t i=0; iaudioOut.count; ++i) { - const String portIndexNum(portIndex++); - const String portIndexLabel(i+1); + const water::String portIndexNum(portIndex++); + const water::String portIndexLabel(i+1); mainStream << " lv2:port [\n"; mainStream << " a lv2:OutputPort, lv2:AudioPort ;\n"; @@ -1214,7 +1216,7 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) const ParameterData& paramData(pData->param.data[i]); const ParameterRanges& paramRanges(pData->param.ranges[i]); - const String portIndexNum(portIndex++); + const water::String portIndexNum(portIndex++); mainStream << " lv2:port [\n"; @@ -1238,7 +1240,7 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) if (strBufSymbol[0] == '\0') { - CarlaString s(strBufName); + String s(strBufName); s.toBasic(); std::memcpy(strBufSymbol, s.buffer(), s.length()+1); @@ -1277,7 +1279,7 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) mainStream << " doap:maintainer [ foaf:name \"\"\"" << strBuf << "\"\"\" ] .\n"; mainStream << "\n"; - const CarlaString mainFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".ttl"); + const String mainFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".ttl"); const File mainFile(mainFilename.buffer()); if (! mainFile.replaceWithData(mainStream.getData(), mainStream.getDataSize())) @@ -1287,15 +1289,15 @@ bool CarlaPlugin::exportAsLV2(const char* const lv2path) } } - const CarlaString binaryFilename(bundlepath + CARLA_OS_SEP_STR + symbol + CARLA_LIB_EXT); + const String binaryFilename(bundlepath + CARLA_OS_SEP_STR + symbol + CARLA_LIB_EXT); const File binaryFileSource(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("carla-bridge-lv2" CARLA_LIB_EXT)); const File binaryFileTarget(binaryFilename.buffer()); const EngineOptions& opts(pData->engine->getOptions()); - const CarlaString binFolderTarget(bundlepath + CARLA_OS_SEP_STR + "bin"); - const CarlaString resFolderTarget(bundlepath + CARLA_OS_SEP_STR + "res"); + const String binFolderTarget(bundlepath + CARLA_OS_SEP_STR + "bin"); + const String resFolderTarget(bundlepath + CARLA_OS_SEP_STR + "res"); if (! binaryFileSource.copyFileTo(binaryFileTarget)) { @@ -2489,7 +2491,7 @@ void CarlaPlugin::uiIdle() carla_stdout("Trying to get window..."); - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { diff --git a/source/backend/plugin/CarlaPluginAU.cpp b/source/backend/plugin/CarlaPluginAU.cpp index 8660883bc..2922aaff0 100644 --- a/source/backend/plugin/CarlaPluginAU.cpp +++ b/source/backend/plugin/CarlaPluginAU.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" @@ -8,6 +8,7 @@ # include "CarlaBackendUtils.hpp" # include "CarlaPluginUI.hpp" # include "CarlaMacUtils.hpp" +# include "CarlaMathUtils.hpp" # include # include #endif @@ -248,7 +249,7 @@ public: bool needsCtrlIn, needsCtrlOut, hasMidiIn, hasMidiOut; needsCtrlIn = needsCtrlOut = hasMidiIn = hasMidiOut = false; - CarlaString portName; + String portName; const uint portNameSize = pData->engine->getMaxPortNameSize(); UInt32 outDataSize; @@ -400,7 +401,7 @@ public: if (audioIns > 1) { portName += "input_"; - portName += CarlaString(i + 1); + portName += String(i + 1); } else portName += "input"; @@ -425,7 +426,7 @@ public: if (audioOuts > 1) { portName += "output_"; - portName += CarlaString(i + 1); + portName += String(i + 1); } else portName += "output"; @@ -496,7 +497,7 @@ public: if (min > max) max = min; - if (carla_isEqual(min, max)) + if (d_isEqual(min, max)) { carla_stderr2("WARNING - Broken plugin parameter '%s': max == min", info.name); max = min + 0.1f; @@ -1037,9 +1038,9 @@ private: BundleLoader fBundleLoader; AudioComponentPlugInInterface* fInterface; AudioBufferList* fAudioBufferData; - CarlaString fName; - CarlaString fLabel; - CarlaString fMaker; + String fName; + String fLabel; + String fMaker; struct Functions { InitializeFn initialize; diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 6dc5dab06..c206a54cc 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -1,37 +1,25 @@ -/* - * Carla Plugin Bridge - * Copyright (C) 2011-2024 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaBridgeUtils.hpp" #include "CarlaEngineUtils.hpp" #include "CarlaMathUtils.hpp" #include "CarlaPipeUtils.hpp" #include "CarlaScopeUtils.hpp" #include "CarlaShmUtils.hpp" -#include "CarlaTimeUtils.hpp" #include "CarlaThread.hpp" #include "jackbridge/JackBridge.hpp" #include +#include "extra/Base64.hpp" +#include "extra/ScopedPointer.hpp" +#include "extra/Time.hpp" + #include "water/files/File.h" #include "water/misc/Time.h" #include "water/threads/ChildProcess.h" @@ -40,8 +28,6 @@ using water::ChildProcess; using water::File; -using water::String; -using water::StringArray; CARLA_BACKEND_START_NAMESPACE @@ -53,17 +39,17 @@ static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 }; // -------------------------------------------------------------------------------------------------------------------- #ifndef CARLA_OS_WIN -static String findWinePrefix(const String filename, const int recursionLimit = 10) +static water::String findWinePrefix(const water::String filename, const int recursionLimit = 10) { if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/")) - return ""; + return {}; - const String path(filename.upToLastOccurrenceOf("/", false, false)); + const water::String path(filename.upToLastOccurrenceOf("/", false, false)); - if (File(String(path + "/dosdevices").toRawUTF8()).isDirectory()) + if (File(water::String(path + "/dosdevices").toRawUTF8()).isDirectory()) return path; - return findWinePrefix(path, recursionLimit-1); + return findWinePrefix(path, recursionLimit - 1); } #endif @@ -71,9 +57,9 @@ static String findWinePrefix(const String filename, const int recursionLimit = 1 struct BridgeParamInfo { float value; - CarlaString name; - CarlaString symbol; - CarlaString unit; + String name; + String symbol; + String unit; BridgeParamInfo() noexcept : value(0.0f), @@ -185,18 +171,18 @@ protected: const EngineOptions& options(kEngine->getOptions()); - String filename(kPlugin->getFilename()); + water::String filename(kPlugin->getFilename()); if (filename.isEmpty()) filename = "(none)"; - StringArray arguments; + water::StringArray arguments; #ifndef CARLA_OS_WIN // start with "wine" if needed if (fBridgeBinary.endsWithIgnoreCase(".exe")) { - String wineCMD; + water::String wineCMD; if (options.wine.executable != nullptr && options.wine.executable[0] != '\0') { @@ -204,7 +190,7 @@ protected: if (fBridgeBinary.endsWithIgnoreCase("64.exe") && options.wine.executable[0] == CARLA_OS_SEP - && File(String(wineCMD + "64").toRawUTF8()).existsAsFile()) + && File(water::String(wineCMD + "64").toRawUTF8()).existsAsFile()) wineCMD += "64"; } else @@ -240,7 +226,7 @@ protected: arguments.add(fLabel); // uniqueId - arguments.add(String(static_cast(kPlugin->getUniqueId()))); + arguments.add(water::String(static_cast(kPlugin->getUniqueId()))); bool started; @@ -386,7 +372,7 @@ protected: } for (; fProcess->isRunning() && ! shouldThreadExit();) - carla_sleep(1); + d_msleep(100); // we only get here if bridge crashed or thread asked to exit if (fProcess->isRunning() && shouldThreadExit()) @@ -410,9 +396,9 @@ protected: { carla_stderr("CarlaPluginBridgeThread::run() - bridge crashed"); - CarlaString errorString("Plugin '" + CarlaString(kPlugin->getName()) + "' has crashed!\n" - "Saving now will lose its current settings.\n" - "Please remove this plugin, and not rely on it from this point."); + String errorString("Plugin '" + String(kPlugin->getName()) + "' has crashed!\n" + "Saving now will lose its current settings.\n" + "Please remove this plugin, and not rely on it from this point."); kEngine->callback(true, true, ENGINE_CALLBACK_ERROR, kPlugin->getId(), 0, 0, 0, 0.0f, errorString); } @@ -425,15 +411,15 @@ private: CarlaEngine* const kEngine; CarlaPlugin* const kPlugin; - String fBinaryArchName; - String fBridgeBinary; - String fLabel; - String fShmIds; + water::String fBinaryArchName; + water::String fBridgeBinary; + water::String fLabel; + water::String fShmIds; #ifndef CARLA_OS_WIN - CarlaString fWinePrefix; + String fWinePrefix; #endif - CarlaScopedPointer fProcess; + ScopedPointer fProcess; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridgeThread) }; @@ -690,10 +676,10 @@ public: if (fReceivingParamText.wasDataReceived(&success)) return success; - const uint32_t timeoutEnd = carla_gettime_ms() + 500; // 500 ms + const uint32_t timeoutEnd = d_gettime_ms() + 500; // 500 ms const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; - for (; carla_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) + for (; d_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) { if (fReceivingParamText.wasDataReceived(&success)) return success; @@ -701,7 +687,7 @@ public: if (needsEngineIdle) pData->engine->idle(); - carla_msleep(5); + d_msleep(5); } if (! fBridgeThread.isThreadRunning()) @@ -720,10 +706,10 @@ public: return; // TODO: only wait 1 minute for NI plugins - const uint32_t timeoutEnd = carla_gettime_ms() + 60*1000; // 60 secs, 1 minute + const uint32_t timeoutEnd = d_gettime_ms() + 60*1000; // 60 secs, 1 minute const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; - for (; carla_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) + for (; d_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) { pData->engine->callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); @@ -733,7 +719,7 @@ public: if (fSaved) break; - carla_msleep(20); + d_msleep(20); } if (! fBridgeThread.isThreadRunning()) @@ -991,7 +977,7 @@ public: { if (valueLen > maxLocalValueLen) { - String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); + water::String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); filePath += CARLA_OS_SEP_STR ".CarlaCustomData_"; filePath += fShmAudioPool.getFilenameSuffix(); @@ -1026,10 +1012,10 @@ public: CARLA_SAFE_ASSERT_RETURN(data != nullptr,); CARLA_SAFE_ASSERT_RETURN(dataSize > 0,); - CarlaString dataBase64(CarlaString::asBase64(data, dataSize)); + String dataBase64(String::asBase64(data, dataSize)); CARLA_SAFE_ASSERT_RETURN(dataBase64.length() > 0,); - String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); + water::String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += fShmAudioPool.getFilenameSuffix(); @@ -1116,10 +1102,10 @@ public: fShmNonRtClientControl.commitWrite(); } - const uint32_t timeoutEnd = carla_gettime_ms() + 15*1000; // 15 secs + const uint32_t timeoutEnd = d_gettime_ms() + 15*1000; // 15 secs const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; - for (; carla_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) + for (; d_gettime_ms() < timeoutEnd && fBridgeThread.isThreadRunning();) { pData->engine->callback(true, true, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); @@ -1133,7 +1119,7 @@ public: break; } - carla_msleep(20); + d_msleep(20); } return reinterpret_cast(fPendingEmbedCustomUI); @@ -1219,7 +1205,7 @@ public: needsCtrlOut = true; const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; // Audio Ins for (uint32_t j=0; j < fInfo.aIns; ++j) @@ -1239,7 +1225,7 @@ public: else if (fInfo.aIns > 1) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -1268,7 +1254,7 @@ public: else if (fInfo.aOuts > 1) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -1299,7 +1285,7 @@ public: else if (fInfo.cvIns > 1) { portName += "cv_input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_input"; @@ -1328,7 +1314,7 @@ public: else if (fInfo.cvOuts > 1) { portName += "cv_output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_output"; @@ -2207,7 +2193,7 @@ public: if (fBridgeVersion < 9 || fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64) #endif { - pData->hints &= ~PLUGIN_HAS_CUSTOM_EMBED_UI; + pData->hints &= ~(PLUGIN_HAS_CUSTOM_EMBED_UI|PLUGIN_HAS_CUSTOM_RESIZABLE_UI); } fInfo.category = static_cast(category); @@ -2531,13 +2517,13 @@ public: { const BridgeTextReader bigValueFilePath(fShmNonRtServerControl); - String realBigValueFilePath(bigValueFilePath.text); + water::String realBigValueFilePath(bigValueFilePath.text); #ifndef CARLA_OS_WIN // Using Wine, fix temp dir if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64) { - const StringArray driveLetterSplit(StringArray::fromTokens(realBigValueFilePath, ":/", "")); + const water::StringArray driveLetterSplit(water::StringArray::fromTokens(realBigValueFilePath, ":/", "")); carla_stdout("big value save path BEFORE => '%s' | using wineprefix '%s'", realBigValueFilePath.toRawUTF8(), fWinePrefix.buffer()); realBigValueFilePath = fWinePrefix.buffer(); @@ -2572,13 +2558,13 @@ public: // chunkFilePath const BridgeTextReader chunkFilePath(fShmNonRtServerControl); - String realChunkFilePath(chunkFilePath.text); + water::String realChunkFilePath(chunkFilePath.text); #ifndef CARLA_OS_WIN // Using Wine, fix temp dir if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64) { - const StringArray driveLetterSplit(StringArray::fromTokens(realChunkFilePath, ":/", "")); + const water::StringArray driveLetterSplit(water::StringArray::fromTokens(realChunkFilePath, ":/", "")); carla_stdout("chunk save path BEFORE => '%s' | using wineprefix '%s'", realChunkFilePath.toRawUTF8(), fWinePrefix.buffer()); realChunkFilePath = fWinePrefix.buffer(); @@ -2594,7 +2580,7 @@ public: const File chunkFile(realChunkFilePath.toRawUTF8()); CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile()); - fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8()); + d_getChunkFromBase64String_impl(fInfo.chunk, chunkFile.loadFileAsString().toRawUTF8()); chunkFile.deleteFile(); } break; @@ -2912,7 +2898,7 @@ private: uint fProcWaitTime; uint64_t fPendingEmbedCustomUI; - CarlaString fBridgeBinary; + String fBridgeBinary; CarlaPluginBridgeThread fBridgeThread; BridgeAudioPool fShmAudioPool; @@ -2921,7 +2907,7 @@ private: BridgeNonRtServerControl fShmNonRtServerControl; #ifndef CARLA_OS_WIN - CarlaString fWinePrefix; + String fWinePrefix; #endif class ReceivingParamText { @@ -2989,10 +2975,10 @@ private: uint32_t mIns, mOuts; PluginCategory category; uint optionsAvailable; - CarlaString name; - CarlaString label; - CarlaString maker; - CarlaString copyright; + String name; + String label; + String maker; + String copyright; const char** aInNames; const char** aOutNames; const char** cvInNames; @@ -3204,7 +3190,7 @@ private: if (pData->engine->isAboutToClose() || pData->engine->wasActionCanceled()) break; - carla_msleep(5); + d_msleep(5); } #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH @@ -3237,10 +3223,10 @@ private: #else void* data = &fInfo.chunk.front(); #endif - CarlaString dataBase64(CarlaString::asBase64(data, dataSize)); + String dataBase64(String::asBase64(data, dataSize)); CARLA_SAFE_ASSERT_RETURN(dataBase64.length() > 0, true); - String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); + water::String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += fShmAudioPool.getFilenameSuffix(); @@ -3263,7 +3249,7 @@ private: void _setUiTitleFromName() { - CarlaString uiName(pData->name); + String uiName(pData->name); uiName += " (GUI)"; const uint32_t size = static_cast(uiName.length()); diff --git a/source/backend/plugin/CarlaPluginCLAP.cpp b/source/backend/plugin/CarlaPluginCLAP.cpp index 35da2db79..162526f46 100644 --- a/source/backend/plugin/CarlaPluginCLAP.cpp +++ b/source/backend/plugin/CarlaPluginCLAP.cpp @@ -1,19 +1,5 @@ -/* - * Carla CLAP Plugin - * Copyright (C) 2022-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" @@ -685,6 +671,10 @@ struct carla_clap_output_events : clap_output_events_t, CarlaPluginClapEventData case CLAP_EVENT_MIDI: e.midi = *static_cast(static_cast(event)); break; + case CLAP_EVENT_PARAM_GESTURE_BEGIN: + case CLAP_EVENT_PARAM_GESTURE_END: + // TODO for now be nice to the plugins that require this + return true; default: return false; } @@ -1085,7 +1075,7 @@ public: if (!fUI.isCreated) return; - CarlaString uiTitle; + String uiTitle; if (title != nullptr) { @@ -1552,7 +1542,7 @@ public: const EngineProcessMode processMode = pData->engine->getProccessMode(); const uint portNameSize = pData->engine->getMaxPortNameSize(); - CarlaString portName; + String portName; // Audio Ins for (uint32_t j=0; j < aIns; ++j) @@ -1568,7 +1558,7 @@ public: if (aIns > 1) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -1594,7 +1584,7 @@ public: if (aOuts > 1) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -1825,6 +1815,8 @@ public: pData->hints |= PLUGIN_HAS_CUSTOM_UI; pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI; pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD; + if (guiExt->can_resize(fPlugin)) + pData->hints |= PLUGIN_HAS_CUSTOM_RESIZABLE_UI; } else if (guiExt->is_api_supported(fPlugin, CLAP_WINDOW_API_NATIVE, true)) { diff --git a/source/backend/plugin/CarlaPluginFluidSynth.cpp b/source/backend/plugin/CarlaPluginFluidSynth.cpp index cfcf00710..2c8278bc0 100644 --- a/source/backend/plugin/CarlaPluginFluidSynth.cpp +++ b/source/backend/plugin/CarlaPluginFluidSynth.cpp @@ -1,19 +1,5 @@ -/* - * Carla FluidSynth Plugin - * Copyright (C) 2011-2020 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" @@ -29,9 +15,6 @@ #define FLUID_DEFAULT_POLYPHONY 64 -using water::String; -using water::StringArray; - CARLA_BACKEND_START_NAMESPACE // ------------------------------------------------------------------------------------------------------------------- @@ -519,12 +502,12 @@ public: if (std::strcmp(key, "midiPrograms") != 0) return carla_stderr2("CarlaPluginFluidSynth::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui)); - StringArray midiProgramList(StringArray::fromTokens(value, ":", "")); + water::StringArray midiProgramList(water::StringArray::fromTokens(value, ":", "")); if (midiProgramList.size() == MAX_MIDI_CHANNELS) { uint8_t channel = 0; - for (String *it=midiProgramList.begin(), *end=midiProgramList.end(); it != end; ++it) + for (water::String *it=midiProgramList.begin(), *end=midiProgramList.end(); it != end; ++it) { const int index(it->getIntValue()); @@ -649,7 +632,7 @@ public: pData->param.createNew(params, false); const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; // --------------------------------------- // Audio Outputs @@ -671,7 +654,7 @@ public: if ((i+2)/2 < 9) portName += "0"; - portName += CarlaString((i+2)/2); + portName += String((i+2)/2); if (i % 2 == 0) portName += "L"; @@ -1719,12 +1702,12 @@ public: // --------------------------------------------------------------- // get info - CarlaString label2(label); + String label2(label); if (kUse16Outs && ! label2.endsWith(" (16 outs)")) label2 += " (16 outs)"; - fLabel = label2.dup(); + fLabel = carla_strdup(label2); pData->filename = carla_strdup(filename); if (name != nullptr && name[0] != '\0') diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index 5d8c2e00b..94e7f2d42 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_PLUGIN_INTERNAL_HPP_INCLUDED #define CARLA_PLUGIN_INTERNAL_HPP_INCLUDED @@ -26,9 +12,10 @@ #include "CarlaMIDI.h" #include "CarlaMutex.hpp" -#include "CarlaString.hpp" #include "RtLinkedList.hpp" +#include "extra/String.hpp" + CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- @@ -286,7 +273,7 @@ struct CarlaPlugin::ProtectedData { CarlaStateSave stateSave; - CarlaString uiTitle; + String uiTitle; struct ExternalNotes { CarlaMutex mutex; diff --git a/source/backend/plugin/CarlaPluginJSFX.cpp b/source/backend/plugin/CarlaPluginJSFX.cpp index b7725fdc3..9d6785727 100644 --- a/source/backend/plugin/CarlaPluginJSFX.cpp +++ b/source/backend/plugin/CarlaPluginJSFX.cpp @@ -1,19 +1,6 @@ -/* - * Carla JSFX Plugin - * Copyright (C) 2021-2024 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2021 Jean Pierre Cimalando +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later // TODO(jsfx) graphics section @@ -35,8 +22,6 @@ using water::CharPointer_UTF8; using water::File; -using water::String; -using water::StringArray; CARLA_BACKEND_START_NAMESPACE @@ -332,7 +317,7 @@ public: } const uint portNameSize = pData->engine->getMaxPortNameSize(); - CarlaString portName; + String portName; // Audio Ins for (uint32_t j = 0; j < aIns; ++j) @@ -353,7 +338,7 @@ public: else if (aIns > 1) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -383,7 +368,7 @@ public: else if (aOuts > 1) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -414,13 +399,13 @@ public: // only use values as integer if we have a proper range const bool isEnum = ysfx_slider_is_enum(fEffect, rindex) && - carla_isZero(min) && + d_isZero(min) && max >= 0.0f && - carla_isEqual(max + 1.0f, static_cast(ysfx_slider_get_enum_names(fEffect, rindex, nullptr, 0))); + d_isEqual(max + 1.0f, static_cast(ysfx_slider_get_enum_names(fEffect, rindex, nullptr, 0))); // NOTE: in case of incomplete slider specification without ; // these are usually output-only sliders. - if (carla_isEqual(min, max)) + if (d_isEqual(min, max)) { // replace with a dummy range min = 0.0f; @@ -929,10 +914,10 @@ public: fUnit = CarlaJsfxUnit(); { - StringArray splitPaths; + water::StringArray splitPaths; if (const char* paths = pData->engine->getOptions().pathJSFX) - splitPaths = StringArray::fromTokens(CharPointer_UTF8(paths), CARLA_OS_SPLIT_STR, ""); + splitPaths = water::StringArray::fromTokens(CharPointer_UTF8(paths), CARLA_OS_SPLIT_STR, ""); File file; if (filename && filename[0] != '\0') @@ -977,8 +962,8 @@ public: ysfx_config_u config(ysfx_config_new()); CARLA_SAFE_ASSERT_RETURN(config != nullptr, false); - const CarlaString rootPath = fUnit.getRootPath(); - const CarlaString filePath = fUnit.getFilePath(); + const String rootPath = fUnit.getRootPath(); + const String filePath = fUnit.getFilePath(); ysfx_register_builtin_audio_formats(config.get()); ysfx_set_import_root(config.get(), rootPath); @@ -1021,7 +1006,7 @@ public: pData->name = carla_strdup(ysfx_get_name(fEffect)); } - pData->filename = filePath.dup(); + pData->filename = carla_strdup(filePath); // --------------------------------------------------------------- // register client diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index 02f4dbc70..ce6a7fce7 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" @@ -22,6 +22,7 @@ # warning No liblo support, NSM (session state) will not be available #endif +#include "extra/ScopedPointer.hpp" #include "water/files/File.h" #include "water/misc/Time.h" #include "water/text/StringArray.h" @@ -36,8 +37,6 @@ using water::ChildProcess; using water::File; -using water::String; -using water::StringArray; CARLA_BACKEND_START_NAMESPACE @@ -126,12 +125,12 @@ public: char* getEnvVarsToExport() { const EngineOptions& options(kEngine->getOptions()); - CarlaString binaryDir(options.binaryDir); + String binaryDir(options.binaryDir); #ifdef HAVE_LIBLO const int sessionManager = fSetupLabel[4U] - '0'; #endif - CarlaString ret; + String ret; #ifdef CARLA_OS_MAC ret += "export DYLD_LIBRARY_PATH=" + binaryDir + "/jack\n"; ret += "export DYLD_INSERT_LIBRARIES=" + binaryDir + "/libcarla_interposer-jack-x11.dylib\n"; @@ -144,7 +143,7 @@ public: if (sessionManager == LIBJACK_SESSION_MANAGER_NSM) { for (int i=50; fOscServer == nullptr && --i>=0;) - carla_msleep(100); + d_msleep(100); ret += "export NSM_URL="; ret += lo_server_get_url(fOscServer); @@ -153,12 +152,12 @@ public: #endif if (kPlugin->getHints() & PLUGIN_HAS_CUSTOM_UI) - ret += "export CARLA_FRONTEND_WIN_ID=" + CarlaString(options.frontendWinId) + "\n"; + ret += "export CARLA_FRONTEND_WIN_ID=" + String(options.frontendWinId) + "\n"; ret += "export CARLA_LIBJACK_SETUP=" + fSetupLabel + "\n"; ret += "export CARLA_SHM_IDS=" + fShmIds + "\n"; - return ret.releaseBufferPointer(); + return ret.getAndReleaseBuffer(); } protected: @@ -333,15 +332,15 @@ protected: carla_stderr("CarlaPluginJackThread::run() - already running"); } - String name(kPlugin->getName()); - String filename(kPlugin->getFilename()); + water::String name(kPlugin->getName()); + water::String filename(kPlugin->getFilename()); if (name.isEmpty()) name = "(none)"; CARLA_SAFE_ASSERT_RETURN(filename.isNotEmpty(),); - StringArray arguments; + water::StringArray arguments; // binary arguments.addTokens(filename, true); @@ -352,11 +351,11 @@ protected: std::snprintf(winIdStr, STR_MAX, P_UINTPTR, options.frontendWinId); winIdStr[STR_MAX] = '\0'; - const CarlaString libjackdir(CarlaString(options.binaryDir) + "/jack"); + const String libjackdir(String(options.binaryDir) + "/jack"); #ifdef CARLA_OS_MAC - const CarlaString ldpreload(CarlaString(options.binaryDir) + "/libcarla_interposer-jack-x11.dylib"); + const String ldpreload(String(options.binaryDir) + "/libcarla_interposer-jack-x11.dylib"); #else - const CarlaString ldpreload(CarlaString(options.binaryDir) + "/libcarla_interposer-jack-x11.so"); + const String ldpreload(String(options.binaryDir) + "/libcarla_interposer-jack-x11.so"); #endif const ScopedEngineEnvironmentLocker _seel(kEngine); @@ -399,7 +398,7 @@ protected: else #endif { - carla_msleep(50); + d_msleep(50); } } @@ -437,7 +436,7 @@ protected: { carla_stderr("CarlaPluginJackThread::run() - application crashed"); - CarlaString errorString("Plugin '" + CarlaString(kPlugin->getName()) + "' has crashed!\n" + String errorString("Plugin '" + String(kPlugin->getName()) + "' has crashed!\n" "Saving now will lose its current settings.\n" "Please remove this plugin, and not rely on it from this point."); kEngine->callback(true, true, @@ -457,8 +456,8 @@ private: CarlaEngine* const kEngine; CarlaPlugin* const kPlugin; - CarlaString fShmIds; - CarlaString fSetupLabel; + String fShmIds; + String fSetupLabel; #ifdef HAVE_LIBLO lo_address fOscClientAddress; @@ -466,10 +465,10 @@ private: bool fHasOptionalGui; struct ProjectData { - CarlaString appName; - CarlaString path; - CarlaString display; - CarlaString clientName; + String appName; + String path; + String display; + String clientName; ProjectData() : appName(), @@ -485,7 +484,7 @@ private: CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false); CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false); - CarlaString child(pluginName); + String child(pluginName); child += "."; child += uniqueCodeID; @@ -502,7 +501,7 @@ private: } fProject; #endif - CarlaScopedPointer fProcess; + ScopedPointer fProcess; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginJackThread) }; @@ -849,7 +848,7 @@ public: needsCtrlOut = true; const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; // Audio Ins for (uint8_t j=0; j < fInfo.aIns; ++j) @@ -865,7 +864,7 @@ public: if (fInfo.aIns > 1) { portName += "audio_in_"; - portName += CarlaString(j+1); + portName += String(j+1); } else { @@ -892,7 +891,7 @@ public: if (fInfo.aOuts > 1) { portName += "audio_out_"; - portName += CarlaString(j+1); + portName += String(j+1); } else { @@ -1140,7 +1139,7 @@ public: break; case kEngineControlEventTypeMidiBank: - if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) + if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) { fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiBank); fShmRtClientControl.writeUInt(event.time); @@ -1151,7 +1150,7 @@ public: break; case kEngineControlEventTypeMidiProgram: - if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) + if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) { fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiProgram); fShmRtClientControl.writeUInt(event.time); @@ -1809,7 +1808,7 @@ private: struct Info { uint8_t aIns, aOuts; uint8_t mIns, mOuts; - CarlaString setupLabel; + String setupLabel; std::vector chunk; Info() @@ -1872,7 +1871,7 @@ private: char code[6]; code[5] = '\0'; - CarlaString child; + String child; for (;;) { @@ -1951,21 +1950,21 @@ private: const bool needsCancelableAction = ! pData->engine->isLoadingProject(); const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; - CarlaString actionName; + String actionName; if (needsCancelableAction) { if (fSetupHints & LIBJACK_FLAG_EXTERNAL_START) { const EngineOptions& options(pData->engine->getOptions()); - CarlaString binaryDir(options.binaryDir); + String binaryDir(options.binaryDir); char* const hwVars = fBridgeThread.getEnvVarsToExport(); actionName = "Waiting for external JACK application start, please use the following environment variables:\n"; actionName += hwVars; - delete[] hwVars; + std::free(hwVars); } else { @@ -1995,7 +1994,7 @@ private: if (pData->engine->isAboutToClose() || pData->engine->wasActionCanceled()) break; - carla_msleep(5); + d_msleep(5); } if (needsCancelableAction) diff --git a/source/backend/plugin/CarlaPluginLADSPADSSI.cpp b/source/backend/plugin/CarlaPluginLADSPADSSI.cpp index a39a4b713..e4b0b3657 100644 --- a/source/backend/plugin/CarlaPluginLADSPADSSI.cpp +++ b/source/backend/plugin/CarlaPluginLADSPADSSI.cpp @@ -1,19 +1,5 @@ -/* - * Carla Plugin, LADSPA/DSSI implementation - * Copyright (C) 2011-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngineUtils.hpp" @@ -28,13 +14,11 @@ # include "CarlaOscUtils.hpp" # include "CarlaScopeUtils.hpp" # include "CarlaThread.hpp" +# include "extra/ScopedPointer.hpp" # include "water/threads/ChildProcess.h" using water::ChildProcess; #endif -using water::String; -using water::StringArray; - #define CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ /* check argument count */ \ if (argc != argcToCompare) \ @@ -135,8 +119,8 @@ public: return; } - String name(kPlugin->getName()); - String filename(kPlugin->getFilename()); + water::String name(kPlugin->getName()); + water::String filename(kPlugin->getFilename()); if (name.isEmpty()) name = "(none)"; @@ -144,13 +128,13 @@ public: if (filename.isEmpty()) filename = "\"\""; - StringArray arguments; + water::StringArray arguments; // binary arguments.add(fBinary.buffer()); // osc-url - arguments.add(String(kEngine->getOscServerPathUDP()) + String("/") + String(kPlugin->getId())); + arguments.add(String(kEngine->getOscServerPathUDP()) + water::String("/") + water::String(kPlugin->getId())); // filename arguments.add(filename); @@ -176,12 +160,12 @@ public: winIdStr[STR_MAX] = '\0'; // for LD_PRELOAD - CarlaString ldPreloadValue; + String ldPreloadValue; if (winId != 0) { std::snprintf(winIdStr, STR_MAX, P_UINTPTR, winId); - ldPreloadValue = (CarlaString(kEngine->getOptions().binaryDir) + ldPreloadValue = (String(kEngine->getOptions().binaryDir) + "/libcarla_interposer-x11.so"); } else @@ -209,7 +193,7 @@ public: if (waitForOscGuiShow()) { for (; fProcess->isRunning() && ! shouldThreadExit();) - carla_sleep(1); + d_msleep(100); // we only get here if UI was closed or thread asked to exit if (fProcess->isRunning() && shouldThreadExit()) @@ -251,12 +235,12 @@ private: CarlaEngine* const kEngine; CarlaPlugin* const kPlugin; - CarlaString fBinary; - CarlaString fLabel; - CarlaString fUiTitle; + String fBinary; + String fLabel; + String fUiTitle; const CarlaOscData& fOscData; - CarlaScopedPointer fProcess; + ScopedPointer fProcess; bool waitForOscGuiShow() { @@ -274,7 +258,7 @@ private: } if (fProcess != nullptr && fProcess->isRunning() && ! shouldThreadExit()) - carla_msleep(100); + d_msleep(100); else return false; } @@ -990,7 +974,7 @@ public: } const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCtrl=0; i < portCount; ++i) { @@ -1019,7 +1003,7 @@ public: if (aIns > 1) { portName += "audio-in_"; - portName += CarlaString(iAudioIn+1); + portName += String(iAudioIn+1); } else portName += "audio-in"; @@ -1029,7 +1013,7 @@ public: if (aOuts > 1) { portName += "audio-out_"; - portName += CarlaString(iAudioOut+1); + portName += String(iAudioOut+1); } else portName += "audio-out"; @@ -2896,7 +2880,7 @@ public: // --------------------------------------------------------------- // check for fixed buffer size requirement - fNeedsFixedBuffers = CarlaString(filename).contains("dssi-vst", true); + fNeedsFixedBuffers = String(filename).contains("dssi-vst", true); if (fNeedsFixedBuffers && ! pData->engine->usesConstantBufferSize()) { @@ -2997,7 +2981,7 @@ public: { fUiFilename = guiFilename; - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 6cb5ebcab..001abc252 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later // testing macros @@ -11,13 +11,14 @@ #include "CarlaLv2Utils.hpp" #include "CarlaBackendUtils.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaEngineUtils.hpp" #include "CarlaPipeUtils.hpp" #include "CarlaPluginUI.hpp" #include "CarlaScopeUtils.hpp" #include "Lv2AtomRingBuffer.hpp" +#include "extra/Base64.hpp" + #include "../modules/lilv/config/lilv_config.h" extern "C" { @@ -545,7 +546,7 @@ public: { char sampleRateStr[32]; { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; std::snprintf(sampleRateStr, 31, "%.12g", kEngine->getSampleRate()); } sampleRateStr[31] = '\0'; @@ -582,10 +583,10 @@ private: CarlaEngine* const kEngine; CarlaPluginLV2* const kPlugin; - CarlaString fFilename; - CarlaString fPluginURI; - CarlaString fUiURI; - UiState fUiState; + String fFilename; + String fPluginURI; + String fUiURI; + UiState fUiState; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServerLV2) }; @@ -1476,7 +1477,7 @@ public: void setWindowTitle(const char* const title) noexcept { - CarlaString uiTitle; + String uiTitle; if (title != nullptr) { @@ -1489,7 +1490,7 @@ public: } std::free(const_cast(fLv2Options.windowTitle)); - fLv2Options.windowTitle = uiTitle.releaseBufferPointer(); + fLv2Options.windowTitle = uiTitle.getAndReleaseBuffer(); fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle); fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle; @@ -1651,7 +1652,8 @@ public: if (parameterId == UINT32_MAX) break; - std::vector chunk(carla_getChunkFromBase64String(value)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, value); CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0,); #ifdef CARLA_PROPER_CPP11_SUPPORT @@ -1843,7 +1845,7 @@ public: tmpBuf[0xfe] = '\0'; const CarlaMutexLocker cml(fPipeServer.getPipeLock()); - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; // write URI mappings uint32_t u = 0; @@ -1938,11 +1940,6 @@ public: fPipeServer.syncMessages(); } - -#ifndef BUILD_BRIDGE - if (fUI.rdfDescriptor->Type == LV2_UI_MOD) - pData->tryTransient(); -#endif } else { @@ -2547,7 +2544,7 @@ public: } const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; uint32_t iCtrl = 0; for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCvIn=0, iCvOut=0, iEvIn=0, iEvOut=0; i < portCount; ++i) @@ -3318,7 +3315,18 @@ public: case LV2_UI_OLD_EXTERNAL: break; default: - pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI; + pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI|PLUGIN_HAS_CUSTOM_RESIZABLE_UI; + for (uint32_t i = 0; i < fUI.rdfDescriptor->ExtensionCount; ++i) + { + const char* const extension = fUI.rdfDescriptor->Extensions[i]; + CARLA_SAFE_ASSERT_CONTINUE(extension != nullptr); + + if (std::strcmp(extension, LV2_UI__noUserResize) == 0) + { + pData->hints &= ~PLUGIN_HAS_CUSTOM_RESIZABLE_UI; + break; + } + } break; } } @@ -5364,7 +5372,7 @@ public: const char* getUiBridgeBinary(const LV2_Property type) const { - CarlaString bridgeBinary(pData->engine->getOptions().binaryDir); + String bridgeBinary(pData->engine->getOptions().binaryDir); if (bridgeBinary.isEmpty()) return nullptr; @@ -5392,9 +5400,6 @@ public: case LV2_UI_X11: bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-x11"; break; - case LV2_UI_MOD: - bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-modgui"; - break; #if 0 case LV2_UI_EXTERNAL: case LV2_UI_OLD_EXTERNAL: @@ -5412,7 +5417,7 @@ public: if (! File(bridgeBinary.buffer()).existsAsFile()) return nullptr; - return bridgeBinary.dupSafe(); + return carla_strdup_safe(bridgeBinary); } // ------------------------------------------------------------------- @@ -5839,7 +5844,7 @@ public: return nullptr; } - CarlaString basedir(pData->engine->getName()); + String basedir(pData->engine->getName()); if (temporary) basedir += ".tmp"; @@ -5902,7 +5907,7 @@ public: return File(); } - CarlaString basedir(pData->engine->getName()); + String basedir(pData->engine->getName()); if (temporary) basedir += ".tmp"; @@ -5974,7 +5979,7 @@ public: if (type == kUridAtomString || type == kUridAtomPath) cData.value = carla_strdup((const char*)value); else - cData.value = CarlaString::asBase64(value, size).dup(); + cData.value = carla_strdup(String::asBase64(value, size)); return LV2_STATE_SUCCESS; } @@ -5988,7 +5993,7 @@ public: if (type == kUridAtomString || type == kUridAtomPath) newData.value = carla_strdup((const char*)value); else - newData.value = CarlaString::asBase64(value, size).dup(); + newData.value = carla_strdup(String::asBase64(value, size)); pData->custom.append(newData); @@ -6047,7 +6052,8 @@ public: fLastStateChunk = nullptr; } - std::vector chunk(carla_getChunkFromBase64String(stringData)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, stringData); CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0, nullptr); fLastStateChunk = std::malloc(chunk.size()); @@ -6662,7 +6668,7 @@ public: } else if (feature.Required && ! is_lv2_feature_supported(feature.URI)) { - CarlaString msg("Plugin wants a feature that is not supported:\n"); + String msg("Plugin wants a feature that is not supported:\n"); msg += feature.URI; canContinue = false; @@ -6987,8 +6993,8 @@ public: // --------------------------------------------------------------- // find the most appropriate ui - int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eMod, iCocoa, iWindows, iX11, iExt, iFinal; - eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eMod = iCocoa = iWindows = iX11 = iExt = iFinal = -1; + int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, iCocoa, iWindows, iX11, iExt, iFinal; + eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = iCocoa = iWindows = iX11 = iExt = iFinal = -1; #if defined(LV2_UIS_ONLY_BRIDGES) const bool preferUiBridges = true; @@ -7046,9 +7052,6 @@ public: case LV2_UI_OLD_EXTERNAL: iExt = ii; break; - case LV2_UI_MOD: - eMod = ii; - break; default: break; } @@ -7115,14 +7118,8 @@ public: if (iFinal < 0) { - if (eMod < 0) - { - carla_stderr("Failed to find an appropriate LV2 UI for this plugin"); - return; - } - - // use MODGUI as last resort - iFinal = eMod; + carla_stderr("Failed to find an appropriate LV2 UI for this plugin"); + return; } } @@ -7176,8 +7173,7 @@ public: iFinal == eGtk3 || iFinal == eCocoa || iFinal == eWindows || - iFinal == eX11 || - iFinal == eMod) + iFinal == eX11) #ifdef BUILD_BRIDGE && ! hasShowInterface #endif @@ -7190,7 +7186,7 @@ public: { carla_stdout("Will use UI-Bridge for '%s', binary: \"%s\"", pData->name, bridgeBinary); - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { @@ -7202,7 +7198,7 @@ public: uiTitle += " (GUI)"; } - fLv2Options.windowTitle = uiTitle.releaseBufferPointer(); + fLv2Options.windowTitle = uiTitle.getAndReleaseBuffer(); fUI.type = UI::TYPE_BRIDGE; fPipeServer.setData(bridgeBinary, fRdfDescriptor->URI, fUI.rdfDescriptor->URI); @@ -7211,7 +7207,7 @@ public: return; } - if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || iFinal == eMod) + if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3) { carla_stderr2("Failed to find UI bridge binary for '%s', cannot use UI", pData->name); fUI.rdfDescriptor = nullptr; @@ -7336,7 +7332,7 @@ public: // initialize ui data { - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { @@ -7348,7 +7344,7 @@ public: uiTitle += " (GUI)"; } - fLv2Options.windowTitle = uiTitle.releaseBufferPointer(); + fLv2Options.windowTitle = uiTitle.getAndReleaseBuffer(); } fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle); @@ -7572,7 +7568,7 @@ private: EngineTimeInfo fLastTimeInfo; // if plugin provides path parameter, use it as fake "gui" - CarlaString fFilePathURI; + String fFilePathURI; struct Extensions { const LV2_Options_Interface* options; @@ -8344,7 +8340,8 @@ bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size), true); CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom, false, base64Size), true); - std::vector chunk(carla_getChunkFromBase64String(base64atom)); + std::vector chunk; + d_getChunkFromBase64String_impl(chunk, base64atom); CARLA_SAFE_ASSERT_UINT2_RETURN(chunk.size() >= sizeof(LV2_Atom), chunk.size(), sizeof(LV2_Atom), true); #ifdef CARLA_PROPER_CPP11_SUPPORT @@ -8442,7 +8439,7 @@ CarlaPluginPtr CarlaPlugin::newLV2(const Initializer& init) #ifndef CARLA_OS_WASM if (needsArchBridge != nullptr) { - CarlaString bridgeBinary(init.engine->getOptions().binaryDir); + String bridgeBinary(init.engine->getOptions().binaryDir); bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-native"; return CarlaPlugin::newBridge(init, BINARY_NATIVE, PLUGIN_LV2, needsArchBridge, bridgeBinary); diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp index 72ca45bc5..7b8a56e2c 100644 --- a/source/backend/plugin/CarlaPluginNative.cpp +++ b/source/backend/plugin/CarlaPluginNative.cpp @@ -1,19 +1,5 @@ -/* - * Carla Native Plugin - * Copyright (C) 2012-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" @@ -25,9 +11,6 @@ #include "water/misc/Time.h" #include "water/text/StringArray.h" -using water::String; -using water::StringArray; - // ----------------------------------------------------------------------- // used in carla-base.cpp @@ -715,7 +698,7 @@ public: void setWindowTitle(const char* const title) noexcept { - CarlaString uiName; + String uiName; if (title != nullptr) { @@ -728,7 +711,7 @@ public: } std::free(const_cast(fHost.uiName)); - fHost.uiName = uiName.releaseBufferPointer(); + fHost.uiName = uiName.getAndReleaseBuffer(); if (fDescriptor->dispatcher != nullptr && fIsUiVisible) { @@ -819,12 +802,12 @@ public: } else if (std::strcmp(key, "midiPrograms") == 0 && fDescriptor->set_midi_program != nullptr) { - StringArray midiProgramList(StringArray::fromTokens(value, ":", "")); + water::StringArray midiProgramList(water::StringArray::fromTokens(value, ":", "")); if (midiProgramList.size() == MAX_MIDI_CHANNELS) { uint8_t channel = 0; - for (String *it=midiProgramList.begin(), *end=midiProgramList.end(); it != end; ++it) + for (water::String *it=midiProgramList.begin(), *end=midiProgramList.end(); it != end; ++it) { const int index(it->getIntValue()); @@ -1160,7 +1143,7 @@ public: } const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; // Audio Ins for (j=0; j < aIns; ++j) @@ -1180,7 +1163,7 @@ public: else if (aIns > 1 && ! forcedStereoIn) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -1217,7 +1200,7 @@ public: else if (aOuts > 1 && ! forcedStereoOut) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -1254,7 +1237,7 @@ public: else if (cvIns > 1) { portName += "cv_input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_input"; @@ -1296,7 +1279,7 @@ public: else if (cvOuts > 1) { portName += "cv_output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_output"; @@ -1334,7 +1317,7 @@ public: } portName += "midi-in_"; - portName += CarlaString(j+1); + portName += String(j+1); portName.truncate(portNameSize); fMidiIn.ports[j] = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j); @@ -1358,7 +1341,7 @@ public: } portName += "midi-out_"; - portName += CarlaString(j+1); + portName += String(j+1); portName.truncate(portNameSize); fMidiOut.ports[j] = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j); @@ -2967,7 +2950,7 @@ public: { CARLA_ASSERT(fHost.uiName == nullptr); - CarlaString uiName; + String uiName; if (pData->uiTitle.isNotEmpty()) { @@ -2979,7 +2962,7 @@ public: uiName += " (GUI)"; } - fHost.uiName = uiName.releaseBufferPointer(); + fHost.uiName = uiName.getAndReleaseBuffer(); } // --------------------------------------------------------------- @@ -3085,8 +3068,8 @@ private: bool fInlineDisplayNeedsRedraw; int64_t fInlineDisplayLastRedrawTime; - CarlaString fLastProjectFilename; - CarlaString fLastProjectFolder; + String fLastProjectFilename; + String fLastProjectFolder; float** fAudioAndCvInBuffers; float** fAudioAndCvOutBuffers; diff --git a/source/backend/plugin/CarlaPluginSFZero.cpp b/source/backend/plugin/CarlaPluginSFZero.cpp index 426a53774..d1a2f5600 100644 --- a/source/backend/plugin/CarlaPluginSFZero.cpp +++ b/source/backend/plugin/CarlaPluginSFZero.cpp @@ -1,19 +1,5 @@ -/* - * Carla SFZero Plugin - * Copyright (C) 2018-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" @@ -35,7 +21,6 @@ using water::AudioSampleBuffer; using water::File; using water::MidiMessage; -using water::String; // ----------------------------------------------------------------------- @@ -229,7 +214,7 @@ public: pData->param.createNew(1, false); const uint portNameSize(pData->engine->getMaxPortNameSize()); - CarlaString portName; + String portName; // --------------------------------------- // Audio Outputs @@ -713,11 +698,11 @@ public: // --------------------------------------------------------------- - const String basename(File(filename).getFileNameWithoutExtension()); + const water::String basename(File(filename).getFileNameWithoutExtension()); - CarlaString label2(label != nullptr ? label : basename.toRawUTF8()); + String label2(label != nullptr ? label : basename.toRawUTF8()); - fLabel = label2.dup(); + fLabel = carla_strdup(label2); fRealName = carla_strdup(basename.toRawUTF8()); pData->filename = carla_strdup(filename); diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp index e0050ff59..0eb0fa722 100644 --- a/source/backend/plugin/CarlaPluginVST2.cpp +++ b/source/backend/plugin/CarlaPluginVST2.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaPluginInternal.hpp" @@ -369,7 +369,7 @@ public: if (fUI.window == nullptr || pData->uiTitle.isNotEmpty()) return; - CarlaString uiTitle(pData->name); + String uiTitle(pData->name); uiTitle += " (GUI)"; fUI.window->setTitle(uiTitle.buffer()); } @@ -501,7 +501,7 @@ public: if (yesNo) { - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { @@ -733,7 +733,7 @@ public: const EngineProcessMode processMode = pData->engine->getProccessMode(); const uint portNameSize = pData->engine->getMaxPortNameSize(); - CarlaString portName; + String portName; // Audio Ins for (uint32_t j=0; j < aIns; ++j) @@ -749,7 +749,7 @@ public: if (aIns > 1) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -774,7 +774,7 @@ public: if (aOuts > 1) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -2465,7 +2465,7 @@ public: VST_Function vstFn; #ifdef CARLA_OS_MAC - CarlaString filenameCheck(filename); + String filenameCheck(filename); filenameCheck.toLower(); if (filenameCheck.endsWith(".vst") || filenameCheck.endsWith(".vst/")) diff --git a/source/backend/plugin/CarlaPluginVST3.cpp b/source/backend/plugin/CarlaPluginVST3.cpp index 39bacf3e2..0e7f16b26 100644 --- a/source/backend/plugin/CarlaPluginVST3.cpp +++ b/source/backend/plugin/CarlaPluginVST3.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later /* TODO list @@ -9,6 +9,7 @@ #include "CarlaEngine.hpp" #include "CarlaBackendUtils.hpp" +#include "CarlaMathUtils.hpp" #include "CarlaVst3Utils.hpp" #include "CarlaPluginUI.hpp" @@ -895,7 +896,12 @@ private: // -------------------------------------------------------------------------------------------------------------------- struct carla_v3_output_event_list : v3_event_list_cpp { + v3_event* const events; + uint16_t numEvents; + carla_v3_output_event_list() + : events(new v3_event[kPluginMaxMidiEvents]), + numEvents(0) { query_interface = v3_query_interface_static; ref = v3_ref_static; @@ -905,6 +911,11 @@ struct carla_v3_output_event_list : v3_event_list_cpp { list.add_event = add_event; } + ~carla_v3_output_event_list() + { + delete[] events; + } + private: static uint32_t V3_API get_event_count(void*) { @@ -920,10 +931,13 @@ private: return V3_NOT_IMPLEMENTED; } - static v3_result V3_API add_event(void*, v3_event*) + static v3_result V3_API add_event(void* const self, v3_event* const event) { - carla_debug("TODO %s", __PRETTY_FUNCTION__); - return V3_NOT_IMPLEMENTED; + carla_v3_output_event_list* const me = *static_cast(self); + if (me->numEvents >= kPluginMaxMidiEvents) + return V3_NOMEM; + std::memcpy(&me->events[me->numEvents++], event, sizeof(v3_event)); + return V3_OK; } CARLA_DECLARE_NON_COPYABLE(carla_v3_output_event_list) @@ -1620,7 +1634,7 @@ public: if (yesNo) { - CarlaString uiTitle; + String uiTitle; if (pData->uiTitle.isNotEmpty()) { @@ -1658,7 +1672,7 @@ public: fUI.window->setTitle(uiTitle.buffer()); #ifndef CARLA_OS_MAC - if (carla_isNotZero(opts.uiScale)) + if (d_isNotZero(opts.uiScale)) { // TODO inform plugin of what UI scale we use } @@ -1762,7 +1776,7 @@ public: #ifndef CARLA_OS_MAC const EngineOptions& opts(pData->engine->getOptions()); - if (carla_isNotZero(opts.uiScale)) + if (d_isNotZero(opts.uiScale)) { // TODO } @@ -2060,7 +2074,7 @@ public: const EngineProcessMode processMode = pData->engine->getProccessMode(); const uint portNameSize = pData->engine->getMaxPortNameSize(); - CarlaString portName; + String portName; // Audio Ins for (uint32_t j=0; j < aIns; ++j) @@ -2076,7 +2090,7 @@ public: if (aIns > 1) { portName += "input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "input"; @@ -2102,7 +2116,7 @@ public: if (aOuts > 1) { portName += "output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "output"; @@ -2128,7 +2142,7 @@ public: if (cvIns > 1) { portName += "cv_input_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_input"; @@ -2154,7 +2168,7 @@ public: if (cvOuts > 1) { portName += "cv_output_"; - portName += CarlaString(j+1); + portName += String(j+1); } else portName += "cv_output"; @@ -2305,6 +2319,8 @@ public: pData->hints |= PLUGIN_HAS_CUSTOM_UI; pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI; pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD; + if (v3_cpp_obj(fV3.view)->can_resize(fV3.view) == V3_TRUE) + pData->hints |= PLUGIN_HAS_CUSTOM_RESIZABLE_UI; } #endif @@ -3016,15 +3032,6 @@ public: } // End of Plugin processing (no events) - // ------------------------------------------------------------------------------------------------------------ - // MIDI Output - - if (pData->event.portOut != nullptr) - { - // TODO - - } // End of MIDI Output - fFirstActive = false; // ------------------------------------------------------------------------------------------------------------ @@ -3131,6 +3138,67 @@ public: v3_cpp_obj(fV3.processor)->process(fV3.processor, &processData); } CARLA_SAFE_EXCEPTION("process"); + // ------------------------------------------------------------------------------------------------------------ + // Handle MIDI output + + int32_t minPortOutOffset = 0; + + if (fEvents.eventOutputs != nullptr) + { + uint8_t midiData[3], midiSize; + + for (uint32_t i=0; i < fEvents.eventOutputs->numEvents; ++i) + { + v3_event& v3event(fEvents.eventOutputs->events[i]); + + if (v3event.bus_index != 0) + continue; + + switch (v3event.type) + { + case V3_EVENT_NOTE_OFF: + midiData[0] = MIDI_STATUS_NOTE_OFF | (v3event.note_off.channel & MIDI_CHANNEL_BIT); + midiData[1] = v3event.note_off.pitch; + midiData[2] = carla_fixedValue(0, + MAX_MIDI_VALUE - 1, + v3event.note_off.velocity * MAX_MIDI_VALUE); + midiSize = 3; + break; + case V3_EVENT_NOTE_ON: + midiData[0] = MIDI_STATUS_NOTE_ON | (v3event.note_on.channel & MIDI_CHANNEL_BIT); + midiData[1] = v3event.note_on.pitch; + midiData[2] = carla_fixedValue(0, + MAX_MIDI_VALUE - 1, + v3event.note_on.velocity * MAX_MIDI_VALUE); + midiSize = 3; + break; + case V3_EVENT_POLY_PRESSURE: + midiData[0] = MIDI_STATUS_POLYPHONIC_AFTERTOUCH | (v3event.poly_pressure.channel & MIDI_CHANNEL_BIT); + midiData[1] = v3event.poly_pressure.pitch; + midiData[2] = carla_fixedValue(0, + MAX_MIDI_VALUE - 1, + v3event.poly_pressure.pressure * MAX_MIDI_VALUE); + midiSize = 3; + break; + case V3_EVENT_LEGACY_MIDI_CC_OUT: + midiData[0] = MIDI_STATUS_CONTROL_CHANGE | (v3event.midi_cc_out.channel & MIDI_CHANNEL_BIT); + midiData[1] = v3event.midi_cc_out.cc_number; + midiData[2] = v3event.midi_cc_out.value; + midiSize = 3; + break; + default: + continue; + } + + if (! pData->event.portOut->writeMidiEvent(static_cast(v3event.sample_offset) + timeOffset, + midiSize, + midiData)) + break; + + minPortOutOffset = v3event.sample_offset; + } + } + // ------------------------------------------------------------------------------------------------------------ // Handle parameter outputs @@ -3157,7 +3225,7 @@ public: channel = pData->param.data[i].midiChannel; param = static_cast(pData->param.data[i].mappedControlIndex); - pData->event.portOut->writeControlEvent(queue->offset, + pData->event.portOut->writeControlEvent(std::max(minPortOutOffset, queue->offset) + timeOffset, channel, kEngineControlEventTypeParameter, param, @@ -4168,6 +4236,9 @@ private: if (eventInputs != nullptr) eventInputs->numEvents = 0; + + if (eventOutputs != nullptr) + eventOutputs->numEvents = 0; } void prepare() diff --git a/source/backend/utils/CachedPlugins.cpp b/source/backend/utils/CachedPlugins.cpp index 39eeae797..bec3462a7 100644 --- a/source/backend/utils/CachedPlugins.cpp +++ b/source/backend/utils/CachedPlugins.cpp @@ -1,10 +1,9 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaUtils.h" #include "CarlaNative.h" -#include "CarlaString.hpp" #include "CarlaBackendUtils.hpp" #include "CarlaLv2Utils.hpp" @@ -178,7 +177,7 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl // text data { - static CarlaString suri, sname, smaker, slicense; + static String suri, sname, smaker, slicense; suri.clear(); sname.clear(); smaker.clear(); slicense.clear(); suri = lilvPlugin.get_uri().as_uri(); @@ -263,15 +262,26 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl if (false) #endif { - info.hints |= CB::PLUGIN_HAS_CUSTOM_EMBED_UI; + info.hints |= CB::PLUGIN_HAS_CUSTOM_EMBED_UI|CB::PLUGIN_HAS_CUSTOM_RESIZABLE_UI; + + Lilv::Nodes lilvSupportedFeatureNodes(lilvUI.get_supported_features()); + LILV_FOREACH(nodes, it, lilvSupportedFeatureNodes) + { + Lilv::Node lilvFeatureNode(lilvSupportedFeatureNodes.get(it)); + const char* const featureURI(lilvFeatureNode.as_uri()); + CARLA_SAFE_ASSERT_CONTINUE(featureURI != nullptr); + + if (std::strcmp(featureURI, LV2_UI__noUserResize) == 0) + { + info.hints &= ~CB::PLUGIN_HAS_CUSTOM_RESIZABLE_UI; + break; + } + } + lilv_nodes_free(const_cast(lilvSupportedFeatureNodes.me)); break; } } } -#ifdef CARLA_OS_LINUX - else if (lilvPlugin.get_modgui_resources_directory().as_uri() != nullptr) - info.hints |= CB::PLUGIN_HAS_CUSTOM_UI; -#endif lilv_nodes_free(const_cast(lilvUIs.me)); } @@ -589,7 +599,7 @@ static const CarlaCachedPluginInfo* get_cached_plugin_sfz(const water::File& fil { static CarlaCachedPluginInfo info; - static CarlaString name, filename; + static String name, filename; name = file.getFileNameWithoutExtension().toRawUTF8(); name.replace('_',' '); @@ -627,8 +637,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CB::CarlaJsfxUn ysfx_config_u config(ysfx_config_new()); - const CarlaString rootPath = unit.getRootPath(); - const CarlaString filePath = unit.getFilePath(); + const String rootPath = unit.getRootPath(); + const String filePath = unit.getFilePath(); ysfx_register_builtin_audio_formats(config.get()); ysfx_set_import_root(config.get(), rootPath); @@ -653,7 +663,7 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CB::CarlaJsfxUn return &info; } - static CarlaString name, label, maker; + static String name, label, maker; label = unit.getFileId(); name = ysfx_get_name(effect.get()); maker = ysfx_get_author(effect.get()); diff --git a/source/backend/utils/Information.cpp b/source/backend/utils/Information.cpp index e6cb52d50..ff7f3b0e6 100644 --- a/source/backend/utils/Information.cpp +++ b/source/backend/utils/Information.cpp @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaUtils.h" -#include "CarlaString.hpp" #if defined(HAVE_FLUIDSYNTH) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) # include @@ -26,6 +25,7 @@ # pragma GCC diagnostic pop #endif +#include "extra/String.hpp" #include "water/files/File.h" // ------------------------------------------------------------------------------------------------------------------- @@ -34,7 +34,7 @@ const char* carla_get_complete_license_text() { carla_debug("carla_get_complete_license_text()"); - static CarlaString retText; + static String retText; if (retText.isEmpty()) { @@ -196,7 +196,7 @@ const char* carla_get_library_filename() { carla_debug("carla_get_library_filename()"); - static CarlaString ret; + static String ret; if (ret.isEmpty()) { @@ -211,7 +211,7 @@ const char* carla_get_library_folder() { carla_debug("carla_get_library_folder()"); - static CarlaString ret; + static String ret; if (ret.isEmpty()) { diff --git a/source/backend/utils/PluginDiscovery.cpp b/source/backend/utils/PluginDiscovery.cpp index 2ba24f597..07c57a34a 100644 --- a/source/backend/utils/PluginDiscovery.cpp +++ b/source/backend/utils/PluginDiscovery.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaUtils.h" @@ -7,8 +7,10 @@ #include "CarlaBinaryUtils.hpp" #include "CarlaJuceUtils.hpp" #include "CarlaPipeUtils.hpp" +#include "CarlaScopeUtils.hpp" #include "CarlaSha1Utils.hpp" -#include "CarlaTimeUtils.hpp" + +#include "extra/Time.hpp" #include "water/files/File.h" #include "water/files/FileInputStream.h" @@ -68,8 +70,8 @@ struct CarlaPluginDiscoveryOptions { #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN) struct { bool autoPrefix; - CarlaString executable; - CarlaString fallbackPrefix; + String executable; + String fallbackPrefix; } wine; #endif @@ -152,7 +154,7 @@ public: idlePipe(); // automatically skip a plugin if 30s passes without a reply - const uint32_t timeNow = carla_gettime_ms(); + const uint32_t timeNow = d_gettime_ms(); if (timeNow - fLastMessageTime < 30000) return true; @@ -189,7 +191,7 @@ public: protected: bool msgReceived(const char* const msg) noexcept { - fLastMessageTime = carla_gettime_ms(); + fLastMessageTime = d_gettime_ms(); if (std::strcmp(msg, "warning") == 0 || std::strcmp(msg, "error") == 0) { @@ -381,12 +383,12 @@ private: uint fBinaryIndex; const uint fBinaryCount; const std::vector fBinaries; - const CarlaString fDiscoveryTool; + const String fDiscoveryTool; uint32_t fLastMessageTime; CarlaPluginDiscoveryInfo fNextInfo; - CarlaString fNextSha1Sum; + String fNextSha1Sum; char* fNextLabel; char* fNextMaker; char* fNextName; @@ -396,7 +398,7 @@ private: using water::File; using water::String; - fLastMessageTime = carla_gettime_ms(); + fLastMessageTime = d_gettime_ms(); fPluginsFoundInBinary = false; fNextSha1Sum.clear(); diff --git a/source/bridges-plugin/CarlaBridgePlugin.cpp b/source/bridges-plugin/CarlaBridgePlugin.cpp index 31339fcca..fa8344ff2 100644 --- a/source/bridges-plugin/CarlaBridgePlugin.cpp +++ b/source/bridges-plugin/CarlaBridgePlugin.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #ifndef BUILD_BRIDGE @@ -12,7 +12,6 @@ #include "CarlaBackendUtils.hpp" #include "CarlaJuceUtils.hpp" #include "CarlaMainLoop.hpp" -#include "CarlaTimeUtils.hpp" #include "CarlaMIDI.h" @@ -38,6 +37,8 @@ # include #endif +#include "extra/Sleep.hpp" + #include "water/files/File.h" #include "water/misc/Time.h" @@ -51,7 +52,6 @@ using CARLA_BACKEND_NAMESPACE::runMainLoopOnce; using water::CharPointer_UTF8; using water::File; -using water::String; // ------------------------------------------------------------------------- @@ -112,7 +112,7 @@ static void initSignalHandler() // ------------------------------------------------------------------------- static CarlaHostHandle gHostHandle; -static CarlaString gProjectFilename; +static String gProjectFilename; static void gIdle() { @@ -230,9 +230,9 @@ public: gIdle(); #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) // MacOS and Win32 have event-loops to run, so minimize sleep time - carla_msleep(1); + d_msleep(1); #else - carla_msleep(5); + d_msleep(5); #endif if (testing && timeToEnd - water::Time::currentTimeMillis() < 0) break; @@ -418,7 +418,7 @@ int main(int argc, char* argv[]) // --------------------------------------------------------------------- // Set client name - CarlaString clientName; + String clientName; if (name != nullptr) { @@ -430,7 +430,7 @@ int main(int argc, char* argv[]) CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0', 1); // LV2 URI is not usable as client name, create a usable name from URI - CarlaString label2(label); + String label2(label); // truncate until last valid char for (std::size_t i=label2.length()-1; i != 0; --i) @@ -544,7 +544,7 @@ int main(int argc, char* argv[]) { if (sched_setscheduler(0, SCHED_RR|SCHED_RESET_ON_FORK, &sparam) < 0) { - CarlaString error(std::strerror(errno)); + String error(std::strerror(errno)); carla_stderr("Failed to set high priority, error %i: %s", errno, error.buffer()); } } diff --git a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp index 77af3202e..512e065db 100644 --- a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp +++ b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp @@ -1,19 +1,5 @@ -/* - * Carla LV2 Single Plugin - * Copyright (C) 2017-2024 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef BUILD_BRIDGE # error This file should not be compiled if not building bridge @@ -57,10 +43,10 @@ public: return; // xxxxx - CarlaString binaryDir(bundlePath); + String binaryDir(bundlePath); binaryDir += CARLA_OS_SEP_STR "bin" CARLA_OS_SEP_STR; - CarlaString resourceDir(bundlePath); + String resourceDir(bundlePath); resourceDir += CARLA_OS_SEP_STR "res" CARLA_OS_SEP_STR; pData->bufferSize = fBufferSize; @@ -79,8 +65,8 @@ public: if (pData->options.binaryDir != nullptr) delete[] pData->options.binaryDir; - pData->options.binaryDir = binaryDir.dup(); - pData->options.resourceDir = resourceDir.dup(); + pData->options.binaryDir = carla_strdup(binaryDir); + pData->options.resourceDir = carla_strdup(resourceDir); setCallback(_engine_callback, this); @@ -695,17 +681,17 @@ const LV2_Descriptor* lv2_descriptor(uint32_t index) if (index != 0) return nullptr; - static CarlaString ret; + static String ret; if (ret.isEmpty()) { using namespace water; const File file(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("ttl")); #ifdef CARLA_OS_WIN - ret = String("file:///" + file.getFullPathName()).toRawUTF8(); + ret = water::String("file:///" + file.getFullPathName()).toRawUTF8(); ret.replace('\\','/'); #else - ret = String("file://" + file.getFullPathName()).toRawUTF8(); + ret = water::String("file://" + file.getFullPathName()).toRawUTF8(); #endif } @@ -730,16 +716,16 @@ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index) { carla_debug("lv2ui_descriptor(%i)", index); - static CarlaString ret; + static String ret; { using namespace water; const File file(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("ext-ui")); #ifdef CARLA_OS_WIN - ret = String("file:///" + file.getFullPathName()).toRawUTF8(); + ret = water::String("file:///" + file.getFullPathName()).toRawUTF8(); ret.replace('\\','/'); #else - ret = String("file://" + file.getFullPathName()).toRawUTF8(); + ret = water::String("file://" + file.getFullPathName()).toRawUTF8(); #endif } diff --git a/source/bridges-ui/CarlaBridgeFormat.cpp b/source/bridges-ui/CarlaBridgeFormat.cpp index 2703fa289..58f11623b 100644 --- a/source/bridges-ui/CarlaBridgeFormat.cpp +++ b/source/bridges-ui/CarlaBridgeFormat.cpp @@ -1,29 +1,16 @@ -/* - * Carla Bridge UI - * Copyright (C) 2011-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaBridgeFormat.hpp" #include "CarlaBridgeToolkit.hpp" -#include "CarlaBase64Utils.hpp" #include "CarlaProcessUtils.hpp" -#include "CarlaTimeUtils.hpp" #include "CarlaMIDI.h" +#include "extra/Base64.hpp" +#include "extra/Sleep.hpp" + // needed for atom-util #ifndef nullptr # undef NULL @@ -127,7 +114,7 @@ bool CarlaBridgeFormat::msgReceived(const char* const msg) noexcept CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size), true); CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom, false, base64Size), true); - carla_getChunkFromBase64String_impl(fBase64ReservedChunk, base64atom); + d_getChunkFromBase64String_impl(fBase64ReservedChunk, base64atom); CARLA_SAFE_ASSERT_UINT2_RETURN(fBase64ReservedChunk.size() >= sizeof(LV2_Atom), fBase64ReservedChunk.size(), sizeof(LV2_Atom), true); @@ -320,7 +307,7 @@ bool CarlaBridgeFormat::init(const int argc, const char* argv[]) for (; ++fLastMsgTimer < 50 && ! fGotOptions;) { idlePipe(true); - carla_msleep(20); + d_msleep(20); } if (! fGotOptions) diff --git a/source/bridges-ui/CarlaBridgeFormat.hpp b/source/bridges-ui/CarlaBridgeFormat.hpp index c3f05e045..d978d95a6 100644 --- a/source/bridges-ui/CarlaBridgeFormat.hpp +++ b/source/bridges-ui/CarlaBridgeFormat.hpp @@ -1,19 +1,5 @@ -/* - * Carla Bridge UI - * Copyright (C) 2011-2021 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_BRIDGE_FORMAT_HPP_INCLUDED #define CARLA_BRIDGE_FORMAT_HPP_INCLUDED @@ -22,7 +8,8 @@ #include "CarlaLibUtils.hpp" #include "CarlaPipeUtils.hpp" -#include "CarlaString.hpp" + +#include "extra/String.hpp" #include "lv2/atom.h" #include "lv2/urid.h" @@ -144,7 +131,7 @@ public: /*! * Window title. */ - CarlaString windowTitle; + String windowTitle; /*! * Transient window id (parent), zero if unset. @@ -177,7 +164,7 @@ protected: CarlaBridgeToolkit* fToolkit; lib_t fLib; - CarlaString fLibFilename; + String fLibFilename; std::vector fBase64ReservedChunk; /*! @internal */ diff --git a/source/bridges-ui/CarlaBridgeFormatLV2.cpp b/source/bridges-ui/CarlaBridgeFormatLV2.cpp index 8637bec8c..92f74f1cb 100644 --- a/source/bridges-ui/CarlaBridgeFormatLV2.cpp +++ b/source/bridges-ui/CarlaBridgeFormatLV2.cpp @@ -1,19 +1,5 @@ -/* - * Carla Bridge UI - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaBridgeFormat.hpp" #include "CarlaBridgeToolkit.hpp" @@ -1555,7 +1541,7 @@ int main(int argc, const char* argv[]) // try to get sampleRate value if (const char* const sampleRateStr = std::getenv("CARLA_SAMPLE_RATE")) { - const CarlaScopedLocale csl; + const ScopedSafeLocale ssl; gInitialSampleRate = std::atof(sampleRateStr); } diff --git a/source/bridges-ui/CarlaBridgeToolkitNative.cpp b/source/bridges-ui/CarlaBridgeToolkitNative.cpp index 452598d8f..06b33b7db 100644 --- a/source/bridges-ui/CarlaBridgeToolkitNative.cpp +++ b/source/bridges-ui/CarlaBridgeToolkitNative.cpp @@ -1,32 +1,19 @@ -/* - * Carla Bridge UI - * Copyright (C) 2014-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaBridgeFormat.hpp" #include "CarlaBridgeToolkit.hpp" #include "CarlaMainLoop.hpp" #include "CarlaPluginUI.hpp" -#include "CarlaTimeUtils.hpp" #include "CarlaUtils.h" #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA) # include "CarlaMacUtils.hpp" #endif +#include "extra/Sleep.hpp" + #if defined(HAVE_X11) && defined(BRIDGE_X11) # include #endif @@ -118,9 +105,9 @@ public: fHostUI->idle(); #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) // MacOS and Win32 have event-loops to run, so minimize sleep time - carla_msleep(1); + d_msleep(1); #else - carla_msleep(33); + d_msleep(33); #endif } } diff --git a/source/bridges-ui/Makefile b/source/bridges-ui/Makefile index 243bbfa29..352e37892 100644 --- a/source/bridges-ui/Makefile +++ b/source/bridges-ui/Makefile @@ -22,7 +22,7 @@ endif # --------------------------------------------------------------------------------------------------------------------- -BUILD_CXX_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_UI -I. -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/utils -I$(CWD)/modules +BUILD_CXX_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_UI -I. -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils LINK_FLAGS += $(WATER_LIBS) ifneq ($(WASM),true) diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index 440064ccf..3d40a0ab7 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "CarlaBackendUtils.hpp" @@ -16,6 +16,8 @@ #include "CarlaVst3Utils.hpp" #include "CarlaClapUtils.hpp" +#include "extra/ScopedPointer.hpp" + #ifndef BUILDING_CARLA_FOR_WINE # include "CarlaPipeUtils.cpp" #endif @@ -152,7 +154,7 @@ public: }; #endif -CarlaScopedPointer gPipe; +ScopedPointer gPipe; // -------------------------------------------------------------------------------------------------------------------- // Don't print ELF/EXE related errors since discovery can find multi-architecture binaries @@ -799,7 +801,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) Lilv::Node bundleNode(lv2World.new_file_uri(nullptr, bundle)); CARLA_SAFE_ASSERT_RETURN(bundleNode.is_uri(),); - CarlaString sBundle(bundleNode.as_uri()); + String sBundle(bundleNode.as_uri()); if (! sBundle.endsWith("/")) sBundle += "/"; @@ -833,7 +835,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) const char* const URI = it.getValue(nullptr); CARLA_SAFE_ASSERT_CONTINUE(URI != nullptr); - CarlaScopedPointer rdfDescriptor(lv2_rdf_new(URI, false)); + ScopedPointer rdfDescriptor(lv2_rdf_new(URI, false)); if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr) { @@ -1155,9 +1157,9 @@ static bool do_vst2_check(lib_t& libHandle, const char* const filename, const bo gVstCurrentUniqueId = effect->uniqueID; char strBuf[STR_MAX+1]; - CarlaString cName; - CarlaString cProduct; - CarlaString cVendor; + String cName; + String cProduct; + String cVendor; PluginCategory category; LinkedList uniqueIds; @@ -1822,9 +1824,9 @@ static bool do_vst3_check(lib_t& libHandle, const char* const filename, const bo if (v3_cpp_obj(view)->is_platform_type_supported(view, V3_VIEW_PLATFORM_TYPE_NATIVE) == V3_TRUE) { hints |= PLUGIN_HAS_CUSTOM_UI; - #ifndef BUILD_BRIDGE hints |= PLUGIN_HAS_CUSTOM_EMBED_UI; - #endif + if (v3_cpp_obj(view)->can_resize(view) == V3_TRUE) + hints |= PLUGIN_HAS_CUSTOM_RESIZABLE_UI; } v3_cpp_obj_unref(view); @@ -2632,10 +2634,12 @@ static bool do_clap_check(lib_t& libHandle, const char* const filename, const bo if (gui != nullptr) { hints |= PLUGIN_HAS_CUSTOM_UI; - #ifndef BUILD_BRIDGE if (gui->is_api_supported(plugin, CLAP_WINDOW_API_NATIVE, false)) + { hints |= PLUGIN_HAS_CUSTOM_EMBED_UI; - #endif + if (gui->can_resize(plugin)) + hints |= PLUGIN_HAS_CUSTOM_RESIZABLE_UI; + } } #endif @@ -2739,8 +2743,8 @@ static void do_fluidsynth_check(const char* const filename, const PluginType typ delete_fluid_settings(f_settings); } - CarlaString name(file.getFileNameWithoutExtension().toRawUTF8()); - CarlaString label(name); + String name(file.getFileNameWithoutExtension().toRawUTF8()); + String label(name); // 2 channels DISCOVERY_OUT("init", "------------"); @@ -2852,7 +2856,7 @@ int main(int argc, const char* argv[]) const char* const filename = argv[2]; const PluginType type = getPluginTypeFromString(stype); - CarlaString filenameCheck(filename); + String filenameCheck(filename); filenameCheck.toLower(); bool openLib; diff --git a/source/frontend/C++/carla_app.cpp b/source/frontend/C++/carla_app.cpp index 15260332f..332aef341 100644 --- a/source/frontend/C++/carla_app.cpp +++ b/source/frontend/C++/carla_app.cpp @@ -58,8 +58,8 @@ CarlaApplication::CarlaApplication(const QString appName, int& argc, char* argv[ QApplication.addLibraryPath(CWD) // Needed for local wine build - if WINDOWS and CWD.endswith(("frontend", "resources")) and os.getenv("CXFREEZE") is None: - if kIs64bit: + if CARLA_OS_WIN and CWD.endswith(("frontend", "resources")) and os.getenv("CXFREEZE") is None: + if CARLA_OS_64BIT: path = "H:\\builds\\msys2-x86_64\\mingw64\\share\\qt5\\plugins" else: path = "H:\\builds\\msys2-i686\\mingw32\\share\\qt5\\plugins" diff --git a/source/frontend/Makefile b/source/frontend/Makefile index 805933756..9ba29c911 100644 --- a/source/frontend/Makefile +++ b/source/frontend/Makefile @@ -34,12 +34,24 @@ else NON_STATIC_LINK_FLAGS = $(LINK_FLAGS) endif +ifeq ($(STATIC_PLUGIN_TARGET),true) + ifeq ($(WINDOWS),true) QT_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_utils.dll else QT_LINK_FLAGS += -L$(BINDIR) -lcarla_utils endif +else + +ifeq ($(WINDOWS),true) +QT_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_standalone2.dll $(BINDIR)/libcarla_utils.dll +else +QT_LINK_FLAGS += -L$(BINDIR) -lcarla_standalone2 -lcarla_utils +endif + +endif + ifeq ($(MACOS),true) QT_LINK_FLAGS += -install_name @rpath/libcarla_frontend.dylib # FIXME this does not work: -Wl,-rpath,@loader_path @@ -58,6 +70,7 @@ QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES)) CPP_FILES = \ carla_frontend.cpp \ + dialogs/aboutdialog.cpp \ dialogs/jackappdialog.cpp \ pluginlist/pluginlistdialog.cpp @@ -69,7 +82,6 @@ OBJS = $(CPP_FILES:%=$(OBJDIR)/%.o) RES = \ qt_config.py \ resources_rc.py \ - $(BINDIR)/resources/modgui \ $(BINDIR)/resources/patchcanvas \ $(BINDIR)/resources/widgets \ $(BINDIR)/resources/bigmeter-ui \ @@ -80,7 +92,6 @@ RES = \ $(BINDIR)/resources/carla_backend_qt.py \ $(BINDIR)/resources/carla_host.py \ $(BINDIR)/resources/carla_host_control.py \ - $(BINDIR)/resources/carla_modgui.py \ $(BINDIR)/resources/carla_settings.py \ $(BINDIR)/resources/carla_skin.py \ $(BINDIR)/resources/carla_shared.py \ @@ -91,7 +102,6 @@ RES = \ $(BINDIR)/resources/notes-ui \ $(BINDIR)/resources/xycontroller-ui \ $(BINDIR)/resources/resources_rc.py \ - $(BINDIR)/resources/ui_carla_about.py \ $(BINDIR)/resources/ui_carla_edit.py \ $(BINDIR)/resources/ui_carla_host.py \ $(BINDIR)/resources/ui_carla_osc_connect.py \ @@ -124,11 +134,8 @@ PLUGINLIST_UI_FILES = $(wildcard pluginlist/*.ui) UIs = $(DIALOG_UI_FILES:dialogs/%.ui=dialogs/ui_%.h) UIs += $(PLUGINLIST_UI_FILES:pluginlist/%.ui=pluginlist/ui_%.h) -UIs += $(DIALOG_UI_FILES:%.ui=%_ui.py) - # old stuff, not yet converted UIs += \ - ui_carla_about.py \ ui_carla_edit.py \ ui_carla_host.py \ ui_carla_osc_connect.py \ diff --git a/source/frontend/carla-plugin b/source/frontend/carla-plugin index f23b0356e..a3850b915 100755 --- a/source/frontend/carla-plugin +++ b/source/frontend/carla-plugin @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -541,7 +541,7 @@ class CarlaEmbedW(QEmbedWidget): # set our gui as parent for all plugins UIs if self.host.manageUIs: - if MACOS: + if CARLA_OS_MAC: nsViewPtr = int(self.fWinId) winIdStr = "%x" % gCarla.utils.cocoa_get_window(nsViewPtr) else: @@ -579,7 +579,7 @@ if __name__ == '__main__': except: winId = 0 - usingEmbed = bool(LINUX and winId != 0) + usingEmbed = bool(CARLA_OS_LINUX and winId != 0) # ------------------------------------------------------------- # Init host backend (part 1) diff --git a/source/frontend/carla_app.py b/source/frontend/carla_app.py index d14d1cbb8..42cce8b7e 100644 --- a/source/frontend/carla_app.py +++ b/source/frontend/carla_app.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -18,6 +18,8 @@ from ctypes import CDLL, RTLD_GLOBAL from qt_compat import qt_config +# pylint: disable=import-error + if qt_config == 5: from PyQt5.QtCore import QT_VERSION, Qt, QCoreApplication, QLibraryInfo, QLocale, QTranslator from PyQt5.QtGui import QColor, QIcon, QPalette @@ -27,17 +29,26 @@ elif qt_config == 6: from PyQt6.QtGui import QColor, QIcon, QPalette from PyQt6.QtWidgets import QApplication +# pylint: enable=import-error +# pylint: disable=possibly-used-before-assignment + # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) -from carla_backend import kIs64bit, LINUX, MACOS, WINDOWS +from carla_backend import ( + CARLA_OS_64BIT, + CARLA_OS_LINUX, + CARLA_OS_MAC, + CARLA_OS_WIN, + CARLA_VERSION_STRING, +) from carla_shared import ( CARLA_KEY_MAIN_USE_PRO_THEME, CARLA_KEY_MAIN_PRO_THEME_COLOR, CARLA_DEFAULT_MAIN_USE_PRO_THEME, CARLA_DEFAULT_MAIN_PRO_THEME_COLOR, - CWD, VERSION, + CWD, getPaths, gCarla ) @@ -50,13 +61,13 @@ class CarlaApplication(): def __init__(self, appName = "Carla2", libPrefix = None): pathBinaries, pathResources = getPaths(libPrefix) - # Needed for MacOS and Windows - if os.path.exists(CWD) and (MACOS or WINDOWS): + # Needed for macOS and Windows + if os.path.exists(CWD) and (CARLA_OS_MAC or CARLA_OS_WIN): QApplication.addLibraryPath(CWD) # Needed for local wine build - if WINDOWS and CWD.endswith(("frontend", "resources")) and os.getenv("CXFREEZE") is None: - if kIs64bit: + if CARLA_OS_WIN and CWD.endswith(("frontend", "resources")) and os.getenv("CXFREEZE") is None: + if CARLA_OS_64BIT: path = "H:\\PawPawBuilds\\targets\\win64\\lib\\qt5\\plugins" else: path = "H:\\PawPawBuilds\\targets\\win32\\lib\\qt5\\plugins" @@ -94,7 +105,7 @@ class CarlaApplication(): # base settings settings = QSafeSettings("falkTX", appName) - useProTheme = MACOS or settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, CARLA_DEFAULT_MAIN_USE_PRO_THEME, bool) + useProTheme = CARLA_OS_MAC or settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, CARLA_DEFAULT_MAIN_USE_PRO_THEME, bool) if not useProTheme: self.createApp(appName) @@ -111,7 +122,7 @@ class CarlaApplication(): self.fApp.setStyle("carla" if stylesDir else "fusion") - if WINDOWS: + if CARLA_OS_WIN: carlastyle1 = os.path.join(pathBinaries, "styles", "carlastyle.dll") carlastyle2 = os.path.join(pathResources, "styles", "carlastyle.dll") carlastyle = carlastyle2 if os.path.exists(carlastyle2) else carlastyle1 @@ -123,14 +134,14 @@ class CarlaApplication(): # set palette proThemeColor = settings.value(CARLA_KEY_MAIN_PRO_THEME_COLOR, CARLA_DEFAULT_MAIN_PRO_THEME_COLOR, str).lower() - if MACOS or proThemeColor == "black": + if CARLA_OS_MAC or proThemeColor == "black": self.createPaletteBlack() elif proThemeColor == "blue": self.createPaletteBlue() def createApp(self, appName): - if qt_config == 5 and LINUX: + if qt_config == 5 and CARLA_OS_LINUX: # AA_X11InitThreads is not available on old PyQt versions try: attr = Qt.AA_X11InitThreads @@ -142,17 +153,17 @@ class CarlaApplication(): QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) - if MACOS: + if CARLA_OS_MAC: QApplication.setAttribute(Qt.AA_DontShowIconsInMenus) args = sys.argv[:] - if WINDOWS: + if CARLA_OS_WIN: args += ["-platform", "windows:fontengine=freetype"] self.fApp = QCoreApplication(args) if gCarla.nogui else QApplication(args) self.fApp.setApplicationName(appName) - self.fApp.setApplicationVersion(VERSION) + self.fApp.setApplicationVersion(CARLA_VERSION_STRING) self.fApp.setOrganizationName("falkTX") if self.fAppTranslator is not None: @@ -306,3 +317,4 @@ class CarlaApplication(): self.fApp.quit() # ------------------------------------------------------------------------------------------------------------ +# pylint: enable=possibly-used-before-assignment diff --git a/source/frontend/carla_backend.py b/source/frontend/carla_backend.py index 9ff33e39e..15b93a158 100644 --- a/source/frontend/carla_backend.py +++ b/source/frontend/carla_backend.py @@ -1,20 +1,6 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla Backend code -# Copyright (C) 2011-2021 Filipe Coelho -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +# SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- # Imports (Global) @@ -36,14 +22,27 @@ from ctypes import ( # Imports (Custom) from common import ( - kIs64bit, HAIKU, LINUX, MACOS, WINDOWS, VERSION + CARLA_OS_64BIT, + CARLA_OS_BSD, + CARLA_OS_GNU_HURD, + CARLA_OS_HAIKU, + CARLA_OS_LINUX, + CARLA_OS_MAC, + CARLA_OS_UNIX, + CARLA_OS_WASM, + CARLA_OS_WIN, + CARLA_OS_WIN32, + CARLA_OS_WIN64, + CARLA_VERSION_HEX, + CARLA_VERSION_STRING, + CARLA_VERSION_STRMIN, ) # --------------------------------------------------------------------------------------------------------------------- # Define custom types c_enum = c_int -c_uintptr = c_uint64 if kIs64bit else c_uint32 +c_uintptr = c_uint64 if CARLA_OS_64BIT else c_uint32 # --------------------------------------------------------------------------------------------------------------------- # Convert a ctypes c_char_p into a python string @@ -208,6 +207,21 @@ PLUGIN_USES_MULTI_PROGS = 0x400 # Plugin can make use of inline display API. PLUGIN_HAS_INLINE_DISPLAY = 0x800 +# Plugin has its own custom UI which can be embed into another Window. +# @see carla_embed_custom_ui() +# @note This is very experimental and subject to change at this point +PLUGIN_HAS_CUSTOM_EMBED_UI = 0x1000 + +# Plugin custom UI is a fake one that simply invokes an open file browser dialog. +PLUGIN_HAS_CUSTOM_UI_USING_FILE_OPEN = 0x2000 + +# Plugin needs all idle events in the main thread. +# @note Not possible on all engine implementations. +PLUGIN_NEEDS_MAIN_THREAD_IDLE = 0x4000 + +# Plugin has its own custom UI which is user resizable. +PLUGIN_HAS_CUSTOM_RESIZABLE_UI = 0x8000 + # --------------------------------------------------------------------------------------------------------------------- # Plugin Options # Various plugin options. @@ -1513,10 +1527,14 @@ PyCarlaRuntimeEngineDriverDeviceInfo = { # --------------------------------------------------------------------------------------------------------------------- # Set BINARY_NATIVE -if WINDOWS: - BINARY_NATIVE = BINARY_WIN64 if kIs64bit else BINARY_WIN32 +if CARLA_OS_WIN64: + BINARY_NATIVE = BINARY_WIN64 +elif CARLA_OS_WIN32: + BINARY_NATIVE = BINARY_WIN32 +elif CARLA_OS_64BIT: + BINARY_NATIVE = BINARY_POSIX64 else: - BINARY_NATIVE = BINARY_POSIX64 if kIs64bit else BINARY_POSIX32 + BINARY_NATIVE = BINARY_POSIX32 # --------------------------------------------------------------------------------------------------------------------- # Carla Host object (Meta) @@ -1528,6 +1546,7 @@ class CarlaHostMeta(): self.isPlugin = False self.isRemote = False self.nsmOK = False + self.handle = None # settings self.processMode = ENGINE_PROCESS_MODE_PATCHBAY diff --git a/source/frontend/carla_frontend.cpp b/source/frontend/carla_frontend.cpp index de2dc26ec..31da0358f 100644 --- a/source/frontend/carla_frontend.cpp +++ b/source/frontend/carla_frontend.cpp @@ -1,23 +1,136 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "carla_frontend.h" // ------------------------------------------------------------------------------------------------------------------- // common files #include "utils/qsafesettings.cpp" -// ------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- +// aboutdialog + +#include "dialogs/aboutdialog.hpp" + +void carla_frontend_createAndExecAboutDialog(QWidget* const parent, + const CarlaHostHandle hostHandle, + const bool isControl, + const bool isPlugin) +{ + AboutDialog(parent, hostHandle, isControl, isPlugin).exec(); +} + +// -------------------------------------------------------------------------------------------------------------------- +// jackappdialog + +#include "dialogs/jackappdialog.hpp" +#include "extra/String.hpp" + +const JackAppDialogResults* +carla_frontend_createAndExecJackAppDialog(QWidget* const parent, const char* const projectFilename) +{ + JackAppDialog gui(parent, projectFilename); + + if (gui.exec()) + { + static JackAppDialogResults ret = {}; + static String retCommand; + static String retName; + static String retLabelSetup; + + const JackAppDialog::CommandAndFlags cafs = gui.getCommandAndFlags(); + retCommand = cafs.command.toUtf8().constData(); + retName = cafs.name.toUtf8().constData(); + retLabelSetup = cafs.labelSetup.toUtf8().constData(); + + ret.command = retCommand; + ret.name = retName; + ret.labelSetup = retLabelSetup; + + return &ret; + } + + return nullptr; +} + +// -------------------------------------------------------------------------------------------------------------------- +// pluginlistdialog + +#include "pluginlist/pluginlistdialog.hpp" +#include "CarlaUtils.h" + +PluginListDialog* +carla_frontend_createPluginListDialog(QWidget* const parent, const HostSettings* const hostSettings) +{ + return new PluginListDialog(parent, hostSettings); +} + +void +carla_frontend_destroyPluginListDialog(PluginListDialog* const dialog) +{ + dialog->close(); + delete dialog; +} + +void +carla_frontend_setPluginListDialogPath(PluginListDialog* const dialog, const int ptype, const char* const path) +{ + dialog->setPluginPath(static_cast(ptype), path); +} + +const PluginListDialogResults* +carla_frontend_execPluginListDialog(PluginListDialog* const dialog) +{ + if (dialog->exec()) + { + static PluginListDialogResults ret; + static String category; + static String filename; + static String name; + static String label; + static String maker; + + const PluginInfo& plugin(dialog->getSelectedPluginInfo()); + + category = plugin.category.toUtf8(); + filename = plugin.filename.toUtf8(); + name = plugin.name.toUtf8(); + label = plugin.label.toUtf8(); + maker = plugin.maker.toUtf8(); + + ret.build = plugin.build; + ret.type = plugin.type; + ret.hints = plugin.hints; + ret.category = category; + ret.filename = filename; + ret.name = name; + ret.label = label; + ret.maker = maker; + ret.uniqueId = plugin.uniqueId; + ret.audioIns = plugin.audioIns; + ret.audioOuts = plugin.audioOuts; + ret.cvIns = plugin.cvIns; + ret.cvOuts = plugin.cvOuts; + ret.midiIns = plugin.midiIns; + ret.midiOuts = plugin.midiOuts; + ret.parameterIns = plugin.parameterIns; + ret.parameterOuts = plugin.parameterOuts; + + return &ret; + } + + return nullptr; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// const PluginListDialogResults* +// carla_frontend_createAndExecPluginListDialog(void* const parent, const HostSettings* const hostSettings) +// { +// PluginListDialog gui(reinterpret_cast(parent), hostSettings); +// +// return carla_frontend_execPluginListDialog(&gui); +// } + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/CarlaFrontend.h b/source/frontend/carla_frontend.h similarity index 73% rename from source/frontend/CarlaFrontend.h rename to source/frontend/carla_frontend.h index 4d2500bcd..98ddcaeab 100644 --- a/source/frontend/CarlaFrontend.h +++ b/source/frontend/carla_frontend.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -10,6 +10,8 @@ using CARLA_BACKEND_NAMESPACE::PluginType; extern "C" { #endif +typedef struct _CarlaHostHandle* CarlaHostHandle; + // -------------------------------------------------------------------------------------------------------------------- typedef struct { @@ -49,17 +51,26 @@ typedef struct { #ifdef __cplusplus class PluginListDialog; +class QWidget; #else struct PluginListDialog; +struct QWidget; #endif // -------------------------------------------------------------------------------------------------------------------- +CARLA_PLUGIN_EXPORT void +carla_frontend_createAndExecAboutDialog(QWidget* parent, CarlaHostHandle hostHandle, bool isControl, bool isPlugin); + +// -------------------------------------------------------------------------------------------------------------------- + CARLA_PLUGIN_EXPORT const JackAppDialogResults* -carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename); +carla_frontend_createAndExecJackAppDialog(QWidget* parent, const char* projectFilename); + +// -------------------------------------------------------------------------------------------------------------------- CARLA_PLUGIN_EXPORT PluginListDialog* -carla_frontend_createPluginListDialog(void* parent, const HostSettings* hostSettings); +carla_frontend_createPluginListDialog(QWidget* parent, const HostSettings* hostSettings); CARLA_PLUGIN_EXPORT void carla_frontend_destroyPluginListDialog(PluginListDialog* dialog); diff --git a/source/frontend/carla_frontend.py b/source/frontend/carla_frontend.py index f741a1a6a..8167cf055 100644 --- a/source/frontend/carla_frontend.py +++ b/source/frontend/carla_frontend.py @@ -81,6 +81,9 @@ class CarlaFrontendLib(): def __init__(self, filename): self.lib = cdll.LoadLibrary(filename) + self.lib.carla_frontend_createAndExecAboutDialog.argtypes = (c_void_p, c_void_p, c_bool, c_bool) + self.lib.carla_frontend_createAndExecAboutDialog.restype = None + self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) @@ -98,9 +101,16 @@ class CarlaFrontendLib(): # -------------------------------------------------------------------------------------------------------- + def createAndExecAboutDialog(self, parent, hostHandle, isControl, isPlugin): + return structToDictOrNull(self.lib.carla_frontend_createAndExecAboutDialog(unwrapinstance(parent), + hostHandle, + isControl, + isPlugin)) + def createAndExecJackAppDialog(self, parent, projectFilename): - return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), - projectFilename.encode("utf-8"))) + return structToDictOrNull( + self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), + projectFilename.encode("utf-8"))) def createPluginListDialog(self, parent, hostSettings): hostSettingsC = HostSettings() diff --git a/source/frontend/carla_host.py b/source/frontend/carla_host.py index 09f572ffb..4af6fd9c4 100644 --- a/source/frontend/carla_host.py +++ b/source/frontend/carla_host.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -110,7 +110,10 @@ from widgets.pixmapkeyboard import PixmapKeyboardHArea # Try Import OpenGL try: - from PyQt5.QtOpenGL import QGLWidget + if qt_config == 5: + from PyQt5.QtOpenGL import QGLWidget + elif qt_config == 6: + from PyQt6.QtOpenGL import QGLWidget hasGL = True except: hasGL = False @@ -220,7 +223,7 @@ class HostWindow(QMainWindow): self.fOscAddressTCP = "" self.fOscAddressUDP = "" - if MACOS: + if CARLA_OS_MAC: self.fMacClosingHelper = True # CancelableActionCallback Box @@ -304,7 +307,7 @@ class HostWindow(QMainWindow): else: self.ui.act_engine_start.setEnabled(True) - if WINDOWS: + if CARLA_OS_WIN: self.ui.tabWidget.removeTab(2) if self.host.isControl: @@ -356,7 +359,7 @@ class HostWindow(QMainWindow): self.ui.menu_Canvas.menuAction().setVisible(False) self.ui.tw_miniCanvas.hide() self.ui.tabWidget.removeTab(1) - if WINDOWS: + if CARLA_OS_WIN: self.ui.tabWidget.tabBar().hide() # ---------------------------------------------------------------------------------------------------- @@ -471,7 +474,7 @@ class HostWindow(QMainWindow): # ---------------------------------------------------------------------------------------------------- # Set up GUI (special stuff for Mac OS) - if MACOS: + if CARLA_OS_MAC: self.ui.act_file_quit.setMenuRole(QAction.QuitRole) self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole) self.ui.act_help_about.setMenuRole(QAction.AboutRole) @@ -2102,7 +2105,7 @@ class HostWindow(QMainWindow): folder = diskFolders[i] self.ui.cb_disk.addItem(os.path.basename(folder), folder) - #if MACOS and not settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, bool): + #if CARLA_OS_MAC and not settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, bool): # self.setUnifiedTitleAndToolBarOnMac(True) showMeters = settings.value("ShowMeters", True, bool) @@ -2288,7 +2291,10 @@ class HostWindow(QMainWindow): @pyqtSlot() def slot_aboutCarla(self): - CarlaAboutW(self.fParentOrSelf, self.host).exec_() + gCarla.felib.createAndExecAboutDialog(self.fParentOrSelf, + self.host.handle, + self.host.isControl, + self.host.isPlugin) @pyqtSlot() def slot_aboutQt(self): @@ -2912,10 +2918,10 @@ class HostWindow(QMainWindow): # set our gui as parent for all plugins UIs if self.host.manageUIs and not self.host.isControl: - if MACOS: + if CARLA_OS_MAC: nsViewPtr = int(self.winId()) winIdStr = "%x" % gCarla.utils.cocoa_get_window(nsViewPtr) - elif WINDOWS or QApplication.platformName() == "xcb": + elif CARLA_OS_WIN or QApplication.platformName() == "xcb": winIdStr = "%x" % int(self.winId()) else: winIdStr = "0" @@ -3077,7 +3083,7 @@ class HostWindow(QMainWindow): #def paintEvent(self, event): #QMainWindow.paintEvent(self, event) - #if MACOS or not self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING]: + #if CARLA_OS_MAC or not self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING]: #return #painter = QPainter(self) @@ -3113,7 +3119,7 @@ class HostWindow(QMainWindow): patchcanvas.handleAllPluginsRemoved() - if MACOS and self.fMacClosingHelper and not (self.host.isControl or self.host.isPlugin): + if CARLA_OS_MAC and self.fMacClosingHelper and not (self.host.isControl or self.host.isPlugin): self.fCustomStopAction = self.CUSTOM_ACTION_APP_CLOSE self.fMacClosingHelper = False event.ignore() @@ -3423,7 +3429,7 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No # Print info if not (gCarla.nogui and isinstance(gCarla.nogui, int)): - print("Carla %s started, status:" % VERSION) + print("Carla %s started, status:" % CARLA_VERSION_STRING) print(" Python version: %s" % sys.version.split(" ",1)[0]) print(" Qt version: %s" % QT_VERSION_STR) print(" PyQt version: %s" % PYQT_VERSION_STR) @@ -3502,7 +3508,7 @@ def loadHostSettings(host): host.preferPluginBridges = settings.value(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, bool) host.preferUIBridges = settings.value(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, CARLA_DEFAULT_PREFER_UI_BRIDGES, bool) host.preventBadBehaviour = settings.value(CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR, CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR, bool) - host.showLogs = settings.value(CARLA_KEY_MAIN_SHOW_LOGS, CARLA_DEFAULT_MAIN_SHOW_LOGS, bool) and not WINDOWS + host.showLogs = settings.value(CARLA_KEY_MAIN_SHOW_LOGS, CARLA_DEFAULT_MAIN_SHOW_LOGS, bool) and not CARLA_OS_WIN host.showPluginBridges = settings.value(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES, bool) host.showWineBridges = settings.value(CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES, bool) host.uiBridgesTimeout = settings.value(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, CARLA_DEFAULT_UI_BRIDGES_TIMEOUT, int) diff --git a/source/frontend/carla_host_control.py b/source/frontend/carla_host_control.py index 7defa8435..8df839d3a 100755 --- a/source/frontend/carla_host_control.py +++ b/source/frontend/carla_host_control.py @@ -23,16 +23,28 @@ from carla_host import * # ------------------------------------------------------------------------------------------------------------ # Imports (liblo) -from liblo import ( - Address, - AddressError, - ServerError, - Server, - make_method, - send as lo_send, - TCP as LO_TCP, - UDP as LO_UDP, -) +try: + from pyliblo3 import ( + Address, + AddressError, + ServerError, + Server, + make_method, + send as lo_send, + TCP as LO_TCP, + UDP as LO_UDP, + ) +except ModuleNotFoundError: + from liblo import ( + Address, + AddressError, + ServerError, + Server, + make_method, + send as lo_send, + TCP as LO_TCP, + UDP as LO_UDP, + ) from random import random diff --git a/source/frontend/carla_modgui.py b/source/frontend/carla_modgui.py deleted file mode 100755 index f8060df53..000000000 --- a/source/frontend/carla_modgui.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla bridge for LV2 modguis -# Copyright (C) 2015-2019 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. - -# ------------------------------------------------------------------------------------------------------------ -# Imports (Global) - -import os -import sys - -# ------------------------------------------------------------------------------------------------------------ -# Imports (local) - -from carla_app import CarlaApplication, gCarla, getPaths -from carla_shared import DLL_EXTENSION, setUpSignals -from carla_utils import CarlaUtils - -from modgui.host import HostWindow - -# ------------------------------------------------------------------------------------------------------------ -# Main - -if __name__ == '__main__': - # ------------------------------------------------------------- - # Read CLI args - - if len(sys.argv) < 2: - print("usage: %s " % sys.argv[0]) - sys.exit(1) - - libPrefix = os.getenv("CARLA_LIB_PREFIX") - - # ------------------------------------------------------------- - # App initialization - - app = CarlaApplication("Carla2-MODGUI", libPrefix) - - # ------------------------------------------------------------- - # Init utils - - pathBinaries, pathResources = getPaths(libPrefix) - - utilsname = "libcarla_utils.%s" % (DLL_EXTENSION) - - gCarla.utils = CarlaUtils(os.path.join(pathBinaries, utilsname)) - gCarla.utils.set_process_name("carla-bridge-lv2-modgui") - - # ------------------------------------------------------------- - # Set-up custom signal handling - - setUpSignals() - - # ------------------------------------------------------------- - # Create GUI - - gui = HostWindow() - - # -------------------------------------------------------------------------------------------------------- - # App-Loop - - app.exit_exec() - -# ------------------------------------------------------------------------------------------------------------ diff --git a/source/frontend/carla_settings.py b/source/frontend/carla_settings.py index b35c2ddc0..80fff3340 100755 --- a/source/frontend/carla_settings.py +++ b/source/frontend/carla_settings.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- @@ -21,7 +21,9 @@ import ui_carla_settings import ui_carla_settings_driver from carla_backend import ( - LINUX, MACOS, WINDOWS, + CARLA_OS_LINUX, + CARLA_OS_MAC, + CARLA_OS_WIN, ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL, ENGINE_DRIVER_DEVICE_CAN_TRIPLE_BUFFER, ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE, @@ -215,7 +217,7 @@ class DriverSettingsW(QDialog): self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - if MACOS: + if CARLA_OS_MAC: self.setWindowModality(Qt.WindowModal) # ------------------------------------------------------------------------------------------------------------- @@ -406,7 +408,7 @@ class RuntimeDriverSettingsW(QDialog): self.adjustSize() self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - if MACOS: + if CARLA_OS_MAC: self.setWindowModality(Qt.WindowModal) # ------------------------------------------------------------------------------------------------------------- @@ -533,11 +535,11 @@ class CarlaSettingsW(QDialog): for i in range(Theme.THEME_MAX): self.ui.cb_canvas_theme.addItem(getThemeName(i)) - if MACOS: + if CARLA_OS_MAC: self.ui.group_main_theme.setEnabled(False) self.ui.group_main_theme.setVisible(False) - if WINDOWS or host.isControl: + if CARLA_OS_WIN or host.isControl: self.ui.ch_main_show_logs.setEnabled(False) self.ui.ch_main_show_logs.setVisible(False) @@ -576,15 +578,15 @@ class CarlaSettingsW(QDialog): self.ui.lw_page.hideRow(self.TAB_INDEX_OSC) self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) - if not LINUX: + if not CARLA_OS_LINUX: self.ui.ch_exp_wine_bridges.setVisible(False) self.ui.ch_exp_prevent_bad_behaviour.setVisible(False) self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) - if not MACOS: + if not CARLA_OS_MAC: self.ui.label_engine_ui_bridges_mac_note.setVisible(False) - if not (LINUX or MACOS): + if not (CARLA_OS_LINUX or CARLA_OS_MAC): self.ui.ch_exp_jack_apps.setVisible(False) # FIXME, not implemented yet @@ -599,7 +601,7 @@ class CarlaSettingsW(QDialog): self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - if MACOS: + if CARLA_OS_MAC: self.setWindowModality(Qt.WindowModal) # ------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/carla_shared.py b/source/frontend/carla_shared.py index e8a7c66e2..aae07a0d0 100644 --- a/source/frontend/carla_shared.py +++ b/source/frontend/carla_shared.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -26,6 +26,8 @@ except: from qt_compat import qt_config +# pylint: disable=import-error + if qt_config == 5: # import changed in PyQt 5.15.8, so try both try: @@ -42,19 +44,25 @@ elif qt_config == 6: from PyQt6.QtGui import QIcon from PyQt6.QtWidgets import QFileDialog, QMessageBox +# pylint: enable=import-error +# pylint: disable=possibly-used-before-assignment + # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from carla_backend import ( + CARLA_OS_64BIT, + CARLA_OS_HAIKU, + CARLA_OS_MAC, + CARLA_OS_WIN, + CARLA_VERSION_STRING, MAX_DEFAULT_PARAMETERS, ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, ENGINE_PROCESS_MODE_PATCHBAY, ENGINE_TRANSPORT_MODE_INTERNAL, - ENGINE_TRANSPORT_MODE_JACK + ENGINE_TRANSPORT_MODE_JACK, ) -from common import kIs64bit, HAIKU, LINUX, MACOS, WINDOWS, VERSION - # ------------------------------------------------------------------------------------------------------------ # Config @@ -65,7 +73,7 @@ X_DATADIR_X = None # ------------------------------------------------------------------------------------------------------------ # Platform specific stuff -if WINDOWS: +if CARLA_OS_WIN: WINDIR = os.getenv("WINDIR") # ------------------------------------------------------------------------------------------------------------ @@ -74,7 +82,7 @@ if WINDOWS: envTMP = os.getenv("TMP") if envTMP is None: - if WINDOWS: + if CARLA_OS_WIN: qWarning("TMP variable not set") TMP = QDir.tempPath() else: @@ -92,7 +100,7 @@ del envTMP envHOME = os.getenv("HOME") if envHOME is None: - if not WINDOWS: + if not CARLA_OS_WIN: qWarning("HOME variable not set") HOME = QDir.toNativeSeparators(QDir.homePath()) else: @@ -111,9 +119,9 @@ envPATH = os.getenv("PATH") if envPATH is None: qWarning("PATH variable not set") - if MACOS: + if CARLA_OS_MAC: PATH = ("/opt/local/bin", "/usr/local/bin", "/usr/bin", "/bin") - elif WINDOWS: + elif CARLA_OS_WIN: PATH = (os.path.join(WINDIR, "system32"), WINDIR) else: PATH = ("/usr/local/bin", "/usr/bin", "/bin") @@ -262,7 +270,7 @@ CARLA_DEFAULT_MAIN_PRO_THEME_COLOR = "Black" CARLA_DEFAULT_MAIN_REFRESH_INTERVAL = 20 CARLA_DEFAULT_MAIN_CONFIRM_EXIT = True CARLA_DEFAULT_MAIN_CLASSIC_SKIN = False -CARLA_DEFAULT_MAIN_SHOW_LOGS = bool(not WINDOWS) +CARLA_DEFAULT_MAIN_SHOW_LOGS = bool(not CARLA_OS_WIN) CARLA_DEFAULT_MAIN_SYSTEM_ICONS = False CARLA_DEFAULT_MAIN_EXPERIMENTAL = False @@ -296,11 +304,11 @@ CARLA_DEFAULT_AUDIO_BUFFER_SIZE = 512 CARLA_DEFAULT_AUDIO_SAMPLE_RATE = 44100 CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER = False -if HAIKU: +if CARLA_OS_HAIKU: CARLA_DEFAULT_AUDIO_DRIVER = "SDL" -elif MACOS: +elif CARLA_OS_MAC: CARLA_DEFAULT_AUDIO_DRIVER = "CoreAudio" -elif WINDOWS: +elif CARLA_OS_WIN: CARLA_DEFAULT_AUDIO_DRIVER = "Windows Audio" elif os.path.exists("/usr/bin/jackd") or os.path.exists("/usr/bin/jackdbus") or os.path.exists("/usr/bin/pw-jack"): CARLA_DEFAULT_AUDIO_DRIVER = "JACK" @@ -315,7 +323,7 @@ else: CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_INTERNAL # OSC -CARLA_DEFAULT_OSC_ENABLED = not (MACOS or WINDOWS) +CARLA_DEFAULT_OSC_ENABLED = not (CARLA_OS_MAC or CARLA_OS_WIN) CARLA_DEFAULT_OSC_TCP_PORT_ENABLED = True CARLA_DEFAULT_OSC_TCP_PORT_NUMBER = 22752 CARLA_DEFAULT_OSC_TCP_PORT_RANDOM = False @@ -358,7 +366,7 @@ DEFAULT_SF2_PATH = "" DEFAULT_SFZ_PATH = "" DEFAULT_JSFX_PATH = "" -if WINDOWS: +if CARLA_OS_WIN: splitter = ";" APPDATA = os.getenv("APPDATA") @@ -396,7 +404,7 @@ if WINDOWS: DEFAULT_JSFX_PATH = APPDATA + "\\REAPER\\Effects" #DEFAULT_JSFX_PATH += ";" + PROGRAMFILES + "\\REAPER\\InstallData\\Effects" - if kIs64bit: + if CARLA_OS_64BIT: DEFAULT_VST2_PATH += ";" + COMMONPROGRAMFILES + "\\VST2" DEFAULT_VST3_PATH = COMMONPROGRAMFILES + "\\VST3" @@ -419,7 +427,7 @@ if WINDOWS: DEFAULT_VST3_PATH += COMMONPROGRAMFILESx86 + "\\VST3" DEFAULT_CLAP_PATH += COMMONPROGRAMFILESx86 + "\\CLAP" -elif HAIKU: +elif CARLA_OS_HAIKU: splitter = ":" DEFAULT_LADSPA_PATH = HOME + "/.ladspa" @@ -442,7 +450,7 @@ elif HAIKU: DEFAULT_CLAP_PATH = HOME + "/.clap" DEFAULT_CLAP_PATH += ":/system/add-ons/media/clapplugins" -elif MACOS: +elif CARLA_OS_MAC: splitter = ":" DEFAULT_LADSPA_PATH = HOME + "/Library/Audio/Plug-Ins/LADSPA" @@ -511,7 +519,7 @@ else: DEFAULT_JSFX_PATH = CONFIG_HOME + "/REAPER/Effects" #DEFAULT_JSFX_PATH += ":" + "/opt/REAPER/InstallData/Effects" -if not WINDOWS: +if not CARLA_OS_WIN: winePrefix = os.getenv("WINEPREFIX") if not winePrefix: @@ -525,7 +533,7 @@ if not WINDOWS: DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3" DEFAULT_CLAP_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP" - if kIs64bit: + if CARLA_OS_64BIT: DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins" DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VSTPlugins" DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VstPlugins" @@ -540,7 +548,7 @@ if not WINDOWS: readEnvVars = True -if WINDOWS: +if CARLA_OS_WIN: # Check if running Wine. If yes, ignore env vars # pylint: disable=import-error from winreg import ConnectRegistry, OpenKey, CloseKey, HKEY_CURRENT_USER @@ -620,7 +628,7 @@ if os.path.isfile(CWD): if CWD.endswith("/lib"): CWD = CWD.rsplit("/lib",1)[0] CXFREEZE = True - if not WINDOWS: + if not CARLA_OS_WIN: os.environ['CARLA_MAGIC_FILE'] = os.path.join(CWD, "magic.mgc") else: CXFREEZE = False @@ -628,9 +636,9 @@ else: # ------------------------------------------------------------------------------------------------------------ # Set DLL_EXTENSION -if WINDOWS: +if CARLA_OS_WIN: DLL_EXTENSION = "dll" -elif MACOS: +elif CARLA_OS_MAC: DLL_EXTENSION = "dylib" else: DLL_EXTENSION = "so" @@ -708,7 +716,7 @@ def handleInitialCommandLineArguments(file): elif arg in ("-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui"): gCarla.nogui = True - elif MACOS and arg.startswith("-psn_"): + elif CARLA_OS_MAC and arg.startswith("-psn_"): pass elif arg in ("-h", "--h", "-help", "--help"): @@ -737,7 +745,7 @@ def handleInitialCommandLineArguments(file): elif arg in ("-v", "--v", "-version", "--version"): pathBinaries, pathResources = getPaths(libPrefix) - print("Using Carla version %s" % VERSION) + print("Using Carla version %s" % CARLA_VERSION_STRING) print(" Python version: %s" % sys.version.split(" ",1)[0]) print(" Qt version: %s" % QT_VERSION_STR) print(" PyQt version: %s" % PYQT_VERSION_STR) @@ -785,7 +793,7 @@ def getInitialProjectFile(skipExistCheck = False): continue if arg in ("-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui", "--gdb"): continue - if MACOS and arg.startswith("-psn_"): + if CARLA_OS_MAC and arg.startswith("-psn_"): continue arg = os.path.expanduser(arg) if skipExistCheck or os.path.exists(arg): @@ -914,7 +922,10 @@ def CustomMessageBox(parent, icon, title, text, msgBox.setInformativeText(extraText) msgBox.setStandardButtons(buttons) msgBox.setDefaultButton(defButton) + # pylint: disable=no-value-for-parameter return msgBox.exec_() + # pylint: enable=no-value-for-parameter # pylint: enable=too-many-arguments # ------------------------------------------------------------------------------------------------------------ +# pylint: enable=possibly-used-before-assignment diff --git a/source/frontend/carla_utils.py b/source/frontend/carla_utils.py index 4f6b13530..126e1a850 100644 --- a/source/frontend/carla_utils.py +++ b/source/frontend/carla_utils.py @@ -1,20 +1,6 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla Backend utils -# Copyright (C) 2011-2020 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +# SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ # Imports (Global) @@ -35,6 +21,7 @@ from ctypes import ( # Imports (Custom) from carla_backend import ( + CARLA_OS_WIN, PLUGIN_NONE, PLUGIN_INTERNAL, PLUGIN_LADSPA, @@ -60,7 +47,6 @@ from carla_backend import ( PLUGIN_CATEGORY_MODULATOR, PLUGIN_CATEGORY_UTILITY, PLUGIN_CATEGORY_OTHER, - WINDOWS, c_enum, c_uintptr, charPtrToString, charPtrPtrToStringList, @@ -347,7 +333,7 @@ class CarlaUtils(): self._pipeClientCallback = None # use _putenv on windows - if not WINDOWS: + if not CARLA_OS_WIN: self.msvcrt = None return @@ -363,7 +349,7 @@ class CarlaUtils(): def setenv(self, key, value): environ[key] = value - if WINDOWS: + if CARLA_OS_WIN: keyvalue = "%s=%s" % (key, value) # pylint: disable=protected-access self.msvcrt._putenv(keyvalue.encode("utf-8")) @@ -374,7 +360,7 @@ class CarlaUtils(): if environ.get(key) is not None: environ.pop(key) - if WINDOWS: + if CARLA_OS_WIN: keyrm = "%s=" % key # pylint: disable=protected-access self.msvcrt._putenv(keyrm.encode("utf-8")) diff --git a/source/frontend/carla_widgets.py b/source/frontend/carla_widgets.py index 136268467..0a90cdd12 100755 --- a/source/frontend/carla_widgets.py +++ b/source/frontend/carla_widgets.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -42,13 +42,14 @@ elif qt_config == 6: # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) -import ui_carla_about import ui_carla_edit import ui_carla_parameter from carla_backend import ( - MACOS, WINDOWS, BINARY_NATIVE, + CARLA_VERSION_STRING, + CARLA_OS_MAC, + CARLA_OS_WIN, PLUGIN_INTERNAL, PLUGIN_DSSI, PLUGIN_LV2, @@ -92,7 +93,6 @@ from carla_backend import ( from carla_shared import ( MIDI_CC_LIST, MAX_MIDI_CC_LIST_ITEM, - VERSION, countDecimalPoints, fontMetricsHorizontalAdvance, setUpSignals, @@ -100,7 +100,6 @@ from carla_shared import ( ) from carla_utils import getPluginTypeAsString -#) from widgets.collapsablewidget import CollapsibleBox from widgets.pixmapkeyboard import PixmapKeyboardHArea @@ -113,135 +112,6 @@ ICON_STATE_WAIT = 2 # nothing, sets as off ICON_STATE_OFF = 1 # turns off, sets as null ICON_STATE_NULL = 0 # nothing -# ------------------------------------------------------------------------------------------------------------ -# Carla About dialog - -class CarlaAboutW(QDialog): - def __init__(self, parent, host): - QDialog.__init__(self, parent) - self.ui = ui_carla_about.Ui_CarlaAboutW() - self.ui.setupUi(self) - - if host.isControl: - extraInfo = " - %s" % self.tr("OSC Bridge Version") - elif host.isPlugin: - extraInfo = " - %s" % self.tr("Plugin Version") - else: - extraInfo = "" - - self.ui.l_about.setText(self.tr("" - "
Version %s" - "
Carla is a fully-featured audio plugin host%s.
" - "
Copyright (C) 2011-2022 falkTX
" - "" % (VERSION, extraInfo))) - - if self.ui.about.palette().color(QPalette.Background).blackF() < 0.5: - self.ui.l_icons.setPixmap(QPixmap(":/bitmaps/carla_about_black.png")) - self.ui.ico_example_edit.setPixmap(QPixmap(":/bitmaps/button_file-black.png")) - self.ui.ico_example_file.setPixmap(QPixmap(":/scalable/button_edit-black.svg")) - self.ui.ico_example_gui.setPixmap(QPixmap(":/bitmaps/button_gui-black.png")) - - if host.isControl: - self.ui.l_extended.hide() - self.ui.tabWidget.removeTab(3) - self.ui.tabWidget.removeTab(2) - - self.ui.l_extended.setText(gCarla.utils.get_complete_license_text()) - - if host.is_engine_running() and not host.isControl: - self.ui.le_osc_url_tcp.setText(host.get_host_osc_url_tcp()) - self.ui.le_osc_url_udp.setText(host.get_host_osc_url_udp()) - else: - self.ui.le_osc_url_tcp.setText(self.tr("(Engine not running)")) - self.ui.le_osc_url_udp.setText(self.tr("(Engine not running)")) - - # pylint: disable=line-too-long - self.ui.l_osc_cmds.setText("" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
" "/set_active" " <i-value>
" "/set_drywet" " <f-value>
" "/set_volume" " <f-value>
" "/set_balance_left" " <f-value>
" "/set_balance_right" " <f-value>
" "/set_panning" " <f-value>
" "/set_parameter_value" " <i-index> <f-value>
" "/set_parameter_midi_cc" " <i-index> <i-cc>
" "/set_parameter_midi_channel" " <i-index> <i-channel>
" "/set_program" " <i-index>
" "/set_midi_program" " <i-index>
" "/note_on" " <i-channel> <i-note> <i-velo>
" "/note_off" " <i-channel> <i-note
" - ) - - self.ui.l_example.setText("/Carla/2/set_parameter_value 5 1.0") - self.ui.l_example_help.setText("(as in this example, \"2\" is the plugin number and \"5\" the parameter)") - # pylint: enable=line-too-long - - self.ui.l_ladspa.setText(self.tr("Everything! (Including LRDF)")) - self.ui.l_dssi.setText(self.tr("Everything! (Including CustomData/Chunks)")) - self.ui.l_lv2.setText(self.tr("About 110% complete (using custom extensions)
" - "Implemented Feature/Extensions:" - "
    " - "
  • http://lv2plug.in/ns/ext/atom
  • " - "
  • http://lv2plug.in/ns/ext/buf-size
  • " - "
  • http://lv2plug.in/ns/ext/data-access
  • " - #"
  • http://lv2plug.in/ns/ext/dynmanifest
  • " - "
  • http://lv2plug.in/ns/ext/event
  • " - "
  • http://lv2plug.in/ns/ext/instance-access
  • " - "
  • http://lv2plug.in/ns/ext/log
  • " - "
  • http://lv2plug.in/ns/ext/midi
  • " - #"
  • http://lv2plug.in/ns/ext/morph
  • " - "
  • http://lv2plug.in/ns/ext/options
  • " - "
  • http://lv2plug.in/ns/ext/parameters
  • " - #"
  • http://lv2plug.in/ns/ext/patch
  • " - "
  • http://lv2plug.in/ns/ext/port-props
  • " - "
  • http://lv2plug.in/ns/ext/presets
  • " - "
  • http://lv2plug.in/ns/ext/resize-port
  • " - "
  • http://lv2plug.in/ns/ext/state
  • " - "
  • http://lv2plug.in/ns/ext/time
  • " - "
  • http://lv2plug.in/ns/ext/uri-map
  • " - "
  • http://lv2plug.in/ns/ext/urid
  • " - "
  • http://lv2plug.in/ns/ext/worker
  • " - "
  • http://lv2plug.in/ns/extensions/ui
  • " - "
  • http://lv2plug.in/ns/extensions/units
  • " - "
  • http://home.gna.org/lv2dynparam/rtmempool/v1
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/external-ui
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/programs
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/props
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/rtmempool
  • " - "
  • http://ll-plugins.nongnu.org/lv2/ext/midimap
  • " - "
  • http://ll-plugins.nongnu.org/lv2/ext/miditype
  • " - "
")) - - self.ui.l_vst2.setText(self.tr("About 85% complete (missing vst bank/presets and some minor stuff)")) - self.ui.l_vst3.setText(self.tr("About 66% complete")) - - if MACOS: - self.ui.l_au.setText(self.tr("About 20% complete")) - else: - self.ui.line_vst3.hide() - self.ui.l_au.hide() - self.ui.lid_au.hide() - - # 3rd tab is usually longer than the 1st - # adjust appropriately - self.ui.tabWidget.setCurrentIndex(2) - self.adjustSize() - self.ui.tabWidget.setCurrentIndex(0) - - self.setFixedSize(self.size()) - - flags = self.windowFlags() - flags &= ~Qt.WindowContextHelpButtonHint - - if WINDOWS: - flags |= Qt.MSWindowsFixedSizeDialogHint - - self.setWindowFlags(flags) - - if MACOS: - self.setWindowModality(Qt.WindowModal) - # ------------------------------------------------------------------------------------------------------------ # Plugin Parameter @@ -1281,7 +1151,7 @@ class PluginEdit(QDialog): QDialog.setVisible(self, yesNo) - if MACOS and yesNo: + if CARLA_OS_MAC and yesNo: parent = self.parent() if parent is None: return @@ -1852,9 +1722,6 @@ if __name__ == '__main__': _host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None, 0x0) _host.set_active(0, True) - gui1 = CarlaAboutW(None, _host) - gui1.show() - gui2 = PluginEdit(None, _host, 0) gui2.testTimer() gui2.show() diff --git a/source/frontend/common/__init__.py b/source/frontend/common/__init__.py index 28c9e6238..51b0b1f7e 100644 --- a/source/frontend/common/__init__.py +++ b/source/frontend/common/__init__.py @@ -1,20 +1,6 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Common Carla code -# Copyright (C) 2011-2022 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +# SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- # Imports (Global) @@ -25,40 +11,43 @@ from sys import platform, maxsize # --------------------------------------------------------------------------------------------------------------------- # Set Version -VERSION = "2.6.0-alpha1" +CARLA_VERSION_HEX = 0x020591 +CARLA_VERSION_STRING = "2.6.0-alpha1" +CARLA_VERSION_STRMIN = "2.6" # --------------------------------------------------------------------------------------------------------------------- -# 64bit check +# Set Platform + +CARLA_OS_BSD = False +CARLA_OS_GNU_HURD = False +CARLA_OS_HAIKU = False +CARLA_OS_LINUX = False +CARLA_OS_MAC = False +CARLA_OS_UNIX = False +CARLA_OS_WASM = False +CARLA_OS_WIN = False +CARLA_OS_WIN32 = False +CARLA_OS_WIN64 = False -kIs64bit = bool(architecture()[0] == "64bit" and maxsize > 2**32) +if platform == "darwin": + CARLA_OS_MAC = True +elif platform == "haiku": + CARLA_OS_HAIKU = True +elif platform == "linux": + CARLA_OS_LINUX = True +elif platform == "win32": + CARLA_OS_WIN32 = True +elif platform == "win64": + CARLA_OS_WIN64 = True + +if CARLA_OS_WIN32 and CARLA_OS_WIN64: + CARLA_OS_WIN = True +elif CARLA_OS_BSD or CARLA_OS_GNU_HURD or CARLA_OS_LINUX or CARLA_OS_MAC: + CARLA_OS_UNIX = True # --------------------------------------------------------------------------------------------------------------------- -# Set Platform +# 64bit check -if platform == "darwin": - HAIKU = False - LINUX = False - MACOS = True - WINDOWS = False -elif "haiku" in platform: - HAIKU = True - LINUX = False - MACOS = False - WINDOWS = False -elif "linux" in platform: - HAIKU = False - LINUX = True - MACOS = False - WINDOWS = False -elif platform in ("win32", "win64", "cygwin"): - HAIKU = False - LINUX = False - MACOS = False - WINDOWS = True -else: - HAIKU = False - LINUX = False - MACOS = False - WINDOWS = False +CARLA_OS_64BIT = bool(architecture()[0] == "64bit" and maxsize > 2**32) # --------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/__init__.py b/source/frontend/dialogs/__init__.py deleted file mode 100644 index e933411be..000000000 --- a/source/frontend/dialogs/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla plugin host -# Copyright (C) 2011-2022 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. - -from .jackappdialog import JackAppDialog diff --git a/source/frontend/dialogs/aboutdialog.cpp b/source/frontend/dialogs/aboutdialog.cpp new file mode 100644 index 000000000..ede29cd1d --- /dev/null +++ b/source/frontend/dialogs/aboutdialog.cpp @@ -0,0 +1,147 @@ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "aboutdialog.hpp" + +#include "CarlaHost.h" + +// -------------------------------------------------------------------------------------------------------------------- +// About Dialog + +AboutDialog::AboutDialog(QWidget* const parent, + const CarlaHostHandle hostHandle, + const bool isControl, + const bool isPlugin) + : QDialog(parent) +{ + ui.setupUi(this); + + QString extraInfo; + if (isControl) + extraInfo = QString(" - %1").arg(tr("OSC Bridge Version")); + else if (isPlugin) + extraInfo = QString(" - %1").arg(tr("Plugin Version")); + + ui.l_about->setText(tr("" + "
Version %1" + "
Carla is a fully-featured audio plugin host%2.
" + "
Copyright (C) 2011-2025 falkTX
" + "").arg(CARLA_VERSION_STRING).arg(extraInfo)); + + if (ui.about->palette().color(QPalette::Window).blackF() < 0.5) + { + ui.l_icons->setPixmap(QPixmap(":/bitmaps/carla_about_black.png")); + ui.ico_example_edit->setPixmap(QPixmap(":/bitmaps/button_file-black.png")); + ui.ico_example_file->setPixmap(QPixmap(":/scalable/button_edit-black.svg")); + ui.ico_example_gui->setPixmap(QPixmap(":/bitmaps/button_gui-black.png")); + } + + if (isControl || isPlugin) + { + ui.l_extended->hide(); + ui.tabWidget->removeTab(3); + ui.tabWidget->removeTab(2); + } + #ifndef STATIC_PLUGIN_TARGET + else if (carla_is_engine_running(hostHandle)) + { + ui.le_osc_url_tcp->setText(carla_get_host_osc_url_tcp(hostHandle)); + ui.le_osc_url_udp->setText(carla_get_host_osc_url_udp(hostHandle)); + } + #endif + else + { + ui.le_osc_url_tcp->setText(tr("(Engine not running)")); + ui.le_osc_url_udp->setText(tr("(Engine not running)")); + } + + ui.l_extended->setText(carla_get_complete_license_text()); + + ui.l_osc_cmds->setText("" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
" "/set_active" " <i-value>
" "/set_drywet" " <f-value>
" "/set_volume" " <f-value>
" "/set_balance_left" " <f-value>
" "/set_balance_right" " <f-value>
" "/set_panning" " <f-value>
" "/set_parameter_value" " <i-index> <f-value>
" "/set_parameter_midi_cc" " <i-index> <i-cc>
" "/set_parameter_midi_channel" " <i-index> <i-channel>
" "/set_program" " <i-index>
" "/set_midi_program" " <i-index>
" "/note_on" " <i-channel> <i-note> <i-velo>
" "/note_off" " <i-channel> <i-note
"); + + ui.l_example->setText("/Carla/2/set_parameter_value 5 1.0"); + ui.l_example_help->setText("(as in this example, \"2\" is the plugin number and \"5\" the parameter)"); + + ui.l_ladspa->setText(tr("Everything! (Including LRDF)")); + ui.l_dssi->setText(tr("Everything! (Including CustomData/Chunks)")); + ui.l_lv2->setText(tr("About 110% complete (using custom extensions)
" + "Implemented Feature/Extensions:" + "
    " + "
  • http://lv2plug.in/ns/ext/atom
  • " + "
  • http://lv2plug.in/ns/ext/buf-size
  • " + "
  • http://lv2plug.in/ns/ext/data-access
  • " + // "
  • http://lv2plug.in/ns/ext/dynmanifest
  • " + "
  • http://lv2plug.in/ns/ext/event
  • " + "
  • http://lv2plug.in/ns/ext/instance-access
  • " + "
  • http://lv2plug.in/ns/ext/log
  • " + "
  • http://lv2plug.in/ns/ext/midi
  • " + // "
  • http://lv2plug.in/ns/ext/morph
  • " + "
  • http://lv2plug.in/ns/ext/options
  • " + "
  • http://lv2plug.in/ns/ext/parameters
  • " + // "
  • http://lv2plug.in/ns/ext/patch
  • " + // "
  • http://lv2plug.in/ns/ext/port-groups
  • " + "
  • http://lv2plug.in/ns/ext/port-props
  • " + "
  • http://lv2plug.in/ns/ext/presets
  • " + "
  • http://lv2plug.in/ns/ext/resize-port
  • " + "
  • http://lv2plug.in/ns/ext/state
  • " + "
  • http://lv2plug.in/ns/ext/time
  • " + "
  • http://lv2plug.in/ns/ext/uri-map
  • " + "
  • http://lv2plug.in/ns/ext/urid
  • " + "
  • http://lv2plug.in/ns/ext/worker
  • " + "
  • http://lv2plug.in/ns/extensions/ui
  • " + "
  • http://lv2plug.in/ns/extensions/units
  • " + "
  • http://home.gna.org/lv2dynparam/rtmempool/v1
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/external-ui
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/programs
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/props
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/rtmempool
  • " + "
  • http://ll-plugins.nongnu.org/lv2/ext/midimap
  • " + "
  • http://ll-plugins.nongnu.org/lv2/ext/miditype
  • " + "
")); + + ui.l_vst2->setText(tr("About 85% complete (missing vst bank/presets and some minor stuff)")); + ui.l_vst3->setText(tr("About 66% complete")); + +#ifdef CARLA_OS_MAC + ui.l_au->setText(tr("About 20% complete")); +#else + ui.line_vst3->hide(); + ui.l_au->hide(); + ui.lid_au->hide(); +#endif + + // 3rd tab is usually longer than the 1st, adjust appropriately + ui.tabWidget->setCurrentIndex(2); + adjustSize(); + ui.tabWidget->setCurrentIndex(0); + + setFixedSize(size()); + + Qt::WindowFlags flags = windowFlags(); + flags &= ~Qt::WindowContextHelpButtonHint; +#ifdef CARLA_OS_WIN + flags |= Qt::MSWindowsFixedSizeDialogHint; +#endif + setWindowFlags(flags); + +#ifdef CARLA_OS_MAC + if (parent != nullptr) + setWindowModality(Qt::WindowModal); +#endif +} + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/aboutdialog.hpp b/source/frontend/dialogs/aboutdialog.hpp new file mode 100644 index 000000000..6d557b0d9 --- /dev/null +++ b/source/frontend/dialogs/aboutdialog.hpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "carla_frontend.h" + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" +# pragma clang diagnostic ignored "-Wdeprecated-register" +#elif defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclass-memaccess" +# pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + +#include "ui_aboutdialog.h" + +#ifdef __clang__ +# pragma clang diagnostic pop +#elif defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic pop +#endif + +// -------------------------------------------------------------------------------------------------------------------- +// About Dialog + +class AboutDialog : public QDialog +{ + Ui_AboutDialog ui; + + // ---------------------------------------------------------------------------------------------------------------- + +public: + explicit AboutDialog(QWidget* parent, CarlaHostHandle hostHandle, bool isControl, bool isPlugin); +}; + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/resources/ui/carla_about.ui b/source/frontend/dialogs/aboutdialog.ui similarity index 99% rename from resources/ui/carla_about.ui rename to source/frontend/dialogs/aboutdialog.ui index 2eb2f0a7e..3e6cdca0a 100644 --- a/resources/ui/carla_about.ui +++ b/source/frontend/dialogs/aboutdialog.ui @@ -1,7 +1,7 @@ - CarlaAboutW - + AboutDialog + 0 @@ -1425,7 +1425,7 @@ POSSIBILITY OF SUCH DAMAGES. buttonBox accepted() - CarlaAboutW + AboutDialog accept() @@ -1441,7 +1441,7 @@ POSSIBILITY OF SUCH DAMAGES. buttonBox rejected() - CarlaAboutW + AboutDialog reject() diff --git a/source/frontend/dialogs/jackappdialog.cpp b/source/frontend/dialogs/jackappdialog.cpp index 371042868..bd02358e2 100644 --- a/source/frontend/dialogs/jackappdialog.cpp +++ b/source/frontend/dialogs/jackappdialog.cpp @@ -1,19 +1,5 @@ -/* - * Carla plugin host - * Copyright (C) 2011-2023 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #include "jackappdialog.hpp" @@ -27,9 +13,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include "ui_jackappdialog.h" #include -#include #include #ifdef __clang__ @@ -40,43 +24,28 @@ #include "qsafesettings.hpp" -#include "CarlaFrontend.h" #include "CarlaLibJackHints.h" -#include "CarlaString.hpp" // -------------------------------------------------------------------------------------------------------------------- // Jack Application Dialog -enum { - UI_SESSION_NONE = 0, - UI_SESSION_LADISH = 1, - UI_SESSION_NSM = 2, -}; - -struct JackAppDialog::Self { - Ui_JackAppDialog ui; +struct JackAppDialog::PrivateData { const QString fProjectFilename; - Self(const char* const projectFilename) + PrivateData(const char* const projectFilename) : fProjectFilename(projectFilename) {} - - static Self& create(const char* const projectFilename) - { - Self* const self = new Self(projectFilename); - return *self; - } }; JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFilename) : QDialog(parent), - self(Self::create(projectFilename)) + p(new PrivateData(projectFilename)) { - self.ui.setupUi(this); + ui.setupUi(this); - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // UI setup - self.ui.group_error->setVisible(false); + ui.group_error->setVisible(false); adjustSize(); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -86,34 +55,34 @@ JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFil setWindowModality(Qt::WindowModal); #endif - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // Load settings loadSettings(); - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // Set-up connections connect(this, &QDialog::finished, this, &JackAppDialog::slot_saveSettings); - connect(self.ui.cb_session_mgr, static_cast(&QComboBox::currentIndexChanged), + connect(ui.cb_session_mgr, static_cast(&QComboBox::currentIndexChanged), this, &JackAppDialog::slot_sessionManagerChanged); - connect(self.ui.le_command, &QLineEdit::textChanged, + connect(ui.le_command, &QLineEdit::textChanged, this, &JackAppDialog::slot_commandChanged); } JackAppDialog::~JackAppDialog() { - delete &self; + delete p; } -// ----------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // public methods JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const { - const QString command = self.ui.le_command->text(); - QString name = self.ui.le_name->text(); + const QString command = ui.le_command->text(); + QString name = ui.le_name->text(); if (name.isEmpty()) { @@ -122,7 +91,7 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const } SessionManager smgr; - switch (self.ui.cb_session_mgr->currentIndex()) + switch (ui.cb_session_mgr->currentIndex()) { case UI_SESSION_LADISH: smgr = LIBJACK_SESSION_MANAGER_LADISH; @@ -136,28 +105,28 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const } uint flags = 0x0; - if (self.ui.cb_manage_window->isChecked()) + if (ui.cb_manage_window->isChecked()) flags |= LIBJACK_FLAG_CONTROL_WINDOW; - if (self.ui.cb_capture_first_window->isChecked()) + if (ui.cb_capture_first_window->isChecked()) flags |= LIBJACK_FLAG_CAPTURE_FIRST_WINDOW; - if (self.ui.cb_buffers_addition_mode->isChecked()) + if (ui.cb_buffers_addition_mode->isChecked()) flags |= LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION; - if (self.ui.cb_out_midi_mixdown->isChecked()) + if (ui.cb_out_midi_mixdown->isChecked()) flags |= LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN; - if (self.ui.cb_external_start->isChecked()) + if (ui.cb_external_start->isChecked()) flags |= LIBJACK_FLAG_EXTERNAL_START; - const QString labelSetup(QString("%1%2%3%4%5%6").arg(QChar('0' + self.ui.sb_audio_ins->value())) - .arg(QChar('0' + self.ui.sb_audio_outs->value())) - .arg(QChar('0' + self.ui.sb_midi_ins->value())) - .arg(QChar('0' + self.ui.sb_midi_outs->value())) + const QString labelSetup(QString("%1%2%3%4%5%6").arg(QChar('0' + ui.sb_audio_ins->value())) + .arg(QChar('0' + ui.sb_audio_outs->value())) + .arg(QChar('0' + ui.sb_midi_ins->value())) + .arg(QChar('0' + ui.sb_midi_outs->value())) .arg(QChar('0' + smgr)) .arg(QChar('0' + flags))); return {command, name, labelSetup}; } -// ----------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // private methods void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarlaString& command) @@ -166,28 +135,28 @@ void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarl QCarlaString showErr; // NSM applications must not be abstract or absolute paths, and must not contain arguments - if (enabled and index == UI_SESSION_NSM) + if (enabled && index == UI_SESSION_NSM) { - if (QVector{'.', '/'}.contains(command[0])) + if (command[0] == '.' || command[0] == '/') showErr = tr("NSM applications cannot use abstract or absolute paths"); else if (command.contains(' ') or command.contains(';') or command.contains('&')) showErr = tr("NSM applications cannot use CLI arguments"); - else if (self.fProjectFilename.isEmpty()) + else if (p->fProjectFilename.isEmpty()) showErr = tr("You need to save the current Carla project before NSM can be used"); } if (showErr.isNotEmpty()) { enabled = false; - self.ui.l_error->setText(showErr); - self.ui.group_error->setVisible(true); + ui.l_error->setText(showErr); + ui.group_error->setVisible(true); } else { - self.ui.group_error->setVisible(false); + ui.group_error->setVisible(false); } - if (QPushButton* const button = self.ui.buttonBox->button(QDialogButtonBox::Ok)) + if (QPushButton* const button = ui.buttonBox->button(QDialogButtonBox::Ok)) button->setEnabled(enabled); } @@ -198,104 +167,53 @@ void JackAppDialog::loadSettings() const QString smName = settings.valueString("SessionManager", ""); if (smName == "LADISH (SIGUSR1)") - self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_LADISH); + ui.cb_session_mgr->setCurrentIndex(UI_SESSION_LADISH); else if (smName == "NSM") - self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); + ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); else - self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NONE); - - self.ui.le_command->setText(settings.valueString("Command", "")); - self.ui.le_name->setText(settings.valueString("Name", "")); - self.ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); - self.ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); - self.ui.sb_audio_outs->setValue(settings.valueIntPositive("NumAudioOuts", 2)); - self.ui.sb_midi_ins->setValue(settings.valueIntPositive("NumMidiIns", 0)); - self.ui.sb_midi_outs->setValue(settings.valueIntPositive("NumMidiOuts", 0)); - self.ui.cb_manage_window->setChecked(settings.valueBool("ManageWindow", true)); - self.ui.cb_capture_first_window->setChecked(settings.valueBool("CaptureFirstWindow", false)); - self.ui.cb_out_midi_mixdown->setChecked(settings.valueBool("MidiOutMixdown", false)); - - checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr->currentIndex(), - self.ui.le_command->text()); + ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NONE); + + ui.le_command->setText(settings.valueString("Command", "")); + ui.le_name->setText(settings.valueString("Name", "")); + ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); + ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); + ui.sb_audio_outs->setValue(settings.valueIntPositive("NumAudioOuts", 2)); + ui.sb_midi_ins->setValue(settings.valueIntPositive("NumMidiIns", 0)); + ui.sb_midi_outs->setValue(settings.valueIntPositive("NumMidiOuts", 0)); + ui.cb_manage_window->setChecked(settings.valueBool("ManageWindow", true)); + ui.cb_capture_first_window->setChecked(settings.valueBool("CaptureFirstWindow", false)); + ui.cb_out_midi_mixdown->setChecked(settings.valueBool("MidiOutMixdown", false)); + + checkIfButtonBoxShouldBeEnabled(ui.cb_session_mgr->currentIndex(), + ui.le_command->text()); } -// ----------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // private slots void JackAppDialog::slot_commandChanged(const QString& command) { - checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr->currentIndex(), command); + checkIfButtonBoxShouldBeEnabled(ui.cb_session_mgr->currentIndex(), command); } void JackAppDialog::slot_sessionManagerChanged(const int index) { - checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command->text()); + checkIfButtonBoxShouldBeEnabled(index, ui.le_command->text()); } void JackAppDialog::slot_saveSettings() { QSafeSettings settings("falkTX", "CarlaAddJackApp"); - settings.setValue("Command", self.ui.le_command->text()); - settings.setValue("Name", self.ui.le_name->text()); - settings.setValue("SessionManager", self.ui.cb_session_mgr->currentText()); - settings.setValue("NumAudioIns", self.ui.sb_audio_ins->value()); - settings.setValue("NumAudioOuts", self.ui.sb_audio_outs->value()); - settings.setValue("NumMidiIns", self.ui.sb_midi_ins->value()); - settings.setValue("NumMidiOuts", self.ui.sb_midi_outs->value()); - settings.setValue("ManageWindow", self.ui.cb_manage_window->isChecked()); - settings.setValue("CaptureFirstWindow", self.ui.cb_capture_first_window->isChecked()); - settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown->isChecked()); + settings.setValue("Command", ui.le_command->text()); + settings.setValue("Name", ui.le_name->text()); + settings.setValue("SessionManager", ui.cb_session_mgr->currentText()); + settings.setValue("NumAudioIns", ui.sb_audio_ins->value()); + settings.setValue("NumAudioOuts", ui.sb_audio_outs->value()); + settings.setValue("NumMidiIns", ui.sb_midi_ins->value()); + settings.setValue("NumMidiOuts", ui.sb_midi_outs->value()); + settings.setValue("ManageWindow", ui.cb_manage_window->isChecked()); + settings.setValue("CaptureFirstWindow", ui.cb_capture_first_window->isChecked()); + settings.setValue("MidiOutMixdown", ui.cb_out_midi_mixdown->isChecked()); } // -------------------------------------------------------------------------------------------------------------------- - -const JackAppDialogResults* -carla_frontend_createAndExecJackAppDialog(void* const parent, const char* const projectFilename) -{ - JackAppDialog gui(reinterpret_cast(parent), projectFilename); - - if (gui.exec()) - { - static JackAppDialogResults ret = {}; - static CarlaString retCommand; - static CarlaString retName; - static CarlaString retLabelSetup; - - const JackAppDialog::CommandAndFlags cafs = gui.getCommandAndFlags(); - retCommand = cafs.command.toUtf8().constData(); - retName = cafs.name.toUtf8().constData(); - retLabelSetup = cafs.labelSetup.toUtf8().constData(); - - ret.command = retCommand; - ret.name = retName; - ret.labelSetup = retLabelSetup; - - return &ret; - } - - return nullptr; -} - -#if 0 -// -------------------------------------------------------------------------------------------------------------------- -// Testing - -#include "../utils/qsafesettings.cpp" - -int main(int argc, char* argv[]) -{ - QApplication app(argc, argv); - - if (JackAppDialogResults* const res = carla_frontend_createAndExecJackAppDialog(nullptr, "")) - { - printf("Results:\n"); - printf("\tCommand: %s\n", res->command); - printf("\tName: %s\n", res->name); - printf("\tLabelSetup: %s\n", res->labelSetup); - } - - return 0; -} -#endif - -// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/jackappdialog.hpp b/source/frontend/dialogs/jackappdialog.hpp index 0a52a5d2b..922ab11a0 100644 --- a/source/frontend/dialogs/jackappdialog.hpp +++ b/source/frontend/dialogs/jackappdialog.hpp @@ -1,22 +1,10 @@ -/* - * Carla plugin host - * Copyright (C) 2011-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include "carla_frontend.h" + #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" @@ -27,7 +15,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include +#include "ui_jackappdialog.h" #ifdef __clang__ # pragma clang diagnostic pop @@ -42,8 +30,16 @@ class JackAppDialog : public QDialog { - struct Self; - Self& self; + enum { + UI_SESSION_NONE, + UI_SESSION_LADISH, + UI_SESSION_NSM, + }; + + struct PrivateData; + PrivateData* const p; + + Ui_JackAppDialog ui; // ---------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/jackappdialog.py b/source/frontend/dialogs/jackappdialog.py deleted file mode 100755 index 878ebd830..000000000 --- a/source/frontend/dialogs/jackappdialog.py +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla plugin host -# Copyright (C) 2011-2022 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. - -# --------------------------------------------------------------------------------------------------------------------- -# Imports (Global) - -import os - -from PyQt5.QtCore import pyqtSlot, Qt -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QWidget - -# --------------------------------------------------------------------------------------------------------------------- -# Imports (Carla) - -from utils import QSafeSettings - -# --------------------------------------------------------------------------------------------------------------------- -# Imports (Local) - -from jackappdialog_ui import Ui_JackAppDialog - -# --------------------------------------------------------------------------------------------------------------------- -# Imports (API) - -SESSION_MGR_NONE = 0 -SESSION_MGR_AUTO = 1 -SESSION_MGR_JACK = 2 -SESSION_MGR_LADISH = 3 -SESSION_MGR_NSM = 4 - -FLAG_CONTROL_WINDOW = 0x01 -FLAG_CAPTURE_FIRST_WINDOW = 0x02 -FLAG_BUFFERS_ADDITION_MODE = 0x10 -FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN = 0x20 -FLAG_EXTERNAL_START = 0x40 - -# --------------------------------------------------------------------------------------------------------------------- -# Jack Application Dialog - -UI_SESSION_NONE = 0 -UI_SESSION_LADISH = 1 -UI_SESSION_NSM = 2 - -class JackAppDialog(QDialog): - def __init__(self, parent: QWidget, projectFilename: str): - QDialog.__init__(self, parent) - self.ui = Ui_JackAppDialog() - self.ui.setupUi(self) - - self.fProjectFilename = projectFilename - - # -------------------------------------------------------------------------------------------------------------- - # UI setup - - self.ui.group_error.setVisible(False) - self.adjustSize() - self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - - # -------------------------------------------------------------------------------------------------------------- - # Load settings - - self._loadSettings() - - # -------------------------------------------------------------------------------------------------------------- - # Set-up connections - - self.finished.connect(self._slot_saveSettings) - self.ui.cb_session_mgr.currentIndexChanged.connect(self._slot_sessionManagerChanged) - self.ui.le_command.textChanged.connect(self._slot_commandChanged) - - # ----------------------------------------------------------------------------------------------------------------- - # public methods - - def getCommandAndFlags(self): - name = self.ui.le_name.text() - command = self.ui.le_command.text() - smgr = SESSION_MGR_NONE - flags = 0x0 - - if not name: - name = os.path.basename(command.split(" ",1)[0]).title() - - uiSessionMgrIndex = self.ui.cb_session_mgr.currentIndex() - if uiSessionMgrIndex == UI_SESSION_LADISH: - smgr = SESSION_MGR_LADISH - elif uiSessionMgrIndex == UI_SESSION_NSM: - smgr = SESSION_MGR_NSM - - if self.ui.cb_manage_window.isChecked(): - flags |= FLAG_CONTROL_WINDOW - if self.ui.cb_capture_first_window.isChecked(): - flags |= FLAG_CAPTURE_FIRST_WINDOW - if self.ui.cb_buffers_addition_mode.isChecked(): - flags |= FLAG_BUFFERS_ADDITION_MODE - if self.ui.cb_out_midi_mixdown.isChecked(): - flags |= FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN - if self.ui.cb_external_start.isChecked(): - flags |= FLAG_EXTERNAL_START - - bv = ord('0') - v1 = chr(bv + self.ui.sb_audio_ins.value()) - v2 = chr(bv + self.ui.sb_audio_outs.value()) - v3 = chr(bv + self.ui.sb_midi_ins.value()) - v4 = chr(bv + self.ui.sb_midi_outs.value()) - v5 = chr(bv + smgr) - v6 = chr(bv + flags) - labelSetup = f"{v1}{v2}{v3}{v4}{v5}{v6}" - - return (command, name, labelSetup) - - # ----------------------------------------------------------------------------------------------------------------- - # private methods - - def _checkIfButtonBoxShouldBeEnabled(self, index: int, command: str): - enabled = len(command) > 0 - showErr = "" - - # NSM applications must not be abstract or absolute paths, and must not contain arguments - if enabled and index == UI_SESSION_NSM: - if command[0] in (".", "/"): - showErr = self.tr("NSM applications cannot use abstract or absolute paths") - elif " " in command or ";" in command or "&" in command: - showErr = self.tr("NSM applications cannot use CLI arguments") - elif not self.fProjectFilename: - showErr = self.tr("You need to save the current Carla project before NSM can be used") - - if showErr: - enabled = False - self.ui.l_error.setText(showErr) - self.ui.group_error.setVisible(True) - else: - self.ui.group_error.setVisible(False) - - self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) - - def _loadSettings(self): - settings = QSafeSettings("falkTX", "CarlaAddJackApp") - - smName = settings.value("SessionManager", "", str) - - if smName == "LADISH (SIGUSR1)": - self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_LADISH) - elif smName == "NSM": - self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NSM) - else: - self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NONE) - - self.ui.le_command.setText(settings.value("Command", "", str)) - self.ui.le_name.setText(settings.value("Name", "", str)) - self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int)) - self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int)) - self.ui.sb_audio_outs.setValue(settings.value("NumAudioOuts", 2, int)) - self.ui.sb_midi_ins.setValue(settings.value("NumMidiIns", 0, int)) - self.ui.sb_midi_outs.setValue(settings.value("NumMidiOuts", 0, int)) - self.ui.cb_manage_window.setChecked(settings.value("ManageWindow", True, bool)) - self.ui.cb_capture_first_window.setChecked(settings.value("CaptureFirstWindow", False, bool)) - self.ui.cb_out_midi_mixdown.setChecked(settings.value("MidiOutMixdown", False, bool)) - - self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(), - self.ui.le_command.text()) - - # ----------------------------------------------------------------------------------------------------------------- - # private slots - - @pyqtSlot(str) - def _slot_commandChanged(self, command: str): - self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(), command) - - @pyqtSlot(int) - def _slot_sessionManagerChanged(self, index: int): - self._checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command.text()) - - @pyqtSlot() - def _slot_saveSettings(self): - settings = QSafeSettings("falkTX", "CarlaAddJackApp") - settings.setValue("Command", self.ui.le_command.text()) - settings.setValue("Name", self.ui.le_name.text()) - settings.setValue("SessionManager", self.ui.cb_session_mgr.currentText()) - settings.setValue("NumAudioIns", self.ui.sb_audio_ins.value()) - settings.setValue("NumAudioOuts", self.ui.sb_audio_outs.value()) - settings.setValue("NumMidiIns", self.ui.sb_midi_ins.value()) - settings.setValue("NumMidiOuts", self.ui.sb_midi_outs.value()) - settings.setValue("ManageWindow", self.ui.cb_manage_window.isChecked()) - settings.setValue("CaptureFirstWindow", self.ui.cb_capture_first_window.isChecked()) - settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown.isChecked()) - -# --------------------------------------------------------------------------------------------------------------------- -# Testing - -if __name__ == '__main__': - import sys - # pylint: disable=ungrouped-imports - from PyQt5.QtWidgets import QApplication - # pylint: enable=ungrouped-imports - - _app = QApplication(sys.argv) - _gui = JackAppDialog(None, "") - - if _gui.exec_(): - _command, _name, _labelSetup = _gui.getCommandAndFlags() - print("Results:") - print(f"\tCommand: {_command}") - print(f"\tName: {_name}") - print(f"\tLabelSetup: {_labelSetup}") - -# --------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/modgui/__init__.py b/source/frontend/modgui/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/frontend/modgui/host.py b/source/frontend/modgui/host.py deleted file mode 100644 index 8d8e3334f..000000000 --- a/source/frontend/modgui/host.py +++ /dev/null @@ -1,546 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla bridge for LV2 modguis -# Copyright (C) 2015-2019 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. - -# ------------------------------------------------------------------------------------------------------------ -# Imports (Global) - -from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QSize, QUrl -from PyQt5.QtGui import QImage, QPainter, QPalette -from PyQt5.QtWidgets import QApplication, QMainWindow -from PyQt5.QtWebKit import QWebSettings -from PyQt5.QtWebKitWidgets import QWebView - -import sys - -# ------------------------------------------------------------------------------------------------------------ -# Imports (Custom) - -from carla_host import charPtrToString, gCarla -from .webserver import WebServerThread, PORT - -# ------------------------------------------------------------------------------------------------------------ -# Imports (MOD) - -from modtools.utils import get_plugin_info, init as lv2_init - -# ------------------------------------------------------------------------------------------------------------ -# Host Window - -class HostWindow(QMainWindow): - # signals - SIGTERM = pyqtSignal() - SIGUSR1 = pyqtSignal() - - # -------------------------------------------------------------------------------------------------------- - - def __init__(self): - QMainWindow.__init__(self) - gCarla.gui = self - - URI = sys.argv[1] - - # ---------------------------------------------------------------------------------------------------- - # Internal stuff - - self.fCurrentFrame = None - self.fDocElemement = None - self.fCanSetValues = False - self.fNeedsShow = False - self.fSizeSetup = False - self.fQuitReceived = False - self.fWasRepainted = False - - lv2_init() - - self.fPlugin = get_plugin_info(URI) - self.fPorts = self.fPlugin['ports'] - self.fPortSymbols = {} - self.fPortValues = {} - self.fParamTypes = {} - self.fParamValues = {} - - for port in self.fPorts['control']['input']: - self.fPortSymbols[port['index']] = (port['symbol'], False) - self.fPortValues [port['index']] = port['ranges']['default'] - - for port in self.fPorts['control']['output']: - self.fPortSymbols[port['index']] = (port['symbol'], True) - self.fPortValues [port['index']] = port['ranges']['default'] - - for parameter in self.fPlugin['parameters']: - if parameter['ranges'] is None: - continue - if parameter['type'] == "http://lv2plug.in/ns/ext/atom#Bool": - paramtype = 'b' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Int": - paramtype = 'i' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Long": - paramtype = 'l' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Float": - paramtype = 'f' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Double": - paramtype = 'g' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#String": - paramtype = 's' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Path": - paramtype = 'p' - elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#URI": - paramtype = 'u' - else: - continue - if paramtype not in ('s','p','u') and parameter['ranges']['minimum'] == parameter['ranges']['maximum']: - continue - self.fParamTypes [parameter['uri']] = paramtype - self.fParamValues[parameter['uri']] = parameter['ranges']['default'] - - # ---------------------------------------------------------------------------------------------------- - # Init pipe - - if len(sys.argv) == 7: - self.fPipeClient = gCarla.utils.pipe_client_new(lambda s,msg: self.msgCallback(msg)) - else: - self.fPipeClient = None - - # ---------------------------------------------------------------------------------------------------- - # Init Web server - - self.fWebServerThread = WebServerThread(self) - self.fWebServerThread.start() - - # ---------------------------------------------------------------------------------------------------- - # Set up GUI - - self.setContentsMargins(0, 0, 0, 0) - - self.fWebview = QWebView(self) - #self.fWebview.setAttribute(Qt.WA_OpaquePaintEvent, False) - #self.fWebview.setAttribute(Qt.WA_TranslucentBackground, True) - self.setCentralWidget(self.fWebview) - - page = self.fWebview.page() - page.setViewportSize(QSize(980, 600)) - - mainFrame = page.mainFrame() - mainFrame.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) - mainFrame.setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) - - palette = self.fWebview.palette() - palette.setBrush(QPalette.Base, palette.brush(QPalette.Window)) - page.setPalette(palette) - self.fWebview.setPalette(palette) - - settings = self.fWebview.settings() - settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) - - self.fWebview.loadFinished.connect(self.slot_webviewLoadFinished) - - url = "http://127.0.0.1:%s/icon.html#%s" % (PORT, URI) - print("url:", url) - self.fWebview.load(QUrl(url)) - - # ---------------------------------------------------------------------------------------------------- - # Connect actions to functions - - self.SIGTERM.connect(self.slot_handleSIGTERM) - - # ---------------------------------------------------------------------------------------------------- - # Final setup - - self.fIdleTimer = self.startTimer(30) - - if self.fPipeClient is None: - # testing, show UI only - self.setWindowTitle("TestUI") - self.fNeedsShow = True - - # -------------------------------------------------------------------------------------------------------- - - def closeExternalUI(self): - self.fWebServerThread.stopWait() - - if self.fPipeClient is None: - return - - if not self.fQuitReceived: - self.send(["exiting"]) - - gCarla.utils.pipe_client_destroy(self.fPipeClient) - self.fPipeClient = None - - def idleStuff(self): - if self.fPipeClient is not None: - gCarla.utils.pipe_client_idle(self.fPipeClient) - self.checkForRepaintChanges() - - if self.fSizeSetup: - return - if self.fDocElemement is None or self.fDocElemement.isNull(): - return - - pedal = self.fDocElemement.findFirst(".mod-pedal") - - if pedal.isNull(): - return - - size = pedal.geometry().size() - - if size.width() <= 10 or size.height() <= 10: - return - - # render web frame to image - image = QImage(self.fWebview.page().viewportSize(), QImage.Format_ARGB32_Premultiplied) - image.fill(Qt.transparent) - - painter = QPainter(image) - self.fCurrentFrame.render(painter) - painter.end() - - #image.save("/tmp/test.png") - - # get coordinates and size from image - #x = -1 - #y = -1 - #lastx = -1 - #lasty = -1 - #bgcol = self.fHostColor.rgba() - - #for h in range(0, image.height()): - #hasNonTransPixels = False - - #for w in range(0, image.width()): - #if image.pixel(w, h) not in (0, bgcol): # 0xff070707): - #hasNonTransPixels = True - #if x == -1 or x > w: - #x = w - #lastx = max(lastx, w) - - #if hasNonTransPixels: - ##if y == -1: - ##y = h - #lasty = h - - # set size and position accordingly - #if -1 not in (x, lastx, lasty): - #self.setFixedSize(lastx-x, lasty) - #self.fCurrentFrame.setScrollPosition(QPoint(x, 0)) - #else: - - # TODO that^ needs work - if True: - self.setFixedSize(size) - - # set initial values - self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue(':bypass', 0, null)") - - for index in self.fPortValues.keys(): - symbol, isOutput = self.fPortSymbols[index] - value = self.fPortValues[index] - if isOutput: - self.fCurrentFrame.evaluateJavaScript("icongui.setOutputPortValue('%s', %f)" % (symbol, value)) - else: - self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue('%s', %f, null)" % (symbol, value)) - - for uri in self.fParamValues.keys(): - ptype = self.fParamTypes[uri] - value = str(self.fParamValues[uri]) - print("icongui.setWritableParameterValue('%s', '%c', %s, 'from-carla')" % (uri, ptype, value)) - self.fCurrentFrame.evaluateJavaScript("icongui.setWritableParameterValue('%s', '%c', %s, 'from-carla')" % ( - uri, ptype, value)) - - # final setup - self.fCanSetValues = True - self.fSizeSetup = True - self.fDocElemement = None - - if self.fNeedsShow: - self.show() - - def checkForRepaintChanges(self): - if not self.fWasRepainted: - return - - self.fWasRepainted = False - - if not self.fCanSetValues: - return - - for index in self.fPortValues.keys(): - symbol, isOutput = self.fPortSymbols[index] - - if isOutput: - continue - - oldValue = self.fPortValues[index] - newValue = self.fCurrentFrame.evaluateJavaScript("icongui.controls['%s'].value" % (symbol,)) - - if oldValue != newValue: - self.fPortValues[index] = newValue - self.send(["control", index, newValue]) - - for uri in self.fParamValues.keys(): - oldValue = self.fParamValues[uri] - newValue = self.fCurrentFrame.evaluateJavaScript("icongui.parameters['%s'].value" % (uri,)) - - if oldValue != newValue: - self.fParamValues[uri] = newValue - self.send(["pcontrol", uri, newValue]) - - # -------------------------------------------------------------------------------------------------------- - - @pyqtSlot(bool) - def slot_webviewLoadFinished(self, ok): - page = self.fWebview.page() - page.repaintRequested.connect(self.slot_repaintRequested) - - self.fCurrentFrame = page.currentFrame() - self.fDocElemement = self.fCurrentFrame.documentElement() - - def slot_repaintRequested(self): - if self.fCanSetValues: - self.fWasRepainted = True - - # -------------------------------------------------------------------------------------------------------- - # Callback - - def msgCallback(self, msg): - msg = charPtrToString(msg) - - if msg == "control": - index = self.readlineblock_int() - value = self.readlineblock_float() - self.dspControlChanged(index, value) - - elif msg == "parameter": - uri = self.readlineblock() - value = self.readlineblock_float() - self.dspParameterChanged(uri, value) - - elif msg == "program": - index = self.readlineblock_int() - self.dspProgramChanged(index) - - elif msg == "midiprogram": - bank = self.readlineblock_int() - program = self.readlineblock_int() - self.dspMidiProgramChanged(bank, program) - - elif msg == "configure": - key = self.readlineblock() - value = self.readlineblock() - self.dspStateChanged(key, value) - - elif msg == "note": - onOff = self.readlineblock_bool() - channel = self.readlineblock_int() - note = self.readlineblock_int() - velocity = self.readlineblock_int() - self.dspNoteReceived(onOff, channel, note, velocity) - - elif msg == "atom": - index = self.readlineblock_int() - atomsize = self.readlineblock_int() - base64size = self.readlineblock_int() - base64atom = self.readlineblock() - # nothing to do yet - - elif msg == "urid": - urid = self.readlineblock_int() - size = self.readlineblock_int() - uri = self.readlineblock() - # nothing to do yet - - elif msg == "uiOptions": - sampleRate = self.readlineblock_float() - bgColor = self.readlineblock_int() - fgColor = self.readlineblock_int() - uiScale = self.readlineblock_float() - useTheme = self.readlineblock_bool() - useThemeColors = self.readlineblock_bool() - windowTitle = self.readlineblock() - transWindowId = self.readlineblock_int() - self.uiTitleChanged(windowTitle) - - elif msg == "show": - self.uiShow() - - elif msg == "focus": - self.uiFocus() - - elif msg == "hide": - self.uiHide() - - elif msg == "quit": - self.fQuitReceived = True - self.uiQuit() - - elif msg == "uiTitle": - uiTitle = self.readlineblock() - self.uiTitleChanged(uiTitle) - - else: - print("unknown message: \"" + msg + "\"") - - # -------------------------------------------------------------------------------------------------------- - - def dspControlChanged(self, index, value): - self.fPortValues[index] = value - - if self.fCurrentFrame is None or not self.fCanSetValues: - return - - symbol, isOutput = self.fPortSymbols[index] - - if isOutput: - self.fCurrentFrame.evaluateJavaScript("icongui.setOutputPortValue('%s', %f)" % (symbol, value)) - else: - self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue('%s', %f, null)" % (symbol, value)) - - def dspParameterChanged(self, uri, value): - print("dspParameterChanged", uri, value) - if uri not in self.fParamValues: - return - - self.fParamValues[uri] = value - - if self.fCurrentFrame is None or not self.fCanSetValues: - return - - ptype = self.fParamTypes[uri] - - self.fCurrentFrame.evaluateJavaScript("icongui.setWritableParameterValue('%s', '%c', %f, 'from-carla')" % ( - uri, ptype, value)) - - def dspProgramChanged(self, index): - return - - def dspMidiProgramChanged(self, bank, program): - return - - def dspStateChanged(self, key, value): - return - - def dspNoteReceived(self, onOff, channel, note, velocity): - return - - # -------------------------------------------------------------------------------------------------------- - - def uiShow(self): - if self.fSizeSetup: - self.show() - else: - self.fNeedsShow = True - - def uiFocus(self): - if not self.fSizeSetup: - return - - self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) - self.show() - - self.raise_() - self.activateWindow() - - def uiHide(self): - self.hide() - - def uiQuit(self): - self.closeExternalUI() - self.close() - QApplication.instance().quit() - - def uiTitleChanged(self, uiTitle): - self.setWindowTitle(uiTitle) - - # -------------------------------------------------------------------------------------------------------- - # Qt events - - def closeEvent(self, event): - self.closeExternalUI() - QMainWindow.closeEvent(self, event) - - # there might be other qt windows open which will block carla-modgui from quitting - QApplication.instance().quit() - - def timerEvent(self, event): - if event.timerId() == self.fIdleTimer: - self.idleStuff() - - QMainWindow.timerEvent(self, event) - - # -------------------------------------------------------------------------------------------------------- - - @pyqtSlot() - def slot_handleSIGTERM(self): - print("Got SIGTERM -> Closing now") - self.close() - - # -------------------------------------------------------------------------------------------------------- - # Internal stuff - - def readlineblock(self): - if self.fPipeClient is None: - return "" - - return gCarla.utils.pipe_client_readlineblock(self.fPipeClient, 5000) - - def readlineblock_bool(self): - if self.fPipeClient is None: - return False - - return gCarla.utils.pipe_client_readlineblock_bool(self.fPipeClient, 5000) - - def readlineblock_int(self): - if self.fPipeClient is None: - return 0 - - return gCarla.utils.pipe_client_readlineblock_int(self.fPipeClient, 5000) - - def readlineblock_float(self): - if self.fPipeClient is None: - return 0.0 - - return gCarla.utils.pipe_client_readlineblock_float(self.fPipeClient, 5000) - - def send(self, lines): - if self.fPipeClient is None or len(lines) == 0: - return - - gCarla.utils.pipe_client_lock(self.fPipeClient) - - # this must never fail, we need to unlock at the end - try: - for line in lines: - if line is None: - line2 = "(null)" - elif isinstance(line, str): - line2 = line.replace("\n", "\r") - elif isinstance(line, bool): - line2 = "true" if line else "false" - elif isinstance(line, int): - line2 = "%i" % line - elif isinstance(line, float): - line2 = "%.10f" % line - else: - print("unknown data type to send:", type(line)) - return - - gCarla.utils.pipe_client_write_msg(self.fPipeClient, line2 + "\n") - except: - pass - - gCarla.utils.pipe_client_flush_and_unlock(self.fPipeClient) diff --git a/source/frontend/modgui/webserver.py b/source/frontend/modgui/webserver.py deleted file mode 100644 index 1f89de2db..000000000 --- a/source/frontend/modgui/webserver.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla bridge for LV2 modguis -# Copyright (C) 2015-2020 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 -# published by the Free Software Foundation; either version 2 of -# the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the doc/GPL.txt file. - -# ------------------------------------------------------------------------------------------------------------ -# Imports (Global) - -import os - -from PyQt5.QtCore import pyqtSignal, QThread - -# ------------------------------------------------------------------------------------------------------------ -# Generate a random port number between 9000 and 18000 - -from random import random - -PORTn = 8998 + int(random()*9000) - -# ------------------------------------------------------------------------------------------------------------ -# Imports (asyncio) - -try: - from asyncio import new_event_loop, set_event_loop - haveAsyncIO = True -except: - haveAsyncIO = False - -# ------------------------------------------------------------------------------------------------------------ -# Imports (tornado) - -from tornado.log import enable_pretty_logging -from tornado.ioloop import IOLoop -from tornado.util import unicode_type -from tornado.web import HTTPError -from tornado.web import Application, RequestHandler, StaticFileHandler - -# ------------------------------------------------------------------------------------------------------------ -# Set up environment for the webserver - -PORT = str(PORTn) -ROOT = "/usr/share/mod" -DATA_DIR = os.path.expanduser("~/.local/share/mod-data/") -HTML_DIR = os.path.join(ROOT, "html") - -os.environ['MOD_DEV_HOST'] = "1" -os.environ['MOD_DEV_HMI'] = "1" -os.environ['MOD_DESKTOP'] = "1" - -os.environ['MOD_DATA_DIR'] = DATA_DIR -os.environ['MOD_HTML_DIR'] = HTML_DIR -os.environ['MOD_KEY_PATH'] = os.path.join(DATA_DIR, "keys") -os.environ['MOD_CLOUD_PUB'] = os.path.join(ROOT, "keys", "cloud_key.pub") -os.environ['MOD_PLUGIN_LIBRARY_DIR'] = os.path.join(DATA_DIR, "lib") - -os.environ['MOD_PHANTOM_BINARY'] = "/usr/bin/phantomjs" -os.environ['MOD_SCREENSHOT_JS'] = os.path.join(ROOT, "screenshot.js") -os.environ['MOD_DEVICE_WEBSERVER_PORT'] = PORT - -# ------------------------------------------------------------------------------------------------------------ -# Imports (MOD) - -from modtools.utils import get_plugin_info, get_plugin_gui, get_plugin_gui_mini - -# ------------------------------------------------------------------------------------------------------------ -# MOD related classes - -class JsonRequestHandler(RequestHandler): - def write(self, data): - if isinstance(data, (bytes, unicode_type, dict)): - RequestHandler.write(self, data) - self.finish() - return - - elif data is True: - data = "true" - self.set_header("Content-Type", "application/json; charset=UTF-8") - - elif data is False: - data = "false" - self.set_header("Content-Type", "application/json; charset=UTF-8") - - else: - data = json.dumps(data) - self.set_header("Content-Type", "application/json; charset=UTF-8") - - RequestHandler.write(self, data) - self.finish() - -class EffectGet(JsonRequestHandler): - def get(self): - uri = self.get_argument('uri') - - try: - data = get_plugin_info(uri) - except: - print("ERROR: get_plugin_info for '%s' failed" % uri) - raise HTTPError(404) - - self.write(data) - -class EffectFile(StaticFileHandler): - def initialize(self): - # return custom type directly. The browser will do the parsing - self.custom_type = None - - uri = self.get_argument('uri') - - try: - self.modgui = get_plugin_gui(uri) - except: - raise HTTPError(404) - - try: - root = self.modgui['resourcesDirectory'] - except: - raise HTTPError(404) - - return StaticFileHandler.initialize(self, root) - - def parse_url_path(self, prop): - try: - path = self.modgui[prop] - except: - raise HTTPError(404) - - if prop in ("iconTemplate", "settingsTemplate", "stylesheet", "javascript"): - self.custom_type = "text/plain" - - return path - - def get_content_type(self): - if self.custom_type is not None: - return self.custom_type - return StaticFileHandler.get_content_type(self) - -class EffectResource(StaticFileHandler): - - def initialize(self): - # Overrides StaticFileHandler initialize - pass - - def get(self, path): - try: - uri = self.get_argument('uri') - except: - return self.shared_resource(path) - - try: - modgui = get_plugin_gui_mini(uri) - except: - raise HTTPError(404) - - try: - root = modgui['resourcesDirectory'] - except: - raise HTTPError(404) - - try: - super(EffectResource, self).initialize(root) - return super(EffectResource, self).get(path) - except HTTPError as e: - if e.status_code != 404: - raise e - return self.shared_resource(path) - except IOError: - raise HTTPError(404) - - def shared_resource(self, path): - super(EffectResource, self).initialize(os.path.join(HTML_DIR, 'resources')) - return super(EffectResource, self).get(path) - -# ------------------------------------------------------------------------------------------------------------ -# WebServer Thread - -class WebServerThread(QThread): - # signals - running = pyqtSignal() - - def __init__(self, parent=None): - QThread.__init__(self, parent) - - self.fApplication = Application( - [ - (r"/effect/get/?", EffectGet), - (r"/effect/file/(.*)", EffectFile), - (r"/resources/(.*)", EffectResource), - (r"/(.*)", StaticFileHandler, {"path": HTML_DIR}), - ], - debug=True) - - self.fPrepareWasCalled = False - self.fEventLoop = None - - def run(self): - if not self.fPrepareWasCalled: - self.fPrepareWasCalled = True - if haveAsyncIO: - self.fEventLoop = new_event_loop() - set_event_loop(self.fEventLoop) - self.fApplication.listen(PORT, address="0.0.0.0") - if int(os.getenv("MOD_LOG", "0")): - enable_pretty_logging() - - self.running.emit() - IOLoop.instance().start() - - def stopWait(self): - IOLoop.instance().stop() - if self.fEventLoop is not None: - self.fEventLoop.call_soon_threadsafe(self.fEventLoop.stop) - return self.wait(5000) diff --git a/source/frontend/patchcanvas/theme.py b/source/frontend/patchcanvas/theme.py index fe9b2c4cb..16b4936f3 100644 --- a/source/frontend/patchcanvas/theme.py +++ b/source/frontend/patchcanvas/theme.py @@ -317,14 +317,14 @@ class Theme(object): self.port_font_state = QFont.Normal self.port_mode = self.THEME_PORT_SQUARE - self.port_audio_jack_pen = QPen(QColor(35, 61, 99), Qt.NoPen, 0) - self.port_audio_jack_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) - self.port_midi_jack_pen = QPen(QColor(120, 15, 16), Qt.NoPen, 0) - self.port_midi_jack_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) - self.port_midi_alsa_pen = QPen(QColor(63, 112, 19), Qt.NoPen, 0) - self.port_midi_alsa_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) - self.port_parameter_pen = QPen(QColor(101, 47, 17), Qt.NoPen, 0) - self.port_parameter_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) + self.port_audio_jack_pen = QPen(QColor(35, 61, 99), 0, Qt.NoPen) + self.port_audio_jack_pen_sel = QPen(QColor(255, 0, 0), 0, Qt.NoPen) + self.port_midi_jack_pen = QPen(QColor(120, 15, 16), 0, Qt.NoPen) + self.port_midi_jack_pen_sel = QPen(QColor(255, 0, 0), 0, Qt.NoPen) + self.port_midi_alsa_pen = QPen(QColor(63, 112, 19), 0, Qt.NoPen) + self.port_midi_alsa_pen_sel = QPen(QColor(255, 0, 0), 0, Qt.NoPen) + self.port_parameter_pen = QPen(QColor(101, 47, 17), 0, Qt.NoPen) + self.port_parameter_pen_sel = QPen(QColor(255, 0, 0), 0, Qt.NoPen) self.port_audio_jack_bg = QColor(35, 61, 99) self.port_audio_jack_bg_sel = QColor(255, 0, 0) diff --git a/source/frontend/pluginlist/pluginlistdialog.cpp b/source/frontend/pluginlist/pluginlistdialog.cpp index 3847699d8..bc6ff2cc8 100644 --- a/source/frontend/pluginlist/pluginlistdialog.cpp +++ b/source/frontend/pluginlist/pluginlistdialog.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #include "pluginlistdialog.hpp" @@ -32,7 +32,7 @@ #include "CarlaJuceUtils.hpp" #include "CarlaUtils.h" -#include "CarlaString.hpp" +#include "extra/ScopedPointer.hpp" #include @@ -382,31 +382,6 @@ int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& // -------------------------------------------------------------------------------------------------------------------- // Qt-compatible plugin info -// base details, nicely packed and POD-only so we can directly use as binary -struct PluginInfoHeader { - uint16_t build; - uint16_t type; - uint32_t hints; - uint64_t uniqueId; - uint16_t audioIns; - uint16_t audioOuts; - uint16_t cvIns; - uint16_t cvOuts; - uint16_t midiIns; - uint16_t midiOuts; - uint16_t parameterIns; - uint16_t parameterOuts; -}; - -// full details, now with non-POD types -struct PluginInfo : PluginInfoHeader { - QString category; - QString filename; - QString name; - QString label; - QString maker; -}; - // convert PluginInfo to Qt types static QVariant asByteArray(const PluginInfo& info) { @@ -672,7 +647,7 @@ struct PluginListDialog::PrivateData { bool useWineBridges = false; CarlaPluginDiscoveryHandle handle = nullptr; QCarlaString tool; - CarlaScopedPointer dialog; + ScopedPointer dialog; Discovery() { restart(); @@ -908,7 +883,7 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings* co #if 0 // NOTE: We Assume win32 carla build will not run win64 plugins - if (WINDOWS and not kIs64bit) or not host.showPluginBridges: + if (CARLA_OS_WIN and not CARLA_OS_64BIT) or not host.showPluginBridges: ui.ch_native.setChecked(True) ui.ch_native.setEnabled(False) ui.ch_native.setVisible(True) @@ -2090,78 +2065,3 @@ void PluginListDialog::saveSettings() } // -------------------------------------------------------------------------------------------------------------------- - -PluginListDialog* -carla_frontend_createPluginListDialog(void* const parent, const HostSettings* const hostSettings) -{ - return new PluginListDialog(reinterpret_cast(parent), hostSettings); -} - -void -carla_frontend_destroyPluginListDialog(PluginListDialog* const dialog) -{ - dialog->close(); - delete dialog; -} - -void -carla_frontend_setPluginListDialogPath(PluginListDialog* const dialog, const int ptype, const char* const path) -{ - dialog->setPluginPath(static_cast(ptype), path); -} - -const PluginListDialogResults* -carla_frontend_execPluginListDialog(PluginListDialog* const dialog) -{ - if (dialog->exec()) - { - static PluginListDialogResults ret; - static CarlaString category; - static CarlaString filename; - static CarlaString name; - static CarlaString label; - static CarlaString maker; - - const PluginInfo& plugin(dialog->getSelectedPluginInfo()); - - category = plugin.category.toUtf8(); - filename = plugin.filename.toUtf8(); - name = plugin.name.toUtf8(); - label = plugin.label.toUtf8(); - maker = plugin.maker.toUtf8(); - - ret.build = plugin.build; - ret.type = plugin.type; - ret.hints = plugin.hints; - ret.category = category; - ret.filename = filename; - ret.name = name; - ret.label = label; - ret.maker = maker; - ret.uniqueId = plugin.uniqueId; - ret.audioIns = plugin.audioIns; - ret.audioOuts = plugin.audioOuts; - ret.cvIns = plugin.cvIns; - ret.cvOuts = plugin.cvOuts; - ret.midiIns = plugin.midiIns; - ret.midiOuts = plugin.midiOuts; - ret.parameterIns = plugin.parameterIns; - ret.parameterOuts = plugin.parameterOuts; - - return &ret; - } - - return nullptr; -} - -// -------------------------------------------------------------------------------------------------------------------- - -// const PluginListDialogResults* -// carla_frontend_createAndExecPluginListDialog(void* const parent, const HostSettings* const hostSettings) -// { -// PluginListDialog gui(reinterpret_cast(parent), hostSettings); -// -// return carla_frontend_execPluginListDialog(&gui); -// } - -// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/pluginlist/pluginlistdialog.hpp b/source/frontend/pluginlist/pluginlistdialog.hpp index 447cbeee7..332b37f40 100644 --- a/source/frontend/pluginlist/pluginlistdialog.hpp +++ b/source/frontend/pluginlist/pluginlistdialog.hpp @@ -1,9 +1,9 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include "CarlaFrontend.h" +#include "carla_frontend.h" #ifdef __clang__ # pragma clang diagnostic push @@ -15,7 +15,6 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include #include "ui_pluginlistdialog.h" #ifdef __clang__ @@ -24,10 +23,35 @@ # pragma GCC diagnostic pop #endif -class QSafeSettings; typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; typedef struct _HostSettings HostSettings; -struct PluginInfo; + +// -------------------------------------------------------------------------------------------------------------------- + +// base details, nicely packed and POD-only so we can directly use as binary +struct PluginInfoHeader { + uint16_t build; + uint16_t type; + uint32_t hints; + uint64_t uniqueId; + uint16_t audioIns; + uint16_t audioOuts; + uint16_t cvIns; + uint16_t cvOuts; + uint16_t midiIns; + uint16_t midiOuts; + uint16_t parameterIns; + uint16_t parameterOuts; +}; + +// full details, now with non-POD types +struct PluginInfo : PluginInfoHeader { + QString category; + QString filename; + QString name; + QString label; + QString maker; +}; // -------------------------------------------------------------------------------------------------------------------- // Plugin List Dialog diff --git a/source/frontend/qt_compat.py b/source/frontend/qt_compat.py index 56c23bbcb..3cec424a1 100644 --- a/source/frontend/qt_compat.py +++ b/source/frontend/qt_compat.py @@ -21,13 +21,16 @@ elif qt_config == 6: QDialog, QDialogButtonBox, QFileDialog, + QFrame, QGraphicsItem, QGraphicsScene, QGraphicsView, QHeaderView, + QLineEdit, QListWidgetItem, QMenu, QMessageBox, + QSizePolicy, QStyle, ) @@ -36,11 +39,16 @@ elif qt_config == 6: Qt.AA_DontShowIconsInMenus = Qt.ApplicationAttribute.AA_DontShowIconsInMenus + Qt.DownArrow = Qt.ArrowType.DownArrow + Qt.RightArrow = Qt.ArrowType.RightArrow + Qt.IgnoreAspectRatio = Qt.AspectRatioMode.IgnoreAspectRatio Qt.KeepAspectRatio = Qt.AspectRatioMode.KeepAspectRatio Qt.NoBrush = Qt.BrushStyle.NoBrush + Qt.ToolButtonTextBesideIcon = Qt.ToolButtonStyle.ToolButtonTextBesideIcon + Qt.Checked = Qt.CheckState.Checked Qt.Unchecked = Qt.CheckState.Unchecked @@ -83,6 +91,8 @@ elif qt_config == 6: Qt.Key_E = Qt.Key.Key_E Qt.Key_Eacute = Qt.Key.Key_Eacute Qt.Key_Egrave = Qt.Key.Key_Egrave + Qt.Key_End = Qt.Key.Key_End + Qt.Key_Enter = Qt.Key.Key_Enter Qt.Key_Escape = Qt.Key.Key_Escape Qt.Key_F = Qt.Key.Key_F Qt.Key_G = Qt.Key.Key_G @@ -95,12 +105,16 @@ elif qt_config == 6: Qt.Key_N = Qt.Key.Key_N Qt.Key_O = Qt.Key.Key_O Qt.Key_P = Qt.Key.Key_P + Qt.Key_PageDown = Qt.Key.Key_PageDown + Qt.Key_PageUp = Qt.Key.Key_PageUp Qt.Key_ParenLeft = Qt.Key.Key_ParenLeft Qt.Key_Plus = Qt.Key.Key_Plus Qt.Key_Q = Qt.Key.Key_Q Qt.Key_QuoteDbl = Qt.Key.Key_QuoteDbl Qt.Key_R = Qt.Key.Key_R + Qt.Key_Return = Qt.Key.Key_Return Qt.Key_S = Qt.Key.Key_S + Qt.Key_Space = Qt.Key.Key_Space Qt.Key_T = Qt.Key.Key_T Qt.Key_U = Qt.Key.Key_U Qt.Key_V = Qt.Key.Key_V @@ -132,8 +146,10 @@ elif qt_config == 6: Qt.Horizontal = Qt.Orientation.Horizontal Qt.FlatCap = Qt.PenCapStyle.FlatCap + Qt.RoundCap = Qt.PenCapStyle.RoundCap Qt.MiterJoin = Qt.PenJoinStyle.MiterJoin + Qt.RoundJoin = Qt.PenJoinStyle.RoundJoin Qt.DashLine = Qt.PenStyle.DashLine Qt.NoPen = Qt.PenStyle.NoPen @@ -144,6 +160,11 @@ elif qt_config == 6: Qt.AscendingOrder = Qt.SortOrder.AscendingOrder + Qt.TextSelectableByMouse = Qt.TextInteractionFlag.TextSelectableByMouse + + Qt.ToolButtonIconOnly = Qt.ToolButtonStyle.ToolButtonIconOnly + Qt.ToolButtonTextBesideIcon = Qt.ToolButtonStyle.ToolButtonTextBesideIcon + Qt.SmoothTransformation = Qt.TransformationMode.SmoothTransformation Qt.WA_OpaquePaintEvent = Qt.WidgetAttribute.WA_OpaquePaintEvent @@ -173,6 +194,7 @@ elif qt_config == 6: QDialog.exec_ = lambda d: d.exec() + QDialogButtonBox.Ok = QDialogButtonBox.StandardButton.Ok QDialogButtonBox.Reset = QDialogButtonBox.StandardButton.Reset QEvent.EnabledChange = QEvent.Type.EnabledChange @@ -195,6 +217,12 @@ elif qt_config == 6: QFont.Bold = QFont.Weight.Bold QFont.Normal = QFont.Weight.Normal + QFrame.HLine = QFrame.Shape.HLine + QFrame.StyledPanel = QFrame.Shape.StyledPanel + + QFrame.Raised = QFrame.Shadow.Raised + QFrame.Sunken = QFrame.Shadow.Sunken + QGraphicsItem.ItemSelectedHasChanged = QGraphicsItem.GraphicsItemChange.ItemSelectedHasChanged QGraphicsItem.ItemIsFocusable = QGraphicsItem.GraphicsItemFlag.ItemIsFocusable @@ -211,6 +239,9 @@ elif qt_config == 6: QGraphicsView.MinimalViewportUpdate = QGraphicsView.ViewportUpdateMode.MinimalViewportUpdate QHeaderView.Fixed = QHeaderView.ResizeMode.Fixed + QHeaderView.ResizeToContents = QHeaderView.ResizeMode.ResizeToContents + + QLineEdit.Normal = QLineEdit.EchoMode.Normal QListWidgetItem.UserType = QListWidgetItem.ItemType.UserType @@ -218,9 +249,15 @@ elif qt_config == 6: QMessageBox.exec_ = lambda mb: mb.exec() + QMessageBox.Cancel = QMessageBox.StandardButton.Cancel QMessageBox.No = QMessageBox.StandardButton.No + QMessageBox.Ok = QMessageBox.StandardButton.Ok QMessageBox.Yes = QMessageBox.StandardButton.Yes + QMessageBox.Critical = QMessageBox.Icon.Critical + QMessageBox.Information = QMessageBox.Icon.Information + QMessageBox.Warning = QMessageBox.Icon.Warning + QPainter.CompositionMode_Difference = QPainter.CompositionMode.CompositionMode_Difference QPainter.CompositionMode_Multiply = QPainter.CompositionMode.CompositionMode_Multiply QPainter.CompositionMode_Plus = QPainter.CompositionMode.CompositionMode_Plus @@ -256,6 +293,10 @@ elif qt_config == 6: QPalette.Window = QPalette.ColorRole.Window QPalette.WindowText = QPalette.ColorRole.WindowText + # TODO remove this QPalette.Background is deprecated already in Qt5 QPalette.Background = QPalette.Window + QSizePolicy.Expanding = QSizePolicy.Policy.Expanding + QSizePolicy.Preferred = QSizePolicy.Policy.Preferred + QStyle.State_Selected = QStyle.StateFlag.State_Selected diff --git a/source/frontend/widgets/canvaspreviewframe.py b/source/frontend/widgets/canvaspreviewframe.py index 064009a23..f8c18c944 100644 --- a/source/frontend/widgets/canvaspreviewframe.py +++ b/source/frontend/widgets/canvaspreviewframe.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- @@ -199,7 +199,11 @@ class CanvasPreviewFrame(QFrame): return if self.fMouseMode == self._MOUSE_MODE_SCALE: event.accept() - self._scaleViewRect(event.globalY()) + if qt_config == 5: + y = event.globalY() + else: + y = event.globalPosition().y() + self._scaleViewRect(y) return QFrame.mouseMoveEvent(self, event) @@ -384,24 +388,28 @@ class CanvasPreviewFrame(QFrame): self.setCursor(self.fZoomCursors[self._kCursorZoomIn if dy > 0 else self._kCursorZoomOut]) self.fScene.zoom_wheel(dy) + # FIXME do not rely on this self.cursor().setPos(self.fMouseInitialZoomPos) def _updateMouseMode(self, event): if self.fMouseLeftDown and self.fMouseRightDown: - self.fMouseInitialZoomPos = event.globalPos() + if qt_config == 5: + self.fMouseInitialZoomPos = event.globalPos() + else: + self.fMouseInitialZoomPos = event.globalPosition().toPoint() self.setCursor(self.fZoomCursors[self._kCursorZoom]) self.fMouseMode = self._MOUSE_MODE_SCALE elif self.fMouseLeftDown: self.setCursor(QCursor(Qt.SizeAllCursor)) if self.fMouseMode == self._MOUSE_MODE_NONE: - if QT_VERSION >= 0x60000: + if qt_config == 5: + x = event.x() + y = event.y() + else: pos = event.position() x = pos.x() y = pos.y() - else: - x = event.x() - y = event.y() self._moveViewRect(x, y) self.fMouseMode = self._MOUSE_MODE_MOVE diff --git a/source/frontend/widgets/draggablegraphicsview.py b/source/frontend/widgets/draggablegraphicsview.py index 36293f404..ae22ee11b 100644 --- a/source/frontend/widgets/draggablegraphicsview.py +++ b/source/frontend/widgets/draggablegraphicsview.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- @@ -21,7 +21,8 @@ elif qt_config == 6: # --------------------------------------------------------------------------------------------------------------------- # Imports (Custom Stuff) -from carla_shared import MACOS, CustomMessageBox, gCarla +from carla_backend import CARLA_OS_MAC +from carla_shared import CustomMessageBox, gCarla # --------------------------------------------------------------------------------------------------------------------- # Widget Class @@ -47,7 +48,7 @@ class DraggableGraphicsView(QGraphicsView): if os.path.isdir(filename): #if os.path.exists(os.path.join(filename, "manifest.ttl")): #return True - if MACOS and lfilename.endswith(".vst"): + if CARLA_OS_MAC and lfilename.endswith(".vst"): return True if lfilename.endswith(".vst3") and ".vst3" in self.fSupportedExtensions: return True @@ -119,18 +120,18 @@ class DraggableGraphicsView(QGraphicsView): if timestamp is None: return - if QT_VERSION >= 0x60000: - event = QMouseEvent(QEvent.MouseButtonPress, - event.position(), event.scenePosition(), event.globalPosition(), - Qt.LeftButton, Qt.LeftButton, - Qt.NoModifier) - else: + if qt_config == 5: event = QMouseEvent(QEvent.MouseButtonPress, event.localPos(), event.windowPos(), event.screenPos(), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier, Qt.MouseEventSynthesizedByApplication) event.setTimestamp(timestamp) + else: + event = QMouseEvent(QEvent.MouseButtonPress, + event.position(), event.scenePosition(), event.globalPosition(), + Qt.LeftButton, Qt.LeftButton, + Qt.NoModifier) QGraphicsView.mousePressEvent(self, event) diff --git a/source/frontend/widgets/paramspinbox.py b/source/frontend/widgets/paramspinbox.py index 8d6c2dfe0..4a85a1669 100644 --- a/source/frontend/widgets/paramspinbox.py +++ b/source/frontend/widgets/paramspinbox.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -24,7 +24,8 @@ elif qt_config == 6: import ui_inputdialog_value -from carla_shared import countDecimalPoints, MACOS +from carla_backend import CARLA_OS_MAC +from carla_shared import countDecimalPoints # ------------------------------------------------------------------------------------------------------------ # Get a fixed value within min/max bounds @@ -59,7 +60,7 @@ class CustomInputDialog(QDialog): self.ui.doubleSpinBox.setPrefix(prefix) self.ui.doubleSpinBox.setSuffix(suffix) - if MACOS: + if CARLA_OS_MAC: self.setWindowModality(Qt.WindowModal) if not scalePoints: diff --git a/source/frontend/widgets/pixmapkeyboard.py b/source/frontend/widgets/pixmapkeyboard.py index a81e687f8..160e3d319 100755 --- a/source/frontend/widgets/pixmapkeyboard.py +++ b/source/frontend/widgets/pixmapkeyboard.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # --------------------------------------------------------------------------------------------------------------------- @@ -408,7 +408,10 @@ class PixmapKeyboard(QWidget): if self.fPcKeybOffset == 0: actOctaveDown.setEnabled(False) - actSelected = menu.exec_(event.screenPos().toPoint()) + if qt_config == 5: + actSelected = menu.exec_(event.screenPos().toPoint()) + else: + actSelected = menu.exec_(event.globalPosition().toPoint()) if not actSelected: return diff --git a/source/frontend/widgets/racklistwidget.py b/source/frontend/widgets/racklistwidget.py index f9513d17b..d64c5761e 100644 --- a/source/frontend/widgets/racklistwidget.py +++ b/source/frontend/widgets/racklistwidget.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +# SPDX-FileCopyrightText: 2011-2025 Filipe Coelho # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------------------------------------------------ @@ -24,7 +24,7 @@ elif qt_config == 6: # ------------------------------------------------------------------------------------------------------------ # Imports (Custom Stuff) -from carla_backend import CUSTOM_DATA_TYPE_PROPERTY, MACOS +from carla_backend import CARLA_OS_MAC, CUSTOM_DATA_TYPE_PROPERTY from carla_shared import gCarla, CustomMessageBox from carla_skin import createPluginSlot @@ -259,7 +259,7 @@ class RackListWidget(QListWidget): if os.path.isdir(filename): #if os.path.exists(os.path.join(filename, "manifest.ttl")): #return True - if MACOS and lfilename.endswith(".vst"): + if CARLA_OS_MAC and lfilename.endswith(".vst"): return True if lfilename.endswith(".vst3") and ".vst3" in self.fSupportedExtensions: return True diff --git a/source/includes/CarlaNativeExtUI.hpp b/source/includes/CarlaNativeExtUI.hpp index 31f867397..47cfe813a 100644 --- a/source/includes/CarlaNativeExtUI.hpp +++ b/source/includes/CarlaNativeExtUI.hpp @@ -1,19 +1,5 @@ -/* - * Carla Native Plugin API (C++) - * Copyright (C) 2012-2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED #define CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED @@ -220,7 +206,7 @@ protected: #endif private: - CarlaString fExtUiPath; + String fExtUiPath; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginAndUiClass) }; diff --git a/source/includes/CarlaNativePrograms.hpp b/source/includes/CarlaNativePrograms.hpp index 23c930b42..1291709ab 100644 --- a/source/includes/CarlaNativePrograms.hpp +++ b/source/includes/CarlaNativePrograms.hpp @@ -1,19 +1,5 @@ -/* - * Carla Native Plugin API (C++) - * Copyright (C) 2012-2024 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 - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// SPDX-License-Identifier: GPL-2.0-or-later #ifndef CARLA_NATIVE_PROGRAMS_HPP_INCLUDED #define CARLA_NATIVE_PROGRAMS_HPP_INCLUDED @@ -23,14 +9,14 @@ #include "CarlaMathUtils.hpp" #include "CarlaMutex.hpp" +#include "extra/String.hpp" + #include "water/files/File.h" #include "water/memory/SharedResourcePointer.h" #include "water/text/StringArray.h" using water::File; using water::SharedResourcePointer; -using water::String; -using water::StringArray; /*! * @defgroup CarlaNativeAPI Carla Native API @@ -48,7 +34,7 @@ enum FileType { template struct NativePluginPresetManager { - StringArray filenames; + water::StringArray filenames; NativePluginPresetManager(const char* const paths, const char* const wildcard) : filenames() @@ -58,9 +44,9 @@ struct NativePluginPresetManager { if (paths == nullptr || paths[0] == '\0' || wildcard[0] == '\0') return; - const StringArray splitPaths(StringArray::fromTokens(paths, CARLA_OS_SPLIT_STR, "")); + const water::StringArray splitPaths(water::StringArray::fromTokens(paths, CARLA_OS_SPLIT_STR, "")); - for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) + for (water::String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) { std::vector results; @@ -126,11 +112,11 @@ protected: const NativePluginPresetManagerType& pm(kPrograms.get()); CARLA_SAFE_ASSERT_RETURN(index < pm.filenames.size(), nullptr); - fRetMidiProgramName = File(pm.filenames.strings.getUnchecked(index).toRawUTF8()).getFileNameWithoutExtension(); + fRetMidiProgramName = File(pm.filenames.strings.getUnchecked(index).toRawUTF8()).getFileNameWithoutExtension().toRawUTF8(); fRetMidiProgram.bank = 0; fRetMidiProgram.program = uindex; - fRetMidiProgram.name = fRetMidiProgramName.toRawUTF8(); + fRetMidiProgram.name = fRetMidiProgramName; return &fRetMidiProgram; } diff --git a/source/includes/lv2/atom-helpers.h b/source/includes/lv2/atom-helpers.h index 97cef2c34..b46079650 100644 --- a/source/includes/lv2/atom-helpers.h +++ b/source/includes/lv2/atom-helpers.h @@ -54,6 +54,7 @@ struct _LV2_Atom_Buffer uint32_t capacity; uint32_t chunk_type; uint32_t sequence_type; + uint32_t _alignment_padding; LV2_Atom_Sequence atoms; } LV2_Atom_Buffer; @@ -209,6 +210,11 @@ LV2_Atom_Event *lv2_atom_buffer_get ( // Write an event at a LV2 atom:Sequence buffer iterator. +#if defined(__GNUC__) && __GNUC__ > 7 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + static inline bool lv2_atom_buffer_write ( LV2_Atom_Buffer_Iterator *iter, @@ -240,6 +246,10 @@ bool lv2_atom_buffer_write ( return true; } +#if defined(__GNUC__) && __GNUC__ > 7 +# pragma GCC diagnostic pop +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/source/includes/lv2_rdf.hpp b/source/includes/lv2_rdf.hpp index ac2eb7315..c42d32350 100644 --- a/source/includes/lv2_rdf.hpp +++ b/source/includes/lv2_rdf.hpp @@ -242,7 +242,6 @@ typedef uint32_t LV2_Property; #define LV2_UI_X11 7 #define LV2_UI_EXTERNAL 8 #define LV2_UI_OLD_EXTERNAL 9 -#define LV2_UI_MOD 10 #define LV2_IS_UI_GTK2(x) ((x) == LV2_UI_GTK2) #define LV2_IS_UI_GTK3(x) ((x) == LV2_UI_GTK3) @@ -253,7 +252,6 @@ typedef uint32_t LV2_Property; #define LV2_IS_UI_X11(x) ((x) == LV2_UI_X11) #define LV2_IS_UI_EXTERNAL(x) ((x) == LV2_UI_EXTERNAL) #define LV2_IS_UI_OLD_EXTERNAL(x) ((x) == LV2_UI_OLD_EXTERNAL) -#define LV2_IS_UI_MOD(x) ((x) == LV2_UI_MOD) // Plugin Types #define LV2_PLUGIN_DELAY 0x000001 diff --git a/source/includes/vst3sdk/JUCE_README.md b/source/includes/vst3sdk/JUCE_README.md deleted file mode 100644 index d337f051b..000000000 --- a/source/includes/vst3sdk/JUCE_README.md +++ /dev/null @@ -1,6 +0,0 @@ -This list details modifications made to the VST3 SDK in order to facilitate -inclusion in JUCE. - -- `#warning` directives were removed from fstring.cpp, as these cannot be - silenced with a `pragma GCC diagnostic ignored "-Wcpp"` when building with - g++. diff --git a/source/includes/vst3sdk/LICENSE.txt b/source/includes/vst3sdk/LICENSE.txt deleted file mode 100644 index b5fddfe76..000000000 --- a/source/includes/vst3sdk/LICENSE.txt +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -This license applies only to files referencing this license, -for other files of the Software Development Kit the respective embedded license text -is applicable. The license can be found at: www.steinberg.net/sdklicenses_vst3 - -This Software Development Kit is licensed under the terms of the Steinberg VST3 License, -or alternatively under the terms of the General Public License (GPL) Version 3. -You may use the Software Development Kit according to either of these licenses as it is -most appropriate for your project on a case-by-case basis (commercial or not). - -a) Proprietary Steinberg VST3 License -The Software Development Kit may not be distributed in parts or its entirety -without prior written agreement by Steinberg Media Technologies GmbH. -The SDK must not be used to re-engineer or manipulate any technology used -in any Steinberg or Third-party application or software module, -unless permitted by law. -Neither the name of the Steinberg Media Technologies GmbH nor the names of its -contributors may be used to endorse or promote products derived from this -software without specific prior written permission. -Before publishing a software under the proprietary license, you need to obtain a copy -of the License Agreement signed by Steinberg Media Technologies GmbH. -The Steinberg VST SDK License Agreement can be found at: -www.steinberg.net/en/company/developers.html - -THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - -b) General Public License (GPL) Version 3 -Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html -//---------------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/README.md b/source/includes/vst3sdk/README.md deleted file mode 100644 index 7be410549..000000000 --- a/source/includes/vst3sdk/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Welcome to VST 3 SDK Interfaces - -Here are located all VST interfaces definitions (including VST Component/Controller, UI, Test). - -## License & Usage guidelines - -More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3) - ----- -Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk) \ No newline at end of file diff --git a/source/includes/vst3sdk/base/LICENSE.txt b/source/includes/vst3sdk/base/LICENSE.txt deleted file mode 100644 index d5d3145b1..000000000 --- a/source/includes/vst3sdk/base/LICENSE.txt +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/base/README.md b/source/includes/vst3sdk/base/README.md deleted file mode 100644 index d612400fc..000000000 --- a/source/includes/vst3sdk/base/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Welcome to VST SDK 3 base - -Here you can find some helper classes useful for developing VST3 Plug-Ins. - -## License & Usage guidelines -More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3) - ----- -Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk) \ No newline at end of file diff --git a/source/includes/vst3sdk/base/source/baseiids.cpp b/source/includes/vst3sdk/base/source/baseiids.cpp deleted file mode 100644 index d7b1f7b52..000000000 --- a/source/includes/vst3sdk/base/source/baseiids.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/baseidds.cpp -// Created by : Steinberg, 01/2008 -// Description : Basic Interface -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "pluginterfaces/base/funknown.h" -#include "pluginterfaces/base/istringresult.h" -#include "pluginterfaces/base/ipersistent.h" - - -namespace Steinberg { - -DEF_CLASS_IID (IString) -DEF_CLASS_IID (IStringResult) - -DEF_CLASS_IID (IPersistent) -DEF_CLASS_IID (IAttributes) -DEF_CLASS_IID (IAttributes2) -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/classfactoryhelpers.h b/source/includes/vst3sdk/base/source/classfactoryhelpers.h deleted file mode 100644 index 075c0a738..000000000 --- a/source/includes/vst3sdk/base/source/classfactoryhelpers.h +++ /dev/null @@ -1,87 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/classfactoryhelpers.h -// Created by : Steinberg, 03/2017 -// Description : Class factory -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#pragma once - -//------------------------------------------------------------------------------ -// Helper Macros. Not intended for direct use. -// Use: -// META_CLASS(className), -// META_CLASS_IFACE(className,Interface), -// META_CLASS_SINGLE(className,Interface) -// instead. -//------------------------------------------------------------------------------ -#define META_CREATE_FUNC(funcName) static FUnknown* funcName () - -#define CLASS_CREATE_FUNC(className) \ - namespace Meta { \ - META_CREATE_FUNC (make##className) { return (NEW className)->unknownCast (); } \ - } - -#define SINGLE_CREATE_FUNC(className) \ - namespace Meta { \ - META_CREATE_FUNC (make##className) { return className::instance ()->unknownCast (); } \ - } - -#define _META_CLASS(className) \ - namespace Meta { \ - static Steinberg::MetaClass meta##className ((#className), Meta::make##className); \ - } - -#define _META_CLASS_IFACE(className, Interface) \ - namespace Meta { \ - static Steinberg::MetaClass meta##Interface##className ((#className), Meta::make##className, \ - Interface##_iid); \ - } - -/** TODO - */ -#define META_CLASS(className) \ - CLASS_CREATE_FUNC (className) \ - _META_CLASS (className) - -/** TODO - */ -#define META_CLASS_IFACE(className, Interface) \ - CLASS_CREATE_FUNC (className) \ - _META_CLASS_IFACE (className, Interface) - -/** TODO - */ -#define META_CLASS_SINGLE(className, Interface) \ - SINGLE_CREATE_FUNC (className) \ - _META_CLASS_IFACE (className, Interface) diff --git a/source/includes/vst3sdk/base/source/fbuffer.cpp b/source/includes/vst3sdk/base/source/fbuffer.cpp deleted file mode 100644 index a67ad5691..000000000 --- a/source/includes/vst3sdk/base/source/fbuffer.cpp +++ /dev/null @@ -1,643 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fbuffer.cpp -// Created by : Steinberg, 2008 -// Description : -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "base/source/fbuffer.h" -#include "base/source/fstring.h" -#include - -namespace Steinberg { - -//------------------------------------------------------------------------------------- -Buffer::Buffer () -: buffer (nullptr) -, memSize (0) -, fillSize (0) -, delta (defaultDelta) -{} - -//------------------------------------------------------------------------------------- -Buffer::Buffer (uint32 s, uint8 initVal) -: buffer (nullptr) -, memSize (s) -, fillSize (0) -, delta (defaultDelta) -{ - if (memSize == 0) - return; - buffer = (int8*)::malloc (memSize); - if (buffer) - memset (buffer, initVal, memSize); - else - memSize = 0; -} - -//------------------------------------------------------------------------------------- -Buffer::Buffer (uint32 s) -: buffer (nullptr) -, memSize (s) -, fillSize (0) -, delta (defaultDelta) -{ - if (memSize == 0) - return; - buffer = (int8*)::malloc (memSize); - if (!buffer) - memSize = 0; -} - -//------------------------------------------------------------------------------------- -Buffer::Buffer (const void* b , uint32 s) -: buffer (nullptr) -, memSize (s) -, fillSize (s) -, delta (defaultDelta) -{ - if (memSize == 0) - return; - buffer = (int8*)::malloc (memSize); - if (buffer) - memcpy (buffer, b, memSize); - else - { - memSize = 0; - fillSize = 0; - } -} - -//------------------------------------------------------------------------------------- -Buffer::Buffer (const Buffer& bufferR) -: buffer (nullptr) -, memSize (bufferR.memSize) -, fillSize (bufferR.fillSize) -, delta (bufferR.delta) -{ - if (memSize == 0) - return; - - buffer = (int8*)::malloc (memSize); - if (buffer) - memcpy (buffer, bufferR.buffer, memSize); - else - memSize = 0; -} - -//------------------------------------------------------------------------------------- -Buffer::~Buffer () -{ - if (buffer) - ::free (buffer); - buffer = nullptr; -} - -//------------------------------------------------------------------------------------- -void Buffer::operator = (const Buffer& b2) -{ - if (&b2 != this) - { - setSize (b2.memSize); - if (b2.memSize > 0 && buffer) - memcpy (buffer, b2.buffer, b2.memSize); - fillSize = b2.fillSize; - delta = b2.delta; - } -} - -//------------------------------------------------------------------------------------- -bool Buffer::operator == (const Buffer& b2)const -{ - if (&b2 == this) - return true; - if (b2.getSize () != getSize ()) - return false; - return memcmp (this->int8Ptr (), b2.int8Ptr (), getSize ()) == 0 ? true : false; -} - -//------------------------------------------------------------------------------------- -uint32 Buffer::get (void* b, uint32 size) -{ - uint32 maxGet = memSize - fillSize; - if (size > maxGet) - size = maxGet; - if (size > 0) - memcpy (b, buffer + fillSize, size); - fillSize += size; - return size; -} - -//------------------------------------------------------------------------------------- -bool Buffer::put (char16 c) -{ - return put ((const void*)&c, sizeof (c)); -} - -//------------------------------------------------------------------------------------- -bool Buffer::put (uint8 byte) -{ - if (grow (fillSize + 1) == false) - return false; - - buffer [fillSize++] = byte; - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::put (char c) -{ - if (grow (fillSize + 1) == false) - return false; - - buffer [fillSize++] = c; - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::put (const void* toPut, uint32 s) -{ - if (!toPut) - return false; - - if (grow (fillSize + s) == false) - return false; - - memcpy (buffer + fillSize, toPut, s); - fillSize += s; - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::put (const String& str) -{ - return put ((const void*)str.text () , (str.length () + 1) * sizeof (tchar)); -} - -//------------------------------------------------------------------------------------- -bool Buffer::appendString8 (const char8* s) -{ - if (!s) - return false; - - uint32 len = (uint32) strlen (s); - return put (s, len); -} - -//------------------------------------------------------------------------------------- -bool Buffer::appendString16 (const char16* s) -{ - if (!s) - return false; - ConstString str (s); - uint32 len = (uint32) str.length () * sizeof (char16); - return put (s, len); -} - -//------------------------------------------------------------------------------------- -bool Buffer::prependString8 (const char8* s) -{ - if (!s) - return false; - - uint32 len = (uint32) strlen (s); - if (len > 0) - { - shiftStart (len); - memcpy (buffer, s, len); - return true; - } - return false; -} - -//------------------------------------------------------------------------------------- -bool Buffer::prependString16 (const char16* s) -{ - if (!s) - return false; - - ConstString str (s); - uint32 len = (uint32) str.length () * sizeof (char16); - - if (len > 0) - { - shiftStart (len); - memcpy (buffer, s, len); - return true; - } - return false; -} - -//------------------------------------------------------------------------------------- -bool Buffer::prependString8 (char8 c) -{ - shiftStart (sizeof (char)); - char* b = (char*)buffer; - b [0] = c; - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::prependString16 (char16 c) -{ - shiftStart (sizeof (char16)); - char16* b = (char16*)buffer; - b [0] = c; - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::copy (uint32 from, uint32 to, uint32 bytes) -{ - if (from + bytes > memSize || bytes == 0) - return false; - - if (to + bytes > memSize) - setSize (to + bytes); - - if (from + bytes > to && from < to) - { // overlap - Buffer tmp (buffer + from, bytes); - memcpy (buffer + to, tmp, bytes); - } - else - memcpy (buffer + to, buffer + from, bytes); - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::makeHexString (String& result) -{ - unsigned char* data = uint8Ptr (); - uint32 bytes = getSize (); - - if (data == nullptr || bytes == 0) - return false; - - char8* stringBuffer = (char8*)malloc ((bytes * 2) + 1); - if (!stringBuffer) - return false; - - int32 count = 0; - while (bytes > 0) - { - unsigned char t1 = ((*data) >> 4) & 0x0F; - unsigned char t2 = (*data) & 0x0F; - if (t1 < 10) - t1 += '0'; - else - t1 = t1 - 10 + 'A'; - if (t2 < 10) - t2 += '0'; - else - t2 = t2 - 10 + 'A'; - - stringBuffer [count++] = t1; - stringBuffer [count++] = t2; - data++; - bytes--; - } - stringBuffer [count] = 0; - - result.take ((void*)stringBuffer, false); - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::fromHexString (const char8* string) -{ - flush (); - if (string == nullptr) - return false; - - int32 len = strlen8 (string); - if (len == 0 || ((len & 1) == 1)/*odd number*/ ) - return false; - - setSize (len / 2); - unsigned char* data = uint8Ptr (); - - bool upper = true; - int32 count = 0; - while (count < len) - { - char c = string [count]; - - unsigned char d = 0; - if (c >= '0' && c <= '9') d += c - '0'; - else if (c >= 'A' && c <= 'F') d += c - 'A' + 10; - else if (c >= 'a' && c <= 'f') d += c - 'a' + 10; - else return false; // no hex string - - if (upper) - data [count >> 1] = static_cast (d << 4); - else - data [count >> 1] += d; - - upper = !upper; - count++; - } - setFillSize (len / 2); - return true; -} - -//------------------------------------------------------------------------ -void Buffer::set (uint8 value) -{ - if (buffer) - memset (buffer, value, memSize); -} - -//------------------------------------------------------------------------------------- -bool Buffer::setFillSize (uint32 c) -{ - if (c <= memSize) - { - fillSize = c; - return true; - } - return false; -} - -//------------------------------------------------------------------------------------- -bool Buffer::truncateToFillSize () -{ - if (fillSize < memSize) - setSize (fillSize); - - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::grow (uint32 newSize) -{ - if (newSize > memSize) - { - if (delta == 0) - delta = defaultDelta; - uint32 s = ((newSize + delta - 1) / delta) * delta; - return setSize (s); - } - return true; -} - -//------------------------------------------------------------------------ -void Buffer::shiftAt (uint32 position, int32 amount) -{ - if (amount > 0) - { - if (grow (fillSize + amount)) - { - if (position < fillSize) - memmove (buffer + amount + position, buffer + position, fillSize - position); - - fillSize += amount; - } - } - else if (amount < 0 && fillSize > 0) - { - uint32 toRemove = -amount; - - if (toRemove < fillSize) - { - if (position < fillSize) - memmove (buffer + position, buffer + toRemove + position, fillSize - position - toRemove); - fillSize -= toRemove; - } - } -} - -//------------------------------------------------------------------------------------- -void Buffer::move (int32 amount, uint8 initVal) -{ - if (memSize == 0) - return; - - if (amount > 0) - { - if ((uint32)amount < memSize) - { - memmove (buffer + amount, buffer, memSize - amount); - memset (buffer, initVal, amount); - } - else - memset (buffer, initVal, memSize); - } - else - { - uint32 toRemove = -amount; - if (toRemove < memSize) - { - memmove (buffer, buffer + toRemove, memSize - toRemove); - memset (buffer + memSize - toRemove, initVal, toRemove); - } - else - memset (buffer, initVal, memSize); - } -} - -//------------------------------------------------------------------------------------- -bool Buffer::setSize (uint32 newSize) -{ - if (memSize != newSize) - { - if (buffer) - { - if (newSize > 0) - { - int8* newBuffer = (int8*) ::realloc (buffer, newSize); - if (newBuffer == nullptr) - { - newBuffer = (int8*)::malloc (newSize); - if (newBuffer) - { - uint32 tmp = newSize; - if (tmp > memSize) - tmp = memSize; - memcpy (newBuffer, buffer, tmp); - ::free (buffer); - buffer = newBuffer; - } - else - { - ::free (buffer); - buffer = nullptr; - } - } - else - buffer = newBuffer; - } - else - { - ::free (buffer); - buffer = nullptr; - } - } - else - buffer = (int8*)::malloc (newSize); - - if (newSize > 0 && !buffer) - memSize = 0; - else - memSize = newSize; - if (fillSize > memSize) - fillSize = memSize; - } - - return (newSize > 0) == (buffer != nullptr); -} - -//------------------------------------------------------------------------------------- -void Buffer::fillup (uint8 value) -{ - if (getFree () > 0) - memset (buffer + fillSize, value, getFree ()); -} - -//------------------------------------------------------------------------------------- -int8* Buffer::operator + (uint32 i) -{ - if (i < memSize) - return buffer + i; - else - { - static int8 eof; - eof = 0; - return &eof; - } -} - -//------------------------------------------------------------------------------------- -bool Buffer::swap (int16 swapSize) -{ - return swap (buffer, memSize, swapSize); -} - -//------------------------------------------------------------------------------------- -bool Buffer::swap (void* buffer, uint32 bufferSize, int16 swapSize) -{ - if (swapSize != kSwap16 && swapSize != kSwap32 && swapSize != kSwap64) - return false; - - if (swapSize == kSwap16) - { - for (uint32 count = 0 ; count < bufferSize ; count += 2) - { - SWAP_16 ( * (((int16*)buffer) + count) ); - } - } - else if (swapSize == kSwap32) - { - for (uint32 count = 0 ; count < bufferSize ; count += 4) - { - SWAP_32 ( * (((int32*)buffer) + count) ); - } - } - else if (swapSize == kSwap64) - { - for (uint32 count = 0 ; count < bufferSize ; count += 8) - { - SWAP_64 ( * (((int64*)buffer) + count) ); - } - } - - return true; -} - -//------------------------------------------------------------------------------------- -void Buffer::take (Buffer& from) -{ - setSize (0); - memSize = from.memSize; - fillSize = from.fillSize; - buffer = from.buffer; - from.buffer = nullptr; - from.memSize = 0; - from.fillSize = 0; -} - -//------------------------------------------------------------------------------------- -int8* Buffer::pass () -{ - int8* res = buffer; - buffer = nullptr; - memSize = 0; - fillSize = 0; - return res; -} - -//------------------------------------------------------------------------------------- -bool Buffer::toWideString (int32 sourceCodePage) -{ - if (getFillSize () > 0) - { - if (str8 () [getFillSize () - 1] != 0) // multiByteToWideString only works with 0-terminated strings - endString8 (); - - Buffer dest (getFillSize () * sizeof (char16)); - int32 result = String::multiByteToWideString (dest.str16 (), buffer, dest.getFree () / sizeof (char16), sourceCodePage); - if (result > 0) - { - dest.setFillSize ((result - 1) * sizeof (char16)); - take (dest); - return true; - } - return false; - } - return true; -} - -//------------------------------------------------------------------------------------- -bool Buffer::toMultibyteString (int32 destCodePage) -{ - if (getFillSize () > 0) - { - int32 textLength = getFillSize () / sizeof (char16); // wideStringToMultiByte only works with 0-terminated strings - if (str16 () [textLength - 1] != 0) - endString16 (); - - Buffer dest (getFillSize ()); - int32 result = String::wideStringToMultiByte (dest.str8 (), str16 (), dest.getFree (), destCodePage); - if (result > 0) - { - dest.setFillSize (result - 1); - take (dest); - return true; - } - return false; - } - return true; -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fbuffer.h b/source/includes/vst3sdk/base/source/fbuffer.h deleted file mode 100644 index d0e2f3940..000000000 --- a/source/includes/vst3sdk/base/source/fbuffer.h +++ /dev/null @@ -1,306 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fbuffer.h -// Created by : Steinberg, 2008 -// Description : -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/ftypes.h" -#include - -namespace Steinberg { -class String; - -//------------------------------------------------------------------------ -/** Buffer. -@ingroup adt - -A Buffer is an object-oriented wrapper for a piece of memory. -It adds several utility functions, e.g. for managing the size of the Buffer, -appending or prepending values or strings to it. -Internally it uses the standard memory functions malloc(), free(), etc. */ -//------------------------------------------------------------------------ -class Buffer -{ -public: -//--------------------------------------------------------------------- - - /** Default constructor, allocates no memory at all. - */ - Buffer (); - - /** Constructor - creates a new Buffer with a given size and copies contents from optional memory pointer. - \param[in] b : optional memory pointer with the size of at least the given size - \param[in] size : the size of the new Buffer to be allocated, in bytes. - */ - Buffer (const void* b, uint32 size); - - /** Constructor - creates a new Buffer with a given size and fills it all with a given value. - \param[in] size : the size of the new Buffer to be allocated, in bytes. - \param[in] initVal : the initial value the Buffer will be completely filled with - */ - Buffer (uint32 size, uint8 initVal); - - /** Constructor - creates a new Buffer with a given size. - \param[in] size : the size of the new Buffer to be allocated, in bytes. - */ - Buffer (uint32 size); - - /** Copy constructor - creates a new Buffer from a given Buffer. - \param[in] buff : the Buffer from which all memory will be copied to the new one - */ - Buffer (const Buffer& buff); - - /** Destructor - deallocates the internal memory. - */ - virtual ~Buffer (); - - /** Assignment operator - copies contents from a given Buffer and increases the size if necessary. - \param[in] buff : the Buffer from which all memory will be copied - */ - void operator = (const Buffer& buff); - - /** Comparison operator - copies contents from a given Buffer and increases the size if necessary. - \param[in] buff : the Buffer to be compared to - \return true, if the given Buffer's content is equal to this one, else false - */ - bool operator == (const Buffer& buff)const; - - uint32 getSize () const {return memSize;} ///< \return the actual size of the Buffer's memory, in bytes. - - /** Sets a new size for this Buffer, keeping as much content as possible. - \param[in] newSize : the new size for the Buffer, in bytes, newSize maybe zero - \return true, if the new size could be adapted, else false - */ - bool setSize (uint32 newSize); - - /** Increases the Buffer to the next block, block size given by delta. - \param[in] memSize : the new minimum size of the Buffer, newSize maybe zero - \return true, if the Buffer could be grown successfully, else false - */ - bool grow (uint32 memSize); - bool setMaxSize (uint32 size) {return grow (size);} ///< see \ref grow() - - void fillup (uint8 initVal = 0); ///< set from fillSize to end - uint32 getFillSize ()const {return fillSize;} ///< \return the actual fill size - bool setFillSize (uint32 c); ///< sets a new fill size, does not change any memory - inline void flush () {setFillSize (0);} ///< sets fill size to zero - bool truncateToFillSize (); ///< \return always true, truncates the size of the Buffer to the actual fill size - - bool isFull () const { return (fillSize == memSize); } ///< \return true, if all memory is filled up, else false - uint32 getFree () const { return (memSize - fillSize); }///< \return remaining memory - - inline void shiftStart (int32 amount) {return shiftAt (0, amount);} ///< moves all memory by given amount, grows the Buffer if necessary - void shiftAt (uint32 position, int32 amount); ///< moves memory starting at the given position - void move (int32 amount, uint8 initVal = 0); ///< shifts memory at start without growing the buffer, so data is lost and initialized with init val - - bool copy (uint32 from, uint32 to, uint32 bytes); ///< copies a number of bytes from one position to another, the size may be adapted - uint32 get (void* b, uint32 size); ///< copy to buffer from fillSize, and shift fillSize - - void setDelta (uint32 d) {delta = d;} ///< define the block size by which the Buffer grows, see \ref grow() - - bool put (uint8); ///< append value at end, grows Buffer if necessary - bool put (char16 c); ///< append value at end, grows Buffer if necessary - bool put (char c); ///< append value at end, grows Buffer if necessary - bool put (const void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (const uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (const char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary - bool put (const String&); ///< append String at end, grows Buffer if necessary - - void set (uint8 value); ///< fills complete Buffer with given value - - // strings ---------------- - bool appendString (const tchar* s); - bool appendString (tchar* s); - bool appendString (tchar c) { return put (c); } - - bool appendString8 (const char8* s); - bool appendString16 (const char16* s); - - bool appendString8 (char8* s) { return appendString8 ((const char8*)s); } - bool appendString8 (unsigned char* s) { return appendString8 ((const char8*)s); } - bool appendString8 (const unsigned char* s) { return appendString8 ((const char8*)s); } - - bool appendString8 (char8 c) { return put ((uint8)c); } - bool appendString8 (unsigned char c) { return put (c); } - bool appendString16 (char16 c) { return put (c); } - bool appendString16 (char16* s) { return appendString16 ((const char16*)s); } - - bool prependString (const tchar* s); - bool prependString (tchar* s); - bool prependString (tchar c); - - bool prependString8 (const char8* s); - bool prependString16 (const char16* s); - - bool prependString8 (char8 c); - bool prependString8 (unsigned char c) { return prependString8 ((char8)c); } - bool prependString8 (char8* s) { return prependString8 ((const char8*)s); } - bool prependString8 (unsigned char* s) { return prependString8((const char8*)s); } - bool prependString8 (const unsigned char* s) { return prependString8 ((const char8*)s); } - bool prependString16 (char16 c); - bool prependString16 (char16* s) { return prependString16 ((const char16*)s); } - - bool operator+= (const char* s) { return appendString8 (s); } - bool operator+= (char c) { return appendString8 (c); } - bool operator+= (const char16* s) { return appendString16 (s); } - bool operator+= (char16 c) { return appendString16 (c); } - - bool operator= (const char* s) { flush (); return appendString8 (s); } - bool operator= (const char16* s) { flush (); return appendString16 (s); } - bool operator= (char8 c) { flush (); return appendString8 (c); } - bool operator= (char16 c) { flush (); return appendString16 (c); } - - void endString () {put (tchar (0));} - void endString8 () {put (char8 (0));} - void endString16 () {put (char16 (0));} - - bool makeHexString (String& result); - bool fromHexString (const char8* string); - - // conversion - operator void* () const { return (void*)buffer; } ///< conversion - inline tchar* str () const {return (tchar*)buffer;} ///< conversion - inline char8* str8 () const {return (char8*)buffer;} ///< conversion - inline char16* str16 () const {return (char16*)buffer;} ///< conversion - inline int8* int8Ptr () const {return (int8*)buffer;} ///< conversion - inline uint8* uint8Ptr () const {return (uint8*)buffer; } ///< conversion - inline int16* int16Ptr () const {return (int16*)buffer; } ///< conversion - inline uint16* uint16Ptr () const {return (uint16*)buffer; } ///< conversion - inline int32* int32Ptr () const {return (int32*)buffer; } ///< conversion - inline uint32* uint32Ptr () const {return (uint32*)buffer; } ///< conversion - inline float* floatPtr () const {return (float*)buffer; } ///< conversion - inline double* doublePtr () const {return (double*)buffer; } ///< conversion - inline char16* wcharPtr () const {return (char16*)buffer;} ///< conversion - - int8* operator + (uint32 i); ///< \return the internal Buffer's address plus the given offset i, zero if offset is out of range - - int32 operator ! () { return buffer == nullptr; } - - enum swapSize - { - kSwap16 = 2, - kSwap32 = 4, - kSwap64 = 8 - }; - bool swap (int16 swapSize); ///< swap all bytes of this Buffer by the given swapSize - static bool swap (void* buffer, uint32 bufferSize, int16 swapSize); ///< utility, swap given number of bytes in given buffer by the given swapSize - - void take (Buffer& from); ///< takes another Buffer's memory, frees the current Buffer's memory - int8* pass (); ///< pass the current Buffer's memory - - /** Converts a Buffer's content to UTF-16 from a given multi-byte code page, Buffer must contain char8 of given encoding. - \param[in] sourceCodePage : the actual code page of the Buffer's content - \return true, if the conversion was successful, else false - */ - virtual bool toWideString (int32 sourceCodePage); // Buffer contains char8 of given encoding -> utf16 - - /** Converts a Buffer's content from UTF-16 to a given multi-byte code page, Buffer must contain UTF-16 encoded characters. - \param[in] destCodePage : the desired code page to convert the Buffer's content to - \return true, if the conversion was successful, else false - */ - virtual bool toMultibyteString (int32 destCodePage); // Buffer contains utf16 -> char8 of given encoding - -//------------------------------------------------------------------------ -protected: - static const uint32 defaultDelta = 0x1000; // 0x1000 - - int8* buffer; - uint32 memSize; - uint32 fillSize; - uint32 delta; -}; - -inline bool Buffer::put (void* p, uint32 count) { return put ((const void*)p , count ); } -inline bool Buffer::put (uint8 * p, uint32 count) { return put ((const void*)p , count ); } -inline bool Buffer::put (char8* p, uint32 count) { return put ((const void*)p , count ); } -inline bool Buffer::put (const uint8* p, uint32 count) { return put ((const void*)p , count ); } -inline bool Buffer::put (const char8* p, uint32 count) { return put ((const void*)p , count ); } - -//------------------------------------------------------------------------ -inline bool Buffer::appendString (const tchar* s) -{ -#ifdef UNICODE - return appendString16 (s); -#else - return appendString8 (s); -#endif -} - -//------------------------------------------------------------------------ -inline bool Buffer::appendString (tchar* s) -{ -#ifdef UNICODE - return appendString16 (s); -#else - return appendString8 (s); -#endif -} - -//------------------------------------------------------------------------ -inline bool Buffer::prependString (const tchar* s) -{ -#ifdef UNICODE - return prependString16 (s); -#else - return prependString8 (s); -#endif -} - -//------------------------------------------------------------------------ -inline bool Buffer::prependString (tchar* s) -{ -#ifdef UNICODE - return prependString16 (s); -#else - return prependString8 (s); -#endif -} - -//------------------------------------------------------------------------ -inline bool Buffer::prependString (tchar c) -{ -#ifdef UNICODE - return prependString16 (c); -#else - return prependString8 (c); -#endif -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fdebug.cpp b/source/includes/vst3sdk/base/source/fdebug.cpp deleted file mode 100644 index 6355feba1..000000000 --- a/source/includes/vst3sdk/base/source/fdebug.cpp +++ /dev/null @@ -1,319 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fdebug.cpp -// Created by : Steinberg, 1995 -// Description : There are 2 levels of debugging messages: -// DEVELOPMENT During development -// RELEASE Program is shipping. -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "base/source/fdebug.h" - -#if SMTG_OS_WINDOWS -#include - -bool AmIBeingDebugged () -{ - return IsDebuggerPresent (); -} -#endif - -#if SMTG_OS_LINUX -#include -#include -#include -//-------------------------------------------------------------------------- -bool AmIBeingDebugged () -{ - // TODO: check if GDB or LLDB is attached - return true; -} -#endif - -#if SMTG_OS_MACOS - -#include -#include -#include -#include - -//------------------------------------------------------------------------ -// from Technical Q&A QA1361 (http://developer.apple.com/qa/qa2004/qa1361.html) -//------------------------------------------------------------------------ -bool AmIBeingDebugged () -// Returns true if the current process is being debugged (either -// running under the debugger or has a debugger attached post facto). -{ - int mib[4]; - struct kinfo_proc info; - size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid (); - - // Call sysctl. - - size = sizeof (info); - sysctl (mib, sizeof (mib) / sizeof (*mib), &info, &size, NULL, 0); - - // We're being debugged if the P_TRACED flag is set. - return ((info.kp_proc.p_flag & P_TRACED) != 0); -} - -#endif // SMTG_OS_MACOS - -#if DEVELOPMENT - -#include -#include -#include - -#if SMTG_OS_WINDOWS -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 -#endif -#if _MSC_VER -#include -#endif -#define vsnprintf _vsnprintf -#define snprintf _snprintf - -#elif SMTG_OS_MACOS -#include -#include -#include -#include -#include - -#define THREAD_ALLOC_WATCH 0 // check allocations on specific threads - -#if THREAD_ALLOC_WATCH -mach_port_t watchThreadID = 0; -#endif - -#endif - -AssertionHandler gAssertionHandler = nullptr; -AssertionHandler gPreAssertionHook = nullptr; -DebugPrintLogger gDebugPrintLogger = nullptr; - -//-------------------------------------------------------------------------- -static const int kDebugPrintfBufferSize = 10000; -static bool neverDebugger = false; // so I can switch it off in the debugger... - -//-------------------------------------------------------------------------- -static void printDebugString (const char* string) -{ - if (!string) - return; - - if (gDebugPrintLogger) - { - gDebugPrintLogger (string); - } - else - { -#if SMTG_OS_MACOS || defined(__MINGW32__) - fprintf (stderr, "%s", string); -#elif SMTG_OS_WINDOWS - OutputDebugStringA (string); -#endif - } -} - -//-------------------------------------------------------------------------- -// printf style debugging output -//-------------------------------------------------------------------------- -void FDebugPrint (const char* format, ...) -{ - char string[kDebugPrintfBufferSize]; - va_list marker; - va_start (marker, format); - vsnprintf (string, kDebugPrintfBufferSize, format, marker); - - printDebugString (string); -} - -//-------------------------------------------------------------------------- -// printf style debugging output -//-------------------------------------------------------------------------- -void FDebugBreak (const char* format, ...) -{ - char string[kDebugPrintfBufferSize]; - va_list marker; - va_start (marker, format); - vsnprintf (string, kDebugPrintfBufferSize, format, marker); - - printDebugString (string); - - // The Pre-assertion hook is always called, even if we're not running in the debugger, - // so that we can log asserts without displaying them - if (gPreAssertionHook) - { - gPreAssertionHook (string); - } - - if (neverDebugger) - return; - if (AmIBeingDebugged ()) - { - // do not crash if no debugger present - // If there is an assertion handler defined then let this override the UI - // and tell us whether we want to break into the debugger - bool breakIntoDebugger = true; - if (gAssertionHandler && gAssertionHandler (string) == false) - { - breakIntoDebugger = false; - } - - if (breakIntoDebugger) - { -#if SMTG_OS_WINDOWS && _MSC_VER - __debugbreak (); // intrinsic version of DebugBreak() -#elif SMTG_OS_MACOS && __arm64__ - raise (SIGSTOP); - -#elif __ppc64__ || __ppc__ || __arm__ - kill (getpid (), SIGINT); -#elif __i386__ || __x86_64__ - { - __asm__ volatile ("int3"); - } -#endif - } - } -} - -//-------------------------------------------------------------------------- -void FPrintLastError (const char* file, int line) -{ -#if SMTG_OS_WINDOWS - LPVOID lpMessageBuffer; - FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, - GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&lpMessageBuffer, 0, nullptr); - FDebugPrint ("%s(%d) : %s\n", file, line, lpMessageBuffer); - LocalFree (lpMessageBuffer); -#endif - -#if SMTG_OS_MACOS -#if !__MACH__ - extern int errno; -#endif - FDebugPrint ("%s(%d) : Errno %d\n", file, line, errno); -#endif -} - -#if SMTG_OS_MACOS - -//------------------------------------------------------------------------ -void* operator new (size_t size, int, const char* file, int line) -{ -#if THREAD_ALLOC_WATCH - mach_port_t threadID = mach_thread_self (); - if (watchThreadID == threadID) - { - FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line); - } -#endif - try - { - return ::operator new (size); - } - catch (std::bad_alloc exception) - { - FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line); - } - return (void*)-1; -} - -//------------------------------------------------------------------------ -void* operator new[] (size_t size, int, const char* file, int line) -{ -#if THREAD_ALLOC_WATCH - mach_port_t threadID = mach_thread_self (); - if (watchThreadID == threadID) - { - FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line); - } -#endif - try - { - return ::operator new[] (size); - } - catch (std::bad_alloc exception) - { - FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line); - } - return (void*)-1; -} - -//------------------------------------------------------------------------ -void operator delete (void* p, int, const char* file, int line) -{ - ::operator delete (p); -} - -//------------------------------------------------------------------------ -void operator delete[] (void* p, int, const char* file, int line) -{ - ::operator delete[] (p); -} - -#endif // SMTG_OS_MACOS - -#endif // DEVELOPMENT - -static bool smtg_unit_testing_active = false; // ugly hack to unit testing ... - -//------------------------------------------------------------------------ -bool isSmtgUnitTesting () -{ - return smtg_unit_testing_active; -} - -//------------------------------------------------------------------------ -void setSmtgUnitTesting () -{ - smtg_unit_testing_active = true; -} diff --git a/source/includes/vst3sdk/base/source/fdebug.h b/source/includes/vst3sdk/base/source/fdebug.h deleted file mode 100644 index a5d9923f8..000000000 --- a/source/includes/vst3sdk/base/source/fdebug.h +++ /dev/null @@ -1,241 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fdebug.h -// Created by : Steinberg, 1995 -// Description : There are 2 levels of debugging messages: -// DEVELOPMENT During development -// RELEASE Program is shipping. -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -/** @file base/source/fdebug.h - Debugging tools. - - There are 2 levels of debugging messages: - - DEVELOPMENT - - During development - - RELEASE - - Program is shipping. -*/ -//----------------------------------------------------------------------------- -#pragma once - -#include "pluginterfaces/base/ftypes.h" -#include - -#if SMTG_OS_MACOS -#include -#endif - -/** Returns true if a debugger is attached. */ -bool AmIBeingDebugged (); - -//----------------------------------------------------------------------------- -// development / release -//----------------------------------------------------------------------------- -#if !defined (DEVELOPMENT) && !defined (RELEASE) - #ifdef _DEBUG - #define DEVELOPMENT 1 - #elif defined (NDEBUG) - #define RELEASE 1 - #else - #error DEVELOPMENT, RELEASE, _DEBUG, or NDEBUG must be defined! - #endif -#endif - -//----------------------------------------------------------------------------- -#if SMTG_OS_WINDOWS - -/** Disable compiler warning: - * C4291: "No matching operator delete found; memory will not be freed if initialization throws an - * exception. A placement new is used for which there is no placement delete." */ -#if DEVELOPMENT && defined(_MSC_VER) -#pragma warning(disable : 4291) -#pragma warning(disable : 4985) -#endif - -#endif // SMTG_OS_WINDOWS - -#if DEVELOPMENT -//----------------------------------------------------------------------------- -/** If "f" is not true and a debugger is present, send an error string to the debugger for display - and cause a breakpoint exception to occur in the current process. SMTG_ASSERT is removed - completely in RELEASE configuration. So do not pass methods calls to this macro that are expected - to exist in the RELEASE build (for method calls that need to be present in a RELEASE build, use - the VERIFY macros instead)*/ -#define SMTG_ASSERT(f) \ - if (!(f)) \ - FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f); - -/** Send "comment" string to the debugger for display. */ -#define SMTG_WARNING(comment) FDebugPrint ("%s(%d) : %s\n", __FILE__, __LINE__, comment); - -/** Send the last error string to the debugger for display. */ -#define SMTG_PRINTSYSERROR FPrintLastError (__FILE__, __LINE__); - -/** If a debugger is present, send string "s" to the debugger for display and - cause a breakpoint exception to occur in the current process. */ -#define SMTG_DEBUGSTR(s) FDebugBreak (s); - -/** Use VERIFY for calling methods "f" having a bool result (expecting them to return 'true') - The call of "f" is not removed in RELEASE builds, only the result verification. eg: SMTG_VERIFY - (isValid ()) */ -#define SMTG_VERIFY(f) SMTG_ASSERT (f) - -/** Use VERIFY_IS for calling methods "f" and expect a certain result "r". - The call of "f" is not removed in RELEASE builds, only the result verification. eg: - SMTG_VERIFY_IS (callMethod (), kResultOK) */ -#define SMTG_VERIFY_IS(f, r) \ - if ((f) != (r)) \ - FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f); - -/** Use VERIFY_NOT for calling methods "f" and expect the result to be anything else but "r". - The call of "f" is not removed in RELEASE builds, only the result verification. eg: - SMTG_VERIFY_NOT (callMethod (), kResultError) */ -#define SMTG_VERIFY_NOT(f, r) \ - if ((f) == (r)) \ - FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f); - -/** @name Shortcut macros for sending strings to the debugger for display. - First parameter is always the format string (printf like). -*/ - -///@{ -#define SMTG_DBPRT0(a) FDebugPrint (a); -#define SMTG_DBPRT1(a, b) FDebugPrint (a, b); -#define SMTG_DBPRT2(a, b, c) FDebugPrint (a, b, c); -#define SMTG_DBPRT3(a, b, c, d) FDebugPrint (a, b, c, d); -#define SMTG_DBPRT4(a, b, c, d, e) FDebugPrint (a, b, c, d, e); -#define SMTG_DBPRT5(a, b, c, d, e, f) FDebugPrint (a, b, c, d, e, f); -///@} - -/** @name Helper functions for the above defined macros. - - You shouldn't use them directly (if you do so, don't forget "#if DEVELOPMENT")! - It is recommended to use the macros instead. -*/ -///@{ -void FDebugPrint (const char* format, ...); -void FDebugBreak (const char* format, ...); -void FPrintLastError (const char* file, int line); -///@} - -/** @name Provide a custom assertion handler and debug print handler, eg - so that we can provide an assert with a custom dialog, or redirect - the debug output to a file or stream. -*/ -///@{ -using AssertionHandler = bool (*) (const char* message); -extern AssertionHandler gAssertionHandler; -extern AssertionHandler gPreAssertionHook; -using DebugPrintLogger = void (*) (const char* message); -extern DebugPrintLogger gDebugPrintLogger; -///@} - -/** Definition of memory allocation macros: - Use "NEW" to allocate storage for individual objects. - Use "NEWVEC" to allocate storage for an array of objects. */ -#if SMTG_OS_MACOS -void* operator new (size_t, int, const char*, int); -void* operator new[] (size_t, int, const char*, int); -void operator delete (void* p, int, const char* file, int line); -void operator delete[] (void* p, int, const char* file, int line); -#ifndef NEW -#define NEW new (1, __FILE__, __LINE__) -#define NEWVEC new (1, __FILE__, __LINE__) -#endif - -#define DEBUG_NEW DEBUG_NEW_LEAKS - -#elif SMTG_OS_WINDOWS && defined(_MSC_VER) -#ifndef NEW -void* operator new (size_t, int, const char*, int); -#define NEW new (1, __FILE__, __LINE__) -#define NEWVEC new (1, __FILE__, __LINE__) -#endif - -#else -#ifndef NEW -#define NEW new -#define NEWVEC new -#endif -#endif - -#else -/** if DEVELOPMENT is not set, these macros will do nothing. */ -#define SMTG_ASSERT(f) -#define SMTG_WARNING(s) -#define SMTG_PRINTSYSERROR -#define SMTG_DEBUGSTR(s) -#define SMTG_VERIFY(f) f; -#define SMTG_VERIFY_IS(f, r) f; -#define SMTG_VERIFY_NOT(f, r) f; - -#define SMTG_DBPRT0(a) -#define SMTG_DBPRT1(a, b) -#define SMTG_DBPRT2(a, b, c) -#define SMTG_DBPRT3(a, b, c, d) -#define SMTG_DBPRT4(a, b, c, d, e) -#define SMTG_DBPRT5(a, b, c, d, e, f) - -#ifndef NEW -#define NEW new -#define NEWVEC new - -#endif -#endif - -// replace #if SMTG_CPPUNIT_TESTING -bool isSmtgUnitTesting (); -void setSmtgUnitTesting (); - -#if !SMTG_RENAME_ASSERT -#if SMTG_OS_WINDOWS -#undef ASSERT -#endif - -#define ASSERT SMTG_ASSERT -#define WARNING SMTG_WARNING -#define DEBUGSTR SMTG_DEBUGSTR -#define VERIFY SMTG_VERIFY -#define VERIFY_IS SMTG_VERIFY_IS -#define VERIFY_NOT SMTG_VERIFY_NOT -#define PRINTSYSERROR SMTG_PRINTSYSERROR - -#define DBPRT0 SMTG_DBPRT0 -#define DBPRT1 SMTG_DBPRT1 -#define DBPRT2 SMTG_DBPRT2 -#define DBPRT3 SMTG_DBPRT3 -#define DBPRT4 SMTG_DBPRT4 -#define DBPRT5 SMTG_DBPRT5 -#endif diff --git a/source/includes/vst3sdk/base/source/fobject.cpp b/source/includes/vst3sdk/base/source/fobject.cpp deleted file mode 100644 index e085a3435..000000000 --- a/source/includes/vst3sdk/base/source/fobject.cpp +++ /dev/null @@ -1,184 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fobject.cpp -// Created by : Steinberg, 2008 -// Description : Basic Object implementing FUnknown -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "base/source/fobject.h" -#include "base/thread/include/flock.h" - -#include - -namespace Steinberg { - -IUpdateHandler* FObject::gUpdateHandler = nullptr; - -//------------------------------------------------------------------------ -const FUID FObject::iid; - -//------------------------------------------------------------------------ -struct FObjectIIDInitializer -{ - // the object iid is always generated so that different components - // only can cast to their own objects - // this initializer must be after the definition of FObject::iid, otherwise - // the default constructor of FUID will clear the generated iid - FObjectIIDInitializer () - { - const_cast (FObject::iid).generate (); - } -} gFObjectIidInitializer; - -//------------------------------------------------------------------------ -uint32 PLUGIN_API FObject::addRef () -{ - return FUnknownPrivate::atomicAdd (refCount, 1); -} - -//------------------------------------------------------------------------ -uint32 PLUGIN_API FObject::release () -{ - if (FUnknownPrivate::atomicAdd (refCount, -1) == 0) - { - refCount = -1000; - delete this; - return 0; - } - return refCount; -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API FObject::queryInterface (const TUID _iid, void** obj) -{ - QUERY_INTERFACE (_iid, obj, FUnknown::iid, FUnknown) - QUERY_INTERFACE (_iid, obj, IDependent::iid, IDependent) - QUERY_INTERFACE (_iid, obj, FObject::iid, FObject) - *obj = nullptr; - return kNoInterface; -} - -//------------------------------------------------------------------------ -void FObject::addDependent (IDependent* dep) -{ - if (gUpdateHandler) - gUpdateHandler->addDependent (unknownCast (), dep); -} - -//------------------------------------------------------------------------ -void FObject::removeDependent (IDependent* dep) -{ - if (gUpdateHandler) - gUpdateHandler->removeDependent (unknownCast (), dep); -} - -//------------------------------------------------------------------------ -void FObject::changed (int32 msg) -{ - if (gUpdateHandler) - gUpdateHandler->triggerUpdates (unknownCast (), msg); - else - updateDone (msg); -} - -//------------------------------------------------------------------------ -void FObject::deferUpdate (int32 msg) -{ - if (gUpdateHandler) - gUpdateHandler->deferUpdates (unknownCast (), msg); - else - updateDone (msg); -} - -//------------------------------------------------------------------------ -/** Automatic creation and destruction of singleton instances. */ -//------------------------------------------------------------------------ -namespace Singleton -{ - using ObjectVector = std::vector; - ObjectVector* singletonInstances = nullptr; - bool singletonsTerminated = false; - Steinberg::Base::Thread::FLock* singletonsLock; - - bool isTerminated () {return singletonsTerminated;} - - void lockRegister () - { - if (!singletonsLock) // assume first call not from multiple threads - singletonsLock = NEW Steinberg::Base::Thread::FLock; - singletonsLock->lock (); - } - void unlockRegister () - { - singletonsLock->unlock (); - } - - void registerInstance (FObject** o) - { - SMTG_ASSERT (singletonsTerminated == false) - if (singletonsTerminated == false) - { - if (singletonInstances == nullptr) - singletonInstances = NEW std::vector; - singletonInstances->push_back (o); - } - } - - struct Deleter - { - ~Deleter () - { - singletonsTerminated = true; - if (singletonInstances) - { - for (ObjectVector::iterator it = singletonInstances->begin (), - end = singletonInstances->end (); - it != end; ++it) - { - FObject** obj = (*it); - (*obj)->release (); - *obj = nullptr; - obj = nullptr; - } - - delete singletonInstances; - singletonInstances = nullptr; - } - delete singletonsLock; - singletonsLock = nullptr; - } - } deleter; -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fobject.h b/source/includes/vst3sdk/base/source/fobject.h deleted file mode 100644 index 9bcf4435c..000000000 --- a/source/includes/vst3sdk/base/source/fobject.h +++ /dev/null @@ -1,516 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fobject.h -// Created by : Steinberg, 2008 -// Description : Basic Object implementing FUnknown -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -//------------------------------------------------------------------------ -/** @file base/source/fobject.h - Basic Object implementing FUnknown. */ -//------------------------------------------------------------------------ -#pragma once - -#include "pluginterfaces/base/funknown.h" -#include "pluginterfaces/base/iupdatehandler.h" -#include "base/source/fdebug.h" // use of NEW - -namespace Steinberg { - -//---------------------------------- - -using FClassID = FIDString; - -//------------------------------------------------------------------------ -// Basic FObject - implements FUnknown + IDependent -//------------------------------------------------------------------------ -/** Implements FUnknown and IDependent. - -FObject is a polymorphic class that implements IDependent (of SKI module) and therefore derived from -FUnknown, which is the most abstract base class of all. - -All COM-like virtual methods of FUnknown such as queryInterface(), addRef(), release() are -implemented here. On top of that, dependency-related methods are implemented too. - -Pointer casting is done via the template methods FCast, either FObject to FObject or FUnknown to -FObject. - -FObject supports a new singleton concept, therefore these objects are deleted automatically upon -program termination. - -- Runtime type information: An object can be queried at runtime, of what class it is. To do this -correctly, every class must override some methods. This is simplified by using the OBJ_METHODS -macros - -@see - - FUnknown - - IDependent - - IUpdateHandler -*/ -//------------------------------------------------------------------------ -class FObject : public IDependent -{ -public: - //------------------------------------------------------------------------ - FObject () : refCount (1) {} ///< default constructor... - FObject (const FObject&) : refCount (1) {} ///< overloaded constructor... - virtual ~FObject () {} ///< destructor... - FObject& operator = (const FObject&) { return *this; } ///< overloads operator "=" as the reference assignment - - // OBJECT_METHODS - static inline FClassID getFClassID () {return "FObject";} ///< return Class ID as an ASCII string (statically) - virtual FClassID isA () const {return FObject::getFClassID ();} ///< a local alternative to getFClassID () - virtual bool isA (FClassID s) const {return isTypeOf (s, false);} ///< evaluates if the passed ID is of the FObject type - virtual bool isTypeOf (FClassID s, bool /*askBaseClass*/ = true) const {return classIDsEqual (s, FObject::getFClassID ());} - ///< evaluates if the passed ID is of the FObject type - int32 getRefCount () {return refCount;} ///< returns the current interface reference count - FUnknown* unknownCast () {return this;} ///< get FUnknown interface from object - - // FUnknown - tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE; ///< please refer to FUnknown::queryInterface () - uint32 PLUGIN_API addRef () SMTG_OVERRIDE; ///< please refer to FUnknown::addref () - uint32 PLUGIN_API release () SMTG_OVERRIDE; ///< please refer to FUnknown::release () - - // IDependent - void PLUGIN_API update (FUnknown* /*changedUnknown*/, int32 /*message*/) SMTG_OVERRIDE {} - ///< empty virtual method that should be overridden by derived classes for data updates upon changes - // IDependency - virtual void addDependent (IDependent* dep); ///< adds dependency to the object - virtual void removeDependent (IDependent* dep); ///< removes dependency from the object - virtual void changed (int32 msg = kChanged); ///< Inform all dependents, that the object has changed. - virtual void deferUpdate (int32 msg = kChanged); ///< Similar to triggerUpdates, except only delivered in idle (usefull in collecting updates). - virtual void updateDone (int32 /* msg */) {} ///< empty virtual method that should be overridden by derived classes - virtual bool isEqualInstance (FUnknown* d) {return this == d;} - - static void setUpdateHandler (IUpdateHandler* handler) {gUpdateHandler = handler;} ///< set method for the local attribute - static IUpdateHandler* getUpdateHandler () {return gUpdateHandler;} ///< get method for the local attribute - - // static helper functions - static inline bool classIDsEqual (FClassID ci1, FClassID ci2); ///< compares (evaluates) 2 class IDs - static inline FObject* unknownToObject (FUnknown* unknown); ///< pointer conversion from FUnknown to FObject - - /** Special UID that is used to cast an FUnknown pointer to a FObject */ - static const FUID iid; - -//------------------------------------------------------------------------ -protected: - int32 refCount; ///< COM-model local reference count - - static IUpdateHandler* gUpdateHandler; -}; - - -//------------------------------------------------------------------------ -// conversion from FUnknown to FObject -//------------------------------------------------------------------------ -inline FObject* FObject::unknownToObject (FUnknown* unknown) -{ - FObject* object = nullptr; - if (unknown) - { - unknown->queryInterface (FObject::iid, (void**)&object); - if (object) - object->release (); // queryInterface has added ref - } - return object; -} - -//------------------------------------------------------------------------ -inline bool FObject::classIDsEqual (FClassID ci1, FClassID ci2) -{ - return (ci1 && ci2) ? (strcmp (ci1, ci2) == 0) : false; -} - -//----------------------------------------------------------------------- -/** FCast overload 1 - FObject to FObject */ -//----------------------------------------------------------------------- -template -inline C* FCast (const FObject* object) -{ - if (object && object->isTypeOf (C::getFClassID (), true)) - return (C*) object; - return 0; -} - -//----------------------------------------------------------------------- -/** FCast overload 2 - FUnknown to FObject */ -//----------------------------------------------------------------------- -template -inline C* FCast (FUnknown* unknown) -{ - FObject* object = FObject::unknownToObject (unknown); - return FCast (object); -} - -//----------------------------------------------------------------------- -/** FUCast - casting from FUnknown to Interface */ -//----------------------------------------------------------------------- -template -inline C* FUCast (FObject* object) -{ - return FUnknownPtr (object ? object->unknownCast () : nullptr); -} - -template -inline C* FUCast (FUnknown* object) -{ - return FUnknownPtr (object); -} - -//------------------------------------------------------------------------ -/** @name Convenience methods that call release or delete respectively - on a pointer if it is non-zero, and then set the pointer to zero. - Note: you should prefer using IPtr or OPtr instead of these methods - whenever possible. - Examples: - @code - ~Foo () - { - // instead of ... - if (somePointer) - { - somePointer->release (); - somePointer = 0; - } - // ... just being lazy I write - SafeRelease (somePointer) - } - @endcode -*/ -///@{ -//----------------------------------------------------------------------- -template -inline void SafeRelease (I *& ptr) -{ - if (ptr) - { - ptr->release (); - ptr = 0; - } -} - -//----------------------------------------------------------------------- -template -inline void SafeRelease (IPtr & ptr) -{ - ptr = 0; -} - - -//----------------------------------------------------------------------- -template -inline void SafeDelete (T *& ptr) -{ - if (ptr) - { - delete ptr; - ptr = 0; - } -} -///@} - -//----------------------------------------------------------------------- -template -inline void AssignShared (T*& dest, T* newPtr) -{ - if (dest == newPtr) - return; - - if (dest) - dest->release (); - dest = newPtr; - if (dest) - dest->addRef (); -} - -//----------------------------------------------------------------------- -template -inline void AssignSharedDependent (IDependent* _this, T*& dest, T* newPtr) -{ - if (dest == newPtr) - return; - - if (dest) - dest->removeDependent (_this); - AssignShared (dest, newPtr); - if (dest) - dest->addDependent (_this); -} - -//----------------------------------------------------------------------- -template -inline void AssignSharedDependent (IDependent* _this, IPtr& dest, T* newPtr) -{ - if (dest == newPtr) - return; - - if (dest) - dest->removeDependent (_this); - dest = newPtr; - if (dest) - dest->addDependent (_this); -} - -//----------------------------------------------------------------------- -template -inline void SafeReleaseDependent (IDependent* _this, T*& dest) -{ - if (dest) - dest->removeDependent (_this); - SafeRelease (dest); -} - -//----------------------------------------------------------------------- -template -inline void SafeReleaseDependent (IDependent* _this, IPtr& dest) -{ - if (dest) - dest->removeDependent (_this); - SafeRelease (dest); -} - - -//------------------------------------------------------------------------ -/** Automatic creation and destruction of singleton instances. */ -namespace Singleton { - /** registers an instance (type FObject) */ - void registerInstance (FObject** o); - - /** Returns true when singleton instances were already released. */ - bool isTerminated (); - - /** lock and unlock the singleton registration for multi-threading safety */ - void lockRegister (); - void unlockRegister (); -} - -//------------------------------------------------------------------------ -} // namespace Steinberg - -//----------------------------------------------------------------------- -#define SINGLETON(ClassName) \ - static ClassName* instance (bool create = true) \ - { \ - static Steinberg::FObject* inst = nullptr; \ - if (inst == nullptr && create && Steinberg::Singleton::isTerminated () == false) \ - { \ - Steinberg::Singleton::lockRegister (); \ - if (inst == nullptr) \ - { \ - inst = NEW ClassName; \ - Steinberg::Singleton::registerInstance (&inst); \ - } \ - Steinberg::Singleton::unlockRegister (); \ - } \ - return (ClassName*)inst; \ - } - -//----------------------------------------------------------------------- -#define OBJ_METHODS(className, baseClass) \ - static inline Steinberg::FClassID getFClassID () {return (#className);} \ - virtual Steinberg::FClassID isA () const SMTG_OVERRIDE {return className::getFClassID ();} \ - virtual bool isA (Steinberg::FClassID s) const SMTG_OVERRIDE {return isTypeOf (s, false);} \ - virtual bool isTypeOf (Steinberg::FClassID s, bool askBaseClass = true) const SMTG_OVERRIDE \ - { return (classIDsEqual (s, #className) ? true : (askBaseClass ? baseClass::isTypeOf (s, true) : false)); } - -//------------------------------------------------------------------------ -/** Delegate refcount functions to BaseClass. - BaseClase must implement ref counting. -*/ -//------------------------------------------------------------------------ -#define REFCOUNT_METHODS(BaseClass) \ -virtual Steinberg::uint32 PLUGIN_API addRef ()SMTG_OVERRIDE{ return BaseClass::addRef (); } \ -virtual Steinberg::uint32 PLUGIN_API release ()SMTG_OVERRIDE{ return BaseClass::release (); } - -//------------------------------------------------------------------------ -/** @name Macros to implement FUnknown::queryInterface (). - - Examples: - @code - class Foo : public FObject, public IFoo2, public IFoo3 - { - ... - DEFINE_INTERFACES - DEF_INTERFACE (IFoo2) - DEF_INTERFACE (IFoo3) - END_DEFINE_INTERFACES (FObject) - REFCOUNT_METHODS(FObject) - // Implement IFoo2 interface ... - // Implement IFoo3 interface ... - ... - }; - @endcode -*/ -///@{ -//------------------------------------------------------------------------ -/** Start defining interfaces. */ -//------------------------------------------------------------------------ -#define DEFINE_INTERFACES \ -Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) SMTG_OVERRIDE \ -{ - -//------------------------------------------------------------------------ -/** Add a interfaces. */ -//------------------------------------------------------------------------ -#define DEF_INTERFACE(InterfaceName) \ - QUERY_INTERFACE (iid, obj, InterfaceName::iid, InterfaceName) - -//------------------------------------------------------------------------ -/** End defining interfaces. */ -//------------------------------------------------------------------------ -#define END_DEFINE_INTERFACES(BaseClass) \ - return BaseClass::queryInterface (iid, obj); \ -} -///@} - -//------------------------------------------------------------------------ -/** @name Convenient macros to implement Steinberg::FUnknown::queryInterface (). - Examples: - @code - class Foo : public FObject, public IFoo2, public IFoo3 - { - ... - DEF_INTERFACES_2(IFoo2,IFoo3,FObject) - REFCOUNT_METHODS(FObject) - ... - }; - @endcode -*/ -///@{ -//------------------------------------------------------------------------ -#define DEF_INTERFACES_1(InterfaceName,BaseClass) \ -DEFINE_INTERFACES \ -DEF_INTERFACE (InterfaceName) \ -END_DEFINE_INTERFACES (BaseClass) - -//------------------------------------------------------------------------ -#define DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \ -DEFINE_INTERFACES \ -DEF_INTERFACE (InterfaceName1) \ -DEF_INTERFACE (InterfaceName2) \ -END_DEFINE_INTERFACES (BaseClass) - -//------------------------------------------------------------------------ -#define DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \ -DEFINE_INTERFACES \ -DEF_INTERFACE (InterfaceName1) \ -DEF_INTERFACE (InterfaceName2) \ -DEF_INTERFACE (InterfaceName3) \ -END_DEFINE_INTERFACES (BaseClass) - -//------------------------------------------------------------------------ -#define DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \ - DEFINE_INTERFACES \ - DEF_INTERFACE (InterfaceName1) \ - DEF_INTERFACE (InterfaceName2) \ - DEF_INTERFACE (InterfaceName3) \ - DEF_INTERFACE (InterfaceName4) \ - END_DEFINE_INTERFACES (BaseClass) -///@} - -//------------------------------------------------------------------------ -/** @name Convenient macros to implement Steinberg::FUnknown methods. - Examples: - @code - class Foo : public FObject, public IFoo2, public IFoo3 - { - ... - FUNKNOWN_METHODS2(IFoo2,IFoo3,FObject) - ... - }; - @endcode -*/ -///@{ -#define FUNKNOWN_METHODS(InterfaceName,BaseClass) \ -DEF_INTERFACES_1(InterfaceName,BaseClass) \ -REFCOUNT_METHODS(BaseClass) - -#define FUNKNOWN_METHODS2(InterfaceName1,InterfaceName2,BaseClass) \ -DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \ -REFCOUNT_METHODS(BaseClass) - -#define FUNKNOWN_METHODS3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \ -DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \ -REFCOUNT_METHODS(BaseClass) - -#define FUNKNOWN_METHODS4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \ -DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \ -REFCOUNT_METHODS(BaseClass) -///@} - - -//------------------------------------------------------------------------ -//------------------------------------------------------------------------ -#if COM_COMPATIBLE -//------------------------------------------------------------------------ -/** @name Macros to implement IUnknown interfaces with FObject. - Examples: - @code - class MyEnumFormat : public FObject, IEnumFORMATETC - { - ... - COM_UNKNOWN_METHODS (IEnumFORMATETC, IUnknown) - ... - }; - @endcode -*/ -///@{ -//------------------------------------------------------------------------ -#define IUNKNOWN_REFCOUNT_METHODS(BaseClass) \ -STDMETHOD_ (ULONG, AddRef) (void) {return BaseClass::addRef ();} \ -STDMETHOD_ (ULONG, Release) (void) {return BaseClass::release ();} - -//------------------------------------------------------------------------ -#define COM_QUERY_INTERFACE(iid, obj, InterfaceName) \ -if (riid == __uuidof(InterfaceName)) \ -{ \ - addRef (); \ - *obj = (InterfaceName*)this; \ - return kResultOk; \ -} - -//------------------------------------------------------------------------ -#define COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \ -STDMETHOD (QueryInterface) (REFIID riid, void** object) \ -{ \ - COM_QUERY_INTERFACE (riid, object, InterfaceName) \ - return BaseClass::queryInterface ((FIDString)&riid, object); \ -} - -//------------------------------------------------------------------------ -#define COM_UNKNOWN_METHODS(InterfaceName,BaseClass) \ -COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \ -IUNKNOWN_REFCOUNT_METHODS(BaseClass) -///@} - -#endif // COM_COMPATIBLE diff --git a/source/includes/vst3sdk/base/source/fstreamer.cpp b/source/includes/vst3sdk/base/source/fstreamer.cpp deleted file mode 100644 index b9af91e08..000000000 --- a/source/includes/vst3sdk/base/source/fstreamer.cpp +++ /dev/null @@ -1,726 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fstreamer.cpp -// Created by : Steinberg, 15.12.2005 -// Description : Extract of typed stream i/o methods from FStream -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "fstreamer.h" - -#include "base/source/fstring.h" -#include "base/source/fbuffer.h" -#include "pluginterfaces/base/ibstream.h" - -#ifndef UNICODE -#include "pluginterfaces/base/futils.h" -#endif - -namespace Steinberg { - -//------------------------------------------------------------------------ -// IBStreamer -//------------------------------------------------------------------------ -IBStreamer::IBStreamer (IBStream* stream, int16 _byteOrder) -: FStreamer (_byteOrder) -, stream (stream) -{} - -//------------------------------------------------------------------------ -TSize IBStreamer::readRaw (void* buffer, TSize size) -{ - int32 numBytesRead = 0; - stream->read (buffer, (int32)size, &numBytesRead); - return numBytesRead; -} - -//------------------------------------------------------------------------ -TSize IBStreamer::writeRaw (const void* buffer, TSize size) -{ - int32 numBytesWritten = 0; - stream->write ((void*)buffer, (int32)size, &numBytesWritten); - return numBytesWritten; -} - -//------------------------------------------------------------------------ -int64 IBStreamer::seek (int64 pos, FSeekMode mode) -{ - int64 result = -1; - stream->seek (pos, mode, &result); - return result; -} - -//------------------------------------------------------------------------ -int64 IBStreamer::tell () -{ - int64 pos = 0; - stream->tell (&pos); - return pos; -} - -//------------------------------------------------------------------------ -// FStreamSizeHolder Implementation -//------------------------------------------------------------------------ -FStreamSizeHolder::FStreamSizeHolder (FStreamer &s) -: stream (s), sizePos (-1) -{} - -//------------------------------------------------------------------------ -void FStreamSizeHolder::beginWrite () -{ - sizePos = stream.tell (); - stream.writeInt32 (0L); -} - -//------------------------------------------------------------------------ -int32 FStreamSizeHolder::endWrite () -{ - if (sizePos < 0) - return 0; - - int64 currentPos = stream.tell (); - - stream.seek (sizePos, kSeekSet); - int32 size = int32 (currentPos - sizePos - sizeof (int32)); - stream.writeInt32 (size); - - stream.seek (currentPos, kSeekSet); - return size; -} - -//------------------------------------------------------------------------ -int32 FStreamSizeHolder::beginRead () -{ - sizePos = stream.tell (); - int32 size = 0; - stream.readInt32 (size); - sizePos += size + sizeof (int32); - return size; -} - -//------------------------------------------------------------------------ -void FStreamSizeHolder::endRead () -{ - if (sizePos >= 0) - stream.seek (sizePos, kSeekSet); -} - -//------------------------------------------------------------------------ -// FStreamer -//------------------------------------------------------------------------ -FStreamer::FStreamer (int16 _byteOrder) -: byteOrder (_byteOrder) -{} - -// int8 / char ----------------------------------------------------------- -//------------------------------------------------------------------------ -bool FStreamer::writeChar8 (char8 c) -{ - return writeRaw ((void*)&c, sizeof (char8)) == sizeof (char8); -} - -//------------------------------------------------------------------------ -bool FStreamer::readChar8 (char8& c) -{ - return readRaw ((void*)&c, sizeof (char8)) == sizeof (char8); -} - -//------------------------------------------------------------------------ -bool FStreamer::writeUChar8 (unsigned char c) -{ - return writeRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char); -} - -//------------------------------------------------------------------------ -bool FStreamer::readUChar8 (unsigned char& c) -{ - return readRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char); -} - -//------------------------------------------------------------------------ -bool FStreamer::writeChar16 (char16 c) -{ - if (BYTEORDER != byteOrder) - SWAP_16 (c); - return writeRaw ((void*)&c, sizeof (char16)) == sizeof (char16); -} - -//------------------------------------------------------------------------ -bool FStreamer::readChar16 (char16& c) -{ - if (readRaw ((void*)&c, sizeof (char16)) == sizeof (char16)) - { - if (BYTEORDER != byteOrder) - SWAP_16 (c); - return true; - } - c = 0; - return false; -} - -// int16 ----------------------------------------------------------------- -//------------------------------------------------------------------------ -bool FStreamer::writeInt16 (int16 i) -{ - if (BYTEORDER != byteOrder) - SWAP_16 (i); - return writeRaw ((void*)&i, sizeof (int16)) == sizeof (int16); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt16 (int16& i) -{ - if (readRaw ((void*)&i, sizeof (int16)) == sizeof (int16)) - { - if (BYTEORDER != byteOrder) - SWAP_16 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt16Array (const int16* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt16 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt16Array (int16* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt16 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt16u (uint16 i) -{ - if (BYTEORDER != byteOrder) - SWAP_16 (i); - return writeRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt16u (uint16& i) -{ - if (readRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16)) - { - if (BYTEORDER != byteOrder) - SWAP_16 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt16uArray (const uint16* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt16u (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt16uArray (uint16* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt16u (array[i])) - return false; - } - return true; -} - -// int32 ----------------------------------------------------------------- -//------------------------------------------------------------------------ -bool FStreamer::writeInt32 (int32 i) -{ - if (BYTEORDER != byteOrder) - SWAP_32 (i); - return writeRaw ((void*)&i, sizeof (int32)) == sizeof (int32); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt32 (int32& i) -{ - if (readRaw ((void*)&i, sizeof (int32)) == sizeof (int32)) - { - if (BYTEORDER != byteOrder) - SWAP_32 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt32Array (const int32* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt32 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt32Array (int32* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt32 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt32u (uint32 i) -{ - if (BYTEORDER != byteOrder) - SWAP_32 (i); - return writeRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt32u (uint32& i) -{ - if (readRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32)) - { - if (BYTEORDER != byteOrder) - SWAP_32 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt32uArray (const uint32* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt32u (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt32uArray (uint32* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt32u (array[i])) - return false; - } - return true; -} - -// int64 ----------------------------------------------------------------- -//------------------------------------------------------------------------ -bool FStreamer::writeInt64 (int64 i) -{ - if (BYTEORDER != byteOrder) - SWAP_64 (i); - return writeRaw ((void*)&i, sizeof (int64)) == sizeof (int64); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt64 (int64& i) -{ - if (readRaw ((void*)&i, sizeof (int64)) == sizeof (int64)) - { - if (BYTEORDER != byteOrder) - SWAP_64 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt64Array (const int64* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt64 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt64Array (int64* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt64 (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt64u (uint64 i) -{ - if (BYTEORDER != byteOrder) - SWAP_64 (i); - return writeRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64); -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt64u (uint64& i) -{ - if (readRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64)) - { - if (BYTEORDER != byteOrder) - SWAP_64 (i); - return true; - } - i = 0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeInt64uArray (const uint64* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeInt64u (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readInt64uArray (uint64* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readInt64u (array[i])) - return false; - } - return true; -} - -// float / double -------------------------------------------------------- -//------------------------------------------------------------------------ -bool FStreamer::writeFloat (float f) -{ - if (BYTEORDER != byteOrder) - SWAP_32 (f); - return writeRaw ((void*)&f, sizeof (float)) == sizeof (float); -} - -//------------------------------------------------------------------------ -bool FStreamer::readFloat (float& f) -{ - if (readRaw ((void*)&f, sizeof (float)) == sizeof (float)) - { - if (BYTEORDER != byteOrder) - SWAP_32 (f); - return true; - } - f = 0.f; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeFloatArray (const float* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeFloat (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readFloatArray (float* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readFloat (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeDouble (double d) -{ - if (BYTEORDER != byteOrder) - SWAP_64 (d); - return writeRaw ((void*)&d, sizeof (double)) == sizeof (double); -} - -//------------------------------------------------------------------------ -bool FStreamer::readDouble (double& d) -{ - if (readRaw ((void*)&d, sizeof (double)) == sizeof (double)) - { - if (BYTEORDER != byteOrder) - SWAP_64 (d); - return true; - } - d = 0.0; - return false; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeDoubleArray (const double* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!writeDouble (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readDoubleArray (double* array, int32 count) -{ - for (int32 i = 0; i < count; i++) - { - if (!readDouble (array[i])) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::readBool (bool& b) -{ - int16 v = 0; - bool res = readInt16 (v); - b = (v != 0); - return res; -} - -//------------------------------------------------------------------------ -bool FStreamer::writeBool (bool b) -{ - return writeInt16 ((int16)b); -} - -//------------------------------------------------------------------------ -TSize FStreamer::writeString8 (const char8* ptr, bool terminate) -{ - TSize size = strlen (ptr); - if (terminate) // write \0 - size++; - - return writeRaw ((void*)ptr, size); -} - -//------------------------------------------------------------------------ -TSize FStreamer::readString8 (char8* ptr, TSize size) -{ - TSize i = 0; - char8 c = 0; - while (i < size) - { - if (readRaw ((void*)&c, sizeof (char)) != sizeof (char)) - break; - ptr[i] = c; - i++; - if (c == '\n' || c == '\0') - break; - } - if (c == '\n' && ptr[i - 2] == '\r') - ptr[i - 2] = 0; - if (i < size) - ptr[i] = 0; - else - ptr[size - 1] = 0; - - return strlen (ptr); -} - -//------------------------------------------------------------------------ -bool FStreamer::writeStringUtf8 (const tchar* ptr) -{ - bool isUtf8 = false; - - String str (ptr); - if (str.isAsciiString () == false) - { - str.toMultiByte (kCP_Utf8); - isUtf8 = true; - } - else - { - str.toMultiByte (); - } - - if (isUtf8) - if (writeRaw (kBomUtf8, kBomUtf8Length) != kBomUtf8Length) - return false; - - TSize size = str.length () + 1; - if (writeRaw (str.text8 (), size) != size) - return false; - - return true; -} - -//------------------------------------------------------------------------ -int32 FStreamer::readStringUtf8 (tchar* ptr, int32 nChars) -{ - char8 c = 0; - - ptr [0] = 0; - - Buffer tmp; - tmp.setDelta (1024); - - while (true) - { - if (readRaw ((void*)&c, sizeof (char)) != sizeof (char)) - break; - tmp.put (c); - if (c == '\0') - break; - } - - char8* source = tmp.int8Ptr (); - uint32 codePage = kCP_Default; // for legacy take default page if no utf8 bom is present... - if (tmp.getFillSize () > 2) - { - if (memcmp (source, kBomUtf8, kBomUtf8Length) == 0) - { - codePage = kCP_Utf8; - source += 3; - } - } - - if (tmp.getFillSize () > 1) - { -#ifdef UNICODE - ConstString::multiByteToWideString (ptr, source, nChars, codePage); -#else - if (codePage == kCP_Utf8) - { - Buffer wideBuffer (tmp.getFillSize () * 3); - ConstString::multiByteToWideString (wideBuffer.wcharPtr (), source, wideBuffer.getSize () / 2, kCP_Utf8); - ConstString::wideStringToMultiByte (ptr, wideBuffer.wcharPtr (), nChars); - } - else - { - memcpy (ptr, source, Min (nChars, tmp.getFillSize ())); - } -#endif - } - - ptr[nChars - 1] = 0; - return ConstString (ptr).length (); -} - -//------------------------------------------------------------------------ -bool FStreamer::writeStr8 (const char8* s) -{ - int32 length = (s) ? (int32) strlen (s) + 1 : 0; - if (!writeInt32 (length)) - return false; - - if (length > 0) - return writeRaw (s, sizeof (char8) * length) == static_cast(sizeof (char8) * length); - - return true; -} - -//------------------------------------------------------------------------ -int32 FStreamer::getStr8Size (const char8* s) -{ - return sizeof (int32) + (int32)strlen (s) + 1; -} - -//------------------------------------------------------------------------ -char8* FStreamer::readStr8 () -{ - int32 length; - if (!readInt32 (length)) - return nullptr; - - // check corruption - if (length > 262144) - return nullptr; - - char8* s = (length > 0) ? NEWVEC char8[length] : nullptr; - if (s) - readRaw (s, length * sizeof (char8)); - return s; -} - -//------------------------------------------------------------------------ -bool FStreamer::skip (uint32 bytes) -{ - int8 tmp; - while (bytes-- > 0) - { - if (readInt8 (tmp) == false) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -bool FStreamer::pad (uint32 bytes) -{ - while (bytes-- > 0) - { - if (writeInt8 (0) == false) - return false; - } - return true; -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fstreamer.h b/source/includes/vst3sdk/base/source/fstreamer.h deleted file mode 100644 index 750e5e183..000000000 --- a/source/includes/vst3sdk/base/source/fstreamer.h +++ /dev/null @@ -1,242 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fstreamer.h -// Created by : Steinberg, 12/2005 -// Description : Extract of typed stream i/o methods from FStream -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/funknown.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -enum FSeekMode -{ - kSeekSet, - kSeekCurrent, - kSeekEnd -}; - -//------------------------------------------------------------------------ -// FStreamer -//------------------------------------------------------------------------ -/** Byteorder-aware base class for typed stream i/o. */ -//------------------------------------------------------------------------ -class FStreamer -{ -public: -//------------------------------------------------------------------------ - FStreamer (int16 byteOrder = BYTEORDER); - virtual ~FStreamer () {} - - /** @name Implementing class must override. */ - ///@{ - virtual TSize readRaw (void*, TSize) = 0; ///< Read one buffer of size. - virtual TSize writeRaw (const void*, TSize) = 0; ///< Write one buffer of size. - virtual int64 seek (int64, FSeekMode) = 0; ///< Set file position for stream. - virtual int64 tell () = 0; ///< Return current file position. - ///@} - - /** @name Streams are byteOrder aware. */ - ///@{ - inline void setByteOrder (int32 e) { byteOrder = (int16)e; } - inline int32 getByteOrder () const { return byteOrder; } - ///@} - - /** @name read and write int8 and char. */ - ///@{ - bool writeChar8 (char8); - bool readChar8 (char8&); - bool writeUChar8 (unsigned char); - bool readUChar8 (unsigned char&); - bool writeChar16 (char16 c); - bool readChar16 (char16& c); - - bool writeInt8 (int8 c){return writeChar8 (c);} - bool readInt8 (int8& c){return readChar8 (c);} - bool writeInt8u (uint8 c){return writeUChar8 (c);} - bool readInt8u (uint8& c){return readUChar8 (c);} - ///@} - - /** @name read and write int16. */ - ///@{ - bool writeInt16 (int16); - bool readInt16 (int16&); - bool writeInt16Array (const int16* array, int32 count); - bool readInt16Array (int16* array, int32 count); - bool writeInt16u (uint16); - bool readInt16u (uint16&); - bool writeInt16uArray (const uint16* array, int32 count); - bool readInt16uArray (uint16* array, int32 count); - ///@} - - /** @name read and write int32. */ - ///@{ - bool writeInt32 (int32); - bool readInt32 (int32&); - bool writeInt32Array (const int32* array, int32 count); - bool readInt32Array (int32* array, int32 count); - bool writeInt32u (uint32); - bool readInt32u (uint32&); - bool writeInt32uArray (const uint32* array, int32 count); - bool readInt32uArray (uint32* array, int32 count); - ///@} - - /** @name read and write int64. */ - ///@{ - bool writeInt64 (int64); - bool readInt64 (int64&); - bool writeInt64Array (const int64* array, int32 count); - bool readInt64Array (int64* array, int32 count); - bool writeInt64u (uint64); - bool readInt64u (uint64&); - bool writeInt64uArray (const uint64* array, int32 count); - bool readInt64uArray (uint64* array, int32 count); - ///@} - - /** @name read and write float and float array. */ - ///@{ - bool writeFloat (float); - bool readFloat (float&); - bool writeFloatArray (const float* array, int32 count); - bool readFloatArray (float* array, int32 count); - ///@} - - /** @name read and write double and double array. */ - ///@{ - bool writeDouble (double); - bool readDouble (double&); - bool writeDoubleArray (const double* array, int32 count); - bool readDoubleArray (double* array, int32 count); - ///@} - - /** @name read and write Boolean. */ - ///@{ - bool writeBool (bool); ///< Write one boolean - bool readBool (bool&); ///< Read one bool. - ///@} - - /** @name read and write Strings. */ - ///@{ - TSize writeString8 (const char8* ptr, bool terminate = false); ///< a direct output function writing only one string (ascii 8bit) - TSize readString8 (char8* ptr, TSize size); ///< a direct input function reading only one string (ascii) (ended by a \n or \0 or eof) - - bool writeStr8 (const char8* ptr); ///< write a string length (strlen) and string itself - char8* readStr8 (); ///< read a string length and string text (The return string must be deleted when use is finished) - - static int32 getStr8Size (const char8* ptr); ///< returns the size of a saved string - - bool writeStringUtf8 (const tchar* ptr); ///< always terminated, converts to utf8 if non ascii characters are in string - int32 readStringUtf8 (tchar* ptr, int32 maxSize); ///< read a UTF8 string - ///@} - - bool skip (uint32 bytes); - bool pad (uint32 bytes); - - -//------------------------------------------------------------------------ -protected: - int16 byteOrder; -}; - - -//------------------------------------------------------------------------ -/** FStreamSizeHolder Declaration - remembers size of stream chunk for backward compatibility. - - Example: - @code - externalize (a) - { - FStreamSizeHolder sizeHolder; - sizeHolder.beginWrite (); // sets start mark, writes dummy size - a << .... - sizeHolder.endWrite (); // jumps to start mark, updates size, jumps back here - } - - internalize (a) - { - FStreamSizeHolder sizeHolder; - sizeHolder.beginRead (); // reads size, mark - a >> .... - sizeHolder.endRead (); // jumps forward if new version has larger size - } - @endcode -*/ -//------------------------------------------------------------------------ -class FStreamSizeHolder -{ -public: - FStreamSizeHolder (FStreamer &s); - - void beginWrite (); ///< remembers position and writes 0 - int32 endWrite (); ///< writes and returns size (since the start marker) - int32 beginRead (); ///< returns size - void endRead (); ///< jump to end of chunk - -protected: - FStreamer &stream; - int64 sizePos; -}; - -class IBStream; - -//------------------------------------------------------------------------ -// IBStreamer -//------------------------------------------------------------------------ -/** Wrapper class for typed reading/writing from or to IBStream. - Can be used framework-independent in plug-ins. */ -//------------------------------------------------------------------------ -class IBStreamer: public FStreamer -{ -public: -//------------------------------------------------------------------------ - /** Constructor for a given IBSTream and a byteOrder. */ - IBStreamer (IBStream* stream, int16 byteOrder = BYTEORDER); - - IBStream* getStream () { return stream; } ///< Returns the associated IBStream. - - // FStreamer overrides: - TSize readRaw (void*, TSize) SMTG_OVERRIDE; ///< Read one buffer of size. - TSize writeRaw (const void*, TSize) SMTG_OVERRIDE; ///< Write one buffer of size. - int64 seek (int64, FSeekMode) SMTG_OVERRIDE; ///< Set file position for stream. - int64 tell () SMTG_OVERRIDE; ///< Return current file position. -//------------------------------------------------------------------------ -protected: - IBStream* stream; -}; - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fstring.cpp b/source/includes/vst3sdk/base/source/fstring.cpp deleted file mode 100644 index 7fae6b0c8..000000000 --- a/source/includes/vst3sdk/base/source/fstring.cpp +++ /dev/null @@ -1,3991 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fstring.cpp -// Created by : Steinberg, 2008 -// Description : String class -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "base/source/fstring.h" -#include "base/source/fdebug.h" -#include "pluginterfaces/base/futils.h" -#include "pluginterfaces/base/fvariant.h" - -#include -#include -#include -#include -#include - -#if SMTG_OS_WINDOWS -#include -#ifdef _MSC_VER -#pragma warning (disable : 4244) -#pragma warning (disable : 4267) -#pragma warning (disable : 4996) - -#if DEVELOPMENT -#include - -#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define realloc(p,s) _realloc_dbg(p,s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define free(p) _free_dbg(p, _NORMAL_BLOCK) - -#endif // DEVELOPMENT -#endif // _MSC_VER -#endif // SMTG_OS_WINDOWS - -#ifndef kPrintfBufferSize -#define kPrintfBufferSize 4096 -#endif - -#if SMTG_OS_MACOS -#include -#include -#include -#include - -#if defined (__GNUC__) && (__GNUC__ >= 4) && !__LP64__ -// on 32 bit Mac OS X we can safely ignore the format warnings as sizeof(int) == sizeof(long) -#pragma GCC diagnostic ignored "-Wformat" -#endif - -#define SMTG_ENABLE_DEBUG_CFALLOCATOR 0 -#define SMTG_DEBUG_CFALLOCATOR (DEVELOPMENT && SMTG_ENABLE_DEBUG_CFALLOCATOR) - -#if SMTG_DEBUG_CFALLOCATOR -#include -#include -#endif - -namespace Steinberg { -#if SMTG_DEBUG_CFALLOCATOR -static CFAllocatorRef kCFAllocator = NULL; - -struct CFStringDebugAllocator : CFAllocatorContext -{ - CFStringDebugAllocator () - { - version = 0; - info = this; - retain = nullptr; - release = nullptr; - copyDescription = nullptr; - allocate = allocateCallBack; - reallocate = reallocateCallBack; - deallocate = deallocateCallBack; - preferredSize = preferredSizeCallBack; - - numAllocations = allocationSize = numDeallocations = 0; - cfAllocator = CFAllocatorCreate (kCFAllocatorUseContext, this); - - Dl_info info; - if (dladdr ((const void*)CFStringDebugAllocator::allocateCallBack, &info)) - { - moduleName = info.dli_fname; - } - kCFAllocator = cfAllocator; - } - - ~CFStringDebugAllocator () - { - kCFAllocator = kCFAllocatorDefault; - CFRelease (cfAllocator); - FDebugPrint ("CFStringDebugAllocator (%s):\n", moduleName.text8 ()); - FDebugPrint ("\tNumber of allocations : %u\n", numAllocations); - FDebugPrint ("\tNumber of deallocations: %u\n", numDeallocations); - FDebugPrint ("\tAllocated Bytes : %u\n", allocationSize); - } - - String moduleName; - CFAllocatorRef cfAllocator; - volatile int64_t numAllocations; - volatile int64_t numDeallocations; - volatile int64_t allocationSize; - - void* doAllocate (CFIndex allocSize, CFOptionFlags hint) - { - void* ptr = CFAllocatorAllocate (kCFAllocatorDefault, allocSize, hint); - OSAtomicIncrement64 (&numAllocations); - OSAtomicAdd64 (allocSize, &allocationSize); - return ptr; - } - void* doReallocate (void* ptr, CFIndex newsize, CFOptionFlags hint) - { - void* newPtr = CFAllocatorReallocate (kCFAllocatorDefault, ptr, newsize, hint); - return newPtr; - } - void doDeallocate (void* ptr) - { - CFAllocatorDeallocate (kCFAllocatorDefault, ptr); - OSAtomicIncrement64 (&numDeallocations); - } - CFIndex getPreferredSize (CFIndex size, CFOptionFlags hint) - { - return CFAllocatorGetPreferredSizeForSize (kCFAllocatorDefault, size, hint); - } - - static void* allocateCallBack (CFIndex allocSize, CFOptionFlags hint, void* info) - { - return static_cast (info)->doAllocate (allocSize, hint); - } - static void* reallocateCallBack (void* ptr, CFIndex newsize, CFOptionFlags hint, void* info) - { - return static_cast (info)->doReallocate (ptr, newsize, hint); - } - - static void deallocateCallBack (void* ptr, void* info) - { - static_cast (info)->doDeallocate (ptr); - } - static CFIndex preferredSizeCallBack (CFIndex size, CFOptionFlags hint, void* info) - { - return static_cast (info)->getPreferredSize (size, hint); - } -}; -static CFStringDebugAllocator gDebugAllocator; -#else - -static const CFAllocatorRef kCFAllocator = ::kCFAllocatorDefault; -#endif // SMTG_DEBUG_CFALLOCATOR -} - -//----------------------------------------------------------------------------- -static void* toCFStringRef (const Steinberg::char8* source, Steinberg::uint32 encoding) -{ - if (encoding == 0xFFFF) - encoding = kCFStringEncodingASCII; - if (source) - return (void*)CFStringCreateWithCString (Steinberg::kCFAllocator, source, encoding); - else - return (void*)CFStringCreateWithCString (Steinberg::kCFAllocator, "", encoding); -} - -//----------------------------------------------------------------------------- -static bool fromCFStringRef (Steinberg::char8* dest, Steinberg::int32 destSize, const void* cfStr, Steinberg::uint32 encoding) -{ - CFIndex usedBytes; - CFRange range = {0, CFStringGetLength ((CFStringRef)cfStr)}; - bool result = CFStringGetBytes ((CFStringRef)cfStr, range, encoding, '?', false, (UInt8*)dest, destSize, &usedBytes); - dest[usedBytes] = 0; - return result; -} -#endif // SMTG_OS_MACOS - -#if SMTG_OS_WINDOWS -#define stricmp16 wcsicmp -#define strnicmp16 wcsnicmp -#define strrchr16 wcsrchr -#define sprintf16 swprintf -#define snprintf16 snwprintf -#define vsnprintf16 vsnwprintf -#define vsprintf16 wvsprintf -#define vfprintf16 vfwprintf -#define sscanf16 swscanf -#define toupper16 towupper -#define tolower16 towlower -#define isupper16 iswupper -#define islower16 iswlower -#define isspace16 iswspace -#define isalpha16 iswalpha -#define isdigit16 iswdigit -#define isalnum16 iswalnum - -#define stricmp _stricmp -#define strnicmp _strnicmp -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define snwprintf _snwprintf -#define vsnwprintf _vsnwprintf - -#define wtoi _wtoi -#define wtol _wtol -#define wtof _wtof - -#elif SMTG_OS_LINUX -#include -#include -#include -#include -#include -#include -#include - -using ConverterFacet = std::codecvt_utf8_utf16; -using Converter = std::wstring_convert; - -//------------------------------------------------------------------------ -static ConverterFacet& converterFacet () -{ - static ConverterFacet gFacet; - return gFacet; -} - -//------------------------------------------------------------------------ -static Converter& converter () -{ - static Converter gConverter; - return gConverter; -} - -//----------------------------------------------------------------------------- -static inline int stricasecmp (const Steinberg::char8* s1, const Steinberg::char8* s2) -{ - return ::strcasecmp (s1, s2); -} - -//----------------------------------------------------------------------------- -static inline int strnicasecmp (const Steinberg::char8* s1, const Steinberg::char8* s2, size_t n) -{ - return ::strncasecmp (s1, s2, n); -} - -//----------------------------------------------------------------------------- -static inline int stricmp16 (const Steinberg::char16* s1, const Steinberg::char16* s2) -{ - auto str1 = converter ().to_bytes (s1); - auto str2 = converter ().to_bytes (s2); - return stricasecmp (str1.data (), str2.data ()); -} - -//----------------------------------------------------------------------------- -static inline int strnicmp16 (const Steinberg::char16* s1, const Steinberg::char16* s2, int n) -{ - auto str1 = converter ().to_bytes (s1); - auto str2 = converter ().to_bytes (s2); - return strnicasecmp (str1.data (), str2.data (), n); -} - -//----------------------------------------------------------------------------- -static inline int sprintf16 (Steinberg::char16* wcs, const Steinberg::char16* format, ...) -{ - assert(false && "DEPRECATED No Linux implementation"); - return 0; -} - -//----------------------------------------------------------------------------- -static inline int vsnwprintf (Steinberg::char16* wcs, size_t maxlen, - const Steinberg::char16* format, va_list args) -{ - Steinberg::char8 str8[kPrintfBufferSize]; - auto format_utf8 = converter ().to_bytes(format); - auto len = vsnprintf (str8, kPrintfBufferSize, format_utf8.data (), args); - - auto tmp_str = converter ().from_bytes (str8, str8 + len); - auto target_len = std::min (tmp_str.size (), maxlen - 1); - tmp_str.copy (wcs, target_len); - wcs[target_len] = '\0'; - - return tmp_str.size (); -} - -//----------------------------------------------------------------------------- -static inline Steinberg::char16* strrchr16 (const Steinberg::char16* str, Steinberg::char16 c) -{ - assert(false && "DEPRECATED No Linux implementation"); - return nullptr; -} - -#elif SMTG_OS_MACOS -#define tstrtoi64 strtoll -#define stricmp strcasecmp -#define strnicmp strncasecmp - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 strnicmp16 (const Steinberg::char16* str1, const Steinberg::char16* str2, size_t size) -{ - if (size == 0) - return 0; - - CFIndex str1Len = Steinberg::strlen16 (str1); - CFIndex str2Len = Steinberg::strlen16 (str2); - if (static_cast (size) < str2Len) // range is not applied to second string - str2Len = size; - CFStringRef cfStr1 = CFStringCreateWithCharactersNoCopy (Steinberg::kCFAllocator, (UniChar*)str1, str1Len, kCFAllocatorNull); - CFStringRef cfStr2 = CFStringCreateWithCharactersNoCopy (Steinberg::kCFAllocator, (UniChar*)str2, str2Len, kCFAllocatorNull); - CFComparisonResult result = CFStringCompareWithOptions (cfStr1, cfStr2, CFRangeMake (0, size), kCFCompareCaseInsensitive); - CFRelease (cfStr1); - CFRelease (cfStr2); - switch (result) - { - case kCFCompareEqualTo: return 0; - case kCFCompareLessThan: return -1; - case kCFCompareGreaterThan: - default: return 1; - }; -} - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 stricmp16 (const Steinberg::char16* str1, CFIndex str1Len, const Steinberg::char16* str2, CFIndex str2Len) -{ - CFStringRef cfStr1 = CFStringCreateWithCharactersNoCopy (Steinberg::kCFAllocator, (UniChar*)str1, str1Len, kCFAllocatorNull); - CFStringRef cfStr2 = CFStringCreateWithCharactersNoCopy (Steinberg::kCFAllocator, (UniChar*)str2, str2Len, kCFAllocatorNull); - CFComparisonResult result = CFStringCompare (cfStr1, cfStr2, kCFCompareCaseInsensitive); - CFRelease (cfStr1); - CFRelease (cfStr2); - switch (result) - { - case kCFCompareEqualTo: return 0; - case kCFCompareLessThan: return -1; - case kCFCompareGreaterThan: - default: return 1; - }; -} - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 stricmp16 (const Steinberg::ConstString& str1, const Steinberg::ConstString& str2) -{ - return stricmp16 (str1.text16 (), str1.length (), str2.text16 (), str2.length ()); -} - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 stricmp16 (const Steinberg::char16* str1, const Steinberg::char16* str2) -{ - CFIndex str1Len = Steinberg::strlen16 (str1); - CFIndex str2Len = Steinberg::strlen16 (str2); - return stricmp16 (str1, str1Len, str2, str2Len); -} - -//----------------------------------------------------------------------------- -static inline Steinberg::char16* strrchr16 (const Steinberg::char16* str, Steinberg::char16 c) -{ - Steinberg::int32 len = Steinberg::ConstString (str).length (); - while (len > 0) - { - if (str[len] == c) - return const_cast(str + len); - len--; - } - return 0; -} - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 vsnwprintf (Steinberg::char16* str, Steinberg::int32 size, const Steinberg::char16* format, va_list ap) -{ - // wrapped using CoreFoundation's CFString - CFMutableStringRef formatString = (CFMutableStringRef)Steinberg::ConstString (format).toCFStringRef (0xFFFF, true); - CFStringFindAndReplace (formatString, CFSTR("%s"), CFSTR("%S"), CFRangeMake (0, CFStringGetLength (formatString)), 0); - CFStringRef resultString = CFStringCreateWithFormatAndArguments (Steinberg::kCFAllocator, 0, formatString, ap); - CFRelease (formatString); - if (resultString) - { - Steinberg::String res; - res.fromCFStringRef (resultString); - res.copyTo16 (str, 0, size); - CFRelease (resultString); - return 0; - } - return 1; -} - -//----------------------------------------------------------------------------- -static inline Steinberg::int32 sprintf16 (Steinberg::char16* str, const Steinberg::char16* format, ...) -{ - va_list marker; - va_start (marker, format); - return vsnwprintf (str, -1, format, marker); -} - -#endif // SMTG_OS_LINUX - -/* -UTF-8 EF BB BF -UTF-16 Big Endian FE FF -UTF-16 Little Endian FF FE -UTF-32 Big Endian 00 00 FE FF -UTF-32 Little Endian FF FE 00 00 -*/ - -namespace Steinberg { - -//----------------------------------------------------------------------------- -static inline bool isCaseSensitive (ConstString::CompareMode mode) -{ - return mode == ConstString::kCaseSensitive; -} - -//----------------------------------------------------------------------------- -// ConstString -//----------------------------------------------------------------------------- -ConstString::ConstString (const char8* str, int32 length) -: buffer8 ((char8*)str) -, len (length < 0 ? (str ? static_cast (strlen (str)) : 0) : length) -, isWide (0) -{ -} - -//----------------------------------------------------------------------------- -ConstString::ConstString (const char16* str, int32 length) -: buffer16 ((char16*)str) -, len (length < 0 ? (str ? strlen16 (str) : 0) : length) -, isWide (1) -{ -} - -//----------------------------------------------------------------------------- -ConstString::ConstString (const ConstString& str, int32 offset, int32 length) -: buffer (str.buffer) -, len (length < 0 ? (str.len - (offset > 0 ? offset : 0)) : length) -, isWide (str.isWide) -{ - if (offset > 0) - { - if (isWide) - buffer16 += offset; - else - buffer8 += offset; - } -} - -//----------------------------------------------------------------------------- -ConstString::ConstString (const FVariant& var) -: buffer (nullptr) -, len (0) -, isWide (0) -{ - switch (var.getType ()) - { - case FVariant::kString8: - buffer8 = (char8*)var.getString8 (); - len = buffer8 ? strlen8 (buffer8) : 0; - isWide = false; - break; - - case FVariant::kString16: - buffer16 = (char16*)var.getString16 (); - len = buffer16 ? strlen16 (buffer16) : 0; - isWide = true; - break; - } -} - -//----------------------------------------------------------------------------- -ConstString::ConstString () -: buffer (nullptr) -, len (0) -, isWide (0) -{ -} - -//----------------------------------------------------------------------------- -bool ConstString::testChar8 (uint32 index, char8 c) const -{ - if (index >= len) - return c == 0; - if (isWide) - { - // make c wide - char8 src[] = {c, 0}; - char16 dest[2] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - return buffer16[index] == dest[0]; - return false; - } - return buffer8[index] == c; -} - -//----------------------------------------------------------------------------- -bool ConstString::testChar16 (uint32 index, char16 c) const -{ - if (index >= len) - return c == 0; - if (!isWide) - { - // make c ansi - char16 src[] = {c, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - return buffer8[index] == dest[0]; - return false; - } - return buffer16[index] == c; -} - -//----------------------------------------------------------------------------- -bool ConstString::extract (String& result, uint32 idx, int32 n) const -{ - if (len == 0|| idx >= len) - return false; - - if ((idx + n > len) || n < 0) - n = len - idx; - - if (isWide) - result.assign (buffer16 + idx, n); - else - result.assign (buffer8 + idx, n); - - return true; -} - -//----------------------------------------------------------------------------- -int32 ConstString::copyTo8 (char8* str, uint32 idx, int32 n) const -{ - if (!str) - return 0; - - if (isWide) - { - String tmp (text16 ()); - if (tmp.toMultiByte () == false) - return 0; - return tmp.copyTo8 (str, idx, n); - } - - if (isEmpty () || idx >= len || !buffer8) - { - str[0] = 0; - return 0; - } - - if ((idx + n > len) || n < 0) - n = len - idx; - - memcpy (str, &(buffer8[idx]), n * sizeof (char8)); - str[n] = 0; - return n; -} - -//----------------------------------------------------------------------------- -int32 ConstString::copyTo16 (char16* str, uint32 idx, int32 n) const -{ - if (!str) - return 0; - - if (!isWide) - { - String tmp (text8 ()); - if (tmp.toWideString () == false) - return 0; - return tmp.copyTo16 (str, idx, n); - } - - if (isEmpty () || idx >= len || !buffer16) - { - str[0] = 0; - return 0; - } - - if ((idx + n > len) || n < 0) - n = len - idx; - - memcpy (str, &(buffer16[idx]), n * sizeof (char16)); - str[n] = 0; - return n; -} - -//----------------------------------------------------------------------------- -int32 ConstString::copyTo (tchar* str, uint32 idx, int32 n) const -{ -#ifdef UNICODE - return copyTo16 (str, idx, n); -#else - return copyTo8 (str, idx, n); -#endif -} - -//----------------------------------------------------------------------------- -void ConstString::copyTo (IStringResult* result) const -{ - if (isWideString () == false) - { - result->setText (text8 ()); - } - else - { - FUnknownPtr iStr (result); - if (iStr) - { - iStr->setText16 (text16 ()); - } - else - { - String tmp (*this); - tmp.toMultiByte (); - result->setText (tmp.text8 ()); - } - } -} - -//----------------------------------------------------------------------------- -void ConstString::copyTo (IString& string) const -{ - if (isWideString ()) - string.setText16 (text16 ()); - else - string.setText8 (text8 ()); -} - - - -//----------------------------------------------------------------------------- -int32 ConstString::compare (const ConstString& str, int32 n, CompareMode mode) const -{ - if (n == 0) - return 0; - - if (str.isEmpty ()) - { - if (isEmpty ()) - return 0; - return 1; - } - else if (isEmpty ()) - return -1; - - if (!isWide && !str.isWide) - { - if (n < 0) - { - if (isCaseSensitive (mode)) - return strcmp (*this, str); - else - return stricmp (*this, str); - } - else - { - if (isCaseSensitive (mode)) - return strncmp (*this, str, n); - else - return strnicmp (*this, str, n); - } - } - else if (isWide && str.isWide) - { - if (n < 0) - { - if (isCaseSensitive (mode)) - return strcmp16 (*this, str); - else - return stricmp16 (*this, str); - } - else - { - if (isCaseSensitive (mode)) - return strncmp16 (*this, str, n); - else - return strnicmp16 (*this, str, n); - } - } - return compareAt (0, str, n, mode); -} - -//----------------------------------------------------------------------------- -int32 ConstString::compare (const ConstString& str, CompareMode mode) const -{ - return compare (str, -1, mode); -} - -//----------------------------------------------------------------------------- -int32 ConstString::compareAt (uint32 index, const ConstString& str, int32 n, CompareMode mode) const -{ - if (n == 0) - return 0; - - if (str.isEmpty ()) - { - if (isEmpty ()) - return 0; - return 1; - } - else if (isEmpty ()) - return -1; - - if (!isWide && !str.isWide) - { - char8* toCompare = buffer8; - if (index > 0) - { - if (index >= len) - { - if (str.isEmpty ()) - return 0; - return -1; - } - toCompare += index; - } - - if (n < 0) - { - if (isCaseSensitive (mode)) - return strcmp (toCompare, str); - else - return stricmp (toCompare, str); - } - else - { - if (isCaseSensitive (mode)) - return strncmp (toCompare, str, n); - else - return strnicmp (toCompare, str, n); - } - } - else if (isWide && str.isWide) - { - char16* toCompare = buffer16; - if (index > 0) - { - if (index >= len) - { - if (str.isEmpty ()) - return 0; - return -1; - } - toCompare += index; - } - - if (n < 0) - { - if (isCaseSensitive (mode)) - return strcmp16 (toCompare, str.text16 ()); - else - return stricmp16 (toCompare, str.text16 ()); - } - else - { - if (isCaseSensitive (mode)) - return strncmp16 (toCompare, str.text16 (), n); - else - return strnicmp16 (toCompare, str.text16 (), n); - } - } - else - { - if (isWide) - { - String tmp (str.text8 ()); - if (tmp.toWideString () == false) - return -1; - return compareAt (index, tmp, n, mode); - } - else - { - String tmp (text8 ()); - if (tmp.toWideString () == false) - return 1; - return tmp.compareAt (index, str, n, mode); - } - } -} - -//------------------------------------------------------------------------ -Steinberg::int32 ConstString::naturalCompare (const ConstString& str, CompareMode mode /*= kCaseSensitive*/) const -{ - if (str.isEmpty ()) - { - if (isEmpty ()) - return 0; - return 1; - } - else if (isEmpty ()) - return -1; - - if (!isWide && !str.isWide) - return strnatcmp8 (buffer8, str.text8 (), isCaseSensitive (mode)); - else if (isWide && str.isWide) - return strnatcmp16 (buffer16, str.text16 (), isCaseSensitive (mode)); - else - { - if (isWide) - { - String tmp (str.text8 ()); - tmp.toWideString (); - return strnatcmp16 (buffer16, tmp.text16 (), isCaseSensitive (mode)); - } - else - { - String tmp (text8 ()); - tmp.toWideString (); - return strnatcmp16 (tmp.text16 (), str.text16 (), isCaseSensitive (mode)); - } - } -} - -//----------------------------------------------------------------------------- -bool ConstString::startsWith (const ConstString& str, CompareMode mode /*= kCaseSensitive*/) const -{ - if (str.isEmpty ()) - { - return isEmpty (); - } - else if (isEmpty ()) - { - return false; - } - if (length () < str.length ()) - { - return false; - } - if (!isWide && !str.isWide) - { - if (isCaseSensitive (mode)) - return strncmp (buffer8, str.buffer8, str.length ()) == 0; - return strnicmp (buffer8, str.buffer8, str.length ()) == 0; - } - else if (isWide && str.isWide) - { - if (isCaseSensitive (mode)) - return strncmp16 (buffer16, str.buffer16, str.length ()) == 0; - return strnicmp16 (buffer16, str.buffer16, str.length ()) == 0; - } - else if (isWide) - { - String tmp (str.text8 ()); - tmp.toWideString (); - if (tmp.length () > length ()) - return false; - if (isCaseSensitive (mode)) - return strncmp16 (buffer16, tmp.buffer16, tmp.length ()) == 0; - return strnicmp16 (buffer16, tmp.buffer16, tmp.length ()) == 0; - } - else - { - String tmp (text8 ()); - tmp.toWideString (); - if (str.length () > tmp.length ()) - return false; - if (isCaseSensitive (mode)) - return strncmp16 (tmp.buffer16, str.buffer16, str.length ()) == 0; - return strnicmp16 (tmp.buffer16, str.buffer16, str.length ()) == 0; - } -} - -//----------------------------------------------------------------------------- -bool ConstString::endsWith (const ConstString& str, CompareMode mode /*= kCaseSensitive*/) const -{ - if (str.isEmpty ()) - { - return isEmpty (); - } - else if (isEmpty ()) - { - return false; - } - if (length () < str.length ()) - { - return false; - } - if (!isWide && !str.isWide) - { - if (isCaseSensitive (mode)) - return strncmp (buffer8 + (length () - str.length ()), str.buffer8, str.length ()) == 0; - return strnicmp (buffer8 + (length () - str.length ()), str.buffer8, str.length ()) == 0; - } - else if (isWide && str.isWide) - { - if (isCaseSensitive (mode)) - return strncmp16 (buffer16 + (length () - str.length ()), str.buffer16, str.length ()) == 0; - return strnicmp16 (buffer16 + (length () - str.length ()), str.buffer16, str.length ()) == 0; - } - else if (isWide) - { - String tmp (str.text8 ()); - tmp.toWideString (); - if (tmp.length () > length ()) - return false; - if (isCaseSensitive (mode)) - return strncmp16 (buffer16 + (length () - tmp.length ()), tmp.buffer16, tmp.length ()) == 0; - return strnicmp16 (buffer16 + (length () - tmp.length ()), tmp.buffer16, tmp.length ()) == 0; - } - else - { - String tmp (text8 ()); - tmp.toWideString (); - if (str.length () > tmp.length ()) - return false; - if (isCaseSensitive (mode)) - return strncmp16 (tmp.buffer16 + (tmp.length () - str.length ()), str.buffer16, str.length ()) == 0; - return strnicmp16 (tmp.buffer16 + (tmp.length () - str.length ()), str.buffer16, str.length ()) == 0; - } -} - -//----------------------------------------------------------------------------- -bool ConstString::contains (const ConstString& str, CompareMode m) const -{ - return findFirst (str, -1, m) != -1; -} - -//----------------------------------------------------------------------------- -int32 ConstString::findNext (int32 startIndex, const ConstString& str, int32 n, CompareMode mode, int32 endIndex) const -{ - uint32 endLength = len; - if (endIndex > -1 && (uint32)endIndex < len) - endLength = endIndex + 1; - - if (isWide && str.isWide) - { - if (startIndex < 0) - startIndex = 0; - - uint32 stringLength = str.length (); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (n > 0) - { - uint32 i = 0; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i < endLength; i++) - if (strncmp16 (buffer16 + i, str, n) == 0) - return i; - } - else - { - for (i = startIndex; i < endLength; i++) - if (strnicmp16 (buffer16 + i, str, n) == 0) - return i; - } - } - return -1; - } - else if (!isWide && !str.isWide) - { - uint32 stringLength = str.length (); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (startIndex < 0) - startIndex = 0; - - if (n > 0) - { - uint32 i = 0; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i < endLength; i++) - if (strncmp (buffer8 + i, str, n) == 0) - return i; - } - else - { - for (i = startIndex; i < endLength; i++) - if (strnicmp (buffer8 + i, str, n) == 0) - return i; - } - } - return -1; - } - String tmp; - if (isWide) - { - tmp = str.text8 (); - tmp.toWideString (); - return findNext (startIndex, tmp, n , mode, endIndex); - } - tmp = text8 (); - tmp.toWideString (); - return tmp.findNext (startIndex, str, n, mode, endIndex); -} - -//------------------------------------------------------------------------------------------------ -int32 ConstString::findNext (int32 startIndex, char8 c, CompareMode mode, int32 endIndex) const -{ - uint32 endLength = len; - if (endIndex > -1 && (uint32)endIndex < len) - endLength = endIndex + 1; - - if (isWide) - { - char8 src[] = {c, 0}; - char16 dest[8] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - return findNext (startIndex, dest[0], mode, endIndex); - return -1; - } - - if (startIndex < 0) - startIndex = 0; - uint32 i; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i < endLength; i++) - { - if (buffer8[i] == c) - return i; - } - } - else - { - c = toLower (c); - for (i = startIndex; i < endLength; i++) - { - if (toLower (buffer8[i]) == c) - return i; - } - } - return -1; -} - -//----------------------------------------------------------------------------- -int32 ConstString::findNext (int32 startIndex, char16 c, CompareMode mode, int32 endIndex) const -{ - uint32 endLength = len; - if (endIndex > -1 && (uint32)endIndex < len) - endLength = endIndex + 1; - - if (!isWide) - { - char16 src[] = {c, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - return findNext (startIndex, dest[0], mode, endIndex); - - return -1; - } - - uint32 i; - if (startIndex < 0) - startIndex = 0; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i < endLength; i++) - { - if (buffer16[i] == c) - return i; - } - } - else - { - c = toLower (c); - for (i = startIndex; i < endLength; i++) - { - if (toLower (buffer16[i]) == c) - return i; - } - } - return -1; -} - -//----------------------------------------------------------------------------- -int32 ConstString::findPrev (int32 startIndex, char8 c, CompareMode mode) const -{ - if (len == 0) - return -1; - - if (isWide) - { - char8 src[] = {c, 0}; - char16 dest[8] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - return findPrev (startIndex, dest[0], mode); - return -1; - } - - if (startIndex < 0 || startIndex > (int32)len) - startIndex = len; - - int32 i; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i >= 0; i--) - { - if (buffer8[i] == c) - return i; - } - } - else - { - c = toLower (c); - for (i = startIndex; i >= 0; i--) - { - if (toLower (buffer8[i]) == c) - return i; - } - } - return -1; -} - -//----------------------------------------------------------------------------- -int32 ConstString::findPrev (int32 startIndex, char16 c, CompareMode mode) const -{ - if (len == 0) - return -1; - - if (!isWide) - { - char16 src[] = {c, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - return findPrev (startIndex, dest[0], mode); - - return -1; - } - - if (startIndex < 0 || startIndex > (int32)len) - startIndex = len; - - int32 i; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i >= 0; i--) - { - if (buffer16[i] == c) - return i; - } - } - else - { - c = toLower (c); - for (i = startIndex; i >= 0; i--) - { - if (toLower (buffer16[i]) == c) - return i; - } - } - return -1; -} - -//----------------------------------------------------------------------------- -int32 ConstString::findPrev (int32 startIndex, const ConstString& str, int32 n, CompareMode mode) const -{ - if (isWide && str.isWide) - { - uint32 stringLength = str.length (); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (startIndex < 0 || startIndex >= (int32)len) - startIndex = len - 1; - - if (n > 0) - { - int32 i = 0; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i >= 0; i--) - if (strncmp16 (buffer16 + i, str, n) == 0) - return i; - } - else - { - for (i = startIndex; i >= 0; i--) - if (strnicmp16 (buffer16 + i, str, n) == 0) - return i; - } - } - return -1; - } - else if (!isWide && !str.isWide) - { - uint32 stringLength = str.length (); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (startIndex < 0 || startIndex >= (int32)len) - startIndex = len - 1; - - if (n > 0) - { - int32 i = 0; - - if (isCaseSensitive (mode)) - { - for (i = startIndex; i >= 0; i--) - if (strncmp (buffer8 + i, str, n) == 0) - return i; - } - else - { - for (i = startIndex; i >= 0; i--) - if (strnicmp (buffer8 + i, str, n) == 0) - return i; - } - } - return -1; - } - if (isWide) - { - String tmp (str.text8 ()); - tmp.toWideString (); - return findPrev (startIndex, tmp, n, mode); - } - String tmp (text8 ()); - tmp.toWideString (); - return tmp.findPrev (startIndex, str, n, mode); -} - -//----------------------------------------------------------------------------- -int32 ConstString::countOccurences (char8 c, uint32 startIndex, CompareMode mode) const -{ - if (isWide) - { - char8 src[] = {c, 0}; - char16 dest[8] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - return countOccurences (dest[0], startIndex, mode); - return -1; - } - - int32 result = 0; - int32 next = startIndex; - while (true) - { - next = findNext (next, c, mode); - if (next >= 0) - { - next++; - result++; - } - else - break; - } - return result; -} - -//----------------------------------------------------------------------------- -int32 ConstString::countOccurences (char16 c, uint32 startIndex, CompareMode mode) const -{ - if (!isWide) - { - char16 src[] = {c, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - return countOccurences (dest[0], startIndex, mode); - - return -1; - } - int32 result = 0; - int32 next = startIndex; - while (true) - { - next = findNext (next, c, mode); - if (next >= 0) - { - next++; - result++; - } - else - break; - } - return result; -} - -//----------------------------------------------------------------------------- -int32 ConstString::getFirstDifferent (const ConstString& str, CompareMode mode) const -{ - if (str.isWide != isWide) - { - if (isWide) - { - String tmp (str.text8 ()); - if (tmp.toWideString () == false) - return -1; - return getFirstDifferent (tmp, mode); - } - else - { - String tmp (text8 ()); - if (tmp.toWideString () == false) - return -1; - return tmp.getFirstDifferent (str, mode); - } - } - - uint32 len1 = len; - uint32 len2 = str.len; - uint32 i; - - if (isWide) - { - if (isCaseSensitive (mode)) - { - for (i = 0; i <= len1 && i <= len2; i++) - { - if (buffer16[i] != str.buffer16[i]) - return i; - } - } - else - { - for (i = 0; i <= len1 && i <= len2; i++) - { - if (toLower (buffer16[i]) != toLower (str.buffer16[i])) - return i; - } - } - } - else - { - if (isCaseSensitive (mode)) - { - for (i = 0; i <= len1 && i <= len2; i++) - { - if (buffer8[i] != str.buffer8[i]) - return i; - } - } - else - { - for (i = 0; i <= len1 && i <= len2; i++) - { - if (toLower (buffer8[i]) != toLower (str.buffer8[i])) - return i; - } - } - } - return -1; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanInt64 (int64& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - if (isWide) - return scanInt64_16 (buffer16 + offset, value, scanToEnd); - else - return scanInt64_8 (buffer8 + offset, value, scanToEnd); -} - -//----------------------------------------------------------------------------- -bool ConstString::scanUInt64 (uint64& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - if (isWide) - return scanUInt64_16 (buffer16 + offset, value, scanToEnd); - else - return scanUInt64_8 (buffer8 + offset, value, scanToEnd); -} - -//----------------------------------------------------------------------------- -bool ConstString::scanHex (uint8& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - if (isWide) - return scanHex_16 (buffer16 + offset, value, scanToEnd); - else - return scanHex_8 (buffer8 + offset, value, scanToEnd); -} - -//----------------------------------------------------------------------------- -bool ConstString::scanInt32 (int32& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - if (isWide) - return scanInt32_16 (buffer16 + offset, value, scanToEnd); - else - return scanInt32_8 (buffer8 + offset, value, scanToEnd); -} - -//----------------------------------------------------------------------------- -bool ConstString::scanUInt32 (uint32& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - if (isWide) - return scanUInt32_16 (buffer16 + offset, value, scanToEnd); - else - return scanUInt32_8 (buffer8 + offset, value, scanToEnd); -} - -//----------------------------------------------------------------------------- -bool ConstString::scanInt64_8 (const char8* text, int64& value, bool scanToEnd) -{ - while (text && text[0]) - { - if (sscanf (text, "%" FORMAT_INT64A, &value) == 1) - return true; - else if (scanToEnd == false) - return false; - text++; - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanInt64_16 (const char16* text, int64& value, bool scanToEnd) -{ - if (text && text[0]) - { - String str (text); - str.toMultiByte (kCP_Default); - return scanInt64_8 (str, value, scanToEnd); - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanUInt64_8 (const char8* text, uint64& value, bool scanToEnd) -{ - while (text && text[0]) - { - if (sscanf (text, "%" FORMAT_UINT64A, &value) == 1) - return true; - else if (scanToEnd == false) - return false; - text++; - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanUInt64_16 (const char16* text, uint64& value, bool scanToEnd) -{ - if (text && text[0]) - { - String str (text); - str.toMultiByte (kCP_Default); - return scanUInt64_8 (str, value, scanToEnd); - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanInt64 (const tchar* text, int64& value, bool scanToEnd) -{ -#ifdef UNICODE - return scanInt64_16 (text, value,scanToEnd); -#else - return scanInt64_8 (text, value, scanToEnd); -#endif -} - -//----------------------------------------------------------------------------- -bool ConstString::scanUInt64 (const tchar* text, uint64& value, bool scanToEnd) -{ -#ifdef UNICODE - return scanUInt64_16 (text, value, scanToEnd); -#else - return scanUInt64_8 (text, value, scanToEnd); -#endif -} - -//----------------------------------------------------------------------------- -bool ConstString::scanHex_8 (const char8* text, uint8& value, bool scanToEnd) -{ - while (text && text[0]) - { - unsigned int v; // scanf expects an unsigned int for %x - if (sscanf (text, "%x", &v) == 1) - { - value = (uint8)v; - return true; - } - else if (scanToEnd == false) - return false; - text++; - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanHex_16 (const char16* text, uint8& value, bool scanToEnd) -{ - if (text && text[0]) - { - String str (text); - str.toMultiByte (kCP_Default); // scanf uses default codepage - return scanHex_8 (str, value, scanToEnd); - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::scanHex (const tchar* text, uint8& value, bool scanToEnd) -{ -#ifdef UNICODE - return scanHex_16 (text, value, scanToEnd); -#else - return scanHex_8 (text, value, scanToEnd); -#endif -} - -//----------------------------------------------------------------------------- -bool ConstString::scanFloat (double& value, uint32 offset, bool scanToEnd) const -{ - if (isEmpty () || offset >= len) - return false; - - String str (*this); - int32 pos = -1; - if (isWide) - { - if ((pos = str.findNext (offset, STR(','))) >= 0 && ((uint32)pos) >= offset) - str.setChar (pos, STR('.')); - - str.toMultiByte (kCP_Default); // scanf uses default codepage - } - else - { - if ((pos = str.findNext (offset, ',')) >= 0 && ((uint32)pos) >= offset) - str.setChar (pos, '.'); - } - - const char8* txt = str.text8 () + offset; - while (txt && txt[0]) - { - if (sscanf (txt, "%lf", &value) == 1) - return true; - else if (scanToEnd == false) - return false; - txt++; - } - return false; -} - -//----------------------------------------------------------------------------- -char16 ConstString::toLower (char16 c) -{ - #if SMTG_OS_WINDOWS - WCHAR temp[2] = {c, 0}; - ::CharLowerW (temp); - return temp[0]; - #elif SMTG_OS_MACOS - // only convert characters which in lowercase are also single characters - UniChar characters [2] = {0}; - characters[0] = c; - CFMutableStringRef str = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocator, characters, 1, 2, kCFAllocatorNull); - if (str) - { - CFStringLowercase (str, NULL); - CFRelease (str); - if (characters[1] == 0) - return characters[0]; - } - return c; - #elif SMTG_OS_LINUX - assert(false && "DEPRECATED No Linux implementation"); - return c; - #else - return towlower (c); - #endif -} - -//----------------------------------------------------------------------------- -char16 ConstString::toUpper (char16 c) -{ - #if SMTG_OS_WINDOWS - WCHAR temp[2] = {c, 0}; - ::CharUpperW (temp); - return temp[0]; - #elif SMTG_OS_MACOS - // only convert characters which in uppercase are also single characters (don't translate a sharp-s which would result in SS) - UniChar characters [2] = {0}; - characters[0] = c; - CFMutableStringRef str = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocator, characters, 1, 2, kCFAllocatorNull); - if (str) - { - CFStringUppercase (str, NULL); - CFRelease (str); - if (characters[1] == 0) - return characters[0]; - } - return c; - #elif SMTG_OS_LINUX - assert(false && "DEPRECATED No Linux implementation"); - return c; - #else - return towupper (c); - #endif -} - -//----------------------------------------------------------------------------- -char8 ConstString::toLower (char8 c) -{ - if ((c >= 'A') && (c <= 'Z')) - return c + ('a' - 'A'); - #if SMTG_OS_WINDOWS - CHAR temp[2] = {c, 0}; - ::CharLowerA (temp); - return temp[0]; - #else - return static_cast (tolower (c)); - #endif -} - -//----------------------------------------------------------------------------- -char8 ConstString::toUpper (char8 c) -{ - if ((c >= 'a') && (c <= 'z')) - return c - ('a' - 'A'); - #if SMTG_OS_WINDOWS - CHAR temp[2] = {c, 0}; - ::CharUpperA (temp); - return temp[0]; - #else - return static_cast (toupper (c)); - #endif -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharSpace (const char8 character) -{ - return isspace (character) != 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharSpace (const char16 character) -{ - switch (character) - { - case 0x0020: - case 0x00A0: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200A: - case 0x200B: - case 0x202F: - case 0x205F: - case 0x3000: - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAlpha (const char8 character) -{ - return isalpha (character) != 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAlpha (const char16 character) -{ - return iswalpha (character) != 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAlphaNum (const char8 character) -{ - return isalnum (character) != 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAlphaNum (const char16 character) -{ - return iswalnum (character) != 0; // this may not work on macOSX when another locale is set inside the c-lib -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharDigit (const char8 character) -{ - return isdigit (character) != 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharDigit (const char16 character) -{ - return iswdigit (character) != 0; // this may not work on macOSX when another locale is set inside the c-lib -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAscii (char8 character) -{ - return character >= 0; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharAscii (char16 character) -{ - return character < 128; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharUpper (char8 character) -{ - return toUpper (character) == character; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharUpper (char16 character) -{ - return toUpper (character) == character; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharLower (char8 character) -{ - return toLower (character) == character; -} - -//----------------------------------------------------------------------------- -bool ConstString::isCharLower (char16 character) -{ - return toLower (character) == character; -} - -//----------------------------------------------------------------------------- -bool ConstString::isDigit (uint32 index) const -{ - if (isEmpty () || index >= len) - return false; - - if (isWide) - return ConstString::isCharDigit (buffer16[index]); - else - return ConstString::isCharDigit (buffer8[index]); -} - -//----------------------------------------------------------------------------- -int32 ConstString::getTrailingNumberIndex (uint32 width) const -{ - if (isEmpty ()) - return -1; - - int32 endIndex = len - 1; - int32 i = endIndex; - while (isDigit ((uint32) i) && i >= 0) - i--; - - // now either all are digits or i is on the first non digit - if (i < endIndex) - { - if (width > 0 && (endIndex - i != static_cast (width))) - return -1; - - return i + 1; - } - - return -1; -} - -//----------------------------------------------------------------------------- -int64 ConstString::getTrailingNumber (int64 fallback) const -{ - int32 index = getTrailingNumberIndex (); - - int64 number = 0; - - if (index >= 0) - if (scanInt64 (number, index)) - return number; - - return fallback; -} - - - -//----------------------------------------------------------------------------- -void ConstString::toVariant (FVariant& var) const -{ - if (isWide) - { - var.setString16 (buffer16); - } - else - { - var.setString8 (buffer8); - } -} - -//----------------------------------------------------------------------------- -bool ConstString::isAsciiString () const -{ - uint32 i; - if (isWide) - { - for (i = 0; i < len; i++) - if (ConstString::isCharAscii (buffer16 [i]) == false) - return false; - } - else - { - for (i = 0; i < len; i++) - if (ConstString::isCharAscii (buffer8 [i]) == false) - return false; - } - return true; -} - - -#if SMTG_OS_MACOS -uint32 kDefaultSystemEncoding = kCFStringEncodingMacRoman; -//----------------------------------------------------------------------------- -static CFStringEncoding MBCodePageToCFStringEncoding (uint32 codePage) -{ - switch (codePage) - { - case kCP_ANSI: return kDefaultSystemEncoding; // MacRoman or JIS - case kCP_MAC_ROMAN: return kCFStringEncodingMacRoman; - case kCP_ANSI_WEL: return kCFStringEncodingWindowsLatin1; - case kCP_MAC_CEE: return kCFStringEncodingMacCentralEurRoman; - case kCP_Utf8: return kCFStringEncodingUTF8; - case kCP_ShiftJIS: return kCFStringEncodingShiftJIS_X0213_00; - case kCP_US_ASCII: return kCFStringEncodingASCII; - } - return kCFStringEncodingASCII; -} -#endif - -//----------------------------------------------------------------------------- -int32 ConstString::multiByteToWideString (char16* dest, const char8* source, int32 charCount, uint32 sourceCodePage) -{ - if (source == nullptr || source[0] == 0) - { - if (dest && charCount > 0) - { - dest[0] = 0; - } - return 0; - } - int32 result = 0; -#if SMTG_OS_WINDOWS - result = MultiByteToWideChar (sourceCodePage, MB_ERR_INVALID_CHARS, source, -1, dest, charCount); -#endif - -#if SMTG_OS_MACOS - CFStringRef cfStr = - (CFStringRef)::toCFStringRef (source, MBCodePageToCFStringEncoding (sourceCodePage)); - if (cfStr) - { - CFRange range = {0, CFStringGetLength (cfStr)}; - CFIndex usedBytes; - if (CFStringGetBytes (cfStr, range, kCFStringEncodingUnicode, ' ', false, (UInt8*)dest, - charCount * 2, &usedBytes) > 0) - { - result = static_cast (usedBytes / 2 + 1); - if (dest) - dest[usedBytes / 2] = 0; - } - - CFRelease (cfStr); - } -#endif - -#if SMTG_OS_LINUX - if (sourceCodePage == kCP_ANSI || sourceCodePage == kCP_US_ASCII || sourceCodePage == kCP_Utf8) - { - if (dest == nullptr) - { - auto state = std::mbstate_t (); - auto maxChars = charCount ? charCount : std::numeric_limits::max () - 1; - result = converterFacet ().length (state, source, source + strlen (source), maxChars); - } - else - { - auto utf16Str = converter ().from_bytes (source); - if (!utf16Str.empty ()) - { - result = std::min (charCount, utf16Str.size ()); - memcpy (dest, utf16Str.data (), result * sizeof (char16)); - dest[result] = 0; - } - } - } - else - { - assert(false && "DEPRECATED No Linux implementation"); - } - -#endif - - SMTG_ASSERT (result > 0) - return result; -} - -//----------------------------------------------------------------------------- -int32 ConstString::wideStringToMultiByte (char8* dest, const char16* wideString, int32 charCount, uint32 destCodePage) -{ -#if SMTG_OS_WINDOWS - return WideCharToMultiByte (destCodePage, 0, wideString, -1, dest, charCount, nullptr, nullptr); - -#elif SMTG_OS_MACOS - int32 result = 0; - if (wideString != 0) - { - if (dest) - { - CFStringRef cfStr = CFStringCreateWithCharactersNoCopy (kCFAllocator, (const UniChar*)wideString, strlen16 (wideString), kCFAllocatorNull); - if (cfStr) - { - if (fromCFStringRef (dest, charCount, cfStr, MBCodePageToCFStringEncoding (destCodePage))) - result = static_cast (strlen (dest) + 1); - CFRelease (cfStr); - } - } - else - { - return static_cast (CFStringGetMaximumSizeForEncoding (strlen16 (wideString), MBCodePageToCFStringEncoding (destCodePage))); - } - } - return result; - -#elif SMTG_OS_LINUX - int32 result = 0; - if (destCodePage == kCP_Utf8) - { - if (dest == nullptr) - { - auto maxChars = charCount ? charCount : tstrlen (wideString); - result = converterFacet ().max_length () * maxChars; - } - else - { - auto utf8Str = converter ().to_bytes (wideString); - if (!utf8Str.empty ()) - { - result = std::min (charCount, utf8Str.size ()); - memcpy (dest, utf8Str.data (), result * sizeof (char8)); - dest[result] = 0; - } - } - } - else if (destCodePage == kCP_ANSI || destCodePage == kCP_US_ASCII) - { - if (dest == nullptr) - { - result = strlen16 (wideString) + 1; - } - else - { - int32 i = 0; - for (; i < charCount; ++i) - { - if (wideString[i] == 0) - break; - if (wideString[i] <= 0x007F) - dest[i] = wideString[i]; - else - dest[i] = '_'; - } - dest[i] = 0; - result = i; - } - } - else - { - assert(false && "DEPRECATED No Linux implementation"); - } - return result; - -#else -#warning DEPRECATED No Linux implementation - assert(false && "DEPRECATED No Linux implementation"); - return 0; -#endif - -} - -//----------------------------------------------------------------------------- -bool ConstString::isNormalized (UnicodeNormalization n) -{ - if (isWide == false) - return false; - -#if SMTG_OS_WINDOWS -#ifdef UNICODE - if (n != kUnicodeNormC) - return false; - uint32 normCharCount = static_cast (FoldString (MAP_PRECOMPOSED, buffer16, len, nullptr, 0)); - return (normCharCount == len); -#else - return false; -#endif - -#elif SMTG_OS_MACOS - if (n != kUnicodeNormC) - return false; - - CFStringRef cfStr = (CFStringRef)toCFStringRef (); - CFIndex charCount = CFStringGetLength (cfStr); - CFRelease (cfStr); - return (charCount == len); -#else - return false; -#endif -} - -//----------------------------------------------------------------------------- -// String -//----------------------------------------------------------------------------- -String::String () -{ - isWide = kWideStringDefault ? 1 : 0; -} - -//----------------------------------------------------------------------------- -String::String (const char8* str, MBCodePage codePage, int32 n, bool isTerminated) -{ - isWide = 0; - if (str) - { - assign (str, n, isTerminated); - toWideString (codePage); - } -} - -//----------------------------------------------------------------------------- -String::String (const char8* str, int32 n, bool isTerminated) -{ - if (str) - assign (str, n, isTerminated); -} - -//----------------------------------------------------------------------------- -String::String (const char16* str, int32 n, bool isTerminated) -{ - isWide = 1; - if (str) - assign (str, n, isTerminated); -} - -//----------------------------------------------------------------------------- -String::String (const String& str, int32 n) -{ - isWide = str.isWideString (); - if (!str.isEmpty ()) - assign (str, n); -} - -//----------------------------------------------------------------------------- -String::String (const ConstString& str, int32 n) -{ - isWide = str.isWideString (); - if (!str.isEmpty ()) - assign (str, n); -} - -//----------------------------------------------------------------------------- -String::String (const FVariant& var) -{ - isWide = kWideStringDefault ? 1 : 0; - fromVariant (var); -} - -//----------------------------------------------------------------------------- -String::String (IString* str) -{ - isWide = str->isWideString (); - if (isWide) - assign (str->getText16 ()); - else - assign (str->getText8 ()); -} - -//----------------------------------------------------------------------------- -String::~String () -{ - if (buffer) - resize (0, false); -} - -#if SMTG_CPP11_STDLIBSUPPORT -//----------------------------------------------------------------------------- -String::String (String&& str) -{ - *this = std::move (str); -} - -//----------------------------------------------------------------------------- -String& String::operator= (String&& str) -{ - SMTG_ASSERT (buffer == nullptr || buffer != str.buffer); - tryFreeBuffer (); - - isWide = str.isWide; - buffer = str.buffer; - len = str.len; - str.buffer = nullptr; - str.len = 0; - return *this; -} -#endif - -//----------------------------------------------------------------------------- -void String::updateLength () -{ - if (isWide) - len = strlen16 (text16 ()); - else - len = strlen8 (text8 ()); -} - -//----------------------------------------------------------------------------- -bool String::toWideString (uint32 sourceCodePage) -{ - if (!isWide) - { - if (buffer8 && len > 0) - { - int32 bytesNeeded = multiByteToWideString (nullptr, buffer8, 0, sourceCodePage) * sizeof (char16); - if (bytesNeeded) - { - bytesNeeded += sizeof (char16); - char16* newStr = (char16*) malloc (bytesNeeded); - if (multiByteToWideString (newStr, buffer8, len + 1, sourceCodePage) <= 0) - { - free (newStr); - return false; - } - free (buffer8); - buffer16 = newStr; - isWide = true; - updateLength (); - } - else - { - return false; - } - } - isWide = true; - } - return true; -} - -#define SMTG_STRING_CHECK_CONVERSION 1 -#define SMTG_STRING_CHECK_CONVERSION_NO_BREAK 1 - -#if SMTG_STRING_CHECK_CONVERSION_NO_BREAK - #define SMTG_STRING_CHECK_MSG FDebugPrint -#else - #define SMTG_STRING_CHECK_MSG FDebugBreak -#endif -//----------------------------------------------------------------------------- -bool String::checkToMultiByte (uint32 destCodePage) const -{ - if (!isWide || isEmpty ()) - return true; - -#if DEVELOPMENT && SMTG_STRING_CHECK_CONVERSION - int debugLen = length (); - int debugNonASCII = 0; - for (int32 i = 0; i < length (); i++) - { - if (buffer16[i] > 127) - ++debugNonASCII; - } - - String* backUp = nullptr; - if (debugNonASCII > 0) - backUp = NEW String (*this); -#endif - - // this should be avoided, since it can lead to information loss - bool result = const_cast (*this).toMultiByte (destCodePage); - -#if DEVELOPMENT && SMTG_STRING_CHECK_CONVERSION - if (backUp) - { - String temp (*this); - temp.toWideString (destCodePage); - - if (temp != *backUp) - { - backUp->toMultiByte (kCP_Utf8); - SMTG_STRING_CHECK_MSG ("Indirect string conversion information loss ! %d/%d non ASCII chars: \"%s\" -> \"%s\"\n", debugNonASCII, debugLen, backUp->buffer8, buffer8); - } - else - SMTG_STRING_CHECK_MSG ("Indirect string potential conversion information loss ! %d/%d non ASCII chars result: \"%s\"\n", debugNonASCII, debugLen, buffer8); - - delete backUp; - } -#endif - - return result; -} - -//----------------------------------------------------------------------------- -bool String::toMultiByte (uint32 destCodePage) -{ - if (isWide) - { - if (buffer16 && len > 0) - { - int32 numChars = wideStringToMultiByte (nullptr, buffer16, 0, destCodePage) + sizeof (char8); - char8* newStr = (char8*) malloc (numChars * sizeof (char8)); - if (wideStringToMultiByte (newStr, buffer16, numChars, destCodePage) <= 0) - { - free (newStr); - return false; - } - free (buffer16); - buffer8 = newStr; - isWide = false; - updateLength (); - } - isWide = false; - } - else if (destCodePage != kCP_Default) - { - if (toWideString () == false) - return false; - return toMultiByte (destCodePage); - } - return true; -} - -//----------------------------------------------------------------------------- -void String::fromUTF8 (const char8* utf8String) -{ - assign (utf8String); - toWideString (kCP_Utf8); -} - -//----------------------------------------------------------------------------- -bool String::normalize (UnicodeNormalization n) -{ - if (isWide == false) - return false; - - if (buffer16 == nullptr) - return true; - -#if SMTG_OS_WINDOWS -#ifdef UNICODE - if (n != kUnicodeNormC) - return false; - - uint32 normCharCount = static_cast (FoldString (MAP_PRECOMPOSED, buffer16, len, nullptr, 0)); - if (normCharCount == len) - return true; - - char16* newString = (char16*)malloc ((normCharCount + 1) * sizeof (char16)); - uint32 converterCount = static_cast (FoldString (MAP_PRECOMPOSED, buffer16, len, newString, normCharCount + 1)); - if (converterCount != normCharCount) - { - free (newString); - return false; - } - newString [converterCount] = 0; - free (buffer16); - buffer16 = newString; - updateLength (); - return true; -#else - return false; -#endif - -#elif SMTG_OS_MACOS - CFMutableStringRef origStr = (CFMutableStringRef)toCFStringRef (0xFFFF, true); - if (origStr) - { - CFStringNormalizationForm normForm = kCFStringNormalizationFormD; - switch (n) - { - case kUnicodeNormC: normForm = kCFStringNormalizationFormC; break; - case kUnicodeNormD: normForm = kCFStringNormalizationFormD; break; - case kUnicodeNormKC: normForm = kCFStringNormalizationFormKC; break; - case kUnicodeNormKD: normForm = kCFStringNormalizationFormKD; break; - } - CFStringNormalize (origStr, normForm); - bool result = fromCFStringRef (origStr); - CFRelease (origStr); - return result; - } - return false; -#else - return false; -#endif -} - -//----------------------------------------------------------------------------- -void String::tryFreeBuffer () -{ - if (buffer) - { - free (buffer); - buffer = nullptr; - } -} - -//----------------------------------------------------------------------------- -bool String::resize (uint32 newLength, bool wide, bool fill) -{ - if (newLength == 0) - { - tryFreeBuffer (); - len = 0; - isWide = wide ? 1 : 0; - } - else - { - size_t newCharSize = wide ? sizeof (char16) : sizeof (char8); - size_t oldCharSize = (isWide != 0) ? sizeof (char16) : sizeof (char8); - - size_t newBufferSize = (newLength + 1) * newCharSize; - size_t oldBufferSize = (len + 1) * oldCharSize; - - isWide = wide ? 1 : 0; - - if (buffer) - { - if (newBufferSize != oldBufferSize) - { - void* newstr = realloc (buffer, newBufferSize); - if (newstr == nullptr) - return false; - buffer = newstr; - if (isWide) - buffer16[newLength] = 0; - else - buffer8[newLength] = 0; - } - else if (wide && newCharSize != oldCharSize) - buffer16[newLength] = 0; - } - else - { - void* newstr = malloc (newBufferSize); - if (newstr == nullptr) - return false; - buffer = newstr; - if (isWide) - { - buffer16[0] = 0; - buffer16[newLength] = 0; - } - else - { - buffer8[0] = 0; - buffer8[newLength] = 0; - } - } - - if (fill && len < newLength && buffer) - { - if (isWide) - { - char16 c = ' '; - for (uint32 i = len; i < newLength; i++) - buffer16 [i] = c; - } - else - { - memset (buffer8 + len, ' ', newLength - len); - } - } - } - return true; -} - -//----------------------------------------------------------------------------- -bool String::setChar8 (uint32 index, char8 c) -{ - if (index == len && c == 0) - return true; - - if (index >= len) - { - if (c == 0) - { - if (resize (index, isWide, true) == false) - return false; - len = index; - return true; - } - else - { - if (resize (index + 1, isWide, true) == false) - return false; - len = index + 1; - } - } - - if (index < len && buffer) - { - if (isWide) - { - if (c == 0) - buffer16[index] = 0; - else - { - char8 src[] = {c, 0}; - char16 dest[8] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - buffer16[index] = dest[0]; - } - SMTG_ASSERT (buffer16[len] == 0) - } - else - { - buffer8[index] = c; - SMTG_ASSERT (buffer8[len] == 0) - } - - if (c == 0) - updateLength (); - - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -bool String::setChar16 (uint32 index, char16 c) -{ - if (index == len && c == 0) - return true; - - if (index >= len) - { - if (c == 0) - { - if (resize (index, isWide, true) == false) - return false; - len = index; - return true; - } - else - { - if (resize (index + 1, isWide, true) == false) - return false; - len = index + 1; - } - } - - if (index < len && buffer) - { - if (isWide) - { - buffer16[index] = c; - SMTG_ASSERT (buffer16[len] == 0) - } - else - { - SMTG_ASSERT (buffer8[len] == 0) - char16 src[] = {c, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - buffer8[index] = dest[0]; - else - return false; - } - - if (c == 0) - updateLength (); - - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -String& String::assign (const ConstString& str, int32 n) -{ - if (str.isWideString ()) - return assign (str.text16 (), n < 0 ? str.length () : n); - else - return assign (str.text8 (), n < 0 ? str.length () : n); -} - -//----------------------------------------------------------------------------- -String& String::assign (const char8* str, int32 n, bool isTerminated) -{ - if (str == buffer8) - return *this; - - if (isTerminated) - { - uint32 stringLength = (uint32)((str) ? strlen (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - } - else if (n < 0) - return *this; - - if (resize (n, false)) - { - if (buffer8 && n > 0 && str) - { - memcpy (buffer8, str, n * sizeof (char8)); - SMTG_ASSERT (buffer8[n] == 0) - } - isWide = 0; - len = n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::assign (const char16* str, int32 n, bool isTerminated) -{ - if (str == buffer16) - return *this; - - if (isTerminated) - { - uint32 stringLength = (uint32)((str) ? strlen16 (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - } - else if (n < 0) - return *this; - - if (resize (n, true)) - { - if (buffer16 && n > 0 && str) - { - memcpy (buffer16, str, n * sizeof (char16)); - SMTG_ASSERT (buffer16[n] == 0) - } - isWide = 1; - len = n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::assign (char8 c, int32 n) -{ - if (resize (n, false)) - { - if (buffer8 && n > 0) - { - memset (buffer8, c, n * sizeof (char8)); - SMTG_ASSERT (buffer8[n] == 0) - } - isWide = 0; - len = n; - } - return *this; - -} - -//----------------------------------------------------------------------------- -String& String::assign (char16 c, int32 n) -{ - if (resize (n, true)) - { - if (buffer && n > 0) - { - for (int32 i = 0; i < n; i++) - buffer16[i] = c; - SMTG_ASSERT (buffer16[n] == 0) - } - isWide = 1; - len = n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::append (const ConstString& str, int32 n) -{ - if (str.isWideString ()) - return append (str.text16 (), n); - else - return append (str.text8 (), n); -} - -//----------------------------------------------------------------------------- -String& String::append (const char8* str, int32 n) -{ - if (str == buffer8) - return *this; - - if (len == 0) - return assign (str, n); - - if (isWide) - { - String tmp (str); - if (tmp.toWideString () == false) - return *this; - - return append (tmp.buffer16, n); - } - - uint32 stringLength = (uint32)((str) ? strlen (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (n > 0) - { - int32 newlen = n + len; - if (!resize (newlen, false)) - return *this; - - if (buffer && str) - { - memcpy (buffer8 + len, str, n * sizeof (char8)); - SMTG_ASSERT (buffer8[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::append (const char16* str, int32 n) -{ - if (str == buffer16) - return *this; - - if (len == 0) - return assign (str, n); - - if (!isWide) - { - if (toWideString () == false) - return *this; - } - - uint32 stringLength = (uint32)((str) ? strlen16 (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (n > 0) - { - int32 newlen = n + len; - if (!resize (newlen, true)) - return *this; - - if (buffer16 && str) - { - memcpy (buffer16 + len, str, n * sizeof (char16)); - SMTG_ASSERT (buffer16[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::append (const char8 c, int32 n) -{ - char8 str[] = {c, 0}; - if (n == 1) - { - return append (str, 1); - } - else if (n > 1) - { - if (isWide) - { - String tmp (str); - if (tmp.toWideString () == false) - return *this; - - return append (tmp.buffer16[0], n); - } - - int32 newlen = n + len; - if (!resize (newlen, false)) - return *this; - - if (buffer) - { - memset (buffer8 + len, c, n * sizeof (char8)); - SMTG_ASSERT (buffer8[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::append (const char16 c, int32 n) -{ - if (n == 1) - { - char16 str[] = {c, 0}; - return append (str, 1); - } - else if (n > 1) - { - if (!isWide) - { - if (toWideString () == false) - return *this; - } - - int32 newlen = n + len; - if (!resize (newlen, true)) - return *this; - - if (buffer16) - { - for (int32 i = len; i < newlen; i++) - buffer16[i] = c; - SMTG_ASSERT (buffer16[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::insertAt (uint32 idx, const ConstString& str, int32 n) -{ - if (str.isWideString ()) - return insertAt (idx, str.text16 (), n); - else - return insertAt (idx, str.text8 (), n); -} - -//----------------------------------------------------------------------------- -String& String::insertAt (uint32 idx, const char8* str, int32 n) -{ - if (idx > len) - return *this; - - if (isWide) - { - String tmp (str); - if (tmp.toWideString () == false) - return *this; - return insertAt (idx, tmp.buffer16, n); - } - - uint32 stringLength = (uint32)((str) ? strlen (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (n > 0) - { - int32 newlen = len + n; - if (!resize (newlen, false)) - return *this; - - if (buffer && str) - { - if (idx < len) - memmove (buffer8 + idx + n, buffer8 + idx, (len - idx) * sizeof (char8)); - memcpy (buffer8 + idx, str, n * sizeof (char8)); - SMTG_ASSERT (buffer8[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::insertAt (uint32 idx, const char16* str, int32 n) -{ - if (idx > len) - return *this; - - if (!isWide) - { - if (toWideString () == false) - return *this; - } - - uint32 stringLength = (uint32)((str) ? strlen16 (str) : 0); - n = n < 0 ? stringLength : Min (n, stringLength); - - if (n > 0) - { - int32 newlen = len + n; - if (!resize (newlen, true)) - return *this; - - if (buffer && str) - { - if (idx < len) - memmove (buffer16 + idx + n, buffer16 + idx, (len - idx) * sizeof (char16)); - memcpy (buffer16 + idx, str, n * sizeof (char16)); - SMTG_ASSERT (buffer16[newlen] == 0) - } - - len += n; - } - return *this; -} - -//----------------------------------------------------------------------------- -String& String::replace (uint32 idx, int32 n1, const ConstString& str, int32 n2) -{ - if (str.isWideString ()) - return replace (idx, n1, str.text16 (), n2); - else - return replace (idx, n1, str.text8 (), n2); -} - -// "replace" replaces n1 number of characters at the specified index with -// n2 characters from the specified string. -//----------------------------------------------------------------------------- -String& String::replace (uint32 idx, int32 n1, const char8* str, int32 n2) -{ - if (idx > len || str == nullptr) - return *this; - - if (isWide) - { - String tmp (str); - if (tmp.toWideString () == false) - return *this; - if (tmp.length () == 0 || n2 == 0) - return remove (idx, n1); - return replace (idx, n1, tmp.buffer16, n2); - } - - if (n1 < 0 || idx + n1 > len) - n1 = len - idx; - if (n1 == 0) - return *this; - - uint32 stringLength = (uint32)((str) ? strlen (str) : 0); - n2 = n2 < 0 ? stringLength : Min (n2, stringLength); - - uint32 newlen = len - n1 + n2; - if (newlen > len) - if (!resize (newlen, false)) - return *this; - - if (buffer) - { - memmove (buffer8 + idx + n2, buffer8 + idx + n1, (len - (idx + n1)) * sizeof (char8)); - memcpy (buffer8 + idx, str, n2 * sizeof (char8)); - buffer8[newlen] = 0; // cannot be removed because resize is not called called in all cases (newlen > len) - } - - len = newlen; - - return *this; -} - -//----------------------------------------------------------------------------- -String& String::replace (uint32 idx, int32 n1, const char16* str, int32 n2) -{ - if (idx > len || str == nullptr) - return *this; - - if (!isWide) - { - if (toWideString () == false) - return *this; - } - - if (n1 < 0 || idx + n1 > len) - n1 = len - idx; - if (n1 == 0) - return *this; - - uint32 stringLength = (uint32)((str) ? strlen16 (str) : 0); - n2 = n2 < 0 ? stringLength : Min (n2, stringLength); - - uint32 newlen = len - n1 + n2; - if (newlen > len) - if (!resize (newlen, true)) - return *this; - - if (buffer) - { - memmove (buffer16 + idx + n2, buffer16 + idx + n1, (len - (idx + n1)) * sizeof (char16)); - memcpy (buffer16 + idx, str, n2 * sizeof (char16)); - buffer16[newlen] = 0; // cannot be removed because resize is not called called in all cases (newlen > len) - } - - len = newlen; - - return *this; -} - -//----------------------------------------------------------------------------- -int32 String::replace (const char8* toReplace, const char8* toReplaceWith, bool all, CompareMode m) -{ - if (toReplace == nullptr || toReplaceWith == nullptr) - return 0; - - int32 result = 0; - - int32 idx = findFirst (toReplace, -1, m); - if (idx > -1) - { - int32 toReplaceLen = static_cast (strlen (toReplace)); - int32 toReplaceWithLen = static_cast (strlen (toReplaceWith)); - while (idx > -1) - { - replace (idx, toReplaceLen, toReplaceWith, toReplaceWithLen); - result++; - - if (all) - idx = findNext (idx + toReplaceWithLen , toReplace, -1, m); - else - break; - } - } - - return result; -} - -//----------------------------------------------------------------------------- -int32 String::replace (const char16* toReplace, const char16* toReplaceWith, bool all, CompareMode m) -{ - if (toReplace == nullptr || toReplaceWith == nullptr) - return 0; - - int32 result = 0; - - int32 idx = findFirst (toReplace, -1, m); - if (idx > -1) - { - int32 toReplaceLen = strlen16 (toReplace); - int32 toReplaceWithLen = strlen16 (toReplaceWith); - while (idx > -1) - { - replace (idx, toReplaceLen, toReplaceWith, toReplaceWithLen); - result++; - - if (all) - idx = findNext (idx + toReplaceWithLen, toReplace, -1, m); - else - break; - } - } - return result; -} - -//----------------------------------------------------------------------------- -template -static bool performReplace (T* str, const T* toReplace, T toReplaceBy) -{ - bool anyReplace = false; - T* p = str; - while (*p) - { - const T* rep = toReplace; - while (*rep) - { - if (*p == *rep) - { - *p = toReplaceBy; - anyReplace = true; - break; - } - rep++; - } - p++; - } - return anyReplace; -} - -//----------------------------------------------------------------------------- -bool String::replaceChars8 (const char8* toReplace, char8 toReplaceBy) -{ - if (isEmpty ()) - return false; - - if (isWide) - { - String toReplaceW (toReplace); - if (toReplaceW.toWideString () == false) - return false; - - char8 src[] = {toReplaceBy, 0}; - char16 dest[2] = {0}; - if (multiByteToWideString (dest, src, 2) > 0) - { - return replaceChars16 (toReplaceW.text16 (), dest[0]); - } - return false; - } - - if (toReplaceBy == 0) - toReplaceBy = ' '; - - return performReplace (buffer8, toReplace, toReplaceBy); -} - -//----------------------------------------------------------------------------- -bool String::replaceChars16 (const char16* toReplace, char16 toReplaceBy) -{ - if (isEmpty ()) - return false; - - if (!isWide) - { - String toReplaceA (toReplace); - if (toReplaceA.toMultiByte () == false) - return false; - - if (toReplaceA.length () > 1) - { - SMTG_WARNING("cannot replace non ASCII chars on non Wide String") - return false; - } - - char16 src[] = {toReplaceBy, 0}; - char8 dest[8] = {0}; - if (wideStringToMultiByte (dest, src, 2) > 0 && dest[1] == 0) - return replaceChars8 (toReplaceA.text8 (), dest[0]); - - return false; - } - - if (toReplaceBy == 0) - toReplaceBy = STR16 (' '); - - return performReplace (buffer16, toReplace, toReplaceBy); -} - -// "remove" removes the specified number of characters from the string -// starting at the specified index. -//----------------------------------------------------------------------------- -String& String::remove (uint32 idx, int32 n) -{ - if (isEmpty () || idx >= len || n == 0) - return *this; - - if ((idx + n > len) || n < 0) - n = len - idx; - else - { - int32 toMove = len - idx - n; - if (buffer) - { - if (isWide) - memmove (buffer16 + idx, buffer16 + idx + n, toMove * sizeof (char16)); - else - memmove (buffer8 + idx, buffer8 + idx + n, toMove * sizeof (char8)); - } - } - - resize (len - n, isWide); - updateLength (); - - return *this; -} - -//----------------------------------------------------------------------------- -bool String::removeSubString (const ConstString& subString, bool allOccurences) -{ - bool removed = false; - while (!removed || allOccurences) - { - int32 idx = findFirst (subString); - if (idx < 0) - break; - remove (idx, subString.length ()); - removed = true; - } - return removed; -} - -//----------------------------------------------------------------------------- -template -static uint32 performTrim (T* str, uint32 length, F func, bool funcResult) -{ - uint32 toRemoveAtHead = 0; - uint32 toRemoveAtTail = 0; - - T* p = str; - - while ((*p) && ((func (*p) != 0) == funcResult)) - p++; - - toRemoveAtHead = static_cast (p - str); - - if (toRemoveAtHead < length) - { - p = str + length - 1; - - while (((func (*p) != 0) == funcResult) && (p > str)) - { - p--; - toRemoveAtTail++; - } - } - - uint32 newLength = length - (toRemoveAtHead + toRemoveAtTail); - if (newLength != length) - { - if (toRemoveAtHead) - memmove (str, str + toRemoveAtHead, newLength * sizeof (T)); - } - return newLength; -} - -// "trim" trims the leading and trailing unwanted characters from the string. -//----------------------------------------------------------------------------- -bool String::trim (String::CharGroup group) -{ - if (isEmpty ()) - return false; - - uint32 newLength; - - switch (group) - { - case kSpace: - if (isWide) - newLength = performTrim (buffer16, len, iswspace, true); - else - newLength = performTrim (buffer8, len, isspace, true); - break; - - case kNotAlphaNum: - if (isWide) - newLength = performTrim (buffer16, len, iswalnum, false); - else - newLength = performTrim (buffer8, len, isalnum, false); - break; - - case kNotAlpha: - if (isWide) - newLength = performTrim (buffer16, len, iswalpha, false); - else - newLength = performTrim (buffer8, len, isalpha, false); - break; - - default: // Undefined enum value - return false; - } - - if (newLength != len) - { - resize (newLength, isWide); - len = newLength; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -template -static uint32 performRemove (T* str, uint32 length, F func, bool funcResult) -{ - T* p = str; - - while (*p) - { - if ((func (*p) != 0) == funcResult) - { - size_t toMove = length - (p - str); - memmove (p, p + 1, toMove * sizeof (T)); - length--; - } - else - p++; - } - return length; -} -//----------------------------------------------------------------------------- -void String::removeChars (CharGroup group) -{ - if (isEmpty ()) - return; - - uint32 newLength; - - switch (group) - { - case kSpace: - if (isWide) - newLength = performRemove (buffer16, len, iswspace, true); - else - newLength = performRemove (buffer8, len, isspace, true); - break; - - case kNotAlphaNum: - if (isWide) - newLength = performRemove (buffer16, len, iswalnum, false); - else - newLength = performRemove (buffer8, len, isalnum, false); - break; - - case kNotAlpha: - if (isWide) - newLength = performRemove (buffer16, len, iswalpha, false); - else - newLength = performRemove (buffer8, len, isalpha, false); - break; - - default: // Undefined enum value - return; - } - - if (newLength != len) - { - resize (newLength, isWide); - len = newLength; - } -} - -//----------------------------------------------------------------------------- -template -static uint32 performRemoveChars (T* str, uint32 length, const T* toRemove) -{ - T* p = str; - - while (*p) - { - bool found = false; - const T* rem = toRemove; - while (*rem) - { - if (*p == *rem) - { - found = true; - break; - } - rem++; - } - - if (found) - { - size_t toMove = length - (p - str); - memmove (p, p + 1, toMove * sizeof (T)); - length--; - } - else - p++; - } - return length; -} - -//----------------------------------------------------------------------------- -bool String::removeChars8 (const char8* toRemove) -{ - if (isEmpty () || toRemove == nullptr) - return true; - - if (isWide) - { - String wStr (toRemove); - if (wStr.toWideString () == false) - return false; - return removeChars16 (wStr.text16 ()); - } - - uint32 newLength = performRemoveChars (buffer8, len, toRemove); - - if (newLength != len) - { - resize (newLength, false); - len = newLength; - } - return true; -} - -//----------------------------------------------------------------------------- -bool String::removeChars16 (const char16* toRemove) -{ - if (isEmpty () || toRemove == nullptr) - return true; - - if (!isWide) - { - String str8 (toRemove); - if (str8.toMultiByte () == false) - return false; - return removeChars8 (str8.text8 ()); - } - - uint32 newLength = performRemoveChars (buffer16, len, toRemove); - - if (newLength != len) - { - resize (newLength, true); - len = newLength; - } - return true; -} - -//----------------------------------------------------------------------------- -String& String::printf (const char8* format, ...) -{ - char8 string[kPrintfBufferSize]; - - va_list marker; - va_start (marker, format); - - vsnprintf (string, kPrintfBufferSize-1, format, marker); - return assign (string); -} - - -//----------------------------------------------------------------------------- -String& String::printf (const char16* format, ...) -{ - char16 string[kPrintfBufferSize]; - - va_list marker; - va_start (marker, format); - - vsnwprintf (string, kPrintfBufferSize-1, format, marker); - return assign (string); -} - -//----------------------------------------------------------------------------- -String& String::vprintf (const char8* format, va_list args) -{ - char8 string[kPrintfBufferSize]; - - vsnprintf (string, kPrintfBufferSize-1, format, args); - return assign (string); -} - -//----------------------------------------------------------------------------- -String& String::vprintf (const char16* format, va_list args) -{ - char16 string[kPrintfBufferSize]; - - vsnwprintf (string, kPrintfBufferSize-1, format, args); - return assign (string); -} - -//----------------------------------------------------------------------------- -String& String::printInt64 (int64 value) -{ - if (isWide) - { - #if SMTG_CPP11 - return String::printf (STR("%") STR(FORMAT_INT64A), value); - #else - return String::printf (STR("%" FORMAT_INT64A), value); - #endif - } - else - return String::printf ("%" FORMAT_INT64A, value); -} - -//----------------------------------------------------------------------------- -String& String::printFloat (double value) -{ - if (isWide) - { - char16 string[kPrintfBufferSize]; - sprintf16 (string, STR16 ("%lf"), value); - - char16* pointPtr = strrchr16 (string, STR ('.')); - if (pointPtr) - { - pointPtr++; // keep 1st digit after point - int32 index = strlen16 (string) - 1; - char16 zero = STR16 ('0'); - while (pointPtr < (string + index)) - { - if (string[index] == zero) - { - string[index] = 0; - index--; - } - else - break; - } - } - return assign (string); - } - else - { - char8 string[kPrintfBufferSize]; - sprintf (string, "%lf", value); - - char8* pointPtr = strrchr (string, '.'); - if (pointPtr) - { - pointPtr++; // keep 1st digit after point - int32 index = (int32) (strlen (string) - 1); - while (pointPtr < (string + index)) - { - if (string[index] == '0') - { - string[index] = 0; - index--; - } - else - break; - } - } - return assign (string); - } -} - -//----------------------------------------------------------------------------- -bool String::incrementTrailingNumber (uint32 width, tchar separator, uint32 minNumber, bool applyOnlyFormat) -{ - if (width > 32) - return false; - - int64 number = 1; - int32 index = getTrailingNumberIndex (); - if (index >= 0) - { - if (scanInt64 (number, index)) - if (!applyOnlyFormat) - number++; - - if (separator != 0 && index > 0 && testChar (index - 1, separator) == true) - index--; - - remove (index); - } - - if (number < minNumber) - number = minNumber; - - if (isWide) - { - char16 format[64]; - char16 trail[128]; - if (separator && isEmpty () == false) - { - sprintf16 (format, STR16 ("%%c%%0%uu"), width); - sprintf16 (trail, format, separator, (uint32) number); - } - else - { - sprintf16 (format, STR16 ("%%0%uu"), width); - sprintf16 (trail, format, (uint32) number); - } - append (trail); - } - else - { - char format[64]; - char trail[128]; - if (separator && isEmpty () == false) - { - sprintf (format, "%%c%%0%uu", width); - sprintf (trail, format, separator, (uint32) number); - } - else - { - sprintf (format, "%%0%uu", width); - sprintf (trail, format, (uint32) number); - } - append (trail); - } - - return true; -} - -//----------------------------------------------------------------------------- -void String::toLower (uint32 index) -{ - if (buffer && index < len) - { - if (isWide) - buffer16[index] = ConstString::toLower (buffer16[index]); - else - buffer8[index] = ConstString::toLower (buffer8[index]); - } -} - -//----------------------------------------------------------------------------- -void String::toLower () -{ - int32 i = len; - if (buffer && i > 0) - { - if (isWide) - { -#if SMTG_OS_MACOS - CFMutableStringRef cfStr = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocator, (UniChar*)buffer16, len, len+1, kCFAllocatorNull); - CFStringLowercase (cfStr, NULL); - CFRelease (cfStr); -#else - char16* c = buffer16; - while (i--) - { - *c = ConstString::toLower (*c); - c++; - } -#endif - } - else - { - char8* c = buffer8; - while (i--) - { - *c = ConstString::toLower (*c); - c++; - } - } - } -} - -//----------------------------------------------------------------------------- -void String::toUpper (uint32 index) -{ - if (buffer && index < len) - { - if (isWide) - buffer16[index] = ConstString::toUpper (buffer16[index]); - else - buffer8[index] = ConstString::toUpper (buffer8[index]); - } -} - -//----------------------------------------------------------------------------- -void String::toUpper () -{ - int32 i = len; - if (buffer && i > 0) - { - if (isWide) - { -#if SMTG_OS_MACOS - CFMutableStringRef cfStr = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocator, (UniChar*)buffer16, len, len+1, kCFAllocatorNull); - CFStringUppercase (cfStr, NULL); - CFRelease (cfStr); -#else - char16* c = buffer16; - while (i--) - { - *c = ConstString::toUpper (*c); - c++; - } -#endif - } - else - { - char8* c = buffer8; - while (i--) - { - *c = ConstString::toUpper (*c); - c++; - } - } - } -} - -//----------------------------------------------------------------------------- -bool String::fromVariant (const FVariant& var) -{ - switch (var.getType ()) - { - case FVariant::kString8: - assign (var.getString8 ()); - return true; - - case FVariant::kString16: - assign (var.getString16 ()); - return true; - - case FVariant::kFloat: - printFloat (var.getFloat ()); - return true; - - case FVariant::kInteger: - printInt64 (var.getInt ()); - return true; - - default: - remove (); - } - return false; -} - -//----------------------------------------------------------------------------- -void String::toVariant (FVariant& var) const -{ - if (isWide) - { - var.setString16 (text16 ()); - } - else - { - var.setString8 (text8 ()); - } -} - -//----------------------------------------------------------------------------- -bool String::fromAttributes (IAttributes* a, IAttrID attrID) -{ - FVariant variant; - if (a->get (attrID, variant) == kResultTrue) - return fromVariant (variant); - return false; -} - -//----------------------------------------------------------------------------- -bool String::toAttributes (IAttributes* a, IAttrID attrID) -{ - FVariant variant; - toVariant (variant); - if (a->set (attrID, variant) == kResultTrue) - return true; - return false; -} - -// "swapContent" swaps ownership of the strings pointed to -//----------------------------------------------------------------------------- -void String::swapContent (String& s) -{ - void* tmp = s.buffer; - uint32 tmpLen = s.len; - bool tmpWide = s.isWide; - s.buffer = buffer; - s.len = len; - s.isWide = isWide; - buffer = tmp; - len = tmpLen; - isWide = tmpWide; -} - -//----------------------------------------------------------------------------- -void String::take (String& other) -{ - resize (0, other.isWide); - buffer = other.buffer; - len = other.len; - - other.buffer = nullptr; - other.len = 0; -} - -//----------------------------------------------------------------------------- -void String::take (void* b, bool wide) -{ - resize (0, wide); - buffer = b; - isWide = wide; - updateLength (); -} - -//----------------------------------------------------------------------------- -void* String::pass () -{ - void* res = buffer; - len = 0; - buffer = nullptr; - return res; -} - -//----------------------------------------------------------------------------- -void String::passToVariant (FVariant& var) -{ - void* passed = pass (); - - if (isWide) - { - if (passed) - { - var.setString16 ((const char16*)passed); - var.setOwner (true); - } - else - var.setString16 (kEmptyString16); - } - else - { - if (passed) - { - var.setString8 ((const char8*)passed); - var.setOwner (true); - } - else - var.setString8 (kEmptyString8); - } -} - - -//----------------------------------------------------------------------------- -unsigned char* String::toPascalString (unsigned char* buf) -{ - if (buffer) - { - if (isWide) - { - String tmp (*this); - tmp.toMultiByte (); - return tmp.toPascalString (buf); - } - - int32 length = len; - if (length > 255) - length = 255; - buf[0] = (uint8)length; - while (length >= 0) - { - buf[length + 1] = buffer8[length]; - length--; - } - return buf; - } - else - { - *buf = 0; - return buf; - } -} - -//----------------------------------------------------------------------------- -const String& String::fromPascalString (const unsigned char* buf) -{ - resize (0, false); - isWide = 0; - int32 length = buf[0]; - resize (length + 1, false); - buffer8[length] = 0; // cannot be removed, because we only do the 0-termination for multibyte buffer8 - while (--length >= 0) - buffer8[length] = buf[length + 1]; - len = buf[0]; - return *this; -} - -#if SMTG_OS_MACOS - -//----------------------------------------------------------------------------- -bool String::fromCFStringRef (const void* cfStr, uint32 encoding) -{ - if (cfStr == 0) - return false; - - CFStringRef strRef = (CFStringRef)cfStr; - if (isWide) - { - CFRange range = { 0, CFStringGetLength (strRef)}; - CFIndex usedBytes; - if (resize (static_cast (range.length + 1), true)) - { - if (encoding == 0xFFFF) - encoding = kCFStringEncodingUnicode; - if (CFStringGetBytes (strRef, range, encoding, ' ', false, (UInt8*)buffer16, range.length * 2, &usedBytes) > 0) - { - buffer16[usedBytes/2] = 0; - this->len = strlen16 (buffer16); - return true; - } - } - } - else - { - if (cfStr == 0) - return false; - if (encoding == 0xFFFF) - encoding = kCFStringEncodingASCII; - int32 len = static_cast (CFStringGetLength (strRef) * 2); - if (resize (++len, false)) - { - if (CFStringGetCString (strRef, buffer8, len, encoding)) - { - this->len = static_cast (strlen (buffer8)); - return true; - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- -void* ConstString::toCFStringRef (uint32 encoding, bool mutableCFString) const -{ - if (mutableCFString) - { - CFMutableStringRef str = CFStringCreateMutable (kCFAllocator, 0); - if (isWide) - { - CFStringAppendCharacters (str, (const UniChar *)buffer16, len); - return str; - } - else - { - if (encoding == 0xFFFF) - encoding = kCFStringEncodingASCII; - CFStringAppendCString (str, buffer8, encoding); - return str; - } - } - else - { - if (isWide) - { - if (encoding == 0xFFFF) - encoding = kCFStringEncodingUnicode; - return (void*)CFStringCreateWithBytes (kCFAllocator, (const unsigned char*)buffer16, len * 2, encoding, false); - } - else - { - if (encoding == 0xFFFF) - encoding = kCFStringEncodingASCII; - if (buffer8) - return (void*)CFStringCreateWithCString (kCFAllocator, buffer8, encoding); - else - return (void*)CFStringCreateWithCString (kCFAllocator, "", encoding); - } - } - return 0; -} - -#endif - -//----------------------------------------------------------------------------- -uint32 hashString8 (const char8* s, uint32 m) -{ - uint32 h = 0; - if (s) - { - for (h = 0; *s != '\0'; s++) - h = (64 * h + *s) % m; - } - return h; -} - -//----------------------------------------------------------------------------- -uint32 hashString16 (const char16* s, uint32 m) -{ - uint32 h = 0; - if (s) - { - for (h = 0; *s != 0; s++) - h = (64 * h + *s) % m; - } - return h; -} - -//------------------------------------------------------------------------ -template int32 tstrnatcmp (const T* s1, const T* s2, bool caseSensitive = true) -{ - if (s1 == nullptr && s2 == nullptr) - return 0; - else if (s1 == nullptr) - return -1; - else if (s2 == nullptr) - return 1; - - while (*s1 && *s2) - { - if (ConstString::isCharDigit (*s1) && ConstString::isCharDigit (*s2)) - { - int32 s1LeadingZeros = 0; - while (*s1 == '0') - { - s1++; // skip leading zeros - s1LeadingZeros++; - } - int32 s2LeadingZeros = 0; - while (*s2 == '0') - { - s2++; // skip leading zeros - s2LeadingZeros++; - } - - int32 countS1Digits = 0; - while (*(s1 + countS1Digits) && ConstString::isCharDigit (*(s1 + countS1Digits))) - countS1Digits++; - int32 countS2Digits = 0; - while (*(s2 + countS2Digits) && ConstString::isCharDigit (*(s2 + countS2Digits))) - countS2Digits++; - - if (countS1Digits != countS2Digits) - return countS1Digits - countS2Digits; // one number is longer than the other - - for (int32 i = 0; i < countS1Digits; i++) - { - // countS1Digits == countS2Digits - if (*s1 != *s2) - return (int32)(*s1 - *s2); // the digits differ - s1++; - s2++; - } - - if (s1LeadingZeros != s2LeadingZeros) - return s1LeadingZeros - s2LeadingZeros; // differentiate by the number of leading zeros - } - else - { - if (caseSensitive == false) - { - T srcToUpper = static_cast (toupper (*s1)); - T dstToUpper = static_cast (toupper (*s2)); - if (srcToUpper != dstToUpper) - return (int32)(srcToUpper - dstToUpper); - } - else if (*s1 != *s2) - return (int32)(*s1 - *s2); - - s1++; - s2++; - } - } - - if (*s1 == 0 && *s2 == 0) - return 0; - else if (*s1 == 0) - return -1; - else if (*s2 == 0) - return 1; - else - return (int32)(*s1 - *s2); -} - -//------------------------------------------------------------------------ -int32 strnatcmp8 (const char8* s1, const char8* s2, bool caseSensitive /*= true*/) -{ - return tstrnatcmp (s1, s2, caseSensitive); -} - -//------------------------------------------------------------------------ -int32 strnatcmp16 (const char16* s1, const char16* s2, bool caseSensitive /*= true*/) -{ - return tstrnatcmp (s1, s2, caseSensitive); -} - -//----------------------------------------------------------------------------- -// StringObject Implementation -//----------------------------------------------------------------------------- -void PLUGIN_API StringObject::setText (const char8* text) -{ - assign (text); -} - -//----------------------------------------------------------------------------- -void PLUGIN_API StringObject::setText8 (const char8* text) -{ - assign (text); -} - -//----------------------------------------------------------------------------- -void PLUGIN_API StringObject::setText16 (const char16* text) -{ - assign (text); -} - -//----------------------------------------------------------------------------- -const char8* PLUGIN_API StringObject::getText8 () -{ - return text8 (); -} - -//----------------------------------------------------------------------------- -const char16* PLUGIN_API StringObject::getText16 () -{ - return text16 (); -} - -//----------------------------------------------------------------------------- -void PLUGIN_API StringObject::take (void* s, bool _isWide) -{ - String::take (s, _isWide); -} - -//----------------------------------------------------------------------------- -bool PLUGIN_API StringObject::isWideString () const -{ - return String::isWideString (); -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/fstring.h b/source/includes/vst3sdk/base/source/fstring.h deleted file mode 100644 index 80ff82acf..000000000 --- a/source/includes/vst3sdk/base/source/fstring.h +++ /dev/null @@ -1,748 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/fstring.h -// Created by : Steinberg, 2008 -// Description : String class -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/ftypes.h" -#include "pluginterfaces/base/fstrdefs.h" -#include "pluginterfaces/base/istringresult.h" -#include "pluginterfaces/base/ipersistent.h" - -#include "base/source/fobject.h" - -#include - -namespace Steinberg { - -class FVariant; -class String; - -#ifdef UNICODE -static const bool kWideStringDefault = true; -#else -static const bool kWideStringDefault = false; -#endif - -static const uint16 kBomUtf16 = 0xFEFF; ///< UTF16 Byte Order Mark -static const char8* const kBomUtf8 = "\xEF\xBB\xBF"; ///< UTF8 Byte Order Mark -static const int32 kBomUtf8Length = 3; - - -enum MBCodePage -{ - kCP_ANSI = 0, ///< Default ANSI codepage. - kCP_MAC_ROMAN = 2, ///< Default Mac codepage. - - kCP_ANSI_WEL = 1252, ///< West European Latin Encoding. - kCP_MAC_CEE = 10029, ///< Mac Central European Encoding. - kCP_Utf8 = 65001, ///< UTF8 Encoding. - kCP_ShiftJIS = 932, ///< Shifted Japan Industrial Standard Encoding. - kCP_US_ASCII = 20127, ///< US-ASCII (7-bit). - - kCP_Default = kCP_ANSI ///< Default ANSI codepage. -}; - -enum UnicodeNormalization -{ - kUnicodeNormC, ///< Unicode normalization Form C, canonical composition. - kUnicodeNormD, ///< Unicode normalization Form D, canonical decomposition. - kUnicodeNormKC, ///< Unicode normalization form KC, compatibility composition. - kUnicodeNormKD ///< Unicode normalization form KD, compatibility decomposition. -}; - -//------------------------------------------------------------------------ -// Helper functions to create hash codes from string data. -//------------------------------------------------------------------------ -extern uint32 hashString8 (const char8* s, uint32 m); -extern uint32 hashString16 (const char16* s, uint32 m); -inline uint32 hashString (const tchar* s, uint32 m) -{ -#ifdef UNICODE - return hashString16 (s, m); -#else - return hashString8 (s, m); -#endif -} - - -//----------------------------------------------------------------------------- -/** Invariant String. -@ingroup adt - -A base class which provides methods to work with its -member string. Neither of the operations allows modifying the member string and -that is why all operation are declared as const. - -There are operations for access, comparison, find, numbers and conversion. - -Almost all operations exist in three versions for char8, char16 and the -polymorphic type tchar. The type tchar can either be char8 or char16 depending -on whether UNICODE is activated or not.*/ -//----------------------------------------------------------------------------- -class ConstString -{ -public: -//----------------------------------------------------------------------------- - ConstString (const char8* str, int32 length = -1); ///< Assign from string of type char8 (length=-1: all) - ConstString (const char16* str, int32 length = -1); ///< Assign from string of type char16 (length=-1: all) - ConstString (const ConstString& str, int32 offset = 0, int32 length = -1); ///< Copy constructor (length=-1: all). - ConstString (const FVariant& var); ///< Assign a string from FVariant - ConstString (); - virtual ~ConstString () {} ///< Destructor. - - // access ----------------------------------------------------------------- - virtual int32 length () const {return static_cast (len);} ///< Return length of string - inline bool isEmpty () const {return buffer == nullptr || len == 0;} ///< Return true if string is empty - - operator const char8* () const {return text8 ();} ///< Returns pointer to string of type char8 (no modification allowed) - operator const char16* () const {return text16 ();} ///< Returns pointer to string of type char16(no modification allowed) - inline tchar operator[] (short idx) const {return getChar (static_cast (idx));} ///< Returns character at 'idx' - inline tchar operator[] (long idx) const {return getChar (static_cast (idx));} - inline tchar operator[] (int idx) const {return getChar (static_cast (idx));} - inline tchar operator[] (unsigned short idx) const {return getChar (idx);} - inline tchar operator[] (unsigned long idx) const {return getChar (static_cast (idx));} - inline tchar operator[] (unsigned int idx) const {return getChar (idx);} - - inline virtual const char8* text8 () const; ///< Returns pointer to string of type char8 - inline virtual const char16* text16 () const; ///< Returns pointer to string of type char16 - inline virtual const tchar* text () const; ///< Returns pointer to string of type tchar - inline virtual const void* ptr () const {return buffer;} ///< Returns pointer to string of type void - - inline virtual char8 getChar8 (uint32 index) const; ///< Returns character of type char16 at 'index' - inline virtual char16 getChar16 (uint32 index) const; ///< Returns character of type char8 at 'index' - inline tchar getChar (uint32 index) const; ///< Returns character of type tchar at 'index' - inline tchar getCharAt (uint32 index) const; ///< Returns character of type tchar at 'index', no conversion! - - bool testChar8 (uint32 index, char8 c) const; ///< Returns true if character is equal at position 'index' - bool testChar16 (uint32 index, char16 c) const; - inline bool testChar (uint32 index, char8 c) const {return testChar8 (index, c);} - inline bool testChar (uint32 index, char16 c) const {return testChar16 (index, c);} - - bool extract (String& result, uint32 idx, int32 n = -1) const; ///< Get n characters long substring starting at index (n=-1: until end) - int32 copyTo8 (char8* str, uint32 idx = 0, int32 n = -1) const; - int32 copyTo16 (char16* str, uint32 idx = 0, int32 n = -1) const; - int32 copyTo (tchar* str, uint32 idx = 0, int32 n = -1) const; - void copyTo (IStringResult* result) const; ///< Copies whole member string - void copyTo (IString& string) const; ///< Copies whole member string - - inline uint32 hash (uint32 tsize) const - { - return isWide ? hashString16 (buffer16, tsize) : hashString8 (buffer8, tsize) ; - } - //------------------------------------------------------------------------- - - // compare ---------------------------------------------------------------- - enum CompareMode - { - kCaseSensitive, ///< Comparison is done with regard to character's case - kCaseInsensitive ///< Comparison is done without regard to character's case - }; - - int32 compareAt (uint32 index, const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this starting at index (return: see above) - int32 compare (const ConstString& str, int32 n, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this (return: see above) - int32 compare (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Compare all characters of str with this (return: see above) - - int32 naturalCompare (const ConstString& str, CompareMode mode = kCaseSensitive) const; - - bool startsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this starts with str - bool endsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this ends with str - bool contains (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this contains str - - // static methods - static bool isCharSpace (char8 character); ///< Returns true if character is a space - static bool isCharSpace (char16 character); ///< @copydoc isCharSpace(const char8) - static bool isCharAlpha (char8 character); ///< Returns true if character is an alphabetic character - static bool isCharAlpha (char16 character); ///< @copydoc isCharAlpha(const char8) - static bool isCharAlphaNum (char8 character); ///< Returns true if character is an alphanumeric character - static bool isCharAlphaNum (char16 character); ///< @copydoc isCharAlphaNum(const char8) - static bool isCharDigit (char8 character); ///< Returns true if character is a number - static bool isCharDigit (char16 character); ///< @copydoc isCharDigit(const char8) - static bool isCharAscii (char8 character); ///< Returns true if character is in ASCII range - static bool isCharAscii (char16 character); ///< Returns true if character is in ASCII range - static bool isCharUpper (char8 character); - static bool isCharUpper (char16 character); - static bool isCharLower (char8 character); - static bool isCharLower (char16 character); - //------------------------------------------------------------------------- - - /** @name Find first occurrence of n characters of str in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/ - ///@{ - inline int32 findFirst (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, str, n, m, endIndex);} - inline int32 findFirst (char8 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);} - inline int32 findFirst (char16 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);} - ///@} - /** @name Find next occurrence of n characters of str starting at startIndex in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/ - ///@{ - int32 findNext (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive, int32 endIndex = -1) const; - int32 findNext (int32 startIndex, char8 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const; - int32 findNext (int32 startIndex, char16 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const; - ///@} - /** @name Find previous occurrence of n characters of str starting at startIndex in this (n=-1: all) */ - ///@{ - int32 findPrev (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive) const; - int32 findPrev (int32 startIndex, char8 c, CompareMode = kCaseSensitive) const; - int32 findPrev (int32 startIndex, char16 c, CompareMode = kCaseSensitive) const; - ///@} - - inline int32 findLast (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const {return findPrev (-1, str, n, m);} ///< Find last occurrence of n characters of str in this (n=-1: all) - inline int32 findLast (char8 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);} - inline int32 findLast (char16 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);} - - int32 countOccurences (char8 c, uint32 startIndex, CompareMode = kCaseSensitive) const; ///< Counts occurences of c within this starting at index - int32 countOccurences (char16 c, uint32 startIndex, CompareMode = kCaseSensitive) const; - int32 getFirstDifferent (const ConstString& str, CompareMode = kCaseSensitive) const; ///< Returns position of first different character - //------------------------------------------------------------------------- - - // numbers ---------------------------------------------------------------- - bool isDigit (uint32 index) const; ///< Returns true if character at position is a digit - bool scanFloat (double& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to double value starting at offset - bool scanInt64 (int64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int64 value starting at offset - bool scanUInt64 (uint64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint64 value starting at offset - bool scanInt32 (int32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int32 value starting at offset - bool scanUInt32 (uint32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint32 value starting at offset - bool scanHex (uint8& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to hex/uint8 value starting at offset - - int32 getTrailingNumberIndex (uint32 width = 0) const; ///< Returns start index of trailing number - int64 getTrailingNumber (int64 fallback = 0) const; ///< Returns result of scanInt64 or the fallback - int64 getNumber () const; ///< Returns result of scanInt64 - - // static methods - static bool scanInt64_8 (const char8* text, int64& value, bool scanToEnd = true); ///< Converts string of type char8 to int64 value - static bool scanInt64_16 (const char16* text, int64& value, bool scanToEnd = true); ///< Converts string of type char16 to int64 value - static bool scanInt64 (const tchar* text, int64& value, bool scanToEnd = true); ///< Converts string of type tchar to int64 value - - static bool scanUInt64_8 (const char8* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char8 to uint64 value - static bool scanUInt64_16 (const char16* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char16 to uint64 value - static bool scanUInt64 (const tchar* text, uint64& value, bool scanToEnd = true); ///< Converts string of type tchar to uint64 value - - static bool scanInt32_8 (const char8* text, int32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value - static bool scanInt32_16 (const char16* text, int32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value - static bool scanInt32 (const tchar* text, int32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value - - static bool scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value - static bool scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value - static bool scanUInt32 (const tchar* text, uint32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value - - static bool scanHex_8 (const char8* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char8 to hex/unit8 value - static bool scanHex_16 (const char16* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char16 to hex/unit8 value - static bool scanHex (const tchar* text, uint8& value, bool scanToEnd = true); ///< Converts string of type tchar to hex/unit8 value - //------------------------------------------------------------------------- - - // conversion ------------------------------------------------------------- - void toVariant (FVariant& var) const; - - static char8 toLower (char8 c); ///< Converts to lower case - static char8 toUpper (char8 c); ///< Converts to upper case - static char16 toLower (char16 c); - static char16 toUpper (char16 c); - - static int32 multiByteToWideString (char16* dest, const char8* source, int32 wcharCount, uint32 sourceCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source - static int32 wideStringToMultiByte (char8* dest, const char16* source, int32 char8Count, uint32 destCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source - - bool isWideString () const {return isWide != 0;} ///< Returns true if string is wide - bool isAsciiString () const; ///< Checks if all characters in string are in ascii range - - bool isNormalized (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working - -#if SMTG_OS_MACOS - virtual void* toCFStringRef (uint32 encoding = 0xFFFF, bool mutableCFString = false) const; ///< CFString conversion -#endif -//------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -protected: - - union - { - void* buffer; - char8* buffer8; - char16* buffer16; - }; - uint32 len : 30; - uint32 isWide : 1; -}; - -//----------------------------------------------------------------------------- -/** String. -@ingroup adt - -Extends class ConstString by operations which allow modifications. - -\see ConstString */ -//----------------------------------------------------------------------------- -class String : public ConstString -{ -public: - -//----------------------------------------------------------------------------- - String (); - String (const char8* str, MBCodePage codepage, int32 n = -1, bool isTerminated = true); ///< assign n characters of str and convert to wide string by using the specified codepage - String (const char8* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all) - String (const char16* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all) - String (const String& str, int32 n = -1); ///< assign n characters of str (-1: all) - String (const ConstString& str, int32 n = -1); ///< assign n characters of str (-1: all) - String (const FVariant& var); ///< assign from FVariant - String (IString* str); ///< assign from IString - ~String (); - -#if SMTG_CPP11_STDLIBSUPPORT - String (String&& str); - String& operator= (String&& str); -#endif - - // access------------------------------------------------------------------ - void updateLength (); ///< Call this when the string is truncated outside (not recommended though) - const char8* text8 () const SMTG_OVERRIDE; - const char16* text16 () const SMTG_OVERRIDE; - char8 getChar8 (uint32 index) const SMTG_OVERRIDE; - char16 getChar16 (uint32 index) const SMTG_OVERRIDE; - - bool setChar8 (uint32 index, char8 c); - bool setChar16 (uint32 index, char16 c); - inline bool setChar (uint32 index, char8 c) {return setChar8 (index, c);} - inline bool setChar (uint32 index, char16 c) {return setChar16 (index, c);} - //------------------------------------------------------------------------- - - // assignment-------------------------------------------------------------- - String& operator= (const char8* str) {return assign (str);} ///< Assign from a string of type char8 - String& operator= (const char16* str) {return assign (str);} - String& operator= (const ConstString& str) {return assign (str);} - String& operator= (const String& str) {return assign (str);} - String& operator= (char8 c) {return assign (c);} - String& operator= (char16 c) {return assign (c);} - - String& assign (const ConstString& str, int32 n = -1); ///< Assign n characters of str (-1: all) - String& assign (const char8* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all) - String& assign (const char16* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all) - String& assign (char8 c, int32 n = 1); - String& assign (char16 c, int32 n = 1); - //------------------------------------------------------------------------- - - // concat------------------------------------------------------------------ - String& append (const ConstString& str, int32 n = -1); ///< Append n characters of str to this (n=-1: all) - String& append (const char8* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all) - String& append (const char16* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all) - String& append (const char8 c, int32 n = 1); ///< Append char c n times - String& append (const char16 c, int32 n = 1); ///< Append char c n times - - String& insertAt (uint32 idx, const ConstString& str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all) - String& insertAt (uint32 idx, const char8* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all) - String& insertAt (uint32 idx, const char16* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all) - String& insertAt (uint32 idx, char8 c) {char8 str[] = {c, 0}; return insertAt (idx, str, 1);} - String& insertAt (uint32 idx, char16 c) {char16 str[] = {c, 0}; return insertAt (idx, str, 1);} - - String& operator+= (const String& str) {return append (str);} - String& operator+= (const ConstString& str) {return append (str);} - String& operator+= (const char8* str) {return append (str);} - String& operator+= (const char16* str) {return append (str);} - String& operator+= (const char8 c) {return append (c);} - String& operator+= (const char16 c) {return append (c);} - //------------------------------------------------------------------------- - - // replace----------------------------------------------------------------- - String& replace (uint32 idx, int32 n1, const ConstString& str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end) - String& replace (uint32 idx, int32 n1, const char8* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end) - String& replace (uint32 idx, int32 n1, const char16* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end) - - int32 replace (const char8* toReplace, const char8* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements - int32 replace (const char16* toReplace, const char16* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements - - bool replaceChars8 (const char8* toReplace, char8 toReplaceBy); ///< Returns true when any replacement was done - bool replaceChars16 (const char16* toReplace, char16 toReplaceBy); - inline bool replaceChars8 (char8 toReplace, char8 toReplaceBy) {char8 str[] = {toReplace, 0}; return replaceChars8 (str, toReplaceBy);} - inline bool replaceChars16 (char16 toReplace, char16 toReplaceBy) {char16 str[] = {toReplace, 0}; return replaceChars16 (str, toReplaceBy);} - inline bool replaceChars (char8 toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);} - inline bool replaceChars (char16 toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);} - inline bool replaceChars (const char8* toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);} - inline bool replaceChars (const char16* toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);} - //------------------------------------------------------------------------- - - // remove------------------------------------------------------------------ - String& remove (uint32 index = 0, int32 n = -1); ///< Remove n characters from string starting at index (n=-1: until end) - enum CharGroup {kSpace, kNotAlphaNum, kNotAlpha}; - bool trim (CharGroup mode = kSpace); ///< Trim lead/trail. - void removeChars (CharGroup mode = kSpace); ///< Removes all of group. - bool removeChars8 (const char8* which); ///< Remove all occurrences of each char in 'which' - bool removeChars16 (const char16* which); ///< Remove all occurrences of each char in 'which' - inline bool removeChars8 (const char8 which) {char8 str[] = {which, 0}; return removeChars8 (str); } - inline bool removeChars16 (const char16 which) {char16 str[] = {which, 0}; return removeChars16 (str); } - inline bool removeChars (const char8* which) {return removeChars8 (which);} - inline bool removeChars (const char16* which) {return removeChars16 (which);} - inline bool removeChars (const char8 which) {return removeChars8 (which);} - inline bool removeChars (const char16 which) {return removeChars16 (which);} - bool removeSubString (const ConstString& subString, bool allOccurences = true); - //------------------------------------------------------------------------- - - // print------------------------------------------------------------------- - String& printf (const char8* format, ...); ///< Print formatted data into string - String& printf (const char16* format, ...); ///< Print formatted data into string - String& vprintf (const char8* format, va_list args); - String& vprintf (const char16* format, va_list args); - //------------------------------------------------------------------------- - - // numbers----------------------------------------------------------------- - String& printInt64 (int64 value); - String& printFloat (double value); - /** Increment the trailing number if present else start with minNumber, width specifies the string width format (width 2 for number 3 is 03), - applyOnlyFormat set to true will only format the string to the given width without incrementing the founded trailing number */ - bool incrementTrailingNumber (uint32 width = 2, tchar separator = STR (' '), uint32 minNumber = 1, bool applyOnlyFormat = false); - //------------------------------------------------------------------------- - - // conversion-------------------------------------------------------------- - bool fromVariant (const FVariant& var); ///< Assigns string from FVariant - void toVariant (FVariant& var) const; - bool fromAttributes (IAttributes* a, IAttrID attrID); ///< Assigns string from FAttributes - bool toAttributes (IAttributes* a, IAttrID attrID); - - void swapContent (String& s); ///< Swaps ownership of the strings pointed to - void take (String& str); ///< Take ownership of the string of 'str' - void take (void* _buffer, bool wide); ///< Take ownership of buffer - void* pass (); - void passToVariant (FVariant& var); ///< Pass ownership of buffer to Variant - sets Variant ownership - - void toLower (uint32 index); ///< Lower case the character. - void toLower (); ///< Lower case the string. - void toUpper (uint32 index); ///< Upper case the character. - void toUpper (); ///< Upper case the string. - - unsigned char* toPascalString (unsigned char* buf); ///< Pascal string conversion - const String& fromPascalString (const unsigned char* buf); ///< Pascal string conversion - - bool toWideString (uint32 sourceCodePage = kCP_Default); ///< Converts to wide string according to sourceCodePage - bool toMultiByte (uint32 destCodePage = kCP_Default); - - void fromUTF8 (const char8* utf8String); ///< Assigns from UTF8 string - bool normalize (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working - -#if SMTG_OS_MACOS - virtual bool fromCFStringRef (const void*, uint32 encoding = 0xFFFF); ///< CFString conversion -#endif - //------------------------------------------------------------------------- - - //----------------------------------------------------------------------------- -protected: - bool resize (uint32 newSize, bool wide, bool fill = false); - -private: - void tryFreeBuffer (); - bool checkToMultiByte (uint32 destCodePage = kCP_Default) const; // to remove debug code from inline - const_cast inside!!! -}; - -// String concatenation functions. -inline String operator+ (const ConstString& s1, const ConstString& s2) {return String (s1).append (s2);} -inline String operator+ (const ConstString& s1, const char8* s2) {return String (s1).append (s2);} -inline String operator+ (const ConstString& s1, const char16* s2) {return String (s1).append (s2);} -inline String operator+ (const char8* s1, const ConstString& s2) {return String (s1).append (s2);} -inline String operator+ (const char16* s1, const ConstString& s2) {return String (s1).append (s2);} -inline String operator+ (const ConstString& s1, const String& s2) {return String (s1).append (s2);} -inline String operator+ (const String& s1, const ConstString& s2) {return String (s1).append (s2);} -inline String operator+ (const String& s1, const String& s2) {return String (s1).append (s2);} -inline String operator+ (const String& s1, const char8* s2) {return String (s1).append (s2);} -inline String operator+ (const String& s1, const char16* s2) {return String (s1).append (s2);} -inline String operator+ (const char8* s1, const String& s2) {return String (s1).append (s2);} -inline String operator+ (const char16* s1, const String& s2) {return String (s1).append (s2);} - -//----------------------------------------------------------------------------- -// ConstString -//----------------------------------------------------------------------------- -inline const tchar* ConstString::text () const -{ -#ifdef UNICODE - return text16 (); -#else - return text8 (); -#endif -} - -//----------------------------------------------------------------------------- -inline const char8* ConstString::text8 () const -{ - return (!isWide && buffer8) ? buffer8: kEmptyString8; -} - -//----------------------------------------------------------------------------- -inline const char16* ConstString::text16 () const -{ - return (isWide && buffer16) ? buffer16 : kEmptyString16; -} - -//----------------------------------------------------------------------------- -inline char8 ConstString::getChar8 (uint32 index) const -{ - if (index < len && buffer8 && !isWide) - return buffer8[index]; - return 0; -} - -//----------------------------------------------------------------------------- -inline char16 ConstString::getChar16 (uint32 index) const -{ - if (index < len && buffer16 && isWide) - return buffer16[index]; - return 0; -} - -//----------------------------------------------------------------------------- -inline tchar ConstString::getChar (uint32 index) const -{ -#ifdef UNICODE - return getChar16 (index); -#else - return getChar8 (index); -#endif -} - -//----------------------------------------------------------------------------- -inline tchar ConstString::getCharAt (uint32 index) const -{ -#ifdef UNICODE - if (isWide) - return getChar16 (index); -#endif - - return static_cast (getChar8 (index)); -} - -//----------------------------------------------------------------------------- -inline int64 ConstString::getNumber () const -{ - int64 tmp = 0; - scanInt64 (tmp); - return tmp; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanInt32_8 (const char8* text, int32& value, bool scanToEnd) -{ - int64 tmp; - if (scanInt64_8 (text, tmp, scanToEnd)) - { - value = (int32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanInt32_16 (const char16* text, int32& value, bool scanToEnd) -{ - int64 tmp; - if (scanInt64_16 (text, tmp, scanToEnd)) - { - value = (int32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanInt32 (const tchar* text, int32& value, bool scanToEnd) -{ - int64 tmp; - if (scanInt64 (text, tmp, scanToEnd)) - { - value = (int32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd) -{ - uint64 tmp; - if (scanUInt64_8 (text, tmp, scanToEnd)) - { - value = (uint32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd) -{ - uint64 tmp; - if (scanUInt64_16 (text, tmp, scanToEnd)) - { - value = (uint32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline bool ConstString::scanUInt32 (const tchar* text, uint32& value, bool scanToEnd) -{ - uint64 tmp; - if (scanUInt64 (text, tmp, scanToEnd)) - { - value = (uint32)tmp; - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -inline const char8* String::text8 () const -{ - if (isWide && !isEmpty ()) - checkToMultiByte (); // this should be avoided, since it can lead to information loss - - return ConstString::text8 (); -} - -//----------------------------------------------------------------------------- -inline const char16* String::text16 () const -{ - if (!isWide && !isEmpty ()) - { - const_cast (*this).toWideString (); - } - return ConstString::text16 (); -} - -//----------------------------------------------------------------------------- -inline char8 String::getChar8 (uint32 index) const -{ - if (isWide && !isEmpty ()) - checkToMultiByte (); // this should be avoided, since it can lead to information loss - - return ConstString::getChar8 (index); -} - -//----------------------------------------------------------------------------- -inline char16 String::getChar16 (uint32 index) const -{ - if (!isWide && !isEmpty ()) - { - const_cast (*this).toWideString (); - } - return ConstString::getChar16 (index); -} - -//----------------------------------------------------------------------------- - - -inline bool operator< (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) < 0) ? true : false;} -inline bool operator<= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) <= 0) ? true : false;} -inline bool operator> (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) > 0) ? true : false;} -inline bool operator>= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) >= 0) ? true : false;} -inline bool operator== (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) == 0) ? true : false;} -inline bool operator!= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) != 0) ? true : false;} - -inline bool operator< (const ConstString& s1, const char8* s2) {return (s1.compare (s2) < 0) ? true : false;} -inline bool operator<= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) <= 0) ? true : false;} -inline bool operator> (const ConstString& s1, const char8* s2) {return (s1.compare (s2) > 0) ? true : false;} -inline bool operator>= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) >= 0) ? true : false;} -inline bool operator== (const ConstString& s1, const char8* s2) {return (s1.compare (s2) == 0) ? true : false;} -inline bool operator!= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) != 0) ? true : false;} -inline bool operator< (const char8* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;} -inline bool operator<= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;} -inline bool operator> (const char8* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;} -inline bool operator>= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;} -inline bool operator== (const char8* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;} -inline bool operator!= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;} - -inline bool operator< (const ConstString& s1, const char16* s2) {return (s1.compare (s2) < 0) ? true : false;} -inline bool operator<= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) <= 0) ? true : false;} -inline bool operator> (const ConstString& s1, const char16* s2) {return (s1.compare (s2) > 0) ? true : false;} -inline bool operator>= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) >= 0) ? true : false;} -inline bool operator== (const ConstString& s1, const char16* s2) {return (s1.compare (s2) == 0) ? true : false;} -inline bool operator!= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) != 0) ? true : false;} -inline bool operator< (const char16* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;} -inline bool operator<= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;} -inline bool operator> (const char16* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;} -inline bool operator>= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;} -inline bool operator== (const char16* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;} -inline bool operator!= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;} - -// The following functions will only work with European Numbers! -// (e.g. Arabic, Tibetan, and Khmer digits are not supported) -extern int32 strnatcmp8 (const char8* s1, const char8* s2, bool caseSensitive = true); -extern int32 strnatcmp16 (const char16* s1, const char16* s2, bool caseSensitive = true); -inline int32 strnatcmp (const tchar* s1, const tchar* s2, bool caseSensitive = true) -{ -#ifdef UNICODE - return strnatcmp16 (s1, s2, caseSensitive); -#else - return strnatcmp8 (s1, s2, caseSensitive); -#endif -} - -//----------------------------------------------------------------------------- -/** StringObject implements IStringResult and IString methods. - It can therefore be exchanged with other Steinberg objects using one or both of these -interfaces. - -\see String, ConstString -*/ -//----------------------------------------------------------------------------- -class StringObject : public FObject, public String, public IStringResult, public IString -{ -public: -//----------------------------------------------------------------------------- - StringObject () {} - StringObject (const char16* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {} - StringObject (const char8* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {} - StringObject (const StringObject& str, int32 n = -1) : String (str, n) {} - StringObject (const String& str, int32 n = -1) : String (str, n) {} - StringObject (const FVariant& var) : String (var) {} - - using String::operator=; - - // IStringResult ---------------------------------------------------------- - void PLUGIN_API setText (const char8* text) SMTG_OVERRIDE; - //------------------------------------------------------------------------- - - // IString----------------------------------------------------------------- - void PLUGIN_API setText8 (const char8* text) SMTG_OVERRIDE; - void PLUGIN_API setText16 (const char16* text) SMTG_OVERRIDE; - - const char8* PLUGIN_API getText8 () SMTG_OVERRIDE; - const char16* PLUGIN_API getText16 () SMTG_OVERRIDE; - - void PLUGIN_API take (void* s, bool _isWide) SMTG_OVERRIDE; - bool PLUGIN_API isWideString () const SMTG_OVERRIDE; - //------------------------------------------------------------------------- - - OBJ_METHODS (StringObject, FObject) - FUNKNOWN_METHODS2 (IStringResult, IString, FObject) -}; - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/updatehandler.cpp b/source/includes/vst3sdk/base/source/updatehandler.cpp deleted file mode 100644 index 9213ebc95..000000000 --- a/source/includes/vst3sdk/base/source/updatehandler.cpp +++ /dev/null @@ -1,733 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/updatehandler.cpp -// Created by : Steinberg, 2008 -// Description : -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#include "base/source/updatehandler.h" -#include "base/source/classfactoryhelpers.h" -#include "base/source/fstring.h" - -#if SMTG_CPP11_STDLIBSUPPORT -#include -#else -#include -#endif -#include -#include -#include - -#define NON_EXISTING_DEPENDENCY_CHECK 0 // not yet -#define CLASS_NAME_TRACKED DEVELOPMENT - -using Steinberg::Base::Thread::FGuard; - -namespace Steinberg { - -DEF_CLASS_IID (IUpdateManager) -bool UpdateHandler::lockUpdates = false; - -namespace Update { -const uint32 kHashSize = (1 << 8); // must be power of 2 (16 bytes * 256 == 4096) -const uint32 kMapSize = 1024 * 10; - -//------------------------------------------------------------------------ -inline uint32 hashPointer (void* p) -{ - return (uint32)((uint64 (p) >> 12) & (kHashSize - 1)); -} - -//------------------------------------------------------------------------ -inline IPtr getUnknownBase (FUnknown* unknown) -{ - FUnknown* result = nullptr; - if (unknown) - unknown->queryInterface (FUnknown::iid, (void**)&result); - - return owned (result); -} - -#if CLASS_NAME_TRACKED -//------------------------------------------------------------------------ -struct Dependency -{ - Dependency (FUnknown* o, IDependent* d) - : obj (o), dep (d), objClass (nullptr), depClass (nullptr) - { - } - - inline bool operator== (const Dependency& d) const { return obj == d.obj; } - inline bool operator!= (const Dependency& d) const { return obj != d.obj; } - inline bool operator< (const Dependency& d) const { return obj < d.obj; } - inline bool operator> (const Dependency& d) const { return obj > d.obj; } - FUnknown* obj; - IDependent* dep; - - FClassID objClass; - FClassID depClass; -}; -#endif - -//------------------------------------------------------------------------ -struct DeferedChange -{ - DeferedChange (FUnknown* o, int32 m = 0) : obj (o), msg (m) {} - ~DeferedChange () {} - DeferedChange (const DeferedChange& r) : obj (r.obj), msg (r.msg) {} - inline bool operator== (const DeferedChange& d) const { return obj == d.obj; } - inline bool operator!= (const DeferedChange& d) const { return obj != d.obj; } - FUnknown* obj; - int32 msg; -}; - -//------------------------------------------------------------------------ -struct UpdateData -{ - UpdateData (FUnknown* o, IDependent** d, uint32 c) - : obj (o), dependents (d), count (c) - { - } - FUnknown* obj; - IDependent** dependents; - uint32 count; - bool operator== (const UpdateData& d) const - { - return d.obj == obj && d.dependents == dependents; - } -}; - -//------------------------------------------------------------------------ -using DeferedChangeList = std::deque; -using DeferedChangeListIterConst = DeferedChangeList::const_iterator; -using DeferedChangeListIter = DeferedChangeList::iterator; - -using UpdateDataList = std::deque; -using UpdateDataListIterConst = UpdateDataList::const_iterator; - -#if CLASS_NAME_TRACKED -using DependentList = std::vector; -#else -typedef std::vector DependentList; -#endif -using DependentListIter = DependentList::iterator; -using DependentListIterConst = DependentList::const_iterator; - -#if SMTG_CPP11_STDLIBSUPPORT -using DependentMap = std::unordered_map; -#else -typedef std::map DependentMap; -#endif -using DependentMapIter = DependentMap::iterator; -using DependentMapIterConst = DependentMap::const_iterator; - -struct Table -{ - DependentMap depMap[kHashSize]; - DeferedChangeList defered; - UpdateDataList updateData; -}; - -//------------------------------------------------------------------------ -void updateDone (FUnknown* unknown, int32 message) -{ - if (message != IDependent::kDestroyed) - { - FObject* obj = FObject::unknownToObject (unknown); - if (obj) - obj->updateDone (message); - } -} -} // namespace Update - -//------------------------------------------------------------------------ -static int32 countEntries (Update::DependentMap& map) -{ - int32 total = 0; - Update::DependentMapIterConst iterMap = map.begin (); - while (iterMap != map.end ()) - { - const Update::DependentList& list = iterMap->second; - Update::DependentListIterConst iterList = list.begin (); - while (iterList != list.end ()) - { - total++; - ++iterList; - } - ++iterMap; - } - return total; -} - -//------------------------------------------------------------------------ -UpdateHandler::UpdateHandler () -{ - table = NEW Update::Table; - if (FObject::getUpdateHandler () == nullptr) - FObject::setUpdateHandler (this); -} - -//------------------------------------------------------------------------ -UpdateHandler::~UpdateHandler () -{ - if (FObject::getUpdateHandler () == this) - FObject::setUpdateHandler (nullptr); - delete table; - table = nullptr; -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::addDependent (FUnknown* u, IDependent* _dependent) -{ - IPtr unknown = Update::getUnknownBase (u); - if (!unknown || !_dependent) - return kResultFalse; - - FGuard guard (lock); - -#if CLASS_NAME_TRACKED - Update::Dependency dependent (unknown, _dependent); - - FObject* obj = FObject::unknownToObject (unknown); - if (obj) - dependent.objClass = obj->isA (); - obj = FObject::unknownToObject (_dependent); - if (obj) - dependent.depClass = obj->isA (); -#else - IDependent* dependent = _dependent; -#endif - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIter it = map.find (unknown); - if (it == map.end ()) - { - Update::DependentList list; - list.push_back (dependent); - map[unknown] = list; - } - else - { - (*it).second.push_back (dependent); - } - - return kResultTrue; -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent) -{ - IPtr unknown = Update::getUnknownBase (u); - if (unknown == nullptr && dependent == nullptr) - return kResultFalse; - - FGuard guard (lock); - - Update::UpdateDataListIterConst iter = table->updateData.begin (); - while (iter != table->updateData.end ()) - { - if ((*iter).obj == unknown || unknown == nullptr) - { - for (uint32 count = 0; count < (*iter).count; count++) - { - if ((*iter).dependents[count] == dependent) - (*iter).dependents[count] = nullptr; - } - } - ++iter; - } - // Remove all objects for the given dependent - if (unknown == nullptr) - { - for (uint32 j = 0; j < Update::kHashSize; j++) - { - Update::DependentMap& map = table->depMap[j]; - Update::DependentMapIter iterMap = map.begin (); - while (iterMap != map.end ()) - { - Update::DependentList& list = (*iterMap).second; - Update::DependentListIter iterList = list.begin (); - bool listIsEmpty = false; - - while (iterList != list.end ()) - { -#if CLASS_NAME_TRACKED - if ((*iterList).dep == dependent) -#else - if ((*iterList) == dependent) -#endif - { - if (list.size () == 1u) - { - listIsEmpty = true; - break; - } - else - iterList = list.erase (iterList); - } - else - { - ++iterList; - } - } - - if (listIsEmpty) - iterMap = map.erase (iterMap); - else - ++iterMap; - } - } - } - else - { - bool mustFlush = true; - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIter iterList = map.find (unknown); - -#if NON_EXISTING_DEPENDENCY_CHECK - SMTG_ASSERT (iterList != map.end () && "ERROR: Trying to remove a non existing dependency!") -#endif - if (iterList != map.end ()) - { - if (dependent == nullptr) // Remove all dependents of object - { - map.erase (iterList); - } - else // Remove one dependent - { - int32 eraseCount = 0; - Update::DependentList& dependentlist = (*iterList).second; - Update::DependentListIter iterDependentlist = dependentlist.begin (); - while (iterDependentlist != dependentlist.end ()) - { -#if CLASS_NAME_TRACKED - if ((*iterDependentlist).dep == dependent) -#else - if ((*iterDependentlist) == dependent) -#endif - { - iterDependentlist = dependentlist.erase (iterDependentlist); - eraseCount++; - if (dependentlist.empty ()) - { - map.erase (iterList); - break; - } - } - else - { - ++iterDependentlist; - mustFlush = false; - } - } - } - } - if (mustFlush) - cancelUpdates (unknown); - } - - return kResultTrue; -} - -//------------------------------------------------------------------------ -tresult UpdateHandler::doTriggerUpdates (FUnknown* u, int32 message, bool suppressUpdateDone) -{ - if (lockUpdates) - return kResultFalse; - IPtr unknown = Update::getUnknownBase (u); - if (!unknown) - return kResultFalse; - - // to avoid crashes due to stack overflow, we reduce the amount of memory reserved for the - // dependents - IDependent* smallDependents[Update::kMapSize / 10]; // 8kB for x64 - IDependent** dependents = smallDependents; - int32 maxDependents = Update::kMapSize / 10; - int32 count = 0; - - { - FGuard guard (lock); // scope for lock - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIterConst iterList = map.find (unknown); - if (iterList != map.end ()) - { - const Update::DependentList& dependentlist = (*iterList).second; - Update::DependentListIterConst iterDependentlist = dependentlist.begin (); - while (iterDependentlist != dependentlist.end ()) - { -#if CLASS_NAME_TRACKED - dependents[count] = (*iterDependentlist).dep; -#else - dependents[count] = *iterDependentlist; -#endif - count++; - - if (count >= maxDependents) - { - if (dependents == smallDependents) - { - dependents = NEW IDependent*[Update::kMapSize]; - memcpy (dependents, smallDependents, count * sizeof (dependents[0])); - maxDependents = Update::kMapSize; - } - else - { - SMTG_WARNING ("Dependency overflow") - break; - } - } - ++iterDependentlist; - } - } - - // push update data on the stack - if (count > 0) - { - Update::UpdateData data (unknown, dependents, count); - table->updateData.push_back (data); - } - } // end scope - - int32 i = 0; - while (i < count) - { - if (dependents[i]) - dependents[i]->update (unknown, message); - i++; - } - - if (dependents != smallDependents) - delete[] dependents; - - // remove update data from the stack - if (count > 0) - { - FGuard guard (lock); - - table->updateData.pop_back (); - } - - // send update done message - if (suppressUpdateDone == false) - Update::updateDone (unknown, message); - - return count > 0 ? kResultTrue : kResultFalse; // Object was found and has been updated -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::triggerUpdates (FUnknown* u, int32 message) -{ - return doTriggerUpdates (u, message, false); -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::deferUpdates (FUnknown* u, int32 message) -{ - IPtr unknown = Update::getUnknownBase (u); - if (!unknown) - return kResultFalse; - - FGuard guard (lock); - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIterConst iterList = map.find (unknown); - - bool hasDependency = (iterList != map.end ()); - if (hasDependency == false) - { - Update::updateDone (unknown, message); - return kResultTrue; - } - - bool found = false; - Update::DeferedChangeListIterConst iter = table->defered.begin (); - while (iter != table->defered.end ()) - { - if ((*iter).obj == unknown && (*iter).msg == message) - { - found = true; - break; - } - ++iter; - } - - if (!found) - { - Update::DeferedChange change (unknown, message); - table->defered.push_back (change); - } - - return kResultTrue; -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::triggerDeferedUpdates (FUnknown* unknown) -{ - Update::DeferedChangeList deferedAgain; - if (!unknown) - { - while (table->defered.empty () == false) - { - // Remove first from queue - lock.lock (); - - FUnknown* obj = table->defered.front ().obj; - int32 msg = table->defered.front ().msg; - table->defered.pop_front (); - - // check if this object is currently being updated. in this case, defer update again... - bool canSignal = true; - Update::UpdateDataListIterConst iter = table->updateData.begin (); - while (iter != table->updateData.end ()) - { - if ((*iter).obj == obj) - { - canSignal = false; - break; - } - ++iter; - } - lock.unlock (); - - if (canSignal) - { - triggerUpdates (obj, msg); - } - else - { - Update::DeferedChange change (obj, msg); - deferedAgain.push_back (change); - } - } - } - else - { - IPtr object = Update::getUnknownBase (unknown); - Update::DeferedChange tmp (object); - - while (true) - { - lock.lock (); - Update::DeferedChangeListIter it = - std::find (table->defered.begin (), table->defered.end (), tmp); - if (it == table->defered.end ()) - { - lock.unlock (); - return kResultTrue; - } - - if ((*it).obj != nullptr) - { - int32 msg = (*it).msg; - table->defered.erase (it); - - // check if this object is currently being updated. in this case, defer update - // again... - bool canSignal = true; - Update::UpdateDataListIterConst iter = table->updateData.begin (); - while (iter != table->updateData.end ()) - { - if ((*iter).obj == object) - { - canSignal = false; - break; - } - ++iter; - } - lock.unlock (); - - if (canSignal) - { - triggerUpdates (object, msg); - } - else - { - Update::DeferedChange change (object, msg); - deferedAgain.push_back (change); - } - } - } - } - - if (deferedAgain.empty () == false) - { - FGuard guard (lock); - - Update::DeferedChangeListIterConst iter = deferedAgain.begin (); - while (iter != deferedAgain.end ()) - { - table->defered.push_back (*iter); - ++iter; - } - } - - return kResultTrue; -} - -//------------------------------------------------------------------------ -tresult PLUGIN_API UpdateHandler::cancelUpdates (FUnknown* u) -{ - IPtr unknown = Update::getUnknownBase (u); - if (!unknown) - return kResultFalse; - - FGuard guard (lock); - - Update::DeferedChange change (unknown, 0); - while (true) - { - auto iter = std::find (table->defered.begin (), table->defered.end (), change); - if (iter != table->defered.end ()) - table->defered.erase (iter); - else - break; - } - - return kResultTrue; -} - -//------------------------------------------------------------------------ -size_t UpdateHandler::countDependencies (FUnknown* object) -{ - FGuard guard (lock); - uint32 res = 0; - - IPtr unknown = Update::getUnknownBase (object); - if (unknown) - { - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIter iterList = map.find (unknown); - if (iterList != map.end ()) - return iterList->second.size (); - } - else - { - for (uint32 j = 0; j < Update::kHashSize; j++) - { - Update::DependentMap& map = table->depMap[j]; - res += countEntries (map); - } - } - return res; -} - -#if DEVELOPMENT -//------------------------------------------------------------------------ -bool UpdateHandler::checkDeferred (FUnknown* object) -{ - IPtr unknown = Update::getUnknownBase (object); - - FGuard guard (lock); - - Update::DeferedChange tmp (unknown); - Update::DeferedChangeListIterConst it = - std::find (table->defered.begin (), table->defered.end (), tmp); - if (it != table->defered.end ()) - return true; - - return false; -} - -//------------------------------------------------------------------------ -bool UpdateHandler::hasDependencies (FUnknown* u) -{ - IPtr unknown = Update::getUnknownBase (u); - if (!unknown) - return false; - - FGuard guard (lock); - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIterConst iterList = map.find (unknown); - bool hasDependency = (iterList != map.end ()); - - return hasDependency; -} - -//------------------------------------------------------------------------ -void UpdateHandler::printForObject (FObject* obj) const -{ - IPtr unknown = Update::getUnknownBase (obj); - if (!unknown) - return; - - FUnknownPtr dep (obj); - - bool header = false; - - Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; - Update::DependentMapIterConst iterList = map.begin (); - while (iterList != map.end ()) - { - const Update::DependentList& dependentlist = (*iterList).second; - Update::DependentListIterConst iterDependentlist = dependentlist.begin (); - while (iterDependentlist != dependentlist.end ()) - { -#if CLASS_NAME_TRACKED - if ((*iterList).first == unknown || (*iterDependentlist).dep == dep.getInterface ()) - { - if (!header) - { - FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj, - obj->isA ()); - header = true; - } - FDebugPrint ("%s %8" FORMAT_INT64A "\n <- %s %8" FORMAT_INT64A "\n", - (*iterDependentlist).depClass, (uint64) (*iterDependentlist).dep, - (*iterDependentlist).objClass, (uint64) ((*iterList).first)); - } -#else - if ((*iterList).first == unknown || (*iterDependentlist) == dep.getInterface ()) - { - if (!header) - { - FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj, - obj->isA ()); - header = true; - } - FDebugPrint ("%8" FORMAT_INT64A "\n <- %8" FORMAT_INT64A "\n", - (uint64) (*iterDependentlist), (uint64) ((*iterList).first)); - } -#endif - ++iterDependentlist; - } - - ++iterList; - } -} -#endif - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/source/updatehandler.h b/source/includes/vst3sdk/base/source/updatehandler.h deleted file mode 100644 index 538022e62..000000000 --- a/source/includes/vst3sdk/base/source/updatehandler.h +++ /dev/null @@ -1,139 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/source/updatehandler.h -// Created by : Steinberg, 2008 -// Description : -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#pragma once - -#include "base/source/fobject.h" -#include "base/thread/include/flock.h" -#include "pluginterfaces/base/iupdatehandler.h" - -namespace Steinberg { - -/// @cond ignore -namespace Update { struct Table; } -/// @endcond - -//------------------------------------------------------------------------ -/** Handle Send and Cancel pending message for a given object*/ -//------------------------------------------------------------------------ -class IUpdateManager : public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** cancel pending messages send by \param object or by any if object is 0 */ - virtual tresult PLUGIN_API cancelUpdates (FUnknown* object) = 0; - /** send pending messages send by \param object or by any if object is 0 */ - virtual tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) = 0; - static const FUID iid; -}; - -DECLARE_CLASS_IID (IUpdateManager, 0x030B780C, 0xD6E6418D, 0x8CE00BC2, 0x09C834D4) - -//------------------------------------------------------------------------------ -/** -UpdateHandler implements IUpdateManager and IUpdateHandler to handle dependencies -between objects to store and forward messages to dependent objects. - -This implementation is thread save, so objects can send message, add or remove -dependents from different threads. -Do do so it uses mutex, so be aware of locking. -*/ -//------------------------------------------------------------------------------ -class UpdateHandler : public FObject, public IUpdateHandler, public IUpdateManager -{ -public: -//------------------------------------------------------------------------------ - UpdateHandler (); - ~UpdateHandler (); - - using FObject::addDependent; - using FObject::removeDependent; - using FObject::deferUpdate; - - // IUpdateHandler - /** register \param dependent to get messages from \param object */ - tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) SMTG_OVERRIDE; - /** unregister \param dependent to get no messages from \param object */ - tresult PLUGIN_API removeDependent (FUnknown* object, - IDependent* dependent) SMTG_OVERRIDE; - /** send \param message to all dependents of \param object immediately */ - tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE; - /** send \param message to all dependents of \param object when idle */ - tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE; - - // IUpdateManager - /** cancel pending messages send by \param object or by any if object is 0 */ - tresult PLUGIN_API cancelUpdates (FUnknown* object) SMTG_OVERRIDE; - /** send pending messages send by \param object or by any if object is 0 */ - tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) SMTG_OVERRIDE; - - /// @cond ignore - // obsolete functions kept for compatibility - void checkUpdates (FObject* object = nullptr) { triggerDeferedUpdates (object->unknownCast ()); } - void flushUpdates (FObject* object) { cancelUpdates (object->unknownCast ()); } - void deferUpdate (FObject* object, int32 message) - { - deferUpdates (object->unknownCast (), message); - } - void signalChange (FObject* object, int32 message, bool suppressUpdateDone = false) - { - doTriggerUpdates (object->unknownCast (), message, suppressUpdateDone); - } -#if DEVELOPMENT - bool checkDeferred (FUnknown* object); - bool hasDependencies (FUnknown* object); - void printForObject (FObject* object) const; -#endif - /// @endcond - size_t countDependencies (FUnknown* object = nullptr); - - OBJ_METHODS (UpdateHandler, FObject) - FUNKNOWN_METHODS2 (IUpdateHandler, IUpdateManager, FObject) - SINGLETON (UpdateHandler) -//------------------------------------------------------------------------------ -private: - tresult doTriggerUpdates (FUnknown* object, int32 message, bool suppressUpdateDone); - - Steinberg::Base::Thread::FLock lock; - Update::Table* table = nullptr; - friend struct LockUpdateDependencies; - static bool lockUpdates; -}; - - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/base/thread/include/flock.h b/source/includes/vst3sdk/base/thread/include/flock.h deleted file mode 100644 index bc452502a..000000000 --- a/source/includes/vst3sdk/base/thread/include/flock.h +++ /dev/null @@ -1,183 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/thread/include/flock.h -// Created by : Steinberg, 1995 -// Description : locks -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -//---------------------------------------------------------------------------------- -/** @file base/thread/include/flock.h - Locks. */ -/** @defgroup baseLocks Locks */ -//---------------------------------------------------------------------------------- -#pragma once - -#include "base/source/fobject.h" -#include "pluginterfaces/base/ftypes.h" - -#if SMTG_PTHREADS -#include - -#elif SMTG_OS_WINDOWS -struct CRITSECT // CRITICAL_SECTION -{ - void* DebugInfo; // PRTL_CRITICAL_SECTION_DEBUG DebugInfo; - Steinberg::int32 LockCount; // LONG LockCount; - Steinberg::int32 RecursionCount; // LONG RecursionCount; - void* OwningThread; // HANDLE OwningThread - void* LockSemaphore; // HANDLE LockSemaphore - Steinberg::int32 SpinCount; // ULONG_PTR SpinCount -}; -#endif - -namespace Steinberg { -namespace Base { -namespace Thread { - -//------------------------------------------------------------------------ -/** Lock interface declaration. -@ingroup baseLocks */ -//------------------------------------------------------------------------ -struct ILock -{ -//------------------------------------------------------------------------ - virtual ~ILock () {} - - /** Enables lock. */ - virtual void lock () = 0; - - /** Disables lock. */ - virtual void unlock () = 0; - - /** Tries to disable lock. */ - virtual bool trylock () = 0; -//------------------------------------------------------------------------ -}; - -//------------------------------------------------------------------------ -/** FLock declaration. -@ingroup baseLocks */ -//------------------------------------------------------------------------ -class FLock : public ILock -{ -public: -//------------------------------------------------------------------------ - - /** Lock constructor. - * @param name lock name - */ - FLock (const char8* name = "FLock"); - - /** Lock destructor. */ - ~FLock (); - - //-- ILock ----------------------------------------------------------- - void lock () SMTG_OVERRIDE; - void unlock () SMTG_OVERRIDE; - bool trylock () SMTG_OVERRIDE; - -//------------------------------------------------------------------------ -protected: -#if SMTG_PTHREADS - pthread_mutex_t mutex; ///< Mutex object - -#elif SMTG_OS_WINDOWS - CRITSECT section; ///< Critical section object -#endif -}; - -//------------------------------------------------------------------------ -/** FLockObj declaration. Reference counted lock -@ingroup baseLocks */ -//------------------------------------------------------------------------ -class FLockObject : public FObject, public FLock -{ -public: - OBJ_METHODS (FLockObject, FObject) -}; - -//------------------------------------------------------------------------ -/** FGuard - automatic object for locks. -@ingroup baseLocks */ -//------------------------------------------------------------------------ -class FGuard -{ -public: -//------------------------------------------------------------------------ - - /** FGuard constructor. - * @param _lock guard this lock - */ - FGuard (ILock& _lock) : lock (_lock) { lock.lock (); } - - /** FGuard destructor. */ - ~FGuard () { lock.unlock (); } - -//------------------------------------------------------------------------ -private: - ILock& lock; ///< guarded lock -}; - -//------------------------------------------------------------------------ -/** Conditional Guard - Locks only if valid lock is passed. -@ingroup baseLocks */ -//------------------------------------------------------------------------ -class FConditionalGuard -{ -public: -//------------------------------------------------------------------------ - - /** FConditionGuard constructor. - * @param _lock guard this lock - */ - FConditionalGuard (FLock* _lock) : lock (_lock) - { - if (lock) - lock->lock (); - } - - /** FConditionGuard destructor. */ - ~FConditionalGuard () - { - if (lock) - lock->unlock (); - } - -//------------------------------------------------------------------------ -private: - FLock* lock; ///< guarded lock -}; - -} // Thread -} // Base -} // Steinberg diff --git a/source/includes/vst3sdk/base/thread/source/flock.cpp b/source/includes/vst3sdk/base/thread/source/flock.cpp deleted file mode 100644 index 8135cb6c7..000000000 --- a/source/includes/vst3sdk/base/thread/source/flock.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//------------------------------------------------------------------------ -// Project : SDK Base -// Version : 1.0 -// -// Category : Helpers -// Filename : base/thread/source/flock.cpp -// Created by : Steinberg, 1995 -// Description : Locks -// -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -//----------------------------------------------------------------------------- - -#define DEBUG_LOCK 0 - -#include "base/thread/include/flock.h" -#include "base/source/fdebug.h" - -//------------------------------------------------------------------------ -#if SMTG_OS_WINDOWS -//------------------------------------------------------------------------ -#ifndef WINVER -#define WINVER 0x0500 -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT WINVER -#endif - -#include -#include -#define INIT_CS(cs) \ - InitializeCriticalSection ((LPCRITICAL_SECTION)&cs); - -#endif // SMTG_OS_WINDOWS - -namespace Steinberg { -namespace Base { -namespace Thread { - - -//------------------------------------------------------------------------ -// FLock implementation -//------------------------------------------------------------------------ -FLock::FLock (const char8* /*name*/) -{ -#if SMTG_PTHREADS - pthread_mutexattr_t mutexAttr; - pthread_mutexattr_init (&mutexAttr); - pthread_mutexattr_settype (&mutexAttr, PTHREAD_MUTEX_RECURSIVE); - if (pthread_mutex_init (&mutex, &mutexAttr) != 0) - {SMTG_WARNING("mutex_init failed")} - pthread_mutexattr_destroy (&mutexAttr); - -#elif SMTG_OS_WINDOWS - INIT_CS (section) -#else -#warning implement FLock! -#endif -} - -//------------------------------------------------------------------------ -FLock::~FLock () -{ -#if SMTG_PTHREADS - pthread_mutex_destroy (&mutex); - -#elif SMTG_OS_WINDOWS - DeleteCriticalSection ((LPCRITICAL_SECTION)§ion); - -#endif -} - -//------------------------------------------------------------------------ -void FLock::lock () -{ -#if DEBUG_LOCK - FDebugPrint ("FLock::lock () %x\n", this); -#endif - -#if SMTG_PTHREADS - pthread_mutex_lock (&mutex); - -#elif SMTG_OS_WINDOWS - EnterCriticalSection ((LPCRITICAL_SECTION)§ion); - -#endif -} - -//------------------------------------------------------------------------ -void FLock::unlock () -{ -#if DEBUG_LOCK - FDebugPrint ("FLock::unlock () %x\n", this); -#endif - -#if SMTG_PTHREADS - pthread_mutex_unlock (&mutex); - -#elif SMTG_OS_WINDOWS - LeaveCriticalSection ((LPCRITICAL_SECTION)§ion); - -#endif -} - -//------------------------------------------------------------------------ -bool FLock::trylock () -{ -#if SMTG_PTHREADS - return pthread_mutex_trylock (&mutex) == 0; - -#elif SMTG_OS_WINDOWS - return TryEnterCriticalSection ((LPCRITICAL_SECTION)§ion) != 0 ? true : false; - -#else - return false; -#endif -} - -} // Thread -} // Base -} // Steinberg - diff --git a/source/includes/vst3sdk/pluginterfaces/LICENSE.txt b/source/includes/vst3sdk/pluginterfaces/LICENSE.txt deleted file mode 100644 index b5fddfe76..000000000 --- a/source/includes/vst3sdk/pluginterfaces/LICENSE.txt +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------------- -// LICENSE -// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved -//----------------------------------------------------------------------------- -This license applies only to files referencing this license, -for other files of the Software Development Kit the respective embedded license text -is applicable. The license can be found at: www.steinberg.net/sdklicenses_vst3 - -This Software Development Kit is licensed under the terms of the Steinberg VST3 License, -or alternatively under the terms of the General Public License (GPL) Version 3. -You may use the Software Development Kit according to either of these licenses as it is -most appropriate for your project on a case-by-case basis (commercial or not). - -a) Proprietary Steinberg VST3 License -The Software Development Kit may not be distributed in parts or its entirety -without prior written agreement by Steinberg Media Technologies GmbH. -The SDK must not be used to re-engineer or manipulate any technology used -in any Steinberg or Third-party application or software module, -unless permitted by law. -Neither the name of the Steinberg Media Technologies GmbH nor the names of its -contributors may be used to endorse or promote products derived from this -software without specific prior written permission. -Before publishing a software under the proprietary license, you need to obtain a copy -of the License Agreement signed by Steinberg Media Technologies GmbH. -The Steinberg VST SDK License Agreement can be found at: -www.steinberg.net/en/company/developers.html - -THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - -b) General Public License (GPL) Version 3 -Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html -//---------------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/pluginterfaces/README.md b/source/includes/vst3sdk/pluginterfaces/README.md deleted file mode 100644 index 7be410549..000000000 --- a/source/includes/vst3sdk/pluginterfaces/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Welcome to VST 3 SDK Interfaces - -Here are located all VST interfaces definitions (including VST Component/Controller, UI, Test). - -## License & Usage guidelines - -More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3) - ----- -Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk) \ No newline at end of file diff --git a/source/includes/vst3sdk/pluginterfaces/base/conststringtable.cpp b/source/includes/vst3sdk/pluginterfaces/base/conststringtable.cpp deleted file mode 100644 index 4891cefa1..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/conststringtable.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/conststringtable.cpp -// Created by : Steinberg, 09/2007 -// Description : constant unicode string table -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#include "conststringtable.h" -#include -#include - -namespace Steinberg { - -static std::map* stringMap; -static std::map* charMap; - -static char16* generateUTF16 (const char8* str); - -//---------------------------------------------------------------------------- -ConstStringTable* ConstStringTable::instance () -{ - static ConstStringTable stringTable; - return &stringTable; -} - -//---------------------------------------------------------------------------- -const char16* ConstStringTable::getString (const char8* str) const -{ - std::map::iterator iter = stringMap->find (str); - if (iter != stringMap->end ()) - return iter->second; - char16* uStr = generateUTF16 (str); - stringMap->insert (std::make_pair (str, uStr)); - return uStr; -} - -//---------------------------------------------------------------------------- -const char16 ConstStringTable::getString (const char8 str) const -{ - std::map::iterator iter = charMap->find (str); - if (iter != charMap->end ()) - return iter->second; - char16 uStr = 0; -#if BYTEORDER == kBigEndian - char8* puStr = (char8*)&uStr; - puStr[1] = str; -#else - uStr = str; -#endif - charMap->insert (std::make_pair (str, uStr)); - return uStr; -} - -//---------------------------------------------------------------------------- -ConstStringTable::ConstStringTable () -{ - stringMap = new std::map; - charMap = new std::map; -} - -//---------------------------------------------------------------------------- -ConstStringTable::~ConstStringTable () -{ - // free out allocated strings - { - std::map::iterator iter = stringMap->begin (); - while (iter != stringMap->end ()) - { - delete[] iter->second; - iter++; - } - } // delete iterator on map before deleting the map - - delete stringMap; - delete charMap; -} - -//---------------------------------------------------------------------------- -char16* generateUTF16 (const char8* str) -{ - int32 len = (int32)strlen (str); - char16* result = new char16[len + 1]; - for (int32 i = 0; i < len; i++) - { -#if BYTEORDER == kBigEndian - char8* pChr = (char8*)&result[i]; - pChr[0] = 0; - pChr[1] = str[i]; -#else - result[i] = str[i]; -#endif - } - result[len] = 0; - return result; -} -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/conststringtable.h b/source/includes/vst3sdk/pluginterfaces/base/conststringtable.h deleted file mode 100644 index e19cae651..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/conststringtable.h +++ /dev/null @@ -1,44 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/conststringtable.h -// Created by : Steinberg, 09/2007 -// Description : constant unicode string table -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "ftypes.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -/** Constant unicode string table. -Used for conversion from ASCII string literals to char16. -*/ -class ConstStringTable -{ -public: - static ConstStringTable* instance (); - - /** Returns a char16 string of a ASCII string literal*/ - const char16* getString (const char8* str) const; - /** Returns a char16 character of a ASCII character */ - const char16 getString (const char8 str) const; - -protected: - ConstStringTable (); - ~ConstStringTable (); -}; - -//------------------------------------------------------------------------ -} // namespace Steinberg - diff --git a/source/includes/vst3sdk/pluginterfaces/base/coreiids.cpp b/source/includes/vst3sdk/pluginterfaces/base/coreiids.cpp deleted file mode 100644 index d5935044d..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/coreiids.cpp +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interface IID definitions -// Filename : pluginterfaces/base/coreiids.cpp -// Created by : Steinberg, 01/2004 -// Description : Basic Interface -// -//------------------------------------------------------------------------ -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//------------------------------------------------------------------------ - -#include "pluginterfaces/base/funknown.h" -#include "pluginterfaces/base/ibstream.h" -#include "pluginterfaces/base/icloneable.h" -#include "pluginterfaces/base/ipluginbase.h" -#include "pluginterfaces/base/iupdatehandler.h" - -//------------------------------------------------------------------------ -namespace Steinberg { -DEF_CLASS_IID (IPluginBase) -DEF_CLASS_IID (IPluginFactory) -DEF_CLASS_IID (IPluginFactory2) -DEF_CLASS_IID (IPluginFactory3) - -DEF_CLASS_IID (FUnknown) - -DEF_CLASS_IID (ICloneable) - -DEF_CLASS_IID (IDependent) -DEF_CLASS_IID (IUpdateHandler) - -DEF_CLASS_IID (IBStream) -DEF_CLASS_IID (ISizeableStream) - -//------------------------------------------------------------------------ -} // Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/falignpop.h b/source/includes/vst3sdk/pluginterfaces/base/falignpop.h deleted file mode 100644 index 8ff7faa79..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/falignpop.h +++ /dev/null @@ -1,25 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/falignpop.h -// Created by : Steinberg, 01/2004 -// Description : Restore alignment settings -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -//--------------------------------------------------------------------------------------------------- -#if SMTG_OS_MACOS - #pragma pack(pop) -#elif defined __BORLANDC__ - #pragma -a- -#elif SMTG_OS_WINDOWS - #pragma pack(pop) -#endif -//--------------------------------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/pluginterfaces/base/falignpush.h b/source/includes/vst3sdk/pluginterfaces/base/falignpush.h deleted file mode 100644 index 5ff11f22c..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/falignpush.h +++ /dev/null @@ -1,36 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/falignpush.h -// Created by : Steinberg, 01/2004 -// Description : Set alignment settings -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -//---------------------------------------------------------------------------------------------- -#if SMTG_OS_MACOS - #pragma GCC diagnostic ignored "-Wunknown-warning-option" - #pragma GCC diagnostic ignored "-Wpragma-pack" - #if SMTG_PLATFORM_64 - #pragma pack(push, 16) - #else - #pragma pack(push, 1) - #endif -#elif defined __BORLANDC__ - #pragma -a8 -#elif SMTG_OS_WINDOWS - #pragma pack(push) - #if SMTG_PLATFORM_64 - #pragma pack(16) - #else - #pragma pack(8) - #endif -#endif -//---------------------------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/pluginterfaces/base/fplatform.h b/source/includes/vst3sdk/pluginterfaces/base/fplatform.h deleted file mode 100644 index dea70d0f7..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/fplatform.h +++ /dev/null @@ -1,258 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/fplatform.h -// Created by : Steinberg, 01/2004 -// Description : Detect platform and set define -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#define kLittleEndian 0 -#define kBigEndian 1 - -#undef PLUGIN_API - -#if !defined (__INTEL_CXX11_MODE__) -#define SMTG_INTEL_CXX11_MODE 0 -#else -#define SMTG_INTEL_CXX11_MODE __INTEL_CXX11_MODE__ -#endif - -#if !defined (__INTEL_COMPILER) -#define SMTG_INTEL_COMPILER 0 -#else -#define SMTG_INTEL_COMPILER __INTEL_COMPILER -#endif - -//----------------------------------------------------------------------------- -// WIN32 AND WIN64 (WINDOWS) -//----------------------------------------------------------------------------- -#if defined (_WIN32) - //----------------------------------------------------------------------------- - // ARM32 AND ARM64 (WINDOWS) - #if (defined(_M_ARM64) || defined(_M_ARM)) - #define SMTG_OS_WINDOWS_ARM 1 - #endif - - #define SMTG_OS_LINUX 0 - #define SMTG_OS_MACOS 0 - #define SMTG_OS_WINDOWS 1 - #define SMTG_OS_IOS 0 - #define SMTG_OS_OSX 0 - - #define SMTG_CPU_X86 _M_IX86 - #define SMTG_CPU_X86_64 _M_AMD64 - #define SMTG_CPU_ARM (_M_ARM && !_M_ARM64) - #define SMTG_CPU_ARM_64 _M_ARM64 - - #define BYTEORDER kLittleEndian - - #define COM_COMPATIBLE 1 - #define PLUGIN_API __stdcall - #define SMTG_PTHREADS 0 - - #define SMTG_EXPORT_SYMBOL __declspec (dllexport) - - #ifndef _CRT_SECURE_NO_WARNINGS - #define _CRT_SECURE_NO_WARNINGS - #endif - - #ifdef _MSC_VER - #pragma warning (disable : 4244) // Conversion from 'type1' to 'type2', possible loss of data. - #pragma warning (disable : 4250) // Inheritance via dominance is allowed - #pragma warning (disable : 4996) // deprecated functions - - #pragma warning (3 : 4189) // local variable is initialized but not referenced - #pragma warning (3 : 4238) // nonstandard extension used : class rvalue used as lvalue - #endif - - #if defined (_WIN64) || defined (_M_ARM64) - #define SMTG_PLATFORM_64 1 - #else - #define SMTG_PLATFORM_64 0 - #endif - - #ifndef WIN32 - #define WIN32 1 - #endif - - #ifdef __cplusplus - #define SMTG_CPP11 __cplusplus >= 201103L || _MSC_VER > 1600 || SMTG_INTEL_CXX11_MODE - #define SMTG_CPP11_STDLIBSUPPORT SMTG_CPP11 - #define SMTG_HAS_NOEXCEPT _MSC_VER >= 1900 || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER >= 1300) - #endif - - #define SMTG_DEPRECATED_ATTRIBUTE(message) __declspec (deprecated ("Is Deprecated: " message)) -//----------------------------------------------------------------------------- -// LINUX -//----------------------------------------------------------------------------- -#elif __gnu_linux__ || __linux__ - #define SMTG_OS_LINUX 1 - #define SMTG_OS_MACOS 0 - #define SMTG_OS_WINDOWS 0 - #define SMTG_OS_IOS 0 - #define SMTG_OS_OSX 0 - - #define SMTG_CPU_X86 __i386__ - #define SMTG_CPU_X86_64 __x86_64__ - #define SMTG_CPU_ARM __arm__ - #define SMTG_CPU_ARM_64 __aarch64__ - - #include - #if __BYTE_ORDER == __LITTLE_ENDIAN - #define BYTEORDER kLittleEndian - #else - #define BYTEORDER kBigEndian - #endif - - #define COM_COMPATIBLE 0 - #define PLUGIN_API - #define SMTG_PTHREADS 1 - - #define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default"))) - - #if __LP64__ - #define SMTG_PLATFORM_64 1 - #else - #define SMTG_PLATFORM_64 0 - #endif - #ifdef __cplusplus - #include - #define SMTG_CPP11 (__cplusplus >= 201103L) - #ifndef SMTG_CPP11 - #error unsupported compiler - #endif - #if defined(__GNUG__) && __GNUG__ < 8 - #define SMTG_CPP11_STDLIBSUPPORT 0 - #else - #define SMTG_CPP11_STDLIBSUPPORT 1 - #endif - #define SMTG_HAS_NOEXCEPT 1 - #endif -//----------------------------------------------------------------------------- -// Mac and iOS -//----------------------------------------------------------------------------- -#elif __APPLE__ - #include - #define SMTG_OS_LINUX 0 - #define SMTG_OS_MACOS 1 - #define SMTG_OS_WINDOWS 0 - #define SMTG_OS_IOS TARGET_OS_IPHONE - #define SMTG_OS_OSX TARGET_OS_MAC && !TARGET_OS_IPHONE - - #define SMTG_CPU_X86 TARGET_CPU_X86 - #define SMTG_CPU_X86_64 TARGET_CPU_X86_64 - #define SMTG_CPU_ARM TARGET_CPU_ARM - #define SMTG_CPU_ARM_64 TARGET_CPU_ARM64 - - #if !SMTG_OS_IOS - #ifndef __CF_USE_FRAMEWORK_INCLUDES__ - #define __CF_USE_FRAMEWORK_INCLUDES__ - #endif - #ifndef TARGET_API_MAC_CARBON - #define TARGET_API_MAC_CARBON 1 - #endif - #endif - #if __LP64__ - #define SMTG_PLATFORM_64 1 - #else - #define SMTG_PLATFORM_64 0 - #endif - #if defined (__BIG_ENDIAN__) - #define BYTEORDER kBigEndian - #else - #define BYTEORDER kLittleEndian - #endif - - #define COM_COMPATIBLE 0 - #define PLUGIN_API - #define SMTG_PTHREADS 1 - - #define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default"))) - - #if !defined(__PLIST__) && !defined(SMTG_DISABLE_DEFAULT_DIAGNOSTICS) - #ifdef __clang__ - #pragma GCC diagnostic ignored "-Wswitch-enum" - #pragma GCC diagnostic ignored "-Wparentheses" - #pragma GCC diagnostic ignored "-Wuninitialized" - #if __clang_major__ >= 3 - #pragma GCC diagnostic ignored "-Wtautological-compare" - #pragma GCC diagnostic ignored "-Wunused-value" - #if __clang_major__ >= 4 || __clang_minor__ >= 1 - #pragma GCC diagnostic ignored "-Wswitch" - #pragma GCC diagnostic ignored "-Wcomment" - #endif - #if __clang_major__ >= 5 - #pragma GCC diagnostic ignored "-Wunsequenced" - #if __clang_minor__ >= 1 - #pragma GCC diagnostic ignored "-Wunused-const-variable" - #endif - #endif - #endif - #endif - #endif - #ifdef __cplusplus - #include - #define SMTG_CPP11 (__cplusplus >= 201103L || SMTG_INTEL_CXX11_MODE) - #if defined (_LIBCPP_VERSION) && SMTG_CPP11 - #define SMTG_CPP11_STDLIBSUPPORT 1 - #define SMTG_HAS_NOEXCEPT 1 - #else - #define SMTG_CPP11_STDLIBSUPPORT 0 - #define SMTG_HAS_NOEXCEPT 0 - #endif - #endif -#else - #pragma error unknown platform -#endif - -//----------------------------------------------------------------------------- -#if !SMTG_RENAME_ASSERT -#undef WINDOWS -#undef MAC -#undef PTHREADS -#undef PLATFORM_64 - -#if SMTG_OS_WINDOWS -#define WINDOWS SMTG_OS_WINDOWS -#endif -#if SMTG_OS_MACOS -#define MAC SMTG_OS_MACOS -#endif -#define PLATFORM_64 SMTG_PLATFORM_64 -#define PTHREADS SMTG_PTHREADS -#endif -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -#if SMTG_CPP11 -#define SMTG_OVERRIDE override -#define SMTG_CONSTEXPR constexpr -#else -#define SMTG_OVERRIDE -#define SMTG_CONSTEXPR -#endif -#if SMTG_HAS_NOEXCEPT -#define SMTG_NOEXCEPT noexcept -#else -#define SMTG_NOEXCEPT -#endif - -//----------------------------------------------------------------------------- -// Deprecation setting -//----------------------------------------------------------------------------- -#ifndef SMTG_DEPRECATED_ATTRIBUTE -#define SMTG_DEPRECATED_ATTRIBUTE(msg) -#endif - -#define SMTG_DEPRECATED_MSG(msg) SMTG_DEPRECATED_ATTRIBUTE(msg) -//----------------------------------------------------------------------------- diff --git a/source/includes/vst3sdk/pluginterfaces/base/fstrdefs.h b/source/includes/vst3sdk/pluginterfaces/base/fstrdefs.h deleted file mode 100644 index 00eaa1de9..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/fstrdefs.h +++ /dev/null @@ -1,289 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/fstrdefs.h -// Created by : Steinberg, 01/2004 -// Description : Definitions for handling strings (Unicode / ASCII / Platforms) -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "ftypes.h" - -//---------------------------------------------------------------------------- -/** string methods defines unicode / ASCII */ -//---------------------------------------------------------------------------- - -// 16 bit string operations -#if SMTG_CPP11 // if c++11 unicode string literals - #define SMTG_CPP11_CAT_PRIVATE_DONT_USE(a,b) a ## b - #if SMTG_OS_WINDOWS - #define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(L,x) - #else - #define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(u,x) - #endif -#else - #include "conststringtable.h" - #define STR16(x) Steinberg::ConstStringTable::instance ()->getString (x) -#endif - -#ifdef UNICODE - #define STR(x) STR16(x) - #define tStrBufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::tchar)) - -#else - #define STR(x) x - #define tStrBufferSize(buffer) (sizeof(buffer)) -#endif - -#define str8BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char8)) -#define str16BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char16)) - -#if SMTG_OS_WINDOWS -#define FORMAT_INT64A "I64d" -#define FORMAT_UINT64A "I64u" - -#elif SMTG_OS_MACOS || SMTG_OS_LINUX -#define FORMAT_INT64A "lld" -#define FORMAT_UINT64A "llu" -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -#ifdef UNICODE -#define FORMAT_INT64W STR(FORMAT_INT64A) -#define FORMAT_UINT64W STR(FORMAT_UINT64A) - -#define FORMAT_INT64 FORMAT_INT64W -#define FORMAT_UINT64 FORMAT_UINT64W -#else -#define FORMAT_INT64 FORMAT_INT64A -#define FORMAT_UINT64 FORMAT_UINT64A -#endif - - -//---------------------------------------------------------------------------- -// newline -//---------------------------------------------------------------------------- -#if SMTG_OS_WINDOWS -#define ENDLINE_A "\r\n" -#define ENDLINE_W STR ("\r\n") -#elif SMTG_OS_MACOS -#define ENDLINE_A "\r" -#define ENDLINE_W STR ("\r") -#elif SMTG_OS_LINUX -#define ENDLINE_A "\n" -#define ENDLINE_W STR ("\n") -#endif - -#ifdef UNICODE -#define ENDLINE ENDLINE_W -#else -#define ENDLINE ENDLINE_A -#endif - -#if SMTG_OS_WINDOWS && !defined(__GNUC__) && defined(_MSC_VER) && (_MSC_VER < 1900) -#define stricmp _stricmp -#define strnicmp _strnicmp -#define snprintf _snprintf -#endif - -namespace Steinberg { - -//---------------------------------------------------------------------------- -static const tchar kEmptyString[] = { 0 }; -static const char8 kEmptyString8[] = { 0 }; -static const char16 kEmptyString16[] = { 0 }; - -#ifdef UNICODE -static const tchar kInfiniteSymbol[] = { 0x221E, 0 }; -#else -static const tchar* const kInfiniteSymbol = STR ("oo"); -#endif - -//---------------------------------------------------------------------------- -template -inline int32 _tstrlen (const T* wcs) -{ - const T* eos = wcs; - - while (*eos++) - ; - - return (int32) (eos - wcs - 1); -} - -inline int32 tstrlen (const tchar* str) {return _tstrlen (str);} -inline int32 strlen8 (const char8* str) {return _tstrlen (str);} -inline int32 strlen16 (const char16* str) {return _tstrlen (str);} - -//---------------------------------------------------------------------------- -template -inline int32 _tstrcmp (const T* src, const T* dst) -{ - while (*src == *dst && *dst) - { - src++; - dst++; - } - - if (*src == 0 && *dst == 0) - return 0; - else if (*src == 0) - return -1; - else if (*dst == 0) - return 1; - else - return (int32) (*src - *dst); -} - -inline int32 tstrcmp (const tchar* src, const tchar* dst) {return _tstrcmp (src, dst);} -inline int32 strcmp8 (const char8* src, const char8* dst) {return _tstrcmp (src, dst);} -inline int32 strcmp16 (const char16* src, const char16* dst) {return _tstrcmp (src, dst);} - -template -inline int32 strcmpT (const T* first, const T* last); - -template <> -inline int32 strcmpT (const char8* first, const char8* last) { return _tstrcmp (first, last); } - -template <> -inline int32 strcmpT (const char16* first, const char16* last) { return _tstrcmp (first, last); } - -//---------------------------------------------------------------------------- -template -inline int32 _tstrncmp (const T* first, const T* last, uint32 count) -{ - if (count == 0) - return 0; - - while (--count && *first && *first == *last) - { - first++; - last++; - } - - if (*first == 0 && *last == 0) - return 0; - else if (*first == 0) - return -1; - else if (*last == 0) - return 1; - else - return (int32) (*first - *last); -} - -inline int32 tstrncmp (const tchar* first, const tchar* last, uint32 count) {return _tstrncmp (first, last, count);} -inline int32 strncmp8 (const char8* first, const char8* last, uint32 count) {return _tstrncmp (first, last, count);} -inline int32 strncmp16 (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count);} - -template -inline int32 strncmpT (const T* first, const T* last, uint32 count); - -template <> -inline int32 strncmpT (const char8* first, const char8* last, uint32 count) { return _tstrncmp (first, last, count); } - -template <> -inline int32 strncmpT (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count); } - -//---------------------------------------------------------------------------- -template -inline T* _tstrcpy (T* dst, const T* src) -{ - T* cp = dst; - while ((*cp++ = *src++) != 0) // copy string - ; - return dst; -} -inline tchar* tstrcpy (tchar* dst, const tchar* src) {return _tstrcpy (dst, src);} -inline char8* strcpy8 (char8* dst, const char8* src) {return _tstrcpy (dst, src);} -inline char16* strcpy16 (char16* dst, const char16* src) {return _tstrcpy (dst, src);} - -//---------------------------------------------------------------------------- -template -inline T* _tstrncpy (T* dest, const T* source, uint32 count) -{ - T* start = dest; - while (count && (*dest++ = *source++) != 0) // copy string - count--; - - if (count) // pad out with zeros - { - while (--count) - *dest++ = 0; - } - return start; -} - -inline tchar* tstrncpy (tchar* dest, const tchar* source, uint32 count) {return _tstrncpy (dest, source, count);} -inline char8* strncpy8 (char8* dest, const char8* source, uint32 count) {return _tstrncpy (dest, source, count);} -inline char16* strncpy16 (char16* dest, const char16* source, uint32 count) {return _tstrncpy (dest, source, count);} - -//---------------------------------------------------------------------------- -template -inline T* _tstrcat (T* dst, const T* src) -{ - T* cp = dst; - - while (*cp) - cp++; // find end of dst - - while ((*cp++ = *src++) != 0) // Copy src to end of dst - ; - - return dst; -} - -inline tchar* tstrcat (tchar* dst, const tchar* src) {return _tstrcat (dst, src); } -inline char8* strcat8 (char8* dst, const char8* src) {return _tstrcat (dst, src); } -inline char16* strcat16 (char16* dst, const char16* src) {return _tstrcat (dst, src); } - -//---------------------------------------------------------------------------- -inline void str8ToStr16 (char16* dst, const char8* src, int32 n = -1) -{ - int32 i = 0; - for (;;) - { - if (i == n) - { - dst[i] = 0; - return; - } - -#if BYTEORDER == kBigEndian - char8* pChr = (char8*)&dst[i]; - pChr[0] = 0; - pChr[1] = src[i]; -#else - dst[i] = static_cast (src[i]); -#endif - if (src[i] == 0) - break; - i++; - } - - while (n > i) - { - dst[i] = 0; - i++; - } -} - -//------------------------------------------------------------------------ -inline bool FIDStringsEqual (FIDString id1, FIDString id2) -{ - return (id1 && id2) ? (strcmp8 (id1, id2) == 0) : false; -} - -static const uint32 kPrintfBufferSize = 4096; - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/ftypes.h b/source/includes/vst3sdk/pluginterfaces/base/ftypes.h deleted file mode 100644 index 1f95bd116..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/ftypes.h +++ /dev/null @@ -1,194 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/ftypes.h -// Created by : Steinberg, 01/2004 -// Description : Basic data types -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "fplatform.h" - -//#define UNICODE_OFF // disable / enable unicode - -#ifdef UNICODE_OFF - #ifdef UNICODE - #undef UNICODE - #endif -#else - #define UNICODE 1 -#endif - -#ifdef UNICODE -#define _UNICODE 1 -#endif - -namespace Steinberg -{ -//----------------------------------------------------------------- -// Integral Types - typedef char int8; - typedef unsigned char uint8; - typedef unsigned char uchar; - - typedef short int16; - typedef unsigned short uint16; - -#if SMTG_OS_WINDOWS && !defined(__GNUC__) - typedef long int32; - typedef unsigned long uint32; -#else - typedef int int32; - typedef unsigned int uint32; -#endif - - static const int32 kMaxLong = 0x7fffffff; - static const int32 kMinLong = (-0x7fffffff - 1); - static const int32 kMaxInt32 = kMaxLong; - static const int32 kMinInt32 = kMinLong; - static const uint32 kMaxInt32u = 0xffffffff; - -#if SMTG_OS_WINDOWS && !defined(__GNUC__) - typedef __int64 int64; - typedef unsigned __int64 uint64; - static const int64 kMaxInt64 = 9223372036854775807i64; - static const int64 kMinInt64 = (-9223372036854775807i64 - 1); -#else - typedef long long int64; - typedef unsigned long long uint64; - static const int64 kMaxInt64 = 0x7fffffffffffffffLL; - static const int64 kMinInt64 = (-0x7fffffffffffffffLL-1); -#endif - static const uint64 kMaxInt64u = uint64 (0xffffffff) | (uint64 (0xffffffff) << 32); - -//----------------------------------------------------------------- -// other Semantic Types - typedef int64 TSize; // byte (or other) sizes - typedef int32 tresult; // result code -//----------------------------------------------------------------- - static const float kMaxFloat = 3.40282346638528860E38; - static const double kMaxDouble = 1.7976931348623158E308; - -#if SMTG_PLATFORM_64 - typedef uint64 TPtrInt; -#else - typedef uint32 TPtrInt; -#endif - -//------------------------------------------------------------------ -// Boolean - typedef uint8 TBool; - -//------------------------------------------------------------------ -// Char / Strings - typedef char char8; -#ifdef _NATIVE_WCHAR_T_DEFINED - typedef __wchar_t char16; -#elif defined(__MINGW32__) - typedef wchar_t char16; -#elif SMTG_CPP11 - typedef char16_t char16; -#else - typedef int16 char16; -#endif - -#ifdef UNICODE - typedef char16 tchar; -#else - typedef char8 tchar; -#endif - - typedef const char8* CStringA; - typedef const char16* CStringW; - typedef const tchar* CString; - inline bool strEmpty (const tchar* str) { return (!str || *str == 0); } - inline bool str8Empty (const char8* str) { return (!str || *str == 0); } - inline bool str16Empty (const char16* str) { return (!str || *str == 0); } - - typedef const char8* FIDString; // identifier as string (used for attributes, messages) - - const FIDString kPlatformStringWin = "WIN"; - const FIDString kPlatformStringMac = "MAC"; - const FIDString kPlatformStringIOS = "IOS"; - const FIDString kPlatformStringLinux = "Linux"; -#if SMTG_OS_WINDOWS - const FIDString kPlatformString = kPlatformStringWin; -#elif SMTG_OS_IOS - const FIDString kPlatformString = kPlatformStringIOS; -#elif SMTG_OS_MACOS - const FIDString kPlatformString = kPlatformStringMac; -#elif SMTG_OS_LINUX - const FIDString kPlatformString = kPlatformStringLinux; -#endif - -//------------------------------------------------------------------------ -/** Coordinates */ - typedef int32 UCoord; - static const UCoord kMaxCoord = ((UCoord)0x7FFFFFFF); - static const UCoord kMinCoord = ((UCoord)-0x7FFFFFFF); -} // namespace Steinberg - - -//---------------------------------------------------------------------------- -/** Byte-order Conversion Macros -*/ -#define SWAP_32(l) { \ - unsigned char* p = (unsigned char*)& (l); \ - unsigned char t; \ - t = p[0]; p[0] = p[3]; p[3] = t; t = p[1]; p[1] = p[2]; p[2] = t; } - -#define SWAP_16(w) { \ - unsigned char* p = (unsigned char*)& (w); \ - unsigned char t; \ - t = p[0]; p[0] = p[1]; p[1] = t; } - -#define SWAP_64(i) { \ - unsigned char* p = (unsigned char*)& (i); \ - unsigned char t; \ - t = p[0]; p[0] = p[7]; p[7] = t; t = p[1]; p[1] = p[6]; p[6] = t; \ - t = p[2]; p[2] = p[5]; p[5] = t; t = p[3]; p[3] = p[4]; p[4] = t;} - -namespace Steinberg -{ - static inline void FSwap (int8&) {} - static inline void FSwap (uint8&) {} - static inline void FSwap (int16& i16) { SWAP_16 (i16) } - static inline void FSwap (uint16& i16) { SWAP_16 (i16) } - static inline void FSwap (int32& i32) { SWAP_32 (i32) } - static inline void FSwap (uint32& i32) { SWAP_32 (i32) } - static inline void FSwap (int64& i64) { SWAP_64 (i64) } - static inline void FSwap (uint64& i64) { SWAP_64 (i64) } -} - -// always inline macros (only when RELEASE is 1) -//---------------------------------------------------------------------------- -#if RELEASE - #if SMTG_OS_MACOS || SMTG_OS_LINUX || defined(__MINGW32__) - #define SMTG_ALWAYS_INLINE __inline__ __attribute__((__always_inline__)) - #define SMTG_NEVER_INLINE __attribute__((noinline)) - #elif SMTG_OS_WINDOWS - #define SMTG_ALWAYS_INLINE __forceinline - #define SMTG_NEVER_INLINE __declspec(noinline) - #endif -#endif - -#ifndef SMTG_ALWAYS_INLINE - #define SMTG_ALWAYS_INLINE inline -#endif -#ifndef SMTG_NEVER_INLINE - #define SMTG_NEVER_INLINE -#endif - -#ifndef SMTG_CPP11_STDLIBSUPPORT -// Enable this for old compilers -// #define nullptr NULL -#endif diff --git a/source/includes/vst3sdk/pluginterfaces/base/funknown.cpp b/source/includes/vst3sdk/pluginterfaces/base/funknown.cpp deleted file mode 100644 index 23ca64e6c..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/funknown.cpp +++ /dev/null @@ -1,492 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/funknown.cpp -// Created by : Steinberg, 01/2004 -// Description : Basic Interface -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#include "funknown.h" - -#include "fstrdefs.h" - -#include - -#if SMTG_OS_WINDOWS -#include -#endif - -#if SMTG_OS_MACOS -#include - -#if !defined (SMTG_USE_STDATOMIC_H) -#if defined(MAC_OS_X_VERSION_10_11) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) -#define SMTG_USE_STDATOMIC_H (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_11) -#else -#define SMTG_USE_STDATOMIC_H 0 -#endif -#endif // !defined (SMTG_USE_STDATOMIC_H) - -#if !SMTG_USE_STDATOMIC_H -#include -#if defined(__GNUC__) && (__GNUC__ >= 4) && !__LP64__ -// on 32 bit Mac OS X we can safely ignore the format warnings as sizeof(int) == sizeof(long) -#pragma GCC diagnostic ignored "-Wformat" -#endif -#endif // !SMTG_USE_STDATOMIC_H -#endif // SMTG_OS_MACOS - -#if SMTG_OS_LINUX -#if !defined (SMTG_USE_STDATOMIC_H) -#if defined (__ANDROID__) || defined(_LIBCPP_VERSION) -#define SMTG_USE_STDATOMIC_H 1 -#else -#include -#endif -#endif // !defined (SMTG_USE_STDATOMIC_H) -#include -#endif - -#if defined (SMTG_USE_STDATOMIC_H) && SMTG_USE_STDATOMIC_H -#include -#endif - -namespace Steinberg { - -//------------------------------------------------------------------------ -#if COM_COMPATIBLE -#if SMTG_OS_WINDOWS -#define GuidStruct GUID -#else -struct GuidStruct -{ - uint32 Data1; - uint16 Data2; - uint16 Data3; - uint8 Data4[8]; -}; -#endif -#endif - -static void toString8 (char8* string, const char* data, int32 i1, int32 i2); -static void fromString8 (const char8* string, char* data, int32 i1, int32 i2); -static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4); - -//------------------------------------------------------------------------ -// FUnknownPrivate -//------------------------------------------------------------------------ -namespace FUnknownPrivate { -//------------------------------------------------------------------------ -int32 PLUGIN_API atomicAdd (int32& var, int32 d) -{ -#if SMTG_USE_STDATOMIC_H - return atomic_fetch_add (reinterpret_cast (&var), d) + d; -#else -#if SMTG_OS_WINDOWS -#ifdef __MINGW32__ - return InterlockedExchangeAdd (reinterpret_cast(&var), d) + d; -#else - return InterlockedExchangeAdd ((LONG*)&var, d) + d; -#endif -#elif SMTG_OS_MACOS - return OSAtomicAdd32Barrier (d, (int32_t*)&var); -#elif defined(__ANDROID__) - return atomic_fetch_add ((atomic_int*)&var, d) + d; -#elif SMTG_OS_LINUX - __gnu_cxx::__atomic_add (&var, d); - return var; -#else -#warning implement me! - var += d; - return var; -#endif -#endif -} -} // FUnknownPrivate - -//------------------------------------------------------------------------ -// FUID implementation -//------------------------------------------------------------------------ - -FUID::FUID () -{ - memset (data, 0, sizeof (TUID)); -} - -//------------------------------------------------------------------------ -FUID::FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4) -{ - from4Int (l1, l2, l3, l4); -} - -//------------------------------------------------------------------------ -FUID::FUID (const FUID& f) -{ - memcpy (data, f.data, sizeof (TUID)); -} - -//------------------------------------------------------------------------ -#if SMTG_CPP11_STDLIBSUPPORT -FUID::FUID (FUID&& other) -{ - memcpy (data, other.data, sizeof (TUID)); -} - -FUID& FUID::operator= (FUID&& other) -{ - memcpy (data, other.data, sizeof (TUID)); - return *this; -} -#endif - -//------------------------------------------------------------------------ -bool FUID::generate () -{ -#if SMTG_OS_WINDOWS -#if defined(_M_ARM64) || defined(_M_ARM) - //#warning implement me! - return false; -#else - GUID guid; - HRESULT hr = CoCreateGuid (&guid); - switch (hr) - { - case RPC_S_OK: memcpy (data, (char*)&guid, sizeof (TUID)); return true; - - case (HRESULT)RPC_S_UUID_LOCAL_ONLY: - default: return false; - } -#endif - -#elif SMTG_OS_MACOS - CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault); - if (uuid) - { - CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid); - memcpy (data, (char*)&bytes, sizeof (TUID)); - CFRelease (uuid); - return true; - } - return false; - -#elif SMTG_OS_LINUX - srand ((size_t)this); - for (int32 i = 0; i < 16; i++) - data[i] = static_cast(rand ()); - return true; -#else -#warning implement me! - return false; -#endif -} - -//------------------------------------------------------------------------ -bool FUID::isValid () const -{ - TUID nulluid = {0}; - - return memcmp (data, nulluid, sizeof (TUID)) != 0; -} - -//------------------------------------------------------------------------ -FUID& FUID::operator= (const FUID& f) -{ - memcpy (data, f.data, sizeof (TUID)); - return *this; -} - -//------------------------------------------------------------------------ -void FUID::from4Int (uint32 l1, uint32 l2, uint32 l3, uint32 l4) -{ -#if COM_COMPATIBLE - data [0] = (char)((l1 & 0x000000FF) ); - data [1] = (char)((l1 & 0x0000FF00) >> 8); - data [2] = (char)((l1 & 0x00FF0000) >> 16); - data [3] = (char)((l1 & 0xFF000000) >> 24); - data [4] = (char)((l2 & 0x00FF0000) >> 16); - data [5] = (char)((l2 & 0xFF000000) >> 24); - data [6] = (char)((l2 & 0x000000FF) ); - data [7] = (char)((l2 & 0x0000FF00) >> 8); - data [8] = (char)((l3 & 0xFF000000) >> 24); - data [9] = (char)((l3 & 0x00FF0000) >> 16); - data [10] = (char)((l3 & 0x0000FF00) >> 8); - data [11] = (char)((l3 & 0x000000FF) ); - data [12] = (char)((l4 & 0xFF000000) >> 24); - data [13] = (char)((l4 & 0x00FF0000) >> 16); - data [14] = (char)((l4 & 0x0000FF00) >> 8); - data [15] = (char)((l4 & 0x000000FF) ); -#else - data [0] = (char)((l1 & 0xFF000000) >> 24); - data [1] = (char)((l1 & 0x00FF0000) >> 16); - data [2] = (char)((l1 & 0x0000FF00) >> 8); - data [3] = (char)((l1 & 0x000000FF) ); - data [4] = (char)((l2 & 0xFF000000) >> 24); - data [5] = (char)((l2 & 0x00FF0000) >> 16); - data [6] = (char)((l2 & 0x0000FF00) >> 8); - data [7] = (char)((l2 & 0x000000FF) ); - data [8] = (char)((l3 & 0xFF000000) >> 24); - data [9] = (char)((l3 & 0x00FF0000) >> 16); - data [10] = (char)((l3 & 0x0000FF00) >> 8); - data [11] = (char)((l3 & 0x000000FF) ); - data [12] = (char)((l4 & 0xFF000000) >> 24); - data [13] = (char)((l4 & 0x00FF0000) >> 16); - data [14] = (char)((l4 & 0x0000FF00) >> 8); - data [15] = (char)((l4 & 0x000000FF) ); -#endif -} - -//------------------------------------------------------------------------ -void FUID::to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const -{ - d1 = getLong1 (); - d2 = getLong2 (); - d3 = getLong3 (); - d4 = getLong4 (); -} - -//------------------------------------------------------------------------ -uint32 FUID::getLong1 () const -{ -#if COM_COMPATIBLE - return makeLong (data[3], data[2], data[1], data[0]); -#else - return makeLong (data[0], data[1], data[2], data[3]); -#endif -} - -//------------------------------------------------------------------------ -uint32 FUID::getLong2 () const -{ -#if COM_COMPATIBLE - return makeLong (data[5], data[4], data[7], data[6]); -#else - return makeLong (data[4], data[5], data[6], data[7]); -#endif -} - -//------------------------------------------------------------------------ -uint32 FUID::getLong3 () const -{ -#if COM_COMPATIBLE - return makeLong (data[8], data[9], data[10], data[11]); -#else - return makeLong (data[8], data[9], data[10], data[11]); -#endif -} - -//------------------------------------------------------------------------ -uint32 FUID::getLong4 () const -{ -#if COM_COMPATIBLE - return makeLong (data[12], data[13], data[14], data[15]); -#else - return makeLong (data[12], data[13], data[14], data[15]); -#endif -} - -//------------------------------------------------------------------------ -void FUID::toString (char8* string) const -{ - if (!string) - return; - -#if COM_COMPATIBLE - auto* g = (GuidStruct*)data; - - char8 s[17]; - Steinberg::toString8 (s, data, 8, 16); - - sprintf (string, "%08X%04X%04X%s", g->Data1, g->Data2, g->Data3, s); -#else - Steinberg::toString8 (string, data, 0, 16); -#endif -} - -//------------------------------------------------------------------------ -bool FUID::fromString (const char8* string) -{ - if (!string || !*string) - return false; - if (strlen (string) != 32) - return false; - -#if COM_COMPATIBLE - GuidStruct g; - char s[33]; - - strcpy (s, string); - s[8] = 0; - sscanf (s, "%x", &g.Data1); - strcpy (s, string + 8); - s[4] = 0; - sscanf (s, "%hx", &g.Data2); - strcpy (s, string + 12); - s[4] = 0; - sscanf (s, "%hx", &g.Data3); - - memcpy (data, &g, 8); - Steinberg::fromString8 (string + 16, data, 8, 16); -#else - Steinberg::fromString8 (string, data, 0, 16); -#endif - - return true; -} - -//------------------------------------------------------------------------ -bool FUID::fromRegistryString (const char8* string) -{ - if (!string || !*string) - return false; - if (strlen (string) != 38) - return false; - -// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef} - -#if COM_COMPATIBLE - GuidStruct g; - char8 s[10]; - - strncpy (s, string + 1, 8); - s[8] = 0; - sscanf (s, "%x", &g.Data1); - strncpy (s, string + 10, 4); - s[4] = 0; - sscanf (s, "%hx", &g.Data2); - strncpy (s, string + 15, 4); - s[4] = 0; - sscanf (s, "%hx", &g.Data3); - memcpy (data, &g, 8); - - Steinberg::fromString8 (string + 20, data, 8, 10); - Steinberg::fromString8 (string + 25, data, 10, 16); -#else - Steinberg::fromString8 (string + 1, data, 0, 4); - Steinberg::fromString8 (string + 10, data, 4, 6); - Steinberg::fromString8 (string + 15, data, 6, 8); - Steinberg::fromString8 (string + 20, data, 8, 10); - Steinberg::fromString8 (string + 25, data, 10, 16); -#endif - - return true; -} - -//------------------------------------------------------------------------ -void FUID::toRegistryString (char8* string) const -{ -// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef} - -#if COM_COMPATIBLE - auto* g = (GuidStruct*)data; - - char8 s1[5]; - Steinberg::toString8 (s1, data, 8, 10); - - char8 s2[13]; - Steinberg::toString8 (s2, data, 10, 16); - - sprintf (string, "{%08X-%04X-%04X-%s-%s}", g->Data1, g->Data2, g->Data3, s1, s2); -#else - char8 s1[9]; - Steinberg::toString8 (s1, data, 0, 4); - char8 s2[5]; - Steinberg::toString8 (s2, data, 4, 6); - char8 s3[5]; - Steinberg::toString8 (s3, data, 6, 8); - char8 s4[5]; - Steinberg::toString8 (s4, data, 8, 10); - char8 s5[13]; - Steinberg::toString8 (s5, data, 10, 16); - - sprintf (string, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5); -#endif -} - -//------------------------------------------------------------------------ -void FUID::print (char8* string, int32 style) const -{ - if (!string) // no string: debug output - { - char8 str[128]; - print (str, style); - -#if SMTG_OS_WINDOWS - OutputDebugStringA (str); - OutputDebugStringA ("\n"); -#else - fprintf (stdout, "%s\n", str); -#endif - return; - } - - uint32 l1, l2, l3, l4; - to4Int (l1, l2, l3, l4); - - switch (style) - { - case kINLINE_UID: - sprintf (string, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); - break; - - case kDECLARE_UID: - sprintf (string, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); - break; - - case kFUID: - sprintf (string, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); - break; - - case kCLASS_UID: - default: - sprintf (string, "DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, - l2, l3, l4); - break; - } -} - -//------------------------------------------------------------------------ -// helpers -//------------------------------------------------------------------------ -static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4) -{ - return (uint32 (b1) << 24) | (uint32 (b2) << 16) | (uint32 (b3) << 8) | uint32 (b4); -} - -//------------------------------------------------------------------------ -static void toString8 (char8* string, const char* data, int32 i1, int32 i2) -{ - *string = 0; - for (int32 i = i1; i < i2; i++) - { - char8 s[3]; - sprintf (s, "%02X", (uint8)data[i]); - strcat (string, s); - } -} - -//------------------------------------------------------------------------ -static void fromString8 (const char8* string, char* data, int32 i1, int32 i2) -{ - for (int32 i = i1; i < i2; i++) - { - char8 s[3]; - s[0] = *string++; - s[1] = *string++; - s[2] = 0; - - int32 d = 0; - sscanf (s, "%2x", &d); - data[i] = (char)d; - } -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/funknown.h b/source/includes/vst3sdk/pluginterfaces/base/funknown.h deleted file mode 100644 index d5a5cfc62..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/funknown.h +++ /dev/null @@ -1,550 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/funknown.h -// Created by : Steinberg, 01/2004 -// Description : Basic Interface -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/fplatform.h" -#include "pluginterfaces/base/ftypes.h" -#include "pluginterfaces/base/smartpointer.h" -#include - -#if SMTG_CPP11_STDLIBSUPPORT -#include -#endif - -//------------------------------------------------------------------------ -/*! \defgroup pluginBase Basic Interfaces -*/ - -//------------------------------------------------------------------------ -// Unique Identifier macros -//------------------------------------------------------------------------ - -#if COM_COMPATIBLE -#define INLINE_UID(l1, l2, l3, l4) \ -{ \ - (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \ -} -#else -#define INLINE_UID(l1, l2, l3, l4) \ -{ \ - (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \ - (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \ -} -#endif - -//------------------------------------------------------------------------ -#define DECLARE_UID(name, l1, l2, l3, l4) ::Steinberg::TUID name = INLINE_UID (l1, l2, l3, l4); - -//------------------------------------------------------------------------ -#define EXTERN_UID(name) extern const ::Steinberg::TUID name; - -#ifdef INIT_CLASS_IID -#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \ - static const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4); \ - \ -const ::Steinberg::FUID ClassName::iid (ClassName##_iid); -#else -#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \ - static const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4); -#endif - -#define DEF_CLASS_IID(ClassName) const ::Steinberg::FUID ClassName::iid (ClassName##_iid); - -#define INLINE_UID_OF(ClassName) ClassName##_iid - -#define INLINE_UID_FROM_FUID(x) \ - INLINE_UID (x.getLong1 (), x.getLong2 (), x.getLong3 (), x.getLong4 ()) - -//------------------------------------------------------------------------ -// FUnknown implementation macros -//------------------------------------------------------------------------ - -#define DECLARE_FUNKNOWN_METHODS \ -public: \ - virtual ::Steinberg::tresult PLUGIN_API queryInterface (const ::Steinberg::TUID _iid, void** obj) SMTG_OVERRIDE; \ - virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE; \ - virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE; \ -protected : \ - ::Steinberg::int32 __funknownRefCount; \ -public: - -//------------------------------------------------------------------------ - -#define DELEGATE_REFCOUNT(ClassName) \ -public: \ - virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return ClassName::addRef (); } \ - virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE { return ClassName::release (); } - -//------------------------------------------------------------------------ -#define IMPLEMENT_REFCOUNT(ClassName) \ -::Steinberg::uint32 PLUGIN_API ClassName::addRef () \ -{ \ - return ::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, 1); \ -} \ -::Steinberg::uint32 PLUGIN_API ClassName::release () \ -{ \ - if (::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, -1) == 0) \ - { \ - delete this; \ - return 0; \ - } \ - return __funknownRefCount; \ -} - -//------------------------------------------------------------------------ -#define FUNKNOWN_CTOR { __funknownRefCount = 1; } -#if SMTG_FUNKNOWN_DTOR_ASSERT -#include -#define FUNKNOWN_DTOR { assert (__funknownRefCount == 0); } -#else -#define FUNKNOWN_DTOR -#endif - -//------------------------------------------------------------------------ -#define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName) \ -if (::Steinberg::FUnknownPrivate::iidEqual (iid, InterfaceIID)) \ -{ \ - addRef (); \ - *obj = static_cast< InterfaceName* >(this); \ - return ::Steinberg::kResultOk; \ -} - -//------------------------------------------------------------------------ -#define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID) \ -::Steinberg::tresult PLUGIN_API ClassName::queryInterface (const ::Steinberg::TUID _iid, void** obj)\ -{ \ - QUERY_INTERFACE (_iid, obj, ::Steinberg::FUnknown::iid, InterfaceName) \ - QUERY_INTERFACE (_iid, obj, ClassIID, InterfaceName) \ - *obj = nullptr; \ - return ::Steinberg::kNoInterface; \ -} - -//------------------------------------------------------------------------ -#define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \ - IMPLEMENT_REFCOUNT (ClassName) \ - IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID) - -//------------------------------------------------------------------------ -// Result Codes -//------------------------------------------------------------------------ - -namespace Steinberg { - -//------------------------------------------------------------------------ -#if COM_COMPATIBLE -#if SMTG_OS_WINDOWS -enum -{ - kNoInterface = static_cast(0x80004002L), // E_NOINTERFACE - kResultOk = static_cast(0x00000000L), // S_OK - kResultTrue = kResultOk, - kResultFalse = static_cast(0x00000001L), // S_FALSE - kInvalidArgument = static_cast(0x80070057L), // E_INVALIDARG - kNotImplemented = static_cast(0x80004001L), // E_NOTIMPL - kInternalError = static_cast(0x80004005L), // E_FAIL - kNotInitialized = static_cast(0x8000FFFFL), // E_UNEXPECTED - kOutOfMemory = static_cast(0x8007000EL) // E_OUTOFMEMORY -}; -#else -enum -{ - kNoInterface = static_cast(0x80000004L), // E_NOINTERFACE - kResultOk = static_cast(0x00000000L), // S_OK - kResultTrue = kResultOk, - kResultFalse = static_cast(0x00000001L), // S_FALSE - kInvalidArgument = static_cast(0x80000003L), // E_INVALIDARG - kNotImplemented = static_cast(0x80000001L), // E_NOTIMPL - kInternalError = static_cast(0x80000008L), // E_FAIL - kNotInitialized = static_cast(0x8000FFFFL), // E_UNEXPECTED - kOutOfMemory = static_cast(0x80000002L) // E_OUTOFMEMORY -}; -#endif -#else -enum -{ - kNoInterface = -1, - kResultOk, - kResultTrue = kResultOk, - kResultFalse, - kInvalidArgument, - kNotImplemented, - kInternalError, - kNotInitialized, - kOutOfMemory -}; -#endif - -//------------------------------------------------------------------------ -typedef int64 LARGE_INT; // obsolete - -//------------------------------------------------------------------------ -// FUID class declaration -//------------------------------------------------------------------------ -typedef int8 TUID[16]; ///< plain UID type - -//------------------------------------------------------------------------ -/* FUnknown private */ -namespace FUnknownPrivate { -SMTG_ALWAYS_INLINE bool iidEqual (const void* iid1, const void* iid2) -{ - const uint64* p1 = reinterpret_cast (iid1); - const uint64* p2 = reinterpret_cast (iid2); - return p1[0] == p2[0] && p1[1] == p2[1]; -} - -int32 PLUGIN_API atomicAdd (int32& value, int32 amount); -} - -//------------------------------------------------------------------------ -/** Handling 16 Byte Globally Unique Identifiers. -\ingroup pluginBase - -Each interface declares its identifier as static member inside the interface -namespace (e.g. FUnknown::iid). -*/ -class FUID -{ -public: -//------------------------------------------------------------------------ - FUID (); - FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4); - FUID (const FUID&); - virtual ~FUID () {} - -#if SMTG_CPP11_STDLIBSUPPORT - FUID (FUID&& other); - FUID& operator= (FUID&& other); -#endif - - /** Generates a new Unique Identifier (UID). - Will return true for success. If the return value is false, either no - UID is generated or the UID is not guaranteed to be unique worldwide. */ - bool generate (); - - /** Checks if the UID data is valid. - The default constructor initializes the memory with zeros. */ - bool isValid () const; - - FUID& operator = (const FUID& f); - bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); } - bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; } - bool operator != (const FUID& f) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); } - - uint32 getLong1 () const; - uint32 getLong2 () const; - uint32 getLong3 () const; - uint32 getLong4 () const; - - void from4Int (uint32 d1, uint32 d2, uint32 d3, uint32 d4); - void to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const; - - typedef char8 String[33]; - - /** Converts UID to a string. - The string will be 32 characters long, representing the hexadecimal values - of each data byte (e.g. "9127BE30160E4BB69966670AA6087880"). - - Typical use-case is: - \code{.cpp} - char8[33] strUID = {0}; - FUID uid; - if (uid.generate ()) - uid.toString (strUID); - \endcode - */ - void toString (char8* string) const; - - /** Sets the UID data from a string. - The string has to be 32 characters long, where each character-pair is - the ASCII-encoded hexadecimal value of the corresponding data byte. */ - bool fromString (const char8* string); - - /** Converts UID to a string in Microsoft(R) OLE format. - (e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") */ - void toRegistryString (char8* string) const; - - /** Sets the UID data from a string in Microsoft(R) OLE format. */ - bool fromRegistryString (const char8* string); - - enum UIDPrintStyle - { - kINLINE_UID, ///< "INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" - kDECLARE_UID, ///< "DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" - kFUID, ///< "FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)" - kCLASS_UID ///< "DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)" - }; - /** Prints the UID to a string (or debug output if string is NULL). - \param string is the output string if not NULL. - \param style can be chosen from the FUID::UIDPrintStyle enumeration. */ - void print (char8* string = nullptr, int32 style = kINLINE_UID) const; - - template - inline explicit FUID (const int8 (&uid)[N]) - { -#if SMTG_CPP11_STDLIBSUPPORT - static_assert (N == sizeof (TUID), "only TUID allowed"); -#endif - memcpy (data, uid, sizeof (TUID)); - } - inline void toTUID (TUID result) const { memcpy (result, data, sizeof (TUID)); } - inline operator const TUID& () const { return data; } - inline const TUID& toTUID () const { return data; } - - static FUID fromTUID (const TUID uid) - { - FUID res; - if (uid) - memcpy (res.data, uid, sizeof (TUID)); - return res; - } - -//------------------------------------------------------------------------ -protected: - TUID data; -}; - -#if SMTG_CPP11_STDLIBSUPPORT -template -inline bool operator== (const FUID& f1, T f2) -{ - static_assert ( - std::is_same::type, FUID>::value, - "Do not compare a FUID with a TUID directly. Either convert the TUID to a FUID and compare them or use FUnknownPrivate::iidEqual"); - return f1.operator== (f2); -} -#endif - -//------------------------------------------------------------------------ -// FUnknown -//------------------------------------------------------------------------ -/** The basic interface of all interfaces. -\ingroup pluginBase - -- The FUnknown::queryInterface method is used to retrieve pointers to other - interfaces of the object. -- FUnknown::addRef and FUnknown::release manage the lifetime of the object. - If no more references exist, the object is destroyed in memory. - -Interfaces are identified by 16 byte Globally Unique Identifiers. -The SDK provides a class called FUID for this purpose. - -\ref howtoClass -*/ -class FUnknown -{ -public: - -//------------------------------------------------------------------------ - /** Query for a pointer to the specified interface. - Returns kResultOk on success or kNoInterface if the object does not implement the interface. - The object has to call addRef when returning an interface. - \param _iid : (in) 16 Byte interface identifier (-> FUID) - \param obj : (out) On return, *obj points to the requested interface */ - virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) = 0; - - /** Adds a reference and returns the new reference count. - \par Remarks: - The initial reference count after creating an object is 1. */ - virtual uint32 PLUGIN_API addRef () = 0; - - /** Releases a reference and returns the new reference count. - If the reference count reaches zero, the object will be destroyed in memory. */ - virtual uint32 PLUGIN_API release () = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -//------------------------------------------------------------------------ -}; - - -DECLARE_CLASS_IID (FUnknown, 0x00000000, 0x00000000, 0xC0000000, 0x00000046) - -//------------------------------------------------------------------------ -// FUnknownPtr -//------------------------------------------------------------------------ -/** FUnknownPtr - automatic interface conversion and smart pointer in one. - This template class can be used for interface conversion like this: - \code{.cpp} -IPtr path = owned (FHostCreate (IPath, hostClasses)); -FUnknownPtr path2 (path); // does a query interface for IPath2 -if (path2) - ... - \endcode -*/ -template -class FUnknownPtr : public IPtr -{ -public: -//------------------------------------------------------------------------ - inline FUnknownPtr (FUnknown* unknown); // query interface - inline FUnknownPtr (const FUnknownPtr& p) : IPtr (p) {} - inline FUnknownPtr () {} - - inline FUnknownPtr& operator= (const FUnknownPtr& p) - { - IPtr::operator= (p); - return *this; - } - inline I* operator= (FUnknown* unknown); - inline I* getInterface () { return this->ptr; } - -#if SMTG_CPP11_STDLIBSUPPORT - inline FUnknownPtr (FUnknownPtr&& p) SMTG_NOEXCEPT : IPtr (std::move (p)) {} - inline FUnknownPtr& operator= (FUnknownPtr&& p) SMTG_NOEXCEPT - { - IPtr::operator= (std::move (p)); - return *this; - } -#endif -}; - -#if SMTG_CPP11_STDLIBSUPPORT - -//------------------------------------------------------------------------ -namespace FUnknownPrivate { - -template -struct Void : std::false_type -{ - using Type = void; -}; - -template -using VoidT = typename Void::Type; - -//------------------------------------------------------------------------ -/** - * This type trait detects if a class has an @c iid member variable. It is used to detect if - * the FUID and DECLARE_CLASS_IID method or the SKI::UID method is used. - */ -template -struct HasIIDType : std::false_type -{ -}; - -//------------------------------------------------------------------------ -template -struct HasIIDType> : std::true_type -{ -}; - -//------------------------------------------------------------------------ -} // FUnknownPrivate - -//------------------------------------------------------------------------ -/** @return the TUID for a SKI interface which uses the SKI::UID method. */ -template ::value>::type* = nullptr> -const TUID& getTUID () -{ - return T::IID::toTUID (); -} - -//------------------------------------------------------------------------ -/** @return the TUID for a SKI interface which uses the FUID and DECLARE_CLASS_IID method. */ -template ::value>::type* = nullptr> -const TUID& getTUID () -{ - return T::iid.toTUID (); -} - -#else // SMTG_CPP11_STDLIBSUPPORT - -template -const TUID& getTUID () -{ - return T::iid.toTUID (); -} - -#endif // SMTG_CPP11_STDLIBSUPPORT - -//------------------------------------------------------------------------ -template -inline FUnknownPtr::FUnknownPtr (FUnknown* unknown) -{ - if (unknown && unknown->queryInterface (getTUID (), (void**)&this->ptr) != kResultOk) - this->ptr = 0; -} - -//------------------------------------------------------------------------ -template -inline I* FUnknownPtr::operator= (FUnknown* unknown) -{ - I* newPtr = 0; - if (unknown && unknown->queryInterface (getTUID (), (void**)&newPtr) == kResultOk) - { - OPtr rel (newPtr); - return IPtr::operator= (newPtr); - } - - return IPtr::operator= (0); -} - -//------------------------------------------------------------------------ -// FReleaser (obsolete) -//------------------------------------------------------------------------ -/** Release an interface using automatic object (obsolete). -This class is obsolete and is only kept for compatibility. -The replacement for FReleaser is OPtr. - -Usage example with FReleaser: -\code{.cpp} -void someFunction () -{ - IPath* path = pathCreateMethod (); - FReleaser releaser (path); - .... do something with path... - .... path not used anymore, releaser will destroy it when leaving function scope -} -\endcode -Usage example with OPtr: -\code{.cpp} -void someFunction () -{ - OPtr path = pathCreateMethod (); - .... do something with path... - .... path not used anymore, OPtr will destroy it when leaving function scope -} -\endcode -*/ -struct FReleaser -{ - FReleaser (FUnknown* u) : u (u) {} - ~FReleaser () - { - if (u) - u->release (); - } - FUnknown* u; -}; - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/futils.h b/source/includes/vst3sdk/pluginterfaces/base/futils.h deleted file mode 100644 index 5ce9e295a..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/futils.h +++ /dev/null @@ -1,98 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/futils.h -// Created by : Steinberg, 01/2004 -// Description : Basic utilities -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/ftypes.h" - -namespace Steinberg { -//---------------------------------------------------------------------------- -// min/max/etc. template functions -template -inline const T& Min (const T& a, const T& b) -{ - return b < a ? b : a; -} - -template -inline const T& Max (const T& a, const T& b) -{ - return a < b ? b : a; -} - -template -inline T Abs (const T& value) -{ - return (value >= (T)0) ? value : -value; -} - -template -inline T Sign (const T& value) -{ - return (value == (T)0) ? 0 : ((value >= (T)0) ? 1 : -1); -} - -template -inline T Bound (T minval, T maxval, T x) -{ - if (x < minval) - return minval; - else if (x > maxval) - return maxval; - return x; -} - -template -void Swap (T& t1, T& t2) -{ - T tmp = t1; - t1 = t2; - t2 = tmp; -} - -template -bool IsApproximateEqual (T t1, T t2, T epsilon) -{ - if (t1 == t2) - return true; - T diff = t1 - t2; - if (diff < 0.0) - diff = -diff; - if (diff < epsilon) - return true; - return false; -} - -template -inline T ToNormalized (const T& value, const int32 numSteps) -{ - return value / T (numSteps); -} - -template -inline int32 FromNormalized (const T& norm, const int32 numSteps) -{ - return Min (numSteps, int32 (norm * (numSteps + 1))); -} - -// Four character constant -#ifndef CCONST -#define CCONST(a, b, c, d) \ - ((((int32) (a)) << 24) | (((int32) (b)) << 16) | (((int32) (c)) << 8) | (((int32) (d)) << 0)) -#endif - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/fvariant.h b/source/includes/vst3sdk/pluginterfaces/base/fvariant.h deleted file mode 100644 index 491c93fbf..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/fvariant.h +++ /dev/null @@ -1,297 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/fvariant.h -// Created by : Steinberg, 01/2004 -// Description : Basic Interface -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/fstrdefs.h" -#include "pluginterfaces/base/funknown.h" - -//------------------------------------------------------------------------ -namespace Steinberg { - -class FUnknown; - -//------------------------------------------------------------------------ -// FVariant struct declaration -//------------------------------------------------------------------------ -/** A Value of variable type. - \ingroup pluginBase - */ -class FVariant -{ -//------------------------------------------------------------------------ -public: - enum - { - kEmpty = 0, - kInteger = 1 << 0, - kFloat = 1 << 1, - kString8 = 1 << 2, - kObject = 1 << 3, - kOwner = 1 << 4, - kString16 = 1 << 5 - }; - -//------------------------------------------------------------------------ - // ctors - inline FVariant () { memset (this, 0, sizeof (FVariant)); } - inline FVariant (const FVariant& variant); - - inline FVariant (bool b) : type (kInteger), intValue (b) {} - inline FVariant (uint32 v) : type (kInteger), intValue (v) {} - inline FVariant (int64 v) : type (kInteger), intValue (v) {} - inline FVariant (double v) : type (kFloat), floatValue (v) {} - inline FVariant (const char8* str) : type (kString8), string8 (str) {} - inline FVariant (const char16* str) : type (kString16), string16 (str) {} - inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj) - { - setOwner (owner); - } - inline ~FVariant () { empty (); } - -//------------------------------------------------------------------------ - inline FVariant& operator= (const FVariant& variant); - - inline void set (bool b) - { - setInt (b); - } - - inline void set (uint32 v) - { - setInt (v); - } - - inline void set (int64 v) - { - setInt (v); - } - - inline void set (double v) - { - setFloat (v); - } - - inline void set (const char8* c) - { - setString8 (c); - } - - inline void set (const char16* c) - { - setString16 (c); - } - - inline void setInt (int64 v) - { - empty (); - type = kInteger; - intValue = v; - } - - inline void setFloat (double v) - { - empty (); - type = kFloat; - floatValue = v; - } - inline void setString8 (const char8* v) - { - empty (); - type = kString8; - string8 = v; - } - inline void setString16 (const char16* v) - { - empty (); - type = kString16; - string16 = v; - } - - inline void setObject (FUnknown* obj) - { - empty (); - type = kObject; - object = obj; - } - - template - inline T get () const; - - inline int64 getInt () const { return (type & kInteger) ? intValue : 0; } - inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; } - inline double getNumber () const - { - return (type & kInteger) ? static_cast (intValue) : (type & kFloat) ? floatValue : - 0.; - } - inline const char8* getString8 () const { return (type & kString8) ? string8 : nullptr; } - inline const char16* getString16 () const { return (type & kString16) ? string16 : nullptr; } - - inline FUnknown* getObject () const { return (type & kObject) ? object : nullptr; } - - inline uint16 getType () const { return static_cast (type & ~(kOwner)); } - inline bool isEmpty () const { return getType () == kEmpty; } - inline bool isOwner () const { return (type & kOwner) != 0; } - inline bool isString () const { return (type & (kString8 | kString16)) != 0; } - inline void setOwner (bool state) - { - if (state) - type |= kOwner; - else - type &= ~kOwner; - } - - void empty (); -//------------------------------------------------------------------------ - uint16 type; - union - { - int64 intValue; - double floatValue; - const char8* string8; - const char16* string16; - FUnknown* object; - }; -}; - -//------------------------------------------------------------------------ -inline bool operator== (const FVariant& v1, const FVariant& v2) -{ -#if SMTG_PLATFORM_64 - return v1.type == v2.type && v1.intValue == v2.intValue; -#else - if (v1.type != v2.type) - return false; - if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject)) - return v1.string8 == v2.string8; // pointer type comparisons - return v1.intValue == v2.intValue; // intValue & double comparison - -#endif -} - -template <> -inline bool FVariant::get () const -{ - return getInt () != 0; -} - -template <> -inline uint32 FVariant::get () const -{ - return static_cast (getInt ()); -} - -template <> -inline int32 FVariant::get () const -{ - return static_cast (getInt ()); -} - -template <> -inline int64 FVariant::get () const -{ - return static_cast (getInt ()); -} - -template <> -inline float FVariant::get () const -{ - return static_cast (getFloat ()); -} - -template <> -inline double FVariant::get () const -{ - return getFloat (); -} - -template <> -inline const char8* FVariant::get () const -{ - return getString8 (); -} - -template <> -inline const char16* FVariant::get () const -{ - return getString16 (); -} - -template <> -inline FUnknown* FVariant::get () const -{ - return getObject (); -} - -//------------------------------------------------------------------------ -inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); } - -//------------------------------------------------------------------------ -inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; } - -//------------------------------------------------------------------------ -inline void FVariant::empty () -{ - if (type & kOwner) - { - if ((type & kString8) && string8) - delete[] string8; - else if ((type & kString16) && string16) - delete[] string16; - - else if ((type & kObject) && object) - object->release (); - } - memset (this, 0, sizeof (FVariant)); -} - -//------------------------------------------------------------------------ -inline FVariant& FVariant::operator= (const FVariant& variant) -{ - empty (); - - type = variant.type; - - if ((type & kString8) && variant.string8) - { - string8 = new char8[strlen (variant.string8) + 1]; - strcpy (const_cast (string8), variant.string8); - type |= kOwner; - } - else if ((type & kString16) && variant.string16) - { - auto len = static_cast (strlen16 (variant.string16)); - string16 = new char16[len + 1]; - char16* tmp = const_cast (string16); - memcpy (tmp, variant.string16, len * sizeof (char16)); - tmp[len] = 0; - type |= kOwner; - } - else if ((type & kObject) && variant.object) - { - object = variant.object; - object->addRef (); - type |= kOwner; - } - else - intValue = variant.intValue; // copy memory - - return *this; -} - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/ibstream.h b/source/includes/vst3sdk/pluginterfaces/base/ibstream.h deleted file mode 100644 index f25fd78bd..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/ibstream.h +++ /dev/null @@ -1,87 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/ibstream.h -// Created by : Steinberg, 01/2004 -// Description : Interface for reading/writing streams -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "funknown.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -/** Base class for streams. -\ingroup pluginBase -- read/write binary data from/to stream -- get/set stream read-write position (read and write position is the same) -*/ -class IBStream: public FUnknown -{ -public: - enum IStreamSeekMode - { - kIBSeekSet = 0, ///< set absolute seek position - kIBSeekCur, ///< set seek position relative to current position - kIBSeekEnd ///< set seek position relative to stream end - }; - -//------------------------------------------------------------------------ - /** Reads binary data from stream. - \param buffer : destination buffer - \param numBytes : amount of bytes to be read - \param numBytesRead : result - how many bytes have been read from stream (set to 0 if this is of no interest) */ - virtual tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = nullptr) = 0; - - /** Writes binary data to stream. - \param buffer : source buffer - \param numBytes : amount of bytes to write - \param numBytesWritten : result - how many bytes have been written to stream (set to 0 if this is of no interest) */ - virtual tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = nullptr) = 0; - - /** Sets stream read-write position. - \param pos : new stream position (dependent on mode) - \param mode : value of enum IStreamSeekMode - \param result : new seek position (set to 0 if this is of no interest) */ - virtual tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = nullptr) = 0; - - /** Gets current stream read-write position. - \param pos : is assigned the current position if function succeeds */ - virtual tresult PLUGIN_API tell (int64* pos) = 0; -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IBStream, 0xC3BF6EA2, 0x30994752, 0x9B6BF990, 0x1EE33E9B) - -//------------------------------------------------------------------------ -/** Stream with a size. -\ingroup pluginBase -[extends IBStream] when stream type supports it (like file and memory stream) -*/ -class ISizeableStream: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Return the stream size */ - virtual tresult PLUGIN_API getStreamSize (int64& size) = 0; - /** Set the steam size. File streams can only be resized if they are write enabled. */ - virtual tresult PLUGIN_API setStreamSize (int64 size) = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; -DECLARE_CLASS_IID (ISizeableStream, 0x04F9549E, 0xE02F4E6E, 0x87E86A87, 0x47F4E17F) - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/icloneable.h b/source/includes/vst3sdk/pluginterfaces/base/icloneable.h deleted file mode 100644 index f698a6924..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/icloneable.h +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/icloneable.h -// Created by : Steinberg, 11/2007 -// Description : Interface for object copies -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "funknown.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -/** Interface allowing an object to be copied. -- [plug & host imp] -- [released: N4.12] -*/ -class ICloneable : public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Create exact copy of the object */ - virtual FUnknown* PLUGIN_API clone () = 0; -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (ICloneable, 0xD45406B9, 0x3A2D4443, 0x9DAD9BA9, 0x85A1454B) - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/ipersistent.h b/source/includes/vst3sdk/pluginterfaces/base/ipersistent.h deleted file mode 100644 index 9572d0f2c..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/ipersistent.h +++ /dev/null @@ -1,160 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/ipersistent.h -// Created by : Steinberg, 09/2004 -// Description : Plug-In Storage Interfaces -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/funknown.h" - -namespace Steinberg { - -class FVariant; -class IAttributes; -//------------------------------------------------------------------------ -/** Persistent Object Interface. -[plug imp] \n -This interface is used to store/restore attributes of an object. -An IPlugController can implement this interface to handle presets. -The gui-xml for a preset control looks like this: -\code -.... - -.... - -\endcode -The tag data="Preset" tells the host to create a preset controller that handles the -3 values named "preset control", "store preset", and "remove preset". -*/ -class IPersistent: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** The class ID must be a 16 bytes unique id that is used to create the object. - This ID is also used to identify the preset list when used with presets. */ - virtual tresult PLUGIN_API getClassID (char8* uid) = 0; - /** Store all members/data in the passed IAttributes. */ - virtual tresult PLUGIN_API saveAttributes (IAttributes* ) = 0; - /** Restore all members/data from the passed IAttributes. */ - virtual tresult PLUGIN_API loadAttributes (IAttributes* ) = 0; -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IPersistent, 0xBA1A4637, 0x3C9F46D0, 0xA65DBA0E, 0xB85DA829) - - -typedef FIDString IAttrID; -//------------------------------------------------------------------------ -/** Object Data Archive Interface. -- [host imp] - -- store data/objects/binary/subattributes in the archive -- read stored data from the archive - -All data stored to the archive are identified by a string (IAttrID), which must be unique on each -IAttribute level. - -The basic set/get methods make use of the FVariant class defined in 'funknown.h'. -For a more convenient usage of this interface, you should use the functions defined -in namespace PAttributes (public.sdk/source/common/pattributes.h+cpp) !! - -\ingroup frameworkHostClasses -*/ -class IAttributes: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /*! \name Methods to write attributes - ******************************************************************************************************** */ - //@{ - /** Store any data in the archive. It is even possible to store sub-attributes by creating - a new IAttributes instance via the IHostClasses interface and pass it to the parent in the - FVariant. In this case the archive must take the ownership of the newly created object, which - is true for all objects that have been created only for storing. You tell the archive to take - ownership by adding the FVariant::kOwner flag to the FVariant::type member (data.type |= FVariant::kOwner). - When using the PAttributes functions, this is done through a function parameter.*/ - virtual tresult PLUGIN_API set (IAttrID attrID, const FVariant& data) = 0; - - /** Store a list of data in the archive. Please note that the type of data is not mixable! So - you can only store a list of integers or a list of doubles/strings/etc. You can also store a list - of subattributes or other objects that implement the IPersistent interface.*/ - virtual tresult PLUGIN_API queue (IAttrID listID, const FVariant& data) = 0; - - /** Store binary data in the archive. Parameter 'copyBytes' specifies if the passed data should be copied. - The archive cannot take the ownership of binary data. Either it just references a buffer in order - to write it to a file (copyBytes = false) or it copies the data to its own buffers (copyBytes = true). - When binary data should be stored in the default pool for example, you must always copy it!*/ - virtual tresult PLUGIN_API setBinaryData (IAttrID attrID, void* data, uint32 bytes, bool copyBytes) = 0; - //@} - - /*! \name Methods to read attributes - ******************************************************************************************************** */ - //@{ - /** Get data previously stored to the archive. */ - virtual tresult PLUGIN_API get (IAttrID attrID, FVariant& data) = 0; - - /** Get list of data previously stored to the archive. As long as there are queue members the method - will return kResultTrue. When the queue is empty, the methods returns kResultFalse. All lists except from - object lists can be reset which means that the items can be read once again. \see IAttributes::resetQueue */ - virtual tresult PLUGIN_API unqueue (IAttrID listID, FVariant& data) = 0; - - /** Get the amount of items in a queue. */ - virtual int32 PLUGIN_API getQueueItemCount (IAttrID) = 0; - - /** Reset a queue. If you need to restart reading a queue, you have to reset it. You can reset a queue at any time.*/ - virtual tresult PLUGIN_API resetQueue (IAttrID attrID) = 0; - - /** Reset all queues in the archive.*/ - virtual tresult PLUGIN_API resetAllQueues () = 0; - - /** Read binary data from the archive. The data is copied into the passed buffer. The size of that buffer - must fit the size of data stored in the archive which can be queried via IAttributes::getBinaryDataSize */ - virtual tresult PLUGIN_API getBinaryData (IAttrID attrID, void* data, uint32 bytes) = 0; - /** Get the size in bytes of binary data in the archive. */ - virtual uint32 PLUGIN_API getBinaryDataSize (IAttrID attrID) = 0; - //@} - -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IAttributes, 0xFA1E32F9, 0xCA6D46F5, 0xA982F956, 0xB1191B58) - -//------------------------------------------------------------------------ -/** Extended access to Attributes; supports Attribute retrieval via iteration. -- [host imp] -- [released] C7/N6 - -\ingroup frameworkHostClasses -*/ -class IAttributes2 : public IAttributes -{ -public: - /** Returns the number of existing attributes. */ - virtual int32 PLUGIN_API countAttributes () const = 0; - /** Returns the attribute's ID for the given index. */ - virtual IAttrID PLUGIN_API getAttributeID (int32 index) const = 0; -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IAttributes2, 0x1382126A, 0xFECA4871, 0x97D52A45, 0xB042AE99) - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/ipluginbase.h b/source/includes/vst3sdk/pluginterfaces/base/ipluginbase.h deleted file mode 100644 index 10325fe85..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/ipluginbase.h +++ /dev/null @@ -1,425 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/ipluginbase.h -// Created by : Steinberg, 01/2004 -// Description : Basic Plug-in Interfaces -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "funknown.h" -#include "fstrdefs.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -/** Basic interface to a plug-in component: IPluginBase -\ingroup pluginBase -- [plug imp] -- initialize/terminate the plug-in component - -The host uses this interface to initialize and to terminate the plug-in component. -The context that is passed to the initialize method contains any interface to the -host that the plug-in will need to work. These interfaces can vary from category to category. -A list of supported host context interfaces should be included in the documentation -of a specific category. -*/ -class IPluginBase: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** The host passes a number of interfaces as context to initialize the plug-in class. - @note Extensive memory allocations etc. should be performed in this method rather than in the class' constructor! - If the method does NOT return kResultOk, the object is released immediately. In this case terminate is not called! */ - virtual tresult PLUGIN_API initialize (FUnknown* context) = 0; - - /** This function is called before the plug-in is unloaded and can be used for - cleanups. You have to release all references to any host application interfaces. */ - virtual tresult PLUGIN_API terminate () = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IPluginBase, 0x22888DDB, 0x156E45AE, 0x8358B348, 0x08190625) - - -//------------------------------------------------------------------------ -/** Basic Information about the class factory of the plug-in. -\ingroup pluginBase -*/ -struct PFactoryInfo -{ -//------------------------------------------------------------------------ - enum FactoryFlags - { - kNoFlags = 0, ///< Nothing - kClassesDiscardable = 1 << 0, ///< The number of exported classes can change each time the Module is loaded. If this flag is set, the host does not cache class information. This leads to a longer startup time because the host always has to load the Module to get the current class information. - kLicenseCheck = 1 << 1, ///< Class IDs of components are interpreted as Syncrosoft-License (LICENCE_UID). Loaded in a Steinberg host, the module will not be loaded when the license is not valid - kComponentNonDiscardable = 1 << 3, ///< Component will not be unloaded until process exit - kUnicode = 1 << 4 ///< Components have entirely unicode encoded strings. (True for VST 3 plug-ins so far) - }; - - enum - { - kURLSize = 256, - kEmailSize = 128, - kNameSize = 64 - }; - -//------------------------------------------------------------------------ - char8 vendor[kNameSize]; ///< e.g. "Steinberg Media Technologies" - char8 url[kURLSize]; ///< e.g. "http://www.steinberg.de" - char8 email[kEmailSize]; ///< e.g. "info@steinberg.de" - int32 flags; ///< (see above) -//------------------------------------------------------------------------ - PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email, int32 _flags) - { - strncpy8 (vendor, _vendor, kNameSize); - strncpy8 (url, _url, kURLSize); - strncpy8 (email, _email, kEmailSize); - flags = _flags; -#ifdef UNICODE - flags |= kUnicode; -#endif - } -#if SMTG_CPP11 - constexpr PFactoryInfo () : vendor (), url (), email (), flags () {} -#else - PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); } -#endif -}; - -//------------------------------------------------------------------------ -/** Basic Information about a class provided by the plug-in. -\ingroup pluginBase -*/ -struct PClassInfo -{ -//------------------------------------------------------------------------ - enum ClassCardinality - { - kManyInstances = 0x7FFFFFFF - }; - - enum - { - kCategorySize = 32, - kNameSize = 64 - }; -//------------------------------------------------------------------------ - TUID cid; ///< Class ID 16 Byte class GUID - int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality) - char8 category[kCategorySize]; ///< class category, host uses this to categorize interfaces - char8 name[kNameSize]; ///< class name, visible to the user -//------------------------------------------------------------------------ - - PClassInfo (const TUID _cid, int32 _cardinality, const char8* _category, const char8* _name) - { - memset (this, 0, sizeof (PClassInfo)); - memcpy (cid, _cid, sizeof (TUID)); - if (_category) - strncpy8 (category, _category, kCategorySize); - if (_name) - strncpy8 (name, _name, kNameSize); - cardinality = _cardinality; - } -#if SMTG_CPP11 - constexpr PClassInfo () : cid (), cardinality (), category (), name () {} -#else - PClassInfo () { memset (this, 0, sizeof (PClassInfo)); } -#endif -}; - -//------------------------------------------------------------------------ -// IPluginFactory interface declaration -//------------------------------------------------------------------------ -/** Class factory that any plug-in defines for creating class instances: IPluginFactory -\ingroup pluginBase -- [plug imp] - -From the host's point of view a plug-in module is a factory which can create -a certain kind of object(s). The interface IPluginFactory provides methods -to get information about the classes exported by the plug-in and a -mechanism to create instances of these classes (that usually define the IPluginBase interface). - - An implementation is provided in public.sdk/source/common/pluginfactory.cpp -\see GetPluginFactory -*/ -class IPluginFactory : public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Fill a PFactoryInfo structure with information about the plug-in vendor. */ - virtual tresult PLUGIN_API getFactoryInfo (PFactoryInfo* info) = 0; - - /** Returns the number of exported classes by this factory. - If you are using the CPluginFactory implementation provided by the SDK, it returns the number of classes you registered with CPluginFactory::registerClass. */ - virtual int32 PLUGIN_API countClasses () = 0; - - /** Fill a PClassInfo structure with information about the class at the specified index. */ - virtual tresult PLUGIN_API getClassInfo (int32 index, PClassInfo* info) = 0; - - /** Create a new class instance. */ - virtual tresult PLUGIN_API createInstance (FIDString cid, FIDString _iid, void** obj) = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IPluginFactory, 0x7A4D811C, 0x52114A1F, 0xAED9D2EE, 0x0B43BF9F) - - -//------------------------------------------------------------------------ -/** Version 2 of Basic Information about a class provided by the plug-in. -\ingroup pluginBase -*/ -struct PClassInfo2 -{ -//------------------------------------------------------------------------ - TUID cid; ///< Class ID 16 Byte class GUID - int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref PClassInfo::ClassCardinality) - char8 category[PClassInfo::kCategorySize]; ///< class category, host uses this to categorize interfaces - char8 name[PClassInfo::kNameSize]; ///< class name, visible to the user - - enum { - kVendorSize = 64, - kVersionSize = 64, - kSubCategoriesSize = 128 - }; - - uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined - char8 subCategories[kSubCategoriesSize]; ///< module specific subcategories, can be more than one, logically added by the \c OR operator - char8 vendor[kVendorSize]; ///< overwrite vendor information from factory info - char8 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) - char8 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") - -//------------------------------------------------------------------------ - - PClassInfo2 (const TUID _cid, int32 _cardinality, const char8* _category, const char8* _name, - int32 _classFlags, const char8* _subCategories, const char8* _vendor, const char8* _version, - const char8* _sdkVersion) - { - memset (this, 0, sizeof (PClassInfo2)); - memcpy (cid, _cid, sizeof (TUID)); - cardinality = _cardinality; - if (_category) - strncpy8 (category, _category, PClassInfo::kCategorySize); - if (_name) - strncpy8 (name, _name, PClassInfo::kNameSize); - classFlags = static_cast (_classFlags); - if (_subCategories) - strncpy8 (subCategories, _subCategories, kSubCategoriesSize); - if (_vendor) - strncpy8 (vendor, _vendor, kVendorSize); - if (_version) - strncpy8 (version, _version, kVersionSize); - if (_sdkVersion) - strncpy8 (sdkVersion, _sdkVersion, kVersionSize); - } -#if SMTG_CPP11 - constexpr PClassInfo2 () - : cid () - , cardinality () - , category () - , name () - , classFlags () - , subCategories () - , vendor () - , version () - , sdkVersion () - { - } -#else - PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); } -#endif -}; - -//------------------------------------------------------------------------ -// IPluginFactory2 interface declaration -//------------------------------------------------------------------------ -/** Version 2 of class factory supporting PClassInfo2: IPluginFactory2 -\ingroup pluginBase -\copydoc IPluginFactory -*/ -class IPluginFactory2 : public IPluginFactory -{ -public: -//------------------------------------------------------------------------ - /** Returns the class info (version 2) for a given index. */ - virtual tresult PLUGIN_API getClassInfo2 (int32 index, PClassInfo2* info) = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; -DECLARE_CLASS_IID (IPluginFactory2, 0x0007B650, 0xF24B4C0B, 0xA464EDB9, 0xF00B2ABB) - - -//------------------------------------------------------------------------ -/** Unicode Version of Basic Information about a class provided by the plug-in -*/ -struct PClassInfoW -{ -//------------------------------------------------------------------------ - TUID cid; ///< see \ref PClassInfo - int32 cardinality; ///< see \ref PClassInfo - char8 category[PClassInfo::kCategorySize]; ///< see \ref PClassInfo - char16 name[PClassInfo::kNameSize]; ///< see \ref PClassInfo - - enum { - kVendorSize = 64, - kVersionSize = 64, - kSubCategoriesSize = 128 - }; - - uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined - char8 subCategories[kSubCategoriesSize];///< module specific subcategories, can be more than one, logically added by the \c OR operator - char16 vendor[kVendorSize]; ///< overwrite vendor information from factory info - char16 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) - char16 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") - -//------------------------------------------------------------------------ - PClassInfoW (const TUID _cid, int32 _cardinality, const char8* _category, const char16* _name, - int32 _classFlags, const char8* _subCategories, const char16* _vendor, const char16* _version, - const char16* _sdkVersion) - { - memset (this, 0, sizeof (PClassInfoW)); - memcpy (cid, _cid, sizeof (TUID)); - cardinality = _cardinality; - if (_category) - strncpy8 (category, _category, PClassInfo::kCategorySize); - if (_name) - strncpy16 (name, _name, PClassInfo::kNameSize); - classFlags = static_cast (_classFlags); - if (_subCategories) - strncpy8 (subCategories, _subCategories, kSubCategoriesSize); - if (_vendor) - strncpy16 (vendor, _vendor, kVendorSize); - if (_version) - strncpy16 (version, _version, kVersionSize); - if (_sdkVersion) - strncpy16 (sdkVersion, _sdkVersion, kVersionSize); - } -#if SMTG_CPP11 - constexpr PClassInfoW () - : cid () - , cardinality () - , category () - , name () - , classFlags () - , subCategories () - , vendor () - , version () - , sdkVersion () - { - } -#else - PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); } -#endif - - void fromAscii (const PClassInfo2& ci2) - { - memcpy (cid, ci2.cid, sizeof (TUID)); - cardinality = ci2.cardinality; - strncpy8 (category, ci2.category, PClassInfo::kCategorySize); - str8ToStr16 (name, ci2.name, PClassInfo::kNameSize); - classFlags = ci2.classFlags; - strncpy8 (subCategories, ci2.subCategories, kSubCategoriesSize); - - str8ToStr16 (vendor, ci2.vendor, kVendorSize); - str8ToStr16 (version, ci2.version, kVersionSize); - str8ToStr16 (sdkVersion, ci2.sdkVersion, kVersionSize); - } -}; - -//------------------------------------------------------------------------ -// IPluginFactory3 interface declaration -//------------------------------------------------------------------------ -/** Version 3 of class factory supporting PClassInfoW: IPluginFactory3 -\ingroup pluginBase -\copydoc IPluginFactory -*/ -class IPluginFactory3 : public IPluginFactory2 -{ -public: -//------------------------------------------------------------------------ - /** Returns the unicode class info for a given index. */ - virtual tresult PLUGIN_API getClassInfoUnicode (int32 index, PClassInfoW* info) = 0; - - /** Receives information about host*/ - virtual tresult PLUGIN_API setHostContext (FUnknown* context) = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; -DECLARE_CLASS_IID (IPluginFactory3, 0x4555A2AB, 0xC1234E57, 0x9B122910, 0x36878931) -//------------------------------------------------------------------------ -} // namespace Steinberg - -//------------------------------------------------------------------------ -#define LICENCE_UID(l1, l2, l3, l4) \ -{ \ - (int8)((l1 & 0xFF000000) >> 24), (int8)((l1 & 0x00FF0000) >> 16), \ - (int8)((l1 & 0x0000FF00) >> 8), (int8)((l1 & 0x000000FF) ), \ - (int8)((l2 & 0xFF000000) >> 24), (int8)((l2 & 0x00FF0000) >> 16), \ - (int8)((l2 & 0x0000FF00) >> 8), (int8)((l2 & 0x000000FF) ), \ - (int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \ - (int8)((l3 & 0x0000FF00) >> 8), (int8)((l3 & 0x000000FF) ), \ - (int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \ - (int8)((l4 & 0x0000FF00) >> 8), (int8)((l4 & 0x000000FF) ) \ -} - -//------------------------------------------------------------------------ -// GetPluginFactory -//------------------------------------------------------------------------ -/** Plug-in entry point. -\ingroup pluginBase -Any plug-in must define and export this function. \n -A typical implementation of GetPluginFactory looks like this -\code{.cpp} -SMTG_EXPORT_SYMBOL IPluginFactory* PLUGIN_API GetPluginFactory () -{ - if (!gPluginFactory) - { - static PFactoryInfo factoryInfo = - { - "My Company Name", - "http://www.mywebpage.com", - "mailto:myemail@address.com", - PFactoryInfo::kNoFlags - }; - - gPluginFactory = new CPluginFactory (factoryInfo); - - static PClassInfo componentClass = - { - INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000), // replace by a valid uid - 1, - "Service", // category - "Name" - }; - - gPluginFactory->registerClass (&componentClass, MyComponentClass::newInstance); - } - else - gPluginFactory->addRef (); - - return gPluginFactory; -} -\endcode -\see \ref loadPlugin -*/ -extern "C" -{ - SMTG_EXPORT_SYMBOL Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory (); - typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) (); -} diff --git a/source/includes/vst3sdk/pluginterfaces/base/istringresult.h b/source/includes/vst3sdk/pluginterfaces/base/istringresult.h deleted file mode 100644 index 8d4826661..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/istringresult.h +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/istringresult.h -// Created by : Steinberg, 01/2005 -// Description : Strings Interface -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/funknown.h" - -namespace Steinberg { - -//------------------------------------------------------------------------ -/** Interface to return an ascii string of variable size. - In order to manage memory allocation and deallocation properly, - this interface is used to transfer a string as result parameter of - a method requires a string of unknown size. -- [host imp] or [plug imp] -- [released: SX 4] -*/ -class IStringResult : public FUnknown -{ -public: -//------------------------------------------------------------------------ - virtual void PLUGIN_API setText (const char8* text) = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IStringResult, 0x550798BC, 0x872049DB, 0x84920A15, 0x3B50B7A8) - - -//------------------------------------------------------------------------ -/** Interface to a string of variable size and encoding. -- [host imp] or [plug imp] -- [released: ] -*/ -class IString : public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Assign ASCII string */ - virtual void PLUGIN_API setText8 (const char8* text) = 0; - /** Assign unicode string */ - virtual void PLUGIN_API setText16 (const char16* text) = 0; - - /** Return ASCII string. If the string is unicode so far, it will be converted. - So you need to be careful, because the conversion can result in data loss. - It is save though to call getText8 if isWideString() returns false */ - virtual const char8* PLUGIN_API getText8 () = 0; - /** Return unicode string. If the string is ASCII so far, it will be converted. */ - virtual const char16* PLUGIN_API getText16 () = 0; - - /** !Do not use this method! Early implementations take the given pointer as - internal string and this will cause problems because 'free' will be used to delete the passed memory. - Later implementations will redirect 'take' to setText8 and setText16 */ - virtual void PLUGIN_API take (void* s, bool isWide) = 0; - - /** Returns true if the string is in unicode format, returns false if the string is ASCII */ - virtual bool PLUGIN_API isWideString () const = 0; - -//------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IString, 0xF99DB7A3, 0x0FC14821, 0x800B0CF9, 0x8E348EDF) - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/iupdatehandler.h b/source/includes/vst3sdk/pluginterfaces/base/iupdatehandler.h deleted file mode 100644 index 08f38dd27..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/iupdatehandler.h +++ /dev/null @@ -1,98 +0,0 @@ -//------------------------------------------------------------------------ -// Project : Steinberg Module Architecture SDK -// -// Category : Basic Host Service Interfaces -// Filename : pluginterfaces/base/iupdatehandler.h -// Created by : Steinberg, 01/2004 -// Description : Update handling -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/funknown.h" - -namespace Steinberg { - -class IDependent; - -//------------------------------------------------------------------------ -/** Host implements dependency handling for plugins. -- [host imp] -- [get this interface from IHostClasses] -- [released N3.1] - -- Install/Remove change notifications -- Trigger updates when an object has changed - -Can be used between host-objects and the Plug-In or -inside the Plug-In to handle internal updates! - -\see IDependent -\ingroup frameworkHostClasses -*/ -class IUpdateHandler: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Install update notification for given object. It is essential to - remove all dependencies again using 'removeDependent'! Dependencies - are not removed automatically when the 'object' is released! - \param object : interface to object that sends change notifications - \param dependent : interface through which the update is passed */ - virtual tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) = 0; - - /** Remove a previously installed dependency.*/ - virtual tresult PLUGIN_API removeDependent (FUnknown* object, IDependent* dependent) = 0; - - /** Inform all dependents, that object has changed. - \param object is the object that has changed - \param message is a value of enum IDependent::ChangeMessage, usually IDependent::kChanged - can be - a private message as well (only known to sender and dependent)*/ - virtual tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) = 0; - - /** Same as triggerUpdates, but delivered in idle (usefull to collect updates).*/ - virtual tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) = 0; - static const FUID iid; -}; - -DECLARE_CLASS_IID (IUpdateHandler, 0xF5246D56, 0x86544d60, 0xB026AFB5, 0x7B697B37) - -//------------------------------------------------------------------------ -/** A dependent will get notified about changes of a model. -[plug imp] -- notify changes of a model - -\see IUpdateHandler -\ingroup frameworkHostClasses -*/ -class IDependent: public FUnknown -{ -public: -//------------------------------------------------------------------------ - /** Inform the dependent, that the passed FUnknown has changed. */ - virtual void PLUGIN_API update (FUnknown* changedUnknown, int32 message) = 0; - - enum ChangeMessage - { - kWillChange, - kChanged, - kDestroyed, - kWillDestroy, - - kStdChangeMessageLast = kWillDestroy - }; - //------------------------------------------------------------------------ - static const FUID iid; -}; - -DECLARE_CLASS_IID (IDependent, 0xF52B7AAE, 0xDE72416d, 0x8AF18ACE, 0x9DD7BD5E) - -//------------------------------------------------------------------------ -} // namespace Steinberg diff --git a/source/includes/vst3sdk/pluginterfaces/base/smartpointer.h b/source/includes/vst3sdk/pluginterfaces/base/smartpointer.h deleted file mode 100644 index 99dd03730..000000000 --- a/source/includes/vst3sdk/pluginterfaces/base/smartpointer.h +++ /dev/null @@ -1,384 +0,0 @@ -//----------------------------------------------------------------------------- -// Project : SDK Core -// -// Category : SDK Core Interfaces -// Filename : pluginterfaces/base/smartpointer.h -// Created by : Steinberg, 01/2004 -// Description : Basic Interface -// -//----------------------------------------------------------------------------- -// This file is part of a Steinberg SDK. It is subject to the license terms -// in the LICENSE file found in the top-level directory of this distribution -// and at www.steinberg.net/sdklicenses. -// No part of the SDK, including this file, may be copied, modified, propagated, -// or distributed except according to the terms contained in the LICENSE file. -//----------------------------------------------------------------------------- - -#pragma once - -#include "pluginterfaces/base/fplatform.h" -#if SMTG_CPP11_STDLIBSUPPORT -#include -#endif - -//------------------------------------------------------------------------ -namespace Steinberg { - -//------------------------------------------------------------------------ -// IPtr -//------------------------------------------------------------------------ -/** IPtr - Smart pointer template class. - \ingroup pluginBase - - - can be used as an I* pointer - - handles refCount of the interface - - Usage example: - \code -IPtr path (sharedPath); -if (path) - path->ascend (); - \endcode - */ -template -class IPtr -{ -public: -//------------------------------------------------------------------------ - inline IPtr (I* ptr, bool addRef = true); - inline IPtr (const IPtr&); - - template - inline IPtr (const IPtr& other) : ptr (other.get ()) - { - if (ptr) - ptr->addRef (); - } - - inline IPtr (); - inline ~IPtr (); - - inline I* operator= (I* ptr); - - inline IPtr& operator= (const IPtr& other); - - template - inline IPtr& operator= (const IPtr& other) - { - operator= (other.get ()); - return *this; - } - - inline operator I* () const { return ptr; } // act as I* - inline I* operator-> () const { return ptr; } // act as I* - - inline I* get () const { return ptr; } - -#if SMTG_CPP11_STDLIBSUPPORT - inline IPtr (IPtr&& movePtr) SMTG_NOEXCEPT : ptr (movePtr.take ()) { } - - template - inline IPtr (IPtr&& movePtr) SMTG_NOEXCEPT : ptr (movePtr.take ()) { } - - inline IPtr& operator= (IPtr&& movePtr) SMTG_NOEXCEPT - { - if (ptr) - ptr->release (); - - ptr = movePtr.take (); - return *this; - } - - template - inline IPtr& operator= (IPtr&& movePtr) - { - if (ptr) - ptr->release (); - - ptr = movePtr.take (); - return *this; - } -#endif - - inline void reset (I* obj = nullptr) - { - if (ptr) - ptr->release(); - ptr = obj; - } - - I* take () SMTG_NOEXCEPT - { - I* out = ptr; - ptr = nullptr; - return out; - } - - template - static IPtr adopt (T* obj) SMTG_NOEXCEPT { return IPtr (obj, false); } - -//------------------------------------------------------------------------ -protected: - I* ptr; -}; - -//------------------------------------------------------------------------ -template -inline IPtr::IPtr (I* _ptr, bool addRef) : ptr (_ptr) -{ - if (ptr && addRef) - ptr->addRef (); -} - -//------------------------------------------------------------------------ -template -inline IPtr::IPtr (const IPtr& other) : ptr (other.ptr) -{ - if (ptr) - ptr->addRef (); -} - -//------------------------------------------------------------------------ -template -inline IPtr::IPtr () : ptr (0) -{ -} - -//------------------------------------------------------------------------ -template -inline IPtr::~IPtr () -{ - if (ptr) - { - ptr->release (); - ptr = nullptr; //TODO_CORE: how much does this cost? is this something hiding for us? - } -} - -//------------------------------------------------------------------------ -template -inline I* IPtr::operator= (I* _ptr) -{ - if (_ptr != ptr) - { - if (ptr) - ptr->release (); - ptr = _ptr; - if (ptr) - ptr->addRef (); - } - return ptr; -} - -//------------------------------------------------------------------------ -template -inline IPtr& IPtr::operator= (const IPtr& _ptr) -{ - operator= (_ptr.ptr); - return *this; -} - -//------------------------------------------------------------------------ -/** OPtr - "owning" smart pointer used for newly created FObjects. - \ingroup pluginBase - - FUnknown implementations are supposed to have a refCount of 1 right after creation. - So using an IPtr on newly created objects would lead to a leak. - Instead the OPtr can be used in this case. \n - Example: - \code - OPtr path = FHostCreate (IPath, hostClasses); - // no release is needed... - \endcode - The assignment operator takes ownership of a new object and releases the old. - So its safe to write: - \code - OPtr path = FHostCreate (IPath, hostClasses); - path = FHostCreate (IPath, hostClasses); - path = 0; - \endcode - This is the difference to using an IPtr with addRef=false. - \code - // DONT DO THIS: - IPtr path (FHostCreate (IPath, hostClasses), false); - path = FHostCreate (IPath, hostClasses); - path = 0; - \endcode - This will lead to a leak! - */ -template -class OPtr : public IPtr -{ -public: -//------------------------------------------------------------------------ - inline OPtr (I* p) : IPtr (p, false) {} - inline OPtr (const IPtr& p) : IPtr (p) {} - inline OPtr (const OPtr& p) : IPtr (p) {} - inline OPtr () {} - inline I* operator= (I* _ptr) - { - if (_ptr != this->ptr) - { - if (this->ptr) - this->ptr->release (); - this->ptr = _ptr; - } - return this->ptr; - } -}; - -//------------------------------------------------------------------------ -/** Assigning newly created object to an IPtr. - Example: - \code - IPtr path = owned (FHostCreate (IPath, hostClasses)); - \endcode - which is a slightly shorter form of writing: - \code - IPtr path = OPtr (FHostCreate (IPath, hostClasses)); - \endcode - */ -template -IPtr owned (I* p) -{ - return IPtr (p, false); -} - -/** Assigning shared object to an IPtr. - Example: - \code - IPtr path = shared (iface.getXY ()); - \endcode - */ -template -IPtr shared (I* p) -{ - return IPtr (p, true); -} - -#if SMTG_CPP11_STDLIBSUPPORT -//------------------------------------------------------------------------ -// Ownership functionality -//------------------------------------------------------------------------ -namespace SKI { -namespace Detail { -struct Adopt; -} // Detail - -/** Strong typedef for shared reference counted objects. - * Use SKI::adopt to unwrap the provided object. - * @tparam T Referenced counted type. - */ -template -class Shared -{ - friend struct Detail::Adopt; - T* obj = nullptr; -}; - -/** Strong typedef for transferring the ownership of reference counted objects. - * Use SKI::adopt to unwrap the provided object. - * After calling adopt the reference in this object is null. - * @tparam T Referenced counted type. - */ -template -class Owned -{ - friend struct Detail::Adopt; - T* obj = nullptr; -}; - -/** Strong typedef for using reference counted objects. - * Use SKI::adopt to unwrap the provided object. - * After calling adopt the reference in this object is null. - * @tparam T Referenced counted type. - */ -template -class Used -{ - friend struct Detail::Adopt; - T* obj = nullptr; -}; - -namespace Detail { - -struct Adopt -{ - template - static IPtr adopt (Shared& ref) - { - using Steinberg::shared; - return shared (ref.obj); - } - - template - static IPtr adopt (Owned& ref) - { - using Steinberg::owned; - IPtr out = owned (ref.obj); - ref.obj = nullptr; - return out; - } - - template - static T* adopt (Used& ref) - { - return ref.obj; - } - - template