@@ -2,6 +2,11 @@ name: build | |||
on: | |||
push: | |||
branches: | |||
- '*' | |||
pull_request: | |||
branches: | |||
- '*' | |||
jobs: | |||
linux: | |||
@@ -10,7 +15,7 @@ jobs: | |||
target: [linux-arm64, linux-armhf, linux-i686, linux-riscv64, linux-x86_64] | |||
runs-on: ubuntu-20.04 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: actions/checkout@v4 | |||
with: | |||
submodules: recursive | |||
- uses: distrho/dpf-makefile-action@v1 | |||
@@ -23,7 +28,7 @@ jobs: | |||
target: [macos-intel, macos-universal] | |||
runs-on: macos-11 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: actions/checkout@v4 | |||
with: | |||
submodules: recursive | |||
- uses: distrho/dpf-makefile-action@v1 | |||
@@ -36,7 +41,7 @@ jobs: | |||
target: [win32, win64] | |||
runs-on: ubuntu-20.04 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: actions/checkout@v4 | |||
with: | |||
submodules: recursive | |||
- uses: distrho/dpf-makefile-action@v1 | |||
@@ -47,7 +52,7 @@ jobs: | |||
pluginval: | |||
runs-on: ubuntu-20.04 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: actions/checkout@v4 | |||
with: | |||
submodules: recursive | |||
- 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 | |||
Checks: > | |||
@@ -11,6 +11,7 @@ Checks: > | |||
-clang-diagnostic-unused-macros, | |||
-llvmlibc-*, | |||
-misc-include-cleaner, | |||
-readability-avoid-nested-conditional-operator, | |||
-readability-identifier-length, | |||
CheckOptions: | |||
- 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 | |||
Checks: > | |||
-bugprone-easily-swappable-parameters, | |||
-bugprone-multi-level-implicit-pointer-conversion, | |||
-clang-analyzer-optin.core.EnumCastOutOfRange, | |||
-hicpp-multiway-paths-covered, | |||
-hicpp-signed-bitwise, | |||
-llvm-header-guard, | |||
@@ -633,11 +633,11 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type) | |||
const NSPoint wloc = [self eventLocation:event]; | |||
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 = | |||
@@ -19,6 +19,10 @@ | |||
#include "src/DistrhoDefines.h" | |||
#ifndef __STDC_LIMIT_MACROS | |||
# define __STDC_LIMIT_MACROS | |||
#endif | |||
#include <cstdarg> | |||
#include <cstdio> | |||
#include <cstdlib> | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -19,7 +19,6 @@ | |||
#include "../DistrhoUtils.hpp" | |||
#include <cctype> | |||
#include <vector> | |||
// ----------------------------------------------------------------------- | |||
@@ -55,7 +54,7 @@ | |||
#ifndef DOXYGEN | |||
namespace DistrhoBase64Helpers { | |||
static const char* const kBase64Chars = | |||
static constexpr const char* const kBase64Chars = | |||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |||
"abcdefghijklmnopqrstuvwxyz" | |||
"0123456789+/"; | |||
@@ -63,7 +62,7 @@ static const char* const kBase64Chars = | |||
static inline | |||
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) | |||
{ | |||
@@ -75,10 +74,79 @@ uint8_t findBase64CharIndex(const char c) | |||
return 0; | |||
} | |||
static inline | |||
static constexpr inline | |||
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 | |||
@@ -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 | |||
@@ -24,13 +37,18 @@ START_NAMESPACE_DISTRHO | |||
class ChildProcess | |||
{ | |||
#ifdef _WIN32 | |||
PROCESS_INFORMATION pinfo = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; | |||
PROCESS_INFORMATION pinfo; | |||
#else | |||
pid_t pid = -1; | |||
pid_t pid; | |||
#endif | |||
public: | |||
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; | |||
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;;) | |||
{ | |||
@@ -226,7 +244,7 @@ public: | |||
WaitForSingleObject(pinfo.hProcess, 0) != WAIT_TIMEOUT) | |||
{ | |||
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.hProcess); | |||
return false; | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -78,13 +78,13 @@ public: | |||
Constructor. | |||
*/ | |||
explicit ExternalWindow() | |||
: pData() {} | |||
: pData() {} | |||
/** | |||
Constructor for DPF internal use. | |||
*/ | |||
explicit ExternalWindow(const PrivateData& data) | |||
: pData(data) {} | |||
: pData(data) {} | |||
/** | |||
Destructor. | |||
@@ -691,17 +691,17 @@ bool fileBrowserIdle(const FileBrowserHandle handle) | |||
while (dbus_connection_dispatch(dbuscon) == DBUS_DISPATCH_DATA_REMAINS) {} | |||
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 | |||
&& member != nullptr && std::strcmp(member, "Response") == 0) | |||
{ | |||
do { | |||
DBusMessageIter iter; | |||
dbus_message_iter_init(message, &iter); | |||
dbus_message_iter_init(msg, &iter); | |||
// starts with uint32 for return/exit code | |||
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) | |||
handle->selectedFile = kSelectedFileCancelled; | |||
} | |||
dbus_message_unref(msg); | |||
} | |||
} | |||
#endif | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -119,14 +119,6 @@ struct HugeStackBuffer { | |||
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 | |||
@@ -799,12 +791,7 @@ class HeapRingBuffer : public RingBufferControl<HeapBuffer> | |||
public: | |||
/** Constructor. */ | |||
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. */ | |||
~HeapRingBuffer() noexcept override | |||
@@ -874,11 +861,8 @@ class SmallStackRingBuffer : public RingBufferControl<SmallStackBuffer> | |||
public: | |||
/** Constructor. */ | |||
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); | |||
} | |||
@@ -591,7 +591,7 @@ public: | |||
*/ | |||
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) | |||
{ | |||
@@ -607,7 +607,7 @@ public: | |||
*/ | |||
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) | |||
{ | |||
@@ -676,7 +676,7 @@ public: | |||
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" | |||
"0123456789+/"; | |||
@@ -749,6 +749,192 @@ public: | |||
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 | |||
@@ -830,7 +1016,7 @@ public: | |||
} | |||
// 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); | |||
std::memcpy(newBuf + fBufferLen, strBuf, strBufLen + 1); | |||
@@ -855,7 +1041,7 @@ public: | |||
const std::size_t strBufLen = std::strlen(strBuf); | |||
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()); | |||
std::memcpy(newBuf, fBuffer, fBufferLen); | |||
@@ -912,7 +1098,7 @@ private: | |||
std::free(fBuffer); | |||
fBufferLen = (size > 0) ? size : std::strlen(strBuf); | |||
fBuffer = (char*)std::malloc(fBufferLen+1); | |||
fBuffer = static_cast<char*>(std::malloc(fBufferLen + 1)); | |||
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 strBufAfterLen = std::strlen(strBufAfter); | |||
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()); | |||
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 strAfterLen = strAfter.length(); | |||
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()); | |||
std::memcpy(newBuf, strBufBefore, strBufBeforeLen); | |||
@@ -86,6 +86,7 @@ struct WebViewOptions { | |||
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 scaleFactor: Scale factor in use | |||
@p options: Extra options, optional | |||
@@ -215,6 +215,12 @@ private: \ | |||
#define STRINGIFY2(s) #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 */ | |||
typedef unsigned char uchar; | |||
typedef unsigned short int ushort; | |||
@@ -2038,7 +2038,7 @@ public: | |||
case 0x9: | |||
case 0xD: | |||
// unsupported | |||
kAudioUnitErr_InvalidPropertyValue; | |||
return kAudioUnitErr_InvalidPropertyValue; | |||
case 0x1: | |||
case 0x2: | |||
case 0x3: | |||
@@ -171,12 +171,9 @@ struct ClapEventQueue | |||
ClapEventQueue() | |||
#if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
: fNotesBuffer(StackBuffer_INIT) | |||
: fNotesBuffer(CPP_AGGREGATE_INIT(SmallStackBuffer){0, 0, 0, false, {0}}) | |||
#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 | |||
fCurrentProgram = 0; | |||
#endif | |||
@@ -117,13 +117,10 @@ struct ParameterAndNotesHelper | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
, parameterChecks(nullptr) | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
, notesRingBuffer(StackBuffer_INIT) | |||
, notesRingBuffer(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(¬esRingBuffer, 0, sizeof(notesRingBuffer)); | |||
#endif | |||
} | |||
virtual ~ParameterAndNotesHelper() | |||
@@ -359,14 +359,14 @@ class PluginVst3 | |||
midiEvent.size = 3; | |||
midiEvent.data[0] = 0x90 | (eventStorage.noteOn.channel & 0xf); | |||
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; | |||
break; | |||
case NoteOff: | |||
midiEvent.size = 3; | |||
midiEvent.data[0] = 0x80 | (eventStorage.noteOff.channel & 0xf); | |||
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; | |||
break; | |||
/* TODO | |||
@@ -377,7 +377,7 @@ class PluginVst3 | |||
midiEvent.size = 3; | |||
midiEvent.data[0] = 0xA0 | (eventStorage.polyPressure.channel & 0xf); | |||
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; | |||
break; | |||
case CC_Normal: | |||
@@ -469,7 +469,7 @@ class PluginVst3 | |||
{ | |||
case 128: | |||
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; | |||
break; | |||
case 129: | |||
@@ -480,7 +480,7 @@ class PluginVst3 | |||
default: | |||
eventStorage.type = CC_Normal; | |||
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; | |||
} | |||
@@ -4459,7 +4459,8 @@ struct dpf_component : v3_component_cpp { | |||
dpf_component* const component = *static_cast<dpf_component**>(self); | |||
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 | |||
return V3_NOT_IMPLEMENTED; | |||
@@ -119,7 +119,7 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle) | |||
{ | |||
const HMONITOR hMon = parentWindowHandle != 0 | |||
? MonitorFromWindow((HWND)parentWindowHandle, MONITOR_DEFAULTTOPRIMARY) | |||
: MonitorFromPoint(POINT{0,0}, MONITOR_DEFAULTTOPRIMARY); | |||
: MonitorFromPoint(POINT(), MONITOR_DEFAULTTOPRIMARY); | |||
GetScaleFactorForMonitor(hMon, &scaleFactor); | |||
} | |||
@@ -200,24 +200,30 @@ PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, uint width, uint h | |||
path += "/resources"; | |||
} | |||
path.urlEncode(); | |||
// TODO convert win32 paths to web | |||
// TODO encode paths (e.g. %20 for space) | |||
WebViewOptions opts; | |||
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 | |||
"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 | |||
#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 | |||
; | |||
opts.callback = webViewMessageCallback; | |||
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 | |||
} | |||
// 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 sep = std::strchr(key, ' '); | |||
DISTRHO_SAFE_ASSERT_RETURN(sep != nullptr,); | |||
*sep = 0; | |||
*sep = '\0'; | |||
char* const value = sep + 1; | |||
uiData->setStateCallback(key, value); | |||