Signed-off-by: falkTX <falktx@falktx.com>main
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Ildaeil Plugin | |||
| * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -35,30 +35,21 @@ public: | |||
| static Mutex sPluginInfoLoadMutex; | |||
| static const char* getPluginPath(PluginType ptype); | |||
| const NativePluginDescriptor* fCarlaPluginDescriptor; | |||
| NativePluginHandle fCarlaPluginHandle; | |||
| const NativePluginDescriptor* fCarlaPluginDescriptor = nullptr; | |||
| NativePluginHandle fCarlaPluginHandle = nullptr; | |||
| NativeHostDescriptor fCarlaHostDescriptor; | |||
| CarlaHostHandle fCarlaHostHandle; | |||
| NativeHostDescriptor fCarlaHostDescriptor{}; | |||
| CarlaHostHandle fCarlaHostHandle = nullptr; | |||
| String fBinaryPath; | |||
| void* fUI; | |||
| void* fUI = nullptr; | |||
| IldaeilBasePlugin() | |||
| : Plugin(0, 0, 1), | |||
| fCarlaPluginDescriptor(nullptr), | |||
| fCarlaPluginHandle(nullptr), | |||
| fCarlaHostHandle(nullptr), | |||
| fUI(nullptr) | |||
| { | |||
| memset(&fCarlaHostDescriptor, 0, sizeof(fCarlaHostDescriptor)); | |||
| } | |||
| IldaeilBasePlugin() : Plugin(0, 0, 1) {} | |||
| }; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| const char* ildaeilConfigDir(); | |||
| void ildaeilProjectLoadedFromDSP(void* ui); | |||
| void ildaeilParameterChangeForUI(void* ui, uint32_t index, float value); | |||
| void ildaeilResizeUI(void* ui, uint32_t width, uint32_t height); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Ildaeil Plugin | |||
| * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -316,63 +316,28 @@ const char* IldaeilBasePlugin::getPluginPath(const PluginType ptype) | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| const char* ildaeilConfigDir() | |||
| { | |||
| static water::String configDir; | |||
| if (configDir.isEmpty()) | |||
| { | |||
| #if defined(CARLA_OS_WASM) | |||
| configDir = "/userfiles"; | |||
| #elif defined(CARLA_OS_MAC) | |||
| configDir = getHomePath() + "/Documents/Ildaeil"; | |||
| #elif defined(CARLA_OS_WIN) | |||
| configDir = water::File::getSpecialLocation(water::File::winMyDocuments).getFullPathName() + "\\Ildaeil"; | |||
| #else | |||
| if (const char* const xdgEnv = getenv("XDG_CONFIG_HOME")) | |||
| configDir = xdgEnv; | |||
| else | |||
| configDir = getHomePath() + "/.config"; | |||
| configDir += "/Ildaeil"; | |||
| #endif | |||
| } | |||
| return configDir.toRawUTF8(); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| class IldaeilPlugin : public IldaeilBasePlugin | |||
| { | |||
| #if DISTRHO_PLUGIN_NUM_INPUTS == 0 || DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | |||
| float* fDummyBuffer; | |||
| float* fDummyBuffer = nullptr; | |||
| float* fDummyBuffers[2]; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| static constexpr const uint kMaxMidiEventCount = 512; | |||
| NativeMidiEvent* fMidiEvents; | |||
| NativeMidiEvent* fMidiEvents = nullptr; | |||
| #endif | |||
| mutable NativeTimeInfo fCarlaTimeInfo; | |||
| mutable NativeTimeInfo fCarlaTimeInfo{}; | |||
| mutable water::MemoryOutputStream fLastProjectState; | |||
| uint32_t fLastLatencyValue; | |||
| uint32_t fLastLatencyValue = 0; | |||
| public: | |||
| IldaeilPlugin() | |||
| : IldaeilBasePlugin(), | |||
| #if DISTRHO_PLUGIN_NUM_INPUTS == 0 || DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | |||
| fDummyBuffer(nullptr), | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| fMidiEvents(nullptr), | |||
| #endif | |||
| fLastLatencyValue(0) | |||
| : IldaeilBasePlugin() | |||
| { | |||
| fCarlaPluginDescriptor = carla_get_native_rack_plugin(); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginDescriptor != nullptr,); | |||
| memset(&fCarlaTimeInfo, 0, sizeof(fCarlaTimeInfo)); | |||
| fCarlaHostDescriptor.handle = this; | |||
| fCarlaHostDescriptor.resourceDir = carla_get_library_folder(); | |||
| fCarlaHostDescriptor.uiName = "Ildaeil"; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Ildaeil Plugin | |||
| * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -16,6 +16,7 @@ | |||
| */ | |||
| #include "IldaeilBasePlugin.hpp" | |||
| #include "DistrhoPluginUtils.hpp" | |||
| #include "DistrhoUI.hpp" | |||
| #if ILDAEIL_STANDALONE | |||
| @@ -78,53 +79,37 @@ class IldaeilUI : public UI, | |||
| }; | |||
| struct PluginGenericUI { | |||
| char* title; | |||
| uint parameterCount; | |||
| char* title = nullptr; | |||
| uint parameterCount = 0; | |||
| struct Parameter { | |||
| char* name; | |||
| char* printformat; | |||
| uint32_t rindex; | |||
| bool boolean, bvalue, log, readonly; | |||
| float min, max, power; | |||
| Parameter() | |||
| : name(nullptr), | |||
| printformat(nullptr), | |||
| rindex(0), | |||
| boolean(false), | |||
| bvalue(false), | |||
| log(false), | |||
| readonly(false), | |||
| min(0.0f), | |||
| max(1.0f) {} | |||
| char* name = nullptr; | |||
| char* printformat = nullptr; | |||
| uint32_t rindex = 0; | |||
| bool boolean = false; | |||
| bool bvalue = false; | |||
| bool log = false; | |||
| bool readonly = false; | |||
| float min = 0.f; | |||
| float max = 1.f; | |||
| ~Parameter() | |||
| { | |||
| std::free(name); | |||
| std::free(printformat); | |||
| } | |||
| }* parameters; | |||
| float* values; | |||
| }* parameters = nullptr; | |||
| float* values = nullptr; | |||
| uint presetCount; | |||
| uint presetCount = 0; | |||
| struct Preset { | |||
| uint32_t index; | |||
| char* name; | |||
| uint32_t index = 0; | |||
| char* name = nullptr; | |||
| ~Preset() | |||
| { | |||
| std::free(name); | |||
| } | |||
| }* presets; | |||
| int currentPreset; | |||
| const char** presetStrings; | |||
| PluginGenericUI() | |||
| : title(nullptr), | |||
| parameterCount(0), | |||
| parameters(nullptr), | |||
| values(nullptr), | |||
| presetCount(0), | |||
| presets(nullptr), | |||
| currentPreset(-1), | |||
| presetStrings(nullptr) {} | |||
| }* presets = nullptr; | |||
| int currentPreset = -1; | |||
| const char** presetStrings = nullptr; | |||
| ~PluginGenericUI() | |||
| { | |||
| @@ -144,7 +129,7 @@ class IldaeilUI : public UI, | |||
| kDrawingPluginGenericUI, | |||
| kDrawingErrorInit, | |||
| kDrawingErrorDraw | |||
| } fDrawingState; | |||
| } fDrawingState = kDrawingLoading; | |||
| enum { | |||
| kIdleInit, | |||
| @@ -161,46 +146,42 @@ class IldaeilUI : public UI, | |||
| kIdleNothing | |||
| } fIdleState = kIdleInit; | |||
| IldaeilBasePlugin* const fPlugin; | |||
| void* const fNativeWindowHandle; | |||
| PluginHostWindow fPluginHostWindow; | |||
| BinaryType fBinaryType; | |||
| PluginType fPluginType; | |||
| PluginType fNextPluginType; | |||
| uint fPluginId; | |||
| int fPluginSelected; | |||
| bool fPluginHasCustomUI; | |||
| bool fPluginHasEmbedUI; | |||
| bool fPluginHasFileOpen; | |||
| bool fPluginHasOutputParameters; | |||
| bool fPluginIsBridge; | |||
| bool fPluginIsIdling; | |||
| bool fPluginRunning; | |||
| bool fPluginWillRunInBridgeMode; | |||
| IldaeilBasePlugin* const fPlugin = static_cast<IldaeilBasePlugin*>(getPluginInstancePointer()); | |||
| void* const fNativeWindowHandle = reinterpret_cast<void*>(getWindow().getNativeWindowHandle()); | |||
| PluginHostWindow fPluginHostWindow { fNativeWindowHandle, this }; | |||
| BinaryType fBinaryType = BINARY_NATIVE; | |||
| PluginType fPluginType = PLUGIN_LV2; | |||
| PluginType fNextPluginType = fPluginType; | |||
| uint fPluginId = 0; | |||
| int fPluginSelected = -1; | |||
| bool fPluginHasCustomUI = false; | |||
| bool fPluginHasEmbedUI = false; | |||
| bool fPluginHasFileOpen = false; | |||
| bool fPluginHasOutputParameters = false; | |||
| bool fPluginIsBridge = false; | |||
| bool fPluginIsIdling = false; | |||
| bool fPluginRunning = false; | |||
| bool fPluginWillRunInBridgeMode = false; | |||
| Mutex fPluginsMutex; | |||
| PluginInfoCache fCurrentPluginInfo; | |||
| PluginInfoCache fCurrentPluginInfo{}; | |||
| std::vector<PluginInfoCache> fPlugins; | |||
| ScopedPointer<PluginGenericUI> fPluginGenericUI; | |||
| bool fPluginSearchActive; | |||
| bool fPluginSearchFirstShow; | |||
| char fPluginSearchString[0xff]; | |||
| bool fPluginSearchActive = false; | |||
| bool fPluginSearchFirstShow = false; | |||
| char fPluginSearchString[0xff] = {}; | |||
| String fPopupError, fPluginFilename, fDiscoveryTool; | |||
| Size<uint> fCurrentConstraintSize, fLastSize, fNextSize; | |||
| bool fIgnoreNextHostWindowResize; | |||
| bool fShowingHostWindow; | |||
| bool fUpdateGeometryConstraints; | |||
| bool fIgnoreNextHostWindowResize = false; | |||
| bool fShowingHostWindow = false; | |||
| bool fUpdateGeometryConstraints = false; | |||
| struct RunnerData { | |||
| bool needsReinit; | |||
| CarlaPluginDiscoveryHandle handle; | |||
| bool needsReinit = true; | |||
| CarlaPluginDiscoveryHandle handle = nullptr; | |||
| RunnerData() | |||
| : needsReinit(true), | |||
| handle(nullptr) {} | |||
| void init() | |||
| { | |||
| needsReinit = true; | |||
| @@ -216,32 +197,7 @@ class IldaeilUI : public UI, | |||
| public: | |||
| IldaeilUI() | |||
| : UI(kInitialWidth, kInitialHeight), | |||
| Runner("IldaeilScanner"), | |||
| fDrawingState(kDrawingLoading), | |||
| fIdleState(kIdleInit), | |||
| fPlugin((IldaeilBasePlugin*)getPluginInstancePointer()), | |||
| fNativeWindowHandle(reinterpret_cast<void*>(getWindow().getNativeWindowHandle())), | |||
| fPluginHostWindow(fNativeWindowHandle, this), | |||
| fBinaryType(BINARY_NATIVE), | |||
| fPluginType(PLUGIN_LV2), | |||
| fNextPluginType(fPluginType), | |||
| fPluginId(0), | |||
| fPluginSelected(-1), | |||
| fPluginHasCustomUI(false), | |||
| fPluginHasEmbedUI(false), | |||
| fPluginHasFileOpen(false), | |||
| fPluginHasOutputParameters(false), | |||
| fPluginIsBridge(false), | |||
| fPluginIsIdling(false), | |||
| fPluginRunning(false), | |||
| fPluginWillRunInBridgeMode(false), | |||
| fCurrentPluginInfo(), | |||
| fPluginSearchActive(false), | |||
| fPluginSearchFirstShow(false), | |||
| fIgnoreNextHostWindowResize(false), | |||
| fShowingHostWindow(false), | |||
| fUpdateGeometryConstraints(false), | |||
| fRunnerData() | |||
| Runner("IldaeilScanner") | |||
| { | |||
| const double scaleFactor = getScaleFactor(); | |||
| @@ -1062,7 +1018,7 @@ protected: | |||
| // save plugin info into cache | |||
| if (sha1sum != nullptr) | |||
| { | |||
| const water::String configDir(ildaeilConfigDir()); | |||
| const water::String configDir(getSpecialDir(kSpecialDirConfigForPlugin)); | |||
| const water::File cacheFile((configDir + CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR + sha1sum).toRawUTF8()); | |||
| if (cacheFile.create().ok()) | |||
| @@ -1095,13 +1051,17 @@ protected: | |||
| else | |||
| { | |||
| d_stderr("Failed to write cache file for %s%s%s", | |||
| ildaeilConfigDir(), CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, sha1sum); | |||
| getSpecialDir(kSpecialDirConfigForPlugin), | |||
| CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, | |||
| sha1sum); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| d_stderr("Failed to write cache file directories for %s%s%s", | |||
| ildaeilConfigDir(), CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, sha1sum); | |||
| getSpecialDir(kSpecialDirConfigForPlugin), | |||
| CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, | |||
| sha1sum); | |||
| } | |||
| } | |||
| @@ -1182,7 +1142,7 @@ protected: | |||
| if (sha1sum == nullptr) | |||
| return false; | |||
| const water::String configDir(ildaeilConfigDir()); | |||
| const water::String configDir(getSpecialDir(kSpecialDirConfigForPlugin)); | |||
| const water::File cacheFile((configDir + CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR + sha1sum).toRawUTF8()); | |||
| if (cacheFile.existsAsFile()) | |||
| @@ -1237,7 +1197,9 @@ protected: | |||
| else | |||
| { | |||
| d_stderr("Failed to read cache file for %s%s%s", | |||
| ildaeilConfigDir(), CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, sha1sum); | |||
| getSpecialDir(kSpecialDirConfigForPlugin), | |||
| CARLA_OS_SEP_STR "cache" CARLA_OS_SEP_STR, | |||
| sha1sum); | |||
| } | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Ildaeil Plugin | |||
| * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -54,82 +54,69 @@ struct PluginHostWindow::PrivateData | |||
| void* const windowHandle; | |||
| Callbacks* const pluginWindowCallbacks; | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| NSView* pluginView; | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| ::HWND pluginWindow; | |||
| #else | |||
| ::Display* display; | |||
| ::Window pluginWindow; | |||
| #endif | |||
| uint xOffset, yOffset; | |||
| bool brokenOffsetFactor; | |||
| bool lookingForChildren; | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| NSView* pluginView = nullptr; | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| ::HWND pluginWindow = nullptr; | |||
| #else | |||
| ::Display* display = XOpenDisplay(nullptr); | |||
| ::Window pluginWindow = 0; | |||
| #endif | |||
| uint xOffset = 0; | |||
| uint yOffset = 0; | |||
| bool brokenOffsetFactor = false; | |||
| bool lookingForChildren = false; | |||
| PrivateData(void* const wh, Callbacks* const cbs) | |||
| : windowHandle(wh), | |||
| pluginWindowCallbacks(cbs), | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| pluginView(nullptr), | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| pluginWindow(nullptr), | |||
| #else | |||
| display(nullptr), | |||
| pluginWindow(0), | |||
| #endif | |||
| xOffset(0), | |||
| yOffset(0), | |||
| brokenOffsetFactor(false), | |||
| lookingForChildren(false) | |||
| pluginWindowCallbacks(cbs) | |||
| { | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #else | |||
| display = XOpenDisplay(nullptr); | |||
| DISTRHO_SAFE_ASSERT_RETURN(display != nullptr,) | |||
| #endif | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #else | |||
| DISTRHO_SAFE_ASSERT_RETURN(display != nullptr,); | |||
| #endif | |||
| } | |||
| ~PrivateData() | |||
| { | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #else | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #else | |||
| if (display != nullptr) | |||
| XCloseDisplay(display); | |||
| #endif | |||
| #endif | |||
| } | |||
| void restart() | |||
| { | |||
| lookingForChildren = true; | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| pluginView = nullptr; | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| pluginWindow = nullptr; | |||
| #else | |||
| #else | |||
| pluginWindow = 0; | |||
| for (XEvent event; XPending(display) > 0;) | |||
| XNextEvent(display, &event); | |||
| #endif | |||
| #endif | |||
| } | |||
| bool hide() | |||
| { | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| if (pluginView != nullptr) | |||
| { | |||
| [pluginView setHidden:YES]; | |||
| @@ -137,15 +124,15 @@ struct PluginHostWindow::PrivateData | |||
| [NSOpenGLContext clearCurrentContext]; | |||
| return true; | |||
| } | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| if (pluginWindow != nullptr) | |||
| { | |||
| ShowWindow(pluginWindow, SW_HIDE); | |||
| pluginWindow = nullptr; | |||
| return true; | |||
| } | |||
| #else | |||
| #else | |||
| if (pluginWindow != 0) | |||
| { | |||
| XUnmapWindow(display, pluginWindow); | |||
| @@ -153,7 +140,7 @@ struct PluginHostWindow::PrivateData | |||
| pluginWindow = 0; | |||
| return true; | |||
| } | |||
| #endif | |||
| #endif | |||
| return false; | |||
| } | |||
| @@ -320,19 +307,19 @@ struct PluginHostWindow::PrivateData | |||
| void setSize(const uint width, const uint height) | |||
| { | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| #if defined(DISTRHO_OS_HAIKU) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| if (pluginView != nullptr) | |||
| [pluginView setFrameSize:NSMakeSize(width, height)]; | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| if (pluginWindow != nullptr) | |||
| SetWindowPos(pluginWindow, 0, 0, 0, width, height, | |||
| SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||
| #else | |||
| #else | |||
| if (pluginWindow != 0) | |||
| XResizeWindow(display, pluginWindow, width, height); | |||
| #endif | |||
| #endif | |||
| } | |||
| }; | |||