| @@ -1,221 +0,0 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2014 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. | |||
| */ | |||
| #ifndef DISTRHO_MUTEX_HPP_INCLUDED | |||
| #define DISTRHO_MUTEX_HPP_INCLUDED | |||
| #include "../DistrhoUtils.hpp" | |||
| #include <pthread.h> | |||
| // ----------------------------------------------------------------------- | |||
| // d_mutex class | |||
| class d_mutex | |||
| { | |||
| public: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| d_mutex() noexcept | |||
| { | |||
| pthread_mutex_init(&fMutex, nullptr); | |||
| } | |||
| /* | |||
| * Destructor. | |||
| */ | |||
| ~d_mutex() noexcept | |||
| { | |||
| pthread_mutex_destroy(&fMutex); | |||
| } | |||
| /* | |||
| * Lock the mutex. | |||
| */ | |||
| void lock() const noexcept | |||
| { | |||
| pthread_mutex_lock(&fMutex); | |||
| } | |||
| /* | |||
| * Try to lock the mutex. | |||
| * Returns true if successful. | |||
| */ | |||
| bool tryLock() const noexcept | |||
| { | |||
| return (pthread_mutex_trylock(&fMutex) == 0); | |||
| } | |||
| /* | |||
| * Unlock the mutex, optionally resetting the tryLock check. | |||
| */ | |||
| void unlock() const noexcept | |||
| { | |||
| pthread_mutex_unlock(&fMutex); | |||
| } | |||
| private: | |||
| mutable pthread_mutex_t fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_mutex) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // d_rmutex class | |||
| class d_rmutex | |||
| { | |||
| public: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| d_rmutex() noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| InitializeCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutexattr_t atts; | |||
| pthread_mutexattr_init(&atts); | |||
| pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE); | |||
| pthread_mutex_init(&fMutex, &atts); | |||
| pthread_mutexattr_destroy(&atts); | |||
| #endif | |||
| } | |||
| /* | |||
| * Destructor. | |||
| */ | |||
| ~d_rmutex() noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| DeleteCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_destroy(&fMutex); | |||
| #endif | |||
| } | |||
| /* | |||
| * Lock the mutex. | |||
| */ | |||
| void lock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| EnterCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_lock(&fMutex); | |||
| #endif | |||
| } | |||
| /* | |||
| * Try to lock the mutex. | |||
| * Returns true if successful. | |||
| */ | |||
| bool tryLock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| return (TryEnterCriticalSection(&fSection) != FALSE); | |||
| #else | |||
| return (pthread_mutex_trylock(&fMutex) == 0); | |||
| #endif | |||
| } | |||
| /* | |||
| * Unlock the mutex. | |||
| */ | |||
| void unlock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| LeaveCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_unlock(&fMutex); | |||
| #endif | |||
| } | |||
| private: | |||
| #ifdef DISTRHO_OS_WIN | |||
| mutable CRITICAL_SECTION fSection; | |||
| #else | |||
| mutable pthread_mutex_t fMutex; | |||
| #endif | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_rmutex) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to lock&unlock a mutex during a function scope. | |||
| template <class Mutex> | |||
| class d_scopeLocker | |||
| { | |||
| public: | |||
| d_scopeLocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| ~d_scopeLocker() noexcept | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| private: | |||
| const Mutex& fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_scopeLocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to unlock&lock a mutex during a function scope. | |||
| template <class Mutex> | |||
| class d_scopeUnlocker | |||
| { | |||
| public: | |||
| d_scopeUnlocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| ~d_scopeUnlocker() noexcept | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| private: | |||
| const Mutex& fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_scopeUnlocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Define types | |||
| typedef d_scopeLocker<d_mutex> d_mutexLocker; | |||
| typedef d_scopeLocker<d_rmutex> d_rmutexLocker; | |||
| typedef d_scopeUnlocker<d_mutex> d_mutexUnlocker; | |||
| typedef d_scopeUnlocker<d_rmutex> d_rmutexUnlocker; | |||
| // ----------------------------------------------------------------------- | |||
| #endif // DISTRHO_MUTEX_HPP_INCLUDED | |||
| @@ -106,13 +106,15 @@ void lv2_generate_ttl(const char* const basename) | |||
| manifestString += " ui:showInterface ;\n"; | |||
| # endif | |||
| manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; | |||
| manifestString += " ui:resize ,\n"; | |||
| manifestString += " ui:touch ;\n"; | |||
| manifestString += " lv2:requiredFeature ui:resize ,\n"; | |||
| # if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| manifestString += " <" LV2_DATA_ACCESS_URI "> ,\n"; | |||
| manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n"; | |||
| manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; | |||
| # endif | |||
| manifestString += " <" LV2_OPTIONS__options "> ,\n"; | |||
| # else | |||
| manifestString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | |||
| # endif | |||
| manifestString += " <" LV2_URID__map "> .\n"; | |||
| #endif | |||
| @@ -974,7 +974,8 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster) | |||
| effect->magic = kEffectMagic; | |||
| effect->uniqueID = plugin->getUniqueId(); | |||
| #ifdef VESTIGE_HEADER | |||
| *(int32_t*)&effect->unknown1 = plugin->getVersion(); | |||
| int32_t* const version = (int32_t*)&effect->unknown1; | |||
| *version = plugin->getVersion(); | |||
| #else | |||
| effect->version = plugin->getVersion(); | |||
| #endif | |||
| @@ -248,6 +248,11 @@ int osc_debug_handler(const char* path, const char*, lo_arg**, int, lo_message, | |||
| { | |||
| d_debug("osc_debug_handler(\"%s\")", path); | |||
| return 0; | |||
| #ifndef DEBUG | |||
| // unused | |||
| (void)path; | |||
| #endif | |||
| } | |||
| void osc_error_handler(int num, const char* msg, const char* path) | |||
| @@ -34,7 +34,9 @@ START_NAMESPACE_DISTRHO | |||
| class UiLv2 | |||
| { | |||
| public: | |||
| UiLv2(const intptr_t winId, const LV2_URID_Map* const uridMap, const LV2UI_Resize* const uiResz, const LV2UI_Touch* uiTouch, const LV2UI_Controller controller, const LV2UI_Write_Function writeFunc, void* const dspPtr) | |||
| UiLv2(const intptr_t winId, | |||
| const LV2_Options_Option* options, const LV2_URID_Map* const uridMap, const LV2UI_Resize* const uiResz, const LV2UI_Touch* uiTouch, | |||
| const LV2UI_Controller controller, const LV2UI_Write_Function writeFunc, void* const dspPtr) | |||
| : fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback, dspPtr), | |||
| fUridMap(uridMap), | |||
| fUiResize(uiResz), | |||
| @@ -45,12 +47,35 @@ public: | |||
| fKeyValueURID(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")), | |||
| fWinIdWasNull(winId == 0) | |||
| { | |||
| fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight()); | |||
| if (winId == 0) | |||
| fUI.setTitle(fUI.getName()); | |||
| else if (fUiResize != nullptr) | |||
| fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight()); | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| // tell the DSP we're ready to receive msgs | |||
| setState("__dpf_ui_data__", ""); | |||
| #endif | |||
| if (winId != 0) | |||
| return; | |||
| const LV2_URID uridFrontendWinId(uridMap->map(uridMap->handle, "http://kxstudio.sf.net/ns/carla/frontendWinId")); | |||
| for (int i=0; options[i].key != 0; ++i) | |||
| { | |||
| if (options[i].key == uridFrontendWinId) | |||
| { | |||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Long)) | |||
| { | |||
| if (const int64_t frontendWinId = *(const int64_t*)options[i].value) | |||
| fUI.setTransientWinId(static_cast<intptr_t>(frontendWinId)); | |||
| } | |||
| else | |||
| d_stderr("Host provides frontendWinId but has wrong value type"); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -171,7 +196,9 @@ protected: | |||
| void uiResize(const uint width, const uint height) | |||
| { | |||
| fUI.setSize(width, height); | |||
| fUiResize->ui_resize(fUiResize->handle, width, height); | |||
| if (fUiResize != nullptr && ! fWinIdWasNull) | |||
| fUiResize->ui_resize(fUiResize->handle, width, height); | |||
| } | |||
| private: | |||
| @@ -282,15 +309,9 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| return nullptr; | |||
| } | |||
| if (uiResize == nullptr) | |||
| { | |||
| d_stderr("UI Resize feature missing, cannot continue!"); | |||
| return nullptr; | |||
| } | |||
| if (parentId == nullptr) | |||
| { | |||
| d_stdout("Parent Window Id missing, host should use be ui:showInterface..."); | |||
| d_stdout("Parent Window Id missing, host should be using ui:showInterface..."); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| @@ -313,11 +334,13 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| *widget = parentId; | |||
| const intptr_t winId(*((intptr_t*)&parentId)); | |||
| const intptr_t winId((intptr_t)parentId); | |||
| const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_CORE__sampleRate)); | |||
| for (int i=0; options[i].key != 0; ++i) | |||
| { | |||
| if (options[i].key == uridMap->map(uridMap->handle, LV2_CORE__sampleRate)) | |||
| if (options[i].key == uridSampleRate) | |||
| { | |||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Double)) | |||
| d_lastUiSampleRate = *(const double*)options[i].value; | |||
| @@ -331,7 +354,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| if (d_lastUiSampleRate == 0.0) | |||
| d_lastUiSampleRate = 44100.0; | |||
| return new UiLv2(winId, uridMap, uiResize, uiTouch, controller, writeFunction, instance); | |||
| return new UiLv2(winId, options, uridMap, uiResize, uiTouch, controller, writeFunction, instance); | |||
| } | |||
| #define uiPtr ((UiLv2*)ui) | |||