DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 23692d024e57c617bd0692beb1835d48f98eb914
parent f80b1d66667dafa3f41a2332aa665e418f15a959
Author: falkTX <falktx@falktx.com>
Date:   Mon,  5 Sep 2022 11:53:52 +0100

Reorganize code and cleanup

Diffstat:
Mdistrho/src/DistrhoUILV2.cpp | 221+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mdistrho/src/DistrhoUIStub.cpp | 30+++++++++++++++---------------
Mdistrho/src/DistrhoUIVST3.cpp | 227++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
3 files changed, 256 insertions(+), 222 deletions(-)

diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp @@ -42,8 +42,11 @@ typedef struct _LV2_Atom_MidiEvent { uint8_t data[3]; /**< MIDI data (body). */ } LV2_Atom_MidiEvent; +#if ! DISTRHO_PLUGIN_WANT_STATE +static constexpr const setStateFunc setStateCallback = nullptr; +#endif #if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT -static const sendNoteFunc sendNoteCallback = nullptr; +static constexpr const sendNoteFunc sendNoteCallback = nullptr; #endif // ----------------------------------------------------------------------- @@ -76,19 +79,7 @@ public: const float scaleFactor, const uint32_t bgColor, const uint32_t fgColor) - : fUI(this, winId, sampleRate, - editParameterCallback, - setParameterCallback, - setStateCallback, - sendNoteCallback, - nullptr, // resize is very messy, hosts can do it without extensions - fileRequestCallback, - bundlePath, - dspPtr, - scaleFactor, - bgColor, - fgColor), - fUridMap(uridMap), + : fUridMap(uridMap), fUridUnmap(getLv2Feature<LV2_URID_Unmap>(features, LV2_URID__unmap)), fUiPortMap(getLv2Feature<LV2UI_Port_Map>(features, LV2_UI__portMap)), fUiRequestValue(getLv2Feature<LV2UI_Request_Value>(features, LV2_UI__requestValue)), @@ -98,15 +89,23 @@ public: fURIDs(uridMap), fBypassParameterIndex(fUiPortMap != nullptr ? fUiPortMap->port_index(fUiPortMap->handle, "lv2_enabled") : LV2UI_INVALID_PORT_INDEX), - fWinIdWasNull(winId == 0) + fWinIdWasNull(winId == 0), + fUI(this, winId, sampleRate, + editParameterCallback, + setParameterCallback, + setStateCallback, + sendNoteCallback, + nullptr, // resize is very messy, hosts can do it without extensions + fileRequestCallback, + bundlePath, dspPtr, scaleFactor, bgColor, fgColor) { if (widget != nullptr) *widget = (LV2UI_Widget)fUI.getNativeWindowHandle(); -#if DISTRHO_PLUGIN_WANT_STATE + #if DISTRHO_PLUGIN_WANT_STATE // tell the DSP we're ready to receive msgs setState("__dpf_ui_data__", ""); -#endif + #endif if (winId != 0) return; @@ -170,7 +169,7 @@ public: fUI.parameterChanged(rindex-parameterOffset, value); } -#if DISTRHO_PLUGIN_WANT_STATE + #if DISTRHO_PLUGIN_WANT_STATE else if (format == fURIDs.atomEventTransfer) { const LV2_Atom* const atom = (const LV2_Atom*)buffer; @@ -219,7 +218,7 @@ public: d_stdout("DPF :: received atom not handled"); } } -#endif + #endif } // ------------------------------------------------------------------- @@ -275,24 +274,91 @@ public: // ------------------------------------------------------------------- -#if DISTRHO_PLUGIN_WANT_PROGRAMS + #if DISTRHO_PLUGIN_WANT_PROGRAMS void lv2ui_select_program(const uint32_t bank, const uint32_t program) { const uint32_t realProgram = bank * 128 + program; fUI.programLoaded(realProgram); } -#endif + #endif // ------------------------------------------------------------------- -protected: +private: + // LV2 features + const LV2_URID_Map* const fUridMap; + const LV2_URID_Unmap* const fUridUnmap; + const LV2UI_Port_Map* const fUiPortMap; + const LV2UI_Request_Value* const fUiRequestValue; + const LV2UI_Touch* const fUiTouch; + + // LV2 UI stuff + const LV2UI_Controller fController; + const LV2UI_Write_Function fWriteFunction; + + // LV2 URIDs + const struct URIDs { + const LV2_URID_Map* _uridMap; + const LV2_URID dpfKeyValue; + const LV2_URID atomEventTransfer; + const LV2_URID atomFloat; + const LV2_URID atomLong; + const LV2_URID atomObject; + const LV2_URID atomPath; + const LV2_URID atomString; + const LV2_URID atomURID; + const LV2_URID midiEvent; + const LV2_URID paramSampleRate; + const LV2_URID patchProperty; + const LV2_URID patchSet; + const LV2_URID patchValue; + + URIDs(const LV2_URID_Map* const uridMap) + : _uridMap(uridMap), + dpfKeyValue(map(DISTRHO_PLUGIN_LV2_STATE_PREFIX "KeyValueState")), + atomEventTransfer(map(LV2_ATOM__eventTransfer)), + atomFloat(map(LV2_ATOM__Float)), + atomLong(map(LV2_ATOM__Long)), + atomObject(map(LV2_ATOM__Object)), + atomPath(map(LV2_ATOM__Path)), + atomString(map(LV2_ATOM__String)), + atomURID(map(LV2_ATOM__URID)), + midiEvent(map(LV2_MIDI__MidiEvent)), + paramSampleRate(map(LV2_PARAMETERS__sampleRate)), + patchProperty(map(LV2_PATCH__property)), + patchSet(map(LV2_PATCH__Set)), + patchValue(map(LV2_PATCH__value)) {} + + inline LV2_URID map(const char* const uri) const + { + return _uridMap->map(_uridMap->handle, uri); + } + } fURIDs; + + // index of bypass parameter, if present + const uint32_t fBypassParameterIndex; + + // using ui:showInterface if true + const bool fWinIdWasNull; + + // Plugin UI (after LV2 stuff so the UI can call into us during its constructor) + UIExporter fUI; + + // ---------------------------------------------------------------------------------------------------------------- + // DPF callbacks + void editParameterValue(const uint32_t rindex, const bool started) { if (fUiTouch != nullptr && fUiTouch->touch != nullptr) fUiTouch->touch(fUiTouch->handle, rindex, started); } + static void editParameterCallback(void* const ptr, const uint32_t rindex, const bool started) + { + static_cast<UiLv2*>(ptr)->editParameterValue(rindex, started); + } + void setParameterValue(const uint32_t rindex, float value) { DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,); @@ -303,6 +369,12 @@ protected: fWriteFunction(fController, rindex, sizeof(float), 0, &value); } + static void setParameterCallback(void* const ptr, const uint32_t rindex, const float value) + { + static_cast<UiLv2*>(ptr)->setParameterValue(rindex, value); + } + + #if DISTRHO_PLUGIN_WANT_STATE void setState(const char* const key, const char* const value) { DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,); @@ -342,7 +414,13 @@ protected: free(atomBuf); } -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT + static void setStateCallback(void* const ptr, const char* const key, const char* const value) + { + static_cast<UiLv2*>(ptr)->setState(key, value); + } + #endif + + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) { DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,); @@ -364,7 +442,12 @@ protected: fWriteFunction(fController, eventInPortIndex, lv2_atom_total_size(&atomMidiEvent.atom), fURIDs.atomEventTransfer, &atomMidiEvent); } -#endif + + static void sendNoteCallback(void* const ptr, const uint8_t channel, const uint8_t note, const uint8_t velocity) + { + static_cast<UiLv2*>(ptr)->sendNote(channel, note, velocity); + } + #endif bool fileRequest(const char* const key) { @@ -385,98 +468,10 @@ protected: return r == LV2UI_REQUEST_VALUE_SUCCESS; } -private: - UIExporter fUI; - - // LV2 features - const LV2_URID_Map* const fUridMap; - const LV2_URID_Unmap* const fUridUnmap; - const LV2UI_Port_Map* const fUiPortMap; - const LV2UI_Request_Value* const fUiRequestValue; - const LV2UI_Touch* const fUiTouch; - - // LV2 UI stuff - const LV2UI_Controller fController; - const LV2UI_Write_Function fWriteFunction; - - // LV2 URIDs - const struct URIDs { - const LV2_URID_Map* _uridMap; - const LV2_URID dpfKeyValue; - const LV2_URID atomEventTransfer; - const LV2_URID atomFloat; - const LV2_URID atomLong; - const LV2_URID atomObject; - const LV2_URID atomPath; - const LV2_URID atomString; - const LV2_URID atomURID; - const LV2_URID midiEvent; - const LV2_URID paramSampleRate; - const LV2_URID patchProperty; - const LV2_URID patchSet; - const LV2_URID patchValue; - - URIDs(const LV2_URID_Map* const uridMap) - : _uridMap(uridMap), - dpfKeyValue(map(DISTRHO_PLUGIN_LV2_STATE_PREFIX "KeyValueState")), - atomEventTransfer(map(LV2_ATOM__eventTransfer)), - atomFloat(map(LV2_ATOM__Float)), - atomLong(map(LV2_ATOM__Long)), - atomObject(map(LV2_ATOM__Object)), - atomPath(map(LV2_ATOM__Path)), - atomString(map(LV2_ATOM__String)), - atomURID(map(LV2_ATOM__URID)), - midiEvent(map(LV2_MIDI__MidiEvent)), - paramSampleRate(map(LV2_PARAMETERS__sampleRate)), - patchProperty(map(LV2_PATCH__property)), - patchSet(map(LV2_PATCH__Set)), - patchValue(map(LV2_PATCH__value)) {} - - inline LV2_URID map(const char* const uri) const - { - return _uridMap->map(_uridMap->handle, uri); - } - } fURIDs; - - // index of bypass parameter, if present - const uint32_t fBypassParameterIndex; - - // using ui:showInterface if true - const bool fWinIdWasNull; - - // ------------------------------------------------------------------- - // Callbacks - - #define uiPtr ((UiLv2*)ptr) - - static void editParameterCallback(void* ptr, uint32_t rindex, bool started) - { - uiPtr->editParameterValue(rindex, started); - } - - static void setParameterCallback(void* ptr, uint32_t rindex, float value) - { - uiPtr->setParameterValue(rindex, value); - } - - static void setStateCallback(void* ptr, const char* key, const char* value) - { - uiPtr->setState(key, value); - } - -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT - static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity) - { - uiPtr->sendNote(channel, note, velocity); - } -#endif - static bool fileRequestCallback(void* ptr, const char* key) { - return uiPtr->fileRequest(key); + return static_cast<UiLv2*>(ptr)->fileRequest(key); } - - #undef uiPtr }; // ----------------------------------------------------------------------- diff --git a/distrho/src/DistrhoUIStub.cpp b/distrho/src/DistrhoUIStub.cpp @@ -20,12 +20,12 @@ START_NAMESPACE_DISTRHO // -------------------------------------------------------------------------------------------------------------------- -#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT -static constexpr const sendNoteFunc sendNoteCallback = nullptr; -#endif #if ! DISTRHO_PLUGIN_WANT_STATE static constexpr const setStateFunc setStateCallback = nullptr; #endif +#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT +static constexpr const sendNoteFunc sendNoteCallback = nullptr; +#endif // -------------------------------------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ private: static void editParameterCallback(void* const ptr, const uint32_t rindex, const bool started) { - ((UIStub*)ptr)->editParameter(rindex, started); + static_cast<UIStub*>(ptr)->editParameter(rindex, started); } void setParameterValue(uint32_t, float) @@ -77,7 +77,7 @@ private: static void setParameterCallback(void* const ptr, const uint32_t rindex, const float value) { - ((UIStub*)ptr)->setParameterValue(rindex, value); + static_cast<UIStub*>(ptr)->setParameterValue(rindex, value); } void setSize(uint, uint) @@ -86,28 +86,28 @@ private: static void setSizeCallback(void* const ptr, const uint width, const uint height) { - ((UIStub*)ptr)->setSize(width, height); + static_cast<UIStub*>(ptr)->setSize(width, height); } - #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) + #if DISTRHO_PLUGIN_WANT_STATE + void setState(const char*, const char*) { } - static void sendNoteCallback(void* const ptr, const uint8_t channel, const uint8_t note, const uint8_t velocity) + static void setStateCallback(void* const ptr, const char* key, const char* value) { - ((UIStub*)ptr)->sendNote(channel, note, velocity); + static_cast<UIStub*>(ptr)->setState(key, value); } #endif - #if DISTRHO_PLUGIN_WANT_STATE - void setState(const char*, const char*) + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT + void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) { } - static void setStateCallback(void* const ptr, const char* key, const char* value) + static void sendNoteCallback(void* const ptr, const uint8_t channel, const uint8_t note, const uint8_t velocity) { - ((UIStub*)ptr)->setState(key, value); + static_cast<UIStub*>(ptr)->sendNote(channel, note, velocity); } #endif @@ -118,7 +118,7 @@ private: static bool fileRequestCallback(void* const ptr, const char* const key) { - return ((UIStub*)ptr)->fileRequest(key); + return static_cast<UIStub*>(ptr)->fileRequest(key); } }; diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp @@ -49,12 +49,12 @@ START_NAMESPACE_DISTRHO // -------------------------------------------------------------------------------------------------------------------- -#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT -static constexpr const sendNoteFunc sendNoteCallback = nullptr; -#endif #if ! DISTRHO_PLUGIN_WANT_STATE static constexpr const setStateFunc setStateCallback = nullptr; #endif +#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT +static constexpr const sendNoteFunc sendNoteCallback = nullptr; +#endif // -------------------------------------------------------------------------------------------------------------------- // Static data, see DistrhoPlugin.cpp @@ -133,35 +133,27 @@ static uint translateVST3Modifiers(const int64_t modifiers) noexcept // -------------------------------------------------------------------------------------------------------------------- +#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !DPF_VST3_USING_HOST_RUN_LOOP /** - * Helper class for getting a native idle timer, either through pugl or via native APIs. + * Helper class for getting a native idle timer via native APIs. */ -#if !DPF_VST3_USING_HOST_RUN_LOOP -class NativeIdleCallback : public IdleCallback +class NativeIdleHelper { public: - NativeIdleCallback(UIExporter& ui) - : fUI(ui), - fCallbackRegistered(false) - #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI - #if defined(DISTRHO_OS_MAC) - , fTimerRef(nullptr) - #elif defined(DISTRHO_OS_WINDOWS) - , fTimerWindow(nullptr) - , fTimerWindowClassName() - #endif - #endif + NativeIdleHelper(IdleCallback* const callback) + : fCallback(callback), + #ifdef DISTRHO_OS_MAC + fTimerRef(nullptr) + #else + fTimerWindow(nullptr), + fTimerWindowClassName() + #endif { } void registerNativeIdleCallback() { - DISTRHO_SAFE_ASSERT_RETURN(!fCallbackRegistered,); - fCallbackRegistered = true; - - #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI - fUI.addIdleCallbackForVST3(this, DPF_VST3_TIMER_INTERVAL); - #elif defined(DISTRHO_OS_MAC) + #ifdef DISTRHO_OS_MAC constexpr const CFTimeInterval interval = DPF_VST3_TIMER_INTERVAL * 0.0001; CFRunLoopTimerContext context = {}; @@ -171,12 +163,9 @@ public: DISTRHO_SAFE_ASSERT_RETURN(fTimerRef != nullptr,); CFRunLoopAddTimer(CFRunLoopGetCurrent(), fTimerRef, kCFRunLoopCommonModes); - #elif defined(DISTRHO_OS_WINDOWS) - /* We cannot assume anything about the native parent window passed as a parameter (winId) to the - * UIVst3 constructor because we do not own it. - * These parent windows have class names like 'reaperPluginHostWrapProc' and 'JUCE_nnnnnn'. - * - * Create invisible window to handle a timer instead. + #else + /* + * Create an invisible window to handle a timer. * There is no need for implementing a window proc because DefWindowProc already calls the * callback function when processing WM_TIMER messages. */ @@ -214,12 +203,10 @@ public: void unregisterNativeIdleCallback() { - #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI - fUI.removeIdleCallbackForVST3(this); - #elif defined(DISTRHO_OS_MAC) + #ifdef DISTRHO_OS_MAC CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), fTimerRef, kCFRunLoopCommonModes); CFRelease(fTimerRef); - #elif defined(DISTRHO_OS_WINDOWS) + #else DISTRHO_SAFE_ASSERT_RETURN(fTimerWindow != nullptr,); KillTimer(fTimerWindow, DPF_VST3_WIN32_TIMER_ID); DestroyWindow(fTimerWindow); @@ -228,27 +215,79 @@ public: } private: - UIExporter& fUI; - bool fCallbackRegistered; + IdleCallback* const fCallback; - #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI - #if defined(DISTRHO_OS_MAC) + #ifdef DISTRHO_OS_MAC CFRunLoopTimerRef fTimerRef; static void platformIdleTimerCallback(CFRunLoopTimerRef, void* const info) { - static_cast<NativeIdleCallback*>(info)->idleCallback(); + static_cast<NativeIdleHelper*>(info)->fCallback->idleCallback(); } - #elif defined(DISTRHO_OS_WINDOWS) + #else HWND fTimerWindow; String fTimerWindowClassName; WINAPI static void platformIdleTimerCallback(const HWND hwnd, UINT, UINT_PTR, DWORD) { - reinterpret_cast<NativeIdleCallback*>(GetWindowLongPtr(hwnd, GWLP_USERDATA))->idleCallback(); + reinterpret_cast<NativeIdleHelper*>(GetWindowLongPtr(hwnd, GWLP_USERDATA))->fCallback->idleCallback(); } #endif - #endif +}; +#endif + +/** + * Helper class for getting a native idle timer, either through pugl or via native APIs. + */ +#if !DPF_VST3_USING_HOST_RUN_LOOP +class NativeIdleCallback : public IdleCallback +{ +public: + NativeIdleCallback(UIExporter& ui) + : fCallbackRegistered(false), + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI + fIdleHelper(this) + #else + fUI(ui) + #endif + { + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI + // unused + (void)ui; + #endif + } + + void registerNativeIdleCallback() + { + DISTRHO_SAFE_ASSERT_RETURN(!fCallbackRegistered,); + fCallbackRegistered = true; + + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI + fIdleHelper.registerNativeIdleCallback(); + #else + fUI.addIdleCallbackForVST3(this, DPF_VST3_TIMER_INTERVAL); + #endif + } + + void unregisterNativeIdleCallback() + { + DISTRHO_SAFE_ASSERT_RETURN(fCallbackRegistered,); + fCallbackRegistered = false; + + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI + fIdleHelper.unregisterNativeIdleCallback(); + #else + fUI.removeIdleCallbackForVST3(this); + #endif + } + +private: + bool fCallbackRegistered; + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI + NativeIdleHelper fIdleHelper; + #else + UIExporter& fUI; + #endif }; #endif @@ -759,7 +798,7 @@ private: static void editParameterCallback(void* const ptr, const uint32_t rindex, const bool started) { - ((UIVst3*)ptr)->editParameter(rindex, started); + static_cast<UIVst3*>(ptr)->editParameter(rindex, started); } void setParameterValue(const uint32_t rindex, const float realValue) @@ -782,51 +821,35 @@ private: static void setParameterCallback(void* const ptr, const uint32_t rindex, const float value) { - ((UIVst3*)ptr)->setParameterValue(rindex, value); + static_cast<UIVst3*>(ptr)->setParameterValue(rindex, value); } - void setSize(uint width, uint height) + #if DISTRHO_PLUGIN_WANT_STATE + void setState(const char* const key, const char* const value) { - DISTRHO_SAFE_ASSERT_RETURN(fView != nullptr,); - DISTRHO_SAFE_ASSERT_RETURN(fFrame != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(fConnection != nullptr,); - #ifdef DISTRHO_OS_MAC - const double scaleFactor = fUI.getScaleFactor(); - width /= scaleFactor; - height /= scaleFactor; - #endif + v3_message** const message = createMessage("state-set"); + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr,); - if (fIsResizingFromHost) - { - if (fNeedsResizeFromPlugin) - { - d_debug("plugin->host setSize %u %u (FORCED, exception for first resize)", width, height); - } - else - { - d_debug("plugin->host setSize %u %u (IGNORED, host resize active)", width, height); - return; - } - } - else - { - d_debug("plugin->host setSize %u %u (OK)", width, height); - } + v3_attribute_list** const attrlist = v3_cpp_obj(message)->get_attributes(message); + DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,); - fIsResizingFromPlugin = true; + v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1); + v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); + v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); + v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); + v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); + v3_cpp_obj(fConnection)->notify(fConnection, message); - v3_view_rect rect; - rect.left = rect.top = 0; - rect.right = width; - rect.bottom = height; - fNextPluginRect = rect; - v3_cpp_obj(fFrame)->resize_view(fFrame, fView, &rect); + v3_cpp_obj_unref(message); } - static void setSizeCallback(void* const ptr, const uint width, const uint height) + static void setStateCallback(void* const ptr, const char* const key, const char* const value) { - ((UIVst3*)ptr)->setSize(width, height); + static_cast<UIVst3*>(ptr)->setState(key, value); } + #endif #if DISTRHO_PLUGIN_WANT_MIDI_INPUT void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) @@ -853,36 +876,52 @@ private: static void sendNoteCallback(void* const ptr, const uint8_t channel, const uint8_t note, const uint8_t velocity) { - ((UIVst3*)ptr)->sendNote(channel, note, velocity); + static_cast<UIVst3*>(ptr)->sendNote(channel, note, velocity); } #endif - #if DISTRHO_PLUGIN_WANT_STATE - void setState(const char* const key, const char* const value) + void setSize(uint width, uint height) { - DISTRHO_SAFE_ASSERT_RETURN(fConnection != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(fView != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(fFrame != nullptr,); - v3_message** const message = createMessage("state-set"); - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr,); + #ifdef DISTRHO_OS_MAC + const double scaleFactor = fUI.getScaleFactor(); + width /= scaleFactor; + height /= scaleFactor; + #endif - v3_attribute_list** const attrlist = v3_cpp_obj(message)->get_attributes(message); - DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,); + if (fIsResizingFromHost) + { + if (fNeedsResizeFromPlugin) + { + d_debug("plugin->host setSize %u %u (FORCED, exception for first resize)", width, height); + } + else + { + d_debug("plugin->host setSize %u %u (IGNORED, host resize active)", width, height); + return; + } + } + else + { + d_debug("plugin->host setSize %u %u (OK)", width, height); + } - v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1); - v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); - v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); - v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); - v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); - v3_cpp_obj(fConnection)->notify(fConnection, message); + fIsResizingFromPlugin = true; - v3_cpp_obj_unref(message); + v3_view_rect rect; + rect.left = rect.top = 0; + rect.right = width; + rect.bottom = height; + fNextPluginRect = rect; + v3_cpp_obj(fFrame)->resize_view(fFrame, fView, &rect); } - static void setStateCallback(void* const ptr, const char* const key, const char* const value) + static void setSizeCallback(void* const ptr, const uint width, const uint height) { - ((UIVst3*)ptr)->setState(key, value); + static_cast<UIVst3*>(ptr)->setSize(width, height); } - #endif }; // --------------------------------------------------------------------------------------------------------------------