| @@ -2,6 +2,11 @@ name: build | |||||
| on: | on: | ||||
| push: | push: | ||||
| branches: | |||||
| - '*' | |||||
| pull_request: | |||||
| branches: | |||||
| - '*' | |||||
| jobs: | jobs: | ||||
| linux: | linux: | ||||
| @@ -10,7 +15,7 @@ jobs: | |||||
| target: [linux-arm64, linux-armhf, linux-i686, linux-riscv64, linux-x86_64] | target: [linux-arm64, linux-armhf, linux-i686, linux-riscv64, linux-x86_64] | ||||
| runs-on: ubuntu-20.04 | runs-on: ubuntu-20.04 | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v3 | |||||
| - uses: actions/checkout@v4 | |||||
| with: | with: | ||||
| submodules: recursive | submodules: recursive | ||||
| - uses: distrho/dpf-makefile-action@v1 | - uses: distrho/dpf-makefile-action@v1 | ||||
| @@ -23,7 +28,7 @@ jobs: | |||||
| target: [macos-intel, macos-universal] | target: [macos-intel, macos-universal] | ||||
| runs-on: macos-11 | runs-on: macos-11 | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v3 | |||||
| - uses: actions/checkout@v4 | |||||
| with: | with: | ||||
| submodules: recursive | submodules: recursive | ||||
| - uses: distrho/dpf-makefile-action@v1 | - uses: distrho/dpf-makefile-action@v1 | ||||
| @@ -36,7 +41,7 @@ jobs: | |||||
| target: [win32, win64] | target: [win32, win64] | ||||
| runs-on: ubuntu-20.04 | runs-on: ubuntu-20.04 | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v3 | |||||
| - uses: actions/checkout@v4 | |||||
| with: | with: | ||||
| submodules: recursive | submodules: recursive | ||||
| - uses: distrho/dpf-makefile-action@v1 | - uses: distrho/dpf-makefile-action@v1 | ||||
| @@ -47,7 +52,7 @@ jobs: | |||||
| pluginval: | pluginval: | ||||
| runs-on: ubuntu-20.04 | runs-on: ubuntu-20.04 | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v3 | |||||
| - uses: actions/checkout@v4 | |||||
| with: | with: | ||||
| submodules: recursive | submodules: recursive | ||||
| - uses: distrho/dpf-makefile-action@v1 | - uses: distrho/dpf-makefile-action@v1 | ||||
| @@ -1,4 +1,4 @@ | |||||
| # Copyright 2020-2022 David Robillard <d@drobilla.net> | |||||
| # Copyright 2020-2024 David Robillard <d@drobilla.net> | |||||
| # SPDX-License-Identifier: 0BSD OR ISC | # SPDX-License-Identifier: 0BSD OR ISC | ||||
| Checks: > | Checks: > | ||||
| @@ -11,6 +11,7 @@ Checks: > | |||||
| -clang-diagnostic-unused-macros, | -clang-diagnostic-unused-macros, | ||||
| -llvmlibc-*, | -llvmlibc-*, | ||||
| -misc-include-cleaner, | -misc-include-cleaner, | ||||
| -readability-avoid-nested-conditional-operator, | |||||
| -readability-identifier-length, | -readability-identifier-length, | ||||
| CheckOptions: | CheckOptions: | ||||
| - key: hicpp-uppercase-literal-suffix.NewSuffixes | - key: hicpp-uppercase-literal-suffix.NewSuffixes | ||||
| @@ -1,8 +1,10 @@ | |||||
| # Copyright 2020-2022 David Robillard <d@drobilla.net> | |||||
| # Copyright 2020-2024 David Robillard <d@drobilla.net> | |||||
| # SPDX-License-Identifier: 0BSD OR ISC | # SPDX-License-Identifier: 0BSD OR ISC | ||||
| Checks: > | Checks: > | ||||
| -bugprone-easily-swappable-parameters, | -bugprone-easily-swappable-parameters, | ||||
| -bugprone-multi-level-implicit-pointer-conversion, | |||||
| -clang-analyzer-optin.core.EnumCastOutOfRange, | |||||
| -hicpp-multiway-paths-covered, | -hicpp-multiway-paths-covered, | ||||
| -hicpp-signed-bitwise, | -hicpp-signed-bitwise, | ||||
| -llvm-header-guard, | -llvm-header-guard, | ||||
| @@ -633,11 +633,11 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type) | |||||
| const NSPoint wloc = [self eventLocation:event]; | const NSPoint wloc = [self eventLocation:event]; | ||||
| const NSPoint rloc = [NSEvent mouseLocation]; | const NSPoint rloc = [NSEvent mouseLocation]; | ||||
| double dx = -[event scrollingDeltaX]; | |||||
| double dy = [event scrollingDeltaY]; | |||||
| if (![event hasPreciseScrollingDeltas]) { | |||||
| dx *= 10.0; | |||||
| dy *= 10.0; | |||||
| double dx = -[event scrollingDeltaX] / 2.0; | |||||
| double dy = [event scrollingDeltaY] / 2.0; | |||||
| if ([event hasPreciseScrollingDeltas]) { | |||||
| dx /= 10.0; | |||||
| dy /= 10.0; | |||||
| } | } | ||||
| const PuglScrollDirection dir = | const PuglScrollDirection dir = | ||||
| @@ -19,6 +19,10 @@ | |||||
| #include "src/DistrhoDefines.h" | #include "src/DistrhoDefines.h" | ||||
| #ifndef __STDC_LIMIT_MACROS | |||||
| # define __STDC_LIMIT_MACROS | |||||
| #endif | |||||
| #include <cstdarg> | #include <cstdarg> | ||||
| #include <cstdio> | #include <cstdio> | ||||
| #include <cstdlib> | #include <cstdlib> | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -19,7 +19,6 @@ | |||||
| #include "../DistrhoUtils.hpp" | #include "../DistrhoUtils.hpp" | ||||
| #include <cctype> | |||||
| #include <vector> | #include <vector> | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -55,7 +54,7 @@ | |||||
| #ifndef DOXYGEN | #ifndef DOXYGEN | ||||
| namespace DistrhoBase64Helpers { | namespace DistrhoBase64Helpers { | ||||
| static const char* const kBase64Chars = | |||||
| static constexpr const char* const kBase64Chars = | |||||
| "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||||
| "abcdefghijklmnopqrstuvwxyz" | "abcdefghijklmnopqrstuvwxyz" | ||||
| "0123456789+/"; | "0123456789+/"; | ||||
| @@ -63,7 +62,7 @@ static const char* const kBase64Chars = | |||||
| static inline | static inline | ||||
| uint8_t findBase64CharIndex(const char c) | uint8_t findBase64CharIndex(const char c) | ||||
| { | { | ||||
| static const uint8_t kBase64CharsLen(static_cast<uint8_t>(std::strlen(kBase64Chars))); | |||||
| static const uint8_t kBase64CharsLen = static_cast<uint8_t>(std::strlen(kBase64Chars)); | |||||
| for (uint8_t i=0; i<kBase64CharsLen; ++i) | for (uint8_t i=0; i<kBase64CharsLen; ++i) | ||||
| { | { | ||||
| @@ -75,10 +74,79 @@ uint8_t findBase64CharIndex(const char c) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static inline | |||||
| static constexpr inline | |||||
| bool isBase64Char(const char c) | bool isBase64Char(const char c) | ||||
| { | { | ||||
| return (std::isalnum(c) || (c == '+') || (c == '/')); | |||||
| switch (c) | |||||
| { | |||||
| case 'A': | |||||
| case 'B': | |||||
| case 'C': | |||||
| case 'D': | |||||
| case 'E': | |||||
| case 'F': | |||||
| case 'G': | |||||
| case 'H': | |||||
| case 'I': | |||||
| case 'J': | |||||
| case 'K': | |||||
| case 'L': | |||||
| case 'M': | |||||
| case 'N': | |||||
| case 'O': | |||||
| case 'P': | |||||
| case 'Q': | |||||
| case 'R': | |||||
| case 'S': | |||||
| case 'T': | |||||
| case 'U': | |||||
| case 'V': | |||||
| case 'W': | |||||
| case 'X': | |||||
| case 'Y': | |||||
| case 'Z': | |||||
| case 'a': | |||||
| case 'b': | |||||
| case 'c': | |||||
| case 'd': | |||||
| case 'e': | |||||
| case 'f': | |||||
| case 'g': | |||||
| case 'h': | |||||
| case 'i': | |||||
| case 'j': | |||||
| case 'k': | |||||
| case 'l': | |||||
| case 'm': | |||||
| case 'n': | |||||
| case 'o': | |||||
| case 'p': | |||||
| case 'q': | |||||
| case 'r': | |||||
| case 's': | |||||
| case 't': | |||||
| case 'u': | |||||
| case 'v': | |||||
| case 'w': | |||||
| case 'x': | |||||
| case 'y': | |||||
| case 'z': | |||||
| case '0': | |||||
| case '1': | |||||
| case '2': | |||||
| case '3': | |||||
| case '4': | |||||
| case '5': | |||||
| case '6': | |||||
| case '7': | |||||
| case '8': | |||||
| case '9': | |||||
| case '+': | |||||
| case '/': | |||||
| return true; | |||||
| default: | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| } // namespace DistrhoBase64Helpers | } // namespace DistrhoBase64Helpers | ||||
| @@ -1,5 +1,18 @@ | |||||
| // SPDX-FileCopyrightText: 2023-2024 MOD Audio UG | |||||
| // SPDX-License-Identifier: AGPL-3.0-or-later | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #pragma once | #pragma once | ||||
| @@ -24,13 +37,18 @@ START_NAMESPACE_DISTRHO | |||||
| class ChildProcess | class ChildProcess | ||||
| { | { | ||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||
| PROCESS_INFORMATION pinfo = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||||
| PROCESS_INFORMATION pinfo; | |||||
| #else | #else | ||||
| pid_t pid = -1; | |||||
| pid_t pid; | |||||
| #endif | #endif | ||||
| public: | public: | ||||
| ChildProcess() | ChildProcess() | ||||
| #ifdef _WIN32 | |||||
| : pinfo(CPP_AGGREGATE_INIT(PROCESS_INFORMATION){ INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }) | |||||
| #else | |||||
| : pid(-1) | |||||
| #endif | |||||
| { | { | ||||
| } | } | ||||
| @@ -120,7 +138,7 @@ public: | |||||
| return; | return; | ||||
| const PROCESS_INFORMATION opinfo = pinfo; | const PROCESS_INFORMATION opinfo = pinfo; | ||||
| pinfo = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||||
| pinfo = (PROCESS_INFORMATION){ INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||||
| for (DWORD exitCode;;) | for (DWORD exitCode;;) | ||||
| { | { | ||||
| @@ -226,7 +244,7 @@ public: | |||||
| WaitForSingleObject(pinfo.hProcess, 0) != WAIT_TIMEOUT) | WaitForSingleObject(pinfo.hProcess, 0) != WAIT_TIMEOUT) | ||||
| { | { | ||||
| const PROCESS_INFORMATION opinfo = pinfo; | const PROCESS_INFORMATION opinfo = pinfo; | ||||
| pinfo = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||||
| pinfo = (PROCESS_INFORMATION){ INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||||
| CloseHandle(opinfo.hThread); | CloseHandle(opinfo.hThread); | ||||
| CloseHandle(opinfo.hProcess); | CloseHandle(opinfo.hProcess); | ||||
| return false; | return false; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -78,13 +78,13 @@ public: | |||||
| Constructor. | Constructor. | ||||
| */ | */ | ||||
| explicit ExternalWindow() | explicit ExternalWindow() | ||||
| : pData() {} | |||||
| : pData() {} | |||||
| /** | /** | ||||
| Constructor for DPF internal use. | Constructor for DPF internal use. | ||||
| */ | */ | ||||
| explicit ExternalWindow(const PrivateData& data) | explicit ExternalWindow(const PrivateData& data) | ||||
| : pData(data) {} | |||||
| : pData(data) {} | |||||
| /** | /** | ||||
| Destructor. | Destructor. | ||||
| @@ -691,17 +691,17 @@ bool fileBrowserIdle(const FileBrowserHandle handle) | |||||
| while (dbus_connection_dispatch(dbuscon) == DBUS_DISPATCH_DATA_REMAINS) {} | while (dbus_connection_dispatch(dbuscon) == DBUS_DISPATCH_DATA_REMAINS) {} | ||||
| dbus_connection_read_write_dispatch(dbuscon, 0); | dbus_connection_read_write_dispatch(dbuscon, 0); | ||||
| if (DBusMessage* const message = dbus_connection_pop_message(dbuscon)) | |||||
| if (DBusMessage* const msg = dbus_connection_pop_message(dbuscon)) | |||||
| { | { | ||||
| const char* const interface = dbus_message_get_interface(message); | |||||
| const char* const member = dbus_message_get_member(message); | |||||
| const char* const interface = dbus_message_get_interface(msg); | |||||
| const char* const member = dbus_message_get_member(msg); | |||||
| if (interface != nullptr && std::strcmp(interface, "org.freedesktop.portal.Request") == 0 | if (interface != nullptr && std::strcmp(interface, "org.freedesktop.portal.Request") == 0 | ||||
| && member != nullptr && std::strcmp(member, "Response") == 0) | && member != nullptr && std::strcmp(member, "Response") == 0) | ||||
| { | { | ||||
| do { | do { | ||||
| DBusMessageIter iter; | DBusMessageIter iter; | ||||
| dbus_message_iter_init(message, &iter); | |||||
| dbus_message_iter_init(msg, &iter); | |||||
| // starts with uint32 for return/exit code | // starts with uint32 for return/exit code | ||||
| DISTRHO_SAFE_ASSERT_BREAK(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32); | DISTRHO_SAFE_ASSERT_BREAK(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32); | ||||
| @@ -813,6 +813,8 @@ bool fileBrowserIdle(const FileBrowserHandle handle) | |||||
| if (handle->selectedFile == nullptr) | if (handle->selectedFile == nullptr) | ||||
| handle->selectedFile = kSelectedFileCancelled; | handle->selectedFile = kSelectedFileCancelled; | ||||
| } | } | ||||
| dbus_message_unref(msg); | |||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -119,14 +119,6 @@ struct HugeStackBuffer { | |||||
| uint8_t buf[size]; | uint8_t buf[size]; | ||||
| }; | }; | ||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| # define HeapBuffer_INIT {0, 0, 0, 0, false, nullptr} | |||||
| # define StackBuffer_INIT {0, 0, 0, false, {0}} | |||||
| #else | |||||
| # define HeapBuffer_INIT | |||||
| # define StackBuffer_INIT | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // RingBufferControl templated class | // RingBufferControl templated class | ||||
| @@ -799,12 +791,7 @@ class HeapRingBuffer : public RingBufferControl<HeapBuffer> | |||||
| public: | public: | ||||
| /** Constructor. */ | /** Constructor. */ | ||||
| HeapRingBuffer() noexcept | HeapRingBuffer() noexcept | ||||
| : heapBuffer(HeapBuffer_INIT) | |||||
| { | |||||
| #ifndef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| std::memset(&heapBuffer, 0, sizeof(heapBuffer)); | |||||
| #endif | |||||
| } | |||||
| : heapBuffer(CPP_AGGREGATE_INIT(HeapBuffer){0, 0, 0, 0, false, nullptr}) {} | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~HeapRingBuffer() noexcept override | ~HeapRingBuffer() noexcept override | ||||
| @@ -874,11 +861,8 @@ class SmallStackRingBuffer : public RingBufferControl<SmallStackBuffer> | |||||
| public: | public: | ||||
| /** Constructor. */ | /** Constructor. */ | ||||
| SmallStackRingBuffer() noexcept | SmallStackRingBuffer() noexcept | ||||
| : stackBuffer(StackBuffer_INIT) | |||||
| : stackBuffer(CPP_AGGREGATE_INIT(SmallStackBuffer){0, 0, 0, false, {0}}) | |||||
| { | { | ||||
| #ifndef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| std::memset(&stackBuffer, 0, sizeof(stackBuffer)); | |||||
| #endif | |||||
| setRingBuffer(&stackBuffer, true); | setRingBuffer(&stackBuffer, true); | ||||
| } | } | ||||
| @@ -591,7 +591,7 @@ public: | |||||
| */ | */ | ||||
| String& toLower() noexcept | String& toLower() noexcept | ||||
| { | { | ||||
| static const char kCharDiff('a' - 'A'); | |||||
| static constexpr const char kCharDiff = 'a' - 'A'; | |||||
| for (std::size_t i=0; i < fBufferLen; ++i) | for (std::size_t i=0; i < fBufferLen; ++i) | ||||
| { | { | ||||
| @@ -607,7 +607,7 @@ public: | |||||
| */ | */ | ||||
| String& toUpper() noexcept | String& toUpper() noexcept | ||||
| { | { | ||||
| static const char kCharDiff('a' - 'A'); | |||||
| static constexpr const char kCharDiff = 'a' - 'A'; | |||||
| for (std::size_t i=0; i < fBufferLen; ++i) | for (std::size_t i=0; i < fBufferLen; ++i) | ||||
| { | { | ||||
| @@ -676,7 +676,7 @@ public: | |||||
| static String asBase64(const void* const data, const std::size_t dataSize) | static String asBase64(const void* const data, const std::size_t dataSize) | ||||
| { | { | ||||
| static const char* const kBase64Chars = | |||||
| static constexpr const char* const kBase64Chars = | |||||
| "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||||
| "abcdefghijklmnopqrstuvwxyz" | "abcdefghijklmnopqrstuvwxyz" | ||||
| "0123456789+/"; | "0123456789+/"; | ||||
| @@ -749,6 +749,192 @@ public: | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| /* | |||||
| * Convert to a URL encoded string. | |||||
| */ | |||||
| String& urlEncode() noexcept | |||||
| { | |||||
| static constexpr const char* const kHexChars = "0123456789ABCDEF"; | |||||
| if (fBufferLen == 0) | |||||
| return *this; | |||||
| char* const newbuf = static_cast<char*>(std::malloc(fBufferLen * 3 + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newbuf != nullptr, *this); | |||||
| char* newbufptr = newbuf; | |||||
| for (std::size_t i=0; i < fBufferLen; ++i) | |||||
| { | |||||
| const char c = fBuffer[i]; | |||||
| switch (c) | |||||
| { | |||||
| case '!': // 33 | |||||
| case '#': // 35 | |||||
| case '$': // 36 | |||||
| case '&': // 38 | |||||
| case '\'': // 39 | |||||
| case '(': // 40 | |||||
| case ')': // 41 | |||||
| case '*': // 42 | |||||
| case '+': // 43 | |||||
| case ',': // 44 | |||||
| case '-': // 45 | |||||
| case '.': // 46 | |||||
| case '/': // 47 | |||||
| case '0': // 48 | |||||
| case '1': // 49 | |||||
| case '2': // 50 | |||||
| case '3': // 51 | |||||
| case '4': // 52 | |||||
| case '5': // 53 | |||||
| case '6': // 54 | |||||
| case '7': // 55 | |||||
| case '8': // 56 | |||||
| case '9': // 57 | |||||
| case ':': // 58 | |||||
| case ';': // 59 | |||||
| case '=': // 61 | |||||
| case '?': // 63 | |||||
| case '@': // 64 | |||||
| case 'A': // 65 | |||||
| case 'B': // 66 | |||||
| case 'C': // 67 | |||||
| case 'D': // 68 | |||||
| case 'E': // 69 | |||||
| case 'F': // 70 | |||||
| case 'G': // 71 | |||||
| case 'H': // 72 | |||||
| case 'I': // 73 | |||||
| case 'J': // 74 | |||||
| case 'K': // 75 | |||||
| case 'L': // 76 | |||||
| case 'M': // 77 | |||||
| case 'N': // 78 | |||||
| case 'O': // 79 | |||||
| case 'P': // 80 | |||||
| case 'Q': // 81 | |||||
| case 'R': // 82 | |||||
| case 'S': // 83 | |||||
| case 'T': // 84 | |||||
| case 'U': // 85 | |||||
| case 'V': // 86 | |||||
| case 'W': // 87 | |||||
| case 'X': // 88 | |||||
| case 'Y': // 89 | |||||
| case 'Z': // 90 | |||||
| case '[': // 91 | |||||
| case ']': // 93 | |||||
| case '_': // 95 | |||||
| case 'a': // 97 | |||||
| case 'b': // 98 | |||||
| case 'c': // 99 | |||||
| case 'd': // 100 | |||||
| case 'e': // 101 | |||||
| case 'f': // 102 | |||||
| case 'g': // 103 | |||||
| case 'h': // 104 | |||||
| case 'i': // 105 | |||||
| case 'j': // 106 | |||||
| case 'k': // 107 | |||||
| case 'l': // 108 | |||||
| case 'm': // 109 | |||||
| case 'n': // 110 | |||||
| case 'o': // 111 | |||||
| case 'p': // 112 | |||||
| case 'q': // 113 | |||||
| case 'r': // 114 | |||||
| case 's': // 115 | |||||
| case 't': // 116 | |||||
| case 'u': // 117 | |||||
| case 'v': // 118 | |||||
| case 'w': // 119 | |||||
| case 'x': // 120 | |||||
| case 'y': // 121 | |||||
| case 'z': // 122 | |||||
| case '~': // 126 | |||||
| *newbufptr++ = c; | |||||
| break; | |||||
| default: | |||||
| *newbufptr++ = '%'; | |||||
| *newbufptr++ = kHexChars[(c >> 4) & 0xf]; | |||||
| *newbufptr++ = kHexChars[c & 0xf]; | |||||
| break; | |||||
| } | |||||
| } | |||||
| *newbufptr = '\0'; | |||||
| std::free(fBuffer); | |||||
| fBuffer = newbuf; | |||||
| fBufferLen = std::strlen(newbuf); | |||||
| fBufferAlloc = true; | |||||
| return *this; | |||||
| } | |||||
| /* | |||||
| * Convert to a URL decoded string. | |||||
| */ | |||||
| String& urlDecode() noexcept | |||||
| { | |||||
| if (fBufferLen == 0) | |||||
| return *this; | |||||
| char* const newbuf = static_cast<char*>(std::malloc(fBufferLen + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newbuf != nullptr, *this); | |||||
| char* newbufptr = newbuf; | |||||
| for (std::size_t i=0; i < fBufferLen; ++i) | |||||
| { | |||||
| const char c = fBuffer[i]; | |||||
| if (c == '%') | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_CONTINUE(fBufferLen > i + 2); | |||||
| char c1 = fBuffer[i + 1]; | |||||
| char c2 = fBuffer[i + 2]; | |||||
| i += 2; | |||||
| /**/ if (c1 >= '0' && c1 <= '9') | |||||
| c1 -= '0'; | |||||
| else if (c1 >= 'A' && c1 <= 'Z') | |||||
| c1 -= 'A' - 10; | |||||
| else if (c1 >= 'a' && c1 <= 'z') | |||||
| c1 -= 'a' - 10; | |||||
| else | |||||
| continue; | |||||
| /**/ if (c2 >= '0' && c2 <= '9') | |||||
| c2 -= '0'; | |||||
| else if (c2 >= 'A' && c2 <= 'Z') | |||||
| c2 -= 'A' - 10; | |||||
| else if (c2 >= 'a' && c2 <= 'z') | |||||
| c2 -= 'a' - 10; | |||||
| else | |||||
| continue; | |||||
| *newbufptr++ = c1 << 4 | c2; | |||||
| } | |||||
| else | |||||
| { | |||||
| *newbufptr++ = c; | |||||
| } | |||||
| } | |||||
| *newbufptr = '\0'; | |||||
| std::free(fBuffer); | |||||
| fBuffer = newbuf; | |||||
| fBufferLen = std::strlen(newbuf); | |||||
| fBufferAlloc = true; | |||||
| return *this; | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // public operators | // public operators | ||||
| @@ -830,7 +1016,7 @@ public: | |||||
| } | } | ||||
| // we have some data ourselves, reallocate to add the new stuff | // we have some data ourselves, reallocate to add the new stuff | ||||
| char* const newBuf = (char*)realloc(fBuffer, fBufferLen + strBufLen + 1); | |||||
| char* const newBuf = static_cast<char*>(std::realloc(fBuffer, fBufferLen + strBufLen + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, *this); | DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, *this); | ||||
| std::memcpy(newBuf + fBufferLen, strBuf, strBufLen + 1); | std::memcpy(newBuf + fBufferLen, strBuf, strBufLen + 1); | ||||
| @@ -855,7 +1041,7 @@ public: | |||||
| const std::size_t strBufLen = std::strlen(strBuf); | const std::size_t strBufLen = std::strlen(strBuf); | ||||
| const std::size_t newBufSize = fBufferLen + strBufLen; | const std::size_t newBufSize = fBufferLen + strBufLen; | ||||
| char* const newBuf = (char*)malloc(newBufSize + 1); | |||||
| char* const newBuf = static_cast<char*>(std::malloc(newBufSize + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | ||||
| std::memcpy(newBuf, fBuffer, fBufferLen); | std::memcpy(newBuf, fBuffer, fBufferLen); | ||||
| @@ -912,7 +1098,7 @@ private: | |||||
| std::free(fBuffer); | std::free(fBuffer); | ||||
| fBufferLen = (size > 0) ? size : std::strlen(strBuf); | fBufferLen = (size > 0) ? size : std::strlen(strBuf); | ||||
| fBuffer = (char*)std::malloc(fBufferLen+1); | |||||
| fBuffer = static_cast<char*>(std::malloc(fBufferLen + 1)); | |||||
| if (fBuffer == nullptr) | if (fBuffer == nullptr) | ||||
| { | { | ||||
| @@ -960,7 +1146,7 @@ String operator+(const String& strBefore, const char* const strBufAfter) noexcep | |||||
| const std::size_t strBeforeLen = strBefore.length(); | const std::size_t strBeforeLen = strBefore.length(); | ||||
| const std::size_t strBufAfterLen = std::strlen(strBufAfter); | const std::size_t strBufAfterLen = std::strlen(strBufAfter); | ||||
| const std::size_t newBufSize = strBeforeLen + strBufAfterLen; | const std::size_t newBufSize = strBeforeLen + strBufAfterLen; | ||||
| char* const newBuf = (char*)malloc(newBufSize + 1); | |||||
| char* const newBuf = static_cast<char*>(malloc(newBufSize + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | ||||
| std::memcpy(newBuf, strBefore.buffer(), strBeforeLen); | std::memcpy(newBuf, strBefore.buffer(), strBeforeLen); | ||||
| @@ -980,7 +1166,7 @@ String operator+(const char* const strBufBefore, const String& strAfter) noexcep | |||||
| const std::size_t strBufBeforeLen = std::strlen(strBufBefore); | const std::size_t strBufBeforeLen = std::strlen(strBufBefore); | ||||
| const std::size_t strAfterLen = strAfter.length(); | const std::size_t strAfterLen = strAfter.length(); | ||||
| const std::size_t newBufSize = strBufBeforeLen + strAfterLen; | const std::size_t newBufSize = strBufBeforeLen + strAfterLen; | ||||
| char* const newBuf = (char*)malloc(newBufSize + 1); | |||||
| char* const newBuf = static_cast<char*>(malloc(newBufSize + 1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | DISTRHO_SAFE_ASSERT_RETURN(newBuf != nullptr, String()); | ||||
| std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | ||||
| @@ -86,6 +86,7 @@ struct WebViewOptions { | |||||
| Provided metrics must have scale factor pre-applied. | Provided metrics must have scale factor pre-applied. | ||||
| @p url: The URL to open, assumed to be in encoded form (e.g spaces converted to %20) | |||||
| @p windowId: The native window id to attach this view to (X11 Window, HWND or NSView*) | @p windowId: The native window id to attach this view to (X11 Window, HWND or NSView*) | ||||
| @p scaleFactor: Scale factor in use | @p scaleFactor: Scale factor in use | ||||
| @p options: Extra options, optional | @p options: Extra options, optional | ||||
| @@ -215,6 +215,12 @@ private: \ | |||||
| #define STRINGIFY2(s) #s | #define STRINGIFY2(s) #s | ||||
| #define STRINGIFY(s) STRINGIFY2(s) | #define STRINGIFY(s) STRINGIFY2(s) | ||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| #define CPP_AGGREGATE_INIT(ClassName) ClassName | |||||
| #else | |||||
| #define CPP_AGGREGATE_INIT(ClassName) (ClassName) | |||||
| #endif | |||||
| /* Useful typedefs */ | /* Useful typedefs */ | ||||
| typedef unsigned char uchar; | typedef unsigned char uchar; | ||||
| typedef unsigned short int ushort; | typedef unsigned short int ushort; | ||||
| @@ -2038,7 +2038,7 @@ public: | |||||
| case 0x9: | case 0x9: | ||||
| case 0xD: | case 0xD: | ||||
| // unsupported | // unsupported | ||||
| kAudioUnitErr_InvalidPropertyValue; | |||||
| return kAudioUnitErr_InvalidPropertyValue; | |||||
| case 0x1: | case 0x1: | ||||
| case 0x2: | case 0x2: | ||||
| case 0x3: | case 0x3: | ||||
| @@ -171,12 +171,9 @@ struct ClapEventQueue | |||||
| ClapEventQueue() | ClapEventQueue() | ||||
| #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| : fNotesBuffer(StackBuffer_INIT) | |||||
| : fNotesBuffer(CPP_AGGREGATE_INIT(SmallStackBuffer){0, 0, 0, false, {0}}) | |||||
| #endif | #endif | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| std::memset(&fNotesBuffer, 0, sizeof(fNotesBuffer)); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| fCurrentProgram = 0; | fCurrentProgram = 0; | ||||
| #endif | #endif | ||||
| @@ -117,13 +117,10 @@ struct ParameterAndNotesHelper | |||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| , parameterChecks(nullptr) | , parameterChecks(nullptr) | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| , notesRingBuffer(StackBuffer_INIT) | |||||
| , notesRingBuffer(CPP_AGGREGATE_INIT(SmallStackBuffer){0, 0, 0, false, {0}}) | |||||
| #endif | #endif | ||||
| #endif | #endif | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| std::memset(¬esRingBuffer, 0, sizeof(notesRingBuffer)); | |||||
| #endif | |||||
| } | } | ||||
| virtual ~ParameterAndNotesHelper() | virtual ~ParameterAndNotesHelper() | ||||
| @@ -359,14 +359,14 @@ class PluginVst3 | |||||
| midiEvent.size = 3; | midiEvent.size = 3; | ||||
| midiEvent.data[0] = 0x90 | (eventStorage.noteOn.channel & 0xf); | midiEvent.data[0] = 0x90 | (eventStorage.noteOn.channel & 0xf); | ||||
| midiEvent.data[1] = eventStorage.noteOn.pitch; | midiEvent.data[1] = eventStorage.noteOn.pitch; | ||||
| midiEvent.data[2] = std::max(0, std::min(127, (int)(eventStorage.noteOn.velocity * 127))); | |||||
| midiEvent.data[2] = std::max(0, std::min(127, d_roundToIntPositive(eventStorage.noteOn.velocity * 127))); | |||||
| midiEvent.data[3] = 0; | midiEvent.data[3] = 0; | ||||
| break; | break; | ||||
| case NoteOff: | case NoteOff: | ||||
| midiEvent.size = 3; | midiEvent.size = 3; | ||||
| midiEvent.data[0] = 0x80 | (eventStorage.noteOff.channel & 0xf); | midiEvent.data[0] = 0x80 | (eventStorage.noteOff.channel & 0xf); | ||||
| midiEvent.data[1] = eventStorage.noteOff.pitch; | midiEvent.data[1] = eventStorage.noteOff.pitch; | ||||
| midiEvent.data[2] = std::max(0, std::min(127, (int)(eventStorage.noteOff.velocity * 127))); | |||||
| midiEvent.data[2] = std::max(0, std::min(127, d_roundToIntPositive(eventStorage.noteOff.velocity * 127))); | |||||
| midiEvent.data[3] = 0; | midiEvent.data[3] = 0; | ||||
| break; | break; | ||||
| /* TODO | /* TODO | ||||
| @@ -377,7 +377,7 @@ class PluginVst3 | |||||
| midiEvent.size = 3; | midiEvent.size = 3; | ||||
| midiEvent.data[0] = 0xA0 | (eventStorage.polyPressure.channel & 0xf); | midiEvent.data[0] = 0xA0 | (eventStorage.polyPressure.channel & 0xf); | ||||
| midiEvent.data[1] = eventStorage.polyPressure.pitch; | midiEvent.data[1] = eventStorage.polyPressure.pitch; | ||||
| midiEvent.data[2] = std::max(0, std::min(127, (int)(eventStorage.polyPressure.pressure * 127))); | |||||
| midiEvent.data[2] = std::max(0, std::min(127, d_roundToIntPositive(eventStorage.polyPressure.pressure * 127))); | |||||
| midiEvent.data[3] = 0; | midiEvent.data[3] = 0; | ||||
| break; | break; | ||||
| case CC_Normal: | case CC_Normal: | ||||
| @@ -469,7 +469,7 @@ class PluginVst3 | |||||
| { | { | ||||
| case 128: | case 128: | ||||
| eventStorage.type = CC_ChannelPressure; | eventStorage.type = CC_ChannelPressure; | ||||
| eventStorage.midi[1] = std::max(0, std::min(127, (int)(normalized * 127))); | |||||
| eventStorage.midi[1] = std::max(0, std::min(127, d_roundToIntPositive(normalized * 127))); | |||||
| eventStorage.midi[2] = 0; | eventStorage.midi[2] = 0; | ||||
| break; | break; | ||||
| case 129: | case 129: | ||||
| @@ -480,7 +480,7 @@ class PluginVst3 | |||||
| default: | default: | ||||
| eventStorage.type = CC_Normal; | eventStorage.type = CC_Normal; | ||||
| eventStorage.midi[1] = cc; | eventStorage.midi[1] = cc; | ||||
| eventStorage.midi[2] = std::max(0, std::min(127, (int)(normalized * 127))); | |||||
| eventStorage.midi[2] = std::max(0, std::min(127, d_roundToIntPositive(normalized * 127))); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -4459,7 +4459,8 @@ struct dpf_component : v3_component_cpp { | |||||
| dpf_component* const component = *static_cast<dpf_component**>(self); | dpf_component* const component = *static_cast<dpf_component**>(self); | ||||
| PluginVst3* const vst3 = component->vst3; | PluginVst3* const vst3 = component->vst3; | ||||
| DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALIZED); | |||||
| // It must be called *before* "initialize". | |||||
| DISTRHO_SAFE_ASSERT_RETURN(vst3 == nullptr, V3_NOT_INITIALIZED); | |||||
| // TODO | // TODO | ||||
| return V3_NOT_IMPLEMENTED; | return V3_NOT_IMPLEMENTED; | ||||
| @@ -119,7 +119,7 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle) | |||||
| { | { | ||||
| const HMONITOR hMon = parentWindowHandle != 0 | const HMONITOR hMon = parentWindowHandle != 0 | ||||
| ? MonitorFromWindow((HWND)parentWindowHandle, MONITOR_DEFAULTTOPRIMARY) | ? MonitorFromWindow((HWND)parentWindowHandle, MONITOR_DEFAULTTOPRIMARY) | ||||
| : MonitorFromPoint(POINT{0,0}, MONITOR_DEFAULTTOPRIMARY); | |||||
| : MonitorFromPoint(POINT(), MONITOR_DEFAULTTOPRIMARY); | |||||
| GetScaleFactorForMonitor(hMon, &scaleFactor); | GetScaleFactorForMonitor(hMon, &scaleFactor); | ||||
| } | } | ||||
| @@ -200,24 +200,30 @@ PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, uint width, uint h | |||||
| path += "/resources"; | path += "/resources"; | ||||
| } | } | ||||
| path.urlEncode(); | |||||
| // TODO convert win32 paths to web | // TODO convert win32 paths to web | ||||
| // TODO encode paths (e.g. %20 for space) | |||||
| WebViewOptions opts; | WebViewOptions opts; | ||||
| opts.initialJS = "" | opts.initialJS = "" | ||||
| "editParameter = function(index, started){ postMessage('editparam '+index+' '+(started ? 1 : 0)) };" | |||||
| "setParameterValue = function(index, value){ postMessage('setparam '+index+' '+value) };" | |||||
| "editParameter = function(index, started){ postMessage('editparam ' + index + ' ' + (started ? '1' : '0')) };" | |||||
| "setParameterValue = function(index, value){ postMessage('setparam ' + index + ' ' + value) };" | |||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| "setState = function(key, value){ postMessage('setstate '+key+' '+value) };" | |||||
| "requestStateFile = function(key){ postMessage('reqstatefile '+key) };" | |||||
| "setState = function(key, value){ postMessage('setstate ' + key + ' ' + value) };" | |||||
| "requestStateFile = function(key){ postMessage('reqstatefile ' + key) };" | |||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| "sendNote = function(channel, note, velocity){ postMessage('sendnote '+channel+' '+note+' '+velocity) };" | |||||
| "sendNote = function(channel, note, velocity){ postMessage('sendnote ' + channel + ' ' + note + ' ' + velocity) };" | |||||
| #endif | #endif | ||||
| ; | ; | ||||
| opts.callback = webViewMessageCallback; | opts.callback = webViewMessageCallback; | ||||
| opts.callbackPtr = uiData; | opts.callbackPtr = uiData; | ||||
| uiData->webview = webViewCreate("file://" + path + "/index.html", uiData->winId, width, height, scaleFactor, opts); | |||||
| uiData->webview = webViewCreate("file://" + path + "/index.html", | |||||
| uiData->winId != 0 ? uiData->winId : uiData->window->getNativeWindowHandle(), | |||||
| width, | |||||
| height, | |||||
| scaleFactor, | |||||
| opts); | |||||
| #endif | #endif | ||||
| } | } | ||||
| // If there are no callbacks, this is most likely a temporary window, so ignore idle callbacks | // If there are no callbacks, this is most likely a temporary window, so ignore idle callbacks | ||||
| @@ -268,7 +274,7 @@ void UI::PrivateData::webViewMessageCallback(void* const arg, char* const msg) | |||||
| char* const key = msg + 9; | char* const key = msg + 9; | ||||
| char* const sep = std::strchr(key, ' '); | char* const sep = std::strchr(key, ' '); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(sep != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(sep != nullptr,); | ||||
| *sep = 0; | |||||
| *sep = '\0'; | |||||
| char* const value = sep + 1; | char* const value = sep + 1; | ||||
| uiData->setStateCallback(key, value); | uiData->setStateCallback(key, value); | ||||