| @@ -28,6 +28,7 @@ OBJS = \ | |||
| $(OBJDIR)/ImageWidgets.cpp.o \ | |||
| $(OBJDIR)/NanoVG.cpp.o \ | |||
| $(OBJDIR)/NanoWidgets.cpp.o \ | |||
| $(OBJDIR)/Resources.cpp.o \ | |||
| $(OBJDIR)/Widget.cpp.o | |||
| ifeq ($(MACOS),true) | |||
| @@ -20,6 +20,8 @@ | |||
| #include "Color.hpp" | |||
| #include "Widget.hpp" | |||
| #define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__" | |||
| struct NVGcontext; | |||
| struct NVGpaint; | |||
| @@ -28,6 +30,7 @@ START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // Forward class names | |||
| class BlendishWidget; | |||
| class NanoVG; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -841,10 +844,16 @@ public: | |||
| */ | |||
| int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows); | |||
| /** | |||
| Load DPF's internal shared resources for this NanoVG class. | |||
| */ | |||
| virtual void loadSharedResources(); | |||
| private: | |||
| NVGcontext* const fContext; | |||
| bool fInFrame; | |||
| bool fIsSubWidget; | |||
| friend class BlendishWidget; | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoVG) | |||
| }; | |||
| @@ -18,13 +18,23 @@ | |||
| #define DGL_NANO_WIDGETS_HPP_INCLUDED | |||
| #include "NanoVG.hpp" | |||
| #include "../distrho/extra/String.hpp" | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| class BlendishButton : public NanoWidget | |||
| class BlendishWidget : public NanoWidget | |||
| { | |||
| public: | |||
| explicit BlendishWidget(Window& parent); | |||
| explicit BlendishWidget(NanoWidget* widget); | |||
| void loadSharedResources() override; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| class BlendishButton : public BlendishWidget | |||
| { | |||
| public: | |||
| class Callback | |||
| @@ -14,7 +14,6 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "../ImageWidgets.hpp" | |||
| #include "Common.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| @@ -15,6 +15,7 @@ | |||
| */ | |||
| #include "../NanoVG.hpp" | |||
| #include "Resources.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| // ----------------------------------------------------------------------- | |||
| @@ -894,6 +895,16 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi | |||
| return 0; | |||
| } | |||
| void NanoVG::loadSharedResources() | |||
| { | |||
| if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) | |||
| return; | |||
| using namespace dpf_resources; | |||
| nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| struct NanoWidget::PrivateData { | |||
| @@ -932,6 +943,7 @@ NanoWidget::NanoWidget(NanoWidget* groupWidget) | |||
| nData(new PrivateData(this)) | |||
| { | |||
| pData->needsScaling = true; | |||
| pData->skipDisplay = true; | |||
| groupWidget->nData->subWidgets.push_back(this); | |||
| } | |||
| @@ -14,27 +14,39 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "../NanoWidgets.hpp" | |||
| #include "Common.hpp" | |||
| #include "Resources.hpp" | |||
| #define BLENDISH_IMPLEMENTATION | |||
| #include "nanovg/nanovg.h" | |||
| #include "oui-blendish/blendish.h" | |||
| #include "oui-blendish/blendish_resources.h" | |||
| #include "../distrho/extra/String.hpp" | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| static void registerBlendishResourcesIfNeeded(NVGcontext* const context) | |||
| BlendishWidget::BlendishWidget(Window& parent) | |||
| : NanoWidget(parent) | |||
| { | |||
| if (nvgFindFont(context, "__dpf_blendish__") >= 0) | |||
| loadSharedResources(); | |||
| } | |||
| BlendishWidget::BlendishWidget(NanoWidget* widget) | |||
| : NanoWidget(widget) | |||
| { | |||
| loadSharedResources(); | |||
| } | |||
| void BlendishWidget::loadSharedResources() | |||
| { | |||
| if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) | |||
| return; | |||
| using namespace blendish_resources; | |||
| using namespace dpf_resources; | |||
| bndSetFont(nvgCreateFontMem(context, "__dpf_blendish__", (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0)); | |||
| bndSetIconImage(nvgCreateImageMem(context, 0, (const uchar*)blender_icons16_png, blender_icons16_png_size)); | |||
| bndSetFont(nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0)); | |||
| bndSetIconImage(nvgCreateImageMem(fContext, 0, (const uchar*)blender_icons16_png, blender_icons16_png_size)); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -55,18 +67,16 @@ struct BlendishButton::PrivateData { | |||
| // ----------------------------------------------------------------------- | |||
| BlendishButton::BlendishButton(Window& parent, const char* text, int iconId) | |||
| : NanoWidget(parent), | |||
| : BlendishWidget(parent), | |||
| pData(new PrivateData(this, text, iconId)) | |||
| { | |||
| registerBlendishResourcesIfNeeded(getContext()); | |||
| _updateBounds(); | |||
| } | |||
| BlendishButton::BlendishButton(NanoWidget* widget, const char* text, int iconId) | |||
| : NanoWidget(widget), | |||
| : BlendishWidget(widget), | |||
| pData(new PrivateData(this, text, iconId)) | |||
| { | |||
| registerBlendishResourcesIfNeeded(getContext()); | |||
| _updateBounds(); | |||
| } | |||
| @@ -139,6 +149,4 @@ void BlendishButton::_updateBounds() | |||
| END_NAMESPACE_DGL | |||
| #include "oui-blendish/blendish_resources.cpp" | |||
| // ----------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* (Auto-generated binary data file). */ | |||
| #include "blendish_resources.h" | |||
| #include "Resources.hpp" | |||
| static const unsigned char temp1[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,90,0,0,2,128,8,6,0,0,0,68,254,214,163,0,0,0,4,115,66,73, | |||
| 84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111, | |||
| @@ -6270,7 +6270,7 @@ static const unsigned char temp1[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68 | |||
| 14,240,213,53,106,138,246,238,200,233,43,254,186,60,190,184,78,245,113,54,182,190,78,234,217,40,212,199,217,216,118,255,160,56,225,219,107,228,147,123, | |||
| 169,14,167,207,238,165,186,199,187,107,215,174,20,95,114,250,210,58,138,123,235,217,232,235,84,31,167,143,44,80,117,235,217,40,212,199,233,139,103,72, | |||
| 83,241,254,149,240,127,22,93,33,203,89,128,128,45,0,0,0,0,73,69,78,68,174,66,96,130,0,0}; | |||
| const char* blendish_resources::blender_icons16_png = (const char*) temp1; | |||
| const char* dpf_resources::blender_icons16_png = (const char*) temp1; | |||
| static const unsigned char temp2[] = {0,1,0,0,0,19,1,0,0,4,0,48,70,70,84,77,102,9,29,176,0,0,1,60,0,0,0,28,71,68,69,70,144,48,138,184,0,0,1,88, | |||
| 0,0,2,148,71,80,79,83,63,137,191,2,0,0,3,236,0,0,157,8,71,83,85,66,151,65,114,65,0,0,160,244,0,0,21,114,79,83,47,50, | |||
| @@ -24811,5 +24811,5 @@ static const unsigned char temp2[] = {0,1,0,0,0,19,1,0,0,4,0,48,70,70,84,77,102, | |||
| 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, | |||
| 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, | |||
| 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,29,0,0}; | |||
| const char* blendish_resources::dejavusans_ttf = (const char*) temp2; | |||
| const char* dpf_resources::dejavusans_ttf = (const char*) temp2; | |||
| @@ -1,9 +1,9 @@ | |||
| /* (Auto-generated binary data file). */ | |||
| #ifndef BINARY_BLENDISH_RESOURCES_H | |||
| #define BINARY_BLENDISH_RESOURCES_H | |||
| #ifndef BINARY_DPF_RESOURCES_HPP_INCLUDED | |||
| #define BINARY_DPF_RESOURCES_HPP_INCLUDED | |||
| namespace blendish_resources | |||
| namespace dpf_resources | |||
| { | |||
| extern const char* blender_icons16_png; | |||
| const unsigned int blender_icons16_png_size = 250706; | |||
| @@ -51,7 +51,10 @@ struct Widget::PrivateData { | |||
| visible(true) | |||
| { | |||
| if (addToSubWidgets && groupWidget != nullptr) | |||
| { | |||
| skipDisplay = true; | |||
| groupWidget->pData->subWidgets.push_back(self); | |||
| } | |||
| } | |||
| ~PrivateData() | |||
| @@ -87,9 +87,12 @@ void | |||
| puglLeaveContext(PuglView* view, bool flush) | |||
| { | |||
| #ifdef PUGL_HAVE_GL | |||
| if (view->ctx_type == PUGL_GL && flush) { | |||
| glFlush(); | |||
| SwapBuffers(view->impl->hdc); | |||
| if (view->ctx_type == PUGL_GL) { | |||
| if (flush) { | |||
| glFlush(); | |||
| SwapBuffers(view->impl->hdc); | |||
| } | |||
| wglMakeCurrent(NULL, NULL); | |||
| } | |||
| #endif | |||
| } | |||
| @@ -218,11 +218,14 @@ void | |||
| puglLeaveContext(PuglView* view, bool flush) | |||
| { | |||
| #ifdef PUGL_HAVE_GL | |||
| if (view->ctx_type == PUGL_GL && flush) { | |||
| glFlush(); | |||
| if (view->impl->doubleBuffered) { | |||
| glXSwapBuffers(view->impl->display, view->impl->win); | |||
| if (view->ctx_type == PUGL_GL) { | |||
| if (flush) { | |||
| glFlush(); | |||
| if (view->impl->doubleBuffered) { | |||
| glXSwapBuffers(view->impl->display, view->impl->win); | |||
| } | |||
| } | |||
| glXMakeCurrent(view->impl->display, None, NULL); | |||
| } | |||
| #endif | |||
| } | |||
| @@ -549,26 +549,39 @@ protected: | |||
| */ | |||
| virtual const char* getLabel() const = 0; | |||
| /** | |||
| Get an extensive comment/description about the plugin.@n | |||
| Optional, returns nothing by default. | |||
| */ | |||
| virtual const char* getDescription() const { return ""; } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| virtual const char* getMaker() const = 0; | |||
| /** | |||
| Get the plugin license name (a single line of text).@n | |||
| Get the plugin homepage.@n | |||
| Optional, returns nothing by default. | |||
| */ | |||
| virtual const char* getHomePage() const { return ""; } | |||
| /** | |||
| Get the plugin license (a single line of text or a URL).@n | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| virtual const char* getLicense() const = 0; | |||
| /** | |||
| Get the plugin version, in hexadecimal.@n | |||
| TODO format to be defined | |||
| Get the plugin version, in hexadecimal. | |||
| @see d_version() | |||
| */ | |||
| virtual uint32_t getVersion() const = 0; | |||
| /** | |||
| Get the plugin unique Id.@n | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| @see d_cconst() | |||
| */ | |||
| virtual int64_t getUniqueId() const = 0; | |||
| @@ -631,6 +644,16 @@ protected: | |||
| virtual void loadProgram(uint32_t index) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| /** | |||
| Get the value of an internal state.@n | |||
| The host may call this function from any non-realtime context.@n | |||
| Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_PROGRAMS or DISTRHO_PLUGIN_WANT_FULL_STATE is enabled. | |||
| @note The use of this function breaks compatibility with the DSSI format. | |||
| */ | |||
| virtual String getState(const char* key) const = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| /** | |||
| Change an internal state @a key to @a value.@n | |||
| @@ -33,7 +33,7 @@ | |||
| # include <stdint.h> | |||
| #endif | |||
| #if 0 // defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) | |||
| #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) | |||
| namespace std { | |||
| inline float fmin(float __x, float __y) | |||
| { return __builtin_fminf(__x, __y); } | |||
| @@ -62,6 +62,15 @@ int64_t d_cconst(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_ | |||
| return (a << 24) | (b << 16) | (c << 8) | (d << 0); | |||
| } | |||
| /* | |||
| * Return an hexadecimal representation of a MAJ.MIN.MICRO version number. | |||
| */ | |||
| static inline | |||
| uint32_t d_version(const uint8_t major, const uint8_t minor, const uint8_t micro) noexcept | |||
| { | |||
| return (major << 16) | (minor << 8) | (micro << 0); | |||
| } | |||
| /* | |||
| * Dummy function. | |||
| */ | |||
| @@ -73,6 +73,10 @@ | |||
| # define DISTRHO_PLUGIN_WANT_STATE 0 | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| # define DISTRHO_PLUGIN_WANT_FULL_STATE 0 | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_TIMEPOS | |||
| # define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
| #endif | |||
| @@ -104,6 +108,22 @@ | |||
| # error Synths need MIDI input to work! | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // Enable full state if plugin exports presets | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE | |||
| # undef DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| # define DISTRHO_PLUGIN_WANT_FULL_STATE 1 | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // Disable UI if DGL is not available | |||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||
| # undef DISTRHO_PLUGIN_HAS_UI | |||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| #endif // DISTRHO_PLUGIN_CHECKS_H_INCLUDED | |||
| @@ -196,6 +196,13 @@ public: | |||
| return fPlugin->getLabel(); | |||
| } | |||
| const char* getDescription() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); | |||
| return fPlugin->getDescription(); | |||
| } | |||
| const char* getMaker() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); | |||
| @@ -203,6 +210,13 @@ public: | |||
| return fPlugin->getMaker(); | |||
| } | |||
| const char* getHomePage() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); | |||
| return fPlugin->getHomePage(); | |||
| } | |||
| const char* getLicense() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, ""); | |||
| @@ -371,6 +385,16 @@ public: | |||
| return fData->stateDefValues[index]; | |||
| } | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| String getState(const char* key) const | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackString); | |||
| DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', sFallbackString); | |||
| return fPlugin->getState(key); | |||
| } | |||
| # endif | |||
| void setState(const char* const key, const char* const value) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); | |||
| @@ -40,6 +40,10 @@ | |||
| # error DISTRHO_PLUGIN_URI undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_LV2_STATE_PREFIX | |||
| # define DISTRHO_PLUGIN_LV2_STATE_PREFIX "urn:distrho:" | |||
| #endif | |||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | |||
| #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | |||
| @@ -739,6 +743,15 @@ public: | |||
| if (fPortControls[i] != nullptr) | |||
| *fPortControls[i] = fLastControlValues[i]; | |||
| } | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| // Update state | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| fStateMap[key] = fPlugin.getState(key); | |||
| } | |||
| # endif | |||
| } | |||
| #endif | |||
| @@ -747,12 +760,21 @@ public: | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle) | |||
| { | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| // Update current state | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| fStateMap[key] = fPlugin.getState(key); | |||
| } | |||
| # endif | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| const String& value = cit->second; | |||
| const String urnKey("urn:distrho:" + key); | |||
| const String urnKey(DISTRHO_PLUGIN_LV2_STATE_PREFIX + key); | |||
| // some hosts need +1 for the null terminator, even though the type is string | |||
| store(handle, fUridMap->map(fUridMap->handle, urnKey.buffer()), value.buffer(), value.length()+1, fURIDs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); | |||
| @@ -769,7 +791,7 @@ public: | |||
| for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) | |||
| { | |||
| const String& key(fPlugin.getStateKey(i)); | |||
| const String urnKey("urn:distrho:" + key); | |||
| const String urnKey(DISTRHO_PLUGIN_LV2_STATE_PREFIX + key); | |||
| size = 0; | |||
| type = 0; | |||
| @@ -909,7 +931,7 @@ private: | |||
| atomLong(uridMap->map(uridMap->handle, LV2_ATOM__Long)), | |||
| atomSequence(uridMap->map(uridMap->handle, LV2_ATOM__Sequence)), | |||
| atomString(uridMap->map(uridMap->handle, LV2_ATOM__String)), | |||
| distrhoState(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")), | |||
| distrhoState(uridMap->map(uridMap->handle, DISTRHO_PLUGIN_LV2_STATE_PREFIX "KeyValueState")), | |||
| midiEvent(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)), | |||
| timePosition(uridMap->map(uridMap->handle, LV2_TIME__Position)), | |||
| timeBar(uridMap->map(uridMap->handle, LV2_TIME__bar)), | |||
| @@ -1161,15 +1183,13 @@ static const void* lv2_extension_data(const char* uri) | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| # define DISTRHO_DIRECT_ACCESS_URI "urn:distrho:direct-access" | |||
| struct LV2_DirectAccess_Interface { | |||
| void* (*get_instance_pointer)(LV2_Handle handle); | |||
| }; | |||
| static const LV2_DirectAccess_Interface directaccess = { lv2_get_instance_pointer }; | |||
| if (std::strcmp(uri, DISTRHO_DIRECT_ACCESS_URI) == 0) | |||
| if (std::strcmp(uri, DISTRHO_PLUGIN_LV2_STATE_PREFIX "direct-access") == 0) | |||
| return &directaccess; | |||
| #endif | |||
| @@ -45,6 +45,10 @@ | |||
| # define DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE 2048 | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_USES_MODGUI | |||
| # define DISTRHO_PLUGIN_USES_MODGUI 0 | |||
| #endif | |||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||
| # undef DISTRHO_PLUGIN_HAS_UI | |||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||
| @@ -111,7 +115,12 @@ void lv2_generate_ttl(const char* const basename) | |||
| manifestString += "<" DISTRHO_PLUGIN_URI ">\n"; | |||
| manifestString += " a lv2:Plugin ;\n"; | |||
| manifestString += " lv2:binary <" + pluginDLL + "." DISTRHO_DLL_EXTENSION "> ;\n"; | |||
| #if DISTRHO_PLUGIN_USES_MODGUI | |||
| manifestString += " rdfs:seeAlso <" + pluginTTL + "> ,\n"; | |||
| manifestString += " <modgui.ttl> .\n"; | |||
| #else | |||
| manifestString += " rdfs:seeAlso <" + pluginTTL + "> .\n"; | |||
| #endif | |||
| manifestString += "\n"; | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| @@ -148,16 +157,21 @@ void lv2_generate_ttl(const char* const basename) | |||
| char strBuf[0xff+1]; | |||
| strBuf[0xff] = '\0'; | |||
| String presetString; | |||
| // Presets | |||
| for (uint32_t i = 0; i < plugin.getProgramCount(); ++i) | |||
| { | |||
| std::snprintf(strBuf, 0xff, "%03i", i+1); | |||
| manifestString += "<" DISTRHO_PLUGIN_URI + presetSeparator + "preset" + strBuf + ">\n"; | |||
| manifestString += " a pset:Preset ;\n"; | |||
| manifestString += " lv2:appliesTo <" DISTRHO_PLUGIN_URI "> ;\n"; | |||
| manifestString += " rdfs:seeAlso <presets.ttl> .\n"; | |||
| manifestString += "\n"; | |||
| presetString = "<" DISTRHO_PLUGIN_URI + presetSeparator + "preset" + strBuf + ">\n"; | |||
| presetString += " a pset:Preset ;\n"; | |||
| presetString += " lv2:appliesTo <" DISTRHO_PLUGIN_URI "> ;\n"; | |||
| presetString += " rdfs:label \"" + plugin.getProgramName(i) + "\" ;\n"; | |||
| presetString += " rdfs:seeAlso <presets.ttl> .\n"; | |||
| presetString += "\n"; | |||
| manifestString += presetString; | |||
| } | |||
| #endif | |||
| @@ -181,6 +195,10 @@ void lv2_generate_ttl(const char* const basename) | |||
| pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; | |||
| pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; | |||
| pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||
| #ifdef DISTRHO_PLUGIN_BRAND | |||
| pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n"; | |||
| #endif | |||
| pluginString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||
| pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||
| @@ -252,7 +270,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| pluginString += " a lv2:InputPort, lv2:AudioPort ;\n"; | |||
| pluginString += " lv2:index " + String(portIndex) + " ;\n"; | |||
| pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n"; | |||
| pluginString += " lv2:symbol \"lv2_" + port.symbol + "\" ;\n"; | |||
| pluginString += " lv2:name \"" + port.name + "\" ;\n"; | |||
| if (port.hints & kAudioPortIsSidechain) | |||
| @@ -282,7 +300,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n"; | |||
| pluginString += " lv2:index " + String(portIndex) + " ;\n"; | |||
| pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n"; | |||
| pluginString += " lv2:symbol \"lv2_" + port.symbol + "\" ;\n"; | |||
| pluginString += " lv2:name \"" + port.name + "\" ;\n"; | |||
| if (port.hints & kAudioPortIsSidechain) | |||
| @@ -412,6 +430,14 @@ void lv2_generate_ttl(const char* const basename) | |||
| { | |||
| pluginString += " unit:unit unit:mhz ;\n"; | |||
| } | |||
| else if (unit == "ms") | |||
| { | |||
| pluginString += " unit:unit unit:ms ;\n"; | |||
| } | |||
| else if (unit == "s") | |||
| { | |||
| pluginString += " unit:unit unit:s ;\n"; | |||
| } | |||
| else if (unit == "%") | |||
| { | |||
| pluginString += " unit:unit unit:pc ;\n"; | |||
| @@ -419,8 +445,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| else | |||
| { | |||
| pluginString += " unit:unit [\n"; | |||
| pluginString += " a unit:Unit ;\n"; | |||
| pluginString += " unit:name \"" + unit + "\" ;\n"; | |||
| pluginString += " rdfs:label \"" + unit + "\" ;\n"; | |||
| pluginString += " unit:symbol \"" + unit + "\" ;\n"; | |||
| pluginString += " unit:render \"%f " + unit + "\" ;\n"; | |||
| pluginString += " ] ;\n"; | |||
| @@ -452,8 +477,60 @@ void lv2_generate_ttl(const char* const basename) | |||
| } | |||
| } | |||
| // comment | |||
| { | |||
| const String comment(plugin.getDescription()); | |||
| if (comment.isNotEmpty()) | |||
| pluginString += " rdfs:comment \"\"\"\n" + comment + "\n\"\"\" ;\n\n"; | |||
| } | |||
| #ifdef DISTRHO_PLUGIN_BRAND | |||
| // MOD | |||
| pluginString += " mod:brand \"" DISTRHO_PLUGIN_BRAND "\" ;\n"; | |||
| pluginString += " mod:label \"" DISTRHO_PLUGIN_NAME "\" ;\n\n"; | |||
| #endif | |||
| // name | |||
| pluginString += " doap:name \"" + String(plugin.getName()) + "\" ;\n"; | |||
| pluginString += " doap:maintainer [ foaf:name \"" + String(plugin.getMaker()) + "\" ] .\n"; | |||
| // license | |||
| { | |||
| const String license(plugin.getLicense()); | |||
| if (license.contains("://")) | |||
| pluginString += " doap:license <" + license + "> ;\n\n"; | |||
| else | |||
| pluginString += " doap:license \"" + license + "\" ;\n\n"; | |||
| } | |||
| // developer | |||
| { | |||
| const String homepage(plugin.getHomePage()); | |||
| pluginString += " doap:maintainer [\n"; | |||
| pluginString += " foaf:name \"" + String(plugin.getMaker()) + "\" ;\n"; | |||
| if (homepage.isNotEmpty()) | |||
| pluginString += " foaf:homepage <" + homepage + "> ;\n"; | |||
| pluginString += " ] ;\n\n"; | |||
| } | |||
| { | |||
| const uint32_t version(plugin.getVersion()); | |||
| const uint32_t majorVersion = (version & 0xFF0000) >> 16; | |||
| const uint32_t microVersion = (version & 0x00FF00) >> 8; | |||
| /* */ uint32_t minorVersion = (version & 0x0000FF) >> 0; | |||
| // NOTE: LV2 ignores 'major' version and says 0 for minor is pre-release/unstable. | |||
| if (majorVersion > 0) | |||
| minorVersion += 2; | |||
| pluginString += " lv2:microVersion " + String(microVersion) + " ;\n"; | |||
| pluginString += " lv2:minorVersion " + String(minorVersion) + " .\n"; | |||
| } | |||
| pluginFile << pluginString << std::endl; | |||
| pluginFile.close(); | |||
| @@ -504,7 +581,6 @@ void lv2_generate_ttl(const char* const basename) | |||
| String presetsString; | |||
| presetsString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||
| presetsString += "@prefix pset: <" LV2_PRESETS_PREFIX "> .\n"; | |||
| presetsString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||
| # if DISTRHO_PLUGIN_WANT_STATE | |||
| presetsString += "@prefix state: <" LV2_STATE_PREFIX "> .\n"; | |||
| # endif | |||
| @@ -512,7 +588,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| const uint32_t numParameters = plugin.getParameterCount(); | |||
| const uint32_t numPrograms = plugin.getProgramCount(); | |||
| # if DISTRHO_PLUGIN_WANT_STATE | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| const uint32_t numStates = plugin.getStateCount(); | |||
| # endif | |||
| @@ -530,34 +606,26 @@ void lv2_generate_ttl(const char* const basename) | |||
| plugin.loadProgram(i); | |||
| presetString = "<" DISTRHO_PLUGIN_URI + presetSeparator + "preset" + strBuf + ">\n"; | |||
| presetString += " rdfs:label \"" + plugin.getProgramName(i) + "\" ;\n\n"; | |||
| // TODO | |||
| # if 0 // DISTRHO_PLUGIN_WANT_STATE | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| presetString += " state:state [\n"; | |||
| for (uint32_t j=0; j<numStates; ++j) | |||
| { | |||
| if (j == 0) | |||
| presetString += " state:state [\n"; | |||
| else | |||
| presetString += " [\n"; | |||
| const String key = plugin.getStateKey(j); | |||
| const String value = plugin.getState(key); | |||
| presetString += " <urn:distrho:" + plugin.getStateKey(j) + ">\n"; | |||
| presetString += "\"\"\"\n"; | |||
| presetString += plugin.getState(j); | |||
| presetString += "\"\"\"\n"; | |||
| presetString += " <urn:distrho:" + key + ">"; | |||
| if (j+1 == numStates) | |||
| { | |||
| if (numParameters > 0) | |||
| presetString += " ] ;\n\n"; | |||
| else | |||
| presetString += " ] .\n\n"; | |||
| } | |||
| if (value.length() < 10) | |||
| presetString += " \"" + value + "\" ;\n"; | |||
| else | |||
| { | |||
| presetString += " ] ,\n"; | |||
| } | |||
| presetString += "\n\"\"\"\n" + value + "\n\"\"\" ;\n"; | |||
| } | |||
| if (numParameters > 0) | |||
| presetString += " ] ;\n\n"; | |||
| else | |||
| presetString += " ] .\n\n"; | |||
| # endif | |||
| for (uint32_t j=0; j <numParameters; ++j) | |||
| @@ -454,7 +454,17 @@ public: | |||
| fVstUI = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr); | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| // Update current state from plugin side | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| fStateMap[key] = fPlugin.getState(key); | |||
| } | |||
| # endif | |||
| # if DISTRHO_PLUGIN_WANT_STATE | |||
| // Set state | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| @@ -506,6 +516,15 @@ public: | |||
| } | |||
| else | |||
| { | |||
| # if DISTRHO_PLUGIN_WANT_FULL_STATE | |||
| // Update current state | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| { | |||
| const String& key = cit->first; | |||
| fStateMap[key] = fPlugin.getState(key); | |||
| } | |||
| # endif | |||
| String chunkStr; | |||
| for (StringMap::const_iterator cit=fStateMap.begin(), cite=fStateMap.end(); cit != cite; ++cit) | |||
| @@ -28,6 +28,10 @@ | |||
| #include "lv2/lv2_kxstudio_properties.h" | |||
| #include "lv2/lv2_programs.h" | |||
| #ifndef DISTRHO_PLUGIN_LV2_STATE_PREFIX | |||
| # define DISTRHO_PLUGIN_LV2_STATE_PREFIX "urn:distrho:" | |||
| #endif | |||
| START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| @@ -46,7 +50,7 @@ public: | |||
| fController(controller), | |||
| fWriteFunction(writeFunc), | |||
| fEventTransferURID(uridMap->map(uridMap->handle, LV2_ATOM__eventTransfer)), | |||
| fKeyValueURID(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")), | |||
| fKeyValueURID(uridMap->map(uridMap->handle, DISTRHO_PLUGIN_LV2_STATE_PREFIX "KeyValueState")), | |||
| fWinIdWasNull(winId == 0) | |||
| { | |||
| if (fUiResize != nullptr && winId != 0) | |||
| @@ -331,8 +335,6 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| void* instance = nullptr; | |||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| # define DISTRHO_DIRECT_ACCESS_URI "urn:distrho:direct-access" | |||
| struct LV2_DirectAccess_Interface { | |||
| void* (*get_instance_pointer)(LV2_Handle handle); | |||
| }; | |||
| @@ -381,7 +383,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| return nullptr; | |||
| } | |||
| if (const LV2_DirectAccess_Interface* const directAccess = (const LV2_DirectAccess_Interface*)extData->data_access(DISTRHO_DIRECT_ACCESS_URI)) | |||
| if (const LV2_DirectAccess_Interface* const directAccess = (const LV2_DirectAccess_Interface*)extData->data_access(DISTRHO_PLUGIN_LV2_STATE_PREFIX "direct-access")) | |||
| instance = directAccess->get_instance_pointer(instance); | |||
| else | |||
| instance = nullptr; | |||
| @@ -1 +1 @@ | |||
| ../../../includes/dssi/ | |||
| ../../../includes/dssi | |||
| @@ -1 +1 @@ | |||
| ../../../includes/ladspa/ | |||
| ../../../includes/ladspa | |||
| @@ -1 +1 @@ | |||
| ../../../includes/lv2/ | |||
| ../../../includes/lv2 | |||
| @@ -1 +1 @@ | |||
| ../../../includes/vestige/ | |||
| ../../../includes/vestige | |||